a513360c288b622f29e5436a4b1afe541d521969
[integration/test.git] / csit / libraries / IoTDM / 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", "m2m:cb", "ch"}
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, first=None):
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     if first is True:
83         return dic.get(key1[0], None)
84     else:
85         return dic.get(key1[0], None).get(key, None)
86
87
88 def childResource(response):
89     """Return child resources from the response."""
90     return find_key(response, "ch")
91
92
93 def childResourceFirst(response):
94     """Return child resources from the response."""
95     return find_key(response, "ch", True)
96
97
98 def name(response):
99     """Return the resource name in the response."""
100     return find_key(response, "rn")
101
102
103 def lastModifiedTime(response):
104     """Return the lastModifiedTime in the response."""
105     return find_key(response, "lt")
106
107
108 def stateTag(response):
109     """Return the state tag from the response."""
110     return find_key(response, "st")
111
112
113 def resid(response):
114     """Return the resource id in the response."""
115     return find_key(response, "ri")
116
117
118 def parent(response):
119     """Return the parent resource id in the response."""
120     return find_key(response, "pi")
121
122
123 def content(response):
124     """Return the content the response."""
125     return find_key(response, "con")
126
127
128 def restype(response):
129     """Return the resource type the response."""
130     return find_key(response, "rty")
131
132
133 def currentNumberOfInstances(response):
134     """Return current number of instances from the response."""
135     return find_key(response, "cni")
136
137
138 def currentByteSize(response):
139     """Return current byte size from the response."""
140     return find_key(response, "cbs")
141
142
143 def maxNumberOfInstances(response):
144     """Return max number of instances from the response."""
145     return find_key(response, "mni")
146
147
148 def maxByteSize(response):
149     """Return max byte size from the response."""
150     return find_key(response, "mbs")
151
152
153 def status(response):
154     """Return the protocol status code in the response."""
155     try:
156         return response.status_code
157     except(TypeError, AttributeError):
158         return None
159
160
161 def headers(response):
162     """Return the protocol headers in the response."""
163     try:
164         return response.headers
165     except(TypeError, AttributeError):
166         return None
167
168
169 def error(response):
170     """Return the error string in the response."""
171     try:
172         return response.json()['error']
173     except(TypeError, AttributeError):
174         return None
175
176
177 def normalize(resource_uri):
178     """Remove the first / of /InCSE1/ae1."""
179     if resource_uri is not None:
180         if resource_uri[0] == "/":
181             return resource_uri[1:]
182     return resource_uri
183
184
185 class connect:
186
187     """Create the connection."""
188
189     def __init__(self, server="localhost", base='InCSE1',
190                  auth=('admin', 'admin'), protocol="http"):
191         """Connect to a IoTDM server."""
192         self.session = requests.Session()
193         self.session.auth = auth
194         self.session.headers.update({'content-type': 'application/json'})
195         self.timeout = 5
196         self.payload = cse_payload % (base)
197         self.headers = {
198             # Admittedly these are "magic values" but are required
199             # and until a proper defaulting initializer is in place
200             # are hard-coded.
201             'content-type': 'application/vnd.onem2m-res+json',
202             'X-M2M-Origin': 'iotdm-robot-tests',
203             'X-M2M-RI': '12345',
204             'X-M2M-OT': 'NOW'
205         }
206         self.server = "%s://" % (protocol) + server
207         self.url = self.server + op_provision
208         self.response = self.session.post(
209             self.url, data=self.payload, timeout=self.timeout)
210
211     def modify_headers_origin(self, new_origin):
212         """Modify the headers to test ACP."""
213         self.headers['X-M2M-Origin'] = new_origin
214
215     def create(self, parent, restype, attr=None):
216         """Create certain resource with attributes under parent URI.
217
218         Args:
219             :param parent: the target URI
220             :param restype: the resourceType of the resource
221             :param attr: the payload of the resource
222         """
223         if parent is None:
224             return None
225         restype = int(restype)
226         payload = payload_map[restype]
227         payload = payload % (attr)
228         self.headers['content-type'] = 'application/\
229             vnd.onem2m-res+json;ty=%s' % (restype)
230         parent = normalize(parent)
231         self.url = self.server + ":8282/%s?&rcn=1" % (
232             parent)
233         self.response = self.session.post(
234             self.url, payload, timeout=self.timeout, headers=self.headers)
235
236     def create_with_command(self, parent, restype,
237                             command, attr=None):
238         """Create certain resource with attributes under parent URI.
239
240         Args:
241             :param parent: the target URI
242             :param restype: the resourceType of the resource
243             :param command: the command would be in the URI after &
244             :param attr: the payload of the resource
245         """
246         if parent is None:
247             return None
248         restype = int(restype)
249         payload = payload_map[restype]
250         payload = payload % (attr)
251         self.headers['content-type'] = 'application/\
252             vnd.onem2m-res+json;ty=%s' % (restype)
253         parent = normalize(parent)
254         self.url = self.server + ":8282/%s?%s" % (
255             parent, command)
256         self.response = self.session.post(
257             self.url, payload, timeout=self.timeout, headers=self.headers)
258
259     def retrieve(self, resource_uri):
260         """Retrieve resource using resource_uri."""
261         if resource_uri is None:
262             return None
263         resource_uri = normalize(resource_uri)
264         self.url = self.server + ":8282/%s?rcn=5" % (resource_uri)
265         self.headers['X-M2M-NM'] = None
266         self.headers['content-type'] = 'application/vnd.onem2m-res+json'
267         self.response = self.session.get(
268             self.url, timeout=self.timeout, headers=self.headers
269         )
270
271     def retrieve_with_command(self, resource_uri, command):
272         """Retrieve resource using resource_uri with command."""
273         if resource_uri is None:
274             return None
275         if command is None:
276             return None
277         resource_uri = normalize(resource_uri)
278         self.url = self.server + ":8282/%s?%s" % (resource_uri, command)
279         self.headers['X-M2M-NM'] = None
280         self.headers['content-type'] = 'application/vnd.onem2m-res+json'
281         self.response = self.session.get(
282             self.url, timeout=self.timeout, headers=self.headers
283         )
284
285     def update(self, resource_uri, restype, attr=None):
286         """Update resource at resource_uri with new attributes."""
287         if resource_uri is None:
288             return None
289         resource_uri = normalize(resource_uri)
290         restype = int(restype)
291         payload = payload_map[restype]
292         payload = payload % (attr)
293         self.headers['content-type'] = 'application/vnd.onem2m-res+json'
294         self.url = self.server + ":8282/%s" % (resource_uri)
295         self.response = self.session.put(
296             self.url, payload, timeout=self.timeout, headers=self.headers)
297
298     def update_with_command(self, resource_uri, restype,
299                             command, attr=None):
300         """Update resource at resource_uri with new attributes."""
301         if resource_uri is None:
302             return None
303         resource_uri = normalize(resource_uri)
304         restype = int(restype)
305         payload = payload_map[restype]
306         payload = payload % (attr)
307         self.headers['content-type'] = 'application/vnd.onem2m-res+json'
308         self.url = self.server + ":8282/%s?%s" % (resource_uri, command)
309         self.response = self.session.put(
310             self.url, payload, timeout=self.timeout, headers=self.headers)
311
312     def delete(self, resource_uri):
313         """Delete the resource at the resource_uri."""
314         if resource_uri is None:
315             return None
316         resource_uri = normalize(resource_uri)
317         self.url = self.server + ":8282/%s" % (resource_uri)
318         self.headers['X-M2M-NM'] = None
319         self.headers['content-type'] = 'application/vnd.onem2m-res+json'
320         self.response = self.session.delete(self.url, timeout=self.timeout,
321                                             headers=self.headers)
322
323     def delete_with_command(self, resource_uri, command):
324         """Delete the resource at the resource_uri."""
325         if resource_uri is None:
326             return None
327         resource_uri = normalize(resource_uri)
328         self.url = self.server + ":8282/%s?%s" % (resource_uri, command)
329         self.headers['X-M2M-NM'] = None
330         self.headers['content-type'] = 'application/vnd.onem2m-res+json'
331         self.response = self.session.delete(self.url, timeout=self.timeout,
332                                             headers=self.headers)
333
334     def tree(self):
335         """Get the resource tree."""
336         self.url = self.server + op_tree
337         self.response = self.session.get(self.url)
338
339     def kill(self):
340         """Kill the tree."""
341         self.url = self.server + op_cleanup
342         self.response = self.session.post(self.url)