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

Fix test for invalid rate in FormatUtils.formatDataRate() #15337

Merged
merged 1 commit into from
Oct 18, 2024

Conversation

metadaddy
Copy link
Member

Description

FormatUtils.formatDataRate() contains the following code:

long rate = Math.round(dataSize.toBytes() / duration.getValue(SECONDS));
if (Double.isNaN(rate) || Double.isInfinite(rate)) {
    rate = 0;
}

The test can never evaluate as true, since both functions will return false for any long.

The correct test is:

if (rate == Long.MAX_VALUE) {
    rate = 0;
}

It's not necessary to test for Long.MIN_VALUE, since neither dataSize nor duration can be negative.

Unit Test

I added a new class, TestFormatUtils to test both this fix and the rest of FormatUtils. The tests for this change are:

assertEquals(FormatUtils.formatDataRate(DataSize.ofBytes(1), Duration.valueOf("0s"), false), "0B");
assertEquals(FormatUtils.formatDataRate(DataSize.ofBytes(1), Duration.valueOf("0s"), true), "0B/s");

Release notes

(x) This is not user-visible or docs only and no release notes are required.
( ) Release notes are required, please propose a release note for me.
( ) Release notes are required, with the following suggested text:

Related Issue

Fixes #13093

@@ -115,7 +115,7 @@ else if (longForm) {
public static String formatDataRate(DataSize dataSize, Duration duration, boolean longForm)
{
long rate = Math.round(dataSize.toBytes() / duration.getValue(SECONDS));
if (Double.isNaN(rate) || Double.isInfinite(rate)) {
if (rate == Long.MAX_VALUE) {
Copy link
Member

Choose a reason for hiding this comment

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

I am not sure there is a reason to special case the long max value.
Maybe we should remove the if block altogether?

Copy link
Member

Choose a reason for hiding this comment

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

Math.round returns Long.MAX_VALUE for positive infinity and Long.MIN_VALUE for negative infinity. Double.NaN returns 0. The check looks correct to me since dataSize.toBytes() can only return positive values, making negative infinity impossible.

Copy link
Member Author

Choose a reason for hiding this comment

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

The check against Long.MAX_VALUE preserves the intended semantics (and mirrors those of formatCountRate()) - if the rate calculation results in 'infinity', then set it to zero.

Copy link
Member

Choose a reason for hiding this comment

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

Are we printing "oh, so big a rate that I can't handle it" and "nothing is happening" the same way?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes - this is how formatCountRate works. I'm merely fixing the check here so it works as intended.

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 pretty sure the only way to get infinity (and thus max long) is if the duration is effectively zero. In that case I think printing a zero rate is fine. It will quickly update to a real value.

}

@Test
public void testPluralize()
Copy link
Member

Choose a reason for hiding this comment

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

that's awesome you're adding this test class.
note that it covers lot more than just the fix itself

what about introducing the test class as a prep commit
and then only doing the change (that should be reflected with only a small, related test change)

Copy link
Member Author

Choose a reason for hiding this comment

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

@findepi Two PRs, or one PR containing two commits?

Copy link
Member

Choose a reason for hiding this comment

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

I'd do 1 PR containing two commits.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@Test
public void testFormatCount()
{
assertEquals(FormatUtils.formatCount(1L), "1");
Copy link
Member

Choose a reason for hiding this comment

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

nit: you can import FormatUtils method statically

i know this will make it less clear that we're invking FormatUtils methods
but it will improve readability overall

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@findepi findepi requested a review from pettyjamesm December 7, 2022 21:38
@metadaddy
Copy link
Member Author

Thanks for the reviews! I've made the suggested changes; @findepi - just let me know whether you're looking for two PRs, or one PR with two commits and I'll do another push.

@metadaddy metadaddy force-pushed the fix-formatdatarate-test branch from 5253041 to a3ff146 Compare December 8, 2022 02:39
@metadaddy
Copy link
Member Author

@findepi I refactored to two commits and force-pushed them. Let me know if you need two PRs.

@@ -275,6 +275,9 @@ public void testFormatDataRate()
assertEquals(formatDataRate(DataSize.ofBytes(864000), Duration.valueOf("10d"), true), "1B/s");
assertEquals(formatDataRate(DataSize.ofBytes(8640000), Duration.valueOf("10d"), false), "10B");
assertEquals(formatDataRate(DataSize.ofBytes(8640000), Duration.valueOf("10d"), true), "10B/s");

assertEquals(formatDataRate(DataSize.ofBytes(1), Duration.valueOf("0s"), false), "0B");
Copy link
Member

Choose a reason for hiding this comment

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

If we eg transferred 1 MB within "zero time" (which isn't impossible given clock granularity), why would we want to print 0?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't know; I'm simply honoring the intent of the original code written by @electrum

@metadaddy metadaddy force-pushed the fix-formatdatarate-test branch from a3ff146 to ed8e1a6 Compare December 8, 2022 17:15
@metadaddy
Copy link
Member Author

Force-pushed the fix for the failing maven check (import static io.trino.cli.FormatUtils.*)

@mosabua
Copy link
Member

mosabua commented Jan 11, 2024

@findepi @metadaddy @pettyjamesm can you continue to collaborate on this PR please?

Copy link

github-actions bot commented Sep 4, 2024

This pull request has gone a while without any activity. Tagging the Trino developer relations team: @bitsondatadev @colebow @mosabua

@github-actions github-actions bot added the stale label Sep 4, 2024
@mosabua
Copy link
Member

mosabua commented Sep 5, 2024

Does this PR need anything besides a merge @findepi and @pettyjamesm ?

@pettyjamesm
Copy link
Member

Does this PR need anything besides a merge @findepi and @pettyjamesm ?

Nothing on my end, @findepi had some feedback and conversations going after I had approved it- so I defer to him on merge readiness, although if he’s not available I can pick it up and re-review.

@github-actions github-actions bot removed the stale label Sep 6, 2024
Copy link

This pull request has gone a while without any activity. Tagging the Trino developer relations team: @bitsondatadev @colebow @mosabua

@github-actions github-actions bot added the stale label Sep 30, 2024
@mosabua
Copy link
Member

mosabua commented Oct 17, 2024

Could you rebase @metadaddy .. maybe we can find someone to look and get this merged after.

@metadaddy metadaddy force-pushed the fix-formatdatarate-test branch from ed8e1a6 to adb19f6 Compare October 18, 2024 00:48
@metadaddy
Copy link
Member Author

Hi @mosabua - I rebased, as requested 👍🏻

@github-actions github-actions bot removed the stale label Oct 18, 2024
@@ -115,7 +115,7 @@ else if (longForm) {
public static String formatDataRate(DataSize dataSize, Duration duration, boolean longForm)
{
long rate = Math.round(dataSize.toBytes() / duration.getValue(SECONDS));
if (Double.isNaN(rate) || Double.isInfinite(rate)) {
if (rate == Long.MAX_VALUE) {
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 pretty sure the only way to get infinity (and thus max long) is if the duration is effectively zero. In that case I think printing a zero rate is fine. It will quickly update to a real value.

@dain dain merged commit ff794d2 into trinodb:master Oct 18, 2024
40 checks passed
@github-actions github-actions bot added this to the 463 milestone Oct 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

io.trino.cli.FormatUtils.formatDataRate incorrectly tests long rate with Double functions
5 participants