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

issue122 context propagation tests #132

Merged
merged 1 commit into from
Apr 18, 2019
Merged

Conversation

mmusgrov
Copy link
Contributor

@mmusgrov mmusgrov commented Apr 7, 2019

#122

This PR adds the TCK tests for the new context propagation semantics introduced in issue #122

String lra = invoke(NEW_LRA_PATH, PUT, null, 200, ContextTckResource.EndPhase.SUCCESS, 200);
invoke(REQUIRED_LRA_PATH, PUT, lra, 200, ContextTckResource.EndPhase.SUCCESS, 200);

// verify that the resource was not asked to complete
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// verify that the resource was not asked to complete
// verify that the resource was asked to complete

I think this is a typo (based on the next assert)

// call a resource that begins and ends an LRA and coerces the resource to return ACCEPTED when asked to complete
String lra = invoke(REQUIRED_LRA_PATH, PUT, null, 200, ContextTckResource.EndPhase.ACCEPTED, 202);

// verfiy that the resource was asked to complete and is in the state Conpleting
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// verfiy that the resource was asked to complete and is in the state Conpleting
// verfiy that the resource was asked to complete and is in the state Completing


@Test
public void testLeave() {
// call a resource that begins but does not ends an LRA
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// call a resource that begins but does not ends an LRA
// call a resource that begins but does not end an LRA



assertEquals(testName.getMethodName() + ": Resource left but was still asked to complete",
Integer.toString(0), completions);
Copy link
Member

Choose a reason for hiding this comment

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

This is just personal preference - comparing integers by string equals seems unnecessary. Maybe we can add invokeMetric() method that would call invoke(...) in the same way and return parsed integer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To keep the code simple I just changed it to "0" (instead of Integer.toString(0)) etc

Copy link
Member

Choose a reason for hiding this comment

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

I would still prefer it to be actual integer, but ok

replayEndPhase(TCK_CONTEXT_RESOURCE_PATH);

// the implementation should have called status which will have returned 500
String count1 = invoke(METRIC_PATH + "/" + Status.class.getName(), GET, lra);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
String count1 = invoke(METRIC_PATH + "/" + Status.class.getName(), GET, lra);
String statusCount = invoke(METRIC_PATH + "/" + Status.class.getName(), GET, lra);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I simplified the code by declaring a variable called String count at the beginning of the method.

assertEquals(testName.getMethodName() + " resource status should have been called", "1", count1);

// the implementation should not call forget until it knows the particpant status
String count2 = invoke(METRIC_PATH + "/" + Forget.class.getName(), GET, lra);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
String count2 = invoke(METRIC_PATH + "/" + Forget.class.getName(), GET, lra);
String forgetCount = invoke(METRIC_PATH + "/" + Forget.class.getName(), GET, lra);

assertEquals(testName.getMethodName() + " resource forget should not have been called", "0", count2);

// clear the fault
invoke(STATUS_PATH, PUT, lra, 200, ContextTckResource.EndPhase.FAILED, 200);
Copy link
Member

Choose a reason for hiding this comment

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

I would suggest using different JAX-RS resource method name for clearing/changing the status that is being returned from the resource to prevent confusion when next asserts check how many times @Status method has been called. I can see that this is PUT invocation, but I find this easy to miss :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There should be no confusion since the semantics of PUT and GET are well known in REST based systems:

  • GET is for reading a resource representation
  • PUT is for updating the resource representation

Copy link
Member

Choose a reason for hiding this comment

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

@mmusgrov sure. I meant that it is easy to miss that this is actually a PUT invoke when it's placed on STATUS_PATH so I really just wanted to rename it to something like CLEAR_PATH or similar. But if you don't want to do this it's not big deal.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But then it would not be obvious that the same resource is being accessed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will add a commit that adds more documentation to clarify how the resource and tests interact ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@xstefank I added more comments

}


