organizing the tests area
[tests.git] / federation / regrtests.py
1 #!/usr/bin/python
2
3 import time, sys, urllib, os, tempfile, random
4
5 # set up the api
6 import xmlrpclib
7 api = xmlrpclib.Server('https://www.planet-lab.org/PLCAPI/')
8
9 # create auth struct
10 auth = {}
11 auth['Username'] = "USERNAME GOES HERE"
12 auth['AuthMethod'] = "password"
13 auth['AuthString'] = "PASSWORD GOES HERE"
14 auth['Role'] = "user"
15
16 multiquery_path = "PATH/TO/CODEPLOY/multiquery"
17 gnuplot_path = "/PATH/TO/gnuplot"
18
19 # create plots
20 def make_plots():
21         plot_fill_empty()
22         plot_keys()
23         #os.system("cp plots/*.png ~/public_html/planetlab/tests")
24
25
26 # get formatted tic string for gnuplot
27 def getTimeTicString(t1, t2, step):
28         first_hour = list(time.localtime(t1))
29         if not first_hour[4] == first_hour[5] == 0:
30                 first_hour[4] = 0
31                 first_hour[5] = 0
32         
33         first_hour_time = int(time.mktime(first_hour))
34         first_hour_time += 3600
35         
36         backsteps = (first_hour_time - t1)
37         backsteps /= step
38         start = first_hour_time - backsteps * step
39         
40         tics = []
41         thistime = start
42         while thistime < t2:
43                 tics.append("\"%s\" %d" % \
44                         (time.strftime("%H:%M", time.localtime(thistime)), thistime))
45                 thistime += step
46         
47         ticstr = ", ".join(tics)
48         return ticstr
49
50
51 # count total number of nodes in PlanetLab, according to the api
52 def count_nodes_by_api():
53         all_nodes = [row['node_id'] for row in api.GetNodes(auth, {}, ['node_id'])]
54         print "%d\t%d" % (round(time.time()), len(all_nodes))
55
56
57 # count total number of nodes in slice, according to the api
58 def count_nodes_in_slice_by_api(slice=None):
59         if slice is None:
60                 return
61         
62         slice_id = [row['slice_id'] for row in \
63                 api.GetSlices(auth, {'name': slice}, ['slice_id'])][0]
64                 
65         all_nodes = [row['node_id'] for row in \
66                 api.GetNodes(auth, {}, ['node_id', 'slice_ids']) \
67                 if slice_id in row['slice_ids']]
68         
69         print "%d\t%d" % (round(time.time()), len(all_nodes))
70
71
72 # count total number of "good" nodes, according to CoMon
73 def count_nodes_good_by_comon():
74         comon = urllib.urlopen("http://summer.cs.princeton.edu/status/tabulator.cgi?table=table_nodeviewshort&format=nameonly&select='resptime%20%3E%200%20&&%20((drift%20%3E%201m%20||%20(dns1udp%20%3E%2080%20&&%20dns2udp%20%3E%2080)%20||%20gbfree%20%3C%205%20||%20sshstatus%20%3E%202h)%20==%200)'")
75         good_nodes = comon.readlines()
76
77         print "%d\t%d" % (round(time.time()), len(good_nodes))
78         
79 # estimate total number of nodes reachable by ssh
80 def count_nodes_can_ssh(slice=None, key=None):
81         if slice is None:
82                 return
83         if key is None:
84                 return
85                 
86         pollnum = 20
87         
88         all_nodes = ["%s\n" % row['hostname'] for row in \
89                 api.GetNodes(auth, {}, ['hostname'])]
90
91         rand_nodes = []
92         for i in range(pollnum):
93                 rand_nodes.append(all_nodes[random.randint(0,len(all_nodes)-1)])
94
95         tmpfilename = tempfile.mktemp()
96         tmpfile = open(tmpfilename, 'w')
97         tmpfile.writelines(rand_nodes)
98         tmpfile.close()
99         
100         tmpfilename2 = tempfile.mktemp()
101         tmpfile2 = open(tmpfilename2, 'w')
102         tmpfile2.writelines("""
103         export MQ_SLICE="$1"
104         export MQ_NODES="$2"
105         
106         eval `ssh-agent` >/dev/null 2>&1
107         trap "kill $SSH_AGENT_PID" 0
108         ssh-add ./keys/$3 >/dev/null 2>&1
109         
110         %s 'uname' 2>/dev/null |
111         grep "bytes" |
112         grep -v ": 0 bytes" |
113         wc -l   
114         """ % multiquery_path)
115         tmpfile2.close()
116         
117         ssh_result = os.popen("bash %s %s %s %s 2>/dev/null" % (tmpfilename2, slice, tmpfilename, key)).readlines()
118         if len(ssh_result) > 0:
119                 ssh_count = float(ssh_result[0].strip()) * len(all_nodes) / pollnum
120                 print "%d\t%d" % (round(time.time()), round(ssh_count))
121         
122         if os.path.exists(tmpfilename):
123                 os.unlink(tmpfilename)
124
125         
126         
127         
128 # remove all nodes from a slice
129 def empty_slice(slice=None):
130         if slice is None:
131                 return
132         
133         all_nodes = [row['node_id'] for row in api.GetNodes(auth, {}, ['node_id'])]
134         api.DeleteSliceFromNodes(auth, slice, all_nodes)
135
136         
137 # add all nodes to a slice
138 def fill_slice(slice=None):
139         all_nodes = [row['node_id'] for row in api.GetNodes(auth, {}, ['node_id'])]
140         api.AddSliceToNodes(auth, slice, all_nodes)
141
142         
143 # add a key to a user
144 def add_key(key=None):
145         if key is None:
146                 return
147         
148         key_value = open("keys/%s.pub" % key).readline()
149                 
150         api.AddPersonKey(auth, auth['Username'], {'key_type': 'ssh', 'key': key_value})
151
152         
153 # update a user's key
154 def update_key(oldkey=None, newkey=None):
155         if oldkey is None:
156                 return
157         if newkey is None:
158                 return
159         
160         oldkeyval = open("keys/%s.pub" % oldkey).readline()
161         newkeyval = open("keys/%s.pub" % newkey).readline()
162         keyid = [row['key_id'] for row in api.GetKeys(auth) if row['key'] == oldkeyval]
163         if len(keyid) == 0:
164                 return
165         keyid = keyid[0]
166         api.UpdateKey(auth, keyid, {'key_type': 'ssh', 'key': newkeyval})       
167
168
169 # delete a key from the user
170 def delete_key(delkey=None):
171         if delkey is None:
172                 return
173         
174         delkeyval = open("keys/%s.pub" % delkey).readline()
175         delkeyid = [row['key_id'] for row in api.GetKeys(auth) if row['key'] == delkeyval]
176         if len(delkeyid) == 0:
177                 return
178         delkeyid = delkeyid[0]
179         api.DeleteKey(auth, delkeyid)
180
181         
182 # create the fill/empty plot
183 def plot_fill_empty():
184         #ticstep = 3600 # 1 hour
185         #plotlength = 36000 # 10 hours
186         ticstep = 1800
187         plotlength = 10800
188         
189         tmpfilename = tempfile.mktemp()
190         tmpfile = open(tmpfilename, 'w')
191         
192         starttime = -1
193         stoptime = -1
194         for datafilename in ['data/nodes', 'data/nodes_in_slice', \
195                         'data/nodes_can_ssh', 'data/nodes_good']:
196                 datafile = open(datafilename, 'r')
197                 line1 = datafile.readline()
198                 datafile.seek(-32,2)
199                 line2 = datafile.readlines().pop()
200                 thisstarttime = int(line1.split("\t")[0])
201                 if starttime == -1 or thisstarttime < starttime:
202                         starttime = thisstarttime
203                 thisstoptime = int(line2.split("\t")[0])
204                 if stoptime == -1 or thisstoptime > stoptime:
205                         stoptime = thisstoptime
206         
207         stopx = stoptime
208         startx = max(starttime, stopx - plotlength)
209         starttime = startx
210         
211         tics = getTimeTicString(starttime, stoptime, ticstep)
212         
213         startdate = time.strftime("%b %m, %Y - %H:%M", time.localtime(startx))
214         stopdate = time.strftime("%H:%M", time.localtime(stopx))
215         
216         tmpfile.write("""
217         set term png
218         set output "plots/fill_empty.png"
219         
220         set title "Number of Nodes / Time - %s to %s"
221         set xlabel "Time"
222         set ylabel "Number of Nodes"
223         
224         set xtics (%s)
225         set xrange[%d:%d]
226         set yrange[0:950]
227         
228         plot "data/nodes" u 1:2 w lines title "Total Nodes", \
229                 "data/nodes_in_slice" u 1:2 w lines title "Nodes in Slice", \
230                 "data/nodes_good" u 1:2 w lines title \
231                         "Healthy Nodes (according to CoMon)", \
232                 "data/nodes_can_ssh" u 1:2 w lines title "Nodes Reachable by SSH"
233         
234         """ % (startdate, stopdate, tics, startx, stopx))
235         
236         tmpfile.close()
237         
238         os.system("%s %s" % (gnuplot_path, tmpfilename))
239         
240         if os.path.exists(tmpfilename):
241                 os.unlink(tmpfilename)
242
243
244
245 # create the keys plot
246 def plot_keys():
247         #ticstep = 3600 # 1 hour
248         #plotlength = 36000 # 10 hours
249         ticstep = 1800
250         plotlength = 10800
251         
252         tmpfilename = tempfile.mktemp()
253         tmpfile = open(tmpfilename, 'w')
254
255         starttime = -1
256         stoptime = -1
257         for datafilename in ['data/nodes', 'data/nodes_in_slice2', \
258                         'data/nodes_good', 'data/nodes_can_ssh2_key0', 'data/nodes_can_ssh2_key1', \
259                         'data/nodes_can_ssh2_key2']:
260                 datafile = open(datafilename, 'r')
261                 line1 = datafile.readline()
262                 datafile.seek(-32,2)
263                 line2 = datafile.readlines().pop()
264                 thisstarttime = int(line1.split("\t")[0])
265                 if starttime == -1 or thisstarttime < starttime:
266                         starttime = thisstarttime
267                 thisstoptime = int(line2.split("\t")[0])
268                 if stoptime == -1 or thisstoptime > stoptime:
269                         stoptime = thisstoptime
270
271         stopx = stoptime
272         startx = max(starttime, stopx - plotlength)
273         starttime = startx
274
275         tics = getTimeTicString(starttime, stoptime, ticstep)
276
277         startdate = time.strftime("%b %m, %Y - %H:%M", time.localtime(startx))
278         stopdate = time.strftime("%H:%M", time.localtime(stopx))
279
280         tmpfile.write("""
281         set term png
282         set output "plots/keys.png"
283
284         set title "Number of Nodes / Time - %s to %s"
285         set xlabel "Time"
286         set ylabel "Number of Nodes"
287
288         set xtics (%s)
289         set xrange[%d:%d]
290         set yrange[0:1000]
291
292         plot "data/nodes" u 1:2 w lines title "Total Nodes", \
293                 "data/nodes_in_slice2" u 1:2 w lines title "Nodes in Slice", \
294                 "data/nodes_good" u 1:2 w lines title \
295                         "Healthy Nodes (according to CoMon)", \
296                 "data/nodes_can_ssh2_key0" u 1:2 w lines title "Nodes Accepting Key 0", \
297                 "data/nodes_can_ssh2_key1" u 1:2 w lines title "Nodes Accepting Key 1", \
298                 "data/nodes_can_ssh2_key2" u 1:2 w lines title "Nodes Accepting Key 2"
299
300         """ % (startdate, stopdate, tics, startx, stopx))
301
302         tmpfile.close()
303
304         os.system("%s %s" % (gnuplot_path, tmpfilename))
305         
306         if os.path.exists(tmpfilename):
307                 os.unlink(tmpfilename)
308