Clarifying code and complying with standards. 35/20035/5
authorJoseph Stewart <josstewa@cisco.com>
Mon, 11 May 2015 16:15:16 +0000 (12:15 -0400)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 13 May 2015 17:17:43 +0000 (17:17 +0000)
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>
test/csit/libraries/iotdm.py [new file with mode: 0644]
test/csit/libraries/riotdm.py [new file with mode: 0644]
test/csit/suites/iotdm/basic/020-iotdm-mini.robot [new file with mode: 0644]

diff --git a/test/csit/libraries/iotdm.py b/test/csit/libraries/iotdm.py
new file mode 100644 (file)
index 0000000..923f227
--- /dev/null
@@ -0,0 +1,255 @@
+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
diff --git a/test/csit/libraries/riotdm.py b/test/csit/libraries/riotdm.py
new file mode 100644 (file)
index 0000000..8c2d6b0
--- /dev/null
@@ -0,0 +1,90 @@
+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()
diff --git a/test/csit/suites/iotdm/basic/020-iotdm-mini.robot b/test/csit/suites/iotdm/basic/020-iotdm-mini.robot
new file mode 100644 (file)
index 0000000..92a97e6
--- /dev/null
@@ -0,0 +1,74 @@
+***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}