1 //
2 // ExceptionDispatchInfoTest.cs
3 //
4 // Authors:
5 //	Marek Safar  <marek.safar@gmail.com>
6 //
7 // Copyright (C) 2011 Xamarin, Inc (http://www.xamarin.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 
29 using System;
30 using NUnit.Framework;
31 using System.Runtime.ExceptionServices;
32 using System.Threading.Tasks;
33 using System.Diagnostics;
34 using System.Linq;
35 
36 namespace MonoTests.System.Runtime.ExceptionServices
37 {
38 	[TestFixture]
39 	[Category ("BitcodeNotWorking")]
40 	public class ExceptionDispatchInfoTest
41 	{
GetLines(string str)42 		static string[] GetLines (string str)
43 		{
44 			var lines = str.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
45 
46 			// Ignore Metadata
47 			return lines.Where (l => !l.StartsWith ("[")).ToArray ();
48 		}
49 
50 		[Test]
Capture_InvalidArguments()51 		public void Capture_InvalidArguments ()
52 		{
53 			try {
54 				ExceptionDispatchInfo.Capture (null);
55 				Assert.Fail ();
56 			} catch (ArgumentNullException) {
57 			}
58 		}
59 
60 		[Test]
Capture()61 		public void Capture ()
62 		{
63 			var e = new ApplicationException ("test");
64 			var edi = ExceptionDispatchInfo.Capture (e);
65 			Assert.AreEqual (e, edi.SourceException);
66 		}
67 
68 		[Test]
69 		[Category ("InterpreterNotWorking")]
Throw()70 		public void Throw ()
71 		{
72 			Exception orig = null;
73 			var t = Task.Factory.StartNew (() => {
74 				try {
75 					throw new ApplicationException ("aaa");
76 				} catch (Exception e) {
77 					orig = e;
78 					return ExceptionDispatchInfo.Capture (e);
79 				}
80 			});
81 
82 			var ed = t.Result;
83 			var orig_stack = orig.StackTrace;
84 			try {
85 				ed.Throw ();
86 				Assert.Fail ("#0");
87 			} catch (Exception e) {
88 				var s = GetLines (e.StackTrace);
89 				Assert.AreEqual (4, s.Length, "#1");
90 				Assert.AreEqual (orig, e, "#2");
91 				Assert.AreNotEqual (orig_stack, e.StackTrace, "#3");
92 			}
93 		}
94 
95 		[Test]
96 		[Category ("InterpreterNotWorking")]
ThrowWithEmptyFrames()97 		public void ThrowWithEmptyFrames ()
98 		{
99 			var edi = ExceptionDispatchInfo.Capture (new OperationCanceledException ());
100 			try {
101 				edi.Throw ();
102 				Assert.Fail ("#0");
103 			} catch (OperationCanceledException e) {
104 				Assert.IsTrue (!e.StackTrace.Contains("---"));
105 				var lines = GetLines (e.StackTrace);
106 				Assert.AreEqual (2, lines.Length, "#1");
107 			}
108 		}
109 
110 		[Test]
111 		[Category ("InterpreterNotWorking")]
LastThrowWins()112 		public void LastThrowWins ()
113 		{
114 			Exception e;
115 			try {
116 				throw new Exception ("test");
117 			} catch (Exception e2) {
118 				e = e2;
119 			}
120 
121 			var edi = ExceptionDispatchInfo.Capture (e);
122 
123 			try {
124 				edi.Throw ();
125 			} catch {
126 			}
127 
128 			try {
129 				edi.Throw ();
130 			} catch (Exception ex) {
131 			}
132 
133 			try {
134 				edi.Throw ();
135 			} catch (Exception ex) {
136 				var lines = GetLines (ex.StackTrace);
137 				Assert.AreEqual (4, lines.Length, "#1");
138 				Assert.IsTrue (lines [1].Contains ("---"), "#2");
139 			}
140 		}
141 
142 		[Test]
143 		[Category ("InterpreterNotWorking")]
ThrowMultipleCaptures()144 		public void ThrowMultipleCaptures ()
145 		{
146 			Exception e;
147 			try {
148 				throw new Exception ("test");
149 			} catch (Exception e2) {
150 				e = e2;
151 			}
152 
153 			var edi = ExceptionDispatchInfo.Capture (e);
154 
155 			try {
156 				edi.Throw ();
157 			} catch (Exception e3) {
158 				edi = ExceptionDispatchInfo.Capture (e3);
159 			}
160 
161 			try {
162 				edi.Throw ();
163 			} catch (Exception ex) {
164 				var lines = GetLines (ex.StackTrace);
165 				Assert.AreEqual (7, lines.Length, "#1");
166 				Assert.IsTrue (lines [1].Contains ("---"), "#2");
167 				Assert.IsTrue (lines [4].Contains ("---"), "#3");
168 			}
169 		}
170 
171 		[Test]
172 		[Category ("InterpreterNotWorking")]
StackTraceUserCopy()173 		public void StackTraceUserCopy ()
174 		{
175 			try {
176 				try {
177 					throw new NotImplementedException ();
178 				} catch (Exception e) {
179 					var edi = ExceptionDispatchInfo.Capture (e);
180 					edi.Throw();
181 				}
182 			} catch (Exception ex) {
183 				var st = new StackTrace (ex, true);
184 				var lines = GetLines (st.ToString ());
185 				Assert.AreEqual (4, lines.Length, "#1");
186 				Assert.IsTrue (lines [1].Contains ("---"), "#2");
187 			}
188 		}
189 	}
190 }
191 
192