2 // UnixSignalTest.cs - NUnit Test Cases for Mono.Unix.UnixSignal
5 // Jonathan Pryor <jonpryor@vt.edu>
7 // (C) 2008 Jonathan Pryor
10 using NUnit.Framework;
13 using System.Threading;
15 using Mono.Unix.Native;
17 namespace MonoTests.Mono.Unix {
20 public class UnixSignalTest {
22 public void TestRaise ()
24 Thread t1 = new Thread (delegate () {
25 using (UnixSignal a = new UnixSignal (Signum.SIGINT)) {
26 DateTime start = DateTime.Now;
27 bool r = a.WaitOne (5000, false);
28 DateTime end = DateTime.Now;
29 Assert.AreEqual (a.Count, 1);
30 Assert.AreEqual (r, true);
31 if ((end - start) > new TimeSpan (0, 0, 5))
32 throw new InvalidOperationException ("Signal slept too long");
35 Thread t2 = new Thread (delegate () {
37 Stdlib.raise (Signum.SIGINT);
46 public void TestRaiseAny ()
48 Thread t1 = new Thread (delegate () {
49 using (UnixSignal a = new UnixSignal (Signum.SIGINT)) {
50 DateTime start = DateTime.Now;
51 int idx = UnixSignal.WaitAny (new UnixSignal[]{a}, 5000);
52 DateTime end = DateTime.Now;
53 Assert.AreEqual (idx, 0);
54 Assert.AreEqual (a.Count, 1);
55 if ((end - start) > new TimeSpan (0, 0, 5))
56 throw new InvalidOperationException ("Signal slept too long");
59 Thread t2 = new Thread (delegate () {
61 Stdlib.raise (Signum.SIGINT);
70 public void TestSeparation ()
72 Thread t1 = new Thread (delegate () {
73 using (UnixSignal a = new UnixSignal (Signum.SIGINT))
74 using (UnixSignal b = new UnixSignal (Signum.SIGTERM)) {
75 DateTime start = DateTime.Now;
76 int idx = UnixSignal.WaitAny (new UnixSignal[]{a, b}, 5000);
77 DateTime end = DateTime.Now;
78 Assert.AreEqual (idx, 1);
79 Assert.AreEqual (a.Count, 0);
80 Assert.AreEqual (b.Count, 1);
81 if ((end - start) > new TimeSpan (0, 0, 5))
82 throw new InvalidOperationException ("Signal slept too long");
85 Thread t2 = new Thread (delegate () {
87 Stdlib.raise (Signum.SIGTERM);
96 public void TestNoEmit ()
98 using (UnixSignal u = new UnixSignal (Signum.SIGINT)) {
99 DateTime start = DateTime.Now;
100 bool r = u.WaitOne (5100, false);
101 Assert.AreEqual (r, false);
102 DateTime end = DateTime.Now;
103 if ((end - start) < new TimeSpan (0, 0, 5))
104 throw new InvalidOperationException ("Signal didn't block for 5s; blocked for " + (end-start).ToString());
109 public void TestNoEmitAny ()
111 using (UnixSignal u = new UnixSignal (Signum.SIGINT)) {
112 int idx = UnixSignal.WaitAny (new UnixSignal[]{u}, 5100);
113 Assert.AreEqual (idx, 5100);
118 public void TestDispose1 ()
120 UnixSignal a = new UnixSignal (Signum.SIGINT);
121 UnixSignal b = new UnixSignal (Signum.SIGINT);
123 Stdlib.raise (Signum.SIGINT);
125 Assert.AreEqual (a.Count, 1);
126 Assert.AreEqual (b.Count, 1);
131 Stdlib.raise (Signum.SIGINT);
132 Assert.AreEqual (b.Count, 1);
138 public void TestDispose2 ()
140 UnixSignal a = new UnixSignal (Signum.SIGINT);
141 UnixSignal b = new UnixSignal (Signum.SIGINT);
143 Stdlib.raise (Signum.SIGINT);
145 Assert.AreEqual (a.Count, 1);
146 Assert.AreEqual (b.Count, 1);
151 Stdlib.raise (Signum.SIGINT);
152 Assert.AreEqual (a.Count, 1);
158 public void TestSignalActionInteraction ()
160 using (UnixSignal a = new UnixSignal (Signum.SIGINT)) {
161 Stdlib.SetSignalAction (Signum.SIGINT, SignalAction.Ignore);
162 Stdlib.raise (Signum.SIGINT);
163 Assert.AreEqual (a.Count, 0); // never invoked
167 static readonly Signum[] signals = new Signum[] {
168 Signum.SIGHUP, Signum.SIGINT, Signum.SIGTERM, Signum.SIGCONT,
171 const int StormCount = 100000;
174 public void TestRaiseStorm ()
176 UnixSignal[] usignals = CreateSignals (signals);
177 Thread[] threads = new Thread[]{
178 CreateRaiseStormThread (StormCount/4),
179 CreateRaiseStormThread (StormCount/4),
180 CreateRaiseStormThread (StormCount/4),
181 CreateRaiseStormThread (StormCount/4),
183 foreach (Thread t in threads)
185 foreach (Thread t in threads)
187 AssertCount (usignals);
188 CloseSignals (usignals);
191 static void AssertCount (UnixSignal[] usignals)
194 foreach (UnixSignal s in usignals)
196 Assert.AreEqual (sum, StormCount);
199 static UnixSignal[] CreateSignals (Signum[] signals)
201 UnixSignal[] s = new UnixSignal [signals.Length];
202 for (int i = 0; i < signals.Length; ++i)
203 s [i] = new UnixSignal (signals [i]);
207 static void CloseSignals (UnixSignal[] signals)
209 foreach (UnixSignal s in signals)
213 static Thread CreateRaiseStormThread (int max)
215 return new Thread (delegate () {
216 Random r = new Random (Environment.TickCount);
217 for (int i = 0; i < max; ++i) {
218 int n = r.Next (0, signals.Length);
219 Stdlib.raise (signals [n]);
225 public void TestAddRemove ()
227 UnixSignal[] usignals = CreateSignals (signals);
229 Thread[] threads = new Thread[]{
230 CreateRaiseStormThread (StormCount),
231 CreateSignalCreatorThread (),
234 foreach (Thread t in threads)
236 foreach (Thread t in threads)
239 AssertCount (usignals);
240 CloseSignals (usignals);
243 static Thread CreateSignalCreatorThread ()
245 return new Thread (delegate () {
246 Random r = new Random (Environment.TickCount << 4);
247 for (int i = 0; i < StormCount; ++i) {
248 int n = r.Next (0, signals.Length);
249 using (new UnixSignal (signals [n]))
250 using (new UnixSignal (signals [(n+1)%signals.Length]))
251 using (new UnixSignal (signals [(n+2)%signals.Length]))
252 using (new UnixSignal (signals [(n+3)%signals.Length])) {
259 public void TestWaitAny ()
261 UnixSignal[] usignals = CreateSignals (signals);
263 Thread[] threads = new Thread[]{
264 CreateRaiseStormThread (StormCount),
265 CreateSignalCreatorThread (),
266 CreateWaitAnyThread (usignals [0], usignals [2]),
267 CreateWaitAnyThread (usignals [1], usignals [3]),
268 CreateWaitAnyThread (usignals [1], usignals [2]),
271 foreach (Thread t in threads)
273 foreach (Thread t in threads)
276 AssertCount (usignals);
277 CloseSignals (usignals);
280 static Thread CreateWaitAnyThread (params UnixSignal[] usignals)
282 return new Thread (delegate () {
283 int idx = UnixSignal.WaitAny (usignals);
284 Assert.AreEqual (idx >= 0 && idx < usignals.Length, true);