'A dataset can be moved from a dead node to a live node.
All attributes, including the maximum size, are preserved.'

@skipIf(True, 'Shutting    down    a    node    invalidates    a    public    IP,    which    breaks    all    kinds    of    things.    So    skip    for    now.')
@require_moving_backend
@run_test_with(async_runner(timeout=timedelta(minutes=6)))
@require_cluster(2)
def test_dataset_move_from_dead_node(self, cluster):

    api = get_backend_api(cluster.cluster_uuid)
    if (not ICloudAPI.providedBy(api)):
        raise SkipTest("Backend    doesn't    support    ICloudAPI;    therefore    it    might    support    moving    from    dead    node    but    as    first    pass    we    assume    it    doesn't.")
    node = list((node for node in cluster.nodes if (node.public_address != cluster.control_node.public_address)))[0]
    other_node = list((other_node for other_node in cluster.nodes if (other_node != node)))[0]
    waiting_for_create = create_dataset(self, cluster, node=node)
    def startup_node(node_id):
        api.start_node(node_id)
        return loop_until(reactor, verify_socket(node.public_address, 22))
    def shutdown(dataset):
        live_node_ids = set(api.list_live_nodes())
        d = node.shutdown()
        d.addCallback((lambda _: loop_until(reactor, (lambda : (set(api.list_live_nodes()) != live_node_ids)))))
        d.addCallback((lambda _: self.addCleanup(startup_node, (live_node_ids - set(api.list_live_nodes())).pop())))
        d.addCallback((lambda _: dataset))
        return d
    waiting_for_shutdown = waiting_for_create.addCallback(shutdown)
    def move_dataset(dataset):
        dataset_moving = cluster.client.move_dataset(UUID(other_node.uuid), dataset.dataset_id)
        moved_dataset = dataset.set(primary=UUID(other_node.uuid))
        dataset_moving.addCallback((lambda dataset: cluster.wait_for_dataset(moved_dataset)))
        return dataset_moving
    waiting_for_shutdown.addCallback(move_dataset)
    return waiting_for_shutdown
