code bomb implementing the bulk of the osmo-gsm-tester Change-Id: I53610becbf643ed51b90cfd9debc6992fe211ec9changes/43/2443/1
parent
dae3d3c479
commit
3531a192ae
@ -1,9 +1,12 @@
|
||||
.PHONY: check update
|
||||
|
||||
check:
|
||||
check: set_pythonpath
|
||||
./all_tests.py
|
||||
|
||||
update:
|
||||
./all_tests.py -u
|
||||
|
||||
set_pythonpath:
|
||||
echo "export PYTHONPATH=\"$(PWD)/../src\"" > set_pythonpath
|
||||
|
||||
# vim: noexpandtab tabstop=8 shiftwidth=8
|
@ -0,0 +1,2 @@
|
||||
state_dir: ./test_work/state_dir
|
||||
suites_dir: ./suite_test
|
@ -1,37 +1,55 @@
|
||||
# all hardware and interfaces available to this osmo-gsm-tester
|
||||
|
||||
nitb_iface:
|
||||
- 10.42.42.1
|
||||
- 10.42.42.2
|
||||
- 10.42.42.3
|
||||
- addr: 10.42.42.1
|
||||
- addr: 10.42.42.2
|
||||
- addr: 10.42.42.3
|
||||
|
||||
bts:
|
||||
- label: sysmoBTS 1002
|
||||
type: sysmo
|
||||
unit_id: 1
|
||||
addr: 10.42.42.114
|
||||
trx:
|
||||
- band: GSM-1800
|
||||
band: GSM-1800
|
||||
|
||||
- label: octBTS 3000
|
||||
type: oct
|
||||
unit_id: 5
|
||||
addr: 10.42.42.115
|
||||
band: GSM-1800
|
||||
trx:
|
||||
- band: GSM-1800
|
||||
hwaddr: 00:0c:90:32:b5:8a
|
||||
- hwaddr: 00:0c:90:32:b5:8a
|
||||
|
||||
- label: nanoBTS 1900
|
||||
type: nanobts
|
||||
unit_id: 1902
|
||||
addr: 10.42.42.190
|
||||
band: GSM-1900
|
||||
trx:
|
||||
- band: GSM-1900
|
||||
hwaddr: 00:02:95:00:41:b3
|
||||
- hwaddr: 00:02:95:00:41:b3
|
||||
|
||||
arfcn:
|
||||
- GSM-1800: [512, 514, 516, 518, 520]
|
||||
- GSM-1900: [540, 542, 544, 546, 548]
|
||||
- arfcn: 512
|
||||
band: GSM-1800
|
||||
- arfcn: 514
|
||||
band: GSM-1800
|
||||
- arfcn: 516
|
||||
band: GSM-1800
|
||||
- arfcn: 518
|
||||
band: GSM-1800
|
||||
- arfcn: 520
|
||||
band: GSM-1800
|
||||
|
||||
- arfcn: 540
|
||||
band: GSM-1900
|
||||
- arfcn: 542
|
||||
band: GSM-1900
|
||||
- arfcn: 544
|
||||
band: GSM-1900
|
||||
- arfcn: 546
|
||||
band: GSM-1900
|
||||
- arfcn: 548
|
||||
band: GSM-1900
|
||||
|
||||
modem:
|
||||
- label: m7801
|
@ -0,0 +1,95 @@
|
||||
{'addr': ['0.0.0.0',
|
||||
'255.255.255.255',
|
||||
'10.11.12.13',
|
||||
'10.0.99.1',
|
||||
'192.168.0.14'],
|
||||
'bts': [{'addr': '10.42.42.114',
|
||||
'name': 'sysmoBTS 1002',
|
||||
'trx': [{'band': 'GSM-1800',
|
||||
'timeslots': ['CCCH+SDCCH4',
|
||||
'SDCCH8',
|
||||
'TCH/F_TCH/H_PDCH',
|
||||
'TCH/F_TCH/H_PDCH',
|
||||
'TCH/F_TCH/H_PDCH',
|
||||
'TCH/F_TCH/H_PDCH',
|
||||
'TCH/F_TCH/H_PDCH',
|
||||
'TCH/F_TCH/H_PDCH']},
|
||||
{'band': 'GSM-1900',
|
||||
'timeslots': ['SDCCH8',
|
||||
'PDCH',
|
||||
'PDCH',
|
||||
'PDCH',
|
||||
'PDCH',
|
||||
'PDCH',
|
||||
'PDCH',
|
||||
'PDCH']}],
|
||||
'type': 'sysmobts'}],
|
||||
'hwaddr': ['ca:ff:ee:ba:aa:be',
|
||||
'00:00:00:00:00:00',
|
||||
'CA:FF:EE:BA:AA:BE',
|
||||
'cA:Ff:eE:Ba:aA:Be',
|
||||
'ff:ff:ff:ff:ff:ff'],
|
||||
'imsi': ['012345', '012345678', '012345678912345'],
|
||||
'ki': ['000102030405060708090a0b0c0d0e0f', '000102030405060708090a0b0c0d0e0f'],
|
||||
'modems': [{'dbus_path': '/sierra_0',
|
||||
'imsi': '901700000009001',
|
||||
'ki': 'D620F48487B1B782DA55DF6717F08FF9',
|
||||
'msisdn': '7801'},
|
||||
{'dbus_path': '/sierra_1',
|
||||
'imsi': '901700000009002',
|
||||
'ki': 'D620F48487B1B782DA55DF6717F08FF9',
|
||||
'msisdn': '7802'}]}
|
||||
- expect validation success:
|
||||
Validation: OK
|
||||
- unknown item:
|
||||
--- -: ERR: ValueError: config item not known: 'bts[].unknown_item'
|
||||
Validation: Error
|
||||
- wrong type modems[].imsi:
|
||||
--- -: ERR: ValueError: config item is dict but should be a leaf node of type 'imsi': 'modems[].imsi'
|
||||
Validation: Error
|
||||
- invalid key with space:
|
||||
--- -: ERR: ValueError: invalid config key: 'imsi '
|
||||
Validation: Error
|
||||
- list instead of dict:
|
||||
--- -: ERR: ValueError: config item not known: 'a_dict[]'
|
||||
Validation: Error
|
||||
- unknown band:
|
||||
--- (item='bts[].trx[].band'): ERR: ValueError: Unknown GSM band: 'what'
|
||||
Validation: Error
|
||||
- invalid v4 addrs:
|
||||
--- (item='addr[]'): ERR: ValueError: Invalid IPv4 address: '1.2.3'
|
||||
Validation: Error
|
||||
--- (item='addr[]'): ERR: ValueError: Invalid IPv4 address: '1.2.3 .4'
|
||||
Validation: Error
|
||||
--- (item='addr[]'): ERR: ValueError: Invalid IPv4 address: '91.2.3'
|
||||
Validation: Error
|
||||
--- (item='addr[]'): ERR: ValueError: Invalid IPv4 address: 'go away'
|
||||
Validation: Error
|
||||
--- (item='addr[]'): ERR: ValueError: Invalid IPv4 address: ''
|
||||
Validation: Error
|
||||
--- (item='addr[]'): ERR: ValueError: Invalid IPv4 address: None
|
||||
Validation: Error
|
||||
- invalid hw addrs:
|
||||
--- (item='hwaddr[]'): ERR: ValueError: Invalid hardware address: '1.2.3'
|
||||
Validation: Error
|
||||
--- (item='hwaddr[]'): ERR: ValueError: Invalid hardware address: '0b:0c:0d:0e:0f:0g'
|
||||
Validation: Error
|
||||
--- (item='hwaddr[]'): ERR: ValueError: Invalid hardware address: '0b:0c:0d:0e : 0f:0f'
|
||||
Validation: Error
|
||||
--- (item='hwaddr[]'): ERR: ValueError: Invalid hardware address: 'go away'
|
||||
Validation: Error
|
||||
--- (item='hwaddr[]'): ERR: ValueError: Invalid hardware address: ''
|
||||
Validation: Error
|
||||
--- (item='hwaddr[]'): ERR: ValueError: Invalid hardware address: None
|
||||
Validation: Error
|
||||
- invalid imsis:
|
||||
--- (item='imsi[]'): ERR: ValueError: Invalid IMSI: '99999999x9'
|
||||
Validation: Error
|
||||
--- (item='imsi[]'): ERR: ValueError: Invalid IMSI: '123 456 789 123'
|
||||
Validation: Error
|
||||
--- (item='imsi[]'): ERR: ValueError: Invalid IMSI: 'go away'
|
||||
Validation: Error
|
||||
--- (item='imsi[]'): ERR: ValueError: Invalid IMSI: ''
|
||||
Validation: Error
|
||||
--- (item='imsi[]'): ERR: ValueError: Invalid IMSI: None
|
||||
Validation: Error
|
@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import _prep
|
||||
|
||||
import sys
|
||||
import os
|
||||
import io
|
||||
import pprint
|
||||
import copy
|
||||
|
||||
from osmo_gsm_tester import config, log, schema
|
||||
|
||||
example_config_file = 'test.cfg'
|
||||
example_config = os.path.join(_prep.script_dir, 'config_test', example_config_file)
|
||||
cfg = config.read(example_config)
|
||||
|
||||
pprint.pprint(cfg)
|
||||
|
||||
test_schema = {
|
||||
'modems[].dbus_path': schema.STR,
|
||||
'modems[].msisdn': schema.STR,
|
||||
'modems[].imsi': schema.IMSI,
|
||||
'modems[].ki': schema.STR,
|
||||
'bts[].name' : schema.STR,
|
||||
'bts[].type' : schema.STR,
|
||||
'bts[].addr' : schema.STR,
|
||||
'bts[].trx[].timeslots[]' : schema.STR,
|
||||
'bts[].trx[].band' : schema.BAND,
|
||||
'a_dict.foo' : schema.INT,
|
||||
'addr[]' : schema.IPV4,
|
||||
'hwaddr[]' : schema.HWADDR,
|
||||
'imsi[]' : schema.IMSI,
|
||||
'ki[]' : schema.KI,
|
||||
}
|
||||
|
||||
def val(which):
|
||||
try:
|
||||
schema.validate(which, test_schema)
|
||||
print('Validation: OK')
|
||||
except ValueError:
|
||||
log.log_exn()
|
||||
print('Validation: Error')
|
||||
|
||||
print('- expect validation success:')
|
||||
val(cfg)
|
||||
|
||||
print('- unknown item:')
|
||||
c = copy.deepcopy(cfg)
|
||||
c['bts'][0]['unknown_item'] = 'no'
|
||||
val(c)
|
||||
|
||||
print('- wrong type modems[].imsi:')
|
||||
c = copy.deepcopy(cfg)
|
||||
c['modems'][0]['imsi'] = {'no':'no'}
|
||||
val(c)
|
||||
|
||||
print('- invalid key with space:')
|
||||
c = copy.deepcopy(cfg)
|
||||
c['modems'][0]['imsi '] = '12345'
|
||||
val(c)
|
||||
|
||||
print('- list instead of dict:')
|
||||
c = copy.deepcopy(cfg)
|
||||
c['a_dict'] = [ 1, 2, 3 ]
|
||||
val(c)
|
||||
|
||||
print('- unknown band:')
|
||||
c = copy.deepcopy(cfg)
|
||||
c['bts'][0]['trx'][0]['band'] = 'what'
|
||||
val(c)
|
||||
|
||||
print('- invalid v4 addrs:')
|
||||
c = copy.deepcopy(cfg)
|
||||
c['addr'][3] = '1.2.3'
|
||||
val(c)
|
||||
c['addr'][3] = '1.2.3 .4'
|
||||
val(c)
|
||||
c['addr'][3] = '91.2.3'
|
||||
val(c)
|
||||
c['addr'][3] = 'go away'
|
||||
val(c)
|
||||
c['addr'][3] = ''
|
||||
val(c)
|
||||
c['addr'][3] = None
|
||||
val(c)
|
||||
|
||||
print('- invalid hw addrs:')
|
||||
c = copy.deepcopy(cfg)
|
||||
c['hwaddr'][3] = '1.2.3'
|
||||
val(c)
|
||||
c['hwaddr'][3] = '0b:0c:0d:0e:0f:0g'
|
||||
val(c)
|
||||
c['hwaddr'][3] = '0b:0c:0d:0e : 0f:0f'
|
||||
val(c)
|
||||
c['hwaddr'][3] = 'go away'
|
||||
val(c)
|
||||
c['hwaddr'][3] = ''
|
||||
val(c)
|
||||
c['hwaddr'][3] = None
|
||||
val(c)
|
||||
|
||||
print('- invalid imsis:')
|
||||
c = copy.deepcopy(cfg)
|
||||
c['imsi'][2] = '99999999x9'
|
||||
val(c)
|
||||
c['imsi'][2] = '123 456 789 123'
|
||||
val(c)
|
||||
c['imsi'][2] = 'go away'
|
||||
val(c)
|
||||
c['imsi'][2] = ''
|
||||
val(c)
|
||||
c['imsi'][2] = None
|
||||
val(c)
|
||||
|
||||
# vim: expandtab tabstop=4 shiftwidth=4
|
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Based on http://stackoverflow.com/questions/22390064/use-dbus-to-just-send-a-message-in-python
|
||||
|
||||
# Python DBUS Test Server
|
||||
# runs until the Quit() method is called via DBUS
|
||||
|
||||
from gi.repository import GLib
|
||||
from pydbus import SessionBus
|
||||
|
||||
loop = GLib.MainLoop()
|
||||
|
||||
class MyDBUSService(object):
|
||||
"""
|
||||
<node>
|
||||
<interface name='net.lew21.pydbus.ClientServerExample'>
|
||||
<method name='Hello'>
|
||||
<arg type='s' name='response' direction='out'/>
|
||||
</method>
|
||||
<method name='EchoString'>
|
||||
<arg type='s' name='a' direction='in'/>
|
||||
<arg type='s' name='response' direction='out'/>
|
||||
</method>
|
||||
<method name='Quit'/>
|
||||
</interface>
|
||||
</node>
|
||||
"""
|
||||
|
||||
def Hello(self):
|
||||
"""returns the string 'Hello, World!'"""
|
||||
return "Hello, World!"
|
||||
|
||||
def EchoString(self, s):
|
||||
"""returns whatever is passed to it"""
|
||||
return s
|
||||
|
||||
def Quit(self):
|
||||
"""removes this object from the DBUS connection and exits"""
|
||||
loop.quit()
|
||||
|
||||
bus = SessionBus()
|
||||
bus.publish("net.lew21.pydbus.ClientServerExample", MyDBUSService())
|
||||
loop.run()
|
||||
|
@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
'''
|
||||
Power on and off some modem on ofono, while running the glib main loop in a
|
||||
thread and receiving modem state changes by dbus signals.
|
||||
'''
|
||||
|
||||
from pydbus import SystemBus, Variant
|
||||
import time
|
||||
import threading
|
||||
import pprint
|
||||
|
||||
from gi.repository import GLib
|
||||
loop = GLib.MainLoop()
|
||||
|
||||
def propchanged(*args, **kwargs):
|
||||
print('-> PROP CHANGED: %r %r' % (args, kwargs))
|
||||
|
||||
class GlibMainloop(threading.Thread):
|
||||
def run(self):
|
||||
loop.run()
|
||||
|
||||
ml = GlibMainloop()
|
||||
ml.start()
|
||||
|
||||
try:
|
||||
bus = SystemBus()
|
||||
|
||||
print('\n- list modems')
|
||||
root = bus.get("org.ofono", '/')
|
||||
print(root.Introspect())
|
||||
modems = sorted(root.GetModems())
|
||||
pprint.pprint(modems)
|
||||
|
||||
first_modem_path = modems[0][0]
|
||||
print('\n- first modem %r' % first_modem_path)
|
||||
modem = bus.get("org.ofono", first_modem_path)
|
||||
modem.PropertyChanged.connect(propchanged)
|
||||
|
||||
print(modem.Introspect())
|
||||
print(modem.GetProperties())
|
||||
|
||||
print('\n- set Powered = True')
|
||||
modem.SetProperty('Powered', Variant('b', True))
|
||||
print('call returned')
|
||||
print(modem.GetProperties())
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
print('\n- set Powered = False')
|
||||
modem.SetProperty('Powered', Variant('b', False))
|
||||
print('call returned')
|
||||
|
||||
print(modem.GetProperties())
|
||||
finally:
|
||||
loop.quit()
|
||||
ml.join()
|
@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
'''
|
||||
Power on and off some modem on ofono, while running the glib main loop in a
|
||||
thread and receiving modem state changes by dbus signals.
|
||||
'''
|
||||
|
||||
from pydbus import SystemBus, Variant
|
||||
import time
|
||||
import pprint
|
||||
|
||||
from gi.repository import GLib
|
||||
glib_main_loop = GLib.MainLoop()
|
||||
glib_main_ctx = glib_main_loop.get_context()
|
||||
|
||||
def propchanged(*args, **kwargs):
|
||||
print('-> PROP CHANGED: %r %r' % (args, kwargs))
|
||||
|
||||
|
||||
def pump():
|
||||
global glib_main_ctx
|
||||
print('pump?')
|
||||
while glib_main_ctx.pending():
|
||||
print('* pump')
|
||||
glib_main_ctx.iteration()
|
||||
|
||||
def wait(condition):
|
||||
pump()
|
||||
while not condition():
|
||||
time.sleep(.1)
|
||||
pump()
|
||||
|
||||
bus = SystemBus()
|
||||
|
||||
print('\n- list modems')
|
||||
root = bus.get("org.ofono", '/')
|
||||
print(root.Introspect())
|
||||
modems = sorted(root.GetModems())
|
||||
pprint.pprint(modems)
|
||||
pump()
|
||||
|
||||
first_modem_path = modems[0][0]
|
||||
print('\n- first modem %r' % first_modem_path)
|
||||
modem = bus.get("org.ofono", first_modem_path)
|
||||
modem.PropertyChanged.connect(propchanged)
|
||||
|
||||
print(modem.Introspect())
|
||||
print(modem.GetProperties())
|
||||
|
||||
print('\n- set Powered = True')
|
||||
modem.SetProperty('Powered', Variant('b', True))
|
||||
print('call returned')
|
||||
print('- pump dbus events')
|
||||
pump()
|
||||
pump()
|
||||
print('sleep 1')
|
||||
time.sleep(1)
|
||||
pump()
|
||||
|
||||
|
||||
print('- modem properties:')
|
||||
print(modem.GetProperties())
|
||||
|
||||
|
||||
print('\n- set Powered = False')
|
||||
modem.SetProperty('Powered', Variant('b', False))
|
||||
print('call returned')
|
||||
|
||||
print(modem.GetProperties())
|
||||
|
||||
# vim: tabstop=4 shiftwidth=4 expandtab
|
@ -0,0 +1,41 @@
|
||||
- Testing global log functions
|
||||
01:02:03 tst <origin>: from log.log()
|
||||
01:02:03 tst <origin>: DBG: from log.dbg()
|
||||
01:02:03 tst <origin>: ERR: from log.err()
|
||||
- Testing log.Origin functions
|
||||
01:02:03 tst some-name(some='detail'): hello log
|
||||
01:02:03 tst some-name(some='detail'): ERR: hello err
|
||||
01:02:03 tst some-name(some='detail'): message {int=3, none=None, str='str\n', tuple=('foo', 42)}
|
||||
01:02:03 tst some-name(some='detail'): DBG: hello dbg
|
||||
- Testing log.style()
|
||||
01:02:03: only time
|
||||
tst: only category
|
||||
DBG: only level
|
||||
some-name(some='detail'): only origin
|
||||
only src [log_test.py:70]
|
||||
- Testing log.style_change()
|
||||
no log format
|
||||
01:02:03: add time
|
||||
but no time format
|
||||
01:02:03: DBG: add level
|
||||
01:02:03 tst: DBG: add category
|
||||
01:02:03 tst: DBG: add src [log_test.py:85]
|
||||
01:02:03 tst some-name(some='detail'): DBG: add origin [log_test.py:87]
|
||||
- Testing origin_width
|
||||
01:02:03 tst shortname: origin str set to 23 chars [log_test.py:94]
|
||||
01:02:03 tst very long name(and_some=(3, 'things', 'in a tuple'), some='details'): long origin str [log_test.py:96]
|
||||
01:02:03 tst very long name(and_some=(3, 'things', 'in a tuple'), some='details'): DBG: long origin str dbg [log_test.py:97]
|
||||
01:02:03 tst very long name(and_some=(3, 'things', 'in a tuple'), some='details'): ERR: long origin str err [log_test.py:98]
|
||||
- Testing log.Origin with omitted info
|
||||
01:02:03 tst LogTest: hello log, name implicit from class name [log_test.py:103]
|
||||
01:02:03 --- explicit_name: hello log, no category set [log_test.py:107]
|
||||
01:02:03 --- LogTest: hello log, no category nor name set [log_test.py:110]
|
||||
01:02:03 --- LogTest: DBG: debug message, no category nor name set [log_test.py:113]
|
||||
- Testing logging of Exceptions, tracing origins
|
||||
Not throwing an exception in 'with:' works.
|
||||
nested print just prints
|
||||
01:02:03 tst level3: nested log() [level1↪level2↪level3] [log_test.py:145]
|
||||
01:02:03 tst level2: nested l2 log() from within l3 scope [level1↪level2] [log_test.py:146]
|
||||
01:02:03 tst level3: ERR: ValueError: bork [level1↪level2↪level3] [log_test.py:147: raise ValueError('bork')]
|
||||
- Enter the same Origin context twice
|
||||
01:02:03 tst level2: nested log [level1↪level2] [log_test.py:159]
|
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
msisdn = '0000'
|
||||
|
||||
l = len(msisdn)
|
||||
next_msisdn = ('%%0%dd' % l) % (int(msisdn) + 1)
|
||||
print(next_msisdn)
|
@ -0,0 +1,33 @@
|
||||
run foo: DBG: cd '[TMP]'; PATH=[$PATH] foo.py arg1 arg2 [foo↪foo]
|
||||
run foo: DBG: [TMP]/stdout [foo↪foo]
|
||||
run foo: DBG: [TMP]/stderr [foo↪foo]
|
||||
run foo(pid=[PID]): Launched [foo(pid=[PID])↪foo(pid=[PID])]
|
||||
stdout:
|
||||
(launched: [DATETIME])
|
||||
foo stdout
|
||||
[[$0], 'arg1', 'arg2']
|
||||
|
||||
stderr:
|
||||
(launched: [DATETIME])
|
||||
foo stderr
|
||||
|
||||
run foo(pid=[PID]): Terminating (SIGINT)
|
||||
run foo(pid=[PID]): DBG: Cleanup
|
||||
run foo(pid=[PID]): Terminated {rc=1}
|
||||
result: 1
|
||||
stdout:
|
||||
(launched: [DATETIME])
|
||||
foo stdout
|
||||
[[$0], 'arg1', 'arg2']
|
||||
Exiting (stdout)
|
||||
|
||||
stderr:
|
||||
(launched: [DATETIME])
|
||||
foo stderr
|
||||
Traceback (most recent call last):
|
||||
File [$0], line [LINE], in <module>
|
||||
time.sleep(1)
|
||||
KeyboardInterrupt
|
||||
Exiting (stderr)
|
||||
|
||||
done.
|
@ -0,0 +1,7 @@
|
||||
PATH='[^']*' PATH=[$PATH]
|
||||
/tmp/[^/ '"]* [TMP]
|
||||
pid=[0-9]* pid=[PID]
|
||||
....-..-.._..:..:.. [DATETIME]
|
||||
'[^']*/selftest/process_test/foo.py' [$0]
|
||||
"[^"]*/selftest/process_test/foo.py" [$0]
|
||||
, line [0-9]* , line [LINE]
|
@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import _prep
|
||||
import time
|
||||
import os
|
||||
|
||||
from osmo_gsm_tester import process, util, log
|
||||
|
||||
tmpdir = util.Dir(util.get_tempdir())
|
||||
|
||||
dollar_path = '%s:%s' % (
|
||||
os.path.join(os.getcwd(), 'process_test'),
|
||||
os.getenv('PATH'))
|
||||
|
||||
p = process.Process('foo', tmpdir, ('foo.py', 'arg1', 'arg2'),
|
||||
env={'PATH': dollar_path})
|
||||
|
||||
p.launch()
|
||||
time.sleep(.5)
|
||||
p.poll()
|
||||
print('stdout:')
|
||||
print(p.get_stdout())
|
||||
print('stderr:')
|
||||
print(p.get_stderr())
|
||||
|
||||
assert not p.terminated()
|
||||
p.terminate()
|
||||
assert p.terminated()
|
||||
print('result: %r' % p.result)
|
||||
|
||||
print('stdout:')
|
||||
print(p.get_stdout())
|
||||
print('stderr:')
|
||||
print(p.get_stderr())
|
||||
print('done.')
|
||||
|
||||
test_ssh = True
|
||||
test_ssh = False
|
||||
if test_ssh:
|
||||
# this part of the test requires ability to ssh to localhost
|
||||
p = process.RemoteProcess('localhost', '/tmp', 'ssh-test', tmpdir,
|
||||
('ls', '-al'))
|
||||
p.launch()
|
||||
p.wait()
|
||||
assert p.terminated()
|
||||
print('stdout:')
|
||||
print(p.get_stdout())
|
||||
print('stderr:')
|
||||
print(p.get_stderr())
|
||||
|
||||
# vim: expandtab tabstop=4 shiftwidth=4
|
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import atexit
|
||||
import time
|
||||
|
||||
|
||||
sys.stdout.write('foo stdout\n')
|
||||
sys.stderr.write('foo stderr\n')
|
||||
|
||||
print(repr(sys.argv))
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
||||
def x():
|
||||
sys.stdout.write('Exiting (stdout)\n')
|
||||
sys.stdout.flush()
|
||||
sys.stderr.write('Exiting (stderr)\n')
|
||||
sys.stderr.flush()
|
||||
atexit.register(x)
|
||||
|
||||
while True:
|
||||
time.sleep(1)
|
||||
|
||||
# vim: expandtab tabstop=4 shiftwidth=4
|
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import support
|
||||
import importlib.util
|
||||
|
||||
if hasattr(importlib.util, 'module_from_spec'):
|
||||
def run_test(path):
|
||||
print('py 3.5+')
|
||||
spec = importlib.util.spec_from_file_location("tests.script", path)
|
||||
spec.loader.exec_module( importlib.util.module_from_spec(spec) )
|
||||
else:
|
||||
def run_test(path):
|
||||
print('py 3.4-')
|
||||
from importlib.machinery import SourceFileLoader
|
||||
SourceFileLoader("tests.script", path).load_module()
|
||||
|
||||
path = './subdir/script.py'
|
||||
|
||||
support.config = 'specifics'
|
||||
run_test(path)
|
||||
|
||||
support.config = 'specifics2'
|
||||
run_test(path)
|
||||
|
@ -0,0 +1,9 @@
|
||||
from support import *
|
||||
|
||||
print('hello')
|
||||
|
||||
def run(what):
|
||||
print(what)
|
||||
print(what)
|
||||
|
||||
run(config)
|
@ -0,0 +1,2 @@
|
||||
|
||||
config = None
|
@ -0,0 +1,18 @@
|
||||
This a real gsm test suite configured and ready to use.
|
||||
The only thing missing is a trial dir containing binaries.
|
||||
|
||||
If you have your trial with binary tar archives in ~/my_trial
|
||||
you can run the suite for example like this:
|
||||
|
||||
. ./env # point your environment at all the right places
|
||||
run_once.py ~/my_trial -s sms:trx
|
||||
|
||||
This combines the suites/sms test suite with the scenarios/trx choice of
|
||||
osmo-bts-trx and runs all tests in the 'sms' suite.
|
||||
|
||||
A ./state dir will be created to store the current osmo-gsm-tester state. If
|
||||
you prefer not to write to this dir, set up an own configuration pointing at a
|
||||
different path (see paths.conf: 'state_dir' and the env file). When there is
|
||||
no OSMO_GSM_TESTER_CONF set (from ./env), osmo-gsm-tester will instead look for
|
||||
conf files in several locations like ~/.config/osmo-gsm-tester,
|
||||
/usr/local/etc/osmo-gsm-tester, /etc/osmo-gsm-tester
|
@ -0,0 +1,31 @@
|
||||
nitb:
|
||||
net:
|
||||
mcc: 1
|
||||
mnc: 868
|
||||
short_name: osmo-gsm-tester
|
||||
long_name: osmo-gsm-tester
|
||||
auth_policy: closed
|
||||
encryption: a5 0
|
||||
|
||||
nitb_bts:
|
||||
location_area_code: 23
|
||||
base_station_id_code: 63
|
||||
stream_id: 255
|
||||
trx_list:
|
||||
- max_power_red: 22
|
||||
arfcn: 868
|
||||
timeslot_list:
|
||||
- phys_chan_config: CCCH+SDCCH4
|
||||
- phys_chan_config: SDCCH8
|
||||
- phys_chan_config: TCH_F/TCH_H/PDCH
|
||||
- phys_chan_config: TCH_F/TCH_H/PDCH
|
||||
- phys_chan_config: TCH_F/TCH_H/PDCH
|
||||
- phys_chan_config: TCH_F/TCH_H/PDCH
|
||||
- phys_chan_config: TCH_F/TCH_H/PDCH
|
||||
- phys_chan_config: TCH_F/TCH_H/PDCH
|
||||
|
||||
osmo_bts_sysmo:
|
||||
ipa_unit_id: 1123
|
||||
|
||||
osmo_bts_trx:
|
||||
ipa_unit_id: 1124
|
@ -0,0 +1,4 @@
|
||||
OSMO_GSM_TESTER_SRC="$(readlink -f ../../src)"
|
||||
export PYTHONPATH="$OSMO_GSM_TESTER_SRC"
|
||||
export PATH="$OSMO_GSM_TESTER_SRC:$PATH"
|
||||
export OSMO_GSM_TESTER_CONF="$PWD"
|
@ -0,0 +1,3 @@
|
||||
state_dir: './state'
|
||||
suites_dir: './suites'
|
||||
scenarios_dir: './scenarios'
|
@ -0,0 +1,139 @@
|
||||
# all hardware and interfaces available to this osmo-gsm-tester
|
||||
|
||||
nitb_iface:
|
||||
- addr: 127.0.0.10
|
||||
- addr: 127.0.0.11
|
||||
- addr: 127.0.0.12
|
||||
|
||||
bts:
|
||||
- label: sysmoBTS 1002
|
||||
type: sysmo
|
||||
unit_id: 1
|
||||
addr: 10.42.42.114
|
||||
band: GSM-1800
|
||||
|
||||
- label: octBTS 3000
|
||||
type: oct
|
||||
unit_id: 5
|
||||
addr: 10.42.42.115
|
||||
band: GSM-1800
|
||||
trx:
|
||||
- hwaddr: 00:0c:90:32:b5:8a
|
||||
|
||||
- label: Ettus B210
|
||||
type: osmotrx
|
||||
unit_id: 6
|
||||
addr: 10.42.42.116
|
||||
band: GSM-1800
|
||||
|
||||
- label: nanoBTS 1900
|
||||
type: nanobts
|
||||
unit_id: 1902
|
||||
addr: 10.42.42.190
|
||||
band: GSM-1900
|
||||
trx:
|
||||
- hwaddr: 00:02:95:00:41:b3
|
||||
|
||||
arfcn:
|
||||
- arfcn: 512
|
||||
band: GSM-1800
|
||||
- arfcn: 514
|
||||
band: GSM-1800
|
||||
- arfcn: 516
|
||||
band: GSM-1800
|
||||
- arfcn: 518
|
||||
band: GSM-1800
|
||||
- arfcn: 520
|
||||
band: GSM-1800
|
||||
|
||||
- arfcn: 540
|
||||
band: GSM-1900
|
||||
- arfcn: 542
|
||||
band: GSM-1900
|
||||
- arfcn: 544
|
||||
band: GSM-1900
|
||||
- arfcn: 546
|
||||
band: GSM-1900
|
||||
- arfcn: 548
|
||||
band: GSM-1900
|
||||
|
||||
modem:
|
||||
- label: m7801
|
||||
path: '/wavecom_0'
|
||||
imsi: 901700000007801
|
||||
ki: D620F48487B1B782DA55DF6717F08FF9
|
||||
|
||||
- label: m7802
|
||||
path: '/wavecom_1'
|
||||
imsi: 901700000007802
|
||||
ki: 47FDB2D55CE6A10A85ABDAD034A5B7B3
|
||||
|
||||
- label: m7803
|
||||
path: '/wavecom_2'
|
||||
imsi: 901700000007803
|
||||
ki: ABBED4C91417DF710F60675B6EE2C8D2
|
||||
|
||||
- label: m7804
|
||||
path: '/wavecom_3'
|
||||
imsi: 901700000007804
|
||||
ki: 8BA541179156F2BF0918CA3CFF9351B0
|
||||
|
||||
- label: m7805
|
||||
path: '/wavecom_4'
|
||||
imsi: 901700000007805
|
||||
ki: 82BEC24B5B50C9FAA69D17DEC0883A23
|
||||
|
||||
- label: m7806
|
||||
path: '/wavecom_5'
|
||||
imsi: 901700000007806
|
||||
ki: DAF6BD6A188F7A4F09866030BF0F723D
|
||||
|
||||
- label: m7807
|
||||
path: '/wavecom_6'
|
||||
imsi: 901700000007807
|
||||
ki: AEB411CFE39681A6352A1EAE4DDC9DBA
|
||||
|
||||
- label: m7808
|
||||
path: '/wavecom_7'
|
||||
imsi: 901700000007808
|
||||
ki: F5DEF8692B305D7A65C677CA9EEE09C4
|
||||
|
||||
- label: m7809
|
||||
path: '/wavecom_8'
|
||||
imsi: 901700000007809
|
||||
ki: A644F4503E812FD75329B1C8D625DA44
|
||||
|
||||
- label: m7810
|
||||
path: '/wavecom_9'
|
||||
imsi: 901700000007810
|
||||
ki: EF663BDF3477DCD18D3D2293A2BAED67
|
||||
|
||||
- label: m7811
|
||||
path: '/wavecom_10'
|
||||
imsi: 901700000007811
|
||||
ki: E88F37F048A86A9BC4D652539228C039
|
||||
|
||||
- label: m7812
|
||||
path: '/wavecom_11'
|
||||
imsi: 901700000007812
|
||||
ki: E8D940DD66FCF6F1CD2C0F8F8C45633D
|
||||
|
||||
- label: m7813
|
||||
path: '/wavecom_12'
|
||||
imsi: 901700000007813
|
||||
ki: DBF534700C10141C49F699B0419107E3
|
||||
|
||||
- label: m7814
|
||||
path: '/wavecom_13'
|
||||
imsi: 901700000007814
|
||||
ki: B36021DEB90C4EA607E408A92F3B024D
|
||||
|
||||
- label: m7815
|
||||
path: '/wavecom_14'
|
||||
imsi: 901700000007815
|
||||
ki: 1E209F6F839F9195778C4F96BE281A24
|
||||
|
||||
- label: m7816
|
||||
path: '/wavecom_15'
|
||||
imsi: 901700000007816
|
||||
ki: BF827D219E739DD189F6F59E60D6455C
|
@ -0,0 +1,3 @@
|
||||
resources:
|
||||
bts:
|
||||
- type: osmotrx
|
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python3
|
||||
from osmo_gsm_tester.test import *
|
||||
|
||||
print('use resources...')
|
||||
nitb = suite.nitb()
|
||||
bts = suite.bts()
|
||||
ms_mo = suite.modem()
|
||||
ms_mt = suite.modem()
|
||||
|
||||
print('start nitb and bts...')
|
||||
nitb.add_bts(bts)
|
||||
nitb.start()
|
||||
sleep(.1)
|
||||
assert nitb.running()
|
||||
bts.start()
|
||||
|
||||
nitb.add_subscriber(ms_mo)
|
||||
nitb.add_subscriber(ms_mt)
|
||||
|
||||
ms_mo.connect(nitb)
|
||||
ms_mt.connect(nitb)
|
||||
wait(nitb.subscriber_attached, ms_mo, ms_mt)
|
||||
|
||||
sms = ms_mo.sms_send(ms_mt.msisdn)
|
||||
sleep(3)
|
||||
wait(nitb.sms_received, sms)
|
@ -0,0 +1,10 @@
|
||||
resources:
|
||||
nitb_iface:
|
||||
- times: 1
|
||||
bts:
|
||||
- times: 1
|
||||
modem:
|
||||
- times: 2
|
||||
|
||||
defaults:
|
||||
timeout: 60s
|
@ -0,0 +1,207 @@
|
||||
- expect solutions:
|
||||
[0, 1, 2]
|
||||
[0, 1, 2]
|
||||
[1, 0, 2]
|
||||
[1, 2, 0]
|
||||
- expect failure to solve:
|
||||
The requested resource requirements are not solvable [[0, 2], [2], [0, 2]]
|
||||
- test removing a Resources list from itself
|
||||
ok, caused exception: RuntimeError('Refusing to drop a list of resources from itself. This is probably a bug where a list of Resources() should have been copied but is passed as-is. use Resources.clear() instead.',)
|
||||
- test removing a Resources list from one with the same list in it
|
||||
- test resources config and state dir:
|
||||
*** all resources:
|
||||
{'arfcn': [{'_hash': 'e620569450f8259b3f0212ec19c285dd07df063c',
|
||||
'arfcn': '512',
|
||||
'band': 'GSM-1800'},
|
||||
{'_hash': '022621e513c5a5bf33b77430a1e9c886be676fa1',
|
||||
'arfcn': '514',
|
||||
'band': 'GSM-1800'},
|
||||
{'_hash': '3199abf375a1dd899e554e9d63a552e06d7f38bf',
|
||||
'arfcn': '516',
|
||||
'band': 'GSM-1800'},
|
||||
{'_hash': '57aa7bd1da62495f2857ae6b859193dd592a0a02',
|
||||
'arfcn': '518',
|
||||
'band': 'GSM-1800'},
|
||||
{'_hash': '53dd2e2682b736f427abd2ce59a9a50ca8130678',
|
||||
'arfcn': '520',
|
||||
'band': 'GSM-1800'},
|
||||
{'_hash': '31687a5e6d5140a4b3877606ca5f18244f11d706',
|
||||
'arfcn': '540',
|
||||
'band': 'GSM-1900'},
|
||||
{'_hash': '1def43a5c88a83cdb21279eacab0679ea08ffaf3',
|
||||
'arfcn': '542',
|
||||
'band': 'GSM-1900'},
|
||||
{'_hash': '1d6e3b08a3861fd4d748f111295ec5a93ecd3d23',
|
||||
'arfcn': '544',
|
||||
'band': 'GSM-1900'},
|
||||
{'_hash': '8fb36927de15466fcdbee01f7f65704c312cb36c',
|
||||
'arfcn': '546',
|
||||
'band': 'GSM-1900'},
|
||||
{'_hash': 'dc9ce027a257da087f31a5bc1ee6b4abd2637369',
|
||||
'arfcn': '548',
|
||||
'band': 'GSM-1900'}],
|
||||
'bts': [{'_hash': 'a7c6d2ebaeb139e8c2e7d45c3495d046d7439007',
|
||||
'addr': '10.42.42.114',
|
||||
'band': 'GSM-1800',
|
||||
'label': 'sysmoBTS 1002',
|
||||
'type': 'sysmo',
|
||||
'unit_id': '1'},
|
||||
{'_hash': '02540ab9eb556056a0b4d28443bc9f4793f6d549',
|
||||
'addr': '10.42.42.115',
|
||||
'band': 'GSM-1800',
|
||||
'label': 'octBTS 3000',
|
||||
'trx': [{'hwaddr': '00:0c:90:32:b5:8a'}],
|
||||
'type': 'oct',
|
||||
'unit_id': '5'},
|
||||
{'_hash': '556c954d475d12cf0dc622c0df5743cac5543fa0',
|
||||
'addr': '10.42.42.190',
|
||||
'band': 'GSM-1900',
|
||||
'label': 'nanoBTS 1900',
|
||||
'trx': [{'hwaddr': '00:02:95:00:41:b3'}],
|
||||
'type': 'nanobts',
|
||||
'unit_id': '1902'}],
|
||||
'modem': [{'_hash': '19c69e45aa090fb511446bd00797690aa82ff52f',
|
||||
'imsi': '901700000007801',
|
||||
'ki': 'D620F48487B1B782DA55DF6717F08FF9',
|
||||
'label': 'm7801',
|
||||
'path': '/wavecom_0'},
|
||||
{'_hash': 'e1a46516a1fb493b2617ab14fc1693a9a45ec254',
|
||||
'imsi': '901700000007802',
|
||||
'ki': '47FDB2D55CE6A10A85ABDAD034A5B7B3',
|
||||
'label': 'm7802',
|
||||
'path': '/wavecom_1'},
|
||||
{'_hash': '4fe91500a309782bb0fd8ac6fc827834089f8b00',
|
||||
'imsi': '901700000007803',
|
||||
'ki': 'ABBED4C91417DF710F60675B6EE2C8D2',
|
||||
'label': 'm7803',
|
||||
'path': '/wavecom_2'},
|
||||
{'_hash': 'c895badf0c2faaa4a997cd9f2313b5ebda7486e4',
|
||||
'imsi': '901700000007804',
|
||||
'ki': '8BA541179156F2BF0918CA3CFF9351B0',
|
||||
'label': 'm7804',
|
||||
'path': '/wavecom_3'},
|
||||
{'_hash': '60f182abed05adb530e3d06d88cc47703b65d7d8',
|
||||
'imsi': '901700000007805',
|
||||
'ki': '82BEC24B5B50C9FAA69D17DEC0883A23',
|
||||
'label': 'm7805',
|
||||
'path': '/wavecom_4'},
|
||||
{'_hash': 'd1f0fbf089a4bf32dd566af956d23b89e3d60821',
|
||||
'imsi': '901700000007806',
|
||||
'ki': 'DAF6BD6A188F7A4F09866030BF0F723D',
|
||||
'label': 'm7806',
|
||||
'path': '/wavecom_5'},
|
||||
{'_hash': '2445e3b5949d15f4351c0db1d3f3f593f9d73aa5',
|
||||
'imsi': '901700000007807',
|
||||
'ki': 'AEB411CFE39681A6352A1EAE4DDC9DBA',
|
||||
'label': 'm7807',
|
||||
'path': '/wavecom_6'},
|
||||
{'_hash': '80247388b2ca382382c4aec678102355b7922965',
|
||||
'imsi': '901700000007808',
|
||||
'ki': 'F5DEF8692B305D7A65C677CA9EEE09C4',
|
||||
'label': 'm7808',
|
||||
'path': '/wavecom_7'},
|
||||
{'_hash': '5b9e4e117a8889430542d22a9693e7b999362856',
|
||||
'imsi': '901700000007809',
|
||||
'ki': 'A644F4503E812FD75329B1C8D625DA44',
|
||||
'label': 'm7809',
|
||||
'path': '/wavecom_8'},
|
||||
{'_hash': '219a7abb057050eef3ce4b99c487f32bbaae9a41',
|
||||
'imsi': '901700000007810',
|
||||
'ki': 'EF663BDF3477DCD18D3D2293A2BAED67',
|
||||
'label': 'm7810',
|
||||
'path': '/wavecom_9'},
|
||||
{'_hash': '75d45c2d975b893da34c7cae827c25a2039cecd2',
|
||||
'imsi': '901700000007811',
|
||||
'ki': 'E88F37F048A86A9BC4D652539228C039',
|
||||
'label': 'm7811',
|
||||
'path': '/wavecom_10'},
|
||||
{'_hash': '1777362f556b249a5c1d6a83110704dbd037bc20',
|
||||
'imsi': '901700000007812',
|
||||
'ki': 'E8D940DD66FCF6F1CD2C0F8F8C45633D',
|
||||
'label': 'm7812',
|
||||
'path': '/wavecom_11'},
|
||||
{'_hash': '21d7eb4b0c782e004821a9f7f778891c93956924',
|
||||
'imsi': '901700000007813',
|
||||
'ki': 'DBF534700C10141C49F699B0419107E3',
|
||||
'label': 'm7813',
|
||||
'path': '/wavecom_12'},
|
||||
{'_hash': 'f53e4e79bdbc63eb2845de671007d4f733f28409',
|
||||
'imsi': '901700000007814',
|
||||
'ki': 'B36021DEB90C4EA607E408A92F3B024D',
|
||||
'label': 'm7814',
|
||||
'path': '/wavecom_13'},
|
||||
{'_hash': 'df1abec7704ebc89b2c062a69bd299cf3663ed9e',
|
||||
'imsi': '901700000007815',
|
||||
'ki': '1E209F6F839F9195778C4F96BE281A24',
|
||||
'label': 'm7815',
|
||||
'path': '/wavecom_14'},
|
||||
{'_hash': '11df1e4c7708157e5b89020c757763f58d6e610b',
|
||||
'imsi': '901700000007816',
|
||||
'ki': 'BF827D219E739DD189F6F59E60D6455C',
|
||||
'label': 'm7816',
|
||||
'path': '/wavecom_15'}],
|
||||
'nitb_iface': [{'_hash': 'cde1debf28f07f94f92c761b4b7c6bf35785ced4',
|
||||
'addr': '10.42.42.1'},
|
||||
{'_hash': 'fd103b22c7cf2480d609150e06f4bbd92ac78d8c',
|
||||
'addr': '10.42.42.2'},
|
||||
{'_hash': '1c614d6210c551d142aadca8f25e1534ebb2a70f',
|
||||
'addr': '10.42.42.3'}]}
|
||||
*** end: all resources
|
||||
|
||||
- request some resources
|
||||
--- (want='nitb_iface'): DBG: Looking for 1 x nitb_iface , candidates: 3
|
||||
--- (want='arfcn'): DBG: Looking for 2 x arfcn , candidates: 10
|
||||
--- (want='bts'): DBG: Looking for 2 x bts , candidates: 3
|
||||
--- (want='modem'): DBG: Looking for 2 x modem , candidates: 16
|
||||
~~~ currently reserved:
|
||||
arfcn:
|
||||
- _hash: e620569450f8259b3f0212ec19c285dd07df063c
|
||||
_reserved_by: testowner-123-1490837279
|
||||
arfcn: '512'
|
||||
band: GSM-1800
|
||||
- _hash: 022621e513c5a5bf33b77430a1e9c886be676fa1
|
||||
_reserved_by: testowner-123-1490837279
|
||||
arfcn: '514'
|
||||
band: GSM-1800
|
||||
bts:
|
||||
- _hash: a7c6d2ebaeb139e8c2e7d45c3495d046d7439007
|
||||
_reserved_by: testowner-123-1490837279
|
||||
addr: 10.42.42.114
|
||||
band: GSM-1800
|
||||
label: sysmoBTS 1002
|
||||
type: sysmo
|
||||
unit_id: '1'
|
||||
- _hash: 02540ab9eb556056a0b4d28443bc9f4793f6d549
|
||||
_reserved_by: testowner-123-1490837279
|
||||
addr: 10.42.42.115
|
||||
band: GSM-1800
|
||||
label: octBTS 3000
|
||||
trx:
|
||||
- hwaddr: 00:0c:90:32:b5:8a
|
||||
type: oct
|
||||
unit_id: '5'
|
||||
modem:
|
||||
- _hash: 19c69e45aa090fb511446bd00797690aa82ff52f
|
||||
_reserved_by: testowner-123-1490837279
|
||||
imsi: '901700000007801'
|
||||
ki: D620F48487B1B782DA55DF6717F08FF9
|
||||
label: m7801
|
||||
path: /wavecom_0
|
||||
- _hash: e1a46516a1fb493b2617ab14fc1693a9a45ec254
|
||||
_reserved_by: testowner-123-1490837279
|
||||
imsi: '901700000007802'
|
||||
ki: 47FDB2D55CE6A10A85ABDAD034A5B7B3
|
||||
label: m7802
|
||||
path: /wavecom_1
|
||||
nitb_iface:
|
||||
- _hash: cde1debf28f07f94f92c761b4b7c6bf35785ced4
|
||||
_reserved_by: testowner-123-1490837279
|
||||
addr: 10.42.42.1
|
||||
|
||||
~~~ end: currently reserved
|
||||
|
||||
~~~ currently reserved:
|
||||
{}
|
||||
|
||||
~~~ end: currently reserved
|
||||
|
@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import tempfile
|
||||
import os
|
||||
import pprint
|
||||
import shutil
|
||||
import atexit
|
||||
import _prep
|
||||
from osmo_gsm_tester import config, log, resource, util
|
||||
|
||||
workdir = util.get_tempdir()
|
||||
|
||||
# override config locations to make sure we use only the test conf
|
||||
config.ENV_CONF = './conf'
|
||||
|
||||
log.get_process_id = lambda: '123-1490837279'
|
||||
|
||||
print('- expect solutions:')
|
||||
pprint.pprint(
|
||||
resource.solve([ [0, 1, 2],
|
||||
[0, 1, 2],
|
||||
[0, 1, 2] ]) )
|
||||
pprint.pprint(
|
||||
resource.solve([ [0, 1, 2],
|
||||
[0, 1],
|
||||
[0, 2] ]) ) # == [0, 1, 2]
|
||||
pprint.pprint(
|
||||
resource.solve([ [0, 1, 2],
|
||||
[0],
|
||||
[0, 2] ]) ) # == [1, 0, 2]
|
||||
pprint.pprint(
|
||||
resource.solve([ [0, 1, 2],
|
||||
[2],
|
||||
[0, 2] ]) ) # == [1, 2, 0]
|
||||
|
||||
print('- expect failure to solve:')
|
||||
try:
|
||||
resource.solve([ [0, 2],
|
||||
[2],
|
||||
[0, 2] ])
|
||||
assert False
|
||||
except resource.NoResourceExn as e:
|
||||
print(e)
|
||||
|
||||
print('- test removing a Resources list from itself')
|
||||
try:
|
||||
r = resource.Resources({ 'k': [ {'a': 1, 'b': 2}, {'a': 3, 'b': 4}, ],
|
||||
'i': [ {'c': 1, 'd': 2}, {'c': 3, 'd': 4}, ] })
|
||||
r.drop(r)
|
||||
assert False
|
||||
except RuntimeError as e:
|
||||
print('ok, caused exception: %r' % e)
|
||||
|
||||
print('- test removing a Resources list from one with the same list in it')
|
||||
r = resource.Resources({ 'k': [ {'a': 1, 'b': 2}, {'a': 3, 'b': 4}, ],
|
||||
'i': [ {'c': 1, 'd': 2}, {'c': 3, 'd': 4}, ] })
|
||||
r.drop({ 'k': r.get('k'), 'i': r.get('i') })
|
||||
assert not r
|
||||
|
||||
print('- test resources config and state dir:')
|
||||
resources_conf = os.path.join(_prep.script_dir, 'resource_test', 'etc',
|
||||
'resources.conf')
|
||||
|
||||
state_dir = config.get_state_dir()
|
||||
rrfile = state_dir.child(resource.RESERVED_RESOURCES_FILE)
|
||||
|
||||
pool = resource.ResourcesPool()
|
||||
|
||||
print('*** all resources:')
|
||||
pprint.pprint(pool.all_resources)
|
||||
print('*** end: all resources\n')
|
||||
|
||||
print('- request some resources')
|
||||
want = {
|
||||
'nitb_iface': [ { 'times': 1 } ],
|
||||
'bts': [ { 'type': 'sysmo', 'times': 1 }, { 'type': 'oct', 'times': 1 } ],
|
||||
'arfcn': [ { 'band': 'GSM-1800', 'times': 2 } ],
|
||||
'modem': [ { 'times': 2 } ],
|
||||
}
|
||||
|
||||
origin = log.Origin('testowner')
|
||||
|
||||
resources = pool.reserve(origin, want)
|
||||
|
||||
print('~~~ currently reserved:')
|
||||
with open(rrfile, 'r') as f:
|
||||
print(f.read())
|
||||
print('~~~ end: currently reserved\n')
|
||||
|
||||
resources.free()
|
||||
|
||||
print('~~~ currently reserved:')
|
||||
with open(rrfile, 'r') as f:
|
||||
print(f.read())
|
||||
print('~~~ end: currently reserved\n')
|
||||
|
||||
# vim: expandtab tabstop=4 shiftwidth=4
|
@ -0,0 +1,40 @@
|
||||
- non-existing suite dir
|
||||
--- -: ERR: RuntimeError: Suite not found: 'does_not_exist' in ./suite_test
|
||||
- no suite.conf
|
||||
cnf empty_dir: DBG: reading suite.conf [empty_dir↪empty_dir]
|
||||
--- ./suite_test/empty_dir/suite.conf: ERR: FileNotFoundError: [Errno 2] No such file or directory: './suite_test/empty_dir/suite.conf' [empty_dir↪./suite_test/empty_dir/suite.conf]
|
||||
- valid suite dir
|
||||
cnf test_suite: DBG: reading suite.conf [test_suite↪test_suite]
|
||||
defaults:
|
||||
timeout: 60s
|
||||
resources:
|
||||
bts:
|
||||
- times: '1'
|
||||
modem:
|
||||
- times: '2'
|
||||
nitb_iface:
|
||||
- times: '1'
|
||||
|
||||
- run hello world test
|
||||
tst test_suite: reserving resources...
|
||||
--- (want='nitb_iface'): DBG: Looking for 1 x nitb_iface , candidates: 3
|
||||
--- (want='modem'): DBG: Looking for 2 x modem , candidates: 16
|
||||
--- (want='bts'): DBG: Looking for 1 x bts , candidates: 3
|
||||
tst hello_world.py: START [test_suite↪hello_world.py]
|
||||
tst hello_world.py:3: hello world [test_suite↪hello_world.py:3]
|
||||
tst hello_world.py:4: I am 'test_suite' / 'hello_world.py:4' [test_suite↪hello_world.py:4]
|
||||
tst hello_world.py:5: one [test_suite↪hello_world.py:5]
|
||||