7 import sfa.util.xmlrpcprotocol as xmlrpc
8 from unittest import TestCase
9 from optparse import OptionParser
10 from sfa.util.xmlrpcprotocol import ServerException
11 from sfa.util.namespace import *
12 from sfa.util.config import *
13 from sfa.trust.certificate import *
14 from sfa.trust.credential import *
15 from sfa.util.sfaticket import *
16 from sfa.client import sfi
18 def random_string(size):
19 return "".join(random.sample(string.letters, size))
31 def __init__(self, options):
32 try: self.config = config = Config(options.config_file)
34 print "failed to read config_file %s" % options.config_file
36 key_path = os.path.dirname(options.config_file)
37 user_name = self.config.SFI_USER.split('.')[-1:][0]
38 key_file = key_path + os.sep + user_name + '.pkey'
39 cert_file = key_path + os.sep + user_name + '.cert'
40 self.key = Keypair(filename=key_file)
41 self.cert = Certificate(subject=self.config.SFI_USER)
42 self.cert.set_pubkey(self.key)
43 self.cert.set_issuer(self.key, self.config.SFI_USER)
45 self.cert.save_to_file(cert_file)
46 SFI_AGGREGATE = config.SFI_SM.replace('12347', '12346')
47 SFI_CM = 'http://' + options.cm_host + ':12346'
48 self.registry = xmlrpc.get_server(config.SFI_REGISTRY, key_file, cert_file)
49 self.aggregate = xmlrpc.get_server(SFI_AGGREGATE, key_file, cert_file)
50 self.sm = xmlrpc.get_server(config.SFI_SM, key_file, cert_file)
51 self.cm = xmlrpc.get_server(SFI_CM, key_file, cert_file)
52 self.user = config.SFI_USER
53 # XX defaulting to user, but this should be configurable so we can
54 # test from components persepctive
57 def get_credential(self, hrn = None, type = 'user'):
58 if not hrn: hrn = self.user
60 cert = self.cert.save_to_string(save_parents=True)
61 request_hash = self.key.compute_hash([cert, 'user', hrn])
62 self.credential = self.registry.get_self_credential(cert, type, hrn, request_hash)
63 return self.credential
65 if not self.credential:
66 self.get_credential(self.user, 'user')
67 return self.registry.get_credential(self.credential, type, hrn)
69 class BasicTestCase(unittest.TestCase):
70 def __init__(self, testname, client):
71 unittest.TestCase.__init__(self, testname)
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.user
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_record = {'hrn': ".".join([authority, random_string(10)]),
101 node_record = {'hrn': ".".join([authority, random_string(10)]),
103 slice_record = {'hrn': ".".join([authority, random_string(10)]),
104 'type': 'slice', 'researcher': [self.hrn]}
105 user_record = {'hrn': ".".join([authority, random_string(10)]),
108 all_records = [auth_record, node_record, slice_record, user_record]
109 for record in all_records:
111 self.registry.register(self.cred, record)
112 self.registry.resolve(self.cred, record['hrn'])
116 self.registry.remove(record['hrn'])
119 def testRegisterPeerObject(self):
122 def testUpdate(self):
123 record = self.registry.resolve(self.credential, self.hrn)
124 self.registry.update(record)
126 def testResolve(self):
127 authority = get_authority(self.hrn)
128 self.registry.resolve(self.credential, self.hrn)
130 def testRemove(self):
131 record = {'hrn': ".".join([authority, random_string(10)]),
133 self.registry.register(self.credential, user_record)
134 self.registry.remove(self.credential, user_record['hrn'])
135 # should generate an exception
137 self.registry.resolve(self.credential, record['hrn'])
142 def testRemovePeerObject(self):
146 authority = get_authority(self.client.user)
147 self.registry.list(self.credential, authority)
149 def testGetRegistries(self):
150 self.registry.get_registries(self.credential)
152 def testGetAggregates(self):
153 self.registry.get_aggregates(self.credential)
155 def testGetTrustedCerts(self):
156 # this should fail unless we are a node
157 callable = self.registry.get_trusted_certs
158 server_exception = False
160 callable(self.credential)
161 except ServerException:
162 server_exception = True
164 if self.type in ['user'] and not server_exception:
170 class AggregateTest(BasicTestCase):
173 BasicTestCase.setUp(self)
175 # register a slice that will be used for some test
176 slice_record = {'hrn': ".".join([authority, random_string(10)]),
177 'type': 'slice', 'researcher': [self.hrn]}
178 self.registry.register(self.credential, slice_record)
179 self.slice = slice_record
182 # remove the test slice
183 self.registry.remove(self.credential, self.slice['hrn'])
185 def testGetSlices(self):
186 self.aggregate.get_slices(self.credential)
188 def testGetResources(self):
189 # available resources
190 agg_rspec = self.aggregate.get_resources(self.credential)
191 # resources used by a slice
192 slice_rspec = self.aggregate.get_resources(self.credential, self.slice['hrn'])
193 # will raise an exception if the rspec isnt valid
195 RSpec(xml=slice_rspec)
197 def testCreateSlice(self):
198 # get availabel resources
199 rspec = self.aggregate.get_resources(self.credential)
200 slice_credential = self.client.get_credential(self.slice['hrn'], 'slice')
201 self.aggregate.create_slice(slice_credential, rspec)
203 def testDeleteSlice(self):
204 slice_credential = self.client.get_credential(self.slice['hrn'], 'slice')
205 self.aggregate.delete_slice(slice_credential, self.slice['hrn'])
207 def testGetTicket(self):
208 slice_credential = self.client.get_credential(self.slice['hrn'], 'slice')
209 rspec = self.aggregate.get_resources(self.credential)
210 ticket = self.aggregate.get_ticket(slice_credential, self.slice['hrn'], rspec)
211 # will raise an exception if the ticket inst valid
212 SfaTicket(string=ticket)
214 class SlicemgrTest(AggregateTest):
216 AggregateTest.setUp(self)
218 # force calls to go through slice manager
219 self.aggregate = self.sm
221 class ComponentTest(BasicTestCase):
224 BasicTestCase.setUp(self)
225 AggregateTest.setUp(self)
228 AggregateTest.tearDown(self)
230 def testStartSlice(self):
231 self.cm.start_slice(self.slice['hrn'])
233 def testStopSlice(self):
234 self.cm.stop_slice(self.slice['hrn'])
236 def testDeleteSlice(self):
237 self.cm.delete_slice(self.slice['hrn'])
239 def testRestartSlice(self):
240 self.cm.restart_slice(self.slice['hrn'])
242 def testGetSlices(self):
243 self.cm.get_slices(self.slice['hrn'])
245 def testRedeemTicket(self):
246 slice_credential = self.client.get_credential(self.slice['hrn'], 'slice')
247 rspec = self.aggregate.get_resources(self.credential)
248 ticket = self.aggregate.get_ticket(slice_credential, self.slice['hrn'], rspec)
249 self.cm.redeem_ticket(slice_credential, ticket)
252 def test_names(testcase):
253 return [name for name in dir(testcase) if name.startswith('test')]
255 if __name__ == '__main__':
259 default_config_dir = os.path.expanduser('~/.sfi/sfi_config')
260 default_cm = "echo.cs.princeton.edu"
261 parser = OptionParser(usage="%(prog_name)s [options]" % locals())
262 parser.add_option('-f', '--config_file', dest='config_file', default=default_config_dir,
263 help='config file. default is %s' % default_config_dir)
264 parser.add_option('-r', '--registry', dest='registry', action='store_true',
265 default=False, help='run registry tests')
266 parser.add_option('-a', '--aggregate', dest='aggregate', action='store_true',
267 default=False, help='run aggregate tests')
268 parser.add_option('-s', '--slicemgr', dest='slicemgr', action='store_true',
269 default=False, help='run slicemgr tests')
270 parser.add_option('-c', '--component', dest='component', action='store_true',
271 default=False, help='run component tests')
272 parser.add_option('-d', '--cm_host', dest='cm_host', default=default_cm,
273 help='dns name of component to test. default is %s' % default_cm)
274 parser.add_option('-A', '--all', dest='all', action='store_true',
275 default=False, help='run component tests')
277 options, args = parser.parse_args()
278 suite = unittest.TestSuite()
279 client = Client(options)
280 # bootstrap the users credential
281 client.get_credential()
283 if options.registry or options.all:
284 for name in test_names(RegistryTest):
285 suite.addTest(RegistryTest(name, client))
287 if options.aggregate or options.all:
288 for name in test_names(AggregateTest):
289 suite.addTest(AggregateTest(name, client))
291 if options.slicemgr or options.all:
292 for name in test_names(SlicemgrTest):
293 suite.addTest(SlicemgrTest(name, client))
295 if options.component or options.all:
296 for name in test_names(ComponentTest):
297 suite.addTest(ComponentTest(name, client))
299 unittest.TextTestRunner(verbosity=2).run(suite)