@Test
    void timer_events_during_cluster_down_observe_most_recent_node_changes() throws Exception {
        FleetControllerOptions.Builder options = defaultOptions();
        options.setMaxTransitionTime(NodeType.STORAGE, 1000);
        options.setMinStorageNodesUp(10);
        options.setMinDistributorNodesUp(10);
        initialize(options);

        ctrl.tick();
        communicator.setNodeState(new Node(NodeType.STORAGE, 2), State.DOWN, "foo");
        timer.advanceTime(500);
        ctrl.tick();
        communicator.setNodeState(new Node(NodeType.STORAGE, 3), State.DOWN, "foo");
        ctrl.tick();
        assertThat(ctrl.consolidatedClusterState().toString(), equalTo("version:3 cluster:d distributor:10 storage:10 .2.s:m .3.s:m"));

        // Subsequent timer tick should _not_ trigger additional events. Providing published state
        // only would result in "Marking node down" events for node 2 emitted per tick.
        for (int i = 0; i < 3; ++i) {
            timer.advanceTime(5000);
            ctrl.tick();
        }

        verifyNodeEvents(new Node(NodeType.STORAGE, 2),
                         """
                                 Event: storage.2: Now reporting state U
                                 Event: storage.2: Altered node state in cluster state from 'D' to 'U'
                                 Event: storage.2: Failed to get node state: D: foo
                                 Event: storage.2: Stopped or possibly crashed after 500 ms, which is before stable state time period. Premature crash count is now 1.
                                 Event: storage.2: Altered node state in cluster state from 'U' to 'M: foo'
                                 """);
        // Note: even though max transition time has passed, events are now emitted only on cluster state
        // publish edges. These are currently suppressed when the cluster state is down, as all cluster down
        // states are considered similar to other cluster down states. This is not necessarily optimal, but
        // if the cluster is down there are bigger problems than not having some debug events logged.
    }
Class for testing states of all nodes. Will fail in constructor with
debug message on non-expected results.
clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateChangeTest.java