Fail closed before Domain Store mutations
This commit is contained in:
parent
2f8a9f9178
commit
bfe21dfb3f
2 changed files with 45 additions and 10 deletions
|
|
@ -266,7 +266,7 @@ impl HostCoordinatorDomainStore {
|
||||||
if mutations.is_empty() {
|
if mutations.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
self.validate_metadata()?;
|
self.validate_document()?;
|
||||||
let write = self.database.begin_write()?;
|
let write = self.database.begin_write()?;
|
||||||
for mutation in mutations {
|
for mutation in mutations {
|
||||||
apply_row_mutation(&write, mutation)?;
|
apply_row_mutation(&write, mutation)?;
|
||||||
|
|
@ -305,7 +305,7 @@ impl HostCoordinatorDomainStore {
|
||||||
/// Refuses an invalid, foreign, or already-present intent.
|
/// Refuses an invalid, foreign, or already-present intent.
|
||||||
pub fn begin_state_reset(&self, intent: &StateResetIntentV1) -> Result<(), DomainStoreError> {
|
pub fn begin_state_reset(&self, intent: &StateResetIntentV1) -> Result<(), DomainStoreError> {
|
||||||
intent.validate()?;
|
intent.validate()?;
|
||||||
self.validate_metadata()?;
|
self.validate_document()?;
|
||||||
let write = self.database.begin_write()?;
|
let write = self.database.begin_write()?;
|
||||||
require_transaction_domain(&write, intent.domain_id)?;
|
require_transaction_domain(&write, intent.domain_id)?;
|
||||||
{
|
{
|
||||||
|
|
@ -329,7 +329,7 @@ impl HostCoordinatorDomainStore {
|
||||||
expected: &StateResetIntentV1,
|
expected: &StateResetIntentV1,
|
||||||
) -> Result<(), DomainStoreError> {
|
) -> Result<(), DomainStoreError> {
|
||||||
expected.validate()?;
|
expected.validate()?;
|
||||||
self.validate_metadata()?;
|
self.validate_document()?;
|
||||||
let write = self.database.begin_write()?;
|
let write = self.database.begin_write()?;
|
||||||
require_transaction_domain(&write, expected.domain_id)?;
|
require_transaction_domain(&write, expected.domain_id)?;
|
||||||
{
|
{
|
||||||
|
|
@ -370,6 +370,10 @@ impl HostCoordinatorDomainStore {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validate_document(&self) -> Result<(), DomainStoreError> {
|
||||||
|
self.snapshot().map(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
fn write_snapshot(&self, snapshot: &DomainStore) -> Result<(), DomainStoreError> {
|
fn write_snapshot(&self, snapshot: &DomainStore) -> Result<(), DomainStoreError> {
|
||||||
let write = self.database.begin_write()?;
|
let write = self.database.begin_write()?;
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,17 @@ fn mailbox(state: ParticipantState) -> Mailbox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mailbox_row_bytes(store: &HostCoordinatorDomainStore) -> Vec<u8> {
|
||||||
|
let read = store.database.begin_read().unwrap();
|
||||||
|
let table = read.open_table(MAILBOXES).unwrap();
|
||||||
|
table
|
||||||
|
.get(generation(DurableDecision::None).generation_id.get())
|
||||||
|
.unwrap()
|
||||||
|
.unwrap()
|
||||||
|
.value()
|
||||||
|
.to_vec()
|
||||||
|
}
|
||||||
|
|
||||||
fn bare_terminal(state: SessionTerminalState) -> SessionTerminal {
|
fn bare_terminal(state: SessionTerminalState) -> SessionTerminal {
|
||||||
SessionTerminal::snapshot(SessionTerminalFields {
|
SessionTerminal::snapshot(SessionTerminalFields {
|
||||||
generation_id: GenerationId::new(7),
|
generation_id: GenerationId::new(7),
|
||||||
|
|
@ -250,8 +261,8 @@ fn row_local_mutations_match_the_snapshot_reference_engine() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn row_local_mutation_does_not_rewrite_an_unrelated_invalid_row() {
|
fn row_local_mutation_refuses_an_unrelated_invalid_row() {
|
||||||
let directory = TestDirectory::new("unrelated-row");
|
let directory = TestDirectory::new("invalid-unrelated-row");
|
||||||
let store = open_store(&directory);
|
let store = open_store(&directory);
|
||||||
store
|
store
|
||||||
.apply(&[DomainStoreMutation::PutGeneration(generation(
|
.apply(&[DomainStoreMutation::PutGeneration(generation(
|
||||||
|
|
@ -266,11 +277,10 @@ fn row_local_mutation_does_not_rewrite_an_unrelated_invalid_row() {
|
||||||
}
|
}
|
||||||
write.commit().unwrap();
|
write.commit().unwrap();
|
||||||
|
|
||||||
store
|
let result = store.apply(&[DomainStoreMutation::PutGeneration(generation(
|
||||||
.apply(&[DomainStoreMutation::PutGeneration(generation(
|
DurableDecision::Preparing,
|
||||||
DurableDecision::Preparing,
|
))]);
|
||||||
))])
|
assert!(matches!(result, Err(DomainStoreError::Codec(_))));
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let read = store.database.begin_read().unwrap();
|
let read = store.database.begin_read().unwrap();
|
||||||
let table = read.open_table(MAILBOXES).unwrap();
|
let table = read.open_table(MAILBOXES).unwrap();
|
||||||
|
|
@ -280,6 +290,27 @@ fn row_local_mutation_does_not_rewrite_an_unrelated_invalid_row() {
|
||||||
assert!(matches!(store.snapshot(), Err(DomainStoreError::Codec(_))));
|
assert!(matches!(store.snapshot(), Err(DomainStoreError::Codec(_))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn row_local_mutation_preserves_an_unrelated_valid_row_byte_for_byte() {
|
||||||
|
let directory = TestDirectory::new("valid-unrelated-row");
|
||||||
|
let store = open_store(&directory);
|
||||||
|
store
|
||||||
|
.apply(&[
|
||||||
|
DomainStoreMutation::PutGeneration(generation(DurableDecision::None)),
|
||||||
|
DomainStoreMutation::PutMailbox(mailbox(ParticipantState::Intent)),
|
||||||
|
])
|
||||||
|
.unwrap();
|
||||||
|
let before = mailbox_row_bytes(&store);
|
||||||
|
|
||||||
|
store
|
||||||
|
.apply(&[DomainStoreMutation::PutGeneration(generation(
|
||||||
|
DurableDecision::Preparing,
|
||||||
|
))])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(mailbox_row_bytes(&store), before);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reset_intent_is_typed_transactional_and_domain_bound() {
|
fn reset_intent_is_typed_transactional_and_domain_bound() {
|
||||||
let directory = TestDirectory::new("state-reset");
|
let directory = TestDirectory::new("state-reset");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue