Skip to content

Add API for injecting 'repetitions' into saga executor#88

Merged
smklein merged 7 commits into
mainfrom
inject-repetition
Dec 28, 2022
Merged

Add API for injecting 'repetitions' into saga executor#88
smklein merged 7 commits into
mainfrom
inject-repetition

Conversation

@smklein

@smklein smklein commented Dec 26, 2022

Copy link
Copy Markdown
Contributor

Provides a simple API for instructing a node to "execute twice".

This provides a "bare-minimum" helper API for testing idempotency within a saga. When combined with #67 - which was used to test unwind safety - it should be possible to test that all actions / undo actions within a saga are idempotent, at least across being called twice.

Part of #31

@andrewjstone andrewjstone left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me and will be very helpful for testing! I like that you re-used the error injection pathway :)

Comment thread src/sec.rs Outdated
//
// This helper intends to reduce some of that boilerplate.
async fn saga_runner_helper(
repeat: Option<(NodeIndex, RepeatInjected)>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the tests using the helper somewhat hard to read. The repeat and fail parameters are tagged with comments and it's not immediately clear what the counts represent. What if instead we passed a struct to the saga runner helper so we could have named parameters? This would obviate the need for comments and on top of that give us a way to tie the counts to the named parameters. We could optionally add names to the counts by separating them into node_redos and node_undos in the struct.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 2c281c8

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And also cbd43ff

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @smklein. While, verbose, I think it makes the individual tests easier to read!

Comment thread src/sec.rs Outdated

#[derive(Debug, Copy, Clone)]
pub enum RepeatInjected {
Action,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if there would be any value in adding counts the values here to allow repeating more than once. While it shouldn't matter, it may be possible that executing Action, say 2 times, and Undo 3 times has a perverse effect.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in d9a4de1 ; this forced the input parameters to change a bit, since I didn't want the caller to need to call for the "action" and "undo" counts separately (which would introduce contention on the node-as-key implementation).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@smklein smklein enabled auto-merge (squash) December 28, 2022 00:04
@smklein smklein merged commit 53129dd into main Dec 28, 2022
@smklein smklein deleted the inject-repetition branch December 28, 2022 00:06
smklein added a commit to oxidecomputer/omicron that referenced this pull request Dec 29, 2022
- Makes use of oxidecomputer/steno#88 to test
idempotency of instance creation actions + undo actions
- Fixes all the ways in which it was *not* idempotent, including...
- (Action) Inserting the same network interface failed with a VPC subnet
error, instead of an "already exists" error.
- (Action) Inserting the instance record twice fell victim to
#1168
- (Undo) Deleting the instance record failed to execute twice, as it
could not find the instance record for the second invocation.

Part of #2094
smklein added a commit to oxidecomputer/omicron that referenced this pull request Dec 29, 2022
- Makes use of oxidecomputer/steno#88 to test
idempotency of instance deletion actions
- Fixes the way in which it was not idempotent: deleting the instance
record

Part of #2094
@davepacheco

Copy link
Copy Markdown
Collaborator

Neat! This looks great.

What happens with the saga log when an action is repeated? I think you want only the log entries from one of the repetitions in the log -- otherwise it seems like not a valid log. It'd be great to get coverage for this in the demo example like we have for injecting errors. I think this should be pretty easy, adding a block like this one:

for node_name in &args.inject_error {
let node_id = dag.get_index(node_name).with_context(|| {
format!("bad argument for --inject-error: {:?}", node_name)
})?;
sec.saga_inject_error(saga_id, node_id)
.await
.context("injecting error")?;
if !args.quiet {
println!("will inject error at node \"{}\"", node_name);
}
}

It should be easy to add a test too like this one:

#[test]
fn cmd_run_error() {
assert_contents(
"tests/test_smoke_run_error.out",
&run_example("run_error", |exec| {
exec.arg("run").arg("--inject-error=instance_boot")
}),
);
}

and you could make sure recovery works after using it with something like this:
fn cmd_run_recover_unwind() {

smklein added a commit to oxidecomputer/omicron that referenced this pull request Jan 6, 2023
- Makes use of oxidecomputer/steno#88 to test
idempotency of disk creation actions
- Fixes the way in which it was not idempotent: creating the disk record

Part of #2094
smklein added a commit to oxidecomputer/omicron that referenced this pull request Jan 9, 2023
- Makes use of oxidecomputer/steno#88 to test
idempotency of disk deletion actions

Part of #2094
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants