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() {
|
||||
return Ok(());
|
||||
}
|
||||
self.validate_metadata()?;
|
||||
self.validate_document()?;
|
||||
let write = self.database.begin_write()?;
|
||||
for mutation in mutations {
|
||||
apply_row_mutation(&write, mutation)?;
|
||||
|
|
@ -305,7 +305,7 @@ impl HostCoordinatorDomainStore {
|
|||
/// Refuses an invalid, foreign, or already-present intent.
|
||||
pub fn begin_state_reset(&self, intent: &StateResetIntentV1) -> Result<(), DomainStoreError> {
|
||||
intent.validate()?;
|
||||
self.validate_metadata()?;
|
||||
self.validate_document()?;
|
||||
let write = self.database.begin_write()?;
|
||||
require_transaction_domain(&write, intent.domain_id)?;
|
||||
{
|
||||
|
|
@ -329,7 +329,7 @@ impl HostCoordinatorDomainStore {
|
|||
expected: &StateResetIntentV1,
|
||||
) -> Result<(), DomainStoreError> {
|
||||
expected.validate()?;
|
||||
self.validate_metadata()?;
|
||||
self.validate_document()?;
|
||||
let write = self.database.begin_write()?;
|
||||
require_transaction_domain(&write, expected.domain_id)?;
|
||||
{
|
||||
|
|
@ -370,6 +370,10 @@ impl HostCoordinatorDomainStore {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_document(&self) -> Result<(), DomainStoreError> {
|
||||
self.snapshot().map(|_| ())
|
||||
}
|
||||
|
||||
fn write_snapshot(&self, snapshot: &DomainStore) -> Result<(), DomainStoreError> {
|
||||
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 {
|
||||
SessionTerminal::snapshot(SessionTerminalFields {
|
||||
generation_id: GenerationId::new(7),
|
||||
|
|
@ -250,8 +261,8 @@ fn row_local_mutations_match_the_snapshot_reference_engine() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn row_local_mutation_does_not_rewrite_an_unrelated_invalid_row() {
|
||||
let directory = TestDirectory::new("unrelated-row");
|
||||
fn row_local_mutation_refuses_an_unrelated_invalid_row() {
|
||||
let directory = TestDirectory::new("invalid-unrelated-row");
|
||||
let store = open_store(&directory);
|
||||
store
|
||||
.apply(&[DomainStoreMutation::PutGeneration(generation(
|
||||
|
|
@ -266,11 +277,10 @@ fn row_local_mutation_does_not_rewrite_an_unrelated_invalid_row() {
|
|||
}
|
||||
write.commit().unwrap();
|
||||
|
||||
store
|
||||
.apply(&[DomainStoreMutation::PutGeneration(generation(
|
||||
let result = store.apply(&[DomainStoreMutation::PutGeneration(generation(
|
||||
DurableDecision::Preparing,
|
||||
))])
|
||||
.unwrap();
|
||||
))]);
|
||||
assert!(matches!(result, Err(DomainStoreError::Codec(_))));
|
||||
|
||||
let read = store.database.begin_read().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(_))));
|
||||
}
|
||||
|
||||
#[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]
|
||||
fn reset_intent_is_typed_transactional_and_domain_bound() {
|
||||
let directory = TestDirectory::new("state-reset");
|
||||
|
|
|
|||
Loading…
Reference in a new issue