1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
|
#!/usr/bin/python -N
"""
Framework Test Framework (sic!)
(C) 2008 Guillaume 'Charlie' Chereau <charlie@openmoko.org>
(C) 2008 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
(C) 2008 Openmoko, Inc.
GPLv2 or later
"""
# We are using python unittest for the framework testing.
# One problem comes from the fact that we have to test the receiving of
# DBus signals, wich mean that we have to handle callback from within the test
# cases. It is not easily done using unittest.
# We can use the framewok tasklet module to simplify things a little.
import framework
from framework.patterns.tasklet import Tasklet, Sleep
import types
import unittest
import gobject
import ConfigParser
import dbus
config = ConfigParser.ConfigParser()
config.readfp(open('tests.conf'))
#=========================================================================#
def taskletTest(func):
#=========================================================================#
"""decorator that turn a test into a tasklet
The decorator will also take care of starting and stopping the mainloop
"""
def ret(*args):
loop = gobject.MainLoop()
done = False
ret.error = None
ret.done = False
def on_done(*args):
ret.done = True
loop.quit()
def on_error(type, err, traceback):
ret.done = True
ret.error = type, err, traceback
loop.quit()
Tasklet(generator=func(*args)).start(on_done, on_error)
if not ret.done: # Because it could be we returned even before starting the main loop
loop.run()
if ret.error:
raise ret.error[0], ret.error[1], ret.error[2]
ret.__dict__ = func.__dict__
ret.__name__ = func.__name__
ret.__doc__ = func.__doc__
return ret
#=========================================================================#
def request(*conds):
#=========================================================================#
"""This decorator can be used to skip some tests if a test condition if not satisfy
It is useful for testing without sim card, or operator to answer questions, etc...
You can call it with two arguments :
option : string of the form <section>.<option>
value : the value of the config option
e.g :
@request('sim.present', True)
or with a list of tuple of the form
(option, value)
e.g:
@request(('sim.present', True), ('sim.has_contact', True))
"""
# If we call with a single condition, turn it into a list of conditions
if isinstance(conds[0], str):
conds = (conds,)
# Now we check all the conditions one bye one
# I a single condition fails, then we skip the test
skipped = False
for cond in conds:
section, option = cond[0].split('.')
value = cond[1]
# We make sure to use the same type for the value and the option
if isinstance(value, bool):
conf_value = config.getboolean(section, option)
elif isinstance(value, int):
conf_value = config.getint(section, option)
elif isinstance(value, str):
conf_value = config.get(section, option)
else:
raise TypeError(conf_value)
if conf_value != value:
skipped = True
break
def _request(func):
"""The actual decorator"""
if not skipped:
return func
# The skipped test does nothing
def ret(*args, **kargs):
return
ret.__dict__ = func.__dict__
ret.__name__ = func.__name__
# Important to change the name so that the user see that the test has been skipped
ret.__doc__ = "%s : SKIPPED (need %s)" % (func.__doc__ or func.__name__, conds)
return ret
return _request
#=========================================================================#
class TestTest(unittest.TestCase):
#=========================================================================#
"""Test the test system itself"""
def setUp(self):
self.setup =True
def tearDown(self):
pass
def test_setup(self):
"""Test that we did set up the test"""
assert self.setup
@taskletTest
def test_tasklet(self):
"""Test a tasklet test"""
yield Sleep(1)
yield True
#=========================================================================#
def testDbusError( error, expected ):
#=========================================================================#
ename = error.get_dbus_name()
assert ename == expected, "expected error '%s', got '%s' instead" % ( expected, ename )
#=========================================================================#
def testDbusType( value, type_ ):
#=========================================================================#
assert type( value ) == type_, "expected %s type, got '%s' instead" % ( type_, type( value ) )
#=========================================================================#
def testDbusValueIsInteger( value ):
#=========================================================================#
assert type( value ) == dbus.Int16 or \
type( value ) == dbus.Int32 or \
type( value ) == dbus.Int64, "expected integer value type, got '%s' instead" % type( value )
#=========================================================================#
def testDbusDictionaryWithStringValues( result ):
#=========================================================================#
assert type( result ) is dbus.Dictionary, "expected dictionary type, got '%s' instead" % type( result )
for key, value in result.items():
assert type( key ) == dbus.String, "key type in dictionary not a string, got '%s' instead" % type( key )
assert type( value ) == dbus.String, "value type in dictionary not a string, got '%s' instead" % type( value )
#=========================================================================#
def testDbusDictionaryWithIntegerValues( result ):
#=========================================================================#
assert type( result ) is dbus.Dictionary, "expected dictionary type, got '%s' instead" % type( result )
for key, value in result.items():
assert type( key ) == dbus.String, "key type in dictionary not a string, got '%s' instead" % type( key )
testDBusValueIsInteger( value )
#=========================================================================#
def check_debug_mode():
#=========================================================================#
"""Exit the program if we are not in debug mode"""
try:
assert False
except:
pass
else:
print 'You need to run this in debug mode (-N option on neo)'
import sys
sys.exit(-1)
#=========================================================================#
class Operator(object):
#=========================================================================#
"""Class used to communicate with the test operator during the tests"""
def query(self, question):
"""Ask a y/n question to the operator"""
while True:
answer = raw_input("\n> %s y/n " % question)
if answer.lower() == 'y':
return True
if answer.lower() == 'n':
return False
def tell(self, msg):
"""Print a message to the operator"""
print msg
operator = Operator()
# We check for the debug mode
check_debug_mode()
#=========================================================================#
if __name__ == '__main__':
#=========================================================================#
# This list all the modules containing the tests we want to run
# TODO: provide command line arguments like in Mikey ogsmd test script
modules = ['test', 'opreferencesd', 'sim', 'opimd', 'ogsmd2', 'oevents']
for module in modules:
module = __import__(module)
print "== testing module : %s ==" % module.__name__
suite = unittest.defaultTestLoader.loadTestsFromModule(module)
result = unittest.TextTestRunner(verbosity=3).run(suite)
print
|