def test_resource_record_equal(self): """ Test case for comparing two equal resource records. """ record1: ResourceRecord = ResourceRecord("record", 1, 1, 600, 4, "1.2.3.4") record2: ResourceRecord = ResourceRecord("record", 1, 1, 600, 4, "1.2.3.4") self.assertTrue(record1 == record2)
def test_resource_record_not_equal_name(self): """ Test case for comparing two resource records with different names. """ record1: ResourceRecord = ResourceRecord("name1", 1, 1, 600, 4, "1.2.3.4") record2: ResourceRecord = ResourceRecord("name2", 1, 1, 600, 4, "1.2.3.4") self.assertTrue(record1 != record2)
def test_resource_record_not_equal_rdata(self): """ Test case for comparing two resource records with different rdata. """ record1: ResourceRecord = ResourceRecord("record", 1, 1, 600, 4, "1.2.3.4") record2: ResourceRecord = ResourceRecord("record", 1, 1, 600, 4, "6.5.3.1") self.assertTrue(record1 != record2)
def test_main_helper_two_answers_returned(self): """ Test case for when the resolver returns two answers """ mock_resolver: Mock = Mock(**{'ask.return_value': [ResourceRecord("www.ubc.cs.ca", 1, 1, 600, 4, "1.2.3.4"), ResourceRecord("www.ubc.cs.ca", 28, 1, 2000, 4, "5.6.7.8")]}) with redirect_stdout(self.buffer): main_helper(mock_resolver, "www.cs.ubc.ca", "1.2.3.4", False, False) self.assertEqual(self.buffer.getvalue(), "\nAnswers:" "\n www.cs.ubc.ca 600 A 1.2.3.4" "\n www.cs.ubc.ca 2000 AAAA 5.6.7.8\n")
def test_resource_record_not_equal_different_object_type(self): """ Test case for comparing two resource records with different rdata. """ record1: ResourceRecord = ResourceRecord("record", 1, 1, 600, 4, "1.2.3.4") self.assertTrue(record1 != "string value")
def test_name_resolution(self): """ Test case for when name resolution requires performing a name resolution. This is also a case where the name resolution returns multiple answers. """ resolver: ResolverCore = ResolverCore(self.mock_socket, False, "1.2.3.4", self.mock_random) answers: List[ResourceRecord] = resolver.resolve_domain_name( "www.stanford.edu", "1.2.3.4", 1) expected_answer: List[ResourceRecord] = [ ResourceRecord('www.stanford.edu', 1, 1, 60, 4, '54.218.91.228'), ResourceRecord('www.stanford.edu', 1, 1, 60, 4, '52.27.175.139'), ResourceRecord('www.stanford.edu', 1, 1, 60, 4, '52.10.247.217') ] self.assertEqual(answers, expected_answer)
def test_cname_resolution(self): """ Test case for when name resolution requires performing a cname resolution. """ resolver: ResolverCore = ResolverCore(self.mock_socket, False, "1.2.3.4", self.mock_random) answers: List[ResourceRecord] = resolver.resolve_domain_name("prep.ai.mit.edu", "1.2.3.4", 1) expected_answer: List[ResourceRecord] = [ResourceRecord('ftp.gnu.org', 1, 1, 300, 4, '208.118.235.20')] self.assertEqual(answers, expected_answer)
def test_incorrect_query_id(self): """ Test case for when a response is received that does not match the query id of the previously sent message. Thus, the resolver discards the packet and waits for another packet with the correct query id. """ resolver: ResolverCore = ResolverCore(self.mock_socket, False, "1.2.3.4", self.mock_random) answers: List[ResourceRecord] = resolver.resolve_domain_name("www.cs.ubc.ca", "1.2.3.4", 1) expected_answer: List[ResourceRecord] = [ResourceRecord('www.cs.ubc.ca', 1, 1, 3600, 4, '142.103.6.5')] self.assertEqual(answers, expected_answer)
def test_matching_authoritative_response(self): """ Test case for when the first response given by the queried dns name server is an authoritative response with a matching resource record type. """ resolver: ResolverCore = ResolverCore(self.mock_socket, False, "1.2.3.4", self.mock_random) answers: List[ResourceRecord] = resolver.resolve_domain_name("www.cs.ubc.ca", "1.2.3.4", 1) expected_answer: List[ResourceRecord] = [ResourceRecord('www.cs.ubc.ca', 1, 1, 3600, 4, '142.103.6.5')] self.assertEqual(answers, expected_answer)
def test_print_dns_response(self): """ Test case for printing dns responses to stdout. """ message: DNSMessage = DNSMessage( 1, True, 1, True, True, True, True, 1, 1, 1, 2, 3, [DNSQuestion("question", 1, 1)], [ResourceRecord("record1", 10, 11, 12, 4, "1.2.3.4")], [ ResourceRecord("record1", 10, 11, 12, 4, "1.2.3.4"), ResourceRecord("record2", 15, 16, 17, 4, "5.6.7.8") ], [ ResourceRecord("record1", 10, 11, 12, 4, "1.2.3.4"), ResourceRecord("record2", 15, 16, 17, 4, "5.6.7.8"), ResourceRecord("record3", 18, 19, 20, 4, "9.10.11.12") ]) buffer: StringIO = StringIO() with redirect_stdout(buffer): message.print_dns_response() self.assertEqual( buffer.getvalue(), "Response ID: 1 Authoritative = True\n" " Answers (1)\n" " record1 12 10 1.2.3.4\n" " Name Servers (2)\n" " record1 12 10 1.2.3.4\n" " record2 17 15 5.6.7.8\n" " Additional Information (3)\n" " record1 12 10 1.2.3.4\n" " record2 17 15 5.6.7.8\n" " record3 20 18 9.10.11.12\n" )
def test_print_record_for_trace(self): """ Test case for printing resource records for the tracing """ record: ResourceRecord = ResourceRecord("record", 1, 1, 600, 4, "1.2.3.4") buffer: StringIO = StringIO() with redirect_stdout(buffer): record.print_record_for_trace() self.assertEqual(buffer.getvalue(), " record 600 A 1.2.3.4\n")
def test_get_name_server_ip_address_helper_no_additional_records(self): """ Test case to retrieve the ip address for a name server for which there is additional record whose name matches the name server name. """ name_server_record: ResourceRecord = ResourceRecord( "ca", 2, 1, 172800, 8, "no-match") name_server_ip: Optional[ str] = DNSMessage.get_name_server_ip_address_helper( name_server_record, []) self.assertEqual(name_server_ip, None)
def test_get_name_server_ip_address_helper_no_type_match(self): """ Test case to retrieve the ip address for a name server for which there is an additional record whose name is the name server name, but is of the incorrect type. """ name_server_record: ResourceRecord = ResourceRecord( "ca", 2, 1, 172800, 8, "y.ubc.ca") name_server_ip: Optional[ str] = DNSMessage.get_name_server_ip_address_helper( name_server_record, self.additional_records) self.assertEqual(name_server_ip, None)
def test_resource_record_print(self): """ Test case for printing a resource record using print(), which calls __repr__(). """ record: ResourceRecord = ResourceRecord("record", 1, 1, 600, 4, "1.2.3.4") buffer: StringIO = StringIO() with redirect_stdout(buffer): print(record) self.assertEqual(buffer.getvalue(), "ResourceRecord(name: record, type: 1, class: 1, " "ttl: 600, rdlength: 4, rdata: 1.2.3.4)\n")
def test_get_name_server_ip_address_helper_only_one_match(self): """ Test case to retrieve the ip address of a name server for which there is a match of the correct type and there is only one match in the additional records. """ name_server_record: ResourceRecord = ResourceRecord( "ca", 2, 1, 172800, 8, "x.ubc.ca") name_server_ip: Optional[ str] = DNSMessage.get_name_server_ip_address_helper( name_server_record, self.additional_records) self.assertEqual(name_server_ip, "1.2.3.4")
def test_print_record_with_supplied_domain_name(self): """ Test case for printing resource records with a supplied domain name to be included in the message. (Used when printing the answers of the resolver. We supply the original domain name that was searched for to clearly indicate to the user that the records we have found are for the domain name they initially searched for.) """ record: ResourceRecord = ResourceRecord("record", 1, 1, 600, 4, "1.2.3.4") buffer: StringIO = StringIO() with redirect_stdout(buffer): record.print_record_with_supplied_domain_name("the original domain name") self.assertEqual(buffer.getvalue(), " the original domain name 600 A 1.2.3.4\n")
def test_name_server_response_then_authoritative_ipv6(self): """ Test case for when the first two responses non-authoritative responses and the final one is authoritative and contains a matching resource record. The first two responses both contain the ip address a name server, so we do not need to do a separate lookup for the ip address of the name server. """ resolver: ResolverCore = ResolverCore(self.mock_socket, False, "1.2.3.4", self.mock_random) answers: List[ResourceRecord] = resolver.resolve_domain_name("www.google.com", "1.2.3.4", 28) expected_answer: List[ResourceRecord] = [ResourceRecord('www.google.com', 28, 1, 300, 16, '2607:f8b0:400a:803::2004')] self.assertEqual(answers, expected_answer)
def test_get_name_server_ip_address_helper_multiple_matches(self): """ Test case to retrieve the ip address of a name server for which there is a match of the correct type and there are multiple matching records in the additional records. The first match's ip address should be returned. """ name_server_record: ResourceRecord = ResourceRecord( "ca", 2, 1, 172800, 8, "z.ubc.ca") name_server_ip: Optional[ str] = DNSMessage.get_name_server_ip_address_helper( name_server_record, self.additional_records) self.assertEqual(name_server_ip, "3.4.5.6")
def test_cname_resolution(self): """ Test case for when two different cname resolutions and one name server resolution needs to be performed before finding an authoritative response. """ resolver: ResolverCore = ResolverCore(self.mock_socket, False, "1.2.3.4", self.mock_random) answers: List[ResourceRecord] = resolver.resolve_domain_name( "finance.google.ca", "1.2.3.4", 1) expected_answer: List[ResourceRecord] = [ ResourceRecord('www3.l.google.com', 1, 1, 300, 4, '216.58.193.78') ] self.assertEqual(answers, expected_answer)
def test_cname_and_name_resolution_ipv6(self): """ Test case for when two different cname resolutions and one name server resolution needs to be performed before finding an authoritative response. Searching for an ipv6 address. """ resolver: ResolverCore = ResolverCore(self.mock_socket, False, "1.2.3.4", self.mock_random) answers: List[ResourceRecord] = resolver.resolve_domain_name( "finance.google.ca", "1.2.3.4", 28) expected_answer: List[ResourceRecord] = [ ResourceRecord('www3.l.google.com', 28, 1, 300, 16, '2607:f8b0:400a:800::200e') ] self.assertEqual(answers, expected_answer)
def test_matching_authoritative_response_ipv6(self): """ Test case for when the first response given by the queried dns name server is an authoritative response with an ipv6 resource record type, which is what was asked for. """ resolver: ResolverCore = ResolverCore(self.mock_socket, False, "1.2.3.4", self.mock_random) answers: List[ResourceRecord] = resolver.resolve_domain_name( "www.google.com", "1.2.3.4", 28) expected_answer: List[ResourceRecord] = [ ResourceRecord('www.google.com', 28, 1, 300, 16, '2607:f8b0:400a:800::2004') ] self.assertEqual(answers, expected_answer)
def test_print_dns_query(self): """ Test case for printing a dns query to stdout. """ message: DNSMessage = DNSMessage( 1, True, 1, True, True, True, True, 1, 1, 1, 2, 3, [DNSQuestion("question", 1, 1)], [ResourceRecord("record1", 10, 11, 12, 4, "1.2.3.4")], [ ResourceRecord("record1", 10, 11, 12, 4, "1.2.3.4"), ResourceRecord("record2", 15, 16, 17, 4, "5.6.7.8") ], [ ResourceRecord("record1", 10, 11, 12, 4, "1.2.3.4"), ResourceRecord("record2", 15, 16, 17, 4, "5.6.7.8"), ResourceRecord("record3", 18, 19, 20, 4, "9.10.11.12") ]) buffer: StringIO = StringIO() with redirect_stdout(buffer): message.print_dns_query("255.255.255.255") self.assertEqual(buffer.getvalue(), "Query ID: 1 question A --> 255.255.255.255\n")
def setUpClass(cls): """ Initialize test values used in the tests. """ cls.dns_message_encoded: bytes = Utilities().dns_message_encoded cls.three_consecutive_dns_questions_encoded: bytes = Utilities( ).three_consecutive_dns_questions_encoded cls.three_consecutive_resource_records_encoded: bytes = Utilities( ).three_consecutive_resource_records_encoded cls.resource_record_1: ResourceRecord = ResourceRecord( "name1", 1, 2, 1234, 4, "1.2.3.4") cls.resource_record_2: ResourceRecord = ResourceRecord( "name2", 5, 2, 1234, 1, "a") cls.resource_record_3: ResourceRecord = ResourceRecord( "name3", 2, 2, 1234, 1, "a") cls.resource_record_4: ResourceRecord = ResourceRecord( "name2", 5, 2, 1234, 1, "a") cls.resource_records: List[ResourceRecord] = [ cls.resource_record_1, cls.resource_record_2, cls.resource_record_3, cls.resource_record_4 ] cls.additional_record_1: ResourceRecord = ResourceRecord( "x.ubc.ca", 1, 2, 1234, 4, "1.2.3.4") cls.additional_record_2: ResourceRecord = ResourceRecord( "y.ubc.ca", 28, 2, 1234, 16, "1008:2002:1008:2002:1008:2002:1008:2002") cls.additional_record_3: ResourceRecord = ResourceRecord( "z.ubc.ca", 1, 2, 1234, 4, "3.4.5.6") cls.additional_record_4: ResourceRecord = ResourceRecord( "z.ubc.ca", 1, 2, 1234, 4, "4.5.6.7") cls.additional_records: List[ResourceRecord] = [ cls.additional_record_1, cls.additional_record_2, cls.additional_record_3, cls.additional_record_4 ] cls.name_server_record_1: ResourceRecord = ResourceRecord( "ca", 2, 1, 172800, 8, "x.ubc.ca") cls.name_server_record_2: ResourceRecord = ResourceRecord( "ca", 2, 1, 172800, 8, "z.ubc.ca") cls.name_server_record_3: ResourceRecord = ResourceRecord( "ca", 2, 1, 172800, 8, "a.ubc.ca") cls.name_server_records_list_1: List[ResourceRecord] = [ cls.name_server_record_1, cls.name_server_record_3 ] cls.name_server_records_list_2: List[ResourceRecord] = [ cls.name_server_record_3 ] cls.name_server_records_list_3: List[ResourceRecord] = [ cls.name_server_record_1, cls.name_server_record_2, cls.name_server_record_3 ]