void replayEndPhase(String resource) {
Copy link
Member

Choose a reason for hiding this comment

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

the parameter is not being used. Is the schema of recovery endpoint something we should define under recovery schematics? #116

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Exactly, there should be an option to recover for a singe resource - that's why I added the parameter. But we don't need a schema, the resource to recover can be inferred from the location of the RECOVER annotation if we can get some agreement on that.

Copy link
Member

Choose a reason for hiding this comment

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

@mmusgrov will we use the option to recover a single resource in the TCK? if so, we should correctly implement the replayEndPhase then so that it can be used as such. Otherwise, remove the parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This feature is still up for discussion. With my proposal on issue #116 it is per resource (but could be for all resources if required). BTW you said that you do not need the recovery so that issue will probably be moved out to the interoperability section of milestone 1.x. When/if that decision is made I will rewrite the replayEndPhase functionality to use a blocking wait for the implementation to get around to retrying the end phase.

The TCK already uses a proprietary technique and my plan is to leave this functionality as is until we decide what to do with #116 and like I said that will probably end up being an indefinite blocking call - I don't want to implement something in this PR and then find that I have rewrite it again depending on the outcome of the discussion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rdebusscher I know we discussed in the hangout that I would propose a PR for the recovery semantics and we would use that as a basis for discussion. But since I am the only person that thinks the RECOVERY annotation is useful I doubt it will make it into the spec (and we will need to fall back to something like "... after a crash the implementation must trigger recover at its earliest convenience ..."

// the value returned via the header and body should be equal

assertNotNull("JAX-RS response to PUT request should have returned the header " + LRA.LRA_HTTP_HEADER
// LRAs started programatically should not be available to the caller in the context header
Copy link
Member

Choose a reason for hiding this comment

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

this may be a little misleading to readers as with removal of LRA client there is no possibility to start LRA programatically. the "startViaApi" method uses LRAClientOps which still starts LRA by annotation.

LOGGER.warning("Invalid test data: endPhase ("
+ endPhase
+ ") or endPhaseStatus ("
+ endPhaseStatus + ")");
Copy link
Member

Choose a reason for hiding this comment

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

I would suggest to throw runtime exception here. This code will be called by TCK tests so this should really help TCK developer to find out that the wrong enum value has been used.

Copy link
Member

@xstefank xstefank left a comment

Choose a reason for hiding this comment

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

looks good, thanks

Copy link
Member

@rdebusscher rdebusscher left a comment

Choose a reason for hiding this comment

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

Few questions/remarks and a few improvements/corrections to make in my opinion.

}


void replayEndPhase(String resource) {
Copy link
Member

Choose a reason for hiding this comment

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

@mmusgrov will we use the option to recover a single resource in the TCK? if so, we should correctly implement the replayEndPhase then so that it can be used as such. Otherwise, remove the parameter.

void increment(String metric) {
if (metrics.containsKey(metric)) {
metrics.get(metric).incrementAndGet();
}
Copy link
Member

Choose a reason for hiding this comment

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

Should we be here on the safe side and throw an Exception if not found? (since we also return value -1 from the get() when not found?)

Copy link
Contributor Author

@mmusgrov mmusgrov Apr 16, 2019

Choose a reason for hiding this comment

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

The test should fail if the the test passes in an invalid metric but I can add more code. Would you prefer an exception (which would eventually get mapped to a jax-rs status code) and I can update the test to assert that the invocation returns status OK


private EndPhase endPhase = EndPhase.SUCCESS;
// control which status to return from participant callbacks
private Response.Status endPhaseStatus = Response.Status.OK;
Copy link
Member

Choose a reason for hiding this comment

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

Is it ok to have only 1 participantStatus but keep a list of all LRAids (see metrics property on line 123)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is only ever one LRA in play for each test. The reason I maintain a collection of LRAids is:

/**

  • A class to hold all of the metrics gathered in the context of a single LRA.
    * We need stats per LRA since a misbehaving test may interfere with subsequent tests
    */

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To further clarify why this could be a problem: a misbehaving test may leave an LRA in need of recovery which means that the compensate/complete call will continue to be called when subsequent tests run - ie it is not possible to fully tear down a failing test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have just pushed an update that includes that extra explanatory text.

endPhase = EndPhase.SUCCESS;
endPhaseStatus = Response.Status.OK;

if (metrics.containsKey(lraId)) {
Copy link
Member

Choose a reason for hiding this comment

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

We call /reset also with lraId = null (see TckContextTests:72 - @before - reset everything) -> so when null, we should clear out metric completely.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

okay

Signed-off-by: Michael Musgrove <[email protected]>
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