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