Skip to content

Commit

Permalink
xtask: generate katana test db (#2271)
Browse files Browse the repository at this point in the history
* wip

* wip

* fix: revamp testing to use prefilled database

* fix: keep refactoring tests

* fix: fix name of spawn and move db

* fix: fix clippy and fmt

* fix: fix tests

* fix: fix test setup

---------

Co-authored-by: glihm <dev@glihm.net>
  • Loading branch information
kariy and glihm authored Aug 9, 2024
1 parent dc46e9c commit c6a41ac
Show file tree
Hide file tree
Showing 29 changed files with 487 additions and 403 deletions.
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[alias]
generate-test-db = "run --manifest-path ./xtask/generate-test-db/Cargo.toml --"
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ jobs:
name: dojo-bins
path: /tmp/bins
- run: |
tar -xzf spawn-and-move-db.tar.gz -C /tmp/
tar -xzf types-test-db.tar.gz -C /tmp/
chmod +x /tmp/bins/katana
KATANA_RUNNER_BIN=/tmp/bins/katana cargo llvm-cov nextest --no-report --all-features --workspace --exclude katana --build-jobs 20
cargo llvm-cov nextest --no-report -p katana
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ crates/benches/bench_results.txt
.vscode
bindings
justfile
spawn-and-move-db
types-test-db
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ members = [
"crates/torii/server",
"crates/torii/types-test",
"examples/spawn-and-move",
"xtask/generate-test-db",
]

[workspace.package]
Expand Down
1 change: 1 addition & 0 deletions bin/sozo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ notify = "6.0.1"
num-bigint = "0.4.3"
num-integer = "0.1.45"
prettytable-rs = "0.10.0"
regex.workspace = true
rpassword.workspace = true
scarb-ui.workspace = true
scarb.workspace = true
Expand Down
6 changes: 4 additions & 2 deletions bin/sozo/src/commands/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ mod tests {

let temp_project_dir = config.manifest_path().parent().unwrap().to_path_buf();

println!("temp_project_dir: {:?}", temp_project_dir);

let clean_cmd = CleanArgs { full: false, all_profiles: false };
clean_cmd.run(&config).unwrap();

Expand Down Expand Up @@ -143,7 +145,7 @@ mod tests {
);
assert!(
fs::read_dir(&dev_manifests_abis_depl_dir).is_ok(),
"Expected 'manifests/dev/deployment/abis' to not be empty"
"Expected 'manifests/dev/deployment/abis' to be non empty"
);

// we expect release profile to be not affected
Expand Down Expand Up @@ -214,7 +216,7 @@ mod tests {
);
assert!(
fs::read_dir(&dev_manifests_abis_depl_dir).is_ok(),
"Expected 'manifests/dev/deployment/abis' to not be empty"
"Expected 'manifests/dev/deployment/abis' to be empty"
);

assert!(
Expand Down
31 changes: 13 additions & 18 deletions bin/sozo/tests/register_test.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
mod utils;

use camino::Utf8PathBuf;
use dojo_test_utils::compiler::CompilerTestSetup;
use dojo_test_utils::migration::prepare_migration;
use dojo_world::metadata::{dojo_metadata_from_workspace, get_default_namespace_from_ws};
use dojo_world::migration::TxnConfig;
use katana_runner::KatanaRunner;
use dojo_test_utils::migration::{copy_spawn_and_move_db, prepare_migration_with_world_and_seed};
use katana_runner::{KatanaRunner, KatanaRunnerConfig};
use scarb::compiler::Profile;
use scarb::ops;
use sozo_ops::migration::execute_strategy;
use starknet::accounts::Account;
use starknet::core::types::{BlockId, BlockTag};
use utils::snapbox::get_snapbox;
Expand All @@ -19,36 +17,33 @@ async fn reregister_models() {

let ws = ops::read_workspace(config.manifest_path(), &config)
.unwrap_or_else(|op| panic!("Error building workspace: {op:?}"));
let dojo_metadata =
dojo_metadata_from_workspace(&ws).expect("No current package with dojo metadata found.");

let manifest_path = Utf8PathBuf::from(config.manifest_path().parent().unwrap());
let target_path =
ws.target_dir().path_existent().unwrap().join(ws.config().profile().to_string());

let default_namespace = get_default_namespace_from_ws(&ws).unwrap();
let seq_config = KatanaRunnerConfig::default().with_db_dir(copy_spawn_and_move_db().as_str());
let sequencer = KatanaRunner::new_with_config(seq_config).expect("Failed to start runner.");

let migration = prepare_migration(
config.manifest_path().parent().unwrap().into(),
let (strat, _) = prepare_migration_with_world_and_seed(
manifest_path,
target_path,
dojo_metadata.skip_migration,
&default_namespace,
None,
"dojo_examples",
"dojo_examples",
)
.unwrap();

let sequencer = KatanaRunner::new().expect("Failed to start runner.");

let mut account = sequencer.account(0);
account.set_block_id(BlockId::Tag(BlockTag::Pending));

execute_strategy(&ws, &migration, &account, TxnConfig::init_wait()).await.unwrap();
let world_address = &format!("0x{:x}", &migration.world_address);
let world_address = &format!("0x{:x}", &strat.world_address);
let account_address = &format!("0x{:x}", account.address());
let private_key =
&format!("0x{:x}", sequencer.account_data(0).private_key.as_ref().unwrap().secret_scalar());
let rpc_url = &sequencer.url().to_string();

let moves_model =
migration.models.iter().find(|m| m.diff.tag == "dojo_examples-Moves").unwrap();
let moves_model = strat.models.iter().find(|m| m.diff.tag == "dojo_examples-Moves").unwrap();
let moves_model_class_hash = &format!("0x{:x}", moves_model.diff.local_class_hash);
let args_vec = [
"register",
Expand Down
41 changes: 16 additions & 25 deletions bin/sozo/tests/test_migrate.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::fs;

use dojo_test_utils::compiler::CompilerTestSetup;
use katana_runner::KatanaRunner;
use dojo_test_utils::migration::copy_spawn_and_move_db;
use katana_runner::{KatanaRunner, KatanaRunnerConfig};
use scarb::compiler::Profile;
use starknet::accounts::Account;
use starknet::core::types::{BlockId, BlockTag};
Expand Down Expand Up @@ -55,33 +56,14 @@ async fn test_migrate_then_upgrade() {
let config = setup.build_test_config("spawn-and-move", Profile::DEV);
let tmp_dir = config.manifest_path().parent().unwrap();

let sequencer = KatanaRunner::new().expect("Failed to start runner.");
let seq_config = KatanaRunnerConfig::default().with_db_dir(copy_spawn_and_move_db().as_str());
let sequencer = KatanaRunner::new_with_config(seq_config).expect("Failed to start runner.");

let mut account = sequencer.account(0);
account.set_block_id(BlockId::Tag(BlockTag::Pending));

let account_address = &format!("0x{:x}", account.address());
let private_key =
&format!("0x{:x}", sequencer.account_data(0).private_key.as_ref().unwrap().secret_scalar());
let rpc_url = &sequencer.url().to_string();

let args_vec = [
"migrate",
"apply",
"--account-address",
account_address,
"--rpc-url",
rpc_url,
"--private-key",
private_key,
"--manifest-path",
config.manifest_path().as_ref(),
];

get_snapbox().args(args_vec.iter()).assert().success();

println!("tmp_dir: {:?}", tmp_dir);

// Modify the actions contracts to have a new class hash.
let actions_path = tmp_dir.join("src/actions.cairo");
let mut actions_content = fs::read_to_string(&actions_path).unwrap();
Expand All @@ -92,8 +74,17 @@ async fn test_migrate_then_upgrade() {

get_snapbox().args(build_vec.iter()).assert().success();

let assert = get_snapbox().args(args_vec.iter()).assert().success();
let output = format!("{:#?}", assert.get_output());
let plan_args = [
"migrate",
"plan",
"--rpc-url",
rpc_url,
"--manifest-path",
config.manifest_path().as_ref(),
];

let plan_assert = get_snapbox().args(plan_args.iter()).assert().success();
let plan_output = format!("{:#?}", plan_assert.get_output());

assert!(output.contains("Contracts (1)"));
assert!(plan_output.contains("Contracts (1)"));
}
35 changes: 35 additions & 0 deletions crates/dojo-test-utils/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,41 @@ impl CompilerTestSetup {
}
}

/// Copies a directory into a temporary directory.
///
/// # Returns
///
/// A [`Utf8PathBuf`] object pointing to the copied directory.
pub fn copy_tmp_dir(source_dir: &Utf8PathBuf) -> Utf8PathBuf {
let temp_project_dir = Utf8PathBuf::from(
assert_fs::TempDir::new().unwrap().to_path_buf().to_string_lossy().to_string(),
);

fn copy_dir_recursively(src: &PathBuf, dst: &PathBuf) -> io::Result<()> {
if src.is_dir() {
fs::create_dir_all(dst)?;
for entry in fs::read_dir(src)? {
let entry = entry?;
let path = entry.path();
let dst_path = dst.join(path.file_name().unwrap());
if path.is_dir() {
copy_dir_recursively(&path, &dst_path)?;
} else {
fs::copy(&path, &dst_path)?;
}
}
} else {
fs::copy(src, dst)?;
}
Ok(())
}

copy_dir_recursively(&source_dir.to_path_buf().into(), &temp_project_dir.to_path_buf().into())
.unwrap_or_else(|e| panic!("Failed to copy directory: {}", e));

temp_project_dir
}

/// Copies a project into a temporary directory and loads a config from the copied project.
///
/// # Returns
Expand Down
15 changes: 15 additions & 0 deletions crates/dojo-test-utils/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ use starknet::core::types::Felt;
use starknet::core::utils::cairo_short_string_to_felt;
use starknet::macros::felt;

pub const SPAWN_AND_MOVE_TEST_DB_DIR: &str = "/tmp/spawn-and-move-db";
pub const TYPES_TEST_DB_DIR: &str = "/tmp/types-test-db";

/// Copies the spawn and move test database to a temporary directory and returns the path to the
/// temporary directory. Must be used if the test is going to modify the database.
pub fn copy_spawn_and_move_db() -> Utf8PathBuf {
crate::compiler::copy_tmp_dir(&Utf8PathBuf::from(SPAWN_AND_MOVE_TEST_DB_DIR))
}

/// Copies the types test database to a temporary directory and returns the path to the temporary
/// directory. Must be used if the test is going to modify the database.
pub fn copy_types_test_db() -> Utf8PathBuf {
crate::compiler::copy_tmp_dir(&Utf8PathBuf::from(TYPES_TEST_DB_DIR))
}

pub fn prepare_migration(
manifest_dir: Utf8PathBuf,
target_dir: Utf8PathBuf,
Expand Down
34 changes: 15 additions & 19 deletions crates/dojo-world/src/contracts/model_test.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
use camino::Utf8PathBuf;
use dojo_test_utils::compiler::CompilerTestSetup;
use dojo_test_utils::migration::{copy_spawn_and_move_db, prepare_migration_with_world_and_seed};
use dojo_types::primitive::Primitive;
use dojo_types::schema::{Enum, EnumOption, Member, Struct, Ty};
use katana_runner::KatanaRunner;
use katana_runner::{KatanaRunner, KatanaRunnerConfig};
use scarb::compiler::Profile;
use starknet::accounts::ConnectedAccount;
use starknet::macros::felt;

use crate::contracts::model::ModelReader;
use crate::contracts::world::test::deploy_world;
use crate::contracts::world::WorldContractReader;
use crate::metadata::dojo_metadata_from_workspace;

#[tokio::test(flavor = "multi_thread")]
async fn test_model() {
let runner = KatanaRunner::new().expect("Fail to set runner");
let account = runner.account(0);
let seq_config = KatanaRunnerConfig::default().with_db_dir(copy_spawn_and_move_db().as_str());
let sequencer = KatanaRunner::new_with_config(seq_config).expect("Failed to start runner.");

let account = sequencer.account(0);
let provider = account.provider();

let setup = CompilerTestSetup::from_examples("../dojo-core", "../../examples/");
Expand All @@ -23,22 +25,16 @@ async fn test_model() {
let manifest_dir = config.manifest_path().parent().unwrap();
let target_dir = manifest_dir.join("target").join("dev");

let ws = scarb::ops::read_workspace(config.manifest_path(), &config).unwrap();
let dojo_metadata =
dojo_metadata_from_workspace(&ws).expect("No current package with dojo metadata found.");

let default_namespace = ws.current_package().unwrap().id.name.to_string();

let world_address = deploy_world(
&runner,
&manifest_dir.into(),
&target_dir,
dojo_metadata.skip_migration,
&default_namespace,
let (strat, _) = prepare_migration_with_world_and_seed(
Utf8PathBuf::from(&manifest_dir),
Utf8PathBuf::from(&target_dir),
None,
"dojo_examples",
"dojo_examples",
)
.await;
.unwrap();

let world = WorldContractReader::new(world_address, provider);
let world = WorldContractReader::new(strat.world_address, provider);
let position = world.model_reader("dojo_examples", "Position").await.unwrap();
let schema = position.schema().await.unwrap();

Expand Down
Loading

0 comments on commit c6a41ac

Please sign in to comment.