This is an automated email from the ASF dual-hosted git repository.
pjfanning pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko-persistence-r2dbc.git
The following commit(s) were added to refs/heads/main by this push:
new 2603950 Add negative tests for upsert after deleteObject with
revision (#369)
2603950 is described below
commit 2603950c98304e48447a7ae674e7068feff124c7
Author: PJ Fanning <[email protected]>
AuthorDate: Thu May 14 17:33:36 2026 +0100
Add negative tests for upsert after deleteObject with revision (#369)
* Add negative tests for upsert after deleteObject with revision
Agent-Logs-Url:
https://github.com/pjfanning/incubator-pekko-persistence-r2dbc/sessions/e7b60541-a5d0-4608-8313-b253744ad670
Co-authored-by: pjfanning <[email protected]>
* Remove invalid revision=1 insert test after soft delete
Agent-Logs-Url:
https://github.com/pjfanning/incubator-pekko-persistence-r2dbc/sessions/a7b48548-1726-4355-871a-f8f89b8271ef
Co-authored-by: pjfanning <[email protected]>
---------
Co-authored-by: copilot-swe-agent[bot]
<[email protected]>
Co-authored-by: pjfanning <[email protected]>
---
.../r2dbc/state/DurableStateStoreSpec.scala | 52 ++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git
a/core/src/test/scala/org/apache/pekko/persistence/r2dbc/state/DurableStateStoreSpec.scala
b/core/src/test/scala/org/apache/pekko/persistence/r2dbc/state/DurableStateStoreSpec.scala
index 4d12e1b..991edea 100644
---
a/core/src/test/scala/org/apache/pekko/persistence/r2dbc/state/DurableStateStoreSpec.scala
+++
b/core/src/test/scala/org/apache/pekko/persistence/r2dbc/state/DurableStateStoreSpec.scala
@@ -167,6 +167,58 @@ class DurableStateStoreSpec
store.getObject(persistenceId).futureValue should
be(GetObjectResult(None, 5L))
}
+ "upsert with correct revision after delete succeeds" in {
+ val entityType = nextEntityType()
+ val persistenceId = PersistenceId(entityType,
"to-be-deleted-then-re-inserted").id
+ val value1 = "initial value"
+ store.upsertObject(persistenceId, 1L, value1, unusedTag).futureValue
+ store.getObject(persistenceId).futureValue should
be(GetObjectResult(Some(value1), 1L))
+ store.deleteObject(persistenceId, revision = 2L).futureValue
+ store.getObject(persistenceId).futureValue should
be(GetObjectResult(None, 2L))
+
+ val value2 = "new value after delete"
+ store.upsertObject(persistenceId, 3L, value2, unusedTag).futureValue
+ store.getObject(persistenceId).futureValue should
be(GetObjectResult(Some(value2), 3L))
+ }
+
+ "reject upsert with same revision as delete revision" in {
+ if (!stateSettings.durableStateAssertSingleWriter)
+ pending
+
+ val entityType = nextEntityType()
+ val persistenceId = PersistenceId(entityType,
"to-be-deleted-then-bad-update-same-rev").id
+ val value = "initial value"
+ store.upsertObject(persistenceId, 1L, value, unusedTag).futureValue
+ store.getObject(persistenceId).futureValue should
be(GetObjectResult(Some(value), 1L))
+ store.deleteObject(persistenceId, revision = 2L).futureValue
+ store.getObject(persistenceId).futureValue should
be(GetObjectResult(None, 2L))
+
+ // revision=2 is already used by the delete; next valid revision is 3
+ val failure =
+ store.upsertObject(persistenceId, revision = 2L, "wrong value",
unusedTag).failed.futureValue
+ failure.getMessage should include(
+ s"Update failed: durable state for persistence id [$persistenceId]
could not be updated to revision [2]")
+ }
+
+ "reject upsert with skipped revision after delete" in {
+ if (!stateSettings.durableStateAssertSingleWriter)
+ pending
+
+ val entityType = nextEntityType()
+ val persistenceId = PersistenceId(entityType,
"to-be-deleted-then-bad-update-skipped-rev").id
+ val value = "initial value"
+ store.upsertObject(persistenceId, 1L, value, unusedTag).futureValue
+ store.getObject(persistenceId).futureValue should
be(GetObjectResult(Some(value), 1L))
+ store.deleteObject(persistenceId, revision = 2L).futureValue
+ store.getObject(persistenceId).futureValue should
be(GetObjectResult(None, 2L))
+
+ // revision=4 skips revision 3; the correct next revision after delete
at 2 is 3
+ val failure =
+ store.upsertObject(persistenceId, revision = 4L, "wrong value",
unusedTag).failed.futureValue
+ failure.getMessage should include(
+ s"Update failed: durable state for persistence id [$persistenceId]
could not be updated to revision [4]")
+ }
+
"detect and reject concurrent delete of revision 1" in {
val entityType = nextEntityType()
val persistenceId = PersistenceId(entityType,
"id-to-be-deleted-concurrently")
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]