fix syntax errors
[sfa.git] / tests / testInterfaces.py
1 #!/usr/bin/python
2 import sys
3 import os
4 import random
5 import string
6 import unittest
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
17
18 def random_string(size):
19     return "".join(random.sample(string.letters, size))
20
21 class Client:
22     registry = None
23     aggregate = None
24     sm = None
25     cm = None
26     user = None
27     key = None
28     cert = None
29     credential = None
30     type = None            
31     def __init__(self, options):
32         try: self.config = config = Config(options.config_file)
33         except:
34             print "failed to read config_file %s" % options.config_file
35             sys.exit(1)
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)
44         self.cert.sign()
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
55         self.type = 'user'
56         
57     def get_credential(self, hrn = None, type = 'user'):
58         if not hrn: hrn = self.user 
59         if 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
64         else:
65             if not self.credential:
66                 self.get_credential(self.user, 'user')
67             return self.registry.get_credential(self.credential, type, hrn)     
68
69 class BasicTestCase(unittest.TestCase):
70     def __init__(self, testname, client):
71         unittest.TestCase.__init__(self, testname)
72         self.client = client
73     
74     def setUp(self):
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  
82                 
83 # Registry tests
84 class RegistryTest(BasicTestCase):
85
86     def setUp(self):
87         """
88         Make sure test records dont exsit
89         """
90         BasicTestCase.setUp(self)
91
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)
96
97     def testRegister(self):
98         authority = get_authority(self.hrn)
99         auth_record = {'hrn': ".".join([authority, random_string(10)]),
100                        'type': 'authority'}
101         node_record = {'hrn': ".".join([authority, random_string(10)]),
102                        'type': 'node'}
103         slice_record = {'hrn': ".".join([authority, random_string(10)]),
104                         'type': 'slice', 'researcher': [self.hrn]}
105         user_record = {'hrn': ".".join([authority, random_string(10)]),
106                        'type': 'user'}
107
108         all_records = [auth_record, node_record, slice_record, user_record]
109         for record in all_records:
110             try:
111                 self.registry.register(self.cred, record)
112                 self.registry.resolve(self.cred, record['hrn'])
113             except:
114                 raise
115             finally:
116                 self.registry.remove(record['hrn'])
117
118     
119     def testRegisterPeerObject(self):
120         assert True
121    
122     def testUpdate(self):
123         record = self.registry.resolve(self.credential, self.hrn)
124         self.registry.update(record) 
125
126     def testResolve(self):
127         authority = get_authority(self.hrn)
128         self.registry.resolve(self.credential, self.hrn)
129    
130     def testRemove(self):
131         record = {'hrn': ".".join([authority, random_string(10)]),
132                        'type': 'user'}
133         self.registry.register(self.credential, user_record)
134         self.registry.remove(self.credential, user_record['hrn'])
135         # should generate an exception
136         try:
137             self.registry.resolve(self.credential,  record['hrn'])
138             assert False
139         except:       
140             assert True
141  
142     def testRemovePeerObject(self):
143         assert True
144
145     def testList(self):
146         authority = get_authority(self.client.user)
147         self.registry.list(self.credential, authority)
148              
149     def testGetRegistries(self):
150         self.registry.get_registries(self.credential)
151     
152     def testGetAggregates(self):
153         self.registry.get_aggregates(self.credential)
154
155     def testGetTrustedCerts(self):
156         # this should fail unless we are a node
157         callable = self.registry.get_trusted_certs
158         server_exception = False 
159         try:
160             callable(self.credential)
161         except ServerException:
162             server_exception = True
163         finally:
164             if self.type in ['user'] and not server_exception:
165                 assert False
166             
167             
168
169
170 class AggregateTest(BasicTestCase):
171     slice = None
172     def setUp(self):
173         BasicTestCase.setUp(self)
174         
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 
180
181     def tearDown(self):
182         # remove the test slice
183         self.registry.remove(self.credential, self.slice['hrn'])
184
185     def testGetSlices(self):
186         self.aggregate.get_slices(self.credential)
187
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
194         RSpec(xml=agg_rspec)
195         RSpec(xml=slice_rspec)
196
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)
202
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'])
206
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)        
213
214 class SlicemgrTest(AggregateTest):
215     def setUp(self):
216         AggregateTest.setUp(self)
217         
218         # force calls to go through slice manager   
219         self.aggregate = self.sm
220
221 class ComponentTest(BasicTestCase):
222     slice = None
223     def setUp(self):
224         BasicTestCase.setUp(self)
225         AggregateTest.setUp(self)
226
227     def tearDown(self):
228         AggregateTest.tearDown(self)
229
230     def testStartSlice(self):
231         self.cm.start_slice(self.slice['hrn'])
232
233     def testStopSlice(self):
234         self.cm.stop_slice(self.slice['hrn'])
235
236     def testDeleteSlice(self):
237         self.cm.delete_slice(self.slice['hrn'])
238
239     def testRestartSlice(self):
240         self.cm.restart_slice(self.slice['hrn'])
241
242     def testGetSlices(self):
243         self.cm.get_slices(self.slice['hrn'])
244
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)
250
251
252 def test_names(testcase):
253     return [name for name in dir(testcase) if name.startswith('test')]
254  
255 if __name__ == '__main__':
256
257     args = sys.argv
258     prog_name = args[0]
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')
276     
277     options, args = parser.parse_args()
278     suite = unittest.TestSuite()
279     client = Client(options)
280     # bootstrap the users credential
281     client.get_credential()
282
283     if options.registry or options.all:
284         for name in test_names(RegistryTest):
285             suite.addTest(RegistryTest(name, client))
286
287     if options.aggregate or options.all: 
288         for name in test_names(AggregateTest):
289             suite.addTest(AggregateTest(name, client))
290
291     if options.slicemgr or options.all: 
292         for name in test_names(SlicemgrTest):
293             suite.addTest(SlicemgrTest(name, client))
294
295     if options.component or options.all: 
296         for name in test_names(ComponentTest):
297             suite.addTest(ComponentTest(name, client))
298
299     unittest.TextTestRunner(verbosity=2).run(suite)
300