7 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
8 from unittest import TestCase
9 from optparse import OptionParser
10 from sfa.util.xrn import get_authority
11 from sfa.util.config import *
12 from sfa.trust.certificate import *
13 from sfa.trust.credential import *
14 from sfa.trust.sfaticket import SfaTicket
15 from sfa.client import sfi
17 def random_string(size):
18 return "".join(random.sample(string.letters, size))
29 def __init__(self, options):
30 try: self.config = config = Config(options.config_file)
32 print "failed to read config_file %s" % options.config_file
34 key_path = os.path.dirname(options.config_file)
35 user_name = self.config.SFI_USER.split('.')[-1:][0]
36 key_file = key_path + os.sep + user_name + '.pkey'
37 cert_file = key_path + os.sep + user_name + '.cert'
38 self.key = Keypair(filename=key_file)
39 self.cert = Certificate(subject=self.config.SFI_USER)
40 self.cert.set_pubkey(self.key)
41 self.cert.set_issuer(self.key, self.config.SFI_USER)
43 self.cert.save_to_file(cert_file)
44 SFI_AGGREGATE = config.SFI_SM.replace('12347', '12346')
45 SFI_CM = 'http://' + options.cm_host + ':12346'
46 self.registry = xmlrpcprotocol.server_proxy(config.SFI_REGISTRY, key_file, cert_file)
47 self.aggregate = xmlrpcprotocol.server_proxy(SFI_AGGREGATE, key_file, cert_file)
48 self.sm = xmlrpcprotocol.server_proxy(config.SFI_SM, key_file, cert_file)
49 self.cm = xmlrpcprotocol.server_proxy(SFI_CM, key_file, cert_file)
50 self.hrn = config.SFI_USER
51 # XX defaulting to user, but this should be configurable so we can
52 # test from components persepctive
54 self.credential = self.get_credential(self.hrn)
56 def get_credential(self, hrn = None, type = 'user'):
57 if not hrn: hrn = self.hrn
59 cert = self.cert.save_to_string(save_parents=True)
60 request_hash = self.key.compute_hash([cert, 'user', hrn])
61 credential = self.registry.get_self_credential(cert, type, hrn, request_hash)
64 if not self.credential:
65 self.credential = self.get_credential(self.hrn, 'user')
66 return self.registry.get_credential(self.credential, type, hrn)
68 class BasicTestCase(unittest.TestCase):
69 def __init__(self, testname, client, test_slice=None):
70 unittest.TestCase.__init__(self, testname)
72 self.slice = test_slice
75 self.registry = self.client.registry
76 self.aggregate = self.client.aggregate
77 self.sm = self.client.sm
78 self.cm = self.client.cm
79 self.credential = self.client.credential
80 self.hrn = self.client.hrn
81 self.type = self.client.type
84 class RegistryTest(BasicTestCase):
88 Make sure test records dont exsit
90 BasicTestCase.setUp(self)
92 def testGetSelfCredential(self):
93 cred = self.client.get_credential()
94 # this will raise an openssl error if the credential string isnt valid
95 Credential(string=cred)
97 def testRegister(self):
98 authority = get_authority(self.hrn)
99 auth_cred = self.client.get_credential(authority, 'authority')
100 auth_record = {'hrn': '.'.join([authority, random_string(10).lower()]),
102 node_record = {'hrn': '.'.join([authority, random_string(10)]),
104 'hostname': random_string(6) + '.' + random_string(6)}
105 slice_record = {'hrn': '.'.join([authority, random_string(10)]),
106 'type': 'slice', 'researcher': [self.hrn]}
107 user_record = {'hrn': '.'.join([authority, random_string(10)]),
109 'email': random_string(6) +'@'+ random_string(5) +'.'+ random_string(3),
110 'first_name': random_string(7),
111 'last_name': random_string(7)}
113 all_records = [auth_record, node_record, slice_record, user_record]
114 for record in all_records:
116 self.registry.register(auth_cred, record)
117 self.registry.resolve(self.credential, record['hrn'])
121 try: self.registry.remove(auth_cred, record['type'], record['hrn'])
125 def testRegisterPeerObject(self):
128 def testUpdate(self):
129 authority = get_authority(self.hrn)
130 auth_cred = self.client.get_credential(authority, 'authority')
131 records = self.registry.resolve(self.credential, self.hrn)
132 if not records: assert False
134 self.registry.update(auth_cred, record)
136 def testResolve(self):
137 authority = get_authority(self.hrn)
138 self.registry.resolve(self.credential, self.hrn)
140 def testRemove(self):
141 authority = get_authority(self.hrn)
142 auth_cred = self.client.get_credential(authority, 'authority')
143 record = {'hrn': ".".join([authority, random_string(10)]),
145 self.registry.register(auth_cred, record)
146 self.registry.remove(auth_cred, record['type'], record['hrn'])
147 # should generate an exception
149 self.registry.resolve(self.credential, record['hrn'])
154 def testRemovePeerObject(self):
158 authority = get_authority(self.client.hrn)
159 self.registry.list(self.credential, authority)
161 def testGetRegistries(self):
162 self.registry.get_registries(self.credential)
164 def testGetAggregates(self):
165 self.registry.get_aggregates(self.credential)
167 def testGetTrustedCerts(self):
168 # this should fail unless we are a node
169 callable = self.registry.get_trusted_certs
170 server_exception = False
172 callable(self.credential)
173 except xmlrpcprotocol.ServerException:
174 server_exception = True
176 if self.type in ['user'] and not server_exception:
180 class AggregateTest(BasicTestCase):
182 BasicTestCase.setUp(self)
184 def testGetSlices(self):
185 self.aggregate.ListSlices(self.credential)
187 def testGetResources(self):
188 # available resources
189 agg_rspec = self.aggregate.get_resources(self.credential)
190 # resources used by a slice
191 slice_rspec = self.aggregate.get_resources(self.credential, self.slice['hrn'])
192 # will raise an exception if the rspec isnt valid
194 RSpec(xml=slice_rspec)
196 def testCreateSlice(self):
197 # get availabel resources
198 rspec = self.aggregate.get_resources(self.credential)
199 slice_credential = self.client.get_credential(self.slice['hrn'], 'slice')
200 self.aggregate.CreateSliver(slice_credential, self.slice['hrn'], rspec)
202 def testDeleteSlice(self):
203 slice_credential = self.client.get_credential(self.slice['hrn'], 'slice')
204 self.aggregate.DeleteSliver(slice_credential, self.slice['hrn'],"call-id-delete-slice")
206 def testGetTicket(self):
207 slice_credential = self.client.get_credential(self.slice['hrn'], 'slice')
208 rspec = self.aggregate.get_resources(self.credential)
209 ticket = self.aggregate.get_ticket(slice_credential, self.slice['hrn'], rspec)
210 # will raise an exception if the ticket inst valid
211 SfaTicket(string=ticket)
213 class SlicemgrTest(AggregateTest):
215 AggregateTest.setUp(self)
217 # force calls to go through slice manager
218 self.aggregate = self.sm
220 # get the slice credential
223 class ComponentTest(BasicTestCase):
225 BasicTestCase.setUp(self)
226 self.slice_cred = self.client.get_credential(self.slice['hrn'], 'slice')
228 def testStartSlice(self):
229 self.cm.start_slice(self.slice_cred, self.slice['hrn'])
231 def testStopSlice(self):
232 self.cm.stop_slice(self.slice_cred, self.slice['hrn'])
234 def testDeleteSlice(self):
235 self.cm.DeleteSliver(self.slice_cred, self.slice['hrn'],"call-id-delete-slice-cm")
237 def testRestartSlice(self):
238 self.cm.restart_slice(self.slice_cred, self.slice['hrn'])
240 def testGetSlices(self):
241 self.cm.ListSlices(self.slice_cred, self.slice['hrn'])
243 def testRedeemTicket(self):
244 rspec = self.aggregate.get_resources(self.credential)
245 ticket = self.aggregate.get_ticket(slice_cred, self.slice['hrn'], rspec)
246 self.cm.redeem_ticket(slice_cred, ticket)
249 def test_names(testcase):
250 return [name for name in dir(testcase) if name.startswith('test')]
252 def CreateSliver(client):
253 # register a slice that will be used for some test
254 authority = get_authority(client.hrn)
255 auth_cred = client.get_credential(authority, 'authority')
256 slice_record = {'hrn': ".".join([authority, random_string(10)]),
257 'type': 'slice', 'researcher': [client.hrn]}
258 client.registry.register(auth_cred, slice_record)
261 def DeleteSliver(client, slice):
262 authority = get_authority(client.hrn)
263 auth_cred = client.get_credential(authority, 'authority')
265 client.registry.remove(auth_cred, 'slice', slice['hrn'])
267 if __name__ == '__main__':
271 default_config_dir = os.path.expanduser('~/.sfi/sfi_config')
272 default_cm = "echo.cs.princeton.edu"
273 parser = OptionParser(usage="%(prog_name)s [options]" % locals())
274 parser.add_option('-f', '--config_file', dest='config_file', default=default_config_dir,
275 help='config file. default is %s' % default_config_dir)
276 parser.add_option('-r', '--registry', dest='registry', action='store_true',
277 default=False, help='run registry tests')
278 parser.add_option('-a', '--aggregate', dest='aggregate', action='store_true',
279 default=False, help='run aggregate tests')
280 parser.add_option('-s', '--slicemgr', dest='slicemgr', action='store_true',
281 default=False, help='run slicemgr tests')
282 parser.add_option('-c', '--component', dest='component', action='store_true',
283 default=False, help='run component tests')
284 parser.add_option('-d', '--cm_host', dest='cm_host', default=default_cm,
285 help='dns name of component to test. default is %s' % default_cm)
286 parser.add_option('-A', '--all', dest='all', action='store_true',
287 default=False, help='run component tests')
289 options, args = parser.parse_args()
290 suite = unittest.TestSuite()
291 client = Client(options)
294 # create the test slice if necessary
295 if options.all or options.slicemgr or options.aggregate \
296 or options.component:
297 test_slice = CreateSliver(client)
299 if options.registry or options.all:
300 for name in test_names(RegistryTest):
301 suite.addTest(RegistryTest(name, client))
303 if options.aggregate or options.all:
304 for name in test_names(AggregateTest):
305 suite.addTest(AggregateTest(name, client, test_slice))
307 if options.slicemgr or options.all:
308 for name in test_names(SlicemgrTest):
309 suite.addTest(SlicemgrTest(name, client, test_slice))
311 if options.component or options.all:
312 for name in test_names(ComponentTest):
313 suite.addTest(ComponentTest(name, client, test_slice))
316 unittest.TextTestRunner(verbosity=2).run(suite)
319 DeleteSliver(client, test_slice)