Merge pull request #3036 from tritao/windowsbase_zip_datetime
[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.IO;\r
30 using System.IO.Compression;\r
31 using System.IO.Packaging;\r
32 using System.Linq;\r
33 using System.Text;\r
34 using NUnit.Framework;\r
35 \r
36 namespace MonoTests.System.IO.Packaging {\r
37 \r
38     [TestFixture]\r
39     public class PackageTest : TestBase {\r
40 \r
41         //static void Main (string [] args)\r
42         //{\r
43         //    PackageTest t = new PackageTest ();\r
44         //    t.FixtureSetup ();\r
45         //    t.Setup ();\r
46         //    t.RelationshipPartGetStream ();\r
47         //}\r
48         string path = "test.package";\r
49 \r
50         public override void Setup ()\r
51         {\r
52             if (File.Exists (path))\r
53                 File.Delete (path);\r
54         }\r
55 \r
56         public override void TearDown ()\r
57         {\r
58             try {\r
59                 if (package != null)\r
60                     package.Close ();\r
61             } catch {\r
62                 // FIXME: This shouldn't be required when i implement this\r
63             }\r
64             if (File.Exists (path))\r
65                 File.Delete (path);\r
66         }\r
67 \r
68         [Test]\r
69         public void CheckContentFile ()\r
70         {\r
71             MemoryStream stream = new MemoryStream ();\r
72             package = Package.Open (stream, FileMode.Create, FileAccess.ReadWrite);\r
73             package.CreatePart (uris[0], "custom/type");\r
74             package.CreateRelationship (uris[1], TargetMode.External, "relType");\r
75 \r
76             package.Close ();\r
77             package = Package.Open (new MemoryStream (stream.ToArray ()), FileMode.Open, FileAccess.ReadWrite);\r
78             package.Close ();\r
79             package = Package.Open (new MemoryStream (stream.ToArray ()), FileMode.Open, FileAccess.ReadWrite);\r
80 \r
81             Assert.AreEqual (2, package.GetParts ().Count (), "#1");\r
82             Assert.AreEqual (1, package.GetRelationships ().Count (), "#2");\r
83         }\r
84 \r
85         [Test]\r
86         [ExpectedException (typeof (FileFormatException))]\r
87         public void CorruptStream ()\r
88         {\r
89             stream = new FakeStream (true, true, true);\r
90             stream.Write (new byte [1024], 0, 1024);\r
91             package = Package.Open (stream);\r
92         }\r
93 \r
94         [Test]\r
95         [ExpectedException (typeof (NotSupportedException))]\r
96         public void FileShareReadWrite ()\r
97         {\r
98             package = Package.Open (path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);\r
99         }\r
100 \r
101         [Test]\r
102         [ExpectedException (typeof (FileNotFoundException))]\r
103         public void OpenNonExistantPath ()\r
104         {\r
105             package = Package.Open (path, FileMode.Open);\r
106         }\r
107 \r
108         [Test]\r
109         public void NonExistantPath ()\r
110         {\r
111             package = Package.Open (path);\r
112         }\r
113 \r
114         [Test]\r
115         public void PreExistingPath ()\r
116         {\r
117             package = Package.Open (path);\r
118             package.Close ();\r
119             package = Package.Open (path);\r
120         } \r
121                 \r
122                 [Test]\r
123                 public void Close_FileStreamNotClosed ()\r
124                 {\r
125                         using (var stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.ReadWrite)) {\r
126                                 var package = Package.Open (stream, FileMode.OpenOrCreate);\r
127                                 package.CreatePart (uris [0], contentType);\r
128                                 package.Close ();\r
129                                 stream.Read (new byte [1024], 0, 1024);\r
130                         }\r
131                 }\r
132                 \r
133                 [Test]\r
134                 public void Close_MemoryStreamNotClosed ()\r
135                 {\r
136                         using (var stream = new MemoryStream ()) {\r
137                                 var package = Package.Open (stream, FileMode.OpenOrCreate);\r
138                                 package.CreatePart (uris [0], contentType);\r
139                                 package.Close ();\r
140                                 stream.Read (new byte [1024], 0, 1024);\r
141                         }\r
142                 }\r
143                 \r
144                 [Test]\r
145                 public void Close_Twice ()\r
146                 {\r
147                         var package = Package.Open (new MemoryStream (), FileMode.OpenOrCreate);\r
148                         package.Close ();\r
149                         package.Close ();\r
150                 }\r
151                 \r
152                 [Test]\r
153                 public void Dispose_Twice ()\r
154                 {\r
155                         var package = Package.Open (new MemoryStream (), FileMode.OpenOrCreate);\r
156                         ((IDisposable) package).Dispose ();\r
157                         ((IDisposable) package).Dispose ();\r
158                 }\r
159                 \r
160         [Test]\r
161         public void CreatePath ()\r
162         {\r
163             package = Package.Open (path, FileMode.Create);\r
164             Assert.AreEqual (FileAccess.ReadWrite, package.FileOpenAccess, "#1");\r
165         }\r
166 \r
167         [Test]\r
168         [ExpectedException (typeof (ArgumentException))]\r
169         public void CreatePathReadonly ()\r
170         {\r
171             package = Package.Open (path, FileMode.Create, FileAccess.Read);\r
172             package.Close ();\r
173         }\r
174 \r
175         [Test]\r
176         public void CreatePathTwice ()\r
177         {\r
178             package = Package.Open (path, FileMode.Create);\r
179             package.Close ();\r
180             package = Package.Open (path, FileMode.Open);\r
181             Assert.AreEqual (FileAccess.ReadWrite, package.FileOpenAccess);\r
182         }\r
183 \r
184         [Test]\r
185         public void OpenPackageMultipleTimes ()\r
186         {\r
187             var filename = Path.GetTempFileName ();\r
188             try {\r
189                 using (var file = File.Open (filename, FileMode.OpenOrCreate)) {\r
190                     var package = Package.Open (file, FileMode.OpenOrCreate);\r
191                     var part = package.CreatePart (new Uri ("/test", UriKind.Relative), "test/type");\r
192                     using (var stream = part.GetStream ())\r
193                         stream.Write (new byte [1024 * 1024], 0, 1024 * 1024);\r
194                     package.Close ();\r
195                 }\r
196                 \r
197                 for (int i = 0; i < 10; i++) {\r
198                     using (var file = File.Open (filename, FileMode.OpenOrCreate))\r
199                     using (var package = Package.Open (file)) {\r
200                         package.GetParts ();\r
201                         package.GetRelationships ();\r
202                     }\r
203                 }\r
204             } finally {\r
205                 if (File.Exists (filename))\r
206                     File.Delete (filename);\r
207             }\r
208         }\r
209         \r
210         [Test]\r
211         public void OpenPathReadonly ()\r
212         {\r
213             package = Package.Open (path, FileMode.Create);\r
214             package.CreatePart (uris[0], contentType);\r
215             package.CreateRelationship (uris[1], TargetMode.External, "relType");\r
216             package.Close ();\r
217             package = Package.Open (path, FileMode.Open, FileAccess.Read);\r
218             Assert.AreEqual (2, package.GetParts ().Count (), "#1");\r
219             Assert.AreEqual (1, package.GetRelationships ().Count (), "#2");\r
220             Assert.AreEqual (FileAccess.Read, package.FileOpenAccess, "Should be read access");\r
221             try {\r
222                 package.CreatePart (uris [0], contentType);\r
223                 Assert.Fail ("Cannot modify a read-only package");\r
224             } catch (IOException) {\r
225 \r
226             }\r
227 \r
228             try {\r
229                 package.CreateRelationship (uris [0], TargetMode.Internal, contentType);\r
230                 Assert.Fail ("Cannot modify a read-only package");\r
231             } catch (IOException) {\r
232 \r
233             }\r
234 \r
235             try {\r
236                 package.DeletePart (uris [0]);\r
237                 Assert.Fail ("Cannot modify a read-only package");\r
238             } catch (IOException) {\r
239 \r
240             }\r
241 \r
242             try {\r
243                 package.DeleteRelationship (contentType);\r
244                 Assert.Fail ("Cannot modify a read-only package");\r
245             } catch (IOException) {\r
246 \r
247             }\r
248         }\r
249 \r
250         [Test]\r
251         [ExpectedException (typeof (ArgumentException))]\r
252         public void ReadableStream ()\r
253         {\r
254             stream = new FakeStream (true, false, false);\r
255             package = Package.Open (stream);\r
256         }\r
257 \r
258         [Test]\r
259         [ExpectedException (typeof (FileFormatException))]\r
260         public void ReadableSeekableStream ()\r
261         {\r
262             stream = new FakeStream (true, false, true);\r
263             package = Package.Open (stream);\r
264 \r
265             try {\r
266                 package.DeleteRelationship (contentType);\r
267                 Assert.Fail ("Cannot modify a read-only package");\r
268             } catch (IOException) {\r
269 \r
270             }\r
271         }\r
272 \r
273         [Test]\r
274         [ExpectedException (typeof (ArgumentException))]\r
275         public void ReadOnlyAccess ()\r
276         {\r
277             stream = new FakeStream (true, false, true);\r
278             package = Package.Open (path, FileMode.CreateNew, FileAccess.Read);\r
279 \r
280             try {\r
281                 package.DeleteRelationship (contentType);\r
282                 Assert.Fail ("Cannot modify a read-only package");\r
283             } catch (IOException) {\r
284 \r
285             }\r
286         }\r
287 \r
288         [Test]\r
289         [Category ("NotWorking")]\r
290         [Ignore ("I'm not supposed to write to the relation stream unless i'm flushing")]\r
291         public void RelationshipPartGetStream ()\r
292         {\r
293             package = Package.Open (path);\r
294             package.CreateRelationship (uris [0], TargetMode.External, "rel");\r
295             PackagePart p = package.GetPart (relationshipUri);\r
296             Assert.IsNotNull (p, "#0");\r
297             Stream s = p.GetStream ();\r
298             Assert.AreEqual (0, s.Length, "#1");\r
299             Assert.IsTrue (s.CanRead, "#2");\r
300             Assert.IsTrue (s.CanSeek, "#3");\r
301             Assert.IsFalse (s.CanTimeout, "#4");\r
302             Assert.IsTrue (s.CanWrite, "#5");\r
303         }\r
304 \r
305         [Test]\r
306         [ExpectedException (typeof (IOException))]\r
307         public void SetFileModeOnUnwriteableStream ()\r
308         {\r
309             stream = new FakeStream (true, false, true);\r
310             package = Package.Open (stream, FileMode.Truncate);\r
311         }\r
312 \r
313         [Test]\r
314         [ExpectedException (typeof (NotSupportedException))]\r
315         public void SetAppendOnWriteableStream ()\r
316         {\r
317             stream = new FakeStream (true, true, true);\r
318             package = Package.Open (stream, FileMode.Append);\r
319         }\r
320 \r
321         [Test]\r
322         public void SetCreateNewOnWriteableStream ()\r
323         {\r
324             package = Package.Open (stream, FileMode.CreateNew);\r
325         }\r
326 \r
327         [Test]\r
328         [ExpectedException(typeof(IOException))]\r
329         public void SetCreateNewOnWriteableStream2 ()\r
330         {\r
331             stream = new FakeStream (true, true, true);\r
332             stream.Write (new byte [1000], 0, 1000);\r
333             package = Package.Open (stream, FileMode.CreateNew);\r
334             Assert.AreEqual (0, stream.Length, "#1");\r
335         }\r
336 \r
337         [Test]\r
338         public void SetCreateOnWriteableStream ()\r
339         {\r
340             stream = new FakeStream (true, true, true);\r
341             package = Package.Open (stream, FileMode.Create);\r
342         }\r
343 \r
344         [Test]\r
345         [ExpectedException (typeof (FileFormatException))]\r
346         public void SetOpenOnWriteableStream ()\r
347         {\r
348             stream = new FakeStream (true, true, true);\r
349             package = Package.Open (stream, FileMode.Open);\r
350         }\r
351 \r
352         [Test]\r
353         public void SetOpenOrCreateOnWriteableStream ()\r
354         {\r
355             stream = new FakeStream (true, true, true);\r
356             package = Package.Open (stream, FileMode.OpenOrCreate);\r
357         }\r
358 \r
359         [Test]\r
360         [ExpectedException (typeof (NotSupportedException))]\r
361         public void SetTruncateOnWriteableStream ()\r
362         {\r
363             stream = new FakeStream (true, true, true);\r
364             package = Package.Open (stream, FileMode.Truncate);\r
365         }\r
366 \r
367         [Test]\r
368         [ExpectedException (typeof (NotSupportedException))]\r
369         public void SetTruncateOnWriteablePath ()\r
370         {\r
371             stream = new FakeStream (true, true, true);\r
372             File.Create (path).Close ();\r
373             package = Package.Open (path, FileMode.Truncate);\r
374         }\r
375 \r
376         [Test]\r
377         [ExpectedException (typeof (FileFormatException))]\r
378         public void StreamOpen ()\r
379         {\r
380             stream = new FakeStream (true, true, true);\r
381             package = Package.Open (stream, FileMode.Open);\r
382         }\r
383 \r
384         [Test]\r
385         public void StreamCreate ()\r
386         {\r
387             stream = new FakeStream (true, true, true);\r
388             package = Package.Open (stream, FileMode.Create);\r
389         }\r
390 \r
391         [Test]\r
392         [ExpectedException (typeof (IOException))]\r
393         public void UnusableStream ()\r
394         {\r
395             stream = new FakeStream (false, false, false);\r
396             package = Package.Open (stream);\r
397         }\r
398 \r
399         // Bug - I'm passing in FileAccess.Write but it thinks I've passed FileAccess.Read\r
400         [Test]\r
401         [ExpectedException (typeof (ArgumentException))]\r
402         public void WriteAccessDoesntExist ()\r
403         {\r
404             package = Package.Open (path, FileMode.OpenOrCreate, FileAccess.Write);\r
405         }\r
406 \r
407         [Test]\r
408         public void ReadWriteAccessDoesntExist ()\r
409         {\r
410             package = Package.Open (path, FileMode.OpenOrCreate, FileAccess.ReadWrite);\r
411         }\r
412 \r
413         [Test]\r
414         [ExpectedException (typeof (FileFormatException))]\r
415         public void WriteOnlyAccessExists ()\r
416         {\r
417             File.Create (path).Close ();\r
418             package = Package.Open (path, FileMode.OpenOrCreate, FileAccess.Write);\r
419         }\r
420 \r
421         [Test]\r
422         public void Check_ZipDateTime ()\r
423         {\r
424             using (var zipStream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.ReadWrite))\r
425             using (package = Package.Open (zipStream, FileMode.OpenOrCreate)) {\r
426                 var part = package.CreatePart (new Uri ("/test", UriKind.Relative), "test/type");\r
427                 using (var stream = part.GetStream ())\r
428                     stream.Write (new byte [1024 * 1024], 0, 1024 * 1024);\r
429             }\r
430 \r
431             using (var stream = new FileStream (path, FileMode.Open, FileAccess.Read))\r
432             using (var archive = new ZipArchive(stream))\r
433             {                \r
434                 foreach (var entry in archive.Entries)\r
435                     Assert.AreEqual (entry.LastWriteTime.Year, DateTime.Now.Year);\r
436             }\r
437         }           \r
438     }\r
439 }\r