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

Fixes multiple inclusions of the current frame in aggregate commands … #294

Merged
merged 1 commit into from
Sep 13, 2019
Merged

Conversation

jmkerr
Copy link
Contributor

@jmkerr jmkerr commented Jul 8, 2019

Possible solution for #293.

@jmaupetit
Copy link
Contributor

Thank you @jmkerr ! Can you provide tests for this fix please?

@jmkerr
Copy link
Contributor Author

jmkerr commented Jul 15, 2019

Thank you for Watson, I'm happy to help!

I'm not exactly sure where to best handle the deduplication of the current frame. Maybe it should be part of the behaviour of the frames data structure. Is it ever really useful to ignore the current frame?

For now, this is a simple and fast fix.

@jmaupetit jmaupetit requested a review from k4nar July 16, 2019 08:09
Copy link
Collaborator

@k4nar k4nar left a comment

Choose a reason for hiding this comment

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

Maybe instead we should remove the "current" frame at the end of the report function? It looks like a side effect.

@jmaupetit
Copy link
Contributor

It makes sense indeed.

@jmkerr
Copy link
Contributor Author

jmkerr commented Jul 20, 2019

Maybe instead we should remove the "current" frame at the end of the report function? It looks like a side effect.

You're right. I have changed it to always initialize current to keep track of the extra frame and remove it as soon as possible.

@jmaupetit jmaupetit requested a review from k4nar August 12, 2019 08:26
_ = watson.report(arrow.now(), arrow.now(), current=True)
watson.stop()

assert watson.frames['id'].count('current') == 0
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like you're testing the implementation here (i.e. the current frame has been deleted after report() finishes), but maybe it would be even more useful to test the actual report data returned?

The question I'd like to get answered by the test is this: are we sure that the current frame is not being deleted too soon in the report() method?

The watson.py implementation looks fine to me 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

@jmkerr I'm not sure if I made myself clear. If you need further clarification just let me know.

@k4nar Sorry for stepping in here, I thought it might be useful to move the PR forward... what do you think about my comment?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'll try to explain my point further: I think you should solely rely on Watson class methods to test your assumptions on the behavior of the Watson class.

As I see it, by accessing the Frames object and asserting on its properties, you're effectively testing an implementation detail of the Watson class and adding complexity to the test itself.

What I would have done here is calling two or more times watson.report() and verify that you're always getting the expected report results.

What do you think? ☺️

@jmkerr
Copy link
Contributor Author

jmkerr commented Sep 6, 2019

Thank you @davidag. Since this commit changes the implementation, it should include the tests you mentioned. The tests now assert whether the current frame is included in the report

  • when it should be
  • when it should not be
  • by default

_ = watson.report(arrow.now(), arrow.now(), current=True)
watson.stop()

assert watson.frames['id'].count('current') == 0
Copy link
Contributor

Choose a reason for hiding this comment

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

I'll try to explain my point further: I think you should solely rely on Watson class methods to test your assumptions on the behavior of the Watson class.

As I see it, by accessing the Frames object and asserting on its properties, you're effectively testing an implementation detail of the Watson class and adding complexity to the test itself.

What I would have done here is calling two or more times watson.report() and verify that you're always getting the expected report results.

What do you think? ☺️

)
assert len(report['projects']) == 0

watson.stop()
Copy link
Contributor

@davidag davidag Sep 10, 2019

Choose a reason for hiding this comment

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

Finally, something I missed in my initial review: this seems a great opportunity to split test_report() in multiple tests with more meaningful names. For example, your new tests could be inside a method named test_report_current().

@jmkerr
Copy link
Contributor Author

jmkerr commented Sep 10, 2019

Thanks again @davidag. You're right about not explicitly testing for side effects, but only the methods return value. The only way to detect the error in a report is by verifying the reported time.

I've updated the test (in a new function) to:

  • Construct watson with a current frame with a backdated start date.
  • Verify the reported time (up to 1%).

)
assert len(report['projects']) == 1
assert report['projects'][0]['name'] == 'foo'
assert report['projects'][0]['time'] == pytest.approx(3600, rel=1e-2)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think you need to use pytest.approx() as there are no floating-point numbers involved. In fact, asserting that time equals 3600 is equivalent to what you did, as we are working with a granularity of seconds (ints). This would lead to a flaky test: if there was a change in seconds between building the Watson object and calling the second watson.report(), the assertion would fail.

A possible solution could be to assert that time is less than 3600 * 2, which is enough to test that the time is not duplicated. Any other ideas are more than welcomed! ☺️

Finally, I would use one minute (60) instead of one hour (3600) in order to reduce the complexity of the test (unless there is a reason to use hours that I didn't notice).

It seems we're close to ending this PR 🎉

Copy link
Contributor Author

Choose a reason for hiding this comment

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

report['projects'][0]['time'] is (like timedelta.total_seconds()) floating-point-valued with microsecond precision, and it usually takes a few milliseconds until the second report is generated.

The flakyness should be just as negligible at the current 36 seconds as it is at 3600 seconds tolerance in an automated test, but could be reduced by mocking arrow.now and arrow.utcnow.

Copy link
Contributor

Choose a reason for hiding this comment

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

report['projects'][0]['time'] is (like timedelta.total_seconds()) floating-point-valued with microsecond precision, and it usually takes a few milliseconds until the second report is generated.

I didn't realize that, sorry!

I supposed they were seconds, because that's what is printed in the terminal. Nevertheless, it's the utils.format_timedelta() function that removes millisecond information: seconds = int(delta.total_seconds()). 👍

The flakyness should be just as negligible at the current 36 seconds as it is at 3600 seconds tolerance in an automated test

You're completely right, there's no flakiness ☺️

Copy link
Contributor

@davidag davidag left a comment

Choose a reason for hiding this comment

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

One more thing, could you add a new point to CHANGELOG.md?

…293)

- Inclusion of the current frame in report() does not persistently add
it to the Frames container.

- Added test
@jmkerr
Copy link
Contributor Author

jmkerr commented Sep 12, 2019

I've rebased and added a line to CHANGELOG.md.

Copy link
Contributor

@davidag davidag left a comment

Choose a reason for hiding this comment

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

This looks fine to me. What do you think @jmaupetit ?

Copy link
Contributor

@jmaupetit jmaupetit left a comment

Choose a reason for hiding this comment

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

Yup. Will merge this, thank you all! 🙏

@jmaupetit jmaupetit merged commit 581a107 into jazzband:master Sep 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants