Make code compliant with PEP8 as per ODL check-in rules.
Commit IoTDM tests.
Move libraries from robot test area to "libraries".
Changed tabs to spaced in robot test cases.
Removed commented-out code.
Change-Id: I9b22e3a999d8cf27413ec9ebd6b0f053acbd8783
Signed-off-by: Joseph Stewart <josstewa@cisco.com>
--- /dev/null
+import requests
+from datetime import timedelta
+
+zero = timedelta(0)
+
+application = 2
+container = 3
+contentInstance = 4
+
+op_provision = ":8181/restconf/operations/onem2m:onem2m-cse-provisioning"
+op_tree = ":8181/restconf/operational/onem2m:onem2m-resource-tree"
+op_cleanup = ":8181/restconf/operations/onem2m:onem2m-cleanup-store"
+
+cse_payload = '''
+{ "input": {
+ "onem2m-primitive": [
+ {
+ "name": "CSE_ID",
+ "value": "%s"
+ },
+ {
+ "name": "CSE_TYPE",
+ "value": "IN-CSE"
+ }
+ ]
+ }
+}
+'''
+
+application_payload = '''
+{
+ any:
+ [
+ {"aei":"jb", "api":"jb", "apn":"jb2", "or":"http://hey/you" %s}
+ ]
+}
+'''
+
+_container_payload = '''
+{
+ any:
+ [
+ {
+ "cr": "jb",
+ "mni": 1,
+ "mbs": 3,
+ "or": "http://hey/you"
+ %s
+ }
+ ]
+}
+'''
+
+container_payload = '''
+{
+ any:
+ [
+ {
+ "cr": "jb",
+ "or": "http://hey/you"
+ %s
+ }
+ ]
+}
+'''
+
+contentInstance_payload = '''
+{
+ "any": [
+ {
+ "cnf": "1",
+ "or": "http://hey/you"
+ %s
+ }
+ ]
+}
+'''
+
+
+def which_payload(restype):
+ """Return a template payload for the known datatypes."""
+ if restype == application:
+ return application_payload
+ elif restype == container:
+ return container_payload
+ elif restype == contentInstance:
+ return contentInstance_payload
+ else:
+ return ""
+
+
+def find_key(response, key):
+ try:
+ val = response.json()
+ return val['any'][0][key]
+ except:
+ return None
+
+
+def name(response):
+ """Return the resource name in the response."""
+ return find_key(response, "rn")
+
+
+def resid(response):
+ """Return the resource id in the response."""
+ return find_key(response, "ri")
+
+
+def parent(response):
+ """Return the parent resource id in the response."""
+ return find_key(response, "pi")
+
+
+def content(response):
+ """Return the content the response."""
+ return find_key(response, "con")
+
+
+def restype(response):
+ """Return the resource type the response."""
+ return find_key(response, "rty")
+
+
+def status(response):
+ """Return the protocol status code in the response."""
+ try:
+ return response.status_code
+ except:
+ return None
+
+
+def headers(response):
+ """Return the protocol headers in the response."""
+ try:
+ return response.headers
+ except:
+ return None
+
+
+def error(response):
+ """Return the error string in the response."""
+ try:
+ return response.json()['error']
+ except:
+ return None
+
+
+def normalize(id):
+ if id is not None:
+ if id[0] == "/":
+ return id[1:]
+ return id
+
+
+def attr2str(attr):
+ """Convert a dictionary into a string for a protocol payload."""
+ content = ""
+ if attr is not None:
+ content = ","
+ n = len(attr)
+ c = 1
+ sep = ","
+ for i in attr:
+ if n == c:
+ sep = ""
+ n = str(attr[i])
+ if i != "con" and n.isdigit():
+ content = content + "'%s':%d%s" % (i, int(n), sep)
+ else:
+ content = content + "'%s':'%s'%s" % (i, n, sep)
+ c = c + 1
+ return content
+
+
+class connect:
+ def __init__(self, server="localhost", base='InCSE1',
+ auth=('admin', 'admin'), protocol="http"):
+ """Connect to a IoTDM server."""
+ self.s = requests.Session()
+ self.s.auth = auth
+ self.s.headers.update({'content-type': 'application/json'})
+ self.timeout = (5, 5)
+ self.payload = cse_payload % (base)
+ self.headers = {
+ # Admittedly these are "magic values" but are required
+ # and until a proper defaulting initializer is in place
+ # are hard-coded.
+ 'content-type': 'application/json',
+ 'X-M2M-Origin': '//localhost:10000',
+ 'X-M2M-RI': '12345',
+ 'X-M2M-OT': 'NOW'
+ }
+ self.server = "http://" + server
+ if base is not None:
+ self.url = self.server + op_provision
+ self.r = self.s.post(self.url,
+ data=self.payload, timeout=self.timeout)
+
+ def create(self, parent, restype, name=None, attr=None):
+ """Create resource."""
+ if parent is None:
+ return None
+ payload = which_payload(restype)
+ payload = payload % (attr2str(attr))
+ if name is None:
+ self.headers['X-M2M-NM'] = None
+ else:
+ self.headers['X-M2M-NM'] = name
+ parent = normalize(parent)
+ self.url = self.server + ":8282/%s?ty=%s&rcn=1" % (parent, restype)
+ self.r = self.s.post(self.url, payload,
+ timeout=self.timeout, headers=self.headers)
+ return self.r
+
+ def retrieve(self, id):
+ """Retrieve resource."""
+ if id is None:
+ return None
+ id = normalize(id)
+ self.url = self.server + ":8282/%s?rcn=5&drt=2" % (id)
+ self.headers['X-M2M-NM'] = None
+ self.r = self.s.get(self.url, timeout=self.timeout,
+ headers=self.headers)
+ return self.r
+
+ def update(self, id, attr=None):
+ """Update resource attr"""
+ if id is None:
+ return None
+ id = normalize(id)
+ return None
+
+ def delete(self, id):
+ """Delete the resource with the provided ID."""
+ if id is None:
+ return None
+ id = normalize(id)
+ self.url = self.server + ":8282/%s" % (id)
+ self.headers['X-M2M-NM'] = None
+ self.r = self.s.delete(self.url, timeout=self.timeout,
+ headers=self.headers)
+ return self.r
+
+ def tree(self):
+ """Get the resource tree."""
+ self.url = self.server + op_tree
+ self.r = self.s.get(self.url)
+ return self.r
+
+ def kill(self):
+ """Kill the tree."""
+ self.url = self.server + op_cleanup
+ self.r = self.s.post(self.url)
+ return self.r
--- /dev/null
+import iotdm
+
+application = iotdm.application
+container = iotdm.container
+contentInstance = iotdm.contentInstance
+
+
+def connect_to_iotdm(host, user, pw, p):
+ return iotdm.connect(host, base="InCSE1", auth=(user, pw), protocol=p)
+
+
+def create_resource(connection, parent, restype, a=None):
+ restype = int(restype)
+ if a is None:
+ x = connection.create(parent, restype)
+ else:
+ x = connection.create(parent, restype, attr=a)
+ if x is None:
+ raise AssertionError('Cannot create this resource')
+ elif hasattr(x, 'status_code'):
+ if x.status_code < 200 or x.status_code > 299:
+ raise AssertionError(
+ 'Cannot create this resource [%d] : %s' %
+ (x.status_code, x.text))
+ return x
+
+# this might not be necessary now that the library functions can take dicts
+
+
+def create_subscription(connection, parent, ip, port):
+ uri = "http://%s:%d" % (ip, int(port))
+ x = connection.create(parent, "subscription", {
+ "notificationURI": uri,
+ "notificationContentType": "wholeResource"})
+ if x is None:
+ raise AssertionError('Cannot create this subscription')
+ elif hasattr(x, 'status_code'):
+ if x.status_code < 200 or x.status_code > 299:
+ raise AssertionError('Cannot create subscription [%d] : %s' %
+ (x.status_code, x.text))
+ return x
+
+
+def retrieve_resource(connection, resid):
+ x = connection.retrieve(resid)
+ if x is None:
+ raise AssertionError('Cannot retrieve this resource')
+ elif hasattr(x, 'status_code'):
+ if x.status_code < 200 or x.status_code > 299:
+ raise AssertionError('Cannot retrieve this resource [%d] : %s' %
+ (x.status_code, x.text))
+ return x
+
+
+def update_resource(connection, resid, attr):
+ x = connection.update(resid, attr)
+ if x is None:
+ raise AssertionError('Cannot update this resource')
+ elif hasattr(x, 'status_code'):
+ if x.status_code < 200 or x.status_code > 299:
+ raise AssertionError('Cannot update this resource [%d] : %s' %
+ (x.status_code, x.text))
+ return x
+
+
+def delete_resource(connection, resid):
+ x = connection.delete(resid)
+ if x is None:
+ raise AssertionError('Cannot delete this resource')
+ elif hasattr(x, 'status_code'):
+ if x.status_code < 200 or x.status_code > 299:
+ raise AssertionError('Cannot delete this resource [%d] : %s' %
+ (x.status_code, x.text))
+ return x
+
+
+def text(x):
+ return x.text
+
+
+def status_code(x):
+ return x.status_code
+
+
+def json(x):
+ return x.json()
+
+
+def elapsed(x):
+ return x.elapsed.total_seconds()
--- /dev/null
+***Settings***
+Library ../../../libraries/iotdm.py
+Library ../../../libraries/riotdm.py
+Library Collections
+
+***Variables***
+${httphost} localhost
+${httpuser} admin
+${httppass} admin
+${rt_ae} 2
+${rt_container} 3
+${rt_contentInstance} 4
+
+***Test Cases***
+Basic HTTP CRUD Test
+ ${iserver}= Connect To IoTDM ${httphost} ${httpuser} ${httppass} http
+ #
+ ${r}= Create Resource ${iserver} InCSE1 ${rt_ae}
+ ${ae}= ResId ${r}
+ ${status_code}= Status Code ${r}
+ ${text}= Text ${r}
+ ${json}= Json ${r}
+ ${elapsed}= Elapsed ${r}
+ #
+ ${r}= Create Resource ${iserver} ${ae} ${rt_container}
+ ${container}= ResId ${r}
+ ${status_code}= Status Code ${r}
+ ${text}= Text ${r}
+ ${json}= Json ${r}
+ ${elapsed}= Elapsed ${r}
+ #
+ ${attr}= Create Dictionary con 101
+ ${r}= Create Resource ${iserver} ${container} ${rt_contentInstance} ${attr}
+ ${contentinstance}= ResId ${r}
+ ${status_code}= Status Code ${r}
+ ${text}= Text ${r}
+ ${json}= Json ${r}
+ ${elapsed}= Elapsed ${r}
+ #
+ ${r}= Retrieve Resource ${iserver} ${ae}
+ ${status_code}= Status Code ${r}
+ ${text}= Text ${r}
+ ${json}= Json ${r}
+ ${elapsed}= Elapsed ${r}
+ #
+ ${r}= Retrieve Resource ${iserver} ${container}
+ ${status_code}= Status Code ${r}
+ ${text}= Text ${r}
+ ${json}= Json ${r}
+ ${elapsed}= Elapsed ${r}
+ #
+ ${r}= Retrieve Resource ${iserver} ${contentInstance}
+ ${status_code}= Status Code ${r}
+ ${text}= Text ${r}
+ ${json}= Json ${r}
+ ${elapsed}= Elapsed ${r}
+ #
+ ${r}= Delete Resource ${iserver} ${contentInstance}
+ ${status_code}= Status Code ${r}
+ ${text}= Text ${r}
+ ${json}= Json ${r}
+ ${elapsed}= Elapsed ${r}
+ #
+ ${r}= Delete Resource ${iserver} ${container}
+ ${status_code}= Status Code ${r}
+ ${text}= Text ${r}
+ ${json}= Json ${r}
+ ${elapsed}= Elapsed ${r}
+ #
+ ${r}= Delete Resource ${iserver} ${ae}
+ ${status_code}= Status Code ${r}
+ ${text}= Text ${r}
+ ${json}= Json ${r}
+ ${elapsed}= Elapsed ${r}