summaryrefslogtreecommitdiff
path: root/src/dtf/test/WixToolsetTests.Dtf.Compression.Cab/CabTest.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/dtf/test/WixToolsetTests.Dtf.Compression.Cab/CabTest.cs')
-rw-r--r--src/dtf/test/WixToolsetTests.Dtf.Compression.Cab/CabTest.cs1165
1 files changed, 1165 insertions, 0 deletions
diff --git a/src/dtf/test/WixToolsetTests.Dtf.Compression.Cab/CabTest.cs b/src/dtf/test/WixToolsetTests.Dtf.Compression.Cab/CabTest.cs
new file mode 100644
index 00000000..981ecc69
--- /dev/null
+++ b/src/dtf/test/WixToolsetTests.Dtf.Compression.Cab/CabTest.cs
@@ -0,0 +1,1165 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Dtf.Test
4{
5 using System;
6 using System.IO;
7 using System.Text;
8 using System.Threading;
9 using System.Collections.Generic;
10 using System.Runtime.Serialization;
11 using System.Runtime.Serialization.Formatters.Binary;
12 using Microsoft.VisualStudio.TestTools.UnitTesting;
13 using WixToolset.Dtf.Compression;
14 using WixToolset.Dtf.Compression.Cab;
15
16 [TestClass]
17 public class CabTest
18 {
19 public CabTest()
20 {
21 }
22
23 [TestInitialize]
24 public void Initialize()
25 {
26 }
27
28 [TestCleanup]
29 public void Cleanup()
30 {
31 }
32
33 [TestMethod]
34 public void CabinetMultithread()
35 {
36 this.multithreadExceptions = new List<Exception>();
37
38 const int threadCount = 10;
39 IList<Thread> threads = new List<Thread>(threadCount);
40
41 for (int i = 0; i < threadCount; i++)
42 {
43 Thread thread = new Thread(new ThreadStart(this.CabinetMultithreadWorker));
44 thread.Name = "CabinetMultithreadWorker_" + i;
45 threads.Add(thread);
46 }
47
48 foreach (Thread thread in threads)
49 {
50 thread.Start();
51 }
52
53 foreach (Thread thread in threads)
54 {
55 thread.Join();
56 }
57
58 foreach (Exception ex in this.multithreadExceptions)
59 {
60 Console.WriteLine();
61 Console.WriteLine(ex);
62 }
63 Assert.AreEqual<int>(0, this.multithreadExceptions.Count);
64 }
65
66 private IList<Exception> multithreadExceptions;
67
68 private void CabinetMultithreadWorker()
69 {
70 try
71 {
72 string threadName = Thread.CurrentThread.Name;
73 int threadNumber = Int32.Parse(threadName.Substring(threadName.IndexOf('_') + 1));
74 this.RunCabinetPackUnpack(100, 10240 + threadNumber, 0, 0, CompressionLevel.Normal);
75 }
76 catch (Exception ex)
77 {
78 this.multithreadExceptions.Add(ex);
79 }
80 }
81
82 [TestMethod]
83 public void CabinetFileCounts()
84 {
85 this.RunCabinetPackUnpack(0, 10, 0, 0, CompressionLevel.Normal);
86 this.RunCabinetPackUnpack(1, 10, 0, 0, CompressionLevel.Normal);
87 this.RunCabinetPackUnpack(100, 10, 0, 0, CompressionLevel.Normal);
88 }
89
90 [TestMethod]
91 [Ignore] // Takes ~5 minutes and 66000 is over the 65535 limit anyway.
92 public void CabinetExtremeFileCounts()
93 {
94 this.RunCabinetPackUnpack(66000, 10);
95 }
96
97 [TestMethod]
98 public void CabinetFileSizes()
99 {
100 this.RunCabinetPackUnpack(1, 0, 0, 0, CompressionLevel.Normal);
101 this.RunCabinetPackUnpack(1, 1, 0, 0, CompressionLevel.Normal);
102 this.RunCabinetPackUnpack(1, 2, 0, 0, CompressionLevel.Normal);
103 this.RunCabinetPackUnpack(1, 3, 0, 0, CompressionLevel.Normal);
104 this.RunCabinetPackUnpack(1, 4, 0, 0, CompressionLevel.Normal);
105 this.RunCabinetPackUnpack(1, 5, 0, 0, CompressionLevel.Normal);
106 this.RunCabinetPackUnpack(1, 6, 0, 0, CompressionLevel.Normal);
107 // Skip file sizes 7-9: see "buggy" file sizes test below.
108 this.RunCabinetPackUnpack(1, 10, 0, 0, CompressionLevel.Normal);
109 this.RunCabinetPackUnpack(1, 11, 0, 0, CompressionLevel.Normal);
110 this.RunCabinetPackUnpack(1, 12, 0, 0, CompressionLevel.Normal);
111 this.RunCabinetPackUnpack(1, 100 * 1024, 0, 0, CompressionLevel.Normal);
112 this.RunCabinetPackUnpack(1, 10 * 1024 * 1024, 0, 0, CompressionLevel.Normal);
113 }
114
115 [TestMethod]
116 public void CabinetBuggyFileSizes()
117 {
118 // Windows' cabinet.dll has a known bug (#55001 in Windows OS Bugs)
119 // LZX compression causes an AV with file sizes of 7, 8, or 9 bytes.
120 try
121 {
122 this.RunCabinetPackUnpack(1, 7, 0, 0, CompressionLevel.Normal);
123 this.RunCabinetPackUnpack(1, 8, 0, 0, CompressionLevel.Normal);
124 this.RunCabinetPackUnpack(1, 9, 0, 0, CompressionLevel.Normal);
125 }
126 catch (AccessViolationException)
127 {
128 Assert.Fail("Known 7,8,9 file size bug detected in Windows' cabinet.dll.");
129 }
130 }
131
132 [Timeout(36000000), TestMethod]
133 [Ignore] // Takes too long to run regularly.
134 public void CabinetExtremeFileSizes()
135 {
136 this.RunCabinetPackUnpack(10, 512L * 1024 * 1024); // 5GB
137 //this.RunCabinetPackUnpack(1, 5L * 1024 * 1024 * 1024); // 5GB
138 }
139
140 [TestMethod]
141 public void CabinetFolders()
142 {
143 this.RunCabinetPackUnpack(0, 10, 1, 0, CompressionLevel.Normal);
144 this.RunCabinetPackUnpack(1, 10, 1, 0, CompressionLevel.Normal);
145 this.RunCabinetPackUnpack(100, 10, 1, 0, CompressionLevel.Normal);
146
147 IList<ArchiveFileInfo> fileInfo;
148 fileInfo = this.RunCabinetPackUnpack(7, 100 * 1024, 250 * 1024, 0, CompressionLevel.None);
149 Assert.AreEqual<int>(2, ((CabFileInfo) fileInfo[fileInfo.Count - 1]).CabinetFolderNumber,
150 "Testing whether cabinet has the correct # of folders.");
151
152 fileInfo = this.RunCabinetPackUnpack(10, 100 * 1024, 250 * 1024, 0, CompressionLevel.None);
153 Assert.AreEqual<int>(3, ((CabFileInfo) fileInfo[fileInfo.Count - 1]).CabinetFolderNumber,
154 "Testing whether cabinet has the correct # of folders.");
155
156 fileInfo = this.RunCabinetPackUnpack(2, 100 * 1024, 40 * 1024, 0, CompressionLevel.None);
157 Assert.AreEqual<int>(1, ((CabFileInfo) fileInfo[fileInfo.Count - 1]).CabinetFolderNumber,
158 "Testing whether cabinet has the correct # of folders.");
159 }
160
161 [TestMethod]
162 public void CabinetArchiveCounts()
163 {
164 IList<ArchiveFileInfo> fileInfo;
165 fileInfo = this.RunCabinetPackUnpack(10, 100 * 1024, 0, 400 * 1024, CompressionLevel.None);
166 Assert.AreEqual<int>(2, fileInfo[fileInfo.Count - 1].ArchiveNumber,
167 "Testing whether archive spans the correct # of cab files.");
168
169 fileInfo = this.RunCabinetPackUnpack(2, 90 * 1024, 0, 40 * 1024, CompressionLevel.None);
170 Assert.AreEqual<int>(2, fileInfo[fileInfo.Count - 1].ArchiveNumber,
171 "Testing whether archive spans the correct # of cab files.");
172 }
173
174 [TestMethod]
175 public void CabinetProgress()
176 {
177 CompressionTestUtil.ExpectedProgress = new List<int[]>(new int[][] {
178 // StatusType, CurFile,TotalFiles,CurFolder,CurCab,TotalCabs
179 new int[] { (int) ArchiveProgressType.StartFile, 0, 15, 0, 0, 1 },
180 new int[] { (int) ArchiveProgressType.FinishFile, 0, 15, 0, 0, 1 },
181 new int[] { (int) ArchiveProgressType.StartFile, 1, 15, 0, 0, 1 },
182 new int[] { (int) ArchiveProgressType.FinishFile, 1, 15, 0, 0, 1 },
183 new int[] { (int) ArchiveProgressType.StartFile, 2, 15, 1, 0, 1 },
184 new int[] { (int) ArchiveProgressType.FinishFile, 2, 15, 1, 0, 1 },
185 new int[] { (int) ArchiveProgressType.StartFile, 3, 15, 1, 0, 1 },
186 new int[] { (int) ArchiveProgressType.FinishFile, 3, 15, 1, 0, 1 },
187 new int[] { (int) ArchiveProgressType.StartFile, 4, 15, 2, 0, 1 },
188 new int[] { (int) ArchiveProgressType.FinishFile, 4, 15, 2, 0, 1 },
189 new int[] { (int) ArchiveProgressType.StartFile, 5, 15, 2, 0, 1 },
190 new int[] { (int) ArchiveProgressType.FinishFile, 5, 15, 2, 0, 1 },
191 new int[] { (int) ArchiveProgressType.StartFile, 6, 15, 3, 0, 1 },
192 new int[] { (int) ArchiveProgressType.FinishFile, 6, 15, 3, 0, 1 },
193 new int[] { (int) ArchiveProgressType.StartFile, 7, 15, 3, 0, 1 },
194 new int[] { (int) ArchiveProgressType.FinishFile, 7, 15, 3, 0, 1 },
195 new int[] { (int) ArchiveProgressType.StartArchive, 7, 15, 3, 0, 1 },
196 new int[] { (int) ArchiveProgressType.FinishArchive, 7, 15, 3, 0, 1 },
197 new int[] { (int) ArchiveProgressType.StartFile, 8, 15, 4, 1, 2 },
198 new int[] { (int) ArchiveProgressType.FinishFile, 8, 15, 4, 1, 2 },
199 new int[] { (int) ArchiveProgressType.StartFile, 9, 15, 4, 1, 2 },
200 new int[] { (int) ArchiveProgressType.FinishFile, 9, 15, 4, 1, 2 },
201 new int[] { (int) ArchiveProgressType.StartFile, 10, 15, 5, 1, 2 },
202 new int[] { (int) ArchiveProgressType.FinishFile, 10, 15, 5, 1, 2 },
203 new int[] { (int) ArchiveProgressType.StartFile, 11, 15, 5, 1, 2 },
204 new int[] { (int) ArchiveProgressType.FinishFile, 11, 15, 5, 1, 2 },
205 new int[] { (int) ArchiveProgressType.StartFile, 12, 15, 6, 1, 2 },
206 new int[] { (int) ArchiveProgressType.FinishFile, 12, 15, 6, 1, 2 },
207 new int[] { (int) ArchiveProgressType.StartFile, 13, 15, 6, 1, 2 },
208 new int[] { (int) ArchiveProgressType.FinishFile, 13, 15, 6, 1, 2 },
209 new int[] { (int) ArchiveProgressType.StartArchive, 13, 15, 6, 1, 2 },
210 new int[] { (int) ArchiveProgressType.FinishArchive, 13, 15, 6, 1, 2 },
211 new int[] { (int) ArchiveProgressType.StartFile, 14, 15, 7, 2, 3 },
212 new int[] { (int) ArchiveProgressType.FinishFile, 14, 15, 7, 2, 3 },
213 new int[] { (int) ArchiveProgressType.StartArchive, 14, 15, 7, 2, 3 },
214 new int[] { (int) ArchiveProgressType.FinishArchive, 14, 15, 7, 2, 3 },
215 // StatusType, CurFile,TotalFiles,CurFolder,CurCab,TotalCabs
216 new int[] { (int) ArchiveProgressType.StartArchive, 0, 15, 0, 0, 3 },
217 new int[] { (int) ArchiveProgressType.StartFile, 0, 15, 0, 0, 3 },
218 new int[] { (int) ArchiveProgressType.FinishFile, 0, 15, 0, 0, 3 },
219 new int[] { (int) ArchiveProgressType.StartFile, 1, 15, 0, 0, 3 },
220 new int[] { (int) ArchiveProgressType.FinishFile, 1, 15, 0, 0, 3 },
221 new int[] { (int) ArchiveProgressType.StartFile, 2, 15, 1, 0, 3 },
222 new int[] { (int) ArchiveProgressType.FinishFile, 2, 15, 1, 0, 3 },
223 new int[] { (int) ArchiveProgressType.StartFile, 3, 15, 1, 0, 3 },
224 new int[] { (int) ArchiveProgressType.FinishFile, 3, 15, 1, 0, 3 },
225 new int[] { (int) ArchiveProgressType.StartFile, 4, 15, 2, 0, 3 },
226 new int[] { (int) ArchiveProgressType.FinishFile, 4, 15, 2, 0, 3 },
227 new int[] { (int) ArchiveProgressType.StartFile, 5, 15, 2, 0, 3 },
228 new int[] { (int) ArchiveProgressType.FinishFile, 5, 15, 2, 0, 3 },
229 new int[] { (int) ArchiveProgressType.StartFile, 6, 15, 3, 0, 3 },
230 new int[] { (int) ArchiveProgressType.FinishArchive, 6, 15, 3, 0, 3 },
231 new int[] { (int) ArchiveProgressType.StartArchive, 6, 15, 3, 1, 3 },
232 new int[] { (int) ArchiveProgressType.FinishFile, 6, 15, 3, 1, 3 },
233 new int[] { (int) ArchiveProgressType.StartFile, 7, 15, 3, 1, 3 },
234 new int[] { (int) ArchiveProgressType.FinishFile, 7, 15, 3, 1, 3 },
235 new int[] { (int) ArchiveProgressType.StartFile, 8, 15, 4, 1, 3 },
236 new int[] { (int) ArchiveProgressType.FinishFile, 8, 15, 4, 1, 3 },
237 new int[] { (int) ArchiveProgressType.StartFile, 9, 15, 4, 1, 3 },
238 new int[] { (int) ArchiveProgressType.FinishFile, 9, 15, 4, 1, 3 },
239 new int[] { (int) ArchiveProgressType.StartFile, 10, 15, 5, 1, 3 },
240 new int[] { (int) ArchiveProgressType.FinishFile, 10, 15, 5, 1, 3 },
241 new int[] { (int) ArchiveProgressType.StartFile, 11, 15, 5, 1, 3 },
242 new int[] { (int) ArchiveProgressType.FinishFile, 11, 15, 5, 1, 3 },
243 new int[] { (int) ArchiveProgressType.StartFile, 12, 15, 6, 1, 3 },
244 new int[] { (int) ArchiveProgressType.FinishArchive, 12, 15, 6, 1, 3 },
245 new int[] { (int) ArchiveProgressType.StartArchive, 12, 15, 6, 2, 3 },
246 new int[] { (int) ArchiveProgressType.FinishFile, 12, 15, 6, 2, 3 },
247 new int[] { (int) ArchiveProgressType.StartFile, 13, 15, 6, 2, 3 },
248 new int[] { (int) ArchiveProgressType.FinishFile, 13, 15, 6, 2, 3 },
249 new int[] { (int) ArchiveProgressType.StartFile, 14, 15, 7, 2, 3 },
250 new int[] { (int) ArchiveProgressType.FinishFile, 14, 15, 7, 2, 3 },
251 new int[] { (int) ArchiveProgressType.FinishArchive, 14, 15, 7, 2, 3 },
252 });
253
254 try
255 {
256 this.RunCabinetPackUnpack(15, 20 * 1024, 1 * 1024, 130 * 1024, CompressionLevel.None);
257 }
258 finally
259 {
260 CompressionTestUtil.ExpectedProgress = null;
261 }
262 }
263
264 [TestMethod]
265 public void CabArchiveSizeParam()
266 {
267 Console.WriteLine("Testing various values for the maxArchiveSize parameter.");
268 this.RunCabinetPackUnpack(5, 1024, 0, Int64.MinValue);
269 this.RunCabinetPackUnpack(5, 1024, 0, -1);
270 this.RunCabinetPackUnpack(5, 10, 0, 2);
271 this.RunCabinetPackUnpack(5, 100, 0, 256);
272 this.RunCabinetPackUnpack(5, 24000, 0, 32768);
273 this.RunCabinetPackUnpack(5, 1024, 0, Int64.MaxValue);
274 }
275
276 [TestMethod]
277 public void CabFolderSizeParam()
278 {
279 Console.WriteLine("Testing various values for the maxFolderSize parameter.");
280 this.RunCabinetPackUnpack(5, 10, Int64.MinValue, 0);
281 this.RunCabinetPackUnpack(5, 10, -1, 0);
282 this.RunCabinetPackUnpack(5, 10, 2, 0);
283 this.RunCabinetPackUnpack(5, 10, 16, 0);
284 this.RunCabinetPackUnpack(5, 10, 100, 0);
285 this.RunCabinetPackUnpack(5, 10, Int64.MaxValue, 0);
286 }
287
288 [TestMethod]
289 public void CabCompLevelParam()
290 {
291 Console.WriteLine("Testing various values for the compressionLevel parameter.");
292 this.RunCabinetPackUnpack(5, 1024, 0, 0, CompressionLevel.None);
293 this.RunCabinetPackUnpack(5, 1024, 0, 0, CompressionLevel.Min);
294 this.RunCabinetPackUnpack(5, 1024, 0, 0, CompressionLevel.Normal);
295 this.RunCabinetPackUnpack(5, 1024, 0, 0, CompressionLevel.Max);
296 this.RunCabinetPackUnpack(5, 1024, 0, 0, (CompressionLevel) ((int) CompressionLevel.None - 1));
297 this.RunCabinetPackUnpack(5, 1024, 0, 0, (CompressionLevel) ((int) CompressionLevel.Max + 1));
298 this.RunCabinetPackUnpack(5, 1024, 0, 0, (CompressionLevel) Int32.MinValue);
299 this.RunCabinetPackUnpack(5, 1024, 0, 0, (CompressionLevel) Int32.MaxValue);
300 }
301
302 [TestMethod]
303 public void CabEngineNullParams()
304 {
305 string[] testFiles = new string[] { "test.txt" };
306 ArchiveFileStreamContext streamContext = new ArchiveFileStreamContext("test.cab", null, null);
307
308 using (CabEngine cabEngine = new CabEngine())
309 {
310 cabEngine.CompressionLevel = CompressionLevel.None;
311
312 CompressionTestUtil.TestCompressionEngineNullParams(
313 cabEngine, streamContext, testFiles);
314 }
315 }
316
317 [TestMethod]
318 public void CabBadPackStreamContexts()
319 {
320 string[] testFiles = new string[] { "test.txt" };
321 CompressionTestUtil.GenerateRandomFile(testFiles[0], 0, 20000);
322
323 using (CabEngine cabEngine = new CabEngine())
324 {
325 cabEngine.CompressionLevel = CompressionLevel.None;
326
327 CompressionTestUtil.TestBadPackStreamContexts(cabEngine, "test.cab", testFiles);
328 }
329 }
330
331 [TestMethod]
332 public void CabEngineNoTempFileTest()
333 {
334 int txtSize = 10240;
335 CompressionTestUtil.GenerateRandomFile("testnotemp.txt", 0, txtSize);
336
337 ArchiveFileStreamContext streamContext = new ArchiveFileStreamContext("testnotemp.cab", null, null);
338
339 using (CabEngine cabEngine = new CabEngine())
340 {
341 cabEngine.UseTempFiles = false;
342 cabEngine.Pack(streamContext, new string[] { "testnotemp.txt" });
343 }
344
345 new CabInfo("testnotemp.cab").UnpackFile("testnotemp.txt", "testnotemp2.txt");
346 Assert.AreEqual(txtSize, new FileInfo("testnotemp2.txt").Length);
347 }
348
349 [TestMethod]
350 public void CabExtractorIsCabinet()
351 {
352 int txtSize = 10240;
353 CompressionTestUtil.GenerateRandomFile("test.txt", 0, txtSize);
354 new CabInfo("test.cab").PackFiles(null, new string[] { "test.txt" }, null);
355 using (CabEngine cabEngine = new CabEngine())
356 {
357 bool isCab;
358 using (Stream fileStream = File.OpenRead("test.txt"))
359 {
360 isCab = cabEngine.IsArchive(fileStream);
361 }
362 Assert.IsFalse(isCab);
363 using (Stream cabStream = File.OpenRead("test.cab"))
364 {
365 isCab = cabEngine.IsArchive(cabStream);
366 }
367 Assert.IsTrue(isCab);
368 using (Stream cabStream = File.OpenRead("test.cab"))
369 {
370 using (Stream fileStream = new FileStream("test.txt", FileMode.Open, FileAccess.ReadWrite))
371 {
372 fileStream.Seek(0, SeekOrigin.End);
373 byte[] buf = new byte[1024];
374 int count;
375 while ((count = cabStream.Read(buf, 0, buf.Length)) > 0)
376 {
377 fileStream.Write(buf, 0, count);
378 }
379 fileStream.Seek(0, SeekOrigin.Begin);
380 isCab = cabEngine.IsArchive(fileStream);
381 }
382 }
383 Assert.IsFalse(isCab);
384 using (Stream fileStream = new FileStream("test.txt", FileMode.Open, FileAccess.ReadWrite))
385 {
386 fileStream.Write(new byte[] { (byte) 'M', (byte) 'S', (byte) 'C', (byte) 'F' }, 0, 4);
387 fileStream.Seek(0, SeekOrigin.Begin);
388 isCab = cabEngine.IsArchive(fileStream);
389 }
390 Assert.IsFalse(isCab);
391 }
392 }
393
394 [TestMethod]
395 public void CabExtractorFindOffset()
396 {
397 int txtSize = 10240;
398 CompressionTestUtil.GenerateRandomFile("test.txt", 0, txtSize);
399 new CabInfo("test.cab").PackFiles(null, new string[] { "test.txt" }, null);
400 using (CabEngine cabEngine = new CabEngine())
401 {
402 long offset;
403 using (Stream fileStream = File.OpenRead("test.txt"))
404 {
405 offset = cabEngine.FindArchiveOffset(fileStream);
406 }
407 Assert.AreEqual<long>(-1, offset);
408 using (Stream cabStream = File.OpenRead("test.cab"))
409 {
410 using (Stream fileStream = new FileStream("test.txt", FileMode.Open, FileAccess.ReadWrite))
411 {
412 fileStream.Seek(0, SeekOrigin.End);
413 byte[] buf = new byte[1024];
414 int count;
415 while ((count = cabStream.Read(buf, 0, buf.Length)) > 0)
416 {
417 fileStream.Write(buf, 0, count);
418 }
419 fileStream.Seek(0, SeekOrigin.Begin);
420 offset = cabEngine.FindArchiveOffset(fileStream);
421 }
422 }
423 Assert.AreEqual<long>(txtSize, offset);
424 }
425 }
426
427 [TestMethod]
428 public void CabExtractorGetFiles()
429 {
430 IList<ArchiveFileInfo> fileInfo;
431 CabInfo cabInfo = new CabInfo("testgetfiles.cab");
432 int txtSize = 10240;
433 CompressionTestUtil.GenerateRandomFile("testgetfiles0.txt", 0, txtSize);
434 CompressionTestUtil.GenerateRandomFile("testgetfiles1.txt", 1, txtSize);
435 cabInfo.PackFiles(null, new string[] { "testgetfiles0.txt", "testgetfiles1.txt" }, null);
436 using (CabEngine cabEngine = new CabEngine())
437 {
438 IList<string> files;
439 using (Stream cabStream = File.OpenRead("testgetfiles.cab"))
440 {
441 files = cabEngine.GetFiles(cabStream);
442 }
443 Assert.IsNotNull(files);
444 Assert.AreEqual<int>(2, files.Count);
445 Assert.AreEqual<string>("testgetfiles0.txt", files[0]);
446 Assert.AreEqual<string>("testgetfiles1.txt", files[1]);
447
448 using (Stream cabStream = File.OpenRead("testgetfiles.cab"))
449 {
450 files = cabEngine.GetFiles(new ArchiveFileStreamContext("testgetfiles.cab"), null);
451 }
452 Assert.IsNotNull(files);
453 Assert.AreEqual<int>(2, files.Count);
454 Assert.AreEqual<string>("testgetfiles0.txt", files[0]);
455 Assert.AreEqual<string>("testgetfiles1.txt", files[1]);
456
457 using (Stream cabStream = File.OpenRead("testgetfiles.cab"))
458 {
459 fileInfo = cabEngine.GetFileInfo(cabStream);
460 }
461 Assert.IsNotNull(fileInfo);
462 Assert.AreEqual<int>(2, fileInfo.Count);
463 Assert.AreEqual<string>("testgetfiles0.txt", fileInfo[0].Name);
464 Assert.AreEqual<string>("testgetfiles1.txt", fileInfo[1].Name);
465 using (Stream cabStream = File.OpenRead("testgetfiles.cab"))
466 {
467 fileInfo = cabEngine.GetFileInfo(new ArchiveFileStreamContext("testgetfiles.cab"), null);
468 }
469 Assert.IsNotNull(fileInfo);
470 Assert.AreEqual<int>(2, fileInfo.Count);
471 Assert.AreEqual<string>("testgetfiles0.txt", fileInfo[0].Name);
472 Assert.AreEqual<string>("testgetfiles1.txt", fileInfo[1].Name);
473 }
474
475 fileInfo = this.RunCabinetPackUnpack(15, 20 * 1024, 1 * 1024, 130 * 1024);
476 Assert.IsNotNull(fileInfo);
477 Assert.AreEqual<int>(15, fileInfo.Count);
478 for (int i = 0; i < fileInfo.Count; i++)
479 {
480 Assert.IsNull(fileInfo[i].Archive);
481 Assert.AreEqual<string>(TEST_FILENAME_PREFIX + i + ".txt", fileInfo[i].Name);
482 Assert.IsTrue(DateTime.Now - fileInfo[i].LastWriteTime < new TimeSpan(0, 1, 0));
483 }
484 }
485
486 [TestMethod]
487 public void CabExtractorExtract()
488 {
489 int txtSize = 40960;
490 CabInfo cabInfo = new CabInfo("test.cab");
491 CompressionTestUtil.GenerateRandomFile("test0.txt", 0, txtSize);
492 CompressionTestUtil.GenerateRandomFile("test1.txt", 1, txtSize);
493 cabInfo.PackFiles(null, new string[] { "test0.txt", "test1.txt" }, null);
494 using (CabEngine cabEngine = new CabEngine())
495 {
496 using (Stream cabStream = File.OpenRead("test.cab"))
497 {
498 using (Stream exStream = cabEngine.Unpack(cabStream, "test0.txt"))
499 {
500 string str = new StreamReader(exStream).ReadToEnd();
501 string expected = new StreamReader("test0.txt").ReadToEnd();
502 Assert.AreEqual<string>(expected, str);
503 }
504 cabStream.Seek(0, SeekOrigin.Begin);
505 using (Stream exStream = cabEngine.Unpack(cabStream, "test1.txt"))
506 {
507 string str = new StreamReader(exStream).ReadToEnd();
508 string expected = new StreamReader("test1.txt").ReadToEnd();
509 Assert.AreEqual<string>(expected, str);
510 }
511 }
512 using (Stream txtStream = File.OpenRead("test0.txt"))
513 {
514 Exception caughtEx = null;
515 try
516 {
517 cabEngine.Unpack(txtStream, "test0.txt");
518 }
519 catch (Exception ex) { caughtEx = ex; }
520 Assert.IsInstanceOfType(caughtEx, typeof(CabException));
521 Assert.AreEqual<int>(2, ((CabException) caughtEx).Error);
522 Assert.AreEqual<int>(0, ((CabException) caughtEx).ErrorCode);
523 Assert.AreEqual<string>("Cabinet file does not have the correct format.", caughtEx.Message);
524 }
525 }
526 }
527
528 [TestMethod]
529 public void CabBadUnpackStreamContexts()
530 {
531 int txtSize = 40960;
532 CabInfo cabInfo = new CabInfo("test2.cab");
533 CompressionTestUtil.GenerateRandomFile("cabtest-0.txt", 0, txtSize);
534 CompressionTestUtil.GenerateRandomFile("cabtest-1.txt", 1, txtSize);
535 cabInfo.PackFiles(null, new string[] { "cabtest-0.txt", "cabtest-1.txt" }, null);
536
537 using (CabEngine cabEngine = new CabEngine())
538 {
539 CompressionTestUtil.TestBadUnpackStreamContexts(cabEngine, "test2.cab");
540 }
541 }
542
543 [TestMethod]
544 public void CabinetExtractUpdate()
545 {
546 int fileCount = 5, fileSize = 2048;
547 string dirA = String.Format("{0}-{1}-A", fileCount, fileSize);
548 if (Directory.Exists(dirA)) Directory.Delete(dirA, true);
549 Directory.CreateDirectory(dirA);
550 string dirB = String.Format("{0}-{1}-B", fileCount, fileSize);
551 if (Directory.Exists(dirB)) Directory.Delete(dirB, true);
552 Directory.CreateDirectory(dirB);
553
554 string[] files = new string[fileCount];
555 for (int iFile = 0; iFile < fileCount; iFile++)
556 {
557 files[iFile] = "€" + iFile + ".txt";
558 CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[iFile]), iFile, fileSize);
559 }
560
561 CabInfo cabInfo = new CabInfo("testupdate.cab");
562 cabInfo.Pack(dirA);
563 cabInfo.Unpack(dirB);
564
565 DateTime originalTime = File.GetLastWriteTime(Path.Combine(dirA, "€1.txt"));
566 DateTime pastTime = originalTime - new TimeSpan(0, 5, 0);
567 DateTime futureTime = originalTime + new TimeSpan(0, 5, 0);
568
569 using (CabEngine cabEngine = new CabEngine())
570 {
571 string cabName = "testupdate.cab";
572 ArchiveFileStreamContext streamContext = new ArchiveFileStreamContext(cabName, dirB, null);
573 streamContext.ExtractOnlyNewerFiles = true;
574
575 Assert.AreEqual<bool>(true, streamContext.ExtractOnlyNewerFiles);
576 Assert.IsNotNull(streamContext.ArchiveFiles);
577 Assert.AreEqual<int>(1, streamContext.ArchiveFiles.Count);
578 Assert.AreEqual<string>(cabName, streamContext.ArchiveFiles[0]);
579 Assert.AreEqual<string>(dirB, streamContext.Directory);
580
581 File.SetLastWriteTime(Path.Combine(dirB, "€1.txt"), futureTime);
582 cabEngine.Unpack(streamContext, null);
583 Assert.IsTrue(File.GetLastWriteTime(Path.Combine(dirB, "€1.txt")) - originalTime > new TimeSpan(0, 4, 55));
584
585 File.SetLastWriteTime(Path.Combine(dirB, "€1.txt"), pastTime);
586 File.SetLastWriteTime(Path.Combine(dirB, "€2.txt"), pastTime);
587 File.SetAttributes(Path.Combine(dirB, "€2.txt"), FileAttributes.ReadOnly);
588 File.SetAttributes(Path.Combine(dirB, "€2.txt"), FileAttributes.Hidden);
589 File.SetAttributes(Path.Combine(dirB, "€2.txt"), FileAttributes.System);
590
591 cabEngine.Unpack(streamContext, null);
592 Assert.IsTrue((File.GetLastWriteTime(Path.Combine(dirB, "€1.txt")) - originalTime).Duration() < new TimeSpan(0, 0, 5));
593
594 // Just test the rest of the streamContext properties here.
595 IDictionary<string, string> testMap = new Dictionary<string, string>();
596 streamContext = new ArchiveFileStreamContext(cabName, dirB, testMap);
597 Assert.AreSame(testMap, streamContext.Files);
598
599 Assert.IsFalse(streamContext.EnableOffsetOpen);
600 streamContext.EnableOffsetOpen = true;
601 Assert.IsTrue(streamContext.EnableOffsetOpen);
602 streamContext = new ArchiveFileStreamContext(cabName, ".", testMap);
603 Assert.AreEqual<string>(".", streamContext.Directory);
604 string[] testArchiveFiles = new string[] { cabName };
605 streamContext = new ArchiveFileStreamContext(testArchiveFiles, ".", testMap);
606 Assert.AreSame(testArchiveFiles, streamContext.ArchiveFiles);
607 }
608 }
609
610 [TestMethod]
611 public void CabinetOffset()
612 {
613 int txtSize = 10240;
614 CompressionTestUtil.GenerateRandomFile("test.txt", 0, txtSize);
615 CompressionTestUtil.GenerateRandomFile("base.txt", 1, 2 * txtSize + 4);
616
617 ArchiveFileStreamContext streamContext = new ArchiveFileStreamContext("base.txt", null, null);
618 streamContext.EnableOffsetOpen = true;
619
620 using (CabEngine cabEngine = new CabEngine())
621 {
622 cabEngine.Pack(streamContext, new string[] { "test.txt" });
623 }
624
625 Assert.IsTrue(new FileInfo("base.txt").Length > 2 * txtSize + 4);
626
627 string saveText;
628 using (Stream txtStream = File.OpenRead("test.txt"))
629 {
630 saveText = new StreamReader(txtStream).ReadToEnd();
631 }
632 File.Delete("test.txt");
633
634 using (CabEngine cex = new CabEngine())
635 {
636 cex.Unpack(streamContext, null);
637 }
638 string testText;
639 using (Stream txtStream = File.OpenRead("test.txt"))
640 {
641 testText = new StreamReader(txtStream).ReadToEnd();
642 }
643 Assert.AreEqual<string>(saveText, testText);
644 }
645
646 [TestMethod]
647 public void CabinetUtfPaths()
648 {
649 string[] files = new string[]
650 {
651 "어그리먼트送信ポート1ßà_Agreement.txt",
652 "콘토소ßà_MyProfile.txt",
653 "파트너1ßà_PartnerProfile.txt",
654 };
655
656 string dirA = "utf8-A";
657 if (Directory.Exists(dirA)) Directory.Delete(dirA, true);
658 Directory.CreateDirectory(dirA);
659 string dirB = "utf8-B";
660 if (Directory.Exists(dirB)) Directory.Delete(dirB, true);
661 Directory.CreateDirectory(dirB);
662
663 int txtSize = 1024;
664 CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[0]), 0, txtSize);
665 CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[1]), 1, txtSize);
666 CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[2]), 2, txtSize);
667
668 ArchiveFileStreamContext streamContextA = new ArchiveFileStreamContext("utf8.cab", dirA, null);
669 using (CabEngine cabEngine = new CabEngine())
670 {
671 cabEngine.Pack(streamContextA, files);
672 }
673
674 ArchiveFileStreamContext streamContextB = new ArchiveFileStreamContext("utf8.cab", dirB, null);
675 using (CabEngine cex = new CabEngine())
676 {
677 cex.Unpack(streamContextB, null);
678 }
679
680 bool directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB);
681 Assert.IsTrue(directoryMatch,
682 "Testing whether cabinet output directory matches input directory.");
683 }
684
685 [TestMethod]
686 //[Ignore] // Requires clean environment.
687 public void CabInfoProperties()
688 {
689 Exception caughtEx;
690 CabInfo cabInfo = new CabInfo("test.cab");
691 int txtSize = 10240;
692 CompressionTestUtil.GenerateRandomFile("test00.txt", 0, txtSize);
693 CompressionTestUtil.GenerateRandomFile("test01.txt", 1, txtSize);
694 cabInfo.PackFiles(null, new string[] { "test00.txt", "test01.txt" }, null);
695
696 Assert.AreEqual<string>(new FileInfo("test.cab").Directory.FullName, cabInfo.Directory.FullName, "CabInfo.FullName");
697 Assert.AreEqual<string>(new FileInfo("test.cab").DirectoryName, cabInfo.DirectoryName, "CabInfo.DirectoryName");
698 Assert.AreEqual<long>(new FileInfo("test.cab").Length, cabInfo.Length, "CabInfo.Length");
699 Assert.AreEqual<string>("test.cab", cabInfo.Name, "CabInfo.Name");
700 Assert.AreEqual<string>(new FileInfo("test.cab").FullName, cabInfo.ToString(), "CabInfo.ToString()");
701 cabInfo.CopyTo("test3.cab");
702 caughtEx = null;
703 try
704 {
705 cabInfo.CopyTo("test3.cab");
706 }
707 catch (Exception ex) { caughtEx = ex; }
708 Assert.IsInstanceOfType(caughtEx, typeof(IOException), "CabInfo.CopyTo() caught exception: " + caughtEx);
709 cabInfo.CopyTo("test3.cab", true);
710 cabInfo.MoveTo("test4.cab");
711 Assert.AreEqual<string>("test4.cab", cabInfo.Name);
712 Assert.IsTrue(cabInfo.Exists, "CabInfo.Exists()");
713 Assert.IsTrue(cabInfo.IsValid(), "CabInfo.IsValid");
714 cabInfo.Delete();
715 Assert.IsFalse(cabInfo.Exists, "!CabInfo.Exists()");
716 }
717
718 [TestMethod]
719 //[Ignore] // Requires clean environment.
720 public void CabInfoNullParams()
721 {
722 int fileCount = 10, fileSize = 1024;
723 string dirA = String.Format("{0}-{1}-A", fileCount, fileSize);
724 if (Directory.Exists(dirA)) Directory.Delete(dirA, true);
725 Directory.CreateDirectory(dirA);
726 string dirB = String.Format("{0}-{1}-B", fileCount, fileSize);
727 if (Directory.Exists(dirB)) Directory.Delete(dirB, true);
728 Directory.CreateDirectory(dirB);
729
730 string[] files = new string[fileCount];
731 for (int iFile = 0; iFile < fileCount; iFile++)
732 {
733 files[iFile] = "cabinfo-" + iFile + ".txt";
734 CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[iFile]), iFile, fileSize);
735 }
736
737 CabInfo cabInfo = new CabInfo("testnull.cab");
738
739 CompressionTestUtil.TestArchiveInfoNullParams(cabInfo, dirA, dirB, files);
740 }
741
742 [TestMethod]
743 public void CabInfoGetFiles()
744 {
745 IList<CabFileInfo> fileInfo;
746 CabInfo cabInfo = new CabInfo("test.cab");
747 int txtSize = 10240;
748 CompressionTestUtil.GenerateRandomFile("testinfo0.txt", 0, txtSize);
749 CompressionTestUtil.GenerateRandomFile("testinfo1.txt", 1, txtSize);
750 cabInfo.PackFiles(null, new string[] { "testinfo0.txt", "testinfo1.txt" }, null);
751
752 fileInfo = cabInfo.GetFiles();
753 Assert.IsNotNull(fileInfo);
754 Assert.AreEqual<int>(2, fileInfo.Count);
755 Assert.AreEqual<string>("testinfo0.txt", fileInfo[0].Name);
756 Assert.AreEqual<string>("testinfo1.txt", fileInfo[1].Name);
757
758 fileInfo = cabInfo.GetFiles("*.txt");
759 Assert.IsNotNull(fileInfo);
760 Assert.AreEqual<int>(2, fileInfo.Count);
761 Assert.AreEqual<string>("testinfo0.txt", fileInfo[0].Name);
762 Assert.AreEqual<string>("testinfo1.txt", fileInfo[1].Name);
763
764 fileInfo = cabInfo.GetFiles("testinfo1.txt");
765 Assert.IsNotNull(fileInfo);
766 Assert.AreEqual<int>(1, fileInfo.Count);
767 Assert.AreEqual<string>("testinfo1.txt", fileInfo[0].Name);
768 }
769
770 [TestMethod]
771 public void CabInfoCompressExtract()
772 {
773 int fileCount = 10, fileSize = 1024;
774 string dirA = String.Format("{0}-{1}-A", fileCount, fileSize);
775 if (Directory.Exists(dirA)) Directory.Delete(dirA, true);
776 Directory.CreateDirectory(dirA);
777 Directory.CreateDirectory(Path.Combine(dirA, "sub"));
778 string dirB = String.Format("{0}-{1}-B", fileCount, fileSize);
779 if (Directory.Exists(dirB)) Directory.Delete(dirB, true);
780 Directory.CreateDirectory(dirB);
781
782 string[] files = new string[fileCount];
783 for (int iFile = 0; iFile < fileCount; iFile++)
784 {
785 files[iFile] = "€" + iFile + ".txt";
786 CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[iFile]), iFile, fileSize);
787 }
788 CompressionTestUtil.GenerateRandomFile(Path.Combine(Path.Combine(dirA, "sub"), "€-.txt"), fileCount + 1, fileSize);
789
790 CabInfo cabInfo = new CabInfo("test.cab");
791 cabInfo.Pack(dirA);
792 cabInfo.Unpack(dirB);
793 bool directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB);
794 Assert.IsFalse(directoryMatch,
795 "Testing whether cabinet output directory matches input directory.");
796 Directory.Delete(dirB, true);
797 Directory.CreateDirectory(dirB);
798 cabInfo.Pack(dirA, true, CompressionLevel.Normal, null);
799 cabInfo.Unpack(dirB);
800 directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB);
801 Assert.IsTrue(directoryMatch,
802 "Testing whether cabinet output directory matches input directory.");
803 Directory.Delete(dirB, true);
804 Directory.Delete(Path.Combine(dirA, "sub"), true);
805 Directory.CreateDirectory(dirB);
806 cabInfo.Delete();
807
808 cabInfo.PackFiles(dirA, files, null);
809 cabInfo.UnpackFiles(files, dirB, null);
810 directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB);
811 Assert.IsTrue(directoryMatch,
812 "Testing whether cabinet output directory matches input directory.");
813 Directory.Delete(dirB, true);
814 Directory.CreateDirectory(dirB);
815 cabInfo.Delete();
816
817 IDictionary<string, string> testMap = new Dictionary<string, string>(files.Length);
818 for (int iFile = 0; iFile < fileCount; iFile++)
819 {
820 testMap[files[iFile] + ".key"] = files[iFile];
821 }
822 cabInfo.PackFileSet(dirA, testMap);
823 cabInfo.UnpackFileSet(testMap, dirB);
824 directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB);
825 Assert.IsTrue(directoryMatch,
826 "Testing whether cabinet output directory matches input directory.");
827 Directory.Delete(dirB, true);
828 Directory.CreateDirectory(dirB);
829
830 testMap.Remove(files[1] + ".key");
831 cabInfo.UnpackFileSet(testMap, dirB);
832 directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB);
833 Assert.IsFalse(directoryMatch,
834 "Testing whether cabinet output directory matches input directory.");
835 Directory.Delete(dirB, true);
836 Directory.CreateDirectory(dirB);
837 cabInfo.Delete();
838
839 cabInfo.PackFiles(dirA, files, null);
840 cabInfo.UnpackFile("€2.txt", Path.Combine(dirB, "test.txt"));
841 Assert.IsTrue(File.Exists(Path.Combine(dirB, "test.txt")));
842 Assert.AreEqual<int>(1, Directory.GetFiles(dirB).Length);
843 }
844
845 [TestMethod]
846 //[Ignore] // Requires clean environment.
847 public void CabFileInfoProperties()
848 {
849 CabInfo cabInfo = new CabInfo("test.cab");
850 int txtSize = 10240;
851 CompressionTestUtil.GenerateRandomFile("test00.txt", 0, txtSize);
852 CompressionTestUtil.GenerateRandomFile("test01.txt", 1, txtSize);
853 File.SetAttributes("test01.txt", FileAttributes.ReadOnly | FileAttributes.Archive);
854 DateTime testTime = File.GetLastWriteTime("test01.txt");
855 cabInfo.PackFiles(null, new string[] { "test00.txt", "test01.txt" }, null);
856 File.SetAttributes("test01.txt", FileAttributes.Archive);
857
858 CabFileInfo cfi = new CabFileInfo(cabInfo, "test01.txt");
859 Assert.AreEqual(cabInfo.FullName, cfi.CabinetName);
860 Assert.AreEqual<int>(0, ((CabFileInfo) cfi).CabinetFolderNumber);
861 Assert.AreEqual<string>(Path.Combine(cabInfo.FullName, "test01.txt"), cfi.FullName);
862 cfi = new CabFileInfo(cabInfo, "test01.txt");
863 Assert.IsTrue(cfi.Exists);
864 cfi = new CabFileInfo(cabInfo, "test01.txt");
865 Assert.AreEqual<long>(txtSize, cfi.Length);
866 cfi = new CabFileInfo(cabInfo, "test00.txt");
867 Assert.AreEqual<FileAttributes>(FileAttributes.Archive, cfi.Attributes);
868 cfi = new CabFileInfo(cabInfo, "test01.txt");
869 Assert.AreEqual<FileAttributes>(FileAttributes.ReadOnly | FileAttributes.Archive, cfi.Attributes);
870 cfi = new CabFileInfo(cabInfo, "test01.txt");
871 Assert.IsTrue((testTime - cfi.LastWriteTime).Duration() < new TimeSpan(0, 0, 5));
872 Assert.AreEqual<string>(Path.Combine(cabInfo.FullName, "test01.txt"), cfi.ToString());
873 cfi.CopyTo("testcopy.txt");
874 Assert.IsTrue(File.Exists("testCopy.txt"));
875 Assert.AreEqual<long>(cfi.Length, new FileInfo("testCopy.txt").Length);
876
877 Exception caughtEx = null;
878 try
879 {
880 cfi.CopyTo("testcopy.txt", false);
881 }
882 catch (Exception ex) { caughtEx = ex; }
883 Assert.IsInstanceOfType(caughtEx, typeof(IOException));
884 }
885
886 [TestMethod]
887 public void CabFileInfoOpenText()
888 {
889 CabInfo cabInfo = new CabInfo("test.cab");
890 int txtSize = 10240;
891 CompressionTestUtil.GenerateRandomFile("test00.txt", 0, txtSize);
892 CompressionTestUtil.GenerateRandomFile("test01.txt", 1, txtSize);
893
894 string expectedText = File.ReadAllText("test01.txt");
895
896 cabInfo.PackFiles(null, new string[] { "test00.txt", "test01.txt" }, null);
897
898 CabFileInfo cfi = new CabFileInfo(cabInfo, "test01.txt");
899 using (StreamReader cabFileReader = cfi.OpenText())
900 {
901 string text = cabFileReader.ReadToEnd();
902 Assert.AreEqual(expectedText, text);
903
904 // Check the assumption that the cab can't be deleted while a stream is open.
905 Exception caughtEx = null;
906 try
907 {
908 File.Delete(cabInfo.FullName);
909 }
910 catch (Exception ex)
911 {
912 caughtEx = ex;
913 }
914
915 Assert.IsInstanceOfType(caughtEx, typeof(IOException));
916 }
917
918 // Ensure all streams are closed after disposing of the StreamReader returned by OpenText.
919 File.Delete(cabInfo.FullName);
920 }
921
922 [TestMethod]
923 public void CabFileInfoNullParams()
924 {
925 Exception caughtEx;
926 CabInfo cabInfo = new CabInfo("test.cab");
927 int txtSize = 10240;
928 CompressionTestUtil.GenerateRandomFile("test00.txt", 0, txtSize);
929 CompressionTestUtil.GenerateRandomFile("test01.txt", 1, txtSize);
930 cabInfo.PackFiles(null, new string[] { "test00.txt", "test01.txt" }, null);
931 CabFileInfo cfi = new CabFileInfo(cabInfo, "test01.txt");
932
933 caughtEx = null;
934 try
935 {
936 new CabFileInfo(null, "test00.txt");
937 }
938 catch (Exception ex) { caughtEx = ex; }
939 Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException));
940 caughtEx = null;
941 try
942 {
943 new CabFileInfo(cabInfo, null);
944 }
945 catch (Exception ex) { caughtEx = ex; }
946 Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException));
947 caughtEx = null;
948 try
949 {
950 cfi.CopyTo(null);
951 }
952 catch (Exception ex) { caughtEx = ex; }
953 Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException));
954 }
955
956 [TestMethod]
957 public void CabInfoSerialization()
958 {
959 CabInfo cabInfo = new CabInfo("testser.cab");
960 int txtSize = 10240;
961 CompressionTestUtil.GenerateRandomFile("testser00.txt", 0, txtSize);
962 CompressionTestUtil.GenerateRandomFile("testser01.txt", 1, txtSize);
963 cabInfo.PackFiles(null, new string[] { "testser00.txt", "testser01.txt" }, null);
964 ArchiveFileInfo cfi = cabInfo.GetFiles()[1];
965
966 MemoryStream memStream = new MemoryStream();
967
968 BinaryFormatter formatter = new BinaryFormatter();
969
970 memStream.Seek(0, SeekOrigin.Begin);
971 formatter.Serialize(memStream, cabInfo);
972 memStream.Seek(0, SeekOrigin.Begin);
973 CabInfo cabInfo2 = (CabInfo) formatter.Deserialize(memStream);
974 Assert.AreEqual<string>(cabInfo.FullName, cabInfo2.FullName);
975
976 memStream.Seek(0, SeekOrigin.Begin);
977 formatter.Serialize(memStream, cfi);
978 memStream.Seek(0, SeekOrigin.Begin);
979 CabFileInfo cfi2 = (CabFileInfo) formatter.Deserialize(memStream);
980 Assert.AreEqual<string>(cfi.FullName, cfi2.FullName);
981 Assert.AreEqual<long>(cfi.Length, cfi2.Length);
982
983 CabException cabEx = new CabException();
984 memStream.Seek(0, SeekOrigin.Begin);
985 formatter.Serialize(memStream, cabEx);
986 memStream.Seek(0, SeekOrigin.Begin);
987 formatter.Deserialize(memStream);
988
989 cabEx = new CabException("Test exception.", null);
990 Assert.AreEqual<string>("Test exception.", cabEx.Message);
991 }
992
993 [TestMethod]
994 public void CabFileStreamContextNullParams()
995 {
996 ArchiveFileStreamContext streamContext = null;
997 Exception caughtEx = null;
998 try
999 {
1000 streamContext = new ArchiveFileStreamContext(null);
1001 }
1002 catch (Exception ex) { caughtEx = ex; }
1003 Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Passing null to constructor.");
1004 caughtEx = null;
1005 try
1006 {
1007 streamContext = new ArchiveFileStreamContext(new string[] { }, "testDir", new Dictionary<string, string>());
1008 }
1009 catch (Exception ex) { caughtEx = ex; }
1010 Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Passing 0-length array to constructor.");
1011 caughtEx = null;
1012 try
1013 {
1014 streamContext = new ArchiveFileStreamContext(new string[] { "test.cab" }, null, null);
1015 }
1016 catch (Exception ex) { caughtEx = ex; }
1017 Assert.IsNull(caughtEx);
1018 }
1019
1020 [TestMethod]
1021 public void CabinetTruncateOnCreate()
1022 {
1023 CabInfo cabInfo = new CabInfo("testtruncate.cab");
1024 int txtSize = 20240;
1025 CompressionTestUtil.GenerateRandomFile("testtruncate0.txt", 0, txtSize);
1026 CompressionTestUtil.GenerateRandomFile("testtruncate1.txt", 1, txtSize);
1027 cabInfo.PackFiles(null, new string[] { "testtruncate0.txt", "testtruncate1.txt" }, null);
1028
1029 long size1 = cabInfo.Length;
1030
1031 txtSize /= 5;
1032 CompressionTestUtil.GenerateRandomFile("testtruncate2.txt", 2, txtSize);
1033 CompressionTestUtil.GenerateRandomFile("testtruncate3.txt", 3, txtSize);
1034 cabInfo.PackFiles(null, new string[] { "testtruncate2.txt", "testtruncate3.txt" }, null);
1035
1036 // The newly created cab file should be smaller than before.
1037 Assert.AreNotEqual<long>(size1, cabInfo.Length, "Checking that cabinet file got truncated when creating a smaller cab in-place.");
1038 }
1039
1040 [TestMethod]
1041 public void CabTruncatedArchive()
1042 {
1043 CabInfo cabInfo = new CabInfo("test-t.cab");
1044 CompressionTestUtil.GenerateRandomFile("cabtest-0.txt", 0, 5);
1045 CompressionTestUtil.GenerateRandomFile("cabtest-1.txt", 1, 5);
1046 cabInfo.PackFiles(null, new string[] { "cabtest-0.txt", "cabtest-1.txt" }, null);
1047
1048 CompressionTestUtil.TestTruncatedArchive(cabInfo, typeof(CabException));
1049 }
1050 private const string TEST_FILENAME_PREFIX = "\x20AC";
1051
1052 private IList<ArchiveFileInfo> RunCabinetPackUnpack(int fileCount, long fileSize)
1053 {
1054 return RunCabinetPackUnpack(fileCount, fileSize, 0, 0);
1055 }
1056 private IList<ArchiveFileInfo> RunCabinetPackUnpack(int fileCount, long fileSize,
1057 long maxFolderSize, long maxArchiveSize)
1058 {
1059 return this.RunCabinetPackUnpack(fileCount, fileSize, maxFolderSize, maxArchiveSize, CompressionLevel.Normal);
1060 }
1061 private IList<ArchiveFileInfo> RunCabinetPackUnpack(int fileCount, long fileSize,
1062 long maxFolderSize, long maxArchiveSize, CompressionLevel compLevel)
1063 {
1064 Console.WriteLine("Creating cabinet with {0} files of size {1}",
1065 fileCount, fileSize);
1066 Console.WriteLine("MaxFolderSize={0}, MaxArchiveSize={1}, CompressionLevel={2}",
1067 maxFolderSize, maxArchiveSize, compLevel);
1068
1069 string dirA = String.Format("{0}-{1}-A", fileCount, fileSize);
1070 if (Directory.Exists(dirA)) Directory.Delete(dirA, true);
1071 Directory.CreateDirectory(dirA);
1072 string dirB = String.Format("{0}-{1}-B", fileCount, fileSize);
1073 if (Directory.Exists(dirB)) Directory.Delete(dirB, true);
1074 Directory.CreateDirectory(dirB);
1075
1076 string[] files = new string[fileCount];
1077 for (int iFile = 0; iFile < fileCount; iFile++)
1078 {
1079 files[iFile] = TEST_FILENAME_PREFIX + iFile + ".txt";
1080 CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[iFile]), iFile, fileSize);
1081 }
1082
1083 string[] archiveNames = new string[100];
1084 for (int i = 0; i < archiveNames.Length; i++)
1085 {
1086 archiveNames[i] = String.Format("{0}-{1}{2}{3}.cab", fileCount, fileSize,
1087 (i == 0 ? "" : "-"), (i == 0 ? "" : i.ToString()));
1088 }
1089
1090 string progressTextFile = String.Format("progress_{0}-{1}.txt", fileCount, fileSize);
1091 CompressionTestUtil testUtil = new CompressionTestUtil(progressTextFile);
1092
1093 IList<ArchiveFileInfo> fileInfo;
1094 using (CabEngine cabEngine = new CabEngine())
1095 {
1096 cabEngine.CompressionLevel = compLevel;
1097
1098 File.AppendAllText(progressTextFile,
1099 "\r\n\r\n====================================================\r\nCREATE\r\n\r\n");
1100 cabEngine.Progress += testUtil.PrintArchiveProgress;
1101
1102 OptionStreamContext streamContext = new OptionStreamContext(archiveNames, dirA, null);
1103 if (maxFolderSize == 1)
1104 {
1105 streamContext.OptionHandler =
1106 delegate(string optionName, object[] parameters)
1107 {
1108 if (optionName == "nextFolder") return true;
1109 return null;
1110 };
1111 }
1112 else if (maxFolderSize > 1)
1113 {
1114 streamContext.OptionHandler =
1115 delegate(string optionName, object[] parameters)
1116 {
1117 if (optionName == "maxFolderSize") return maxFolderSize;
1118 return null;
1119 };
1120 }
1121 cabEngine.Pack(streamContext, files, maxArchiveSize);
1122
1123 IList<string> createdArchiveNames = new List<string>(archiveNames.Length);
1124 for (int i = 0; i < archiveNames.Length; i++)
1125 {
1126 if (File.Exists(archiveNames[i]))
1127 {
1128 createdArchiveNames.Add(archiveNames[i]);
1129 }
1130 else
1131 {
1132 break;
1133 }
1134 }
1135
1136 Console.WriteLine("Listing cabinet with {0} files of size {1}",
1137 fileCount, fileSize);
1138 File.AppendAllText(progressTextFile, "\r\n\r\nLIST\r\n\r\n");
1139 fileInfo = cabEngine.GetFileInfo(
1140 new ArchiveFileStreamContext(createdArchiveNames, null, null), null);
1141
1142 Assert.AreEqual<int>(fileCount, fileInfo.Count);
1143 if (fileCount > 0)
1144 {
1145 int folders = ((CabFileInfo) fileInfo[fileInfo.Count - 1]).CabinetFolderNumber + 1;
1146 if (maxFolderSize == 1)
1147 {
1148 Assert.AreEqual<int>(fileCount, folders);
1149 }
1150 }
1151
1152 Console.WriteLine("Extracting cabinet with {0} files of size {1}",
1153 fileCount, fileSize);
1154 File.AppendAllText(progressTextFile, "\r\n\r\nEXTRACT\r\n\r\n");
1155 cabEngine.Unpack(new ArchiveFileStreamContext(createdArchiveNames, dirB, null), null);
1156 }
1157
1158 bool directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB);
1159 Assert.IsTrue(directoryMatch,
1160 "Testing whether cabinet output directory matches input directory.");
1161
1162 return fileInfo;
1163 }
1164 }
1165}