def test_retire_backup(network, args): primary, _ = network.find_primary() backup_to_retire = network.find_any_backup() network.retire_node(primary, backup_to_retire) network.wait_for_node_in_store( primary, backup_to_retire.node_id, node_status=None, timeout=3, ) backup_to_retire.stop() check_can_progress(primary) wait_for_reconfiguration_to_complete(network) return network
def test_learner_catches_up(network, args): primary, _ = network.find_primary() num_nodes_before = 0 with primary.client() as c: s = c.get("/node/consensus") rj = s.body.json() # At this point, there should be exactly one configuration assert len(rj["details"]["configs"]) == 1 c0 = rj["details"]["configs"][0]["nodes"] num_nodes_before = len(c0) new_node = network.create_node("local://localhost") network.join_node(new_node, args.package, args, from_snapshot=False) network.trust_node(new_node, args) with new_node.client() as c: s = c.get("/node/network/nodes/self") rj = s.body.json() assert rj["status"] == "Learner" or rj["status"] == "Trusted" network.wait_for_node_in_store( primary, new_node.node_id, node_status=(ccf.ledger.NodeStatus.TRUSTED), timeout=3, ) with primary.client() as c: s = c.get("/node/consensus") rj = s.body.json() assert len(rj["details"]["learners"]) == 0 # At this point, there should be exactly one configuration, which includes the new node. assert len(rj["details"]["configs"]) == 1 c0 = rj["details"]["configs"][0]["nodes"] assert len(c0) == num_nodes_before + 1 assert new_node.node_id in c0 return network
def test_retire_primary(network, args): pre_count = count_nodes(node_configs(network), network) primary, backup = network.find_primary_and_any_backup() network.retire_node(primary, primary, timeout=15) # Query this backup to find the new primary. If we ask any other # node, then this backup may not know the new primary by the # time we call check_can_progress. new_primary, _ = network.wait_for_new_primary(primary, nodes=[backup]) # The old primary should automatically be removed from the store # once a new primary is elected network.wait_for_node_in_store( new_primary, primary.node_id, node_status=None, timeout=3, ) check_can_progress(backup) post_count = count_nodes(node_configs(network), network) assert pre_count == post_count + 1 primary.stop() wait_for_reconfiguration_to_complete(network) return network
def test_new_service( network, args, install_path, binary_dir, library_dir, version, cycle_existing_nodes=False, ): LOG.info("Update constitution") primary, _ = network.find_primary() new_constitution = get_new_constitution_for_install(args, install_path) network.consortium.set_constitution(primary, new_constitution) all_nodes = network.get_joined_nodes() # Note: Changes to constitution between versions should be tested here LOG.info(f"Add node to new service [cycle nodes: {cycle_existing_nodes}]") nodes_to_cycle = network.get_joined_nodes() if cycle_existing_nodes else [] nodes_to_add_count = len(nodes_to_cycle) if cycle_existing_nodes else 1 # Pre-2.0 nodes require X509 time format valid_from = str(infra.crypto.datetime_to_X509time( datetime.datetime.now())) for _ in range(0, nodes_to_add_count): new_node = network.create_node( "local://localhost", binary_dir=binary_dir, library_dir=library_dir, version=version, ) network.join_node(new_node, args.package, args) network.trust_node( new_node, args, valid_from=valid_from, ) new_node.verify_certificate_validity_period( expected_validity_period_days=DEFAULT_NODE_CERTIFICATE_VALIDITY_DAYS ) all_nodes.append(new_node) for node in nodes_to_cycle: network.retire_node(primary, node) if primary == node: primary, _ = network.wait_for_new_primary(primary) node.stop() test_all_nodes_cert_renewal(network, args, valid_from=valid_from) test_service_cert_renewal(network, args, valid_from=valid_from) LOG.info("Waiting for retired nodes to be automatically removed") for node in all_nodes: network.wait_for_node_in_store( primary, node.node_id, node_status=ccf.ledger.NodeStatus.TRUSTED if node.is_joined() else None, ) if args.check_2tx_reconfig_migration: test_migration_2tx_reconfiguration( network, args, initial_is_1tx=False, # Reconfiguration type added in 2.x binary_dir=binary_dir, library_dir=library_dir, version=version, valid_from=valid_from, ) LOG.info("Apply transactions to new nodes only") issue_activity_on_live_service(network, args) test_random_receipts(network, args, lts=True)