blob: 13cce9760860011d768e7f411d4c0e09eb45a49f [file] [log] [blame]
Neels Hofmeyr3531a192017-03-28 14:30:28 +02001#!/usr/bin/env python3
2
3import tempfile
4import os
Pau Espin Pedrolab1904a2020-05-06 18:35:26 +02005import sys
Neels Hofmeyr3531a192017-03-28 14:30:28 +02006import pprint
7import shutil
8import atexit
Pau Espin Pedrol600c7992020-11-09 21:17:51 +01009import time
10import threading
Neels Hofmeyr3531a192017-03-28 14:30:28 +020011import _prep
Pau Espin Pedrol06cb5362020-05-04 18:58:53 +020012from osmo_gsm_tester.core import config, log, util, resource
Pau Espin Pedrolea8c3d42020-05-04 12:05:05 +020013from osmo_gsm_tester.core.schema import generate_schemas
Neels Hofmeyr3531a192017-03-28 14:30:28 +020014
15workdir = util.get_tempdir()
16
17# override config locations to make sure we use only the test conf
Pau Espin Pedrol6c6c0e82020-05-11 18:30:58 +020018config.override_conf = os.path.join(os.path.dirname(sys.argv[0]), 'conf', 'paths.conf')
Neels Hofmeyr3531a192017-03-28 14:30:28 +020019
20log.get_process_id = lambda: '123-1490837279'
21
Pau Espin Pedrolea8c3d42020-05-04 12:05:05 +020022# Generate supported schemas dynamically from objects:
23generate_schemas()
24
Neels Hofmeyr3531a192017-03-28 14:30:28 +020025print('- expect solutions:')
26pprint.pprint(
27 resource.solve([ [0, 1, 2],
28 [0, 1, 2],
29 [0, 1, 2] ]) )
30pprint.pprint(
31 resource.solve([ [0, 1, 2],
32 [0, 1],
33 [0, 2] ]) ) # == [0, 1, 2]
34pprint.pprint(
35 resource.solve([ [0, 1, 2],
36 [0],
37 [0, 2] ]) ) # == [1, 0, 2]
38pprint.pprint(
39 resource.solve([ [0, 1, 2],
40 [2],
41 [0, 2] ]) ) # == [1, 2, 0]
42
43print('- expect failure to solve:')
44try:
45 resource.solve([ [0, 2],
46 [2],
Pau Espin Pedrol32e33722017-09-04 16:35:02 +020047 [0, 2] ])
Neels Hofmeyr3531a192017-03-28 14:30:28 +020048 assert False
Neels Hofmeyra8a05a22017-06-06 19:47:40 +020049except resource.NotSolvable as e:
Neels Hofmeyr3531a192017-03-28 14:30:28 +020050 print(e)
51
52print('- test removing a Resources list from itself')
53try:
54 r = resource.Resources({ 'k': [ {'a': 1, 'b': 2}, {'a': 3, 'b': 4}, ],
55 'i': [ {'c': 1, 'd': 2}, {'c': 3, 'd': 4}, ] })
56 r.drop(r)
57 assert False
58except RuntimeError as e:
Pau Espin Pedrolafa2fc32020-05-06 17:29:50 +020059 print('ok, caused exception RuntimeError: %s' % str(e))
Neels Hofmeyr3531a192017-03-28 14:30:28 +020060
61print('- test removing a Resources list from one with the same list in it')
62r = resource.Resources({ 'k': [ {'a': 1, 'b': 2}, {'a': 3, 'b': 4}, ],
63 'i': [ {'c': 1, 'd': 2}, {'c': 3, 'd': 4}, ] })
64r.drop({ 'k': r.get('k'), 'i': r.get('i') })
65assert not r
66
67print('- test resources config and state dir:')
68resources_conf = os.path.join(_prep.script_dir, 'resource_test', 'etc',
69 'resources.conf')
70
71state_dir = config.get_state_dir()
72rrfile = state_dir.child(resource.RESERVED_RESOURCES_FILE)
73
74pool = resource.ResourcesPool()
75
76print('*** all resources:')
77pprint.pprint(pool.all_resources)
78print('*** end: all resources\n')
79
80print('- request some resources')
81want = {
Neels Hofmeyr76d81032017-05-18 18:35:32 +020082 'ip_address': [ { 'times': 1 } ],
Pau Espin Pedrol438a3082017-08-28 14:31:28 +020083 'bts': [ { 'type': 'osmo-bts-sysmo', 'times': 1 , 'ciphers': ['a5_1']}, { 'type': 'osmo-bts-trx', 'times': 1 } ],
Neels Hofmeyr3531a192017-03-28 14:30:28 +020084 'arfcn': [ { 'band': 'GSM-1800', 'times': 2 } ],
Pau Espin Pedrol438a3082017-08-28 14:31:28 +020085 'modem': [ { 'times': 2 , 'ciphers': ['a5_0', 'a5_1']} ],
Neels Hofmeyr3531a192017-03-28 14:30:28 +020086 }
Pau Espin Pedrolaab56922018-08-21 14:58:29 +020087modifiers = {
88 'bts': [ {}, {'num_trx': 2 }],
89}
Neels Hofmeyr1a7a3f02017-06-10 01:18:27 +020090origin = log.Origin(None, 'testowner')
Neels Hofmeyr3531a192017-03-28 14:30:28 +020091
Pau Espin Pedrolaab56922018-08-21 14:58:29 +020092resources = pool.reserve(origin, config.replicate_times(want), config.replicate_times(modifiers))
Neels Hofmeyr3531a192017-03-28 14:30:28 +020093
94print('~~~ currently reserved:')
95with open(rrfile, 'r') as f:
96 print(f.read())
97print('~~~ end: currently reserved\n')
98
Pau Espin Pedrolaab56922018-08-21 14:58:29 +020099print('~~~ with modifiers:')
100print(repr(resources))
101print('~~~ end: with modifiers:')
102
Neels Hofmeyr3531a192017-03-28 14:30:28 +0200103resources.free()
104
105print('~~~ currently reserved:')
106with open(rrfile, 'r') as f:
107 print(f.read())
108print('~~~ end: currently reserved\n')
109
Pau Espin Pedrol58475512017-09-14 15:33:15 +0200110print('- item_matches:')
111superset = { 'hello': 'world', 'foo': 'bar', 'ordered_list': [{'xkey': 'xvalue'},{'ykey': 'yvalue'}], 'unordered_list_set': [1, 2, 3]}
112
113subset = { 'foo': 'bar', 'ordered_list': [{'xkey': 'xvalue'},{'ykey': 'yvalue'}], 'unordered_list_set': [2, 1] }
114if resource.item_matches(superset, subset):
115 print('1st subset matches correctly, pass')
116
117subset = { 'ordered_list': [{},{'ykey': 'yvalue'}], 'unordered_list_set': [] }
118if resource.item_matches(superset, subset):
119 print('2nd subset matches correctly, pass')
120
121subset = { 'ordered_list': [{'ykey': 'yvalue'}, {'xkey': 'xvalue'}] }
122if not resource.item_matches(superset, subset):
123 print('3rd subset should not match, pass')
124
125subset = { 'ordered_list': [{'xkey': 'xvalue'}, {'ykey': 'yvalue'}, {'zkey': 'zvalue'}] }
126if not resource.item_matches(superset, subset):
127 print('3rd subset should not match, pass')
128
129subset = { 'unordered_list_set': [4] }
130if not resource.item_matches(superset, subset):
131 print('4th subset should not match, pass')
132
Pau Espin Pedrol600c7992020-11-09 21:17:51 +0100133print('*** concurrent allocation:')
134origin1 = log.Origin(None, 'testowner1')
135origin2 = log.Origin(None, 'testowner2')
136# We disable dbg() for second thread since FileWatch output result is
137# non-deterministic, since sometimes 1 Modiffied event is triggered, sometimes 2.
138origin1.dbg = origin2.dbg = lambda obj, *messages, _src=3, **named_items: None
139resources2 = None
140def second_ogt_instance():
141 # should block here until "resources" are freed.
142 print('- 2nd instance reserve() start')
143 resources2 = pool.reserve(origin2, config.replicate_times(want), config.replicate_times(modifiers))
144 print('- 2nd instance reserve() done')
145 resources2.free()
146resources = pool.reserve(origin1, config.replicate_times(want), config.replicate_times(modifiers))
147th = threading.Thread(target=second_ogt_instance)
148th.start()
149time.sleep(1.0)
150print('- 1st instance free()')
151resources.free()
152th.join()
153print('*** end: concurrent allocation')
154
Neels Hofmeyr3531a192017-03-28 14:30:28 +0200155# vim: expandtab tabstop=4 shiftwidth=4