1
2 '''
3 Monitors to control networked power strips.
4
5 @author: Michael Eddington
6 @author: Adam Cecchetti
7 @version: $Id: power.py 780 2008-03-23 02:58:49Z meddingt $
8 '''
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 import sys, threading, os, time, thread, re, socket
40 import urllib, urllib2, cookielib
41 import md5, time
42
43 from Peach.agent import Monitor
44
46 '''Class to control IP9258 ip power strip.
47 '''
48
49 uri = ""
50 loginurl = "/tgi/login.tgi"
51 powerurl = "/tgi/iocontrol.tgi"
52 username = ""
53 password = ""
54
55 req_headers = {
56 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
57 'Referer':'',
58 }
59
60 - def __init__( self, uri, username, password ):
61 self.uri = uri
62 self.username = username
63 self.password = password
64 self.data = []
65 cookiejar = cookielib.CookieJar()
66 opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
67 urllib2.install_opener(opener)
68
69
71 url = self.uri
72 req = urllib2.Request( url, None, self.req_headers )
73 response = urllib2.urlopen( req )
74 data = response.read()
75 p = re.compile( 'NAME=\"Challenge\" VALUE=\"(.*)\"> <input' )
76 m = p.search( data )
77 challenge = m.group(1)
78
79 md5hex = md5.new()
80 md5hex.update( self.username + self.password + challenge )
81 md5response = md5hex.hexdigest()
82
83 self.password=""
84
85 login_data = {
86 'Username': self.username,
87 'Response': md5response,
88 'Challenge': '',
89 'Password': ''
90 }
91
92 urldata = urllib.urlencode( login_data )
93 req = urllib2.Request( self.uri + self.loginurl, urldata, self.req_headers )
94 response = urllib2.urlopen( req )
95 data = response.read()
96
97
100
103
106
108 self.powerchange(machine, "Off")
109
111
112 if(machine_id < 1 or machine_id > 4):
113 print "Invalid Machine ID"
114 return
115
116 if(state != "On" and state != "Off"):
117 print "Invalid State"
118 return
119
120 req = urllib2.Request( self.uri + self.powerurl, None, self.req_headers )
121 response = urllib2.urlopen( req )
122 data = response.read()
123
124 P = ["Off", "Off", "Off", "Off"]
125
126
127 p= re.compile('NAME="P60" VALUE="On" CHECKED>')
128 if( p.search( data ) != None):
129 P[0]="On"
130 else:
131 P[0]="0ff"
132
133 p= re.compile('NAME="P61" VALUE="On" CHECKED>')
134 if( p.search( data ) != None):
135 P[1]="On"
136 else:
137 P[1]="0ff"
138
139 p= re.compile('NAME="P62" VALUE="On" CHECKED>')
140 if( p.search( data ) != None):
141 P[2]="On"
142 else:
143 P[2]="0ff"
144
145 p= re.compile('NAME="P63" VALUE="On" CHECKED>')
146 if( p.search( data ) != None):
147 P[3]="On"
148 else:
149 P[3]="0ff"
150
151 P[machine_id-1] = state
152
153 urldata="P60=" + P[0] + "&P60_TS=0&P60_TC=Off&P61=" + P[1] + "&P61_TS=0&P61_TC=Off&P62=" + P[2] + "&P62_TS=0&P62_TC=Off&P63=" + P[3] + "&P63_TS=0&P63_TC=Off&ButtonName=Apply"
154
155 req = urllib2.Request( self.uri + self.powerurl, urldata, self.req_headers )
156 response = urllib2.urlopen( req )
157
159 self.powerOff(machine)
160 time.sleep(5)
161 self.powerOn( machine )
162
164 '''
165 Monitor that will cycle the power port of a networked
166 power strip. Usefull for rebooting a machine after
167 a fault is detected, or every N tests.
168
169 Currently only works with "IP9258".
170 '''
171
173 '''
174 Constructor. Arguments are supplied via the Peach XML
175 file.
176
177 @type args: Dictionary
178 @param args: Dictionary of parameters
179 '''
180
181 self.hostname = str(args['hostname'])
182 self.username = str(args['username'])
183 self.password = str(args['password'])
184 self.port = int(args['port'])
185 self.waitTime = int(args['waittime'])
186
187
188 try:
189 self.testCount = int(args['testcount'])
190 except:
191 self.testCount = None
192
193 self.count = 0
194
195
196 self._name = "NetworkedPower"
197
199 '''
200 Called right before start of test case or variation
201 '''
202 if self.testCount != None and self.testCount == self.count:
203 self.count = 0
204 pc = _PowerControl("http://" + self.hostname, self.username, self.password)
205 pc.login()
206 pc.powercycle(self.port)
207 time.sleep(self.waitTime)
208
209 else:
210 self.count += 1
211
222
223
225 '''
226 The tragety that is controling our AMT boxen!
227 '''
228
230 '''
231 Constructor. Arguments are supplied via the Peach XML
232 file.
233
234 @type args: Dictionary
235 @param args: Dictionary of parameters
236 '''
237
238 self.targethostname = str(args['targethostname'])
239 self.makehostname = str(args['makehostname'])
240 self.makeport = int(args['makeport'])
241 self.hostname = str(args['hostname'])
242 self.username = str(args['username'])
243 self.password = str(args['password'])
244 self.port = int(args['port'])
245 self.waitTime = int(args['waittime'])
246
247
248 try:
249 self.testCount = int(args['testcount'])
250 except:
251 self.testCount = None
252
253 self.count = 0
254
255
256 self._name = "NetworkedPower"
257
259 pipe = os.popen("ping -n 2 " + self.targethostname)
260 buff = pipe.read()
261 pipe.close()
262
263 if re.compile(r"Reply from \d+\.\d+\.\d+\.\d+: bytes=", re.M).search(buff) != None:
264 return True
265
266 return False
267
272
278
280 '''
281 Called right before start of test case or variation
282 '''
283 if self.testCount != None and self.testCount == self.count:
284 self.count = 0
285
286 self._powerCycle()
287 self._hitDahButton()
288
289 while not self._canWePing():
290 time.sleep(1)
291
292 else:
293 self.count += 1
294
305
306
307
308