@Test(timeout = 15000)
  public void testAmbryServerStartupWithoutDataNodeIdTimeoutCase() throws Exception {
    ClusterAgentsFactory spyClusterAgentsFactory = spy(new MockClusterAgentsFactory(false, false, 1, 1, 1));
    // Mock ClusterMap
    DataNodeId dataNodeId = spyClusterAgentsFactory.getClusterMap().getDataNodeIds().get(0);
    MockClusterMap spyClusterMap = spy(new MockClusterMap(false, false, 1, 1, 1, false, false, null));
    doReturn(null).when(spyClusterMap).getDataNodeId(dataNodeId.getHostname(), dataNodeId.getPort());
    doReturn(spyClusterMap).when(spyClusterAgentsFactory).getClusterMap();

    // Set up properties
    Properties props = new Properties();
    props.setProperty("host.name", dataNodeId.getHostname());
    props.setProperty("port", Integer.toString(dataNodeId.getPort()));
    props.setProperty("clustermap.cluster.name", "test");
    props.setProperty("clustermap.datacenter.name", "DC1");
    props.setProperty("clustermap.host.name", "localhost");
    props.setProperty("clustermap.port", "1234");
    // timeout for dataNode config latch await in 5 seconds
    props.setProperty("server.datanode.config.timeout", "5");

    VerifiableProperties verifiableProperties = new VerifiableProperties(props);
    // Start the server
    AmbryServer ambryServer =
        new AmbryServer(verifiableProperties, spyClusterAgentsFactory, null, new LoggingNotificationSystem(),
            SystemTime.getInstance(), null);
    assertException(InstantiationException.class, ambryServer::startup, e -> {
      assertEquals("Unexpected exception thrown", e.getMessage(),
          "failure during startup java.lang.IllegalArgumentException: Startup timed out waiting for data node config to be populated");
    });
  }
Test starting and shutting down the server with a custom {@link JmxReporter} factory.
@throws Exception
ambry-server/src/test/java/com/github/ambry/server/AmbryServerTest.java