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

uptime: correctly calculate boot-time #4440

Merged
merged 1 commit into from
Feb 26, 2023
Merged

uptime: correctly calculate boot-time #4440

merged 1 commit into from
Feb 26, 2023

Conversation

zanbaldwin
Copy link
Contributor

@zanbaldwin zanbaldwin commented Feb 26, 2023

Correctly calculate boot-time on Unix systems that cannot access /proc/uptime (eg, macOS).

The number of seconds since boot-time was calculated using the seconds component of OffsetDateTime (eg, boot-time of 2023-02-25 17:46:27 would return Some(27_i64)) rather the total number of seconds since the Unix epoch. Meaning uptime would believe that the boot-time of the system would always be somewhere between 1970-01-01 00:00:00 and 1970-01-01 00:00:59.

And I can guarantee that my M1 mac has not been up for 53 years 😉

Example terminal output:

user@host: uptime
13:23  up 19:37, 2 users, load averages: 1.21 1.82 2.08

user@host: coreutils uptime
 13:24:01 up 19414 days, 12:23,  2 users,  load averages: 1.27, 1.83, 2.08

This was a very easy bug to miss, since (a) this would only be apparent on Unix systems that do not have a /proc/uptime, and (b) the tests could only validate that a value is returned and not whether that value was correct (to do so the tests would need to have knowledge of how long the underlying system has been up - need uptime to test uptime).

@tertsdiepraam
Copy link
Member

Thanks! Could you replace the screenshot with text for better accessibility? Can we also test this in some way? I imagine that's a bit difficult because we don't know the uptime of the device the tests are run on?

@zanbaldwin
Copy link
Contributor Author

zanbaldwin commented Feb 26, 2023

I don't have any ideas on how to test this that I'm happy with.

We could test against some arbitrary point in time? Check that boot time is greater than something like 946681200 (2000-01-01 00:00:00)? Hope that no-one is running coreutils tests on a machine with an uptime exceeding 23 years 😛 (which sounds ridiculous, but "hey we don't have a use for these really old servers anymore but they're not costing us much shall I whack some runners on them until we decide what to do with them?" sounds less ridiculous).

Or we could return Some(OffsetDateTime) instead of Some(i64), and deal with it in get_uptime(boot_time: Option<OffsetDateTime>). At least then the tests could verify that "if the system reported this boot-time what should the output be". The problem is that without overriding Local::now() you'd essentially be testing that the calculation in the library has the same result as the exact same calculation in the test to figure out what the result should be, which makes it kind of redundant.

Not sure I'm completely happy with either solution, but I suppose it's better than no tests at all.

@tertsdiepraam
Copy link
Member

Yeah the options aren't great. GNU doesn't really have tests for uptime either as far as I can see. So I guess it's fine.

@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/tail-2/inotify-dir-recreate. tests/tail-2/inotify-dir-recreate is passing on 'main'. Maybe you have to rebase?

@tertsdiepraam tertsdiepraam merged commit c1d85ad into uutils:main Feb 26, 2023
@tertsdiepraam
Copy link
Member

Thanks!

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.

2 participants