def test_converting_to_python_accepts_byte_string(self): example = factory.make_bytes() validator = config.ByteString() self.assertThat(validator.to_python(example), Equals(example))
def test_atomic_write_overwrites_dest_file(self): content = factory.make_bytes() filename = self.make_file(contents=factory.make_string()) atomic_write(content, filename) self.assertThat(filename, FileContains(content))
def test__string_representation_explains_binary_match(self): contents_binary = factory.make_bytes() self.assertDocTestMatches( "File at path exists and its contents (unencoded; raw) " "match Equals(%r)" % (contents_binary, ), FileContains(contents=contents_binary))
def test_catches_failures(self): patch_popen(self, 1) self.assertRaises(CalledProcessError, sudo_write_file, self.make_file(), factory.make_bytes())
def test_incremental_write_sets_permissions(self): atomic_file = self.make_file() mode = 0o323 incremental_write(factory.make_bytes(), atomic_file, mode=mode) self.assertEqual(mode, stat.S_IMODE(os.stat(atomic_file).st_mode))
def test__can_encrypt_and_decrypt_bytes(self): self.write_secret() testdata = factory.make_bytes() token = fernet_encrypt_psk(testdata) decrypted = fernet_decrypt_psk(token) self.assertThat(decrypted, Equals(testdata))
def test_deletes_maas_id_file(self): self.useFixture(MAASIDFixture(factory.make_string())) url = factory.make_simple_http_url() secret = factory.make_bytes() register_command.run(self.make_args(url=url, secret=to_hex(secret))) self.assertIsNone(get_maas_id())
def test_integration(self): loader_contents = factory.make_bytes() loader = self.make_file(contents=loader_contents) destination = self.make_file() atomic_copy(loader, destination) self.assertThat(destination, FileContains(loader_contents))
def test__parses_udp_packet(self): payload = factory.make_bytes(48) packet = make_udp_packet(payload=payload) udp = UDP(packet) self.assertThat(udp.is_valid(), Equals(True)) self.assertThat(udp.payload, Equals(payload))
def test_sets_secret(self): url = factory.make_simple_http_url() expected = factory.make_bytes() register_command.run(self.make_args(url=url, secret=to_hex(expected))) observed = get_shared_secret_from_filesystem() self.assertEqual(expected, observed)
def test_send_requests_and_await_replies(self): # This test is a bit large because it covers the entire functionality # of the `send_requests_and_await_replies()` method. (It could be # split apart into multiple tests, but the large amount of setup work # and interdependencies makes that a maintenance burden.) mock_socket = patch_socket(self) mock_socket.bind = mock.MagicMock() mock_socket.recvfrom = mock.MagicMock() mock_socket.setsockopt = mock.MagicMock() mock_socket.settimeout = mock.MagicMock() # Pretend we were successful at deferring the DHCP requests. self.patch_autospec(detect_module, "blockingCallFromThread") # This method normally blocks for ~10 seconds, so take control of the # monotonic clock and make sure the last call to `recvfrom()` happens # just as we hit the reply timeout. mock_time_monotonic = self.patch(detect_module.time.monotonic) mock_time_monotonic.side_effect = ( # Start time (before loop starts). 10, # First reply (truncated packet). 11, # Second reply (not a match to our transaction). 12, # Third reply (Matching reply with server identifier option). 13, # First socket timeout (need to make sure the loop continues). 14, # Second socket timeout (hey, we're done!). 10 + detect_module.REPLY_TIMEOUT, ) mock_xid = factory.make_bytes(4) valid_dhcp_reply = factory.make_dhcp_packet( transaction_id=mock_xid, include_server_identifier=True, server_ip="127.1.1.1", ) mock_get_xid = self.patch(detect_module.make_dhcp_transaction_id) mock_get_xid.return_value = mock_xid # Valid DHCP packet, but not a match because it doesn't have a # Server Identifier option. valid_non_match = DHCPDiscoverPacket(mac="01:02:03:04:05:06", transaction_id=mock_xid).packet mock_socket.recvfrom.side_effect = ( # Truncated packet, to test logging. (b"", ("127.0.0.1", BOOTP_SERVER_PORT)), (valid_non_match, ("127.0.0.2", BOOTP_SERVER_PORT)), (valid_dhcp_reply, ("127.0.0.3", BOOTP_SERVER_PORT)), socket.timeout, socket.timeout, ) logger = self.useFixture(TwistedLoggerFixture()) monitor = DHCPRequestMonitor("lo", Clock()) result = monitor.send_requests_and_await_replies() self.assertThat( mock_socket.setsockopt, MockCallsMatch( call(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1), call(socket.SOL_SOCKET, socket.SO_BROADCAST, 1), ), ) self.assertThat(mock_socket.bind, MockCallsMatch(call(("", 68)))) self.assertThat( mock_socket.settimeout, MockCallsMatch(call(detect_module.SOCKET_TIMEOUT)), ) self.assertThat( mock_socket.recvfrom, MockCallsMatch(call(2048), call(2048), call(2048), call(2048), call(2048)), ) # One of the response packets was truncated. self.assertThat( logger.output, DocTestMatches("Invalid DHCP response...Truncated..."), ) self.assertThat(result, HasLength(1)) # Ensure we record the fact that the reply packet came from a different # IP address than the server claimed to be. self.assertThat(result, Contains(DHCPServer("127.1.1.1", "127.0.0.3")))
def write_secret(self): secret = factory.make_bytes() secret_path = security.get_shared_secret_filesystem_path() makedirs(dirname(secret_path), exist_ok=True) write_text_file(secret_path, security.to_hex(secret)) return secret
def test__raises_when_no_secret_exists(self): testdata = factory.make_bytes() with ExpectedException(MissingSharedSecret): fernet_encrypt_psk(testdata) with ExpectedException(MissingSharedSecret): fernet_decrypt_psk(b"")
def test_atomic_write_does_not_overwrite_file_if_overwrite_false(self): content = factory.make_bytes() random_content = factory.make_bytes() filename = self.make_file(contents=random_content) atomic_write(content, filename, overwrite=False) self.assertThat(filename, FileContains(random_content))
def ensureSharedSecret(self): """Make sure the shared-secret is set.""" if get_shared_secret_from_filesystem() is None: set_shared_secret_on_filesystem(factory.make_bytes())
def test_atomic_write_writes_file_if_no_file_present(self): filename = os.path.join(self.make_dir(), factory.make_string()) content = factory.make_bytes() atomic_write(content, filename, overwrite=False) self.assertThat(filename, FileContains(content))
def test_process_OK_response_with_other_content(self): data = factory.make_bytes() response = factory.make_response(http.client.OK, data, "application/octet-stream") self.assertEqual(data, tags.process_response(response))
def test_replaces_file_if_changed(self): contents = factory.make_bytes() loader = self.make_file(contents=contents) dest = self.make_file(contents="Old contents") atomic_copy(loader, dest) self.assertThat(dest, FileContains(contents))
def test__compares_in_binary_mode_when_encoding_not_supplied(self): contents = factory.make_bytes() # bytes filename = self.make_file(contents=contents) self.assertThat(filename, FileContains(contents=contents))
def test_can_delete_file_in_development(self): filename = get_maas_data_path("dhcpd.conf") with open(filename, "wb") as fd: fd.write(factory.make_bytes()) sudo_delete_file(filename) self.assertThat(filename, Not(FileExists()))
def test__writes_secret(self): secret = factory.make_bytes() security.set_shared_secret_on_filesystem(secret) self.assertEqual(secret, self.read_secret())