Files
SpacetimeDB/crates/cli/tests/publish.rs
Tyler Cloutier 46f3e07dfc Fixes issues with --delete-data=on-conflict (#3730)
# Description of Changes

Fixes https://github.com/clockworklabs/SpacetimeDB/issues/3729

I genuinely don't know what came over me.

# API and ABI breaking changes

None

# Expected complexity level and risk

1.5 very straightforward but not strictly trivial

# Testing
Adds automated integration tests (written in Rust and run with `cargo
test`, although note this comment from @matklad about integration tests
for the future
https://internals.rust-lang.org/t/running-test-crates-in-parallel/15639/2):

- [x] Can publish an updated module if no migration is required
- [x] Can publish an updated module if auto-migration is required (with
the yes-break flag true/false)
- [x] Cannot publish if a manual migration is required
- [x] Can publish if a manual migration is required but the user
specified `--delete-data`
- [x] Can publish if a manual migration is required by the user
specified `--delete-data=on-conflict`
- [x] No data deletion occurs if no migration is required and
`--delete-data=on-conflict` is specified

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Phoebe Goldman <phoebe@clockworklabs.io>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
2025-12-04 21:45:41 +00:00

179 lines
5.2 KiB
Rust

mod util;
use crate::util::SpacetimeDbGuard;
use assert_cmd::cargo::cargo_bin_cmd;
#[test]
fn cli_can_publish_spacetimedb_on_disk() {
let spacetime = SpacetimeDbGuard::spawn_in_temp_data_dir();
// Workspace root for `cargo run -p ...`
let workspace_dir = cargo_metadata::MetadataCommand::new().exec().unwrap().workspace_root;
// dir = <workspace_root>/modules/quickstart-chat
let dir = workspace_dir.join("modules").join("quickstart-chat");
let mut cmd = cargo_bin_cmd!("spacetimedb-cli");
cmd.args(["publish", "--server", &spacetime.host_url.to_string(), "foobar"])
.current_dir(dir.clone())
.assert()
.success();
// Can republish without error to the same name
let mut cmd = cargo_bin_cmd!("spacetimedb-cli");
cmd.args(["publish", "--server", &spacetime.host_url.to_string(), "foobar"])
.current_dir(dir)
.assert()
.success();
}
// TODO: Somewhere we should test that data is actually deleted properly in all the expected cases,
// e.g. when providing --delete-data, or when there's a conflict and --delete-data=on-conflict is provided.
fn migration_test(module_name: &str, republish_args: &[&str], expect_success: bool) {
let spacetime = SpacetimeDbGuard::spawn_in_temp_data_dir();
let workspace_dir = cargo_metadata::MetadataCommand::new().exec().unwrap().workspace_root;
let dir = workspace_dir.join("modules").join("module-test");
let mut cmd = cargo_bin_cmd!("spacetimedb-cli");
cmd.args(["publish", module_name, "--server", &spacetime.host_url.to_string()])
.current_dir(dir.clone())
.assert()
.success();
let mut cmd = cargo_bin_cmd!("spacetimedb-cli");
cmd.args(["publish", module_name, "--server", &spacetime.host_url.to_string()])
.args(republish_args)
.current_dir(dir);
if expect_success {
cmd.assert().success();
} else {
cmd.assert().failure();
}
}
#[test]
fn cli_can_publish_no_conflict_does_not_delete_data() {
migration_test(
"no-conflict-test",
&[
// NOTE: deleting data requires --yes,
// so not providing it here ensures that no data deletion is attempted.
"--delete-data=on-conflict",
],
true,
);
}
#[test]
fn cli_can_publish_no_conflict_with_delete_data_flag() {
migration_test("no-conflict-delete-data-test", &["--delete-data", "--yes"], true);
}
#[test]
fn cli_can_publish_no_conflict_without_delete_data_flag() {
migration_test("no-conflict-test", &[], true);
}
#[test]
fn cli_can_publish_with_automigration_change() {
migration_test(
"automigration-test",
&["--build-options=--features test-add-column", "--break-clients"],
true,
);
}
#[test]
fn cli_cannot_publish_automigration_change_without_yes_break_clients() {
migration_test(
"automigration-test-no-break-flag",
&["--build-options=--features test-add-column"],
false,
);
}
#[test]
fn cli_can_publish_automigration_change_with_on_conflict_and_yes_break_clients() {
migration_test(
"automigration-on-conflict-test",
&[
"--build-options=--features test-add-column",
// NOTE: deleting data requires --yes,
// so not providing it here ensures that no data deletion is attempted.
"--delete-data=on-conflict",
"--break-clients",
],
true,
);
}
#[test]
fn cli_cannot_publish_automigration_change_with_on_conflict_without_yes_break_clients() {
migration_test(
"automigration-on-conflict-no-break-flag-test",
&[
"--build-options=--features test-add-column",
// NOTE: deleting data requires --yes,
// so not providing it here ensures that no data deletion is attempted.
"--delete-data=on-conflict",
],
false,
);
}
#[test]
fn cli_can_publish_automigration_change_with_delete_data_always_without_yes_break_clients() {
migration_test(
"automigration-delete-data-test",
&["--build-options=--features test-add-column", "--delete-data", "--yes"],
true,
);
}
#[test]
fn cli_can_publish_automigration_change_with_delete_data_always_and_yes_break_clients() {
migration_test(
"automigration-delete-data-break-test",
&[
"--build-options=--features test-add-column",
"--delete-data",
"--yes",
"--break-clients",
],
true,
);
}
#[test]
fn cli_cannot_publish_breaking_change_without_flag() {
migration_test(
"breaking-change-test",
&["--build-options=--features test-remove-table"],
false,
);
}
#[test]
fn cli_can_publish_breaking_change_with_delete_data_flag() {
migration_test(
"breaking-change-delete-data-test",
&["--build-options=--features test-remove-table", "--delete-data", "--yes"],
true,
);
}
#[test]
fn cli_can_publish_breaking_change_with_on_conflict_flag() {
migration_test(
"breaking-change-on-conflict-test",
&[
"--build-options=--features test-remove-table",
"--delete-data=on-conflict",
"--yes",
],
true,
);
}