Merge pull request #910 from akoeplinger/cleanup-test-ignores
[mono.git] / mcs / class / corlib / Test / System.Security.AccessControl / MutexSecurityTest.cs
1 // MutexSecurityTest.cs - NUnit Test Cases for MutexSecurity
2 //
3 // Authors:
4 //      James Bellinger  <jfb@zer7.com>
5 //
6 // Copyright (C) 2012 James Bellinger
7
8 #if !MOBILE
9
10 using System;
11 using System.Collections.Generic;
12 using System.Security.AccessControl;
13 using System.Security.Principal;
14 using System.Threading;
15 using NUnit.Framework;
16
17 namespace MonoTests.System.Security.AccessControl
18 {
19         [TestFixture]
20         public class MutexSecurityTest
21         {
22                 [Test, ExpectedException (typeof (WaitHandleCannotBeOpenedException))]
23                 public void FailsForNonexistantMutex ()
24                 {
25                         if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
26                                 Assert.Ignore ();
27                         }
28
29                         new MutexSecurity (@"Local\NonexistantMutex", AccessControlSections.Access);
30                 }
31
32                 [Test]
33                 public void SucceedsForExistingMutex ()
34                 {
35                         if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
36                                 Assert.Ignore ();
37                         }
38
39                         bool createdNew;
40                         string name = @"Local\MonoTestMutex";
41
42                         // Let's be sure the mutex destroys on Close() as well.
43                         // Otherwise, many of our tests will fail as they will be accessing the wrong mutex.
44                         using (Mutex mutex = new Mutex (false, name, out createdNew)) {
45                                 Assert.IsTrue (createdNew);
46                                 new MutexSecurity (name, AccessControlSections.Access);
47                         }
48
49                         using (Mutex mutex = new Mutex (false, name, out createdNew)) {
50                                 Assert.IsTrue (createdNew);
51                                 new MutexSecurity (name, AccessControlSections.Access);
52                         }
53                 }
54
55                 [Test]
56                 public void CanSetAndGetMutexSecurity ()
57                 {
58                         if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
59                                 Assert.Ignore ();
60                         }
61
62                         MutexAccessRule rule; SecurityIdentifier sid;
63                         AuthorizationRuleCollection rulesA, rulesB, rulesC;
64                         bool createdNew; MutexSecurity security;
65                         string name = @"Local\MonoTestMutex";
66
67                         using (Mutex mutex = new Mutex(false, name, out createdNew)) {
68                                 Assert.IsTrue (createdNew);
69
70                                 security = mutex.GetAccessControl ();
71                                 rulesA = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
72                                 Assert.AreNotEqual (0, rulesA.Count);
73
74                                 // Contrary to what you'd expect, these classes only try to persist sections that
75                                 // that were *changed*. Awful, eh? To be fair, if you retrieve and modify it's fine.
76                                 security = new MutexSecurity ();
77                                 mutex.SetAccessControl (security);
78
79                                 security = mutex.GetAccessControl ();
80                                 rulesB = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
81                                 Assert.AreEqual (rulesA.Count, rulesB.Count);
82
83                                 // And here's our dummy change. Observe...
84                                 sid = new SecurityIdentifier( "S-1-5-12-3456-7890");
85                                 rule = new MutexAccessRule (sid, MutexRights.Synchronize, AccessControlType.Allow);
86
87                                 security = new MutexSecurity ();
88                                 security.RemoveAccessRuleSpecific (rule);
89                                 mutex.SetAccessControl (security);
90
91                                 security = mutex.GetAccessControl ();
92                                 rulesC = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
93                                 Assert.AreEqual (0, rulesC.Count);
94                         }
95                 }
96
97                 // TODO: Mono System.Threading.Mutex does not throw exceptions on failure!
98                 [Test, ExpectedExceptionAttribute (typeof (UnauthorizedAccessException))]
99                 public void PermissionsActuallyWork ()
100                 {
101                         if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
102                                 Assert.Ignore ();
103                         }
104
105                         bool createdNew; MutexSecurity security;
106                         string name = @"Local\MonoTestMutex";
107
108                         using (Mutex mutex = new Mutex (false, name, out createdNew)) {
109                                 Assert.IsFalse (mutex.SafeWaitHandle.IsInvalid);
110                                 Assert.IsTrue (createdNew);
111
112                                 // Make sure our later error will be due to permissions and not some sharing bug.
113                                 bool createdAnotherNew;
114                                 using (Mutex anotherMutex = new Mutex (false, name, out createdAnotherNew)) {
115                                         Assert.IsFalse (mutex.SafeWaitHandle.IsInvalid);
116                                         Assert.IsFalse (createdAnotherNew);
117                                 }
118
119                                 // Let's make a deny all.
120                                 security = mutex.GetAccessControl ();
121
122                                 foreach (MutexAccessRule rule in security.GetAccessRules
123                                          (true, false, typeof (SecurityIdentifier))) {
124                                         security.RemoveAccessRuleSpecific (rule);
125                                 }
126
127                                 Assert.AreEqual (0, security.GetAccessRules (true, false, typeof (SecurityIdentifier)).Count);
128                                 mutex.SetAccessControl (security);
129
130                                 security = mutex.GetAccessControl ();
131                                 Assert.AreEqual (0, security.GetAccessRules (true, false, typeof (SecurityIdentifier)).Count);
132
133                                 // MS.NET will throw on the first line below.
134                                 // For Mono testing the latter verifies the rest until the Mutex bug is fixed.
135                                 // Also, NUnit 2.4 appears to lacks Assert.Pass ().
136                                 Mutex badMutex = new Mutex(false, name);
137                                 if (badMutex.SafeWaitHandle.IsInvalid)
138                                         throw new UnauthorizedAccessException ();
139                         }
140                 }
141         }
142 }
143
144 #endif
145