moving to multi-plcs daily tests
[tests.git] / system / TestPool.py
1 #
2 # Thierry Parmentelat - INRIA Sophia Antipolis 
3 #
4 # pool class
5
6 # allows to pick an available IP among a pool
7 #
8 # input is expressed as a list of tuples ('hostname_or_ip',user_data)
9 # can be searched iteratively
10 # e.g.
11 # pool = [ (hostname1,ip1,user_data1),  (hostname2,ip2,user_data2),  
12 #          (hostname3,ip3,user_data2),  (hostname4,ip4,user_data4) ]
13 # assuming that ip1 and ip3 are taken (pingable), then we'd get
14 # pool=TestPool(pool)
15 # pool.next_free() -> entry2
16 # pool.next_free() -> entry4
17 # pool.next_free() -> None
18 # that is, even if ip2 is not busy/pingable when the second next_free() is issued
19
20 import commands
21 import utils
22
23 class TestPool:
24
25     def __init__ (self, pool, options):
26         self.pool=pool
27         self.options=options
28         self.busy=[]
29
30     # let's be flexible
31     def locate (self, hostname_or_ip, busy=False):
32         for (h,i,u) in self.pool:
33             if h.find(hostname_or_ip)>=0  or i.find(hostname_or_ip)>=0 :
34                 if busy:
35                     self.busy.append(h)
36                 return (h,i,u)
37         return None
38
39     def next_free (self):
40         # if preferred is provided, let's re-order
41         if self.options.quiet:
42             print 'TestPool is looking for a free IP address',
43         for (host,ip,user_data) in self.pool:
44             if host in self.busy:
45                 continue
46             if not self.options.quiet:
47                 utils.header('TestPool : checking %s'%host)
48             if self.options.quiet:
49                 print '.',
50             if not TestPool.check_ping (host):
51                 if not self.options.quiet:
52                     utils.header('%s is available'%host)
53                 else:
54                     print ''
55                 self.busy.append(host)
56                 return (host,ip,user_data)
57             else:
58                 self.busy.append(host)
59         return None
60
61 # OS-dependent ping option (support for macos, for convenience)
62     ping_timeout_option = None
63 # checks whether a given hostname/ip responds to ping
64     @staticmethod
65     def check_ping (hostname):
66         if not TestPool.ping_timeout_option:
67             (status,osname) = commands.getstatusoutput("uname -s")
68             if status != 0:
69                 raise Exception, "TestPool: Cannot figure your OS name"
70             if osname == "Linux":
71                 TestPool.ping_timeout_option="-w"
72             elif osname == "Darwin":
73                 TestPool.ping_timeout_option="-t"
74
75         command="ping -c 1 %s 1 %s"%(TestPool.ping_timeout_option,hostname)
76         (status,output) = commands.getstatusoutput(command)
77         return status == 0