def test_dhcp_output_error_stream(self, m_subp, m_kill, m_getppid): """"dhcp_log_func is called with the output and error streams of dhclinet when the callable is passed.""" dhclient_err = 'FAKE DHCLIENT ERROR' dhclient_out = 'FAKE DHCLIENT OUT' m_subp.return_value = (dhclient_out, dhclient_err) tmpdir = self.tmp_dir() dhclient_script = os.path.join(tmpdir, 'dhclient.orig') script_content = '#!/bin/bash\necho fake-dhclient' write_file(dhclient_script, script_content, mode=0o755) lease_content = dedent(""" lease { interface "eth9"; fixed-address 192.168.2.74; option subnet-mask 255.255.255.0; option routers 192.168.2.1; } """) lease_file = os.path.join(tmpdir, 'dhcp.leases') write_file(lease_file, lease_content) pid_file = os.path.join(tmpdir, 'dhclient.pid') my_pid = 1 write_file(pid_file, "%d\n" % my_pid) m_getppid.return_value = 1 # Indicate that dhclient has daemonized def dhcp_log_func(out, err): self.assertEqual(out, dhclient_out) self.assertEqual(err, dhclient_err) dhcp_discovery(dhclient_script, 'eth9', tmpdir, dhcp_log_func=dhcp_log_func)
def test_dhcp_discovery_run_in_sandbox_warns_invalid_pid(self, m_subp, m_kill): """dhcp_discovery logs a warning when pidfile contains invalid content. Lease processing still occurs and no proc kill is attempted. """ tmpdir = self.tmp_dir() dhclient_script = os.path.join(tmpdir, 'dhclient.orig') script_content = '#!/bin/bash\necho fake-dhclient' write_file(dhclient_script, script_content, mode=0o755) write_file(self.tmp_path('dhclient.pid', tmpdir), '') # Empty pid '' lease_content = dedent(""" lease { interface "eth9"; fixed-address 192.168.2.74; option subnet-mask 255.255.255.0; option routers 192.168.2.1; } """) write_file(self.tmp_path('dhcp.leases', tmpdir), lease_content) self.assertCountEqual( [{'interface': 'eth9', 'fixed-address': '192.168.2.74', 'subnet-mask': '255.255.255.0', 'routers': '192.168.2.1'}], dhcp_discovery(dhclient_script, 'eth9', tmpdir)) self.assertIn( "dhclient(pid=, parentpid=unknown) failed " "to daemonize after 10.0 seconds", self.logs.getvalue()) m_kill.assert_not_called()
def test_dhcp_discovery_run_in_sandbox_warns_invalid_pid(self, m_subp, m_kill): """dhcp_discovery logs a warning when pidfile contains invalid content. Lease processing still occurs and no proc kill is attempted. """ tmpdir = self.tmp_dir() dhclient_script = os.path.join(tmpdir, 'dhclient.orig') script_content = '#!/bin/bash\necho fake-dhclient' write_file(dhclient_script, script_content, mode=0o755) write_file(self.tmp_path('dhclient.pid', tmpdir), '') # Empty pid '' lease_content = dedent(""" lease { interface "eth9"; fixed-address 192.168.2.74; option subnet-mask 255.255.255.0; option routers 192.168.2.1; } """) write_file(self.tmp_path('dhcp.leases', tmpdir), lease_content) self.assertItemsEqual( [{'interface': 'eth9', 'fixed-address': '192.168.2.74', 'subnet-mask': '255.255.255.0', 'routers': '192.168.2.1'}], dhcp_discovery(dhclient_script, 'eth9', tmpdir)) self.assertIn( "dhclient(pid=, parentpid=unknown) failed " "to daemonize after 10.0 seconds", self.logs.getvalue()) m_kill.assert_not_called()
def test_dhcp_discovery_outside_sandbox(self, m_subp, m_kill, m_getppid): """dhcp_discovery brings up the interface and runs dhclient. It also returns the parsed dhcp.leases file generated in the sandbox. """ m_subp.return_value = ("", "") tmpdir = self.tmp_dir() dhclient_script = os.path.join(tmpdir, "dhclient.orig") script_content = "#!/bin/bash\necho fake-dhclient" write_file(dhclient_script, script_content, mode=0o755) lease_content = dedent(""" lease { interface "eth9"; fixed-address 192.168.2.74; option subnet-mask 255.255.255.0; option routers 192.168.2.1; } """) lease_file = os.path.join(tmpdir, "dhcp.leases") write_file(lease_file, lease_content) pid_file = os.path.join(tmpdir, "dhclient.pid") my_pid = 1 write_file(pid_file, "%d\n" % my_pid) m_getppid.return_value = 1 # Indicate that dhclient has daemonized with mock.patch("os.access", return_value=False): self.assertCountEqual( [{ "interface": "eth9", "fixed-address": "192.168.2.74", "subnet-mask": "255.255.255.0", "routers": "192.168.2.1", }], dhcp_discovery(dhclient_script, "eth9", tmpdir), ) # dhclient script got copied with open(os.path.join(tmpdir, "dhclient.orig")) as stream: self.assertEqual(script_content, stream.read()) # Interface was brought up before dhclient called from sandbox m_subp.assert_has_calls([ mock.call(["ip", "link", "set", "dev", "eth9", "up"], capture=True), mock.call( [ os.path.join(tmpdir, "dhclient.orig"), "-1", "-v", "-lf", lease_file, "-pf", os.path.join(tmpdir, "dhclient.pid"), "eth9", "-sf", "/bin/true", ], capture=True, ), ]) m_kill.assert_has_calls([mock.call(my_pid, signal.SIGKILL)])
def test_dhcp_discovery_outside_sandbox(self, m_subp, m_kill, m_getppid): """dhcp_discovery brings up the interface and runs dhclient. It also returns the parsed dhcp.leases file generated in the sandbox. """ m_subp.return_value = ('', '') tmpdir = self.tmp_dir() dhclient_script = os.path.join(tmpdir, 'dhclient.orig') script_content = '#!/bin/bash\necho fake-dhclient' write_file(dhclient_script, script_content, mode=0o755) lease_content = dedent(""" lease { interface "eth9"; fixed-address 192.168.2.74; option subnet-mask 255.255.255.0; option routers 192.168.2.1; } """) lease_file = os.path.join(tmpdir, 'dhcp.leases') write_file(lease_file, lease_content) pid_file = os.path.join(tmpdir, 'dhclient.pid') my_pid = 1 write_file(pid_file, "%d\n" % my_pid) m_getppid.return_value = 1 # Indicate that dhclient has daemonized with mock.patch('os.access', return_value=False): self.assertCountEqual([{ 'interface': 'eth9', 'fixed-address': '192.168.2.74', 'subnet-mask': '255.255.255.0', 'routers': '192.168.2.1' }], dhcp_discovery(dhclient_script, 'eth9', tmpdir)) # dhclient script got copied with open(os.path.join(tmpdir, 'dhclient.orig')) as stream: self.assertEqual(script_content, stream.read()) # Interface was brought up before dhclient called from sandbox m_subp.assert_has_calls([ mock.call(['ip', 'link', 'set', 'dev', 'eth9', 'up'], capture=True), mock.call([ os.path.join(tmpdir, 'dhclient.orig'), '-1', '-v', '-lf', lease_file, '-pf', os.path.join(tmpdir, 'dhclient.pid'), 'eth9', '-sf', '/bin/true' ], capture=True) ]) m_kill.assert_has_calls([mock.call(my_pid, signal.SIGKILL)])
def test_dhcp_discovery_run_in_sandbox_waits_on_lease_and_pid( self, m_subp, m_wait, m_kill): """dhcp_discovery waits for the presence of pidfile and dhcp.leases.""" tmpdir = self.tmp_dir() dhclient_script = os.path.join(tmpdir, 'dhclient.orig') script_content = '#!/bin/bash\necho fake-dhclient' write_file(dhclient_script, script_content, mode=0o755) # Don't create pid or leases file pidfile = self.tmp_path('dhclient.pid', tmpdir) leasefile = self.tmp_path('dhcp.leases', tmpdir) m_wait.return_value = [pidfile] # Return the missing pidfile wait for self.assertEqual([], dhcp_discovery(dhclient_script, 'eth9', tmpdir)) self.assertEqual( mock.call([pidfile, leasefile], maxwait=5, naplen=0.01), m_wait.call_args_list[0]) self.assertIn( 'WARNING: dhclient did not produce expected files: dhclient.pid', self.logs.getvalue()) m_kill.assert_not_called()
def test_dhcp_discovery_run_in_sandbox_warns_invalid_pid( self, m_subp, m_kill ): """dhcp_discovery logs a warning when pidfile contains invalid content. Lease processing still occurs and no proc kill is attempted. """ m_subp.return_value = ("", "") tmpdir = self.tmp_dir() dhclient_script = os.path.join(tmpdir, "dhclient.orig") script_content = "#!/bin/bash\necho fake-dhclient" write_file(dhclient_script, script_content, mode=0o755) write_file(self.tmp_path("dhclient.pid", tmpdir), "") # Empty pid '' lease_content = dedent( """ lease { interface "eth9"; fixed-address 192.168.2.74; option subnet-mask 255.255.255.0; option routers 192.168.2.1; } """ ) write_file(self.tmp_path("dhcp.leases", tmpdir), lease_content) self.assertCountEqual( [ { "interface": "eth9", "fixed-address": "192.168.2.74", "subnet-mask": "255.255.255.0", "routers": "192.168.2.1", } ], dhcp_discovery(dhclient_script, "eth9", tmpdir), ) self.assertIn( "dhclient(pid=, parentpid=unknown) failed " "to daemonize after 10.0 seconds", self.logs.getvalue(), ) m_kill.assert_not_called()
def test_dhcp_discovery_run_in_sandbox(self, m_subp): """dhcp_discovery brings up the interface and runs dhclient. It also returns the parsed dhcp.leases file generated in the sandbox. """ tmpdir = self.tmp_dir() dhclient_script = os.path.join(tmpdir, 'dhclient.orig') script_content = '#!/bin/bash\necho fake-dhclient' write_file(dhclient_script, script_content, mode=0o755) lease_content = dedent(""" lease { interface "eth9"; fixed-address 192.168.2.74; option subnet-mask 255.255.255.0; option routers 192.168.2.1; } """) lease_file = os.path.join(tmpdir, 'dhcp.leases') write_file(lease_file, lease_content) self.assertItemsEqual([{ 'interface': 'eth9', 'fixed-address': '192.168.2.74', 'subnet-mask': '255.255.255.0', 'routers': '192.168.2.1' }], dhcp_discovery(dhclient_script, 'eth9', tmpdir)) # dhclient script got copied with open(os.path.join(tmpdir, 'dhclient')) as stream: self.assertEqual(script_content, stream.read()) # Interface was brought up before dhclient called from sandbox m_subp.assert_has_calls([ mock.call(['ip', 'link', 'set', 'dev', 'eth9', 'up'], capture=True), mock.call([ os.path.join(tmpdir, 'dhclient'), '-1', '-v', '-lf', lease_file, '-pf', os.path.join(tmpdir, 'dhclient.pid'), 'eth9', '-sf', '/bin/true' ], capture=True) ])
def test_dhcp_discovery_run_in_sandbox(self, m_subp, m_kill, m_getppid): """dhcp_discovery brings up the interface and runs dhclient. It also returns the parsed dhcp.leases file generated in the sandbox. """ tmpdir = self.tmp_dir() dhclient_script = os.path.join(tmpdir, 'dhclient.orig') script_content = '#!/bin/bash\necho fake-dhclient' write_file(dhclient_script, script_content, mode=0o755) lease_content = dedent(""" lease { interface "eth9"; fixed-address 192.168.2.74; option subnet-mask 255.255.255.0; option routers 192.168.2.1; } """) lease_file = os.path.join(tmpdir, 'dhcp.leases') write_file(lease_file, lease_content) pid_file = os.path.join(tmpdir, 'dhclient.pid') my_pid = 1 write_file(pid_file, "%d\n" % my_pid) m_getppid.return_value = 1 # Indicate that dhclient has daemonized self.assertItemsEqual( [{'interface': 'eth9', 'fixed-address': '192.168.2.74', 'subnet-mask': '255.255.255.0', 'routers': '192.168.2.1'}], dhcp_discovery(dhclient_script, 'eth9', tmpdir)) # dhclient script got copied with open(os.path.join(tmpdir, 'dhclient')) as stream: self.assertEqual(script_content, stream.read()) # Interface was brought up before dhclient called from sandbox m_subp.assert_has_calls([ mock.call( ['ip', 'link', 'set', 'dev', 'eth9', 'up'], capture=True), mock.call( [os.path.join(tmpdir, 'dhclient'), '-1', '-v', '-lf', lease_file, '-pf', os.path.join(tmpdir, 'dhclient.pid'), 'eth9', '-sf', '/bin/true'], capture=True)]) m_kill.assert_has_calls([mock.call(my_pid, signal.SIGKILL)])
def test_dhcp_discovery_run_in_sandbox_waits_on_lease_and_pid( self, m_subp, m_wait, m_kill, m_getppid): """dhcp_discovery waits for the presence of pidfile and dhcp.leases.""" m_subp.return_value = ("", "") tmpdir = self.tmp_dir() dhclient_script = os.path.join(tmpdir, "dhclient.orig") script_content = "#!/bin/bash\necho fake-dhclient" write_file(dhclient_script, script_content, mode=0o755) # Don't create pid or leases file pidfile = self.tmp_path("dhclient.pid", tmpdir) leasefile = self.tmp_path("dhcp.leases", tmpdir) m_wait.return_value = [pidfile] # Return the missing pidfile wait for m_getppid.return_value = 1 # Indicate that dhclient has daemonized self.assertEqual([], dhcp_discovery(dhclient_script, "eth9", tmpdir)) self.assertEqual( mock.call([pidfile, leasefile], maxwait=5, naplen=0.01), m_wait.call_args_list[0], ) self.assertIn( "WARNING: dhclient did not produce expected files: dhclient.pid", self.logs.getvalue(), ) m_kill.assert_not_called()
def test_dhcp_discovery_run_in_sandbox_waits_on_lease_and_pid(self, m_subp, m_wait, m_kill, m_getppid): """dhcp_discovery waits for the presence of pidfile and dhcp.leases.""" tmpdir = self.tmp_dir() dhclient_script = os.path.join(tmpdir, 'dhclient.orig') script_content = '#!/bin/bash\necho fake-dhclient' write_file(dhclient_script, script_content, mode=0o755) # Don't create pid or leases file pidfile = self.tmp_path('dhclient.pid', tmpdir) leasefile = self.tmp_path('dhcp.leases', tmpdir) m_wait.return_value = [pidfile] # Return the missing pidfile wait for m_getppid.return_value = 1 # Indicate that dhclient has daemonized self.assertEqual([], dhcp_discovery(dhclient_script, 'eth9', tmpdir)) self.assertEqual( mock.call([pidfile, leasefile], maxwait=5, naplen=0.01), m_wait.call_args_list[0]) self.assertIn( 'WARNING: dhclient did not produce expected files: dhclient.pid', self.logs.getvalue()) m_kill.assert_not_called()