editEdit on GitHub

Sandbox Testing

Sandbox is a package that simulates the rest of the network for a node. The sandbox is used to test services, the consensus algorithm, and service endpoints.

Using sandbox one can send a message to the node and expect some response from it which is then checked against the reference response. The sandbox can be used to test the consensus algorithm (by sending consensus messages to the node and verifying its response) and the operation of the services (by committing transactions to the blockchain and verifying the service response). Similarly, tests of the public REST API can be performed.

Sandbox Interface

A sandbox instance can be created with sandbox_with_services method, which allows to specify a list of services for testing.

Sandbox provides network emulation capabilities:

  • recv
    Simulates receiving a message by the node.

  • send
    Checks if a message has been sent by the node.

  • broadcast
    Checks if the node has broadcasted the message of a particular content (e.g. a transaction).

Sandbox also allows to emulate block acceptance and time:

  • add_time
    Emulates the situation upon expiration of the specified time period (as a std::time::Durationstruct). Is used for timeouts testing.

  • add_one_height_with_transactions
    Allows committing a transaction.

Finally, sandbox provides utility methods:

  • a
    Gets socket address of the validator with the specified number.

  • p
    Gets public key of the validator with the specified number.

  • s
    Gets private key of the validator with the specified number.

Consensus Algorithm Testing

Testing the consensus algorithm implies checking compliance of the node behavior with the algorithm specification. The following components of the consensus algorithm are tested:

Tip

See source code for more details on how sandbox is used for testing the consensus algorithm.

Note

The validator numbers correspond to the validator keys in the validators list specified in the global configuration.

The example below shows how sandbox could be used to check Connect message exchange.

#[test]
fn test_sandbox_recv_and_send() {
    let s = sandbox_with_services(vec![Box::new(ConfigUpdateService::new())]);
    let (public, secret) = gen_keypair();

    // Simulate receiving "Connect" message by the node
    s.recv(Connect::new(&public, s.a(2), s.time(), &secret));

    // Check if the node has sent the "Connect" message
    s.send(s.a(2), Connect::new(&s.p(0), s.a(0), s.time(), s.s(0)));
}

Service Testing

To test a certain set of the services, one should pass the services list to the sandbox constructor:

let s = sandbox_with_services(vec![Box::new(TimestampingService::new()),
                                   Box::new(ConfigUpdateService::new())]);

A service should be tested by committing the service transaction and observing subsequent changes in the blockchain and the storage state.

Note

Transaction constructors are service-specific.

Tip

See source code for more details on how sandbox is used for testing the configuration update service and the anchoring service.

Service Endpoints Testing

Note

Each service should provide its own interface for sandbox testing of the service endpoints.

The example below shows how sandbox could be used to check actual_config endpoint of the configuration update service.

#[test]
fn test_get_actual_config() {
    let _ = init_logger();

    // Create sandbox for testing configuration update service endpoints
    let api_sandbox = ConfigurationApiSandbox::new();

    // Read current configuration
    let sand_cfg = api_sandbox.sandbox.cfg();
    let expected_body = ApiResponseConfigHashInfo {
        hash: sand_cfg.hash(),
        config: sand_cfg,
    };

    // Read current configuration via REST API
    let resp_actual_config = api_sandbox.get_actual_config().unwrap();
    let actual_body = response_body(resp_actual_config);

    // Compare current configuration with GET response
    assert_eq!(actual_body, serde_json::to_value(expected_body).unwrap());
}

Tip

See source code for more details on how sandbox is used for testing the configuration update service endpoints.