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