-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
id: revamp to pass more of GNU's Testsuite #2361
Conversation
* add conflicts_with for '-G' * add required flags for '-r' and '-n' * add usage/help texts from BSD's `id`
38576da
to
c1bbcd1
Compare
Great stuff. I retriggered the CI to get coverage results. GNU is failing on:
Not sure why ?! |
Looks like it still expects the items to be separated by spaces when |
If I'm interpreting the log right, that's not it.
I already noticed this while writing the tests and needed to use a "work around" test: // '--groups' ids are in no particular order and when paired with '--zero' there's no
// delimiter which makes the split_whitespace-collect-into-vector comparison impossible.
for opt in &["-G", "--groups"] {
let args = [opt, z_flag];
let result = new_ucmd!().args(&args).succeeds().stdout_move_str();
assert!(!result.contains(" "));
assert!(result.ends_with('\0'));
} GNU's id definitely uses some kind of order because it behaves deterministically. #GNU (host1)
$ id --groups
1000 10 968 975
#GNU (host2)
$ id --groups
20 501 702 12 61 79 80 81 98 701 33 100 204 250 395 398 e.g. on the CI system (if I'm reading the log right) #GNU (CI)
$ id --groups
121 4 101 |
This shows how GNU's id changes the order of the IDs returned from the $ strace -e getgroups id --groups
getgroups(0, NULL) = 4
getgroups(4, [10, 968, 975, 1000]) = 4
1000 10 968 975
+++ exited with 0 +++ $ strace -e getgroups target/debug/id --groups
getgroups(0, NULL) = 4
getgroups(4, [10, 968, 975, 1000]) = 4
10 968 975 1000
+++ exited with 0 +++
|
Could it be that GNU always shows the primary group first? |
Yes, that might be it! Edit: |
* add tests for '--zero' flag * add a bunch of requires/conflicts rules for flags (incl. tests)
As discussed here: uutils#2361 the group IDs returned for GNU's 'group' and GNU's 'id --groups' starts with the effective group ID. This implements a wrapper for `entris::get_groups()` which mimics GNU's behaviour. * add tests for `id` * add tests for `groups` * fix `id --groups --real` to no longer ignore `--real`
@sylvestre @tertsdiepraam |
As discussed here: uutils#2361 the group IDs returned for GNU's 'group' and GNU's 'id --groups' starts with the effective group ID. This implements a wrapper for `entris::get_groups()` which mimics GNU's behaviour. * add tests for `id` * add tests for `groups` * fix `id --groups --real` to no longer ignore `--real`
As discussed here: uutils#2361 the group IDs returned for GNU's 'group' and GNU's 'id --groups' starts with the effective group ID. This implements a wrapper for `entris::get_groups()` which mimics GNU's behaviour. * add tests for `id` * add tests for `groups` * fix `id --groups --real` to no longer ignore `--real`
As discussed here: uutils#2361 the group IDs returned for GNU's 'group' and GNU's 'id --groups' starts with the effective group ID. This implements a wrapper for `entris::get_groups()` which mimics GNU's behaviour. * add tests for `id` * add tests for `groups` * fix `id --groups --real` to no longer ignore `--real`
As discussed here: uutils#2361 the group IDs returned for GNU's 'group' and GNU's 'id --groups' starts with the effective group ID. This implements a wrapper for `entris::get_groups()` which mimics GNU's behaviour. * add tests for `id` * add tests for `groups` * fix `id --groups --real` to no longer ignore `--real`
As discussed here: uutils#2361 the group IDs returned for GNU's 'group' and GNU's 'id --groups' starts with the effective group ID. This implements a wrapper for `entris::get_groups()` which mimics GNU's behaviour. * add tests for `id` * add tests for `groups` * fix `id --groups --real` to no longer ignore `--real`
As discussed here: uutils#2361 the group IDs returned for GNU's 'group' and GNU's 'id --groups' starts with the effective group ID. This implements a wrapper for `entris::get_groups()` which mimics GNU's behaviour. * add tests for `id` * add tests for `groups` * fix `id --groups --real` to no longer ignore `--real`
As discussed here: uutils#2361 the group IDs returned for GNU's 'group' and GNU's 'id --groups' starts with the effective group ID. This implements a wrapper for `entris::get_groups()` which mimics GNU's behaviour. * add tests for `id` * add tests for `groups` * fix `id --groups --real` to no longer ignore `--real`
As discussed here: uutils#2361 the group IDs returned for GNU's 'group' and GNU's 'id --groups' starts with the effective group ID. This implements a wrapper for `entris::get_groups()` which mimics GNU's behaviour. * add tests for `id` * add tests for `groups` * fix `id --groups --real` to no longer ignore `--real`
After the small detour (#2371) to fix the order of the GIDs, the GNU test suite looks much better. FAIL: tests/id/zero
===================
uid=1001(runner) gid=121(docker) groups=121(docker),4(adm),101(systemd-journal)
uid=1001(runner) gid=121(docker) groups=121(docker),4(adm),101(systemd-journal)
--- gtmp1 2021-06-08 22:26:37.905457698 +0000
+++ gtmp3 2021-06-08 22:26:37.909457730 +0000
@@ -1,8 +1,4 @@
-121 4 101
-
-docker adm systemd-journal
-
-121 4 101
-
-docker adm systemd-journal
-
+121 4 101
+docker adm systemd-journal
+121 4 101
+docker adm systemd-journal On the first glance, it looks like newlines are missing (or too much) and that would be easy to fix. |
8519e49
to
d43e21d
Compare
This now passes two GNU testsuite Tests that fail on master branch.
However, some of the tests I wrote behave differently in the CI environment and need further debugging. |
c0b567a
to
bd67857
Compare
I consider GNU coreutils 8.32 the reference version since it's the latest stable release and the GNU Testsuite runs against it. + id: ‘foobar’: no such user
- id: 'foobar': no such user Therefore, I implemented to check the version before every invocation of the system Does anybody know how feasible it is to run the up-to-date coreutils, that were compiled for the GNU Testsuite, from inside the rust tests ( |
700edf1
to
8c8e32c
Compare
I think that's an issue related to the locale, not the coreutils version. Ultimately, we'll have to support different locales, but I think we can focus on the C locale for now. You can set it like this:
Or set it as an environment variable. |
Interesting, I haven't thought about that and definitely need to keep that in mind and investigate further. However, there are other things besides issues related to # 8.30
$ id root nobody
id: extra operand ‘nobody’
Try 'id --help' for more information.
# 8.32
$ id root nobody
uid=0(root) gid=0(root) groups=0(root)
uid=65534(nobody) gid=65534(nobody) groups=65534(nobody) |
Interesting, I think it's definitely worthwhile to keep testing against the latest versions. Maybe we could make use an environment variable that points to the GNU utils for the tests? Or we use a ppa in the Ubuntu CI? Maybe this one: https://code.launchpad.net/~dns/+archive/ubuntu/gnu? Edit: Nevermind about that PPA, it seems unmaintained |
I know we've had a discussion about running GNU utils in tests before and it's fine if you get this all to work. However, I would suggest changing the tests to use the GNU utils significantly less, maybe with only a few edge cases covered by GNU. For example:
It might not ensure 100% compatibility with GNU, but that's what the GNU tests are for, I guess. |
Well, my main motivation for these extensive tests was to find all the bugs to get GNU Testsuite Now that the tests are there, why not use them on the CICD images that have 8.30/8.32, i.e. ubuntu-latest/macOS? (The multiple user feature, only available on 8.32, would need skipping until there's a new linux image with more up-to-date package repos.) I don't disagree with the kind of tests you suggest, if the initial situation would be that there are not tests. However, now I don't feel too motivated to implement them because it would mean to invest additional work to change something that tests thoroughly into something that tests less thoroughly. Generally, I feel like the testing for uutils should involve more usage of coreutils 8.32 for gathering reference values, not less. |
That's awesome!
I fully understand! There's no point in throwing away perfectly good tests. I was trying to come up with solutions to run them on all platforms, but if you think that's not needed then it's fine.
This is more a workaround than a fix, but that's okay given all the different platforms we're trying to support. Thanks again for your hard work on this! |
`getgrouplist` implementation * add documentation
010ccd4
to
c609fb6
Compare
…t coreutils `id` version 8.31 in `$PATH`
Initially this was just a little PR to close #2351, but @sylvestre 's comment that the zero.sh test from GNU's Testsuite was failing led me go down a rabbit hole which resulted in discovering and fixing multiple underlying bugs first before the Testsuite was satisfied.
TLDR:
Together with the bug fixes from #2371 and #2416 this PR is a revamp of
uu_id
.This revamp passes the relevant tests from GNU's Testsuite that currently fail on master branch.
Long version:
uu_id
was originally based on BSD'sid
(noticeable in functionality, usage text, options text, etc.) and synced with:In this PR:
uu_id
was partially rewritten in order for stdout/stderr/exit_codeto be conform with GNU coreutils (8.32) testsuite for
id
.uu_id
passes GNU's coreutils Testsuite (8.32)for "tests/id/uid.sh" and "tests/id/zero/sh".
uu_id
now supports multiple users (a feature that was introduced in coreutils 8.31)uu_id
now supports '--zero', this flag does not exist for BSD'sid
,therefore '--zero' is only allowed together with other options that are available on GNU's
id
.Help text is now based on BSD's
id
manpage and GNU'sid
manpage.A bunch of requires/conflicts rules for clap options were added.
During debugging I made heavily use of calling the GNU coreutils
(g)id
binary in$PATH
in order to gather reference values.I came up with a little frame work (related: #2391) to help skip tests in environments where the necessary
id
binary doesn't include a coreutils version string, or the version is too low.This framework could be useful for other uutils where the reference values are not known beforehand.
Or it could be integrated in
common/util::TestScenario
so that test case authors could just runucmd()
and test results would automatically show if stdout/stderr/exit_code differ from the respective GNU coreutils binary output.Also thanks @tertsdiepraam for all the great help, feedback and discussions!