Skip to content

Commit

Permalink
Move tests that don't need a network to a separate file; fix project …
Browse files Browse the repository at this point in the history
…template. (#3293)

## Motivation

`cargo test test_project_new` fails for me locally.

## Proposal

Make sure it is executed in CI.

Fix the project template.

Increase the timeout for `default-features-and-witty-integration-test`,
since it now runs more tests.

## Test Plan

The test is now run in CI. (I tried without the second commit, and it
failed.)

## Release Plan

- Nothing to do / These changes follow the usual release cycle.

## Links

- Maybe related to:
#3217
- [reviewer
checklist](https://github.com/linera-io/linera-protocol/blob/main/CONTRIBUTING.md#reviewer-checklist)
  • Loading branch information
afck authored Feb 11, 2025
1 parent b0cb786 commit 78aa9d8
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 98 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:
default-features-and-witty-integration-test:
runs-on: ubuntu-latest
timeout-minutes: 30
timeout-minutes: 40

steps:
- uses: actions/checkout@v3
Expand Down
4 changes: 3 additions & 1 deletion linera-service/template/service.rs.template
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ impl QueryRoot {{

#[cfg(test)]
mod tests {{
use std::sync::Arc;

use async_graphql::{{Request, Response, Value}};
use futures::FutureExt as _;
use linera_sdk::{{util::BlockingWait, views::View, Service, ServiceRuntime}};
Expand All @@ -74,7 +76,7 @@ mod tests {{
#[test]
fn query() {{
let value = 60u64;
let runtime = ServiceRuntime::<{project_name}Service>::new();
let runtime = Arc::new(ServiceRuntime::<{project_name}Service>::new());
let mut state = {project_name}State::load(runtime.root_view_storage_context())
.blocking_wait()
.expect("Failed to read from mock key value store");
Expand Down
5 changes: 3 additions & 2 deletions linera-service/template/tests/single_chain.rs.template
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#![cfg(not(target_arch = "wasm32"))]

use {project_name}::Operation;
use linera_sdk::test::TestValidator;
use linera_sdk::test::{{QueryOutcome, TestValidator}};

/// Tests setting and incrementing a counter
///
Expand All @@ -31,7 +31,8 @@ async fn single_chain_test() {{
.await;

let final_value = initial_state + increment;
let response = chain.graphql_query(application_id, "query {{ value }}").await;
let QueryOutcome {{ response, .. }} =
chain.graphql_query(application_id, "query {{ value }}").await;
let state_value = response["value"].as_u64().expect("Failed to get the u64");

assert_eq!(state_value, final_value);
Expand Down
26 changes: 22 additions & 4 deletions linera-service/tests/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
// Copyright (c) Zefchain Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use std::sync::LazyLock;
use std::env;

use tokio::sync::Mutex;
/// Restores the `RUSTFLAGS` environment variable to make warnings fail as errors.
pub struct RestoreVarOnDrop;

/// A static lock to prevent integration tests from running in parallel.
pub static INTEGRATION_TEST_GUARD: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
impl Drop for RestoreVarOnDrop {
fn drop(&mut self) {
env::set_var("RUSTFLAGS", "-D warnings");
}
}

/// Clears the `RUSTFLAGS` environment variable, if it was configured to make warnings fail as
/// errors.
///
/// The returned [`RestoreVarOnDrop`] restores the environment variable to its original value when
/// it is dropped.
pub fn override_disable_warnings_as_errors() -> Option<RestoreVarOnDrop> {
if matches!(env::var("RUSTFLAGS"), Ok(value) if value == "-D warnings") {
env::set_var("RUSTFLAGS", "");
Some(RestoreVarOnDrop)
} else {
None
}
}
9 changes: 9 additions & 0 deletions linera-service/tests/guard/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) Zefchain Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use std::sync::LazyLock;

use tokio::sync::Mutex;

/// A static lock to prevent integration tests from running in parallel.
pub static INTEGRATION_TEST_GUARD: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
4 changes: 2 additions & 2 deletions linera-service/tests/linera_net_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
feature = "remote-net"
))]

mod common;
mod guard;

use std::{
env,
Expand All @@ -19,12 +19,12 @@ use std::{

use anyhow::Result;
use async_graphql::InputType;
use common::INTEGRATION_TEST_GUARD;
use futures::{
channel::mpsc,
future::{self, Either},
SinkExt, StreamExt,
};
use guard::INTEGRATION_TEST_GUARD;
use linera_base::{
command::resolve_binary,
crypto::CryptoHash,
Expand Down
64 changes: 64 additions & 0 deletions linera-service/tests/local.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) Zefchain Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use std::{path::PathBuf, process::Command};

use anyhow::Result;
use linera_service::cli_wrappers::{local_net::PathProvider, ClientWrapper, Network, OnClientDrop};

mod common;

#[test_log::test(tokio::test)]
async fn test_project_new() -> Result<()> {
let _rustflags_override = common::override_disable_warnings_as_errors();
let path_provider = PathProvider::create_temporary_directory()?;
let id = 0;
let client = ClientWrapper::new(
path_provider,
Network::Grpc,
None,
id,
OnClientDrop::LeakChains,
);
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let linera_root = manifest_dir
.parent()
.expect("CARGO_MANIFEST_DIR should not be at the root");
let tmp_dir = client.project_new("init-test", linera_root).await?;
let project_dir = tmp_dir.path().join("init-test");
client
.build_application(project_dir.as_path(), "init-test", false)
.await?;

let mut child = Command::new("cargo")
.args(["fmt", "--check"])
.current_dir(project_dir.as_path())
.spawn()?;
assert!(child.wait()?.success());

let mut child = Command::new("cargo")
.arg("test")
.current_dir(project_dir.as_path())
.spawn()?;
assert!(child.wait()?.success());

Ok(())
}

#[test_log::test(tokio::test)]
async fn test_project_test() -> Result<()> {
let path_provider = PathProvider::create_temporary_directory()?;
let id = 0;
let client = ClientWrapper::new(
path_provider,
Network::Grpc,
None,
id,
OnClientDrop::LeakChains,
);
client
.project_test(&ClientWrapper::example_path("counter")?)
.await?;

Ok(())
}
95 changes: 9 additions & 86 deletions linera-service/tests/local_net_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
))]

mod common;
mod guard;

use std::{env, path::PathBuf, process::Command, time::Duration};
use std::{env, path::PathBuf, time::Duration};

use anyhow::Result;
use common::INTEGRATION_TEST_GUARD;
use guard::INTEGRATION_TEST_GUARD;
use linera_base::{
data_types::{Amount, BlockHeight},
identifiers::{Account, AccountOwner, ChainId},
Expand All @@ -22,46 +23,23 @@ use linera_core::{data_types::ChainInfoQuery, node::ValidatorNode};
use linera_faucet::ClaimOutcome;
use linera_service::{
cli_wrappers::{
local_net::{
get_node_port, Database, LocalNet, LocalNetConfig, PathProvider, ProcessInbox,
},
ClientWrapper, FaucetOption, LineraNet, LineraNetConfig, Network, OnClientDrop,
local_net::{get_node_port, Database, LocalNet, LocalNetConfig, ProcessInbox},
ClientWrapper, FaucetOption, LineraNet, LineraNetConfig, Network,
},
test_name,
};
use test_case::test_case;
#[cfg(feature = "storage-service")]
use {linera_base::port::get_free_port, linera_service::cli_wrappers::Faucet};
use {
linera_base::port::get_free_port, linera_service::cli_wrappers::Faucet, std::process::Command,
};

#[cfg(feature = "benchmark")]
fn get_fungible_account_owner(client: &ClientWrapper) -> AccountOwner {
let owner = client.get_owner().unwrap();
AccountOwner::User(owner)
}

/// Clears the `RUSTFLAGS` environment variable, if it was configured to make warnings fail as
/// errors.
///
/// The returned [`RestoreVarOnDrop`] restores the environment variable to its original value when
/// it is dropped.
fn override_disable_warnings_as_errors() -> Option<RestoreVarOnDrop> {
if matches!(env::var("RUSTFLAGS"), Ok(value) if value == "-D warnings") {
env::set_var("RUSTFLAGS", "");
Some(RestoreVarOnDrop)
} else {
None
}
}

/// Restores the `RUSTFLAGS` environment variable to make warnings fail as errors.
struct RestoreVarOnDrop;

impl Drop for RestoreVarOnDrop {
fn drop(&mut self) {
env::set_var("RUSTFLAGS", "-D warnings");
}
}

#[cfg_attr(feature = "scylladb", test_case(LocalNetConfig::new_test(Database::ScyllaDb, Network::Udp) ; "scylladb_udp"))]
#[cfg_attr(feature = "scylladb", test_case(LocalNetConfig::new_test(Database::ScyllaDb, Network::Grpc) ; "scylladb_grpc"))]
#[cfg_attr(feature = "storage-service", test_case(LocalNetConfig::new_test(Database::Service, Network::Grpc) ; "storage_service_grpc"))]
Expand Down Expand Up @@ -567,7 +545,7 @@ async fn test_project_publish(database: Database, network: Network) -> Result<()
let _guard = INTEGRATION_TEST_GUARD.lock().await;
tracing::info!("Starting test {}", test_name!());

let _rustflags_override = override_disable_warnings_as_errors();
let _rustflags_override = common::override_disable_warnings_as_errors();
let config = LocalNetConfig {
num_initial_validators: 1,
num_shards: 1,
Expand Down Expand Up @@ -641,61 +619,6 @@ async fn test_example_publish(database: Database, network: Network) -> Result<()
Ok(())
}

#[test_log::test(tokio::test)]
async fn test_project_new() -> Result<()> {
let _rustflags_override = override_disable_warnings_as_errors();
let path_provider = PathProvider::create_temporary_directory()?;
let id = 0;
let client = ClientWrapper::new(
path_provider,
Network::Grpc,
None,
id,
OnClientDrop::LeakChains,
);
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let linera_root = manifest_dir
.parent()
.expect("CARGO_MANIFEST_DIR should not be at the root");
let tmp_dir = client.project_new("init-test", linera_root).await?;
let project_dir = tmp_dir.path().join("init-test");
client
.build_application(project_dir.as_path(), "init-test", false)
.await?;

let mut child = Command::new("cargo")
.args(["fmt", "--check"])
.current_dir(project_dir.as_path())
.spawn()?;
assert!(child.wait()?.success());

let mut child = Command::new("cargo")
.arg("test")
.current_dir(project_dir.as_path())
.spawn()?;
assert!(child.wait()?.success());

Ok(())
}

#[test_log::test(tokio::test)]
async fn test_project_test() -> Result<()> {
let path_provider = PathProvider::create_temporary_directory()?;
let id = 0;
let client = ClientWrapper::new(
path_provider,
Network::Grpc,
None,
id,
OnClientDrop::LeakChains,
);
client
.project_test(&ClientWrapper::example_path("counter")?)
.await?;

Ok(())
}

/// Test if the wallet file is correctly locked when used.
#[cfg(feature = "storage-service")]
#[test_log::test(tokio::test)]
Expand Down
4 changes: 2 additions & 2 deletions linera-service/tests/readme_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

#![cfg(feature = "storage-service")]

mod common;
mod guard;

use std::{env, path::PathBuf};

use common::INTEGRATION_TEST_GUARD;
use guard::INTEGRATION_TEST_GUARD;
use linera_client::{
client_options::{
DEFAULT_PAUSE_AFTER_GQL_MUTATIONS_SECS, DEFAULT_PAUSE_AFTER_LINERA_SERVICE_SECS,
Expand Down

0 comments on commit 78aa9d8

Please sign in to comment.