Step 2: Move test folder to root
[integration/test.git] / tools / OF_Test / robot_suites / 998__Independent_OF_Tests_ovs / libconfig.py
1 import requests
2 import time
3 from threading import Thread
4 from functools import wraps
5 # from multiprocessing import Process
6
7 __all__ = ['configure_flows', 'wait_until', 'deconfigure_flows']
8
9
10 # class KeyWord(Process):
11 class KeyWord(Thread):
12     def __init__(self, *args, **kwargs):
13         super(KeyWord, self).__init__(*args, **kwargs)
14         self._stop = False
15         self._kw_result = None
16
17     def stop(self):
18         self._stop = True
19
20     def result(self):
21         return self._kw_result
22
23
24 def async_task(func):
25     """Taken from http://code.activestate.com/recipes/576684-simple-threading-decorator/
26     and modified
27     """
28     @wraps(func)
29     def async_func(*args, **kwargs):
30         func_hl = KeyWord(target=func, args=args, kwargs=kwargs)
31         func_hl._Thread__args = (func_hl,) + func_hl._Thread__args
32         # func_hl._args = (func_hl,) + func_hl._args
33         func_hl.start()
34         return func_hl
35
36     return async_func
37
38
39 def wait_until(*tasks, **kwargs):
40     tstart = time.time()
41
42     timeout = 30
43     if 'timeout' in kwargs:
44         timeout = int(kwargs['timeout'])
45
46     cnt = len(tasks)
47     while time.time() < (timeout + tstart):
48         tfinished = 0
49         for t in tasks:
50             if t.is_alive() is False:
51                 tfinished += 1
52                 continue
53             t.join(timeout=0.2)
54         if tfinished == cnt:
55             return (time.time()-tstart)
56
57     for t in tasks:
58         if t.is_alive() is True:
59             t.stop()
60             # t.terminate()
61             t.join()
62
63     return (time.time()-tstart)
64
65
66 @async_task
67 def Example_of_robot_keyword(self, a, b, c):
68     """be carefull, when calling this kw from robot,
69     do not count on self, it is a thread object itself
70     injected by decorator. The purpose is to make
71     possibility to exit from thread on demand by
72     wait until keywork which makes thread.stop()
73     if needed. In your fw you should use self._stop
74     variable.
75
76
77     robot sample:
78     ${thread}=  Example Of Robot Keyword   a   b   c
79     """
80     while True:
81         if self._stop is True:
82             break
83
84
85 @async_task
86 def configure_flows(self, host, port, switchid, tableid, minid, maxid):
87     flow_template = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
88 <flow xmlns="urn:opendaylight:flow:inventory">
89     <strict>false</strict>
90     <instructions>
91         <instruction>
92             <order>0</order>
93             <apply-actions>
94                 <action>
95                     <order>0</order>
96                     <dec-nw-ttl/>
97                 </action>
98             </apply-actions>
99         </instruction>
100     </instructions>
101     <table_id>{}</table_id>
102     <id>{}</id>
103     <cookie_mask>255</cookie_mask>
104     <installHw>false</installHw>
105     <match>
106         <ethernet-match>
107             <ethernet-type>
108                 <type>2048</type>
109             </ethernet-type>
110         </ethernet-match>
111         <ipv4-destination>10.0.1.0/24</ipv4-destination>
112     </match>
113     <cookie>1</cookie>
114     <flow-name>FooXf{}</flow-name>
115     <priority>{}</priority>
116     <barrier>false</barrier>
117 </flow>'''
118
119     self._kw_result = 0
120
121     ses = requests.Session()
122
123     for i in range(int(minid), int(maxid) + 1):
124         if self._stop is True:
125             break
126         fid = str(i)
127         flow = flow_template.format(tableid, fid, fid, fid)
128         url = 'http://{}:{}/restconf/config/opendaylight-inventory:nodes/node/openflow:{}/table/{}/flow/{}'.format(
129             host, port, switchid, tableid, fid)
130
131         try:
132             rsp = ses.put(url, headers={'Content-Type': 'application/xml'}, data=flow, timeout=3)
133             if rsp.status_code == 200:
134                 self._kw_result += 1
135
136         except Exception:
137             pass
138
139
140 @async_task
141 def deconfigure_flows(self, host, port, switchid, tableid, minid, maxid):
142     """Result will be the number of status code 200 returned"""
143     self._kw_result = 0
144     ses = requests.Session()
145
146     for fid in range(int(minid), int(maxid)):
147         if self._stop is True:
148             break
149         url = 'http://{}:{}/restconf/config/opendaylight-inventory:nodes/node/openflow:{}/table/{}/flow/{}'.format(
150             host, port, switchid, tableid, fid)
151
152         try:
153             rsp = ses.delete(url, headers={'Content-Type': 'application/xml'}, timeout=3)
154             if rsp.status_code == 200:
155                 self._kw_result += 1
156         except Exception:
157             pass