Example #1
0
    def test_nonzero_default_delays(self, mocked_delay_node):
        topology = {
            "cluster_type": "replset",
            "mongod": [
                {"public_ip": "1.2.3.4", "private_ip": "10.2.0.1"},
                {"public_ip": "2.3.4.5", "private_ip": "10.2.0.2"},
                {"public_ip": "3.4.5.6", "private_ip": "10.2.0.3"},
            ],
        }
        delay_config = {"default": {"delay_ms": 100, "jitter_ms": 10}, "edges": []}

        DelayGraph.client_node = mocked_delay_node.return_value
        delay_graph = DelayGraph(topology, delay_config)
        self.assertEqual(len(delay_graph.graph), 4)
        delay_spec = DelaySpec({"delay_ms": 100, "jitter_ms": 10})
        self.assertEqual(delay_graph.default_delay.delay_ms, delay_spec.delay_ms)
        self.assertEqual(delay_graph.default_delay.jitter_ms, delay_spec.jitter_ms)

        # Each IP gets called thrice: once for each of the other nodes.
        expected = [
            call("10.2.0.1", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.1", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.1", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.2", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.2", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.2", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.3", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.3", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.3", delay_graph.default_delay, defer_to_edgewise=True),
            call("workload_client", delay_graph.default_delay, defer_to_edgewise=True),
            call("workload_client", delay_graph.default_delay, defer_to_edgewise=True),
            call("workload_client", delay_graph.default_delay, defer_to_edgewise=True),
        ]
        self.assertEqual(mocked_delay_node.return_value.add.call_count, len(expected))
        mocked_delay_node.return_value.add.assert_has_calls(expected, any_order=True)
Example #2
0
 def test_parse_standalone(self):
     topology = {"cluster_type": "standalone", "public_ip": "1.2.3.4", "private_ip": "10.2.0.1"}
     delay_graph = DelayGraph(topology, BASIC_DELAY_CONFIG)
     expected = ["10.2.0.1", "workload_client"]
     for private_ip in delay_graph.graph:
         self.assertTrue(private_ip in expected)
     self.assertEqual(len(expected), len(delay_graph.graph))
