Transaction now has limited support for PromotableSinglePhaseEnlistment
[mono.git] / mcs / class / WindowsBase / Test / System.IO.Packaging / PackageTest.cs
1 // Permission is hereby granted, free of charge, to any person obtaining\r
2 // a copy of this software and associated documentation files (the\r
3 // "Software"), to deal in the Software without restriction, including\r
4 // without limitation the rights to use, copy, modify, merge, publish,\r
5 // distribute, sublicense, and/or sell copies of the Software, and to\r
6 // permit persons to whom the Software is furnished to do so, subject to\r
7 // the following conditions:\r
8 // \r
9 // The above copyright notice and this permission notice shall be\r
10 // included in all copies or substantial portions of the Software.\r
11 // \r
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
19 //\r
20 // Copyright (c) 2008 Novell, Inc. (http://www.novell.com)\r
21 //\r
22 // Authors:\r
23 //    Alan McGovern (amcgovern@novell.com)\r
24 //\r
25 \r
26 \r
27 using System;\r
28 using System.Collections.Generic;\r
29 using System.Linq;\r
30 using System.Text;\r
31 using NUnit.Framework;\r
32 \r
33 namespace System.IO.Packaging.Tests {\r
34 \r
35     [TestFixture]\r
36     public class PackageTest : TestBase {\r
37 \r
38         //static void Main (string [] args)\r
39         //{\r
40         //    PackageTest t = new PackageTest ();\r
41         //    t.FixtureSetup ();\r
42         //    t.Setup ();\r
43         //    t.RelationshipPartGetStream ();\r
44         //}\r
45         string path = "test.package";\r
46 \r
47         public override void Setup ()\r
48         {\r
49             if (File.Exists (path))\r
50                 File.Delete (path);\r
51         }\r
52 \r
53         public override void TearDown ()\r
54         {\r
55             try {\r
56                 if (package != null)\r
57                     package.Close ();\r
58             } catch {\r
59                 // FIXME: This shouldn't be required when i implement this\r
60             }\r
61             if (File.Exists (path))\r
62                 File.Delete (path);\r
63         }\r
64 \r
65         [Test]\r
66         public void CheckContentFile ()\r
67         {\r
68             MemoryStream stream = new MemoryStream ();\r
69             package = Package.Open (stream, FileMode.Create, FileAccess.ReadWrite);\r
70             package.CreatePart (uris[0], "custom/type");\r
71             package.CreateRelationship (uris[1], TargetMode.External, "relType");\r
72 \r
73             package.Close ();\r
74             package = Package.Open (new MemoryStream (stream.ToArray ()), FileMode.Open, FileAccess.ReadWrite);\r
75             package.Close ();\r
76             package = Package.Open (new MemoryStream (stream.ToArray ()), FileMode.Open, FileAccess.ReadWrite);\r
77 \r
78             Assert.AreEqual (2, package.GetParts ().Count (), "#1");\r
79             Assert.AreEqual (1, package.GetRelationships ().Count (), "#2");\r
80         }\r
81 \r
82         [Test]\r
83         [ExpectedException (typeof (FileFormatException))]\r
84         public void CorruptStream ()\r
85         {\r
86             stream = new FakeStream (true, true, true);\r
87             stream.Write (new byte [1024], 0, 1024);\r
88             package = Package.Open (stream);\r
89         }\r
90 \r
91         [Test]\r
92         [ExpectedException (typeof (NotSupportedException))]\r
93         public void FileShareReadWrite ()\r
94         {\r
95             package = Package.Open (path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);\r
96         }\r
97 \r
98         [Test]\r
99         [ExpectedException (typeof (FileNotFoundException))]\r
100         public void OpenNonExistantPath ()\r
101         {\r
102             package = Package.Open (path, FileMode.Open);\r
103         }\r
104 \r
105         [Test]\r
106         public void NonExistantPath ()\r
107         {\r
108             package = Package.Open (path);\r
109         }\r
110 \r
111         [Test]\r
112         public void PreExistingPath ()\r
113         {\r
114             package = Package.Open (path);\r
115             package.Close ();\r
116             package = Package.Open (path);\r
117         }\r
118                 \r
119                 [Test]\r
120                 public void Close_FileStreamNotClosed ()\r
121                 {\r
122                         using (var stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.ReadWrite)) {\r
123                                 var package = Package.Open (stream, FileMode.OpenOrCreate);\r
124                                 package.CreatePart (uris [0], contentType);\r
125                                 package.Close ();\r
126                                 stream.Read (new byte [1024], 0, 1024);\r
127                         }\r
128                 }\r
129                 \r
130                 [Test]\r
131                 public void Close_MemoryStreamNotClosed ()\r
132                 {\r
133                         using (var stream = new MemoryStream ()) {\r
134                                 var package = Package.Open (stream, FileMode.OpenOrCreate);\r
135                                 package.CreatePart (uris [0], contentType);\r
136                                 package.Close ();\r
137                                 stream.Read (new byte [1024], 0, 1024);\r
138                         }\r
139                 }\r
140                 \r
141                 [Test]\r
142                 public void Close_Twice ()\r
143                 {\r
144                         var package = Package.Open (new MemoryStream (), FileMode.OpenOrCreate);\r
145                         package.Close ();\r
146                         package.Close ();\r
147                 }\r
148                 \r
149                 [Test]\r
150                 public void Dispose_Twice ()\r
151                 {\r
152                         var package = Package.Open (new MemoryStream (), FileMode.OpenOrCreate);\r
153                         ((IDisposable) package).Dispose ();\r
154                         ((IDisposable) package).Dispose ();\r
155                 }\r
156                 \r
157         [Test]\r
158         public void CreatePath ()\r
159         {\r
160             package = Package.Open (path, FileMode.Create);\r
161             Assert.AreEqual (FileAccess.ReadWrite, package.FileOpenAccess, "#1");\r
162         }\r
163 \r
164         [Test]\r
165         [ExpectedException (typeof (ArgumentException))]\r
166         public void CreatePathReadonly ()\r
167         {\r
168             package = Package.Open (path, FileMode.Create, FileAccess.Read);\r
169             package.Close ();\r
170         }\r
171 \r
172         [Test]\r
173         public void CreatePathTwice ()\r
174         {\r
175             package = Package.Open (path, FileMode.Create);\r
176             package.Close ();\r
177             package = Package.Open (path, FileMode.Open);\r
178             Assert.AreEqual (FileAccess.ReadWrite, package.FileOpenAccess);\r
179         }\r
180 \r
181         [Test]\r
182         public void OpenPackageMultipleTimes ()\r
183         {\r
184             var filename = Path.GetTempFileName ();\r
185             try {\r
186                 using (var file = File.Open (filename, FileMode.OpenOrCreate)) {\r
187                     var package = Package.Open (file, FileMode.OpenOrCreate);\r
188                     var part = package.CreatePart (new Uri ("/test", UriKind.Relative), "test/type");\r
189                     using (var stream = part.GetStream ())\r
190                         stream.Write (new byte [1024 * 1024], 0, 1024 * 1024);\r
191                     package.Close ();\r
192                 }\r
193                 \r
194                 for (int i = 0; i < 10; i++) {\r
195                     using (var file = File.Open (filename, FileMode.OpenOrCreate))\r
196                     using (var package = Package.Open (file)) {\r
197                         package.GetParts ();\r
198                         package.GetRelationships ();\r
199                     }\r
200                 }\r
201             } finally {\r
202                 if (File.Exists (filename))\r
203                     File.Delete (filename);\r
204             }\r
205         }\r
206         \r
207         [Test]\r
208         public void OpenPathReadonly ()\r
209         {\r
210             package = Package.Open (path, FileMode.Create);\r
211             package.CreatePart (uris[0], contentType);\r
212             package.CreateRelationship (uris[1], TargetMode.External, "relType");\r
213             package.Close ();\r
214             package = Package.Open (path, FileMode.Open, FileAccess.Read);\r
215             Assert.AreEqual (2, package.GetParts ().Count (), "#1");\r
216             Assert.AreEqual (1, package.GetRelationships ().Count (), "#2");\r
217             Assert.AreEqual (FileAccess.Read, package.FileOpenAccess, "Should be read access");\r
218             try {\r
219                 package.CreatePart (uris [0], contentType);\r
220                 Assert.Fail ("Cannot modify a read-only package");\r
221             } catch (IOException) {\r
222 \r
223             }\r
224 \r
225             try {\r
226                 package.CreateRelationship (uris [0], TargetMode.Internal, contentType);\r
227                 Assert.Fail ("Cannot modify a read-only package");\r
228             } catch (IOException) {\r
229 \r
230             }\r
231 \r
232             try {\r
233                 package.DeletePart (uris [0]);\r
234                 Assert.Fail ("Cannot modify a read-only package");\r
235             } catch (IOException) {\r
236 \r
237             }\r
238 \r
239             try {\r
240                 package.DeleteRelationship (contentType);\r
241                 Assert.Fail ("Cannot modify a read-only package");\r
242             } catch (IOException) {\r
243 \r
244             }\r
245         }\r
246 \r
247         [Test]\r
248         [ExpectedException (typeof (ArgumentException))]\r
249         public void ReadableStream ()\r
250         {\r
251             stream = new FakeStream (true, false, false);\r
252             package = Package.Open (stream);\r
253         }\r
254 \r
255         [Test]\r
256         [ExpectedException (typeof (FileFormatException))]\r
257         public void ReadableSeekableStream ()\r
258         {\r
259             stream = new FakeStream (true, false, true);\r
260             package = Package.Open (stream);\r
261 \r
262             try {\r
263                 package.DeleteRelationship (contentType);\r
264                 Assert.Fail ("Cannot modify a read-only package");\r
265             } catch (IOException) {\r
266 \r
267             }\r
268         }\r
269 \r
270         [Test]\r
271         [ExpectedException (typeof (FileFormatException))]\r
272         public void ReadableSeekableFullStream ()\r
273         {\r
274             stream = new FakeStream (true, false, true);\r
275             stream.Write (new byte [10], 0, 10);\r
276             package = Package.Open (stream);\r
277         }\r
278 \r
279         [Test]\r
280         [ExpectedException (typeof (ArgumentException))]\r
281         public void ReadOnlyAccess ()\r
282         {\r
283             stream = new FakeStream (true, false, true);\r
284             package = Package.Open (path, FileMode.CreateNew, FileAccess.Read);\r
285 \r
286             try {\r
287                 package.DeleteRelationship (contentType);\r
288                 Assert.Fail ("Cannot modify a read-only package");\r
289             } catch (IOException) {\r
290 \r
291             }\r
292         }\r
293 \r
294         [Test]\r
295         [Category ("NotWorking")]\r
296         [Ignore ("I'm not supposed to write to the relation stream unless i'm flushing")]\r
297         public void RelationshipPartGetStream ()\r
298         {\r
299             package = Package.Open (path);\r
300             package.CreateRelationship (uris [0], TargetMode.External, "rel");\r
301             PackagePart p = package.GetPart (relationshipUri);\r
302             Assert.IsNotNull (p, "#0");\r
303             Stream s = p.GetStream ();\r
304             Assert.AreEqual (0, s.Length, "#1");\r
305             Assert.IsTrue (s.CanRead, "#2");\r
306             Assert.IsTrue (s.CanSeek, "#3");\r
307             Assert.IsFalse (s.CanTimeout, "#4");\r
308             Assert.IsTrue (s.CanWrite, "#5");\r
309         }\r
310 \r
311         [Test]\r
312         [ExpectedException (typeof (IOException))]\r
313         public void SetFileModeOnUnwriteableStream ()\r
314         {\r
315             stream = new FakeStream (true, false, true);\r
316             package = Package.Open (stream, FileMode.Truncate);\r
317         }\r
318 \r
319         [Test]\r
320         [ExpectedException (typeof (NotSupportedException))]\r
321         public void SetAppendOnWriteableStream ()\r
322         {\r
323             stream = new FakeStream (true, true, true);\r
324             package = Package.Open (stream, FileMode.Append);\r
325         }\r
326 \r
327         [Test]\r
328         public void SetCreateNewOnWriteableStream ()\r
329         {\r
330             package = Package.Open (stream, FileMode.CreateNew);\r
331         }\r
332 \r
333         [Test]\r
334         [ExpectedException(typeof(IOException))]\r
335         public void SetCreateNewOnWriteableStream2 ()\r
336         {\r
337             stream = new FakeStream (true, true, true);\r
338             stream.Write (new byte [1000], 0, 1000);\r
339             package = Package.Open (stream, FileMode.CreateNew);\r
340             Assert.AreEqual (0, stream.Length, "#1");\r
341         }\r
342 \r
343         [Test]\r
344         public void SetCreateOnWriteableStream ()\r
345         {\r
346             stream = new FakeStream (true, true, true);\r
347             package = Package.Open (stream, FileMode.Create);\r
348         }\r
349 \r
350         [Test]\r
351         [ExpectedException (typeof (FileFormatException))]\r
352         public void SetOpenOnWriteableStream ()\r
353         {\r
354             stream = new FakeStream (true, true, true);\r
355             package = Package.Open (stream, FileMode.Open);\r
356         }\r
357 \r
358         [Test]\r
359         public void SetOpenOrCreateOnWriteableStream ()\r
360         {\r
361             stream = new FakeStream (true, true, true);\r
362             package = Package.Open (stream, FileMode.OpenOrCreate);\r
363         }\r
364 \r
365         [Test]\r
366         [ExpectedException (typeof (NotSupportedException))]\r
367         public void SetTruncateOnWriteableStream ()\r
368         {\r
369             stream = new FakeStream (true, true, true);\r
370             package = Package.Open (stream, FileMode.Truncate);\r
371         }\r
372 \r
373         [Test]\r
374         [ExpectedException (typeof (NotSupportedException))]\r
375         public void SetTruncateOnWriteablePath ()\r
376         {\r
377             stream = new FakeStream (true, true, true);\r
378             File.Create (path).Close ();\r
379             package = Package.Open (path, FileMode.Truncate);\r
380         }\r
381 \r
382         [Test]\r
383         [ExpectedException (typeof (FileFormatException))]\r
384         public void StreamOpen ()\r
385         {\r
386             stream = new FakeStream (true, true, true);\r
387             package = Package.Open (stream, FileMode.Open);\r
388         }\r
389 \r
390         [Test]\r
391         public void StreamCreate ()\r
392         {\r
393             stream = new FakeStream (true, true, true);\r
394             package = Package.Open (stream, FileMode.Create);\r
395         }\r
396 \r
397         [Test]\r
398         [ExpectedException (typeof (IOException))]\r
399         public void UnusableStream ()\r
400         {\r
401             stream = new FakeStream (false, false, false);\r
402             package = Package.Open (stream);\r
403         }\r
404 \r
405         // Bug - I'm passing in FileAccess.Write but it thinks I've passed FileAccess.Read\r
406         [Test]\r
407         [ExpectedException (typeof (ArgumentException))]\r
408         public void WriteAccessDoesntExist ()\r
409         {\r
410             package = Package.Open (path, FileMode.OpenOrCreate, FileAccess.Write);\r
411         }\r
412 \r
413         [Test]\r
414         public void ReadWriteAccessDoesntExist ()\r
415         {\r
416             package = Package.Open (path, FileMode.OpenOrCreate, FileAccess.ReadWrite);\r
417         }\r
418 \r
419         [Test]\r
420         [ExpectedException (typeof (FileFormatException))]\r
421         public void WriteOnlyAccessExists ()\r
422         {\r
423             System.IO.File.Create (path).Close ();\r
424             package = Package.Open (path, FileMode.OpenOrCreate, FileAccess.Write);\r
425         }\r
426     }\r
427 }