Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xtask: generate katana test db #2271

Merged
merged 9 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@

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 @@
);
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"

Check warning on line 148 in bin/sozo/src/commands/clean.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/clean.rs#L148

Added line #L148 was not covered by tests
);

// we expect release profile to be not affected
Expand Down Expand Up @@ -214,7 +216,7 @@
);
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"

Check warning on line 219 in bin/sozo/src/commands/clean.rs

View check run for this annotation

Codecov / codecov/patch

bin/sozo/src/commands/clean.rs#L219

Added line #L219 was not covered by tests
);

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
}
Comment on lines +71 to +104
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New utility function copy_tmp_dir for directory copying.

The copy_tmp_dir function provides a utility for copying directories to a temporary location. This is useful for setting up test environments. Ensure the error handling is robust, as the function currently panics on failure. Consider using Result for error handling to provide more flexibility in managing errors.

pub fn copy_tmp_dir(source_dir: &Utf8PathBuf) -> Result<Utf8PathBuf, io::Error> {
    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())?;

    Ok(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
Loading