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

Enable/Disable Endpoint timestamps #254

Merged
merged 3 commits into from
Aug 3, 2021

Conversation

MatthewBerk
Copy link
Contributor

What:
Added timestamp to response message when enable/disable chaos monkey with the endpoints /chaosmonkey/enable and /chaosmonkey/disable.
Modified test cases for enableChaosMonkey() and disableChaosMonkey() methods in order to handle timestamp now being present.

Why:
#246 (comment)

How:
Using java.time.Clock to get current time of user and attaching it to the already present "Chaos Monkey is enabled/disabled" message.

Checklist:

  • Documentation added N/A
  • Changelog updated
  • Tests added N/A
  • Ready to be merged

@codecov-commenter
Copy link

codecov-commenter commented Jul 29, 2021

Codecov Report

Merging #254 (1245160) into main (0830691) will decrease coverage by 0.72%.
The diff coverage is 80.00%.

Impacted file tree graph

@@             Coverage Diff              @@
##               main     #254      +/-   ##
============================================
- Coverage     76.30%   75.57%   -0.73%     
- Complexity      380      381       +1     
============================================
  Files            78       80       +2     
  Lines          1034     1040       +6     
  Branches         66       66              
============================================
- Hits            789      786       -3     
- Misses          211      217       +6     
- Partials         34       37       +3     
Impacted Files Coverage Δ
...s/monkey/endpoints/dto/ChaosMonkeyDisabledDto.java 66.66% <66.66%> (ø)
...os/monkey/endpoints/dto/ChaosMonkeyEnabledDto.java 66.66% <66.66%> (ø)
...chaos/monkey/endpoints/ChaosMonkeyJmxEndpoint.java 84.61% <100.00%> (ø)
...haos/monkey/endpoints/ChaosMonkeyRestEndpoint.java 91.30% <100.00%> (ø)
...ring/boot/chaos/monkey/assaults/MemoryAssault.java 83.58% <0.00%> (-10.45%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0830691...1245160. Read the comment docs.

Copy link
Contributor

@WtfJoke WtfJoke left a comment

Choose a reason for hiding this comment

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

Hey @MatthewBerk

I left feedback in the comments. Left some ideas for improving the code.
Let me know if something is unclear

@@ -4,13 +4,15 @@
Built with Spring Boot {spring-boot-version}

=== Bug Fixes
- https://github.com/codecentric/chaos-monkey-spring-boot/pull/252[#252] Update Maven Wrapper from 0.5.5 to 0.5.6.
Copy link
Contributor

Choose a reason for hiding this comment

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

These changes already have been merged.

You need to rebase latest changes of master or merge master into your branch.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do. Had pushed the day before that change got merged!

- https://github.com/codecentric/chaos-monkey-spring-boot/pull/251[#251] Fix missing AssaultPropertiesUpdate validation.
// - https://github.com/codecentric/chaos-monkey-spring-boot/pull/xxx[#xxx] Added example entry. Please don't remove.

=== Improvements
// - https://github.com/codecentric/chaos-monkey-spring-boot/pull/xxx[#xxx] Added example entry. Please don't remove.

=== New Features
- https://github.com/codecentric/chaos-monkey-spring-boot/pull/254[#254] Added timestamps to chaos monkey enable/disable endpoint.
Copy link
Contributor

@WtfJoke WtfJoke Jul 30, 2021

Choose a reason for hiding this comment

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

I think it would suit better in the Improvements section of the changelog.

Also please add yourself to the contributors list a few lines below :)

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 was debating between the two! The reason I went with new feature since I was adding a new element to Chaos Monkey. Will make the changes!

@@ -78,13 +79,15 @@ public String isChaosMonkeyActive() {
@WriteOperation
public String enableChaosMonkey() {
this.chaosMonkeySettings.getChaosMonkeyProperties().setEnabled(true);
return "Chaos Monkey is enabled";
return "Chaos Monkey is enabled\nActivatedAt:"
+ Clock.systemDefaultZone().instant().atZone(Clock.systemDefaultZone().getZone());
Copy link
Contributor

Choose a reason for hiding this comment

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

You can simplify this :)

Suggested change
+ Clock.systemDefaultZone().instant().atZone(Clock.systemDefaultZone().getZone());
+ ZonedDateTime.now();

Copy link
Contributor

Choose a reason for hiding this comment

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

Now that I see it, I would preferr the term "enabledAt" over "activatedAt" as we already use the verb enabled in "Chaos Monkey is enabled".

I think it would make sense to use StringJoiner, it would make the code more readable:

new StringJoiner("\n")
            .add("Chaos Monkey is enabled")
            .add("enabledAt: " + ZonedDateTime.now())
            .toString();

However I think even better would be to introduce a new class (POJO, eg. ChaosMonkeyEnabledDto and ChaosMonkeyDisabledDto) and return that instead. Then we dont need to deal with "\n" and formats and spring/jackson can take care of the conversion of that object to a string :)

Then it could look like this:

  @WriteOperation
 public ChaosMonkeyEnabledDto enableChaosMonkey() {
   this.chaosMonkeySettings.getChaosMonkeyProperties().setEnabled(true);
   return new ChaosMonkeyEnabledDto();
 }
