diff --git a/network_checker/Dockerfile b/network_checker/Dockerfile new file mode 100644 index 0000000000..9c45ccaf59 --- /dev/null +++ b/network_checker/Dockerfile @@ -0,0 +1,10 @@ +FROM phusion/baseimage +ENV ARCH amd64 +ENV DIST precise +RUN echo 'deb http://fuel-repository.mirantis.com/fwm/5.0/ubuntu precise main' >> /etc/apt/sources.list +RUN apt-get -q update +RUN apt-get -y --force-yes install cliff-tablib python-pyparsing python-pypcap scapy python-pip wget openssh-server +RUN pip install pytest mock +RUN sudo locale-gen en_US.UTF-8 + +RUN mkdir -p /app diff --git a/network_checker/Vagrantfile b/network_checker/Vagrantfile index 09d7e9e95b..42043fed6a 100644 --- a/network_checker/Vagrantfile +++ b/network_checker/Vagrantfile @@ -6,39 +6,20 @@ VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| - config.vm.box = "centos" - - config.vm.box_url = "http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-i386-v20130427.box" + config.vm.box = "precise64" config.vm.provider "virtualbox" do |v| v.customize ["modifyvm", :id, "--memory", 348] end config.vm.define :develop do |config| - config.vm.network :private_network, ip: "192.168.0.2" - config.vm.network :private_network, ip: "10.10.0.5" + config.vm.network :private_network, ip: '10.100.0.0', type: "dhcp" + config.vm.network :private_network, ip: '10.200.0.0', type: 'dhcp' + config.vm.provision :shell, :inline => "echo 'deb http://fuel-repository.mirantis.com/fwm/5.0/ubuntu precise main' >> /etc/apt/sources.list" + config.vm.provision :shell, :inline => "sudo apt-get update" + config.vm.provision :shell, :inline => "sudo apt-get -y --force-yes install cliff-tablib python-pyparsing python-pypcap scapy python-pip vde2" + config.vm.provision :shell, :inline => "sudo pip install pytest mock" + config.vm.provision :shell, :inline => "cd /vagrant && sudo python setup.py develop" end - config.vm.define :dhcp2 do |config| - config.vm.network :private_network, ip: "10.10.0.8" - config.vm.provision :shell, :inline => "sudo yum -y install dhcp" - config.vm.provision :shell, :inline => "sudo route add -host 255.255.255.255 dev eth1" - config.vm.provision :shell, :inline => "sudo cp /vagrant/test_utils/dhcpd.conf.sample2 /etc/dhcp/dhcpd.conf" - config.vm.provision :shell, :inline => "sudo /usr/sbin/dhcpd eth1" - end - - config.vm.define :dhcp_relay do |config| - config.vm.network :private_network, ip: "10.10.0.10" - config.vm.provision :shell, :inline => "sudo yum -y install dhcp" - config.vm.provision :shell, :inline => "cp /vagrant/test_utils/dhcp_relay.conf /etc/sysconfig/dhcrelay" - config.vm.provision :shell, :inline => "service dhcrelay start" - end - - config.vm.define :dhcp1 do |config| - config.vm.network :private_network, ip: "192.168.0.5" - config.vm.provision :shell, :inline => "sudo yum -y install dhcp" - config.vm.provision :shell, :inline => "sudo route add -host 255.255.255.255 dev eth1" - config.vm.provision :shell, :inline => "sudo cp /vagrant/test_utils/dhcpd.conf.sample /etc/dhcp/dhcpd.conf" - config.vm.provision :shell, :inline => "sudo /usr/sbin/dhcpd eth1" - end end diff --git a/network_checker/conftest.py b/network_checker/conftest.py new file mode 100644 index 0000000000..c8aabfaa46 --- /dev/null +++ b/network_checker/conftest.py @@ -0,0 +1,44 @@ +# Copyright 2014 Mirantis, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import os + + +PIDFILE = '/tmp/vde_network_checker' +IFACES = ['tap11', 'tap12'] + + +def pytest_addoption(parser): + parser.addoption("--vde", action='store_true', default=False, + help="Use vde switch for network verification.") + + +def pytest_configure(config): + if config.getoption('vde'): + base = 'vde_switch -p {pidfile} -d'.format(pidfile=PIDFILE) + command = [base] + taps = ['-tap {tap}'.format(tap=tap) for tap in IFACES] + full_command = command + taps + os.system(' '.join(full_command)) + for tap in IFACES: + os.system('ifconfig {tap} up'.format(tap=tap)) + os.environ['NET_CHECK_IFACE_1'] = IFACES[0] + os.environ['NET_CHECK_IFACE_2'] = IFACES[1] + + +def pytest_unconfigure(config): + if os.path.exists(PIDFILE): + with open(PIDFILE) as f: + pid = f.read().strip() + os.kill(int(pid), 15) diff --git a/network_checker/dhcp_checker/tests/system/tests.py b/network_checker/dhcp_checker/tests/system/tests.py index 00934cc696..02cca9c29d 100644 --- a/network_checker/dhcp_checker/tests/system/tests.py +++ b/network_checker/dhcp_checker/tests/system/tests.py @@ -24,26 +24,21 @@ from dhcp_checker import utils class TestDhcpServers(unittest.TestCase): - def test_dhcp_server_on_eth0(self): - """Test verifies dhcp server on eth0 iface - """ - response = api.check_dhcp_on_eth('eth0', 2) - self.assertEqual(len(response), 1) - self.assertEqual(response[0]['server_ip'], '10.0.2.2') - def test_dhcp_server_on_eth1(self): """Test verifies dhcp server on eth1 iface """ response = api.check_dhcp_on_eth('eth1', 2) self.assertEqual(len(response), 1) - self.assertEqual(response[0]['server_ip'], '192.168.0.5') + # we need to guarantee that received answer has server_ip + # but dont want to check its real address + self.assertTrue(response[0]['server_ip']) def test_dhcp_server_on_eth2(self): """Test verifies dhcp server on eth2 iface """ response = api.check_dhcp_on_eth('eth2', 2) self.assertEqual(len(response), 1) - self.assertEqual(response[0]['server_ip'], '10.10.0.8') + self.assertTrue(response[0]['server_ip']) class TestDhcpUtils(unittest.TestCase): @@ -83,7 +78,7 @@ class TestDhcpWithNetworkDown(unittest.TestCase): response = api.check_dhcp_on_eth(iface, 2) self.assertEqual(len(response), 1) - self.assertEqual(response[0]['server_ip'], '10.10.0.8') + self.assertTrue(response[0]['server_ip']) self.assertEqual(manager.pre_iface_state, 'DOWN') self.assertEqual(manager.iface_state, 'UP') self.assertEqual(manager.post_iface_state, 'DOWN') @@ -96,7 +91,7 @@ class TestDhcpWithNetworkDown(unittest.TestCase): response = api.check_dhcp_on_eth(iface, 2) self.assertEqual(len(response), 1) - self.assertEqual(response[0]['server_ip'], '10.0.2.2') + self.assertTrue(response[0]['server_ip']) self.assertEqual(manager.pre_iface_state, 'UP') self.assertEqual(manager.iface_state, 'UP') self.assertEqual(manager.post_iface_state, 'UP') @@ -116,15 +111,15 @@ class TestDhcpWithNetworkDown(unittest.TestCase): class TestMainFunctions(unittest.TestCase): def test_with_vlans(self): - config = {'eth0': (100, 101), 'eth1': (103, 105), + config = {'eth1': (103, 105), 'eth2': range(106, 120)} result = api.check_dhcp_with_vlans(config) - self.assertEqual(len(list(result)), 3) + self.assertEqual(len(list(result)), 2) def test_with_duplicated_with_repeat(self): - ifaces = ['eth0', 'eth1', 'eth2'] + ifaces = ['eth1', 'eth2'] result = api.check_dhcp(ifaces, repeat=3) - self.assertEqual(len(list(result)), 3) + self.assertEqual(len(list(result)), 2) if __name__ == '__main__': diff --git a/network_checker/net_check/tests/test_net_check.py b/network_checker/net_check/tests/test_net_check.py index 3e7db57669..b57ecbddec 100644 --- a/network_checker/net_check/tests/test_net_check.py +++ b/network_checker/net_check/tests/test_net_check.py @@ -29,10 +29,11 @@ from net_check import api class BaseListenerTestCase(unittest.TestCase): def setUp(self, config=None): + self.iface = os.environ.get('NET_CHECK_IFACE_1', 'eth1') default_config = { "src": "1.0.0.0", "ready_port": None, "ready_address": "localhost", "dst": "1.0.0.0", - "interfaces": {"eth0": "0,100,100,101,102,103,104,105,106,107"}, + "interfaces": {self.iface: "0,100,101,102,103,104,105,106,107"}, "action": "listen", "cookie": "Nailgun:", "dport": 31337, "sport": 31337, "src_mac": None, "dump_file": "/var/tmp/net-probe-dump" @@ -72,34 +73,48 @@ class BaseListenerTestCase(unittest.TestCase): os.unlink(self.config['dump_file']) -class TestCaseListenerPcapFile(BaseListenerTestCase): +class TestCaseListenerPcap(BaseListenerTestCase): def send_packets(self): - directory_path = os.path.dirname(__file__) - scapy_data = scapy.rdpcap(os.path.join(directory_path, 'vlan.pcap')) - for p in scapy_data: - scapy.sendp(p, iface='eth0') + for vlan in self.config['interfaces'][self.iface].split(','): + p = self.get_packet(vlan) + for i in xrange(5): + scapy.sendp(p, iface=self.iface) + + def get_packet(self, vlan): + normal_data = 'Nailgun:{iface} 1'.format(iface=self.iface) + p = scapy.Ether(src='64:0b:36:0e:0a:b7', + dst="ff:ff:ff:ff:ff:ff") + if int(vlan) > 0: + p = p / scapy.Dot1Q(vlan=int(vlan)) + message_len = len(normal_data) + 8 + p = p / scapy.IP(src=self.config['src'], dst=self.config['dst']) + p = p / scapy.UDP(sport=self.config['sport'], + dport=self.config['dport'], + len=message_len) / normal_data + return p def test_listener_pcap_file(self): with open(self.config['dump_file'], 'r') as f: data = json.loads(f.read()) - self.assertEqual(data, {u'eth0': { - u'102': {u'1': [u'eth0'], u'2': [u'eth0']}, - u'103': {u'1': [u'eth0'], u'2': [u'eth0']}, - u'100': {u'1': [u'eth0'], u'2': [u'eth0']}, - u'101': {u'1': [u'eth0'], u'2': [u'eth0']}, - u'106': {u'1': [u'eth0'], u'2': [u'eth0']}, - u'107': {u'1': [u'eth0'], u'2': [u'eth0']}, - u'104': {u'1': [u'eth0'], u'2': [u'eth0']}, - u'105': {u'1': [u'eth0'], u'2': [u'eth0']}}}) + self.assertEqual(data, {self.iface: { + u'0': {u'1': [self.iface]}, + u'102': {u'1': [self.iface]}, + u'103': {u'1': [self.iface]}, + u'100': {u'1': [self.iface]}, + u'101': {u'1': [self.iface]}, + u'106': {u'1': [self.iface]}, + u'107': {u'1': [self.iface]}, + u'104': {u'1': [self.iface]}, + u'105': {u'1': [self.iface]}}}) class TestCaseListenerCorruptedData(BaseListenerTestCase): def send_packets(self): - normal_data = 'Nailgun:eth0 2' + normal_data = 'Nailgun:{iface} 2'.format(iface=self.iface) corrupted_data = normal_data + '7h 7\00\00\00' message_len = len(normal_data) + 8 p = scapy.Ether(src=self.config['src_mac'], @@ -109,26 +124,24 @@ class TestCaseListenerCorruptedData(BaseListenerTestCase): dport=self.config['dport'], len=message_len) / corrupted_data for i in xrange(5): - scapy.sendp(p, iface='eth0') + scapy.sendp(p, iface=self.iface) def test_listener_corrupted_data(self): with open(self.config['dump_file'], 'r') as f: data = json.loads(f.read()) - self.assertEqual(data, {u'eth0': {u'0': {u'2': [u'eth0']}}}) + self.assertEqual(data, {self.iface: {u'0': {u'2': [self.iface]}}}) class TestNetCheckSender(unittest.TestCase): def setUp(self): - directory_path = os.path.dirname(__file__) - self.scapy_data = scapy.rdpcap(os.path.join(directory_path, - 'vlan.pcap')) + self.iface = os.environ.get('NET_CHECK_IFACE_1', 'eth1') self.config = { "src": "1.0.0.0", "ready_port": 31338, "ready_address": "localhost", "dst": "1.0.0.0", - "interfaces": {"eth0": "0,100,101,102,106,107,108"}, + "interfaces": {self.iface: "0,100,101,102,106,107,108"}, "action": "listen", "cookie": "Nailgun:", "dport": 31337, "sport": 31337, "src_mac": None, @@ -137,8 +150,8 @@ class TestNetCheckSender(unittest.TestCase): } def start_pcap_listener(self): - self.pcap_listener = pcap.pcap('eth0') - self.vlan_pcap_listener = pcap.pcap('eth0') + self.pcap_listener = pcap.pcap(self.iface) + self.vlan_pcap_listener = pcap.pcap(self.iface) filter_string = 'udp and dst port {0}'.format(self.config['dport']) self.vlan_pcap_listener.setfilter('vlan and {0}'.format(filter_string)) self.pcap_listener.setfilter(filter_string) @@ -173,5 +186,5 @@ class TestNetCheckSender(unittest.TestCase): time.sleep(3) self.sender.join() - expected_vlans = set(self.config['interfaces']['eth0'].split(',')) + expected_vlans = set(self.config['interfaces'][self.iface].split(',')) self.assertEqual(expected_vlans, self.received_vlans) diff --git a/network_checker/net_check/tests/vlan.pcap b/network_checker/net_check/tests/vlan.pcap deleted file mode 100644 index 99d523202d..0000000000 Binary files a/network_checker/net_check/tests/vlan.pcap and /dev/null differ