Example #3
0
    def test_zero_edgewise_delay(self, mocked_delay_node):
        topology = {
            "cluster_type": "replset",
            "mongod": [
                {"public_ip": "1.2.3.4", "private_ip": "10.2.0.1"},
                {"public_ip": "2.3.4.5", "private_ip": "10.2.0.2"},
                {"public_ip": "3.4.5.6", "private_ip": "10.2.0.3"},
            ],
        }
        delay_config = {
            "default": {"delay_ms": 100, "jitter_ms": 10},
            "edges": [
                {"node1": "10.2.0.1", "node2": "10.2.0.2", "delay": {"delay_ms": 0, "jitter_ms": 0}}
            ],
        }

        DelayGraph.client_node = mocked_delay_node.return_value
        delay_graph = DelayGraph(topology, delay_config)
        self.assertEqual(len(delay_graph.graph), 4)

        expected_edge_spec = EdgeSpec(
            {"node1": "10.2.0.1", "node2": "10.2.0.2", "delay": {"delay_ms": 0, "jitter_ms": 0}}
        )
        expected_delay_spec = expected_edge_spec.delay
        actual_edge_spec = delay_graph.edgewise_delays[0]
        actual_delay_spec = actual_edge_spec.delay
        self.assertEqual(actual_edge_spec.node1, expected_edge_spec.node1)
        self.assertEqual(actual_edge_spec.node2, expected_edge_spec.node2)
        self.assertEqual(actual_delay_spec.delay_ms, expected_delay_spec.delay_ms)
        self.assertEqual(actual_delay_spec.jitter_ms, expected_delay_spec.jitter_ms)

        # Each IP gets called once for each of the other nodes and the workload client.
        # The nodes along the edge each get called an additional time.
        expected = [
            call("10.2.0.1", actual_delay_spec),
            call("10.2.0.2", actual_delay_spec),
            call("10.2.0.1", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.1", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.1", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.2", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.2", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.2", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.3", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.3", delay_graph.default_delay, defer_to_edgewise=True),
            call("10.2.0.3", delay_graph.default_delay, defer_to_edgewise=True),
            call("workload_client", delay_graph.default_delay, defer_to_edgewise=True),
            call("workload_client", delay_graph.default_delay, defer_to_edgewise=True),
            call("workload_client", delay_graph.default_delay, defer_to_edgewise=True),
        ]
        self.assertEqual(mocked_delay_node.return_value.add.call_count, len(expected))
        mocked_delay_node.return_value.add.assert_has_calls(expected, any_order=True)
Example #4
0
 def test_parse_replset(self):
     topology = {
         "cluster_type": "replset",
         "mongod": [
             {"public_ip": "1.2.3.4", "private_ip": "10.2.0.1"},
             {"public_ip": "2.3.4.5", "private_ip": "10.2.0.2"},
             {"public_ip": "3.4.5.6", "private_ip": "10.2.0.3"},
         ],
     }
     delay_graph = DelayGraph(topology, BASIC_DELAY_CONFIG)
     expected = ["10.2.0.1", "10.2.0.2", "10.2.0.3", "workload_client"]
     for private_ip in delay_graph.graph:
         self.assertTrue(private_ip in expected)
     self.assertEqual(len(expected), len(delay_graph.graph))
Example #5
0
    def test_validate_delays(self):
        blacklisted_configs = ["mongodb_setup.atlas.yml"]  # Some configs don't have topologies.
        directory = whereami.dsi_repo_path("configurations", "mongodb_setup")
        errors = []

        # There are a few files that aren't configuration files.
        names = [name for name in os.listdir(directory) if name.startswith("mongodb_setup")]

        # We need references to provisioning output
        infrastructure_provisioning = whereami.dsi_repo_path(
            "docs/config-specs/infrastructure_provisioning.out.yml"
        )
        with copied_file(infrastructure_provisioning, "infrastructure_provisioning.out.yml"):

            for conf_name in names:
                if conf_name in blacklisted_configs:
                    continue
                with copied_file(os.path.join(directory, conf_name), "mongodb_setup.yml"):
                    config = ConfigDict("mongodb_setup")
                    config.load()

                    topologies = config["mongodb_setup"]["topology"]
                    network_delays = config["mongodb_setup"]["network_delays"]
                    delay_configs = network_delays["clusters"]

                    try:
                        # The DelayNodes throw exceptions when given bad delays, so we
                        # can validate the configuration by simply constructing a DelayGraph
                        # pylint: disable=unused-variable
                        DelayGraph.client_ip = config["infrastructure_provisioning"]["out"][
                            "workload_client"
                        ][0]["private_ip"]

                        version_flag = str_to_version_flag(
                            network_delays.get("version_flag", "default")
                        )
                        DelayGraph.client_node = DelayNode(version_flag)
                        delays = DelayGraph.from_topologies(topologies, delay_configs, version_flag)
                    # pylint: disable=broad-except
                    except Exception as e:
                        errors.append(e)

        # Reset the delay graph's client variables.
        DelayGraph.client_node = DelayNode()
        DelayGraph.client_ip = "workload_client"
        self.assertEqual(errors, [])
Example #6
0
 def test_parse_sharded(self):
     topology = {
         "cluster_type": "sharded_cluster",
         "configsvr": [
             {"public_ip": "1.2.3.4", "private_ip": "10.2.0.1"},
             {"public_ip": "2.3.4.5", "private_ip": "10.2.0.2"},
             {"public_ip": "3.4.5.6", "private_ip": "10.2.0.3"},
         ],
         "mongos": [
             {"public_ip": "6.7.8.9", "private_ip": "10.2.0.4"},
             {"public_ip": "7.8.9.10", "private_ip": "10.2.0.5"},
             {"public_ip": "8.9.10.11", "private_ip": "10.2.0.6"},
         ],
         "shard": [
             {
                 "cluster_type": "replset",
                 "mongod": [
                     {"public_ip": "9.10.11.12", "private_ip": "10.2.0.7"},
                     {"public_ip": "10.11.12.13", "private_ip": "10.2.0.8"},
                     {"public_ip": "11.12.13.14", "private_ip": "10.2.0.9"},
                 ],
             },
             {
                 "cluster_type": "replset",
                 "mongod": [
                     {"public_ip": "12.13.14.15", "private_ip": "10.2.0.10"},
                     {"public_ip": "13.14.15.16", "private_ip": "10.2.0.11"},
                     {"public_ip": "14.15.16.17", "private_ip": "10.2.0.12"},
                 ],
             },
             {
                 "cluster_type": "replset",
                 "mongod": [
                     {"public_ip": "15.16.17.18", "private_ip": "10.2.0.13"},
                     {"public_ip": "16.17.18.19", "private_ip": "10.2.0.14"},
                     {"public_ip": "17.18.19.20", "private_ip": "10.2.0.15"},
                 ],
             },
         ],
     }
     delay_graph = DelayGraph(topology, BASIC_DELAY_CONFIG)
     expected = ["10.2.0.{num}".format(num=i) for i in range(1, 16)]
     expected.append("workload_client")
     for private_ip in delay_graph.graph:
         self.assertTrue(private_ip in expected)
     self.assertEqual(len(expected), len(delay_graph.graph))
Example #7
0
    def parse_cluster(self):
        """Create cluster for each topology and delay"""

        inf_prov_out = self.config["infrastructure_provisioning"]
        client_config = inf_prov_out["out"]["workload_client"][0]
        client_ip = client_config["private_ip"]
        DelayGraph.client_ip = client_ip

        topologies = self.mongodb_setup.get("topology", [])
        network_delays = self.mongodb_setup.get("network_delays", {})
        delay_configs = network_delays.get("clusters", [])
        version_flag = str_to_version_flag(
            network_delays.get("version_flag", "default"))
        DelayGraph.client_node = DelayNode(version_flag)
        delays = DelayGraph.from_topologies(topologies, delay_configs,
                                            version_flag)
        client_config = ClientConfig(self.config)
        self.client = Client(client_config)

        # pylint: disable=consider-using-enumerate
        for i in range(len(topologies)):
            self.clusters.append(
                mongodb_cluster.create_cluster(topologies[i], delays[i],
                                               self.config))