[Mono.Posix] Fix Group-lookup Tests
authorJonathan Pryor <jonpryor@vt.edu>
Thu, 31 May 2012 15:47:37 +0000 (11:47 -0400)
committerJonathan Pryor <jonpryor@vt.edu>
Thu, 31 May 2012 17:22:28 +0000 (13:22 -0400)
Fixes a test failure seen on OS X (and elsewhere), in which
UnixGroupTest.NonReentrantSyscalls() would fail:

#TRC: Exception constructing UnixGroupInfo: NUnit.Framework.AssertionException:
#TNRS: construct by name
Expected: <_appserverusr:*:79:>
But was:  <_appserverusr:*:79:jon>

The difference is in the group members: the expected value contains no
group members, while the actual value does. They both have the same
gorup name and group id; it's just the member list that differs.

The problem is that the _appserverusr group (and others) is returned
_twice_, once containing group members, and once without. (This is
possibly due to NIS; as per the removed comment.) This is readily
observed in a plain C program on OS X:

struct group *g;
setgrent ();
while ((g = getgrent ()) != NULL) {
printf ("local group: gr_name=%s; gr_passwd=%s; gr_gid=%i\n", g->gr_name, g->gr_passwd, g->gr_gid);
}
endgrent ();

Many groups are listed twice, and if you print out g->gr_mem it's
apparent that only the first invocation contains members, the second
does not, and looking up group info by name (getgrnam(3)) contains
group member info (yay!).

The fix here isn't a fix, it's a workaround: we track which groups
we've seen, and if we see a repeated group name we skip it. Thus, the
first time we see the _appserverusr group, we'll do the full
lookup-by-name-and-compare assertions, and the second time we see the
_appserverusr group we skip it entirely.

mcs/class/Mono.Posix/Test/Mono.Unix/UnixGroupTest.cs

index bef27c9a2b52df4b1c4895aaf3cf10b9026a9481..0d2971ef8d035c1847e5341a4660bac2b8332a67 100644 (file)
@@ -10,6 +10,7 @@
 
 using NUnit.Framework;
 using System;
+using System.Collections.Generic;
 using System.Configuration;
 using System.Diagnostics;
 
@@ -40,13 +41,13 @@ namespace MonoTests.Mono.Unix {
                }
 
                [Test]
-               // According to bug 72293, this may not work:
-               // On systems with NIS, it is possible to have multiple users in the passwd
-               // file with the same name, so the assertion above no longer holds.
-               [Category ("NotWorking")]
                public void ReentrantConstructors ()
                {
+                       var seen = new Dictionary<string, object> ();
                        foreach (UnixGroupInfo group in UnixGroupInfo.GetLocalGroups ()) {
+                               if (seen.ContainsKey (group.GroupName))
+                                       continue;
+                               seen.Add (group.GroupName, null);
                                try {
                                        UnixGroupInfo byName = new UnixGroupInfo (group.GroupName);
                                        UnixGroupInfo byId   = new UnixGroupInfo (group.GroupId);
@@ -66,7 +67,11 @@ namespace MonoTests.Mono.Unix {
                [Test]
                public void NonReentrantSyscalls ()
                {
+                       var seen = new Dictionary<string, object> ();
                        foreach (UnixGroupInfo group in UnixGroupInfo.GetLocalGroups ()) {
+                               if (seen.ContainsKey (group.GroupName))
+                                       continue;
+                               seen.Add (group.GroupName, null);
                                try {
                                        Group byName = Syscall.getgrnam (group.GroupName);
                                        Group byId   = Syscall.getgrgid ((uint) group.GroupId);