Python: Fix URL in Variant parsing and serialization; Notification
[smartapi.git] / Common / Python / SmartAPI / tests / TestSequences.py
1 #!/usr/bin/python
2
3 """ 
4 """
5
6 import sys
7
8 import datetime
9 import urllib2
10 import httplib
11 from urlparse import urlparse
12
13
14 from SmartAPI.model.Capacity import Capacity
15 from SmartAPI.model.Evaluation import Evaluation
16 from SmartAPI.model.SystemOfInterest import SystemOfInterest
17 from SmartAPI.model.TemporalContext import TemporalContext
18 from SmartAPI.model.Input import Input
19 from SmartAPI.model.Output import Output
20 from SmartAPI.model.Activity import Activity
21 from SmartAPI.model.Address import Address
22 from SmartAPI.model.AliveRequest import AliveRequest
23 from SmartAPI.model.Availability import Availability
24 from SmartAPI.model.Status import Status
25 from SmartAPI.model.Response import Response
26 from SmartAPI.model.InterfaceAddress import InterfaceAddress
27 from SmartAPI.model.TimeSeries import TimeSeries
28 from SmartAPI.model.ValueObject import ValueObject
29 from SmartAPI.rdf.Variant import Variant
30 from SmartAPI.model.Map import Map
31 from SmartAPI.model.Organization import Organization
32 from SmartAPI.model.PhysicalEntity import PhysicalEntity
33 from SmartAPI.model.Service import Service
34 from SmartAPI.model.Size import Size
35 from SmartAPI.model.Velocity import Velocity
36 from SmartAPI.model.Orientation import Orientation
37 from SmartAPI.model.Direction import Direction
38 from SmartAPI.model.Parameter import Parameter
39 from SmartAPI.model.Waypoints import Waypoints
40 from SmartAPI.model.Waypoint import Waypoint
41 from SmartAPI.model.Address import Address
42 from SmartAPI.model.Route import Route
43 from SmartAPI.model.Coordinates import Coordinates
44 from SmartAPI.model.Request import Request
45 from SmartAPI.model.UnitPriceSpecification import UnitPriceSpecification
46 from SmartAPI.model.PropertyDependentPriceSpecification import PropertyDependentPriceSpecification
47 from SmartAPI.model.SomeItems import SomeItems
48 from SmartAPI.model.Condition import Condition
49 from SmartAPI.model.Offering import Offering
50 from SmartAPI.model.Transaction import Transaction
51 from SmartAPI.model.Entity import Entity
52 from SmartAPI.model.Device import Device
53 from SmartAPI.model.Service import Service
54 from SmartAPI.model.Obj import Obj
55 from SmartAPI.factory.Factory import Factory
56 from SmartAPI.factory.RequestFactory import RequestFactory
57 from SmartAPI.factory.ResponseFactory import ResponseFactory
58 from SmartAPI.factory.NotificationFactory import NotificationFactory
59 from SmartAPI.factory.CommandFactory import CommandFactory
60
61 from SmartAPI.common.Tools import Tools
62 from SmartAPI.common.SmartAPICrypto import SmartAPICrypto
63 from SmartAPI.common.SERIALIZATION import SERIALIZATION
64 from SmartAPI.common.RESOURCE import RESOURCE
65 from SmartAPI.common.PROPERTY import PROPERTY
66 from SmartAPI.common.DATATYPE import DATATYPE
67 from SmartAPI.common.NS import NS
68 from SmartAPI.common.CryptoKeyWallet import CryptoKeyWallet
69 from SmartAPI.agents.OntologyAgent import OntologyAgent
70
71 from SmartAPI.agents.RegistrationAgent import RegistrationAgent
72 from SmartAPI.agents.SearchAgent import SearchAgent
73 from SmartAPI.agents.TransactionAgent import TransactionAgent
74
75 from SmartAPI.rdf.LinkedList import LinkedList
76 from SmartAPI.rdf.OrderedList import OrderedList
77 from SmartAPI.rdf.ItemizedList import ItemizedList
78 from SmartAPI.rdf.NudeList import NudeList
79
80 from rdflib import URIRef
81 from Crypto.PublicKey import RSA
82 import os
83 import uuid
84 import base64
85 import isodate
86 import datetime
87 import random
88 import traceback
89 from datetime import timedelta
90 from SmartAPI.common.URLs import KEYSERVER_URI
91
92
93 def objectCopyTest():
94     fromObject = PhysicalEntity()
95     size = Size()
96     speed = Velocity()
97     alternativeSpeed = Velocity()
98     
99     size.setWidth(ValueObject(unit = NS.UNIT + "Centimeter", value = Variant(100)))
100     size.setHeight(ValueObject(unit = NS.UNIT + "Centimeter", value = Variant(301.9)))
101     size.setDepth(ValueObject(unit = NS.UNIT + "Centimeter", value = Variant(11.222)))
102     
103     speed.setLinearVelocityX(ValueObject(unit = URIRef(NS.UNIT + "MeterPerSecond"), value = Variant(3.4)))
104     speed.setLinearVelocityY(ValueObject(unit = NS.UNIT + "MeterPerSecond", value = Variant(30.1)))
105     speed.setAngularVelocityY(ValueObject(unit = NS.UNIT + "RadianPerSecond", value = Variant(54.3)))
106     
107     alternativeSpeed.setAngularVelocityY(ValueObject(unit = NS.UNIT + "RadianPerSecond", value = Variant(10.1)))
108     
109     fromObject.addType(RESOURCE.CAR)
110     fromObject.setName("This is the source");
111     fromObject.setVelocity(speed);
112     fromObject.setSize(size);
113     
114     fromObject.setWeight(ValueObject(unit = NS.UNIT + "Kilogram", value = Variant(222)))
115     fromObject.add(URIRef(PROPERTY.ADDITIONAL_NAME), "An additional name has been set")
116     fromObject.add(URIRef(PROPERTY.AVERAGEVELOCITY), alternativeSpeed)
117     
118     print "Serialized original:"
119     print Tools().toString(fromObject, SERIALIZATION.TURTLE)
120     
121     toObject = PhysicalEntity()
122     Tools.copy(fromObject, toObject)
123     
124     print "Serialized copy:"
125     print Tools().toString(toObject, SERIALIZATION.TURTLE)
126     
127     print "Changing the copy"
128     print "-----------------"
129     toObjectSize = Size()
130     size.setWidth(ValueObject(unit = NS.UNIT + "Centimeter", value = Variant(2000)))
131     toObject.setSize(toObjectSize);
132     
133     print "Serialized original:"
134     print Tools().toString(fromObject, SERIALIZATION.TURTLE)
135     print "Serialized copy:"
136     print Tools().toString(toObject, SERIALIZATION.TURTLE)
137     
138     
139 def serializeRequestTest():
140
141     sampleValue = 9
142
143     targetSystemUri = "http://localhost:8099/seas/v1.0/access/";
144     myId = "http://seasdemos.asema.com/csharp/controlcommandsender/Cabcd";
145     targetId = "http://seasdemos.asema.com/csharp/controlcommandreceiver/Cabcd";
146     sourceIdentity = "http://seasexamples.asema.com/dataservers/timeseries";
147     myIdentity = "http://seasexamples.asema.com/datafetchers/timeseries";
148
149     print "Test routine for request serialization";
150
151     seriesEnd = datetime.datetime.now()
152     seriesStart = seriesEnd - datetime.timedelta(days = 7)
153
154     request_vars = []
155     request_vars.append(("Temperature", "DegreeCelsius"))
156     request_vars.append(("Cloudiness", "Percent"))
157     request_vars.append(("Precipitation", "MilliMeter"))
158
159     tsRequest = RequestFactory().create(myIdentity);
160
161     tc = TemporalContext()
162     tc.setStart(seriesStart)
163     tc.setEnd(seriesEnd)
164     tc.setDuration(2, 2, 2, 2, 2, 2)
165    
166     a = Activity()
167     i = Input()
168     i.setTemporalContext(tc)
169     
170     if len(request_vars) == 1:
171         tsRequest.setQuantity(NS.SMARTAPI + request_vars[0][0])
172         tsRequest.setUnit(NS.SMARTAPI + request_vars[0][1])
173     else:
174         for idx in range(len(request_vars)):
175             v = ValueObject()
176             sampleValue += 1
177             v.setQuantity(NS.SMARTAPI + request_vars[idx][0])
178             v.setUnit(NS.SMARTAPI + request_vars[idx][1])
179             v.setValue(Variant(sampleValue))
180             i.add(PROPERTY.VALUEOBJECT, v)
181
182     a.setInput(i)
183     a.setMethod(RESOURCE.READ)
184     tsRequest.setActivity(a)
185     
186     payload = Tools().toString(tsRequest, SERIALIZATION.TURTLE)
187     print "Serialze to String ..."
188     print payload
189     print "parse back to request object..."
190     newPayload = Request.fromString(payload, SERIALIZATION.TURTLE)
191     print "and serialze back ...."
192     print "***End ", newPayload.firstActivity().firstInput().getTemporalContext().getEnd()
193     print Tools().toString(newPayload, SERIALIZATION.TURTLE)
194     
195     return tsRequest
196
197 def serializeNotificationTest():
198     myIdentity = "http://tests.smart-api.io/python/notificationsender/Cabcd";
199     n = NotificationFactory.create(myIdentity)
200     a = Activity()
201     a.setMethod(RESOURCE.NOTIFY)
202     e = Entity(myIdentity + "/Cdevice")
203     
204     power = ValueObject(myIdentity + "service/Ppower")
205     power.setQuantity(RESOURCE.POWER)
206     power.setUnit(RESOURCE.AMPERE)
207     power.setValue(501.0)
208     
209     e.addValueObject(power);
210     a.addEntity(e);
211     n.setActivity(a);
212     n.turtlePrint()
213     
214     return True
215
216 def requestResponseTest3():
217     '''
218     This test case is copied and modified from Java version
219     '''
220         
221     clientIdentity = "http://www.client.com/seas/Cclient"
222     serverIdentity = "http://www.server.com/seas/Cserver"
223    
224     #get sessionKey  
225     crypto = SmartAPICrypto() 
226     sessionKey = crypto.generateSymmetricKey()  
227     
228     print "\n\nREQUEST/RESPONSE, TEST 3"
229     print '\n------------REQUEST part test -----------------------\n'
230     # Send request
231     rc = RequestFactory().create(clientIdentity)
232     rc.setMethod(RESOURCE.READ);
233     a = Activity()
234     i = Input()
235     a.addInput(i)
236     i.setSystemOfInterestWithSameAs("http://a.com/b")
237     
238     i2 = Input()
239     a.addInput(i2)
240     i2.setSystemOfInterestWithSameAs("http://additional.com/b")
241     
242     rc.addActivity(a);
243     
244     serializedRequest, ct = Tools.serializeRequest(rc, SERIALIZATION.RDF_XML )#'text/turtle')
245     print "\n ****** REQUEST in RDF/XML:***** \n", serializedRequest
246     print "Request Content-Type:  ", ct
247         
248     # Receive request
249     rs = Tools.parseRequest(serializedRequest, None, SERIALIZATION.RDF_XML)
250     clientId = rs.getGeneratedBy()
251     aa = rs.getActivities()[0]
252     ii = aa.getInputs()[0]
253     print "Request, sys of interest ", ii.getSystemOfInterest().getSameAs().getIdentifierUri(), " from ", clientId
254     
255     
256     print '\n------------RESPONSE part test -----------------------\n'
257     # Send response
258     resp = ResponseFactory().create(serverIdentity)
259     resp.setMethod(RESOURCE.READ)
260     ars = Activity()
261     
262     ors = Output()
263     ars.addOutput(ors)
264     ors.setSystemOfInterestWithSameAs("http://a.com/b")
265     ors.encrypt(sessionKey)
266     
267     ors2 = Input()
268     ars.addInput(ors2)
269     ors2.setSystemOfInterestWithSameAs("http://additional.com/b")
270     ors2.encrypt(sessionKey)
271     
272     resp.addActivity(ars)
273         
274     serializedResponse, ct2 = Tools.serializeResponse(resp, SERIALIZATION.TURTLE) #'text/turtle')
275     print "\n **** RESPONSE in turtle (encrypting Input and Output with Session key):****\n", serializedResponse
276     print "Response Content-Type:  ", ct2
277         
278     # Receive response
279     respc = Tools.parseResponse(serializedResponse, ct2, SERIALIZATION.TURTLE)
280     print 'DEBUG: ', len(Tools.messagePartsForParse)
281     print '\n...reserialize whole Response to String using plain old toString().....'
282     print Tools().toString(respc, SERIALIZATION.TURTLE)
283     
284     serverId = respc.getGeneratedBy()
285     ac = respc.getActivities()[0]
286     oc = ac.getOutputs()[0]
287     ic = ac.getInputs()[0]
288    
289     oc_parsed = oc.decrypt(sessionKey);
290     ic_parsed = ic.decrypt(sessionKey);
291     print '\n...After decrypting, reserialize the recovered Output to String using plain old toString() .....'
292     print Tools().toString(oc_parsed, SERIALIZATION.TURTLE)
293     print "\nResponse, sys of interest ", oc_parsed.getSystemOfInterest().getSameAs().getIdentifierUri(), " from ", serverId
294     print '\n...After decrypting, reserialize the recovered Input to String using plain old toString() .....'
295     print Tools().toString(ic_parsed, SERIALIZATION.TURTLE)
296     
297     
298     print '\n ======= now encrypt REQUEST with public key ========'
299     privKey = SmartAPICrypto().loadPrivateKey('testkey_private.pem')
300     pubKey = SmartAPICrypto().downloadPublicKey(clientId, KEYSERVER_URI)
301     
302     rc.encrypt(pubKey)
303     serializedRequest2, ct2 = Tools.serializeRequest(rc)
304     print 'REQUEST in turtle (encrypt with public key).....'
305     print serializedRequest2
306     rc_recovered = Tools.parseRequest(serializedRequest2, ct2)
307     if rc_recovered.isEncrypted() and rc_recovered.getEncryptionKeyType() == RESOURCE.PUBLICKEY:
308         rc_recovered = rc_recovered.decrypt(privKey)
309         print ' after parsing and decrypting, we get: '
310         rc_recovered.turtlePrint()
311     
312     ac2 = rc_recovered.getActivities()[0]
313     ac2.encrypt(pubKey)
314     serializedRequest3, ct3 = Tools.serializeRequest(rc_recovered)
315     print '.....REQUEST in turtle with Activity being encrypted (encrypt with public key).....'
316     print serializedRequest3
317     
318     rc_recovered3 = Tools.parseRequest(serializedRequest3, ct3)
319     if rc_recovered3.getActivities()[0].isEncrypted():
320         rc_recovered4 = rc_recovered3.getActivities()[0].decrypt(privKey)
321         print ' after parsing and decrypting, we get: '
322         rc_recovered4.turtlePrint()
323     
324
325 def requestResponseTest4():
326     '''
327     it tests key handling, message serialization/parsing, and signature verification
328     '''
329         
330     clientIdentity = "http://www.client.com/seas/Cclient"
331     serverIdentity = "http://www.server.com/seas/Cserver"
332          
333     current_path = os.getcwd()
334 #     pubKey = getPemPublicKey(os.path.join(current_path, "testkey_public.pem"))
335 #     privKey = getPemPrivateKey(os.path.join(current_path,"testkey_private.pem"))
336     #privKey, pubKey = SmartAPICrypto().generateKeyPair() 
337     
338     privKey = SmartAPICrypto().loadPrivateKey('testkey_private.pem')
339     
340     print '\n\nREQUEST/RESPONSE, TEST 4 (request and response with signed data) '
341      # Send request
342     rc = RequestFactory().create(clientIdentity)
343     rc.setMethod(RESOURCE.READ);
344     a = Activity()
345     i = Input()
346     a.addInput(i)
347     i.setSystemOfInterestWithSameAs("http://a.com/b")
348     rc.addActivity(a);
349     
350     print 'run turtlePrint() function for request ....'
351     rc.turtlePrint()
352     
353     rc.sign(privKey)    
354     serializedRequest, ct = Tools.serializeRequest(rc, 'turtle')
355     print "REQUEST, after signing, no outer header :\n", serializedRequest
356     print "Request Content-Type:  ", ct    
357     print '--------  end of request ----------'
358     
359     serializedRequest = serializedRequest.replace('Read', 'Write')
360     # Receive request    
361     rs = Tools.parseRequest(serializedRequest, ct)
362     print ':::: here is rs ::::'
363     rs.turtlePrint()
364     clientId = rs.getGeneratedBy()
365     aa = rs.getActivities()[0]
366     ii = aa.getInputs()[0]
367     print "Request, sys of interest ", ii.getSystemOfInterest().getSameAs().getIdentifierUri(), " from ", clientId
368     
369     pubKey = SmartAPICrypto().downloadPublicKey(clientId, KEYSERVER_URI)
370     
371     print 'verifying signature succeed? ', rs.verifySignature(pubKey)
372     
373     print '\n------------RESPONSE part test -----------------------\n'
374     # Send response
375     resp = ResponseFactory().create(serverIdentity)
376     resp.setMethod(RESOURCE.READ)
377     ars = Activity()
378     
379     ors = Output()
380     ars.addOutput(ors)
381     ors.setSystemOfInterestWithSameAs("http://a.com/b")
382         
383     ors.sign(privKey)
384     resp.addActivity(ars)
385         
386     serializedResponse, ct2 = Tools.serializeResponse(resp, 'turtle', False)
387     print "RESPONSE with outer MIME header:\n", serializedResponse
388     print "Response Content-Type:  ", ct2
389         
390     # Receive response    
391     respc = Tools.parseResponse(serializedResponse)
392     print 'DEBUG: ', len(Tools.messagePartsForParse)
393     print '\n...reserialize whole Response to String using plain old toString().....'
394     print Tools().toString(respc, SERIALIZATION.TURTLE)
395     
396     serverId = respc.getGeneratedBy()
397     ac = respc.getActivities()[0]        
398     oc = ac.getOutputs()[0]
399     print '....... reserialize the recovered Output to String using plain old toString() .....'
400     print Tools().toString(oc, SERIALIZATION.TURTLE)  
401     if oc.isSigned():  
402         verified = oc.verifySignature(pubKey)
403         print "Signature verification successful?: ", verified 
404     print "Response, sys of interest ", oc.getSystemOfInterest().getSameAs().getIdentifierUri()
405
406
407 def notaryKeyStoreTest():
408     myId = "http://seas.test.asema.com/notarykeytest"
409     referenceId = "http://seas.test.asema.com/notarykeytest/ref1"+uuid.uuid4().get_hex()   
410     content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas in lectus at sem commodo venenatis. Fusce in eros ex. In hac habitasse platea dictumst. Phasellus dignissim, augue vel aliquet pretium, nibh eros tristique est, dignissim aliquet elit justo vel mauris. Vestibulum a posuere nulla. Curabitur aliquam semper sagittis."
411     content = content + uuid.uuid4().get_hex()
412
413     pubKey = getPemPublicKey("testkey_public.pem")
414     privKey = getPemPrivateKey("testkey_private.pem")
415     # save these key pairs to keywallet Class, which will used later in TransactionAgent.sendKeyToNotary()
416     
417     CryptoKeyWallet.setPublicKey(pubKey)
418     CryptoKeyWallet.setPrivateKey(privKey)
419     
420     crypto = SmartAPICrypto()
421     
422     notary = TransactionAgent.getDefaultNotary()
423     sessionKey = crypto.generateSymmetricKey()
424     #  save the key to string
425     sessionKeySent = base64.b64encode(sessionKey)
426     contentHash = crypto.createEncodedMessageDigest(content)
427     signature = crypto.sign(privKey, contentHash)
428     sentOK = TransactionAgent.sendKeyToNotary(myId, referenceId, contentHash, sessionKeySent, signature, notary)
429     sessionKeyReceived = TransactionAgent.fetchKeyFromNotary(myId, referenceId, contentHash, signature, notary)
430     
431     print 'Sent OK?: ', sentOK
432     print 'Send key: ', sessionKeySent
433     print 'Receive key: ', sessionKeyReceived
434     print 'Keys match?: ', sessionKeySent==sessionKeyReceived 
435     
436     # test encryptAndNotarize() method
437     print '\n ---- Now test Obj.encryptAndNotarize()----'
438     resp = ResponseFactory().create('http://www.server.com/seas/Cserver')
439     resp.setMethod(RESOURCE.READ)
440     ars = Activity()
441     
442     ors = Output()
443     ars.addOutput(ors)
444     ors.setSystemOfInterestWithSameAs("http://a.com/b")
445     ors.encryptAndNotarize(notary, pubKey, myId)
446     resp.addActivity(ars)
447     
448     serializedResponse, ct2 = Tools.serializeResponse(resp, 'text/turtle')
449     print "RESPONSE:\n", serializedResponse
450     
451     keyReceived = TransactionAgent.fetchKeyFromNotary(myId, ors.getIdentifierUri(), 
452                                                       ors.getHashCode(), ors.getSignature(), notary)
453     print 'Receive key: ', keyReceived
454
455
456 def unitPriceSpecificationTest():
457     '''
458     Test UnitPriceSpecification class parse/serialize
459     '''
460     myIdentity = "http://seasexamples.asema.com/pricefetcher"
461     ps = UnitPriceSpecification(myIdentity)
462     ps.setGrDescription("A subclass of GrObj")
463     ps.setGeneratedAt(datetime.datetime.now())
464     ps.setGrName("Price Fetching service")
465     ps.setCurrency("EUR")
466     ps.setCurrencyValue(3.12)
467     ps.setSameAs("http://bogus.same.as")
468     ps.setValidFrom(datetime.datetime.now())
469     ps.setQuantity(RESOURCE.ENERGYANDWORK)
470     ps.setUnit(RESOURCE.KILOWATTHOUR)
471    
472     ps.addType(RESOURCE.PRICE)
473     ps.setValueAddedTaxIncluded(False)
474     ps.setVatPercentage(Variant(100.2))
475     
476     print "        ---------",ps.getGrDescription()
477     print "        .....serialize UnitPriceSpecification object to string... "
478     st = Tools().toString(ps, SERIALIZATION.TURTLE)
479     print "        ", st
480     print "        parse back to UNITPriceSpecification object..."
481     model = Tools().fromString(st, SERIALIZATION.TURTLE)    
482     res = Tools().getResourceByType(RESOURCE.UNITPRICESPECIFICATION, model)
483     ps_parsed = UnitPriceSpecification().parse(res) 
484     
485     print "        GrDescription: ", ps_parsed.getGrDescription()
486     print "        ValueAddedTaxIncluded: ", ps_parsed.getValueAddedTaxIncluded()
487     print "        Vat percentage: ", ps_parsed.getVatPercentage()
488     print '        unit: ', ps_parsed.getUnit()
489     print '        validFrom: ', ps_parsed.getValidFrom()
490     
491     print "        .....reserialize to string ...."
492     st2 = Tools().toString(ps_parsed, SERIALIZATION.TURTLE)
493     print "        ", st2
494     print "\n"
495     print "        --------------"
496     
497     print '\n----explain---\n'
498     ps.explain()
499     
500     print '\n-----print----\n'
501     ps.printOut()
502     
503     return ps
504
505
506 def offeringTest():
507     '''
508     Test Offering class parse/serialize
509    
510     '''
511     myIdentity = "http://seasexamples.asema.com/offering"
512     offer = Offering(myIdentity, "an Offer", "an offer for extra energy")
513     offer.setBusinessFunction("http://myonlineBusiness.com")
514     offer.setSameAs("http://bogus.same.as")
515     someitems1 = SomeItems(None, RESOURCE.PRICE, "solar energy", "solar energy is unstable and unpredicatable", "http://my.demo.com")    
516     someitems1.setDuration("P1Y2M3DT10H10M1S")
517     offer.addIncludes(someitems1)
518     someitems2 = SomeItems(None, RESOURCE.PRICE, "Northern Sea wind farm", "winder energy is unstable as well", "http://my.demo2.com")
519     someitems2.setDuration(5,5,1,1,10,10)
520     offer.addIncludes(someitems2)
521     
522     ps = UnitPriceSpecification("http://unit.pricespecification.com")
523     ps.setGrDescription("A subclass of GrObj")
524     ps.setGeneratedAt(datetime.datetime.now())
525     ps.setGrName("Price Fetching service")
526     ps.setCurrency("EUR")
527     ps.setCurrencyValue(3.12)
528     ps.setSameAs("http://bogus.same.as")
529     ps.setValidFrom(datetime.datetime.now())
530     ps.setQuantity(RESOURCE.ENERGYANDWORK)
531     ps.setUnit(RESOURCE.KILOWATTHOUR)
532    
533     ps.addType(RESOURCE.PRICE)
534     ps.setValueAddedTaxIncluded(False)
535     ps.setVatPercentage(Variant(100.2))
536     offer.addPriceSpecification(ps)
537     
538     print ".....serialize Offering object to string... "
539     st = Tools().toString(offer, SERIALIZATION.TURTLE)
540     print st
541     print "....parse back to Offering object..."
542     model = Tools().fromString(st, SERIALIZATION.TURTLE)
543     res = Tools().getResourceByType(RESOURCE.OFFERING, model)
544     ps_parsed = Offering.parse(res) 
545     
546     print "business function URI: ", ps_parsed.getBusinessFunction().getIdentifierUri()
547     print "include 1 Types: ", ps_parsed.getIncludes()[0].getTypes()
548     print "include 1 duration: ", ps_parsed.getIncludes()[0].getDuration()
549     print "price specification VatPercentage: ", ps_parsed.getPriceSpecification()[0].getVatPercentage()
550     
551     print ".....reserialize to string ...."
552     st2 = Tools().toString(ps_parsed, SERIALIZATION.TURTLE)
553     print st2
554     
555     print "\n---explain----\n"
556     offer.explain()
557     print "\n---print----\n"
558     offer.printOut()
559
560
561 def TransactionSerialzeTest():
562     '''
563     Test Transaction Class parse/serialized.     
564     '''
565     print '\n <Test Transaction Class parse/serialized> \n'
566     myIdentity = "http://seasexamples.asema.com/transaction"
567     trans = Transaction(myIdentity)
568     trans.setGeneratedBy("http://asema.com/activitySeas")
569     trans.setGeneratedAt(datetime.datetime.now())
570     trans.setSigner("http://myOnlineBusiness.com")
571     
572     tsRequest = RequestFactory().create("http://localhost:8099/seas/v1.0/access/");
573
574     system = SystemOfInterest()
575     system.setSameAs("http://bogus.same.as")
576     system.setSessionKey("Measurement")
577     tsRequest.setSystemOfInterest(system)
578     
579     trans.setMessage(tsRequest)
580     trans.setSignature("XXXQAZWSXEDC")
581     trans.setHashCode("1234567")
582     #refObj = trans.createReference()
583     
584     print ".....serialize Transaction object to string... "
585     st = Tools().toString(trans, SERIALIZATION.TURTLE)
586     print st
587     
588     print ".....parse back to Transaction object using Tools.toObj()..."
589     #model = Tools().fromString(st, SERIALIZATION.TURTLE)    
590     #res = Tools().getResourceByType(RESOURCE.TRANSACTION, model)        
591     #ps_parsed = Transaction.parse(res) 
592     ps_parsed = Tools().toObj(st)
593     
594     print "Signature: ", ps_parsed.getSignature()
595     print "Message Session key: ", ps_parsed.getMessage().getSystemOfInterest().getSessionKey()
596     print "Message Generated By: ", ps_parsed.getMessage().getGeneratedBy().getIdentifierUri()
597     print "Generated At: ", ps_parsed.getGeneratedAt()
598     print "Generated By Types: ", ps_parsed.getGeneratedBy().getTypes()
599     
600     print ".....reserialize to string ...."
601     st2 = Tools().toString(ps_parsed, SERIALIZATION.TURTLE)
602     print st2
603     
604     print '\n----explain---\n'
605     ps_parsed.explain()
606     
607     print '\n-----print----\n'
608     ps_parsed.printOut()
609     # Reference parse/serialize test
610     #print "++++++++++++++serialize Transaction's Reference object to String +++++++"
611     #stRef = Tools().toString(refObj, SERIALIZATION.TURTLE)
612     #print stRef
613     
614     #print "+++++ Parse back to Reference Object ++++++++"
615     #model = Tools().fromString(stRef, SERIALIZATION.TURTLE)    
616     #resRef = Tools().getResourceByType(RESOURCE.REFERENCE, model)        
617     #ref_parsed = Transaction.parse(resRef) 
618     #print "++ Reference Object hashcode: ", ref_parsed.getHashCode()
619     #print "++ Reference Object Notary: ", ref_parsed.getNotary()
620     #print "+++++++ reserialize to string +++++ "
621     #st2Ref = Tools().toString(ref_parsed, SERIALIZATION.TURTLE)
622     #print st2Ref
623     
624     print "\n"
625
626
627 def longSerializeParseTest():
628     from SmartAPI.model.Obj import Obj
629     '''
630     Duration related testings are added in this test case.
631     '''
632     myId = "http://seasdemos.asema.com/cpluplus/controlcommandsender/Cabcd"
633     
634     print "Test routine for serialization + parse of an activity"
635     
636     a = Activity("http://asema.com/activitySeasIdentifier")
637     i1 = Input("http://input.uri", Input.TYPE_DATA)
638     i1.setName("data input")
639     i2 = Input("http://input2.uri", Input.TYPE_REFERENCE)
640     i2.setName("reference input")
641     a.setInput(i1)
642     a.addInput(i2)
643     o1 = Output("http://output.uri")
644     o1.setName("output 1")
645     o2 = Output("http://output.uri")
646     o2.setName("output 2")
647     a.setOutput(o1)
648     a.addOutput(o2)
649     
650     ab = Availability()
651     ab.setIdentifierUri("http://availability.uri")
652     ab.setName("availability")
653     ab.setIsControlledBy("http://availability.controlled.by")
654     a.addAvailability(ab)
655     dab = Availability()
656     dab.setIdentifierUri("http://data.availability.uri")
657     dab.setName("data availability")
658     a.addDataAvailability(dab)
659     
660     iface1 = InterfaceAddress()
661     iface1.setIdentifierUri("http://iface1.uri")
662     iface1.setName("eth0")
663     iface2 = InterfaceAddress()
664     iface2.setIdentifierUri("http://iface2.uri")
665     iface2.setType(RESOURCE.INTERFACEADDRESS)
666     iface2.addType(RESOURCE.BATTERY)
667     iface2.setName("eth1")
668     a.setInterface(iface1)
669     a.addInterface(iface2)
670     
671     tc = TemporalContext()
672     tc.setStart(datetime.datetime.now())
673     tc.setEnd(datetime.datetime.now())
674     tc.setDuration("P8DT8H2M2S")
675
676     status = Status()
677     status.setPercentage(50)
678     status.setCompleted(20)
679
680     req = ResponseFactory().create(myId)
681     req.setSameAs("http://bogus.same.as")
682     req.setName("test request")
683     req.setActivity(a)
684     req.setTemporalContext(tc)
685     req.setMessageId(1)
686     req.setProcessId(2)
687     req.setStatus(status)
688     req.setIdentifierUri("http://bogus.seas.identifier.uri")
689     req.add(URIRef("http://booleanProperty"), True)
690     req.add(URIRef("http://objectProperty"), Obj("http://foo.bar"))
691     req.add(URIRef("http://stringProperty"), "string value")
692     req.add(URIRef("http://doubleProperty"), -12.34)
693     req.add(URIRef("http://integerProperty"), 40)
694     req.add(URIRef("http://datetimeProperty"), datetime.datetime.now())
695     duration = Factory.createDuration(1, 2, 3, 4, 5, 6)
696     req.add(URIRef(PROPERTY.FRESHNESS), duration)
697     req.add(URIRef(PROPERTY.ADDON), 1.234)
698
699     system = SystemOfInterest()
700     system.setSameAs("http://system.of/interest")
701     #system.setRegisterKey("Measurement")
702     req.setSystemOfInterest(system)
703
704     payload = Tools().toString(req, SERIALIZATION.TURTLE)
705     
706     print "Serialized payload:"
707     print payload
708
709     print "Parsing back the serialized payload..."
710
711     model = Tools().fromString(payload, SERIALIZATION.TURTLE)
712     res = Tools().getResourceByType(RESOURCE.RESPONSE, model)
713     tsResponse = Response().parse(res)
714     print "hasTemporalContext? ", tsResponse.hasTemporalContext()
715     print "hasSystemOfInterest? ", tsResponse.hasSystemOfInterest()
716     if tsResponse.getTemporalContext().getStart() is not None:
717         print "temporal context start", tsResponse.getTemporalContext().getStart().getValue()
718     if tsResponse.getGeneratedBy() is not None:
719         print "is generated by ", tsResponse.getGeneratedBy()
720     print "is generated at ", tsResponse.getGeneratedAt()
721     print "is same as", tsResponse.getSystemOfInterest().getSameAs().toString()
722     print "addon: ", tsResponse.getFirstValue(URIRef(PROPERTY.ADDON))
723     print "freshness: ", tsResponse.getFirstValue(URIRef(PROPERTY.FRESHNESS))
724     
725     print "\nRe-serializing into JSON-LD"
726     reserializedPayload = Tools().toString(tsResponse, SERIALIZATION.TURTLE)
727     print reserializedPayload
728     
729     tsResponse.printOut()
730     
731
732
733 def propertySerializeParseTest():
734     o = Evaluation()
735     s = SystemOfInterest()
736     s.setSameAs("my system")
737     
738     a = Activity()
739     i = Input()
740     i.add("abcd", "1234")
741     a.addInput(i)
742     #o.addActivity(a)
743     
744     route = Route()
745     route.addRoutePoint(Coordinates(latitude = 61.15, longitude = 25.89))
746     route.addRoutePoint(Coordinates(latitude = 61.14, longitude = 24.78))
747     route.addRoutePoint(Coordinates(latitude = 61.14, longitude = 24.61))
748     
749     waypoints = Waypoints()
750     wp1 = Waypoint()
751     wp2 = Waypoint()
752     addr1 = Address()
753     addr2 = Address()
754     
755     wp1.setLocation(Coordinates(latitude = 60.2, longitude = 24.1))
756     wp2.setLocation(Coordinates(latitude = 61.2, longitude = 25.1))
757     wp1.setInstant(datetime.datetime.now())
758     wp1.setAddress(addr1)
759     wp2.setAddress(addr2)
760     waypoints.addWaypoint(wp1)
761     waypoints.addWaypoint(wp2)
762     
763     route.addRoutePoint(Coordinates(latitude = 61.15, longitude = 25.89))
764     route.addRoutePoint(Coordinates(latitude = 61.14, longitude = 24.78))
765     route.addRoutePoint(Coordinates(latitude = 61.14, longitude = 24.61))
766
767     map = Map()
768     map.insert("key1", "Value1")
769     map.insert("key2", "Value2")
770     map.insert("key3", waypoints)
771     map.insert("key4", [Variant("Value3"), Variant("Value4"), Variant("Value5")])
772     map.insert("key5", ["Value6", "Value7", "Value8"])
773     
774     s.setSameAs("http://same.as")
775     o.add("my numeric para", 1234.5678)
776     o.add("my string para", "test string")
777     o.add("my variant para", Variant(1234))
778     o.add("my simple object para", s)
779     o.add("my complex object para", a)
780     o.add("list para", route)
781     o.add("somelist", ["ValueA", "ValueB", "ValueC"])
782     o.add("map", map)
783     o.add(URIRef("http://www.example.com/value"), "examplevalue")
784     o.add(URIRef(NS.SMARTAPI + "foo"), "bar")
785     
786     serialized = Tools().toString(o, SERIALIZATION.TURTLE)
787     print "Serialized", serialized
788     
789     #o_parsed = Obj.parse(Tools().getResourceByType(RESOURCE.EVALUATION, Tools().fromString(serialized, SERIALIZATION.TURTLE)))
790     # this works too.
791     #o_parsed = Evaluation.parse(Tools().getResourceByType(RESOURCE.EVALUATION, Tools().fromString(serialized, SERIALIZATION.TURTLE)))    
792     # this alternative also works
793     o_parsed = Evaluation.fromString(serialized, SERIALIZATION.TURTLE)
794     reserialized = Tools().toString(o_parsed, SERIALIZATION.TURTLE)
795         
796     print "-------------------------------------"
797     print reserialized
798     
799
800 def inputOutputTest():
801     r1 = Request("http://me.com")
802     
803     a1 = Activity("http://you.com/colorcalculator")
804     i = Input()
805     map = Map()
806     map.insert("dataitems", "color")
807     map.insert("rgb", ["red", "green", "blue"])
808     i.add("callId", "1234")
809     i.add("callParams", map)
810     a1.addInput(i)
811     r1.addActivity(a1)
812     
813     print "Request:\n", Tools().serializeRequest(r1, serialization = SERIALIZATION.getMimeType(SERIALIZATION.TURTLE))[0]
814     
815     r2 = Response("http://you.com")
816     a2 = Activity("http://you.com/colorcalculator")
817     o = Output()
818     o.add("callId", "1234")
819     o.add("result", "white")
820     a2.addOutput(o)
821     r2.addActivity(a2)
822     
823     print "Response:\n", Tools().serializeRequest(r2, serialization =SERIALIZATION.getMimeType( SERIALIZATION.TURTLE))[0]
824     
825     
826 def parameterSerializeParseTest():
827     pass
828     
829     
830 def physicalEntityTest():
831     entity = PhysicalEntity()
832     size = Size()
833     speed = Velocity()
834     orientation = Orientation()
835     direction = Direction()
836     
837     size.setWidth(ValueObject(unit = NS.UNIT + "Centimeter", value = Variant(100.2)))
838     size.setHeight(ValueObject(unit = NS.UNIT + "Centimeter", value = Variant(301.9)))
839     size.setDepth(ValueObject(unit = NS.UNIT + "Centimeter", value = Variant(11.222)))
840     
841     orientation.setYaw(ValueObject(unit = NS.UNIT + "DegreeAngle", value = Variant(270)))
842     orientation.setPitch(ValueObject(unit = NS.UNIT + "DegreeAngle", value = Variant(45)))
843     orientation.setRoll(ValueObject(unit = NS.UNIT + "DegreeAngle", value = Variant(301)))
844     
845     direction.setBearing(ValueObject(unit = NS.UNIT + "DegreeAngle", value = Variant(121)))
846     direction.setHeading(ValueObject(unit = NS.UNIT + "DegreeAngle", value = Variant(243)))
847
848     speed.setLinearVelocityX(ValueObject(unit = URIRef(NS.UNIT + "MeterPerSecond"), value = Variant(3.4)))
849     speed.setLinearVelocityY(ValueObject(unit = NS.UNIT + "MeterPerSecond", value = Variant(30.1)))
850     speed.setAngularVelocityY(ValueObject(unit = NS.UNIT + "RadianPerSecond", value = Variant(54.3)))
851     
852     entity.addType(RESOURCE.PHYSICALENTITY)
853     entity.addType(RESOURCE.CAR)
854     entity.setName("This is a test entity");
855     entity.setVelocity(speed);
856     entity.setOrientation(orientation);
857     entity.setDirection(direction);
858     entity.setSize(size);
859     
860     entity.setWeight(ValueObject(unit = NS.UNIT + "Kilogram", value = Variant(222)))
861     
862     serialized = Tools().toString(entity, SERIALIZATION.TURTLE)
863     print "Serialized:"
864     print serialized
865     
866     model = Tools().fromString(serialized, SERIALIZATION.TURTLE)
867     res = Tools().getResourceByType(RESOURCE.PHYSICALENTITY, model)
868     parsedEntity = PhysicalEntity().parse(res)
869     
870     print "Width: ", parsedEntity.getSize().getWidth().getValue()
871     print "Depth: ", parsedEntity.getSize().getDepth().getValue()
872     
873     print "\nRe-serializing...";
874     reserializedPayload = Tools().toString(parsedEntity, SERIALIZATION.TURTLE)
875     print reserializedPayload
876
877
878 def waypointsTest():
879     waypoints = Waypoints()
880     
881     wp1 = Waypoint()
882     wp2 = Waypoint()
883     wp3 = Waypoint()
884     
885     loc1 = Address()
886     loc2 = Address()
887     loc3 = Address()
888     coords1 = Coordinates(latitude = 60.2, longitude = 24.1)
889     
890     route = Route()
891     route.addRoutePoint(Coordinates(latitude = 61.15, longitude = 25.89))
892     route.addRoutePoint(Coordinates(latitude = 61.14, longitude = 24.78))
893     route.addRoutePoint(Coordinates(latitude = 61.14, longitude = 24.61))
894
895     #for i in range(100000):
896     for i in range(5):
897         route.addRoutePoint(Coordinates(latitude = 61.14+i/1000.0, longitude = 24.61-i/1000.0))
898         
899     loc1.setCity("Pori")
900     loc2.setCity("Espoo")
901     loc2.setCountry("Finland")
902     loc2.setStreetAddress("Otakaari 1")
903     loc2.setZipCode("02150")
904     loc3.setCity("Kuopio")
905     
906     wp1.setInstant(datetime.datetime.now())
907     wp1.setAddress(loc1)
908     wp1.setLocation(coords1)
909
910     wp2.setAddress(loc2)
911
912     wp3.setAddress(loc3)
913     wp3.setRoute(route)
914
915     waypoints.addWaypoint(wp1)
916     waypoints.addWaypoint(wp2)
917     waypoints.addWaypoint(wp3)
918     
919     oStart = datetime.datetime.now()
920     serialized = Tools().toString(waypoints, SERIALIZATION.TURTLE)
921     oEnd = datetime.datetime.now()
922     print "Serialized (elapsed %s:"%(oEnd - oStart)
923     print serialized
924
925     oStart = datetime.datetime.now()
926     model = Tools().fromString(serialized, SERIALIZATION.TURTLE)
927     res = Tools().getResourceByType(RESOURCE.WAYPOINTS, model)
928     parsedEntity = Waypoints().parse(res)
929     oEnd = datetime.datetime.now()
930     print "Parsed (elapsed %s:"%(oEnd - oStart)
931     
932     for wp in waypoints.getWaypoints():
933         print "WP:", wp.getInstant().getValue() if wp.getInstant() else "no instant"
934     
935     wpr = waypoints.getWaypoints()[2]
936     for rp in wpr.getRoute().getRoutePoints():
937         print "RP:", rp.getLatitude(), rp.getLongitude()
938     
939     print "\nRe-serializing...";
940     reserializedPayload = Tools().toString(parsedEntity, SERIALIZATION.TURTLE)
941     print reserializedPayload
942
943
944 def basicListSerializeParseTest():
945     now = datetime.datetime.now()
946     
947     # Raw lists
948     # This should by default create an ordered list widhout a base object
949     o = Input()
950     o.setName("Some input")
951     l = [1, 2, 3, "ab", o, 4]
952     
953     stringData = Tools().toString(l, SERIALIZATION.TURTLE)
954     print "Ordered list"
955     print stringData
956     o = Tools().fromStringAsList(stringData, SERIALIZATION.TURTLE)
957     print Tools().toString(o, SERIALIZATION.TURTLE)
958     
959     # Explicitly create lists
960     ll = LinkedList()
961     il = ItemizedList()
962     
963     ll.add_items(l)
964     il.add_items(l)
965     
966     print "Linked list"
967     stringData = Tools().toString(ll, SERIALIZATION.TURTLE)
968     print stringData
969     o  = Tools().fromStringAsList(stringData, SERIALIZATION.TURTLE)
970     print Tools().toString(o, SERIALIZATION.TURTLE)
971     
972     print "Itemized list"
973     stringData = Tools().toString(il, SERIALIZATION.TURTLE)
974     print stringData
975     o  = Tools().fromStringAsList(stringData, SERIALIZATION.TURTLE)
976     print Tools().toString(o, SERIALIZATION.TURTLE)
977     
978     # Lists within a context (should use ordered list by default
979     ts = TimeSeries()
980     ts.setType(RESOURCE.TIMESERIES)
981     
982     testList = []
983     
984     for i in range(10):
985         e = Evaluation()
986         e.setValue(Variant(i));
987         e.setInstant(now + datetime.timedelta(days = i))
988         testList.append(e)
989     
990     ts.setList(testList)
991     
992     stringData = Tools().toString(ts, SERIALIZATION.TURTLE)
993     
994     print "Serialized timeseries:"
995     print stringData
996
997     print "Parsing back the serialized data..."
998     tsParsed = Tools().toObj(stringData, SERIALIZATION.TURTLE)
999     print Tools().toString(tsParsed, SERIALIZATION.TURTLE)
1000     
1001     if tsParsed.hasList():
1002         tsl = tsParsed.getList()
1003         for j in range(tsParsed.getListSize()):
1004             e = tsl.get_item(j)
1005             print "Value:", e.getInstant(), e.getValue().getValue()
1006
1007     print '\n---explain TimeSeries---\n'
1008     #ts.explain()
1009     print '\n---print TimeSeries---\n'
1010     #ts.printOut()
1011
1012 def baseObjectListSerializeParseTest():
1013     # Raw lists
1014     # This should by default create an ordered list without a base object
1015     d = Device()
1016     d.add(PROPERTY.GROUNDSPEED, 5)
1017     d.add(PROPERTY.GROUNDSPEED, 10)
1018     d.add(PROPERTY.GROUNDSPEED, 20)
1019     print Tools().toString(d, SERIALIZATION.TURTLE)
1020     
1021     o = Input()
1022     o.setName("Some input")
1023     l = [1, 2, 3, "ab", o, 4]
1024     
1025     stringData = Tools().toString(l, SERIALIZATION.TURTLE)
1026     #print "Ordered list"
1027     #print stringData
1028     o = Tools().fromStringAsList(stringData, SERIALIZATION.TURTLE)
1029     print Tools().toString(o, SERIALIZATION.TURTLE)
1030     
1031     base = ValueObject(unit = NS.UNIT + "Centimeter")
1032     # Explicitly create lists
1033     ll = LinkedList()
1034     ol = OrderedList()
1035     il = ItemizedList()
1036     nl = NudeList()
1037     
1038     ll.setBaseObject(base)
1039     il.setBaseObject(base)
1040     ol.setBaseObject(base)
1041     nl.setBaseObject(base)
1042     
1043     ll.add_items(l)
1044     il.add_items(l)
1045     ol.add_items(l)
1046     nl.add_items(l)
1047     
1048     ll.setBaseObjectProperty(PROPERTY.FRESHNESS)
1049     il.setBaseObjectProperty(PROPERTY.FRESHNESS)
1050     ol.setBaseObjectProperty(PROPERTY.FRESHNESS)
1051     nl.setBaseObjectProperty(PROPERTY.FRESHNESS)
1052     
1053     print "Linked list"
1054     stringData = Tools().toString(ll, SERIALIZATION.TURTLE)
1055     print stringData
1056     o = Tools().fromStringAsList(stringData, SERIALIZATION.TURTLE)
1057     print o
1058     
1059     print "Itemized list"
1060     stringData = Tools().toString(il, SERIALIZATION.TURTLE)
1061     print stringData
1062     o = Tools().fromStringAsList(stringData, SERIALIZATION.TURTLE)
1063     print o
1064     
1065     print "Ordered list"
1066     stringData = Tools().toString(ol, SERIALIZATION.TURTLE)
1067     print stringData
1068     o = Tools().fromStringAsList(stringData, SERIALIZATION.TURTLE)
1069     print o
1070     
1071     print "Nude list"
1072     stringData = Tools().toString(nl, SERIALIZATION.TURTLE)
1073     print stringData
1074     o = Tools().fromStringAsList(stringData, SERIALIZATION.TURTLE)
1075     print o
1076     
1077     # Lists within a context (should use ordered list by default
1078     ts = TimeSeries()
1079     ts.setType(RESOURCE.TIMESERIES)
1080     
1081     testList = [i for i in range(10)]
1082     e = Evaluation()
1083     e.setInstant(datetime.datetime.now())
1084     
1085     ts.setList(testList, baseObject=e, baseObjectProperty=PROPERTY.FRESHNESS)
1086     
1087     stringData = Tools().toString(ts, SERIALIZATION.TURTLE)
1088     
1089     print "Serialized data:"
1090     print stringData
1091
1092     print "Parsing back the serialized data..."
1093     tsParsed = Tools().toObj(stringData, SERIALIZATION.TURTLE)
1094     print Tools().toString(tsParsed, SERIALIZATION.TURTLE)
1095     
1096     if tsParsed.hasList():
1097         tsl = tsParsed.getList()
1098         for j in range(tsParsed.getListSize()):
1099             e = tsl.get_object(j)
1100             print "Value:", e.getInstant(), e.get(PROPERTY.FRESHNESS)
1101             
1102
1103 def timeseriesListSerializeParseTest():
1104     ts = TimeSeries()
1105     ts.setList(OrderedList())
1106     start = datetime.datetime.now()
1107     end = start + Factory.createDuration(0, 0, 0, 5, 0, 0)
1108     # 5 hours
1109     ts.setTemporalContext(TemporalContext(start=start, end=end))
1110     # create valueobject as a base object
1111     baseVo = ValueObject('http://test.vo')
1112     baseVo.setUnit(RESOURCE.DEGREECELSIUS)
1113     baseVo.setQuantity(RESOURCE.TEMPERATURE)
1114     ts.setBaseObject(baseVo)
1115     ts.setBaseObjectProperty(URIRef("http://base.object.com"))
1116     # 1 hour timestep between data values
1117     timeStep = Factory.createDuration(0, 0, 0, 1, 0, 0)
1118     ts.setTimeStep(Variant(timeStep))
1119     # add timeseries values
1120     current = start
1121     i = 0
1122     while current < end:
1123         ts.addListItem(i)
1124         i += 1
1125         current += timeStep
1126         
1127     stringData = Tools().toString(ts, SERIALIZATION.TURTLE)
1128     
1129     print "Serialized data:"
1130     print stringData
1131
1132     print "Parsing back the serialized data..."
1133     tsParsed = Tools().toObj(stringData, SERIALIZATION.TURTLE)
1134     print Tools().toString(tsParsed, SERIALIZATION.TURTLE)
1135
1136     
1137 def listExplainTest():
1138     '''
1139     Test case for testing explain()/printOut() function, serialization/parse for all kinds of List. 
1140     
1141     '''
1142     print '\n listExplainTest()**********\n'
1143     now = datetime.datetime.now()
1144     
1145     ts = TimeSeries()
1146     ts.setType(RESOURCE.TIMESERIES)
1147     
1148     testList = []
1149     
1150     for i in range(3):
1151         e = Evaluation()
1152         e.setValue(Variant(i));
1153         e.setInstant(now + datetime.timedelta(days = i))
1154         testList.append(e)
1155     
1156     ll = LinkedList()
1157     ll.add_items(testList)
1158     ts.setList(ll)
1159     
1160     stringData = Tools().toString(ts, SERIALIZATION.TURTLE)
1161     print "\n >>>>>>>>>>> linked list"
1162     print stringData
1163     o = Tools().toObj(stringData)
1164     print '\n    parse and then reserialize: \n'
1165     
1166     print Tools().toString(o, SERIALIZATION.TURTLE)
1167     
1168     print '\n---explain TimeSeries with linkedlist---\n'    
1169     ts.explain()
1170     print '\n---print TimeSeries with linkedlist---\n'    
1171     ts.printOut()
1172      
1173     
1174     il = ItemizedList()
1175     il.add_items(testList)    
1176     ts.setList(il)
1177     
1178     stringData = Tools().toString(ts, SERIALIZATION.TURTLE)
1179     print "\n >>>>>>>>>itemized list"
1180     print stringData
1181     o = Tools().toObj(stringData)
1182     print '\n    parse and then reserialize: \n'
1183     
1184     print Tools().toString(o, SERIALIZATION.TURTLE)
1185     
1186     print '\n---explain TimeSeries with itemizedList---\n'    
1187     ts.explain()
1188     print '\n---print TimeSeries with itemizedList---\n'    
1189     ts.printOut()
1190     
1191     
1192     ol = OrderedList()
1193     ol.add_items(testList)
1194     ts.setList(ol)
1195     stringData = Tools().toString(ts, SERIALIZATION.TURTLE)
1196     print "\n >>>>>>>>>ordered list"
1197     print stringData
1198     o = Tools().toObj(stringData, SERIALIZATION.TURTLE)
1199     print '\n    parse and then reserialize: \n'
1200     
1201     print Tools().toString(o, SERIALIZATION.TURTLE)
1202     
1203     print '\n---explain TimeSeries with orderedlist---\n'    
1204     ts.explain()
1205     print '\n---print TimeSeries with orderedlist---\n'    
1206     ts.printOut()
1207
1208     
1209     nl = NudeList()
1210     nl.add_items(testList)
1211     ts.setList(nl)
1212     stringData = Tools().toString(ts, SERIALIZATION.TURTLE)
1213     print "\n >>>>>>>>>Nude list"
1214     print stringData
1215     o = Tools().toObj(stringData, SERIALIZATION.TURTLE)
1216     print '\n    parse and then reserialize: \n'
1217     
1218     print Tools().toString(o, SERIALIZATION.TURTLE)
1219     
1220
1221 def listSpeedTestSerialize():
1222     import simplejson
1223     l = [x for x in range(10)]
1224     
1225     a = { "array": l }
1226     print "JSON list"
1227     jStart = datetime.datetime.now()
1228     stringData = simplejson.dumps(a)
1229     jEnd = datetime.datetime.now()
1230     
1231     print "Ordered list"
1232     oStart = datetime.datetime.now()
1233     stringData = Tools().toString(l, SERIALIZATION.TURTLE)
1234     oEnd = datetime.datetime.now()
1235     
1236     # Explicitly create lists
1237     print "Itemized list"
1238     il = ItemizedList()
1239     il.add_items(l)
1240     iStart = datetime.datetime.now()
1241     stringData = Tools().toString(il, SERIALIZATION.TURTLE)
1242     iEnd = datetime.datetime.now()
1243     
1244     print "Linked list"
1245     ll = LinkedList()
1246     ll.add_items(l)
1247     lStart = datetime.datetime.now()
1248     stringData = Tools().toString(ll, SERIALIZATION.TURTLE)
1249     lEnd = datetime.datetime.now()
1250     
1251     print "Nude list"
1252     nl = NudeList()
1253     nl.add_items(l)
1254     nStart = datetime.datetime.now()
1255     stringData = Tools().toString(nl, SERIALIZATION.TURTLE)
1256     print stringData
1257     nEnd = datetime.datetime.now()
1258     
1259     print "RESULTS"
1260     print "Ordered list", (oEnd - oStart)
1261     print "Unordered list", (iEnd - iStart)
1262     print "Linked list", (lEnd - lStart)
1263     print "Nude list", (nEnd - nStart)
1264     print "JSON reference", (jEnd - jStart)
1265
1266
1267 def listSpeedTestSerializeAndParse():
1268     import simplejson
1269     l = [x for x in range(10)]
1270     
1271     print "\n\nOrdered list"
1272     oStart = datetime.datetime.now()
1273     stringData = Tools().toString(l, SERIALIZATION.TURTLE)
1274     oEnd = datetime.datetime.now()
1275     print stringData
1276     opStart = datetime.datetime.now()
1277     try:
1278         o = Tools().fromStringAsObj(stringData, SERIALIZATION.TURTLE)
1279     except:
1280         o = Tools().fromStringAsList(stringData, SERIALIZATION.TURTLE)
1281     opEnd = datetime.datetime.now()
1282     #print Tools().toString(o, SERIALIZATION.TURTLE)
1283     print "-----------------"
1284     print "Serialize:", (oEnd - oStart)
1285     print "Parse:", (opEnd - opStart)
1286     
1287     
1288     # Explicitly create lists
1289     print "\n\nItemized list"
1290     il = ItemizedList()
1291     il.add_items(l)
1292     iStart = datetime.datetime.now()
1293     stringData = Tools().toString(il, SERIALIZATION.TURTLE)
1294     iEnd = datetime.datetime.now()
1295     print stringData
1296     ipStart = datetime.datetime.now()
1297     try:
1298         o = Tools().fromStringAsObj(stringData, SERIALIZATION.TURTLE)
1299     except:
1300         o = Tools().fromStringAsList(stringData, SERIALIZATION.TURTLE)
1301     ipEnd = datetime.datetime.now()
1302     #print Tools().toString(o, SERIALIZATION.TURTLE)
1303     print "-----------------"
1304     print "Serialize:", (iEnd - iStart)
1305     print "Parse:", (ipEnd - ipStart)
1306     
1307     print "\n\nLinked list"
1308     ll = LinkedList()
1309     ll.add_items(l)
1310     lStart = datetime.datetime.now()
1311     stringData = Tools().toString(ll, SERIALIZATION.TURTLE)
1312     lEnd = datetime.datetime.now()
1313     print stringData
1314     lpStart = datetime.datetime.now()
1315     #try:
1316     #    o = Tools().fromStringAsObj(stringData, SERIALIZATION.TURTLE)
1317     #except:
1318     #    o = Tools().fromStringAsList(stringData, SERIALIZATION.TURTLE)
1319     lpEnd = datetime.datetime.now()
1320     #print Tools().toString(o, SERIALIZATION.TURTLE)
1321     print "-----------------"
1322     print "Serialize:", (lEnd - lStart)
1323     print "Parse:", (lpEnd - lpStart)
1324     
1325     print "\n\nNude list"
1326     nl = NudeList()
1327     nl.add_items(l)
1328     nStart = datetime.datetime.now()
1329     stringData = Tools().toString(nl, SERIALIZATION.TURTLE)
1330     nEnd = datetime.datetime.now()
1331     print stringData
1332     npStart = datetime.datetime.now()
1333     try:
1334         o = Tools().fromStringAsObj(stringData, SERIALIZATION.TURTLE)
1335     except:
1336         o = Tools().fromStringAsList(stringData, SERIALIZATION.TURTLE)
1337     npEnd = datetime.datetime.now()
1338     #print Tools().toString(o, SERIALIZATION.TURTLE)
1339     print "-----------------"
1340     print "Serialize:", (nEnd - nStart)
1341     print "Parse:", (npEnd - npStart)
1342
1343     
1344 def listOfMapsTest():
1345     print "List of maps test"
1346     
1347     a = Activity()
1348     i = Input()
1349     o = Output()
1350     
1351     a.addInput(i)
1352     a.addOutput(o)
1353     
1354     # Input
1355     controllable_appliances = []
1356     # Test adding something empty
1357     i.add("ControllableAppliances", controllable_appliances)
1358     
1359     appliance0 = Map()
1360     appliance0.insert("Active", True)
1361     i.add("FirstAppliance", appliance0)
1362     
1363     appliance1 = Map()
1364     appliance1.insert("Active", True)
1365     appliance1.insert("Whatever", 1)
1366     appliance1.insert("ConsumptionRate", 1.267)
1367     appliance1.insert("Name", "String content")
1368     
1369     controllable_works = []
1370     works1 = Map()
1371     works1.insert("EarlyStartPeriod", 2147483647)
1372     works1.insert("LateStopPeriod", 2147483647)
1373     works1.insert("WorkDuration", 2147483647)
1374     controllable_works.append(works1)
1375     appliance1.insert("ControllableWorks", works1)
1376     controllable_appliances.append(appliance1)
1377     
1378     # Output
1379     controllable_appliance_result = []
1380     appliance_result_1 = Map()
1381     appliance_result_1.insert("Name", "String content")
1382     controllable_appliance_work_result = []
1383     appliance_result_1.insert("ControllableWorkResult", controllable_appliance_work_result)
1384     work_result_1 = Map()
1385     controllable_appliance_work_result.append(work_result_1)
1386     usage_information = Map()
1387     usage_information.insert("StartPeriod", 2147483647)
1388     usage_information.insert("StopPeriod", 2147483647)
1389     usage_information.insert("WorkDuration", 2147483647)
1390     work_result_1.insert("UsageInformation", usage_information)
1391     
1392     period_consumptions = []
1393     period_1 = Map()
1394     period_1.insert("Period", 2147483647)
1395     period_1.insert("Value", 1.26743)
1396     period_consumptions.append(period_1)
1397     work_result_1.insert("PeriodConsumption", period_consumptions)
1398     controllable_appliance_result.append(appliance_result_1)
1399     o.add("ControllableApplianceResult", controllable_appliance_result)
1400     
1401     serialized = Tools().toString(a, SERIALIZATION.TURTLE)
1402     print "Serialized:\n", serialized
1403     a_parsed = Tools().fromStringAsObj(serialized, serialization = SERIALIZATION.TURTLE)
1404     reserialized = Tools().toString(a_parsed, SERIALIZATION.TURTLE)
1405     
1406     print "----"
1407     print "Re-serialized:\n", reserialized
1408     
1409 def hugeDataTest():
1410     print "HugeDataTest: Not implemented yet"
1411     myId = "http://seasdemos.asema.com/cplusplus/controlcommandsender/Cabcd"
1412
1413     now = datetime.datetime.now()
1414
1415     req = ResponseFactory().create(myId)
1416     req.setSameAs("http://hugedata.test")
1417     req.setName("Huge dataset test")
1418     req.setIdentifierUri("http://huge.data.uri")
1419         
1420     for i in range(4000):
1421         e = Evaluation()
1422         e.setValue(Variant(i));
1423         e.setInstant(now + datetime.timedelta(days = i))
1424         req.add("http://evaluation.com", e)
1425         
1426     stringData = Tools().toString(req, SERIALIZATION.TURTLE)
1427     
1428     print "Serialized data:"
1429     print stringData
1430
1431     print "Parsing back the serialized data..."
1432
1433     model = Tools().fromString(stringData, SERIALIZATION.TURTLE)
1434     res = Tools().getResourceByType(RESOURCE.RESPONSE, model)
1435     reqParsed = Response().parse(res)
1436     
1437     for p in reqParsed.listProperties()[0]:
1438         print "Value:", e.getValue().getValue()
1439     
1440 def registrationTest():
1441 #     pubKey = SmartAPICrypto().downloadPublicKey("http://www.client.com/seas/Cclient", KEYSERVER_URI)
1442 #     privKey = SmartAPICrypto().loadPrivateKey('testkey_private.pem')
1443     
1444     serverIdentity = "http://seasexamples.asema.com/api/Ctestserver"
1445     service = createSampleRegistrationEntity(serverIdentity)
1446     agent = RegistrationAgent(serverIdentity)
1447     agent.addEntity(service)
1448     
1449     agent.setDebugMode(True)
1450     #payload = agent.generateEncryptedRegistrationMessage(pubKey, service)
1451     
1452     """
1453     # Test sets for compatibility
1454     # C++
1455     payload = "PDvrIUEup/eiTAolieUHSFBgV+UI2h0vvuGhHQjnS5QXlBmPKgO4WrJTUyV60Yqx7/baPg28or6Zat4HokK0ZbXux6xUMvYUTkGpzSjrnaulrn7biv5g/p7dTKx89JkVuW0K3Oci2ICDdg4PcYC1EH/7EWVaLUoUcPb1qRn/qBpsDwieBvvHU4Solo59meo26Ch+CL4hLtsTtrdZmtCvUkn1lIFm9vc3WRo5jXZP9vpR5UMRVXDCu007fqeAD7ppgJHI6/U3kIiyc3n54yvgyzKShlAeORIaxNxMSY09QTEtoGr92M5iBoOZYsfdxndfHy0yPNuGvOhO9ab6nrXwlA==";
1456     payload += '\n';
1457     payload += "LCBcyYE+8ILCD43DOQGBsg==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";
1458     
1459     # Java
1460     payload = "Agj9Y55uNpgn4Y2Z6HqSOjtdTCBpQTW1JniLaqWe7UCZShuryBObDxdWYVSpVJgqKnrU/LmbHVaIGuuOWnhUP2G9oVCV3fYBvFQz9ZXXoz1PkzF0sIh7aBFFfFTA9dSMddZWxnILyL+qpR4dyOHlyHCQBEprmOgDSaJ3YWVj4cgQkfSLEFdYHHG1hqkwYwJ41Ni+RRRd7yT9E1oIuuYme5FRzFXmauX+ZkrXjJDbDrak15Xbng1m356+5wxOufcE4mnBQbYl60ujmXqZZh/wM+80xImC51o5RGjTXcrUDYA3aCvSDbG0qCzLlS8/NQfaa200hts5xTZ+8eqQVTHLWA=="
1461     payload += '\n';
1462     payload += "fibcjFUMHedV3Dxz889SLw==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"
1463     """ 
1464     response = agent.registrate()
1465     print '\n registration result:'
1466     if response.hasErrors():
1467         for err in response.getErrors():
1468             print 'Error message: ', err.getErrorMessage()
1469        
1470     if response.hasStatus():
1471         status = response.getStatus()
1472         print 'status: ' 
1473         status.turtlePrint()
1474         # check if the operation was successful
1475         if ( status.isOfType(RESOURCE.ERROR)):
1476             print "Registration failed."
1477         elif (status.isOfType(RESOURCE.READY)):
1478             print "Registration successful."
1479      
1480     print '\n now testing deregister'
1481     
1482 #     response2 = agent.deRegistrate()
1483 #     if response2.hasErrors():
1484 #         for err in response2.getErrors():
1485 #             print 'Error message: ', err.getErrorMessage()
1486                 
1487     
1488 def getPemPublicKey(fileName):
1489     f = open(fileName,'r')
1490     return RSA.importKey(f.read())
1491
1492 def getPemPrivateKey(fileName):
1493      f = open(fileName,'r')
1494      return RSA.importKey(f.read())
1495
1496 def  createSampleRegistrationEntity(serverIdentity):
1497     from SmartAPI.model.Obj import Obj
1498     serverName = "A Python sample route energy calculation service";
1499         
1500     service = Service(serverIdentity);
1501         
1502     # Service metadata
1503     owner = Organization();
1504     acmeAddress = Address();
1505     iface = InterfaceAddress();
1506         
1507     iface.setHost("www.acme.com");
1508     iface.setScheme("https");
1509     iface.setPath("/seas/v1.0e1.0/access");
1510     acmeAddress.setStreetAddress("Giant Rubber Band Street");
1511     acmeAddress.setZipCode("12345");
1512     acmeAddress.setCity("Fairfield, Python");
1513     owner.setName("Acme Industries");
1514     owner.setAddress(acmeAddress);
1515         
1516     service.addInterface(iface);
1517     service.addOwner(owner);
1518     service.setName(serverName);
1519     service.setDescription("A route calculation service that in addition to length and driving time calculates the amount of energy consumed in the battery. Takes as parameters various efficiency factors such as weight and drag.");
1520     service.addWebsite("http://www.acme.com/acmeoptimizers/roadrunner/beep/beep");
1521         
1522         
1523     # API payload data
1524     a = Activity();
1525     i = Input();
1526     o = Output();
1527     a.addOutput(o);
1528     a.addInput(i);
1529     service.addCapability(a);
1530         
1531     car = PhysicalEntity();
1532     car.setWeight(Factory().createValueObject(unit = NS.UNIT + "Kilogram", description = "Vehicle's weight without any consumables or passengers."));
1533     car.add("frontalAerodynamicCoefficient", Factory().createValueObject(unit = NS.UNIT + "SquareMeter", description = "Product of vehicle's frontal area and aerodynamic coefficient"));
1534     car.add("tireRollingResistanceCoefficient", Factory().createValueObject(datatype = Obj(DATATYPE.INTEGER), description = "Vehicle's tire rolling resistance coefficient, in interval ]0, 1["));
1535     car.add("gearEfficiencyCoefficient", Factory().createValueObject(description = "Vehicle's efficiency coefficient between engine and gear, in interval ]0, 1["));
1536     car.add("batteryCapacity", Factory().createValueObject(unit = NS.UNIT + "KilowattHour", description = "Vehicle's capacity of the battery (enter only if electric vehicle or hybrid rechargeable, 0 otherwise"));
1537     car.add("extraLoadWeight", Factory().createValueObject(unit = NS.UNIT + "Kilogram", description = "Vehicle's extra load (consumables and passengers weight)"));
1538     car.add("auxiliaryEquipmentConsumption", Factory().createValueObject(unit = NS.UNIT + "Watt", description = "Vehicle's instantaneous auxiliary equipments consumption"));
1539     car.add("maximumAcceleration", Factory().createValueObject(unit = NS.UNIT + "MeterPerSecondSquared", description = "Maximum acceleration (> 0.1), based on vehicle's acceleration capacity and expected driving behavior"));
1540     car.add("maximumDeceleration", Factory().createValueObject(unit = NS.UNIT + "MeterPerSecondSquared", description = "Maximum deceleration (< -0.1), based on vehicle's braking capacity and expected driving behavior"));
1541     i.add("vehicleData", car);
1542         
1543     tc = TemporalContext();
1544     averageVelocity = Velocity();
1545     route = Route();
1546         
1547     tc.setDescription("The timespan estimated for traveling the route.");
1548     averageVelocity.setDescription("Estimated average speed for the travel.");
1549         
1550     averageVelocity.setGroundSpeed(Factory().createValueObject(unit = NS.UNIT + "KilometerPerHour", description = "Velocity component in relation to road surface."));
1551     
1552     route.setLength(Factory().createValueObject(unit = NS.UNIT + "Kilometer", description = "Total length of the calculated route."));
1553     route.setEnergyConsumption(Factory().createValueObject(unit = NS.UNIT + "KilowattHour", description = "Total energy consumed in driving the route."));
1554     route.setAverageVelocity(averageVelocity);
1555     route.setDuration(tc);
1556         
1557     o.add("routeData", route);
1558     return service
1559
1560
1561 def registrySearchTest():
1562     serverIdentity = "http://seasexamples.asema.com/api/Ctestserver"
1563     agent = SearchAgent(serverIdentity)
1564     SearchAgent.setDebugMode(True)
1565     
1566     # all entities in Otaniemi, Espoo as defined by the given polygon
1567 #     polygon = []
1568 #     polygon.append(Coordinates(None, 60.178, 24.829))
1569 #     polygon.append(Coordinates(None, 60.183, 24.83))
1570 #     polygon.append(Coordinates(None, 60.1926, 24.842))
1571 #     polygon.append(Coordinates(None, 60.187, 24.809))
1572 #     polygon.append(Coordinates(None, 60.181, 24.818))
1573 #     agent.polygonSearchArea(polygon)
1574 #       
1575 #     entities = agent.search()
1576     # or
1577     #entities = SearchAgent.searchById(serverIdentity, 500, "http://127.0.0.1/smart/97f2468a47792c27eec4f82fa4795cf35e94ef3b")
1578     entities =  SearchAgent.fetchBySmartAPIId(serverIdentity, "http://acme.com/services/Cweather")
1579     
1580     print entities
1581 #     for e in entities:
1582 #         print e.getName(), "-", e.getId() 
1583 #         for ty in e.getTypes():
1584 #             print '------', ty   
1585         #e.turtlePrint()
1586     
1587 def capacityTest():
1588     now = datetime.datetime.now()
1589     
1590     c = Capacity(value = Variant(3), maximum = Variant(4))
1591     stringData = Tools().toString(c, SERIALIZATION.TURTLE)
1592     
1593     print "Serialized data:"
1594     print stringData
1595
1596     print "Parsing back the serialized data..."
1597
1598     c_parsed = Tools().fromStringAsObj(stringData, serialization = SERIALIZATION.TURTLE)
1599     reserialized = Tools().toString(c_parsed, SERIALIZATION.TURTLE)
1600     
1601     print "----"
1602     print "Re-serialized:\n", reserialized
1603     
1604     
1605 def cryptoTests():
1606     crypto = SmartAPICrypto()
1607     clientKeyId = "http://www.acme.com/services/abcd/"
1608     publicKeyServer = "http://127.0.0.1:11371"
1609     
1610     # Test the generation of keypairs
1611     priv, pub = crypto.generateKeyPair()
1612 #     print "Got private and public keys"
1613 #     print "Public is:\n", crypto.convertPublicKeyToPemFormat(pub)
1614 #     
1615 #     # Test fetching a public key for clientIdUri
1616 #     clientPubKey = crypto.downloadPublicKey(clientKeyId, publicKeyServer)
1617 #     print "Got a public key\n", clientPubKey
1618 #     
1619 #     # Test loading keys    
1620 #     current_path = os.getcwd()
1621     pubKey = pub #getPemPublicKey(os.path.join(current_path, "testkey_public.pem"))
1622     privKey = priv # getPemPrivateKey(os.path.join(current_path,"testkey_private.pem"))
1623     
1624     # Test signing and hashes
1625     testData = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras dapibus, sapien eu consequat faucibus, ligula purus tincidunt orci, tincidunt mattis orci dolor in eros. Praesent eget enim ante. Curabitur eleifend ipsum orci, quis vehicula lectus auctor vitae. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean congue nisl lectus. Fusce varius aliquam velit at varius. Integer eu bibendum mi, eget rhoncus metus. Morbi efficitur massa et leo viverra hendrerit. Integer fermentum, dui sed gravida interdum, orci nibh posuere elit, a tincidunt tortor urna a eros. Proin ornare ornare massa quis dignissim. Sed sit amet sapien turpis. Fusce tempus turpis vitae nunc tincidunt ornare. Nulla sit amet scelerisque lectus. Nulla facilisis ipsum ac elit fermentum pharetra. ";
1626     signature = crypto.sign(privKey, testData)
1627     print "Created signature: ", signature
1628     signedProperly = crypto.verifySignature(signature, pubKey, testData)
1629     print "Signature test result: ", signedProperly
1630         
1631     # Generate a session key
1632     sessionKey = crypto.generateSymmetricKey()
1633     # Encrypt data with sessionKey
1634     encryptedResponse = crypto.symmetricEncrypt(sessionKey, testData)
1635     print "\nEncrypted response:\n", encryptedResponse
1636         
1637     # Encrypt sessionKey with client's public key
1638     encryptedSessionKey = crypto.encryptAndEncodeKey(pubKey, sessionKey)
1639     print "\nEncrypted key:\n", encryptedSessionKey
1640
1641     # Calculate a hash for the encryptedResponse
1642     responseHash = crypto.createEncodedMessageDigest(encryptedResponse)
1643     print "\nHash for the response: ", responseHash
1644     
1645     # Verify hash
1646     hashmatches = crypto.verifyEncodedMessageDigest(responseHash, encryptedResponse)
1647     print "Hash verification: ", hashmatches
1648         
1649     # Open the session key
1650     decryptedSessionKey = crypto.decryptAndDecodeKey(privKey, encryptedSessionKey)
1651     decryptedData = crypto.symmetricDecrypt(sessionKey, encryptedResponse)
1652     print "Decrypted data: \n", decryptedData
1653
1654 def keyServerTest():
1655     crypto = SmartAPICrypto()
1656     current_path = os.getcwd()
1657     
1658     content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas in lectus at sem commodo venenatis. Fusce in eros ex. In hac habitasse platea dictumst. Phasellus dignissim, augue vel aliquet pretium, nibh eros tristique est, dignissim aliquet elit justo vel mauris. Vestibulum a posuere nulla. Curabitur aliquam semper sagittis.";
1659     keyId = "http://demo.smart-api.io/testkey"
1660     publicKeyServer = KEYSERVER_URI
1661     downloadedKey = crypto.downloadPublicKey(keyId, publicKeyServer)
1662     
1663     if downloadedKey is None:
1664         print "No key found in downloads"
1665     else:
1666         print 'download key successfully!'
1667         print downloadedKey
1668         
1669     pubKey = getPemPublicKey(os.path.join(current_path, "testkey_public.pem"))
1670     privKey = getPemPrivateKey(os.path.join(current_path,"testkey_private.pem"))
1671
1672     signature = crypto.sign(privKey, content)
1673     verified = False
1674     try:
1675         verified = crypto.verifySignature(signature, pubKey, content)
1676     except:
1677         pass
1678     print "Signature verification, key on disk ", verified
1679         
1680     try:
1681         verified = crypto.verifySignature(signature, downloadedKey, content)
1682     except:
1683         print "Exception in verifying with downloaded key"
1684         verified = False
1685     
1686     print "Signature verification, downloaded key ", verified
1687     
1688 def keyHandlingTest():
1689     privPem, pubPem = Tools.createCryptoKeys()
1690     print privPem
1691     print pubPem
1692     Tools.uploadPublicKey(pubPem, "http://demo.smart-api.io/testkey", "senni", "12345")
1693     Tools.revokePublicKey("http://demo.smart-api.io/testkey", "senni", "12345")
1694     
1695     #SmartAPICrypto().createAndSaveKeyPair("http://demo.smart-api.io/testkey", 'localpath.pem', KEYSERVER_URI, "senni", "12345")
1696     
1697 def simpleHashTest():
1698     current_path = os.getcwd()
1699     pubKey = getPemPublicKey(os.path.join(current_path, "testkey_public.pem"))
1700     privKey = getPemPrivateKey(os.path.join(current_path,"testkey_private.pem"))
1701     
1702     r = "Simple hash input"
1703     responseHash = SmartAPICrypto().createEncodedMessageDigest(r)
1704     print "\nHash for the text: ", responseHash
1705     
1706     signature = "ciTATVtKvAZxwYOBKNcbupgLCfwpuJ+SDjC1JXZYNBXyjSxYxalbmsDhI52nyse32SbbJp6TCj276nkX9wcM3gr7jnDovO4mPtucHHC8L38EHN9/vs8zWl4mh8VQ2Q+kbIl14K+cpacPKVo3KCRKaixnTktFBMbiEHh7S0VWuGICrY3cMS1j3mGrZ3J4lYmhGYTNdFiWGw/8N/DabduBX0RKNcTPa8OCGS9mYMOujEK49932KJ5jAXO3dXZkzXM/3VXbwZIwz36pQVEjiE9YusVWjO55il6mwdKiLIsgA2L2LMjhlWgXsKPwZj3F9fgAxQlfppRrVbeD62150e5i7A=="
1707     data = "Some simple data";
1708         
1709     verify = SmartAPICrypto().verifySignature(signature, pubKey, data);
1710     print "Verify result: " , verify
1711
1712     sig2 = SmartAPICrypto().sign(privKey, data);
1713     print "New sig: ", sig2
1714     print "Old sig: ", signature
1715     
1716     hexbytes = "40707265666978206e73313a203c687474703a2f2f7075726c2e6f72672f676f6f6472656c6174696f6e732f7631233e202e0d0a40707265666978206e73323a203c687474703a2f2f736d61727465672e6f72672f6f6e746f6c6f67792f312e302f73656173233e202e0d0a40707265666978206e73333a203c687474703a2f2f7777772e77332e6f72672f323030322f30372f6f776c233e202e0d0a40707265666978207264663a203c687474703a2f2f7777772e77332e6f72672f313939392f30322f32322d7264662d73796e7461782d6e73233e202e0d0a4070726566697820726466733a203c687474703a2f2f7777772e77332e6f72672f323030302f30312f7264662d736368656d61233e202e0d0a4070726566697820786d6c3a203c687474703a2f2f7777772e77332e6f72672f584d4c2f313939382f6e616d6573706163653e202e0d0a40707265666978207873643a203c687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d61233e202e0d0a3c687474703a2f2f736561732e6173656d612e636f6d2f64617461736572766963652f736f6c61722f50617269732f6f666665722f436f4339555a6d787a733147624e396a6c4a4b445163513d3d3e2061206e73313a4f66666572696e672c0d0a20202020202020206e73323a5265666572656e6365203b0d0a20202020726466733a6c6162656c20225072696365206f6666657220666f7220736f6c61722070616e656c2067617465776179207365727669636522203b0d0a202020206e73313a686173427573696e65737346756e6374696f6e206e73313a53656c6c203b0d0a202020206e73313a686173507269636553706563696669636174696f6e205b2061206e73313a556e6974507269636553706563696669636174696f6e203b0d0a2020202020202020202020206e73313a68617343757272656e6379202245555222203b0d0a2020202020202020202020206e73313a68617343757272656e637956616c75652022302e31225e5e7873643a666c6f6174203b0d0a2020202020202020202020206e73313a76616c69645468726f7567682022323031372d31312d33305432333a35393a3539225e5e7873643a6461746554696d65205d203b0d0a202020206e73313a696e636c75646573205b2061206e73313a536f6d654974656d732c0d0a202020202020202020202020202020206e73323a52657175657374203b0d0a2020202020202020202020206e73313a6465736372697074696f6e2022416e79206b696e64206f66207365727669636520726571756573742e22203b0d0a2020202020202020202020206e73313a6e616d65202253657276696365207265717565737422203b0d0a2020202020202020202020206e73323a73797374656d4f66496e746572657374205b2061206e73323a53797374656d4f66496e746572657374203b0d0a20202020202020202020202020202020202020206e73333a73616d654173203c687474703a2f2f736561732e6173656d612e636f6d2f64617461736572766963652f736f6c61722f50617269732f4370616e656c67773e205d205d203b0d0a20202020726466733a636f6d6d656e7420225072696365206f6666657220666f72207573696e672074686520736f6c61722070616e656c2067617465776179207365727669636520666f72203130206575726f2063656e742070657220726571756573742e22202e0d0a"
1717     bytes = bytearray.fromhex(hexbytes)
1718     sig2 = SmartAPICrypto().sign(privKey, bytes);
1719     print "Proper sig: ", sig2
1720
1721 def crossSystemDecryptionTest():
1722     encrypted = "GUsjdd81ugIzil2isjteOQ==tPkIcebSOYdsS+o6fecuk4MSsA6P++HBv9/7MDuruGvCQvBAAAuMZb5mqyqg/oIjGwAavhi7RHFMG8OtDabbRywW8cWEmt6KKj96fAnozvzuvSbduguOtIiuzgwPVmxURPzHhoKM08bvoQDzhXsfA5YY5eBNDq3SdUHSQIl7rWeyKATjUXOZhlWNwjwkcztF4UCj+g2YcoFRtlaxKFxON2LsGNcNrQght/SBWfX00qys9uXuii9GgMnXjMuP/BlRMC3AZms3BBVAgJD9MvdkBAdU9jN6hpdC0WkXc1IPIumdk5W8jg7mIg9HCzs/g4phGQG5CbHDuSLcns95O5emrNls9K9n0olI7SWfeFwNRimuOUqOk5fO26I7/ELu1jnvVppFzt4MBr13E67CR7PvnQ==";
1723     key = "adUiExOZ/L05Hds1r4W2vg==";
1724     crypto = SmartAPICrypto()
1725     
1726     decodedKey = base64.b64decode(key)
1727
1728     decrypted = crypto.symmetricDecrypt(decodedKey, encrypted);
1729     print decrypted
1730     return decrypted[0:3] == "The" and decrypted[-2:-1] == ". "
1731
1732 def simpleListTest():
1733     print "simpleListTest"
1734     # create timeseries with Evaluations as list items
1735     now = datetime.datetime.now()
1736
1737     # Lists within a context (should use ordered list by default
1738     ts = TimeSeries()
1739     
1740     testList = []
1741     for i in range(10):
1742         e = Evaluation()
1743         e.setValue(Variant(i))
1744         e.setInstant(now + datetime.timedelta(days = i))
1745         testList.append(e)
1746
1747     ts.setList(testList)
1748
1749     # print list items 
1750     print "Printing list before test:"
1751     if ts.hasList():
1752         list = ts.getList().get_items()
1753         for item in list:
1754             print "Value:", item.getInstant().asDate(), item.getInstant().asTime(), item.getValue().getValue()
1755
1756     stringData = Tools().toString(ts, SERIALIZATION.TURTLE)
1757     
1758     # print serialized data
1759     print "Serialized data:"
1760     print stringData
1761
1762     print "Parsing back the serialized data..."
1763     tsParsed = Tools().fromStringAsObj(stringData, SERIALIZATION.TURTLE)
1764     # print parsed-serialized data
1765     print "Parsed-Serialized data:"
1766     print Tools().toString(tsParsed, SERIALIZATION.TURTLE)
1767     
1768     # print list items after serialize-parse 
1769     print "Printing list after serialize-parse:"
1770     if tsParsed.hasList():
1771         list = tsParsed.getList().get_items()
1772         for item in list:
1773             print "Value:", item.getInstant().asDate(), item.getInstant().asTime(), item.getValue().getValue()
1774     
1775     print '\n---explain TimeSeries---\n'
1776     ts.explain()
1777     print '\n---print TimeSeries---\n'
1778     ts.printOut()
1779
1780 def identifierManagementTest():
1781     print "Running identifierManagementTest.."
1782     domain = "asema.com"
1783     systemId = "iotc/123"
1784     objId = "/obj%567&/>qwerty/"
1785     
1786     e = Entity(Tools.createIdentifierUri(domain, systemId, objId))
1787     print "identifier creation successful"
1788     e.turtlePrint()
1789     
1790     domain2 = e.getDomain()
1791     systemId2 = e.getSystemIdentifier()
1792     objId2 = e.getObjectIdentifier()
1793     secondObjetcId = e.getObjectIdentifier(2)
1794     print "domain: ",  domain2
1795     print "systemId: ",  systemId2
1796     print "objectId: ", objId2
1797     print "secondObjetcId: ", secondObjetcId
1798     print "identifier partition successful"
1799     
1800     if domain == domain2:
1801         print "domain correct"
1802     else:
1803         print "domain MISMATCH"
1804     if systemId == systemId2:
1805         print "systemId correct"
1806     else:
1807         print "systemId MISMATCH"
1808     if objId == objId2:
1809         print "objId correct"
1810     else:
1811         print "objId MISMATCH!"
1812     if secondObjetcId is None:
1813         print "secondObjetcId correct"
1814     else:
1815         print "secondObjetcId MISMATCH"
1816
1817 def readAndWriteObjectTest():
1818     from SmartAPI.common.HttpClient import HttpClient
1819     from SmartAPI.model.TemporalContext import TemporalContext
1820     
1821     print "Running readAndWriteObjectTest.."
1822     domain = "asema.com"
1823     systemId = "iotc123"
1824     objId = "lamp"
1825     
1826     d = Device(Tools.createIdentifierUri(domain, systemId, objId))
1827     itf = Factory.createInterface("http://asema.com:8082/smartapi/v1.0e1.0/access/nonstandard")
1828     
1829     vo = ValueObject(quantity=NS.SMARTAPI + "Brightness", unit=RESOURCE.PERCENT, 
1830                      types=[NS.SMARTAPI + "Actuator", NS.SMARTAPI + "Dimmer"])
1831     d.addValueObject(vo);
1832
1833     vo2 = ValueObject(quantity=NS.SMARTAPI + "PowerOnState", unit=RESOURCE.BOOLEANUNIT, 
1834                       types=[NS.SMARTAPI + "Actuator", NS.SMARTAPI + "PowerSwitch"])    
1835     d.addValueObject(vo2)
1836
1837     vo3 = ValueObject(dataType=DATATYPE.STRING, description="String message shown on lamp screen, use the lamp keyboard to change the message", 
1838                       types=NS.SMARTAPI + "Sensor")    
1839     d.addValueObject(vo3)
1840     
1841     aRead = Factory.createStandardReadActivity(interfaceAddress=itf, valueObjects=[vo, vo2, vo3])
1842     d.addCapability(aRead)
1843     aReadts = Factory.createStandardReadTimeSeriesActivity(interfaceAddress=itf, valueObjects=[vo, vo2])
1844     d.addCapability(aReadts)
1845     aWrite = Factory.createStandardWriteActivity(interfaceAddress=itf, valueObjects=[vo, vo2])
1846     d.addCapability(aWrite)
1847     aWritets = Factory.createStandardWriteTimeSeriesActivity(interfaceAddress=itf, valueObjects=[vo])
1848     d.addCapability(aWritets)
1849    
1850     # debug print device description
1851     d.turtlePrint()
1852     
1853     client = HttpClient()
1854     #enable debug mode to see printout of uri and request body
1855     client.debugMode(True)
1856     # just some random temporal context
1857     tcx = TemporalContext(None, "2017-08-22T15:18:54.842", "2017-08-23T15:18:54.842")
1858     
1859     #test call to read whole lamp device object
1860     client.getObject(d)
1861     #test call to read brightness value object time series data
1862     client.getValueObject(d, None, tcx, None, d.getValueObjectByQuantity(NS.SMARTAPI + "Brightness"), d.getValueObjectByQuantity((NS.SMARTAPI + "PowerOnState")))
1863     print '------------'
1864     #test call to write time series data to lamp
1865     client.setObject(d, None, TimeSeries(), None)
1866     #test call to write brightness value
1867     d.getValueObjectByQuantity(NS.SMARTAPI + "Brightness").setValue(80)
1868     client.setValueObject(d, None, None, None, d.getValueObjectByQuantity(NS.SMARTAPI + "Brightness"))
1869     
1870 def standardRWtest():
1871     from SmartAPI.agents.SearchAgent import SearchAgent
1872     from SmartAPI.common.HttpClient import HttpClient
1873     from SmartAPI.common.ValidationMode import ValidationMode
1874     
1875     finalResult = True
1876     
1877     print 'Running standard RW test against SimpleRW servlet...'
1878     
1879     now = datetime.datetime.now()
1880     #search for SimpleRW device, should find one
1881     entities = SearchAgent.searchByNameAndType(Factory.defaultIdentity, 500, ["SimpleRW"], [RESOURCE.DEVICE])
1882     for e in entities:
1883         e.turtlePrint()    
1884         brightness = e.getValueObjectByQuantity(NS.SMARTAPI + "Brightness")
1885         powerOnState = e.getValueObjectByQuantity(NS.SMARTAPI + "PowerOnState")
1886         
1887         client = HttpClient()
1888         # enable debug mode to see printout of uri and request body
1889         #client.debugMode(True)
1890         brightnessValue = 0
1891         powerValue = True
1892         
1893         # fetch brightness value
1894         updated = client.getValueObject(e, None, None, None, brightness).getEntities()[0]
1895         brightnessValue = updated.getValueObjectByQuantity(NS.SMARTAPI + "Brightness").getValue().asInt()
1896         #print "Read: ", brightnessValue
1897         
1898         # set new brightness value
1899         if brightnessValue > 50:
1900             brightnessValue = 30
1901         else:
1902             brightnessValue = 80
1903         
1904         # send new brightness value
1905         updated.getValueObjectByQuantity(NS.SMARTAPI + "Brightness").setValue(brightnessValue)
1906         updated = client.setValueObject(e, None, None, None, updated.getValueObjectByQuantity(NS.SMARTAPI + "Brightness")).getEntities()[0]
1907         
1908         # fetch brightness value again to see if it changed correctly
1909         updated = client.getValueObject(e, None, None, None, brightness).getEntities()[0]
1910         newValue = updated.getValueObjectByQuantity(NS.SMARTAPI + "Brightness").getValue().asInt()
1911         
1912         if brightnessValue != newValue:
1913             print "Standard RW test failed. Value (brightness) was not set correctly!"
1914             finalResult = False
1915         
1916         # fetch power on state value
1917         updated = client.getValueObject(e, None, None, None, powerOnState).getEntities()[0]
1918         powerValue = updated.getValueObjectByQuantity(RESOURCE.POWERONSTATE).getValue().asBoolean()
1919         
1920         # set new power on value
1921         powerValue = not powerValue
1922         
1923         # send new power on state value
1924         e.getValueObjectByQuantity(RESOURCE.POWERONSTATE).setValue(powerValue)
1925         updated = client.setValueObject(e, None, None, None, e.getValueObjectByQuantity(RESOURCE.POWERONSTATE)).getEntities()[0]
1926         
1927         # fetch power on state value
1928         updated = client.getValueObject(e, None, None, None, powerOnState).getEntities()[0]
1929         newPowerValue = updated.getValueObjectByQuantity(RESOURCE.POWERONSTATE).getValue().asBoolean()
1930            
1931         if powerValue != newPowerValue:
1932             print "Standard RW test failed. Value (power on state) was not set correctly!"
1933             finalResult = False
1934         
1935         # note that all read timeseries are just generated, not real values and wrote timeseries values 
1936         # are not followed by any actions on the server side
1937         
1938         # fetch brightness timeseries for the last 5 hours          
1939         tcx = TemporalContext()
1940         tcx.setEnd(now)
1941         tcx.setStart(now - datetime.timedelta(hours=5))
1942         readBrightnessTS = None
1943         try:
1944             readBrightnessTS = client.getValueObject(e, None, tcx, None, brightness).getTimeSeries()[0]
1945         except: 
1946             print 'Standard RW test failed. Error while fetching brightness timeseries!'
1947             finalResult = False
1948             traceback.print_exc()
1949         if readBrightnessTS is None or not readBrightnessTS.hasList():
1950             print "Standard RW test failed. Error while fetching brightness timeseries! Zero items in returned list."
1951             finalResult = False
1952         else:
1953             # debug printing for comparing with the ts seen on browser ui
1954             print "Read brightness timeseries:"
1955             for index in range(readBrightnessTS.getListSize()):
1956                 print readBrightnessTS.getListItem(index).asInt()
1957             print "\n"
1958
1959         # fetch poweronstate timeseries for the last 5 hours
1960         readPowerOnStateTS = None
1961         try:
1962             readPowerOnStateTS = client.getValueObject(e, None, tcx, None, powerOnState).getTimeSeries()[0]
1963         except:
1964             print "Standard RW test failed. Error while fetching brightness timeseries!"
1965             finalResult = False
1966             traceback.print_exc()
1967         
1968         if readPowerOnStateTS is None or not readPowerOnStateTS.hasList():
1969             finalResult = False
1970             print "Standard RW test failed. Error while fetching power on state timeseries! Zero items in returned list."
1971         else:
1972             # debug printing for comparing with the ts seen on browser ui
1973             print "Read PowerOnState timeseries:"
1974             for index in range(readPowerOnStateTS.getListSize()):
1975                 print readPowerOnStateTS.getListItem(index).asBoolean()
1976             print "\n"
1977         
1978         # send timeseries command (next 5 hours)
1979         tcx = TemporalContext()
1980         tcx.setStart(now)
1981         end = now + datetime.timedelta(hours=5)
1982         tcx.setEnd(end) 
1983         ts = TimeSeries()
1984         ts.setTemporalContext(tcx)
1985         # set list type
1986         ts.setList(OrderedList())
1987         # 1 hour timestep between data values
1988         timeStep = Factory.createDuration(0, 0, 0, 1, 0, 0)
1989         ts.setTimeStep(timeStep)
1990         currentDate = now
1991         baseObject = brightness # a ValueObject                 
1992         ts.setBaseObject(baseObject)
1993         while (currentDate < end):
1994             ts.addListItem(random.randint(1, 101))
1995             currentDate = currentDate + timedelta(hours=1)
1996         
1997         # debug printing for comparing with the ts seen on browser ui
1998         print "Wrote brightness timeseries:"
1999         for index in range(ts.getListSize()):
2000             print ts.getListItem(index).asInt()
2001         print "\n"
2002         
2003         ts.turtlePrint()
2004         
2005         
2006     if finalResult:   
2007         print "Standard RW test passed."
2008     
2009     test1 = NS.toAbsoluteUri('asema:monkey')
2010     print  test1
2011     test2 = NS.toAbsoluteUri('owl:Class')
2012     print  test2
2013     test3 = NS.toAbsoluteUri('quantity:Power')
2014     test4 = NS.toAbsoluteUri('unit:watt')
2015
2016 def smallTests():
2017     '''
2018     a series small tests used for writing manual
2019     '''
2020     device = Device()
2021     device.add(URIRef(NS.VCARD + "nickname"), "Sheep")
2022     device.add(URIRef(NS.VCARD + "nickname"), "Nily")
2023     device.add(URIRef("http://someProperty"), Evaluation('http://foo'))
2024     device.add(URIRef("http://otherProperty"), -12.34)
2025     device.setCoordinates(Coordinates(None, 12.3, 34.5))
2026     
2027     rets = device.get(URIRef(NS.VCARD + "nickname"))
2028     
2029     for ret in rets:
2030         r = ret.getValue()
2031         print 'result: ', r
2032     
2033 #     props = device.getProperties()
2034 #     for prop, value in props.iteritems():
2035 #         print 'property: ', prop        
2036 #         for v in value:
2037 #             print '    value: ', v
2038     
2039     print 'first value: ', device.getFirstValue(URIRef(NS.VCARD + "nickname"))
2040     nicknameUri = NS.toAbsoluteUri('vcard:nickname')
2041     nickname_var =  device.getFirst(URIRef(nicknameUri))
2042     if nickname_var.isString():
2043         print 'string value: ', nickname_var.getValue()
2044     
2045     object_result = device.getFirstValue(URIRef("http://someProperty"))
2046     print type(object_result)
2047     
2048     otherDevice = Device()
2049
2050 #   device.add(URIRef(PROPERTY.ISCONTROLLEDBY), otherDevice)
2051     # or
2052     isControlledBy_uri = NS.toAbsoluteUri("smartapi:isControlledBy")
2053     
2054     device.add(URIRef(isControlledBy_uri), otherDevice)
2055     device.turtlePrint()
2056     print '-----------------'
2057     myMap = Map()
2058     myMap.insert("myIntegerValue", 27)
2059     myMap.insert("myDoubleValue", 1.267)
2060     myMap.insert("myStringValue", "The slick fox")
2061
2062     myDouble = myMap.value("myDoubleValue")
2063     print myDouble
2064
2065
2066 def conceptValidationTest():
2067     
2068     print "Running concept validation test..."
2069     try:
2070         s = Service("http://concept.validation.test/")
2071         # add undefined concept
2072         s.addType(NS.SMARTAPI + "MyType")
2073         s.add(URIRef(PROPERTY.METHOD), Obj(RESOURCE.READ))
2074         # add illegal value type (string instead of resource)
2075         s.add(URIRef(PROPERTY.METHOD), RESOURCE.READ)
2076         # add undefined concept
2077         s.add(URIRef(PROPERTY.METHOD), Obj(NS.SMARTAPI + "MyMethod"))
2078         # add undefined property
2079         s.add(URIRef(NS.SMARTAPI + "myProp"), "helloy")
2080         s.setName("Concept validation test Service ")
2081         s.setDescription("Sample service description for concept validation test.")
2082         s.setInterface(Factory.createStandardInterface("acme.com"))
2083         s.addCapability(Factory.createStandardReadActivity("http://acme.com/service/Cread"))
2084         
2085         s.turtlePrint()
2086         
2087         # validate
2088         g = OntologyAgent.quickValidate(s)
2089         g.turtlePrint()
2090         
2091         # check that there were errors
2092         if ( g.getValueGrade() < 10 and g.getValueGrade() > 0 and
2093                 g.getConceptGrade() < 10 and g.getConceptGrade() > 0 and
2094                 g.getGrade() < 10 and g.getGrade() > 0 ):
2095             print "Concept validation test passed."
2096         else:
2097             print "Concept validation test failed."
2098     except:
2099         traceback.print_exc()
2100
2101
2102 def velocityTest():
2103     velocity = Velocity();
2104     velocity.setDescription("Estimated average speed for the travel.");
2105         
2106     velocity.setGroundSpeed(ValueObject(value = 10.0, unit = NS.UNIT + "KilometerPerHour", description = "Velocity component in relation to road surface."));
2107     stringData = Tools().toString(velocity, SERIALIZATION.TURTLE)
2108     
2109     # print serialized data
2110     print "Serialized data:"
2111     print stringData
2112
2113     print "Parsing back the serialized data..."
2114     velParsed = Tools().fromStringAsObj(stringData, SERIALIZATION.TURTLE)
2115     print velParsed.getGroundSpeed().getValue(), velParsed.getGroundSpeed().getUnit()
2116     
2117     """
2118     start = datetime.datetime.now()
2119     for a in range(1000000):
2120         b = Velocity()
2121     end = datetime.datetime.now()
2122     print end - start
2123     """
2124     
2125     
2126 def conditionalPriceSpecificationTest():
2127     offering = Offering()
2128     priceSpec = PropertyDependentPriceSpecification()
2129     
2130     c1 = Condition()
2131     c1.addGreater(0)
2132     c1.addAction(10)
2133     priceSpec.addCondition(c1)
2134     
2135     c2 = Condition()
2136     c2.addGreater(10)
2137     c2.addAction(20)
2138     priceSpec.addCondition(c2)
2139     
2140     c3 = Condition()
2141     c3.addGreater(30)
2142     c3.addAction(40)
2143     priceSpec.addCondition(c3)
2144     
2145     c4 = Condition()
2146     c4.addGreater(40)
2147     c4.addAction(55)
2148     priceSpec.addCondition(c4)
2149     
2150     offering.addPriceSpecification(priceSpec)
2151     
2152     stringData = Tools().toString(offering, SERIALIZATION.TURTLE)
2153     
2154     # print serialized data
2155     print "Serialized data:"
2156     print stringData
2157
2158     print "Parsing back the serialized data..."
2159     parsed = Tools().fromStringAsObj(stringData, SERIALIZATION.TURTLE)
2160     print Tools().toString(offering, SERIALIZATION.TURTLE)
2161     
2162     
2163 def main():
2164     #objectCopyTest()
2165     serializeRequestTest()
2166     serializeNotificationTest()
2167     #longSerializeParseTest()
2168     #propertySerializeParseTest()
2169     #inputOutputTest()
2170     #parameterSerializeParseTest()
2171     #physicalEntityTest()
2172     #waypointsTest()
2173     #basicListSerializeParseTest()
2174     #baseObjectListSerializeParseTest()
2175     #timeseriesListSerializeParseTest()
2176     #listSpeedTestSerialize()
2177     #listSpeedTestSerializeAndParse()
2178     #listOfMapsTest()
2179     #hugeDataTest()
2180     #registrationTest()
2181     #registrySearchTest()
2182     #capacityTest()
2183     #offeringTest()
2184     #TransactionSerialzeTest()
2185     #requestResponseTest3()
2186     #cryptoTests()
2187     #crossSystemDecryptionTest()
2188     #requestResponseTest4()
2189     #notaryKeyStoreTest()
2190     #simpleListTest()
2191     #simpleHashTest()
2192     #keyServerTest()
2193     #keyHandlingTest()
2194     #listExplainTest()
2195     #serializeParseLoopTest()
2196     #identifierManagementTest()
2197     #readAndWriteObjectTest()
2198     #standardRWtest()
2199     #smallTests()
2200     #conceptValidationTest()
2201     #velocityTest()
2202     #unitPriceSpecificationTest()
2203     #conditionalPriceSpecificationTest()
2204     
2205 if __name__=='__main__':
2206     main()