@Test(timeout = 20000)
  public void testAmbryServerStartupWithoutDataNodeId() 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");

    VerifiableProperties verifiableProperties = new VerifiableProperties(props);
    AmbryServer ambryServer =
        new AmbryServer(verifiableProperties, spyClusterAgentsFactory, null, new LoggingNotificationSystem(),
            SystemTime.getInstance(), null);
    // Start the server
    Thread serverThread = new Thread(() -> {
      try {
        ambryServer.startup();
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    });
    serverThread.start();
    // check if the thread is alive after waiting for few seconds
    Thread.sleep(3000);
    assertTrue("Thread should be alive", serverThread.isAlive());
    // Spawn a thread that calls the listener after a delay
    new Thread(() -> {
      try {
        Thread.sleep(5000);
        // change the return value of getDataNodeId to return the dataNodeId
        doReturn(dataNodeId).when(spyClusterMap).getDataNodeId(dataNodeId.getHostname(), dataNodeId.getPort());
        spyClusterMap.invokeListenerForDataNodeChange(Collections.singletonList(
            new DataNodeConfig("localhost_1234", "localhost", 1234, "DC1", null, null, null, 0)));
        // wait for some time for startup to finish
        Thread.sleep(5000);
        // check if the thread is alive after waiting for few seconds
        assertFalse("Thread should not be alive", serverThread.isAlive());
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      }
    }).start();
    // Stop the server
    ambryServer.shutdown();
  }
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