def test_config_file_that_does_not_match_schema_throws_error(self):
     self.assertRaises(
         verify_data_plane_config.
         DataPlaneConfigErrorFailedSchemaVerification,
         verify_data_plane_config.VerifyDataPlaneConfig(
             self.schema).validate_and_return_json,
         json.dumps({"ingress": {}}))
 def test_valid_shared_secret_and_import_does_not_throw(self):
     config_valid = copy.deepcopy(self.config)
     config_valid[
         "sharedSecret"] = "D072D36795A5D10B2010DFE1D04BDF14D072D36795A5D10B2010DFE1D04BDF14"
     verify_data_plane_config.VerifyDataPlaneConfig(
         self.schema, diode_variant="import").validate_and_return_json(
             json.dumps(config_valid))
 def test_shared_secret_not_provided_fails_if_variant_is_is_export(self):
     self.assertRaisesRegex(
         verify_data_plane_config.
         DataPlaneConfigErrorFailedSchemaVerification,
         "Provided config file failed schema verification ",
         verify_data_plane_config.VerifyDataPlaneConfig(
             self.schema, diode_variant="export").validate_and_return_json,
         json.dumps(self.config))
 def test_shared_secret_cannot_be_longer_than_32(self):
     config_longer_than_32 = copy.deepcopy(self.config)
     config_longer_than_32[
         "sharedSecret"] = "D072D36795A5D10B2010DFE1D04BDF14D072D36795A5D10B2010DFE1D04BDF143"
     self.assertRaises(
         verify_data_plane_config.DataPlaneConfigError,
         verify_data_plane_config.VerifyDataPlaneConfig(
             self.schema, diode_variant="export").validate_and_return_json,
         json.dumps(config_longer_than_32))
 def test_shared_secret_must_be_hex(self):
     config_non_hex_shared_secret = copy.deepcopy(self.config)
     config_non_hex_shared_secret[
         "sharedSecret"] = "000000Y00000F000000X0000Z0ZZ0000000000Y00000F000000X0000Z0ZZ0000"
     self.assertRaises(
         verify_data_plane_config.DataPlaneConfigError,
         verify_data_plane_config.VerifyDataPlaneConfig(
             self.schema, diode_variant="export").validate_and_return_json,
         json.dumps(config_non_hex_shared_secret))
 def test_shared_secret_provided_is_not_maximum_value(self):
     config_maximum_value_shared_secret = copy.deepcopy(self.config)
     config_maximum_value_shared_secret[
         "sharedSecret"] = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
     self.assertRaises(
         verify_data_plane_config.DataPlaneConfigError,
         verify_data_plane_config.VerifyDataPlaneConfig(
             self.schema, diode_variant="export").validate_and_return_json,
         json.dumps(config_maximum_value_shared_secret))
 def test_config_file_longer_than_max_length_throws_error(self):
     self.assertRaisesRegex(
         verify_data_plane_config.DataPlaneConfigErrorFileSizeTooLarge,
         "Provided config file size too large",
         verify_data_plane_config.VerifyDataPlaneConfig(
             schema={}, max_config_bytes=10).validate_and_return_json,
         json.dumps({
             "ingress": {},
             "egress": {},
             "routingTable": []
         }))
    def test_status_port_in_use_throws_error(self):
        config_with_status_port_in_use = copy.deepcopy(self.config)
        config_with_status_port_in_use["routingTable"][0][
            "ingressPort"] = self.config["ingress"]["statusPort"]

        self.assertRaisesRegex(
            verify_data_plane_config.DataPlaneConfigErrorStatusPortInUse,
            "Config validation failed: Status port must not be in use",
            verify_data_plane_config.VerifyDataPlaneConfig(
                self.schema).validate_and_return_json,
            json.dumps(config_with_status_port_in_use))

        config_with_status_port_in_use = copy.deepcopy(self.config)
        config_with_status_port_in_use["routingTable"][1][
            "ingressPort"] = self.config["ingress"]["statusPort"]

        self.assertRaisesRegex(
            verify_data_plane_config.DataPlaneConfigErrorStatusPortInUse,
            "Config validation failed: Status port must not be in use",
            verify_data_plane_config.VerifyDataPlaneConfig(
                self.schema).validate_and_return_json,
            json.dumps(config_with_status_port_in_use))
 def test_port_span_exceeds_2048_throws_error(self):
     config_port_span_too_large = copy.deepcopy(self.config)
     config_port_span_too_large["routingTable"] = [{
         "ingressPort": 40000,
         "egressIpAddress": "192.168.0.20",
         "egressSrcPort": 50001,
         "egressDestPort": 50001
     }, {
         "ingressPort": 42048,
         "egressIpAddress": "192.168.0.21",
         "egressSrcPort": 51024,
         "egressDestPort": 51024
     }]
     self.assertRaisesRegex(
         verify_data_plane_config.DataPlaneConfigErrorInvalidPortSpan,
         "Config validation failed: Ingress portSpan must be less than 2048",
         verify_data_plane_config.VerifyDataPlaneConfig(
             self.schema).validate_and_return_json,
         json.dumps(config_port_span_too_large))
    def test_unique_egress_ip_addresses_exceeds_20_throws_error(self):
        config_with_excess_egress_ips = copy.deepcopy(self.config)
        config_with_excess_egress_ips["routingTable"] = [{
            "ingressPort":
            40000 + i,
            "egressIpAddress":
            f"192.168.0.{i % 25}",
            "egressSrcPort":
            50000 + i,
            "egressDestPort":
            51000 + i
        } for i in range(50)]

        self.assertRaisesRegex(
            verify_data_plane_config.DataPlaneConfigErrorInvalidEgressIPs,
            "Config validation failed: The number of egress IPs in the routing table must be 20, or fewer",
            verify_data_plane_config.VerifyDataPlaneConfig(
                self.schema).validate_and_return_json,
            json.dumps(config_with_excess_egress_ips))
 def test_ingress_ports_not_unique_throws_error(self):
     config_ports_not_unique = copy.deepcopy(self.config)
     config_ports_not_unique["routingTable"] = [{
         "ingressPort": 40000,
         "egressIpAddress": "192.168.0.20",
         "egressSrcPort": 50001,
         "egressDestPort": 50001
     }, {
         "ingressPort": 40000,
         "egressIpAddress": "192.168.0.21",
         "egressSrcPort": 51024,
         "egressDestPort": 51024
     }]
     self.assertRaisesRegex(
         verify_data_plane_config.DataPlaneConfigErrorIngressPortsNotUnique,
         "Config validation failed: Ingress ports must be unique",
         verify_data_plane_config.VerifyDataPlaneConfig(
             self.schema).validate_and_return_json,
         json.dumps(config_ports_not_unique))
 def test_config_file_matches_schema_and_is_returned_as_json(self):
     result = verify_data_plane_config.VerifyDataPlaneConfig(
         self.schema).validate_and_return_json(json.dumps(self.config))
     self.assertEqual(result, self.config)
 def test_config_file_that_is_invalid_json_throws_error(self):
     self.assertRaisesRegex(
         verify_data_plane_config.DataPlaneConfigErrorInvalidJson,
         "Provided config file is not valid json: ",
         verify_data_plane_config.VerifyDataPlaneConfig(
             self.schema).validate_and_return_json, "notjson")
 def test_empty_config_throws_error(self):
     self.assertRaisesRegex(
         verify_data_plane_config.DataPlaneConfigErrorEmptyFile,
         "Provided config file is empty",
         verify_data_plane_config.VerifyDataPlaneConfig(
             {}).validate_and_return_json, "")
 def test_no_shared_secret_and_import_variant_does_not_throw(self):
     verify_data_plane_config.VerifyDataPlaneConfig(
         self.schema, diode_variant="import").validate_and_return_json(
             json.dumps(self.config))