Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly handle scenarios with transformed stubs #2140

Conversation

gsmith85
Copy link
Contributor

Revises SnapshotStubMappingPostProcessor to run stub transformers first. That way, if the transformer results in StubMapping requests being equal they are properly
deduplicated or turned into scenarios.

Cleans up process method to make clearer the three phases of processing.

Additionally:

  • Converts SnapshotStubMappingPostProcessorTest.TEST_STUB_MAPPINGS to instance variable to avoid sharing mutable state between test cases which caused the suite to be order dependent.

Fixes: #2137

…sformed stubs

Revises SnapshotStubMappingPostProcessor to run stub transformers first.  That way,
if the transformer results in StubMapping requests being equal they are properly
 deduplicated or turned into scenarios.

Cleans up process method to make clearer the three phases of processing.

Additionally:
- Converts SnapshotStubMappingPostProcessorTest.TEST_STUB_MAPPINGS to instance variable
to avoid sharing mutable state between test cases which caused the suite to be order dependent.

Fixes: wiremock#2137
@oleg-nenashev oleg-nenashev self-requested a review April 21, 2023 18:49
@gsmith85
Copy link
Contributor Author

gsmith85 commented Jul 5, 2023

Hey @tomakehurst gentle bump on this. This issue has my team maintaining a kludgy internal fork of Wiremock, I'd love to get this into the main repo :).

@oleg-nenashev oleg-nenashev added bug needs-tom Tom's Train Project :) labels Jul 12, 2023
@oleg-nenashev oleg-nenashev requested a review from a team as a code owner July 12, 2023 10:13
Copy link
Member

@oleg-nenashev oleg-nenashev left a comment

Choose a reason for hiding this comment

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

Resolved the merge conflicts. Now needs @tomakehurst

@tomakehurst
Copy link
Member

Can we fix the build errors also? Then I'll take a look.

@oleg-nenashev
Copy link
Member

@tomakehurst AFAICT there are codestyle errors only.

@gsmith85
Copy link
Contributor Author

@tomakehurst AFAICT there are codestyle errors only.

Merging did actually result in introducing a bug, I've resolved it. All tests are passing now, and Spotless has been reapplied so this one should be good to go too.

@oleg-nenashev
Copy link
Member

Thanks @gsmith85 , and sorry for messing up the merge

@oleg-nenashev oleg-nenashev self-requested a review July 19, 2023 05:30
@gsmith85
Copy link
Contributor Author

@tomakehurst @oleg-nenashev are we a go here? Anything else you need form me to get this merged?

Copy link
Member

@oleg-nenashev oleg-nenashev left a comment

Choose a reason for hiding this comment

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

I had to sleep on it, and after all I think that the new behavior is wha8t we need for the real use-cases. There is a risk of slight performance degradation, but it repeatAsScenarios is rather an advanced feature so it should not impact many users.

Merging it towards 3.0 Beta and annotation as a breaking change is something I'm +1 for. Needs Tom ofc

@oleg-nenashev oleg-nenashev added the breaking Breaking change label Jul 24, 2023

assertThat(actual, hasSize(2));
assertThat(actual.get(0).getRequest().getUrl(), equalTo("/foo/transformed"));
assertThat(actual.get(1).getRequest().getUrl(), equalTo("/bar/transformed"));
}

@Test
public void processExtractsBodiesWhenMatched() {
public void
process_withShouldRecordRepeatsAsScenariosAndTransformer_runsTransformerBeforeScenarioProcessor() {
Copy link
Member

Choose a reason for hiding this comment

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

I'm finding these test names hard to make sense of, and they're inconsistent in style with the rest of the codebase. Please could we make them statements of outcome and camel cased?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Apologies for going in a different direction with test naming here.

A bit on rationale, the pattern method_condition_expectedOutcome was chosen based on capturing the recommended components for unit test naming per Google Testing and specifically I've included outcomes in this context because documenting that aspect feels valuable. The behavior of the SnapshotStubMappingPostProcessor is a bit subtle, I want to make sure each test's goal is articulated so the reader isn't left attempting to parse the intended behavior from the assertion set.

All of this can be done in a fashion more aligned to the conventions of this project. I've switched over to a method<With>condition<Should>expectedOutcome format, so I think we're in good shape.

final List<StubMapping> processedStubMappings = new ArrayList<>();

// 1. Run any applicable StubMappingTransformers against the stub mappings.
ArrayList<StubMapping> transformedStubMappings = new ArrayList<>();
Copy link
Member

Choose a reason for hiding this comment

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

This plus the next few lines could be done more neatly by mapping over a stream.

Copy link
Contributor Author

@gsmith85 gsmith85 Aug 3, 2023

Choose a reason for hiding this comment

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

If we're using Iterable as the type for stubMappings this actually may be worse from a readability perspective:

List<StubMapping> transformedStubMappings = 
        StreamSupport.stream(stubMappings.spliterator(), false)
                .map(transformerRunner)
                .collect(toList());

Note that when using Iterables you must use StreamSupport to gain access to a Steam.

So what I'm proposing is we change the method signature of process as well to use Collection so you end up with:

public List<StubMapping> process(Collection<StubMapping> stubMappings) {
    // 1. Run any applicable StubMappingTransformers against the stub mappings.
    List<StubMapping> transformedStubMappings =
            stubMappings.stream().map(transformerRunner).collect(toList());
    ...

Collection is a bit more narrow than Iterable but I think a general enough abstraction for this API and appropriate for the semantics of stubMappings.

@gsmith85
Copy link
Contributor Author

gsmith85 commented Aug 3, 2023

@tomakehurst I believe I've addressed your comments, appreciate the guidance on this one. Let me know if you need any other tweaks and I can be more responsive to help get this pushed over the line.

Unrelated note: JUnitJupiterExtensionDeclarativeProgrammaticMixTest appears to be flaky. The only thing that changed between 46c9906 and 42348c2 was a test name and one passed all checks and the later hand a port-bind exception only on ubuntu-latest/11. Will open a bug for this.

@tomakehurst tomakehurst merged commit f82ff84 into wiremock:master Aug 3, 2023
7 checks passed
@tomakehurst
Copy link
Member

Thanks @gsmith85 !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking Breaking change bug needs-tom Tom's Train Project :)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unexpected interplay: repeatsAsScenarios and StubMappingTransformer
3 participants