From fb57eb7abbce3bdb7565033bd29de23d9ee8763f Mon Sep 17 00:00:00 2001 From: John Detter <4099508+jdetter@users.noreply.github.com> Date: Sat, 1 Jul 2023 02:27:41 -0500 Subject: [PATCH] Enable restart tests (#35) * Fixes the restart problem (i.e. rebuilding the datastore from the message log) * Remove logging * Enable restart tests * Fixed small issues with tests * Fixed restart-repeating-reducer test probably --------- Co-authored-by: Tyler Cloutier Co-authored-by: Boppy --- .github/workflows/ci.yml | 2 +- .../core/src/db/datastore/locking_tx_datastore/mod.rs | 8 ++++++-- crates/core/src/host/host_controller.rs | 10 ++++++++++ test/run-smoke-tests.sh | 2 +- test/tests/autoinc2.sh | 8 +++++--- test/tests/zz_docker-restart-repeating-reducer.sh | 7 ++++++- 6 files changed, 29 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ef4e063e7eb..76cd6a08643 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: - name: Start containers run: docker compose up -d - name: Run smoketests - run: test/run-smoke-tests.sh -x bitcraftmini-pretest zz_docker-restart-repeating-reducer zz_docker-restart-module zz_docker-restart-sql + run: test/run-smoke-tests.sh -x bitcraftmini-pretest - name: Stop containers if: always() run: docker compose down diff --git a/crates/core/src/db/datastore/locking_tx_datastore/mod.rs b/crates/core/src/db/datastore/locking_tx_datastore/mod.rs index cbf516a184a..482845a3d8b 100644 --- a/crates/core/src/db/datastore/locking_tx_datastore/mod.rs +++ b/crates/core/src/db/datastore/locking_tx_datastore/mod.rs @@ -1327,8 +1327,12 @@ impl Inner { col_id: &ColId, value: &'a AlgebraicValue, ) -> super::Result { - let tx_state = self.tx_state.as_ref().unwrap(); - if let Some(inserted_rows) = tx_state.index_seek(table_id, col_id, value) { + if let Some(inserted_rows) = self + .tx_state + .as_ref() + .and_then(|tx_state| tx_state.index_seek(table_id, col_id, value)) + { + let tx_state = self.tx_state.as_ref().unwrap(); Ok(IterByColEq::Index(IndexIterByColEq { value, col_id: *col_id, diff --git a/crates/core/src/host/host_controller.rs b/crates/core/src/host/host_controller.rs index 38b743bc8d4..536fbddadd6 100644 --- a/crates/core/src/host/host_controller.rs +++ b/crates/core/src/host/host_controller.rs @@ -175,6 +175,16 @@ impl HostController { Ok(module_host) } + /// NOTE: Currently repeating reducers are only restarted when the [ModuleHost] is spawned. + /// That means that if SpacetimeDB is restarted, repeating reducers will not be restarted unless + /// there is a trigger that causes the [ModuleHost] to be spawned (e.g. a reducer is run). + /// + /// TODO(cloutiertyler): We need to determine what the correct behavior should be. In my mind, + /// the repeating reducers for all [ModuleHost]s should be rescheduled on startup, with the overarching + /// theory that SpacetimeDB should make a best effort to be as invisible as possible and not + /// impact the logic of applications. The idea being that if SpacetimeDB is a distributed operating + /// system, the applications will expect to be called when they are scheduled to be called regardless + /// of whether the OS has been restarted. pub async fn spawn_module_host(&self, module_host_context: ModuleHostContext) -> Result { let key = module_host_context.dbic.database_instance_id; diff --git a/test/run-smoke-tests.sh b/test/run-smoke-tests.sh index c531cf004ae..07edac5348a 100755 --- a/test/run-smoke-tests.sh +++ b/test/run-smoke-tests.sh @@ -17,7 +17,7 @@ export PROJECT_PATH export SPACETIME_DIR="$PWD/.." export SPACETIME_SKIP_CLIPPY=1 -CONTAINER_NAME=$(docker ps | grep node | awk '{print $NF}') +CONTAINER_NAME=$(docker ps | grep "\-node-" | awk '{print $NF}') docker logs "$CONTAINER_NAME" rustup update diff --git a/test/tests/autoinc2.sh b/test/tests/autoinc2.sh index 2b185bf72d3..353f03db518 100644 --- a/test/tests/autoinc2.sh +++ b/test/tests/autoinc2.sh @@ -14,6 +14,7 @@ do_test() { create_project cat > "${PROJECT_PATH}/src/lib.rs" << EOF +use std::error::Error; use spacetimedb::{println, spacetimedb}; #[spacetimedb(table)] @@ -26,15 +27,16 @@ pub struct Person { } #[spacetimedb(reducer)] -pub fn add_new(name: String) { - let value = Person::insert(Person { key_col: 0, name }).unwrap(); +pub fn add_new(name: String) -> Result<(), Box> { + let value = Person::insert(Person { key_col: 0, name })?; println!("Assigned Value: {} -> {}", value.key_col, value.name); + Ok(()) } #[spacetimedb(reducer)] pub fn update(name: String, new_id: REPLACE_VALUE) { Person::delete_by_name(&name); - let value = Person::insert(Person { key_col: new_id, name }); + let _value = Person::insert(Person { key_col: new_id, name }); } #[spacetimedb(reducer)] diff --git a/test/tests/zz_docker-restart-repeating-reducer.sh b/test/tests/zz_docker-restart-repeating-reducer.sh index a810ff5970c..7aded4da94b 100644 --- a/test/tests/zz_docker-restart-repeating-reducer.sh +++ b/test/tests/zz_docker-restart-repeating-reducer.sh @@ -23,18 +23,23 @@ fn init() { pub fn my_repeating_reducer(prev: Timestamp) { println!("Invoked: ts={:?}, delta={:?}", Timestamp::now(), prev.elapsed()); } + +#[spacetimedb(reducer)] +pub fn dummy() {} EOF run_test cargo run publish -s -d --project-path "$PROJECT_PATH" --clear-database [ "1" == "$(grep -c "reated new database" "$TEST_OUT")" ] IDENT="$(grep "reated new database" "$TEST_OUT" | awk 'NF>1{print $NF}')" -CONTAINER_NAME=$(docker ps | grep node | awk '{print $NF}') +CONTAINER_NAME=$(docker ps | grep "\-node-" | awk '{print $NF}') run_test docker kill $CONTAINER_NAME run_test cargo build -p spacetimedb-standalone --release run_test docker-compose start node sleep 10 +run_test cargo run call "$IDENT" dummy +sleep 4 run_test cargo run logs "$IDENT" LINES="$(grep -c "Invoked" "$TEST_OUT")"