]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/test/test_iputil.py
Add Namespace utility class. (This is already used in the leasedb/cloud backend branch.)
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / test / test_iputil.py
1
2 import re, errno, subprocess, os
3
4 from twisted.trial import unittest
5
6 from allmydata.util import iputil
7 import allmydata.test.common_util as testutil
8 from allmydata.util.namespace import Namespace
9
10
11 DOTTED_QUAD_RE=re.compile("^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$")
12
13 MOCK_IPADDR_OUTPUT = """\
14 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN \n\
15     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
16     inet 127.0.0.1/8 scope host lo
17     inet6 ::1/128 scope host \n\
18        valid_lft forever preferred_lft forever
19 2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
20     link/ether d4:3d:7e:01:b4:3e brd ff:ff:ff:ff:ff:ff
21     inet 192.168.0.6/24 brd 192.168.0.255 scope global eth1
22     inet6 fe80::d63d:7eff:fe01:b43e/64 scope link \n\
23        valid_lft forever preferred_lft forever
24 3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
25     link/ether 90:f6:52:27:15:0a brd ff:ff:ff:ff:ff:ff
26     inet 192.168.0.2/24 brd 192.168.0.255 scope global wlan0
27     inet6 fe80::92f6:52ff:fe27:150a/64 scope link \n\
28        valid_lft forever preferred_lft forever
29 """
30
31 MOCK_IFCONFIG_OUTPUT = """\
32 eth1      Link encap:Ethernet  HWaddr d4:3d:7e:01:b4:3e  \n\
33           inet addr:192.168.0.6  Bcast:192.168.0.255  Mask:255.255.255.0
34           inet6 addr: fe80::d63d:7eff:fe01:b43e/64 Scope:Link
35           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
36           RX packets:154242234 errors:0 dropped:0 overruns:0 frame:0
37           TX packets:155461891 errors:0 dropped:0 overruns:0 carrier:0
38           collisions:0 txqueuelen:1000 \n\
39           RX bytes:84367213640 (78.5 GiB)  TX bytes:73401695329 (68.3 GiB)
40           Interrupt:20 Memory:f4f00000-f4f20000 \n\
41
42 lo        Link encap:Local Loopback  \n\
43           inet addr:127.0.0.1  Mask:255.0.0.0
44           inet6 addr: ::1/128 Scope:Host
45           UP LOOPBACK RUNNING  MTU:16436  Metric:1
46           RX packets:27449267 errors:0 dropped:0 overruns:0 frame:0
47           TX packets:27449267 errors:0 dropped:0 overruns:0 carrier:0
48           collisions:0 txqueuelen:0 \n\
49           RX bytes:192643017823 (179.4 GiB)  TX bytes:192643017823 (179.4 GiB)
50
51 wlan0     Link encap:Ethernet  HWaddr 90:f6:52:27:15:0a  \n\
52           inet addr:192.168.0.2  Bcast:192.168.0.255  Mask:255.255.255.0
53           inet6 addr: fe80::92f6:52ff:fe27:150a/64 Scope:Link
54           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
55           RX packets:12352750 errors:0 dropped:0 overruns:0 frame:0
56           TX packets:4501451 errors:0 dropped:0 overruns:0 carrier:0
57           collisions:0 txqueuelen:1000 \n\
58           RX bytes:3916475942 (3.6 GiB)  TX bytes:458353654 (437.1 MiB)
59 """
60
61 # This is actually from a VirtualBox VM running XP.
62 MOCK_ROUTE_OUTPUT = """\
63 ===========================================================================
64 Interface List
65 0x1 ........................... MS TCP Loopback interface
66 0x2 ...08 00 27 c3 80 ad ...... AMD PCNET Family PCI Ethernet Adapter - Packet Scheduler Miniport
67 ===========================================================================
68 ===========================================================================
69 Active Routes:
70 Network Destination        Netmask          Gateway       Interface  Metric
71           0.0.0.0          0.0.0.0         10.0.2.2       10.0.2.15       20
72          10.0.2.0    255.255.255.0        10.0.2.15       10.0.2.15       20
73         10.0.2.15  255.255.255.255        127.0.0.1       127.0.0.1       20
74    10.255.255.255  255.255.255.255        10.0.2.15       10.0.2.15       20
75         127.0.0.0        255.0.0.0        127.0.0.1       127.0.0.1       1
76         224.0.0.0        240.0.0.0        10.0.2.15       10.0.2.15       20
77   255.255.255.255  255.255.255.255        10.0.2.15       10.0.2.15       1
78 Default Gateway:          10.0.2.2
79 ===========================================================================
80 Persistent Routes:
81   None
82 """
83
84 UNIX_TEST_ADDRESSES = set(["127.0.0.1", "192.168.0.6", "192.168.0.2", "192.168.0.10"])
85 WINDOWS_TEST_ADDRESSES = set(["127.0.0.1", "10.0.2.15", "192.168.0.10"])
86 CYGWIN_TEST_ADDRESSES = set(["127.0.0.1", "192.168.0.10"])
87
88
89 class FakeProcess:
90     def __init__(self, output, err):
91         self.output = output
92         self.err = err
93     def communicate(self):
94         return (self.output, self.err)
95
96
97 class ListAddresses(testutil.SignalMixin, unittest.TestCase):
98     def test_get_local_ip_for(self):
99         addr = iputil.get_local_ip_for('127.0.0.1')
100         self.failUnless(DOTTED_QUAD_RE.match(addr))
101
102     def test_list_async(self):
103         d = iputil.get_local_addresses_async()
104         def _check(addresses):
105             self.failUnlessIn("127.0.0.1", addresses)
106             self.failIfIn("0.0.0.0", addresses)
107         d.addCallbacks(_check)
108         return d
109     # David A.'s OpenSolaris box timed out on this test one time when it was at 2s.
110     test_list_async.timeout=4
111
112     def _test_list_async_mock(self, command, output, expected):
113         ns = Namespace()
114         ns.first = True
115
116         def call_Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None,
117                        preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None,
118                        universal_newlines=False, startupinfo=None, creationflags=0):
119             if ns.first:
120                 ns.first = False
121                 e = OSError("EINTR")
122                 e.errno = errno.EINTR
123                 raise e
124             elif os.path.basename(args[0]) == command:
125                 return FakeProcess(output, "")
126             else:
127                 e = OSError("[Errno 2] No such file or directory")
128                 e.errno = errno.ENOENT
129                 raise e
130         self.patch(subprocess, 'Popen', call_Popen)
131         self.patch(os.path, 'isfile', lambda x: True)
132
133         def call_get_local_ip_for(target):
134             if target in ("localhost", "127.0.0.1"):
135                 return "127.0.0.1"
136             else:
137                 return "192.168.0.10"
138         self.patch(iputil, 'get_local_ip_for', call_get_local_ip_for)
139
140         def call_which(name):
141             return [name]
142         self.patch(iputil, 'which', call_which)
143
144         d = iputil.get_local_addresses_async()
145         def _check(addresses):
146             self.failUnlessEquals(set(addresses), set(expected))
147         d.addCallbacks(_check)
148         return d
149
150     def test_list_async_mock_ip_addr(self):
151         self.patch(iputil, 'platform', "linux2")
152         return self._test_list_async_mock("ip", MOCK_IPADDR_OUTPUT, UNIX_TEST_ADDRESSES)
153
154     def test_list_async_mock_ifconfig(self):
155         self.patch(iputil, 'platform', "linux2")
156         return self._test_list_async_mock("ifconfig", MOCK_IFCONFIG_OUTPUT, UNIX_TEST_ADDRESSES)
157
158     def test_list_async_mock_route(self):
159         self.patch(iputil, 'platform', "win32")
160         return self._test_list_async_mock("route.exe", MOCK_ROUTE_OUTPUT, WINDOWS_TEST_ADDRESSES)
161
162     def test_list_async_mock_cygwin(self):
163         self.patch(iputil, 'platform', "cygwin")
164         return self._test_list_async_mock(None, None, CYGWIN_TEST_ADDRESSES)