@Override
    public void load(RoutingTable table) {
        synchronized (monitor) {
            try {
                table = table.routingMethod(RoutingMethod.sharedLayer4); // This router only supports layer 4 endpoints
                testConfig(table);
                loadConfig(table.asMap().size());
                gcConfig();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }
    }
@Test
    public void load_routing_table() {
        NginxTester tester = new NginxTester();
        tester.clock.setInstant(Instant.parse("2022-01-01T15:00:00Z"));

        // Load routing table
        RoutingTable table0 = TestUtil.readRoutingTable("lbservices-config");
        tester.load(table0)
              .assertVerifiedConfig(1)
              .assertLoadedConfig(true)
              .assertConfigContents("nginx.conf")
              .assertTemporaryConfigRemoved(true)
              .assertMetric(Nginx.CONFIG_RELOADS_METRIC, 1)
              .assertMetric(Nginx.OK_CONFIG_RELOADS_METRIC, 1)
              .assertMetric(Nginx.GENERATED_UPSTREAMS_METRIC, 5);

        // Loading the same table again does nothing
        tester.load(table0)
              .assertVerifiedConfig(1)
              .assertLoadedConfig(false)
              .assertConfigContents("nginx.conf")
              .assertTemporaryConfigRemoved(true)
              .assertMetric(Nginx.CONFIG_RELOADS_METRIC, 1)
              .assertMetric(Nginx.OK_CONFIG_RELOADS_METRIC, 1)
              .assertMetric(Nginx.GENERATED_UPSTREAMS_METRIC, 5);

        // A new table is loaded
        Map<RoutingTable.Endpoint, RoutingTable.Target> newEntries = new HashMap<>(table0.asMap());
        newEntries.put(new RoutingTable.Endpoint("endpoint1", RoutingMethod.sharedLayer4),
                       RoutingTable.Target.create(ApplicationId.from("t1", "a1", "i1"),
                                                  ClusterSpec.Id.from("default"),
                                                  ZoneId.from("prod", "us-north-1"),
                                                  List.of(new RoutingTable.Real("host42", 4443, 1, true))));
        RoutingTable table1 = new RoutingTable(newEntries, 43);

        // Verification of new table fails enough times to exhaust retries
        tester.processExecuter.withFailCount(10);
        try {
            tester.load(table1);
            fail("Expected exception");
        } catch (Exception ignored) {}
        tester.assertVerifiedConfig(5)
              .assertLoadedConfig(false)
              .assertConfigContents("nginx.conf")
              .assertTemporaryConfigRemoved(false)
              .assertMetric(Nginx.CONFIG_RELOADS_METRIC, 1)
              .assertMetric(Nginx.OK_CONFIG_RELOADS_METRIC, 1);

        // Verification succeeds, with few enough failures
        tester.processExecuter.withFailCount(3);
        tester.load(table1)
              .assertVerifiedConfig(3)
              .assertLoadedConfig(true)
              .assertConfigContents("nginx-updated.conf")
              .assertTemporaryConfigRemoved(true)
              .assertProducedDiff()
              .assertRotatedFiles("nginxl4.conf-2022-01-01-15:00:00.000")
              .assertMetric(Nginx.CONFIG_RELOADS_METRIC, 2)
              .assertMetric(Nginx.OK_CONFIG_RELOADS_METRIC, 2);

        // Some time passes and new tables are loaded. Old rotated files are removed
        tester.clock.advance(Duration.ofDays(3));
        tester.load(table0);
        tester.clock.advance(Duration.ofDays(4).plusSeconds(1));
        tester.load(table1)
              .assertProducedDiff()
              .assertRotatedFiles("nginxl4.conf-2022-01-04-15:00:00.000",
                                  "nginxl4.conf-2022-01-08-15:00:01.000");
        tester.clock.advance(Duration.ofDays(4));
        tester.load(table1) // Same table is loaded again, which is a no-op, but old rotated files are still removed
              .assertRotatedFiles("nginxl4.conf-2022-01-08-15:00:01.000");
    }