New test.
[mono.git] / mcs / class / corlib / Test / System.IO.IsolatedStorage / IsolatedStorageFileStreamCas.cs
1 //
2 // IsolatedStorageFileStreamCas.cs - CAS unit tests for 
3 //      System.IO.IsolatedStorage.IsolatedStorageFileStream
4 //
5 // Author:
6 //      Sebastien Pouliot  <sebastien@ximian.com>
7 //
8 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using NUnit.Framework;
31
32 using System;
33 using System.IO;
34 using System.IO.IsolatedStorage;
35 using System.Reflection;
36 using System.Security;
37 using System.Security.Permissions;
38 using System.Threading;
39
40 #if NET_2_0
41 using Microsoft.Win32.SafeHandles;
42 #endif
43
44 namespace MonoCasTests.System.IO.IsolatedStorageTest {
45
46         [TestFixture]
47         [Category ("CAS")]
48         public class IsolatedStorageFileStreamCas {
49
50                 private const int timeout = 30000;
51                 private string message;
52
53                 static ManualResetEvent reset;
54
55                 [TestFixtureSetUp]
56                 public void FixtureSetUp ()
57                 {
58                         reset = new ManualResetEvent (false);
59                 }
60
61                 [TestFixtureTearDown]
62                 public void FixtureTearDown ()
63                 {
64                         reset.Close ();
65                 }
66
67                 [SetUp]
68                 public void SetUp ()
69                 {
70                         if (!SecurityManager.SecurityEnabled)
71                                 Assert.Ignore ("SecurityManager.SecurityEnabled is OFF");
72                 }
73
74                 [Test]
75                 [PermissionSet (SecurityAction.Deny, Unrestricted = true)]
76                 [ExpectedException (typeof (SecurityException))]
77                 public void DenyUnrestricted ()
78                 {
79                         IsolatedStorageFileStream isfs = new IsolatedStorageFileStream ("deny", FileMode.Create);
80                 }
81
82                 [Test]
83                 [IsolatedStorageFilePermission (SecurityAction.Deny, Unrestricted = true)]
84                 [ExpectedException (typeof (SecurityException))]
85                 public void DenyIsolatedStorageFilePermission ()
86                 {
87                         IsolatedStorageFileStream isfs = new IsolatedStorageFileStream ("deny", FileMode.Create);
88                 }
89
90                 private void Read (string filename)
91                 {
92                         byte[] buffer = new byte[8];
93                         using (IsolatedStorageFileStream read = new IsolatedStorageFileStream (filename, FileMode.Open, FileAccess.Read)) {
94                                 Assert.AreEqual (8, read.Length, "Length");
95                                 Assert.AreEqual (0, read.Position, "Position");
96                                 Assert.IsTrue (read.CanRead, "read.CanRead");
97                                 Assert.IsTrue (read.CanSeek, "read.CanSeek");
98                                 Assert.IsFalse (read.CanWrite, "read.CanWrite");
99                                 Assert.IsFalse (read.IsAsync, "read.IsAync");
100                                 Assert.AreEqual (buffer.Length, read.ReadByte (), "ReadByte");
101                                 read.Seek (0, SeekOrigin.Begin);
102                                 Assert.AreEqual (buffer.Length, read.Read (buffer, 0, buffer.Length), "Read");
103                                 read.Close ();
104                         }
105                 }
106
107                 private void Write (string filename)
108                 {
109                         byte[] buffer = new byte[8];
110                         using (IsolatedStorageFileStream write = new IsolatedStorageFileStream (filename, FileMode.Create, FileAccess.Write)) {
111                                 Assert.IsFalse (write.CanRead, "write.CanRead");
112                                 Assert.IsTrue (write.CanSeek, "write.CanSeek");
113                                 Assert.IsTrue (write.CanWrite, "write.CanWrite");
114                                 Assert.IsFalse (write.IsAsync, "write.IsAync");
115                                 write.Write (buffer, 0, buffer.Length);
116                                 write.Position = 0;
117                                 write.WriteByte ((byte)buffer.Length);
118                                 write.SetLength (8);
119                                 write.Flush ();
120                                 write.Close ();
121                         }
122                 }
123
124                 [Test]
125                 [IsolatedStorageFilePermission (SecurityAction.PermitOnly, Unrestricted = true)]
126                 [ExpectedException (typeof (FileNotFoundException))]
127                 public void ReadUnexistingFile ()
128                 {
129                         string filename = "cas-doesnt-exists";
130                         try {
131                                 Read (filename);
132                         }
133                         catch (FileNotFoundException fnfe) {
134                                 // check that we do not leak the full path to the missing file
135                                 // as we do not have the FileIOPermission's PathDiscovery rights
136                                 Assert.AreEqual (filename, fnfe.FileName, "FileName");
137                                 throw;
138                         }
139                 }
140
141                 [Test]
142                 [IsolatedStorageFilePermission (SecurityAction.PermitOnly, Unrestricted = true)]
143                 [ExpectedException (typeof (DirectoryNotFoundException))]
144                 public void ReadInUnexistingDirectory ()
145                 {
146                         string filename = Path.Combine ("unexistingdir", "filename");
147                         try {
148                                 Read (filename);
149                         }
150                         catch (DirectoryNotFoundException dnf) {
151                                 // check that we do not leak the full path to the missing file
152                                 // as we do not have the FileIOPermission's PathDiscovery rights
153                                 Assert.IsTrue (dnf.Message.IndexOf (filename) >= 0, "filename");
154                                 Assert.IsFalse (dnf.Message.IndexOf ("\\" + filename) >= 0, "fullpath");
155                                 throw;
156                         }
157                 }
158
159                 [Test]
160                 [IsolatedStorageFilePermission (SecurityAction.PermitOnly, Unrestricted = true)]
161                 [ExpectedException (typeof (UnauthorizedAccessException))]
162                 public void ReadDirectoryAsFile ()
163                 {
164                         string dirname = "this-is-a-dir";
165                         IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForDomain ();
166                         try {
167                                 string[] dirs = isf.GetDirectoryNames (dirname);
168                                 if (dirs.Length == 0) {
169                                         isf.CreateDirectory (dirname);
170                                 }
171                                 Read (dirname);
172                         }
173                         catch (UnauthorizedAccessException uae) {
174                                 // check that we do not leak the full path to the missing file
175                                 // as we do not have the FileIOPermission's PathDiscovery rights
176                                 Assert.IsTrue (uae.Message.IndexOf (dirname) >= 0, "dirname");
177                                 Assert.IsFalse (uae.Message.IndexOf ("\\" + dirname) >= 0, "fullpath");
178                                 try {
179                                         isf.DeleteDirectory (dirname);
180                                 }
181                                 catch (IsolatedStorageException) {
182                                         // this isn't where we want ot fail!
183                                         // and 1.x isn't always cooperative
184                                 }
185                                 throw;
186                         }
187                 }
188
189                 [Test]
190                 [IsolatedStorageFilePermission (SecurityAction.PermitOnly, Unrestricted = true)]
191                 public void ReWrite ()
192                 {
193                         Write ("cas-rewrite");
194                         Write ("cas-rewrite");
195                 }
196
197                 [Test]
198                 [IsolatedStorageFilePermission (SecurityAction.PermitOnly, Unrestricted = true)]
199                 public void WriteThenRead ()
200                 {
201                         Write ("cas-rw");
202                         Read ("cas-rw");
203                 }
204
205                 [Test]
206                 [IsolatedStorageFilePermission (SecurityAction.PermitOnly, Unrestricted = true)]
207                 [ExpectedException (typeof (DirectoryNotFoundException))]
208                 public void WriteInUnexistingDirectory ()
209                 {
210                         string filename = Path.Combine ("unexistingdir", "filename");
211                         try {
212                                 Write (filename);
213                         }
214                         catch (DirectoryNotFoundException dnf) {
215                                 // check that we do not leak the full path to the missing file
216                                 // as we do not have the FileIOPermission's PathDiscovery rights
217                                 Assert.IsTrue (dnf.Message.IndexOf (filename) >= 0, "filename");
218                                 Assert.IsFalse (dnf.Message.IndexOf ("\\" + filename) >= 0, "fullpath");
219                                 throw;
220                         }
221                 }
222
223                 [Test]
224                 [IsolatedStorageFilePermission (SecurityAction.PermitOnly, Unrestricted = true)]
225                 [ExpectedException (typeof (IsolatedStorageException))]
226                 public void Handle ()
227                 {
228                         IsolatedStorageFileStream isfs = new IsolatedStorageFileStream ("cas-Handle", FileMode.Create);
229                         IntPtr p = isfs.Handle;
230                         // Note: The SecurityException for UnmanagedCode cannot be tested here because it's a LinkDemand
231                 }
232 #if NET_2_0
233                 [Test]
234                 [IsolatedStorageFilePermission (SecurityAction.PermitOnly, Unrestricted = true)]
235                 [ExpectedException (typeof (IsolatedStorageException))]
236                 public void SafeFileHandle ()
237                 {
238                         IsolatedStorageFileStream isfs = new IsolatedStorageFileStream ("cas-SafeFileHandle", FileMode.Create);
239                         SafeFileHandle sfh = isfs.SafeFileHandle;
240                         // Note: The SecurityException for UnmanagedCode cannot be tested here because it's a LinkDemand
241                 }
242 #endif
243
244                 // we use reflection to call IsolatedStorageFileStream as the Handle and SafeFileHandle
245                 // properties are protected by LinkDemand (which will be converted into full demand, 
246                 // i.e. a stack walk) when reflection is used (i.e. it gets testable).
247
248                 [Test]
249                 [SecurityPermission (SecurityAction.Deny, UnmanagedCode = true)]
250                 [ExpectedException (typeof (SecurityException))]
251                 public void Handle_UnmanagedCode ()
252                 {
253                         IsolatedStorageFileStream isfs = new IsolatedStorageFileStream ("cas-Handle-Unmanaged", FileMode.Create);
254                         try {
255                                 MethodInfo mi = typeof (IsolatedStorageFileStream).GetProperty ("Handle").GetGetMethod ();
256                                 mi.Invoke (isfs, null);
257                         }
258                         finally {
259                                 isfs.Close ();
260                         }
261                 }
262 #if NET_2_0
263                 [Test]
264                 [SecurityPermission (SecurityAction.Deny, UnmanagedCode = true)]
265                 [ExpectedException (typeof (SecurityException))]
266                 public void SafeFileHandle_UnmanagedCode ()
267                 {
268                         IsolatedStorageFileStream isfs = new IsolatedStorageFileStream ("cas-SafeFileHandle-Unmanaged", FileMode.Create);
269                         try {
270                                 MethodInfo mi = typeof (IsolatedStorageFileStream).GetProperty ("SafeFileHandle").GetGetMethod ();
271                                 mi.Invoke (isfs, null);
272                         }
273                         finally {
274                                 isfs.Close ();
275                         }
276                 }
277 #endif
278
279                 // async tests (for stack propagation)
280
281                 private void ReadCallback (IAsyncResult ar)
282                 {
283                         IsolatedStorageFileStream s = (IsolatedStorageFileStream)ar.AsyncState;
284                         s.EndRead (ar);
285                         try {
286                                 // can we do something bad here ?
287                                 Assert.IsNotNull (Environment.GetEnvironmentVariable ("USERNAME"));
288                                 message = "Expected a SecurityException";
289                         }
290                         catch (SecurityException) {
291                                 message = null;
292                                 reset.Set ();
293                         }
294                         catch (Exception e) {
295                                 message = e.ToString ();
296                         }
297                 }
298
299                 [Test]
300                 [EnvironmentPermission (SecurityAction.Deny, Read = "USERNAME")]
301                 public void AsyncRead ()
302                 {
303                         IsolatedStorageFileStream isfs = new IsolatedStorageFileStream ("cas-AsyncRead", FileMode.Create);
304                         message = "AsyncRead";
305                         reset.Reset ();
306                         IAsyncResult r = isfs.BeginRead (new byte[0], 0, 0, new AsyncCallback (ReadCallback), isfs);
307                         Assert.IsNotNull (r, "IAsyncResult");
308                         if (!reset.WaitOne (timeout, true))
309                                 Assert.Ignore ("Timeout");
310                         Assert.IsNull (message, message);
311                         isfs.Close ();
312                 }
313
314                 private void WriteCallback (IAsyncResult ar)
315                 {
316                         IsolatedStorageFileStream s = (IsolatedStorageFileStream)ar.AsyncState;
317                         s.EndWrite (ar);
318                         try {
319                                 // can we do something bad here ?
320                                 Assert.IsNotNull (Environment.GetEnvironmentVariable ("USERNAME"));
321                                 message = "Expected a SecurityException";
322                         }
323                         catch (SecurityException) {
324                                 message = null;
325                                 reset.Set ();
326                         }
327                         catch (Exception e) {
328                                 message = e.ToString ();
329                         }
330                 }
331
332                 [Test]
333                 [EnvironmentPermission (SecurityAction.Deny, Read = "USERNAME")]
334                 public void AsyncWrite ()
335                 {
336                         IsolatedStorageFileStream isfs = new IsolatedStorageFileStream ("cas-AsyncWrite", FileMode.Create);
337                         message = "AsyncWrite";
338                         reset.Reset ();
339                         IAsyncResult r = isfs.BeginWrite (new byte[0], 0, 0, new AsyncCallback (WriteCallback), isfs);
340                         Assert.IsNotNull (r, "IAsyncResult");
341                         if (!reset.WaitOne (timeout, true))
342                                 Assert.Ignore ("Timeout");
343                         Assert.IsNull (message, message);
344                         isfs.Close ();
345                 }
346         }
347 }