@Data
public class ChaosMonkeyEnabledDto {
   private final String status = "Chaos Monkey is enabled";
   private ZonedDateTime enabledAt = ZonedDateTime.now();
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The class's is a good idea.

That was a fumble on my part. Makes more sense to use that since my complex code just basically invoked ZonedDateTime.now()!

@@ -273,7 +275,7 @@ void postToEnableChaosMonkey() {
testRestTemplate.postForEntity(baseUrl + "/enable", null, String.class);

assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Chaos Monkey is enabled", result.getBody());
assertTrue(Objects.requireNonNull(result.getBody()).startsWith("Chaos Monkey is enabled"));
Copy link
Contributor

Choose a reason for hiding this comment

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

As soon as we introduced an object (see comment above). You could make assertions again.
it would be great if we make a basic assertion that the correct time would be returned.

We could for example remember the time before we send the request and make an assertion that the time is returned should be later than the remembered time.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah it could be two asserts. One which asserts the text/status "Chaos Monkey is enabled" and one the time yes

assertThat(chaosMonkeyJmxEndpoint.disableChaosMonkey(), startsWith("Chaos Monkey is disabled"));
ZonedDateTime disabledAt = ZonedDateTime.now();
ZonedDateTime timeReturned = chaosMonkeyJmxEndpoint.disableChaosMonkey().getDisabledAt();
assertTrue(timeReturned.isAfter(disabledAt) || timeReturned.isEqual(disabledAt));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason I used isAfter and isEqual is because every time I ran the test, except one time, it had isAfter false and isEqual true! So just in case others encounter that odd event, I didn't want them to get a failed test!

Copy link
Contributor

@WtfJoke WtfJoke Jul 31, 2021

Choose a reason for hiding this comment

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

You could use assertIsAfterOrEqualsTo(disabledAt) its a bit more fluent to read

Suggested change
assertTrue(timeReturned.isAfter(disabledAt) || timeReturned.isEqual(disabledAt));
assertThat(timeReturned).isAfterOrEqualTo(disabledAt);

Copy link
Contributor

@WtfJoke WtfJoke left a comment

Choose a reason for hiding this comment

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

Almost there! 👯
Looks pretty good so far. 👍 Have only some smaller remarks on the Tests. After that this can get merged :)

assertThat(chaosMonkeyJmxEndpoint.disableChaosMonkey(), startsWith("Chaos Monkey is disabled"));
ZonedDateTime disabledAt = ZonedDateTime.now();
ZonedDateTime timeReturned = chaosMonkeyJmxEndpoint.disableChaosMonkey().getDisabledAt();
assertTrue(timeReturned.isAfter(disabledAt) || timeReturned.isEqual(disabledAt));
Copy link
Contributor

@WtfJoke WtfJoke Jul 31, 2021

Choose a reason for hiding this comment

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

You could use assertIsAfterOrEqualsTo(disabledAt) its a bit more fluent to read

Suggested change
assertTrue(timeReturned.isAfter(disabledAt) || timeReturned.isEqual(disabledAt));
assertThat(timeReturned).isAfterOrEqualTo(disabledAt);


assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Chaos Monkey is enabled", result.getBody());
assertTrue(Objects.requireNonNull(result.getBody()).getEnabledAt().isAfter(enabledAt));
Copy link
Contributor

@WtfJoke WtfJoke Jul 31, 2021

Choose a reason for hiding this comment

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

It would make sense to assert the status and the enabledAt.
And enabledAt I would do the same like suggested above with assertIsAfterOrEqualsTo


assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("Chaos Monkey is disabled", result.getBody());
assertTrue(Objects.requireNonNull(result.getBody()).getDisabledAt().isAfter(disabledAt));
Copy link
Contributor

Choose a reason for hiding this comment

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

The same as above :)

assertThat(chaosMonkeyJmxEndpoint.enableChaosMonkey(), is("Chaos Monkey is enabled"));
ZonedDateTime enabledAt = ZonedDateTime.now();
ZonedDateTime timeReturned = chaosMonkeyJmxEndpoint.enableChaosMonkey().getEnabledAt();
assertTrue(timeReturned.isAfter(enabledAt) || timeReturned.isEqual(enabledAt));
Copy link
Contributor

@WtfJoke WtfJoke Jul 31, 2021

Choose a reason for hiding this comment

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

Suggested change
assertTrue(timeReturned.isAfter(enabledAt) || timeReturned.isEqual(enabledAt));
assertThat(timeReturned).isAfterOrEqualTo(enabledAt);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It says method doesn't exist when did a quick check!

Copy link
Contributor

@WtfJoke WtfJoke Aug 1, 2021

Choose a reason for hiding this comment

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

oh my bad. The method name is a bit different. Its isAfterOrEqualTo without the assert in its name

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cannot resolve method 'assertThat(java.time.ZonedDateTime)'

Copy link
Contributor

@WtfJoke WtfJoke Aug 1, 2021

Choose a reason for hiding this comment

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

I see why, we usually use assertj, but in this test hamcrest is still used (a similar method there is named greaterThanOrEqualTo).
Assertj has this method, hamcrest not.

I thought we got rid of hamcrest completly, but it seems a few tests still uses it.

Copy link
Contributor

@WtfJoke WtfJoke Aug 1, 2021

Choose a reason for hiding this comment

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

You can keep it that way it is or change the whole test to assertj, I'll leave it up to you.

I most likely would do a PR afterwards which removes hamcrest completly (as it's causes such confusions like here :D)

If you keep it that way, just resolve all the comments related to isAfterOrEqualTo.
I think the only open comments would be the one in ChaosMonkeyRequestScopeRestEndpointIntegration.java

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 updated it! Though I left import static org.hamcrest.MatcherAssert.assertThat; since the other tests needed it!

Copy link
Contributor

@WtfJoke WtfJoke left a comment

Choose a reason for hiding this comment

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

LGTM 🕐

Thank you @MatthewBerk

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.

None yet

3 participants