普通文本  |  169行  |  6.09 KB

#!/usr/bin/python
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import dbus, logging
from autotest_lib.client.common_lib import error

sample = {
    'pdu' :
      '07914140540510F0040B916171056429F500001190804181106904D4F29C0E',
    'parsed' :
      {'text' : 'Test',
       'number' : '+16175046925',
       'timestamp' : '110908141801-04',
       'smsc' : '+14044550010'
       }
    }

sample_multipart = {
    'pdu' :
      ['07912160130320F8440B916171056429F5000011909161037469A0050003920201A9'
       'E5391DF43683E6EF7619C47EBBCF207A194F0789EB74D03D4D47BFEB7450D89D0791'
       'D366737A5C67D3416374581E1ED3CBF23928ED1EB3EBE43219947683E8E832A85D9E'
       'CFC3E7B20B4445A7E72077B94C9E83E86F90B80C7ADBCB72101D5D06B1CBEE331D0D'
       'A2A3E5E539FACD2683CC6F39888E2E83D8EF71980D9ABFCDF47B585E06D1DF',
       '07912160130320F5440B916171056429F50000119091610384691505000392020241'
       'E437888E2E83E670769AEE02'],
    'parsed' :
      {'text' : 'Test of some long text but without any difficult characters'
       ' included in the message. This needs to be over the length threshold'
       ' for the local software to do the split.',
       'number' : '+16175046925',
       'timestamp' : '110919163047-04',
       'smsc' : '+12063130028'
       }
    }


class SmsStore(object):
    '''SMS content management - this maintains an internal model of the
    index->PDU mapping that the fakemodem program should be returning so
    that tests can add and remove individual PDUs and handles generating
    the correct set of responses, including the complete SMS list.
    '''

    def __init__(self, fakemodem):
        self.fakemodem = fakemodem
        self.smsdict = {}
        self.fakemodem.SetResponse('\+CMGR=', '', '+CMS ERROR: 321')
        self.fakemodem.SetResponse('\+CMGD=', '', '+CMS ERROR: 321')
        self._sms_regen_list()

    def sms_insert(self, index, pdu):
        '''Add a SMS to the fake modem's list.'''
        smsc_len = int(pdu[0:1], 16)
        mlen = len(pdu)/2 - smsc_len - 1

        self.fakemodem.RemoveResponse('\+CMGD=')
        self.fakemodem.RemoveResponse('\+CMGR=')
        self.fakemodem.SetResponse('\+CMGD=%d' % (index), '', '')
        self.fakemodem.SetResponse('\+CMGR=%d' % (index),
                                   '+CMGR: 1,,%d\r\n%s' % (mlen, pdu), '')
        self.fakemodem.SetResponse('\+CMGR=', '', '+CMS ERROR: 321')
        self.fakemodem.SetResponse('\+CMGD=', '', '+CMS ERROR: 321')

        self.smsdict[index] = pdu
        self._sms_regen_list()

    def sms_receive(self, index, pdu):
        '''Add a SMS to the fake modem's list, like sms_insert(), and generate
        an unsolicited new-sms message.'''
        self.sms_insert(index, pdu)
        self.fakemodem.SendUnsolicited('+CMTI: "ME",%d'%(index))

    def sms_remove(self, index):
        '''Remove a SMS from the fake modem's list'''
        self.fakemodem.RemoveResponse('\+CMGR=%d' % (index))
        self.fakemodem.RemoveResponse('\+CMGD=%d' % (index))
        del self.smsdict[index]
        self._sms_regen_list()

    def _sms_regen_list(self):
        response = ''
        keys = self.smsdict.keys()
        keys.sort()
        for i in keys:
            pdu = self.smsdict[i]
            smsc_len = int(pdu[0:1],16)
            mlen = len(pdu)/2 - smsc_len - 1
            response = response + '+CMGL: %d,1,,%d\r\n%s\r\n' % (i, mlen, pdu)
        self.fakemodem.SetResponse('\+CMGL=4', response, '')


class SmsTest(object):
    def __init__(self, gsmsms):
        self.gsmsms = gsmsms

    def compare(self, expected, got):
        '''Compare two SMS dictionaries, discounting the index number if
        not specified in the first.'''
        if expected == got:
            return True
        if 'index' in expected:
            return False
        if 'index' not in got:
            return False
        got = dict(got)
        del got['index']
        return expected == got

    def compare_list(self, expected_list, got_list):
        if len(expected_list) != len(got_list):
            return False
        # There must be a more Pythonic way to do this
        for (expected,got) in zip(expected_list, got_list):
            if self.compare(expected, got) == False:
                return False
        return True

    def test_get(self, index, expected):
        try:
            sms = self.gsmsms.Get(index)
        except dbus.DBusException, db:
            if expected is not None:
                raise
            return

        if expected is None:
            logging.info('Got %s' % sms)
            raise error.TestFail('SMS.Get(%d) succeeded unexpectedly' %
                                 index)
        if self.compare(expected, sms) == False:
            logging.info('Got %s, expected %s' % (sms, expected))
            raise error.TestFail('SMS.Get(%d) did not match expected values' %
                                 index)

    def test_delete(self, index, expected_success):
        try:
            self.gsmsms.Delete(index)
            if expected_success == False:
                raise error.TestFail('SMS.Delete(%d) succeeded unexpectedly' %
                                     index)
        except dbus.DBusException, db:
            if expected_success:
                raise

    def test_list(self, expected_list):
        sms_list = self.gsmsms.List()
        if self.compare_list(expected_list, sms_list) == False:
            logging.info('Got %s, expected %s' % (sms_list, expected_list))
            raise error.TestFail('SMS.List() did not match expected values')

    def test_has_none(self):
        '''Test that the SMS interface has no messages.'''
        self.test_list([])
        self.test_get(1, None)
        self.test_delete(1, False)
        self.test_delete(2, False)

    def test_has_one(self, parsed_sms):
        '''Test that the SMS interface has exactly one message at index 1
        As a side effect, deletes the message.'''
        self.test_list([parsed_sms])
        self.test_get(1, parsed_sms)
        self.test_get(2, None)
        self.test_delete(2, False)
        self.test_delete(1, True)