Update iotdm library and tests.
[integration/test.git] / csit / libraries / ciotdm.py
1 """This is the base library for criotdm. Both work for IoTDM project."""
2
3 import requests
4
5 op_provision = ":8181/restconf/operations/onem2m:onem2m-cse-provisioning"
6 op_tree = ":8181/restconf/operational/onem2m:onem2m-resource-tree"
7 op_cleanup = ":8181/restconf/operations/onem2m:onem2m-cleanup-store"
8
9 cse_payload = '''
10 {    "input": {
11         "onem2m-primitive": [
12            {
13                 "name": "CSE_ID",
14                 "value": "%s"
15             },
16             {
17                 "name": "CSE_TYPE",
18                 "value": "IN-CSE"
19             }
20         ]
21     }
22 }
23 '''
24
25 resourcepayload = '''
26 {
27     %s
28 }
29 '''
30
31 ae_payload = '''
32 {
33     "m2m:ae":{%s}
34 }
35 '''
36
37 con_payload = '''
38 {
39     "m2m:cnt":{%s}
40 }
41 '''
42
43 cin_payload = '''
44 {
45    "m2m:cin":{%s}
46 }
47 '''
48
49 sub_payload = '''
50 {
51     "m2m:sub":{%s}
52 }
53 '''
54
55 acp_payload = '''
56 {
57     "m2m:acp":{%s}
58 }
59 '''
60
61 nod_payload = '''
62 {
63     "m2m:nod":{%s}
64 }
65 '''
66
67 resources = {"m2m:ae", "m2m:cnt", "m2m:cin", "m2m:sub",
68              "m2m:acp", "m2m:nod", "m2m:grp"}
69
70 payload_map = {1: acp_payload, 2: ae_payload, 3: con_payload,
71                4: cin_payload, 14: nod_payload, 23: sub_payload}
72
73
74 def find_key(response, key):
75     """Deserialize response, return value for key or None."""
76     dic = response.json()
77     key1 = list(dic.keys())
78     if len(key1) != 1:
79         raise ValueError("The response should be json object")
80     if key1[0] not in resources:
81         raise ValueError("The resource is not recognized")
82     return dic.get(key1[0], None).get(key, None)
83
84
85 def name(response):
86     """Return the resource name in the response."""
87     return find_key(response, "rn")
88
89
90 def lastModifiedTime(response):
91     """Return the lastModifiedTime in the response."""
92     return find_key(response, "lt")
93
94
95 def resid(response):
96     """Return the resource id in the response."""
97     return find_key(response, "ri")
98
99
100 def parent(response):
101     """Return the parent resource id in the response."""
102     return find_key(response, "pi")
103
104
105 def content(response):
106     """Return the content the response."""
107     return find_key(response, "con")
108
109
110 def restype(response):
111     """Return the resource type the response."""
112     return find_key(response, "rty")
113
114
115 def status(response):
116     """Return the protocol status code in the response."""
117     try:
118         return response.status_code
119     except(TypeError, AttributeError):
120         return None
121
122
123 def headers(response):
124     """Return the protocol headers in the response."""
125     try:
126         return response.headers
127     except(TypeError, AttributeError):
128         return None
129
130
131 def error(response):
132     """Return the error string in the response."""
133     try:
134         return response.json()['error']
135     except(TypeError, AttributeError):
136         return None
137
138
139 def normalize(resource_uri):
140     """Remove the first / of /InCSE1/ae1."""
141     if resource_uri is not None:
142         if resource_uri[0] == "/":
143             return resource_uri[1:]
144     return resource_uri
145
146
147 class connect:
148
149     """Create the connection."""
150
151     def __init__(self, server="localhost", base='InCSE1',
152                  auth=('admin', 'admin'), protocol="http"):
153         """Connect to a IoTDM server."""
154         self.session = requests.Session()
155         self.session.auth = auth
156         self.session.headers.update({'content-type': 'application/json'})
157         self.timeout = 5
158         self.payload = cse_payload % (base)
159         self.headers = {
160             # Admittedly these are "magic values" but are required
161             # and until a proper defaulting initializer is in place
162             # are hard-coded.
163             'content-type': 'application/vnd.onem2m-res+json',
164             'X-M2M-Origin': '//localhost:10000',
165             'X-M2M-RI': '12345',
166             'X-M2M-OT': 'NOW'
167         }
168         self.server = "%s://" % (protocol) + server
169         self.url = self.server + op_provision
170         self.response = self.session.post(
171             self.url, data=self.payload, timeout=self.timeout)
172
173     def modify_headers_origin(self, new_origin):
174         """Modify the headers to test ACP."""
175         self.headers['X-M2M-Origin'] = new_origin
176
177     def create(self, parent, restype, attr=None):
178         """Create certain resource with attributes under parent URI.
179
180         Args:
181             :param parent: the target URI
182             :param restype: the resourceType of the resource
183             :param attr: the payload of the resource
184         """
185         if parent is None:
186             return None
187         restype = int(restype)
188         payload = payload_map[restype]
189         payload = payload % (attr)
190         self.headers['content-type'] = 'application/\
191             vnd.onem2m-res+json;ty=%s' % (restype)
192         parent = normalize(parent)
193         self.url = self.server + ":8282/%s?&rcn=1" % (
194             parent)
195         self.response = self.session.post(
196             self.url, payload, timeout=self.timeout, headers=self.headers)
197
198     def create_with_command(self, parent, restype,
199                             command, attr=None):
200         """Create certain resource with attributes under parent URI.
201
202         Args:
203             :param parent: the target URI
204             :param restype: the resourceType of the resource
205             :param command: the command would be in the URI after &
206             :param attr: the payload of the resource
207         """
208         if parent is None:
209             return None
210         restype = int(restype)
211         payload = payload_map[restype]
212         payload = payload % (attr)
213         self.headers['content-type'] = 'application/\
214             vnd.onem2m-res+json;ty=%s' % (restype)
215         parent = normalize(parent)
216         self.url = self.server + ":8282/%s?%s" % (
217             parent, command)
218         self.response = self.session.post(
219             self.url, payload, timeout=self.timeout, headers=self.headers)
220
221     def retrieve(self, resource_uri):
222         """Retrieve resource using resource_uri."""
223         if resource_uri is None:
224             return None
225         resource_uri = normalize(resource_uri)
226         self.url = self.server + ":8282/%s?rcn=5" % (resource_uri)
227         self.headers['X-M2M-NM'] = None
228         self.headers['content-type'] = 'application/vnd.onem2m-res+json'
229         self.response = self.session.get(
230             self.url, timeout=self.timeout, headers=self.headers
231         )
232
233     def retrieve_with_command(self, resource_uri, command):
234         """Retrieve resource using resource_uri with command."""
235         if resource_uri is None:
236             return None
237         if command is None:
238             return None
239         resource_uri = normalize(resource_uri)
240         self.url = self.server + ":8282/%s?%s" % (resource_uri, command)
241         self.headers['X-M2M-NM'] = None
242         self.headers['content-type'] = 'application/vnd.onem2m-res+json'
243         self.response = self.session.get(
244             self.url, timeout=self.timeout, headers=self.headers
245         )
246
247     def update(self, resource_uri, restype, attr=None):
248         """Update resource at resource_uri with new attributes."""
249         if resource_uri is None:
250             return None
251         resource_uri = normalize(resource_uri)
252         restype = int(restype)
253         payload = payload_map[restype]
254         payload = payload % (attr)
255         self.headers['content-type'] = 'application/vnd.onem2m-res+json'
256         self.url = self.server + ":8282/%s" % (resource_uri)
257         self.response = self.session.put(
258             self.url, payload, timeout=self.timeout, headers=self.headers)
259
260     def update_with_command(self, resource_uri, restype,
261                             command, attr=None):
262         """Update resource at resource_uri with new attributes."""
263         if resource_uri is None:
264             return None
265         resource_uri = normalize(resource_uri)
266         restype = int(restype)
267         payload = payload_map[restype]
268         payload = payload % (attr)
269         self.headers['content-type'] = 'application/vnd.onem2m-res+json'
270         self.url = self.server + ":8282/%s?%s" % (resource_uri, command)
271         self.response = self.session.put(
272             self.url, payload, timeout=self.timeout, headers=self.headers)
273
274     def delete(self, resource_uri):
275         """Delete the resource at the resource_uri."""
276         if resource_uri is None:
277             return None
278         resource_uri = normalize(resource_uri)
279         self.url = self.server + ":8282/%s" % (resource_uri)
280         self.headers['X-M2M-NM'] = None
281         self.headers['content-type'] = 'application/vnd.onem2m-res+json'
282         self.response = self.session.delete(self.url, timeout=self.timeout,
283                                             headers=self.headers)
284
285     def delete_with_command(self, resource_uri, command):
286         """Delete the resource at the resource_uri."""
287         if resource_uri is None:
288             return None
289         resource_uri = normalize(resource_uri)
290         self.url = self.server + ":8282/%s?%s" % (resource_uri, command)
291         self.headers['X-M2M-NM'] = None
292         self.headers['content-type'] = 'application/vnd.onem2m-res+json'
293         self.response = self.session.delete(self.url, timeout=self.timeout,
294                                             headers=self.headers)
295
296     def tree(self):
297         """Get the resource tree."""
298         self.url = self.server + op_tree
299         self.response = self.session.get(self.url)
300
301     def kill(self):
302         """Kill the tree."""
303         self.url = self.server + op_cleanup
304         self.response = self.session.post(self.url)