Update named mutex PAL tests to include case of file locks being inherited by child...
authorKoundinya Veluri <kouvel@users.noreply.github.com>
Tue, 18 Dec 2018 22:32:38 +0000 (14:32 -0800)
committerGitHub <noreply@github.com>
Tue, 18 Dec 2018 22:32:38 +0000 (14:32 -0800)
Included case fixed by https://github.com/dotnet/coreclr/pull/21458. Fixes https://github.com/dotnet/coreclr/issues/21494.

Commit migrated from https://github.com/dotnet/coreclr/commit/d67f84b05e02988276eb140194d914185e9c2ca3

src/coreclr/src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp

index a9d46b3..6635d76 100644 (file)
@@ -837,6 +837,67 @@ DWORD AbandonTests_Child_AbruptExit(void *arg = nullptr)
     return 0;
 }
 
+// This child process acquires the mutex lock, creates another child process (to ensure that file locks are not inherited), and
+// abandons the mutex abruptly. The second child process detects the abandonment and abandons the mutex again for the parent to
+// detect. Issue: https://github.com/dotnet/coreclr/issues/21455
+DWORD AbandonTests_Child_FileLocksNotInherited_Parent_AbruptExit(void *arg = nullptr)
+{
+    const char *testName = "AbandonTests";
+
+    DWORD currentPid = test_getpid();
+    TestAssert(currentPid != g_parentPid); // this test needs to run in a separate process
+
+    {
+        char name[MaxPathSize];
+        AutoCloseMutexHandle m;
+
+        // ... root parent waits for child to lock mutex
+        TestCreateMutex(m, BuildName(testName, name, GlobalPrefix, NamePrefix));
+        TestAssert(m != nullptr);
+        TestAssert(WaitForSingleObject(m, 0) == WAIT_OBJECT_0);
+
+        // Start a child process while holding the lock on the mutex, to ensure that file locks are not inherited by the
+        // immediate child, such that the immediate child would be able to detect the mutex being abandoned below. This process
+        // does not communicate with the root parent, it only communicates to the immediate child by abandoning the mutex. The
+        // immediate child communicates with the root parent to complete the test.
+        TestAssert(StartProcess("AbandonTests_Child_FileLocksNotInherited_Child_AbruptExit")); // immediate child waits on mutex
+
+        Sleep(g_expectedTimeoutMilliseconds); // wait for immediate child to wait on mutex
+        m.Abandon(); // don't close the mutex
+    }
+
+    TestAssert(test_kill(currentPid) == 0); // abandon the mutex abruptly
+    return 0;
+}
+
+DWORD AbandonTests_Child_FileLocksNotInherited_Child_AbruptExit(void *arg = nullptr)
+{
+    const char *testName = "AbandonTests";
+
+    DWORD currentPid = test_getpid();
+    TestAssert(currentPid != g_parentPid); // this test needs to run in a separate process
+
+    AutoCloseMutexHandle childRunningEvent, parentEvents[2], childEvents[2];
+    TestAssert(InitializeChild(testName, childRunningEvent, parentEvents, childEvents));
+    int ei = 0;
+
+    {
+        char name[MaxPathSize];
+        AutoCloseMutexHandle m;
+
+        // ... immediate parent expects child to wait on mutex
+        TestCreateMutex(m, BuildName(testName, name, GlobalPrefix, NamePrefix));
+        TestAssert(m != nullptr);
+        TestAssert(WaitForSingleObject(m, FailTimeoutMilliseconds) == WAIT_ABANDONED_0); // attempt to lock and see abandoned mutex
+        TestAssert(YieldToParent(parentEvents, childEvents, ei)); // root parent waits on mutex
+        Sleep(g_expectedTimeoutMilliseconds); // wait for root parent to wait on mutex
+        m.Close(); // close mutex without releasing lock (root parent expects the mutex to be abandoned)
+    }
+
+    UninitializeChild(childRunningEvent, parentEvents, childEvents);
+    return 0;
+}
+
 DWORD PALAPI AbandonTests_Child_TryLock(void *arg)
 {
     const char *testName = "AbandonTests";
@@ -878,6 +939,9 @@ bool AbandonTests()
     TestAssert(StartProcess("AbandonTests_Child_AbruptExit"));
     TestAssert(AbandonTests_Parent());
 
+    TestAssert(StartProcess("AbandonTests_Child_FileLocksNotInherited_Parent_AbruptExit"));
+    TestAssert(AbandonTests_Parent());
+
     return true;
 }
 
@@ -1049,6 +1113,14 @@ int __cdecl main(int argc, char **argv)
     {
         AbandonTests_Child_AbruptExit();
     }
+    else if (test_strcmp(argv[2], "AbandonTests_Child_FileLocksNotInherited_Parent_AbruptExit") == 0)
+    {
+        AbandonTests_Child_FileLocksNotInherited_Parent_AbruptExit();
+    }
+    else if (test_strcmp(argv[2], "AbandonTests_Child_FileLocksNotInherited_Child_AbruptExit") == 0)
+    {
+        AbandonTests_Child_FileLocksNotInherited_Child_AbruptExit();
+    }
     else if (test_strcmp(argv[2], "AbandonTests_Child_TryLock") == 0)
     {
         AbandonTests_Child_TryLock();