#!/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)