From 3f583916719eeef598d10a5d4e14ef14f008243b Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Tue, 11 May 2021 07:36:37 -0700 Subject: Merge Dtf --- .../CompressionTestUtil.cs | 649 +++++++++++++++++++++ 1 file changed, 649 insertions(+) create mode 100644 src/dtf/WixToolsetTests.Dtf.Compression/CompressionTestUtil.cs (limited to 'src/dtf/WixToolsetTests.Dtf.Compression/CompressionTestUtil.cs') diff --git a/src/dtf/WixToolsetTests.Dtf.Compression/CompressionTestUtil.cs b/src/dtf/WixToolsetTests.Dtf.Compression/CompressionTestUtil.cs new file mode 100644 index 00000000..e7a5373d --- /dev/null +++ b/src/dtf/WixToolsetTests.Dtf.Compression/CompressionTestUtil.cs @@ -0,0 +1,649 @@ +// 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. + +using System; +using System.IO; +using System.Text; +using System.Collections.Generic; +using System.Security.Cryptography; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using WixToolset.Dtf.Compression; + +namespace WixToolset.Dtf.Test +{ + public class CompressionTestUtil + { + private static MD5 md5 = new MD5CryptoServiceProvider(); + + private string progressTextFile; + + public CompressionTestUtil(string progressTextFile) + { + this.progressTextFile = progressTextFile; + } + + public static IList ExpectedProgress + { + get { return CompressionTestUtil.expectedProgress; } + set { CompressionTestUtil.expectedProgress = value; } + } + private static IList expectedProgress; + + public void PrintArchiveProgress(object source, ArchiveProgressEventArgs e) + { + switch (e.ProgressType) + { + case ArchiveProgressType.StartFile: + { + Console.WriteLine("StartFile: {0}", e.CurrentFileName); + } break; + case ArchiveProgressType.FinishFile: + { + Console.WriteLine("FinishFile: {0}", e.CurrentFileName); + } break; + case ArchiveProgressType.StartArchive: + { + Console.WriteLine("StartArchive: {0} : {1}", e.CurrentArchiveNumber, e.CurrentArchiveName); + } break; + case ArchiveProgressType.FinishArchive: + { + Console.WriteLine("FinishArchive: {0} : {1}", e.CurrentArchiveNumber, e.CurrentArchiveName); + } break; + } + + File.AppendAllText(this.progressTextFile, e.ToString().Replace("\n", Environment.NewLine)); + + if (CompressionTestUtil.expectedProgress != null && + e.ProgressType != ArchiveProgressType.PartialFile && + e.ProgressType != ArchiveProgressType.PartialArchive) + { + Assert.AreNotEqual(0, CompressionTestUtil.expectedProgress.Count); + int[] expected = CompressionTestUtil.expectedProgress[0]; + CompressionTestUtil.expectedProgress.RemoveAt(0); + Assert.AreEqual((ArchiveProgressType) expected[0], e.ProgressType, "Checking ProgressType."); + Assert.AreEqual(expected[1], e.CurrentFileNumber, "Checking CurrentFileNumber."); + Assert.AreEqual(expected[2], e.TotalFiles, "Checking TotalFiles."); + Assert.AreEqual(expected[4], e.CurrentArchiveNumber, "Checking CurrentArchiveNumber."); + Assert.AreEqual(expected[5], e.TotalArchives, "Checking TotalArchives."); + } + } + + public static bool CompareDirectories(string dirA, string dirB) + { + bool difference = false; + Console.WriteLine("Comparing directories {0}, {1}", dirA, dirB); + + string[] filesA = Directory.GetFiles(dirA); + string[] filesB = Directory.GetFiles(dirB); + for (int iA = 0; iA < filesA.Length; iA++) + { + filesA[iA] = Path.GetFileName(filesA[iA]); + } + for (int iB = 0; iB < filesB.Length; iB++) + { + filesB[iB] = Path.GetFileName(filesB[iB]); + } + Array.Sort(filesA); + Array.Sort(filesB); + + for (int iA = 0, iB = 0; iA < filesA.Length || iB < filesB.Length; ) + { + int comp; + if (iA == filesA.Length) + { + comp = 1; + } + else if (iB == filesB.Length) + { + comp = -1; + } + else + { + comp = String.Compare(filesA[iA], filesB[iB]); + } + if (comp < 0) + { + Console.WriteLine("< " + filesA[iA]); + difference = true; + iA++; + } + else if (comp > 0) + { + Console.WriteLine("> " + filesB[iB]); + difference = true; + iB++; + } + else + { + string fileA = Path.Combine(dirA, filesA[iA]); + string fileB = Path.Combine(dirB, filesB[iB]); + + byte[] hashA; + byte[] hashB; + + lock (CompressionTestUtil.md5) + { + using (Stream fileAStream = File.OpenRead(fileA)) + { + hashA = CompressionTestUtil.md5.ComputeHash(fileAStream); + } + using (Stream fileBStream = File.OpenRead(fileB)) + { + hashB = CompressionTestUtil.md5.ComputeHash(fileBStream); + } + } + + for (int i = 0; i < hashA.Length; i++) + { + if (hashA[i] != hashB[i]) + { + Console.WriteLine("~ " + filesA[iA]); + difference = true; + break; + } + } + + iA++; + iB++; + } + } + + string[] dirsA = Directory.GetDirectories(dirA); + string[] dirsB = Directory.GetDirectories(dirB); + for (int iA = 0; iA < dirsA.Length; iA++) + { + dirsA[iA] = Path.GetFileName(dirsA[iA]); + } + for (int iB = 0; iB < dirsB.Length; iB++) + { + dirsB[iB] = Path.GetFileName(dirsB[iB]); + } + Array.Sort(dirsA); + Array.Sort(dirsB); + + for (int iA = 0, iB = 0; iA < dirsA.Length || iB < dirsB.Length; ) + { + int comp; + if (iA == dirsA.Length) + { + comp = 1; + } + else if (iB == dirsB.Length) + { + comp = -1; + } + else + { + comp = String.Compare(dirsA[iA], dirsB[iB]); + } + if (comp < 0) + { + Console.WriteLine("< {0}\\", dirsA[iA]); + difference = true; + iA++; + } + else if (comp > 0) + { + Console.WriteLine("> {1}\\", dirsB[iB]); + difference = true; + iB++; + } + else + { + string subDirA = Path.Combine(dirA, dirsA[iA]); + string subDirB = Path.Combine(dirB, dirsB[iB]); + if (!CompressionTestUtil.CompareDirectories(subDirA, subDirB)) + { + difference = true; + } + iA++; + iB++; + } + } + + return !difference; + } + + + public static void GenerateRandomFile(string path, int seed, long size) + { + Console.WriteLine("Generating random file {0} (seed={1}, size={2})", + path, seed, size); + Random random = new Random(seed); + bool easy = random.Next(2) == 1; + int chunk = 1024 * random.Next(1, 100); + using (TextWriter tw = new StreamWriter( + File.Create(path, 4096), Encoding.ASCII)) + { + for (long count = 0; count < size; count++) + { + char c = (char) (easy ? random.Next('a', 'b' + 1) + : random.Next(32, 127)); + tw.Write(c); + if (--chunk == 0) + { + chunk = 1024 * random.Next(1, 101); + easy = random.Next(2) == 1; + } + } + } + } + + public static void TestArchiveInfoNullParams( + ArchiveInfo archiveInfo, + string dirA, + string dirB, + string[] files) + { + Exception caughtEx = null; + try + { + archiveInfo.PackFiles(null, null, files); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.PackFiles(null, files, new string[] { }); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentOutOfRangeException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.PackFileSet(dirA, null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.PackFiles(null, files, files); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(FileNotFoundException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.PackFiles(dirA, null, files); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.PackFiles(dirA, files, null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsNull(caughtEx, "Caught exception: " + caughtEx); + + caughtEx = null; + try + { + archiveInfo.CopyTo(null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.CopyTo(null, true); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.MoveTo(null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.GetFiles(null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.UnpackFile(null, "test.txt"); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.UnpackFile("test.txt", null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.UnpackFiles(null, dirB, files); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.UnpackFiles(files, null, null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.UnpackFiles(files, null, files); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsNull(caughtEx, "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.UnpackFiles(files, dirB, null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsNull(caughtEx, "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.UnpackFiles(files, dirB, new string[] { }); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentOutOfRangeException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + archiveInfo.UnpackFileSet(null, dirB); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + } + + public static void TestCompressionEngineNullParams( + CompressionEngine engine, + ArchiveFileStreamContext streamContext, + string[] testFiles) + { + Exception caughtEx; + + Console.WriteLine("Testing null streamContext."); + caughtEx = null; + try + { + engine.Pack(null, testFiles); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + engine.Pack(null, testFiles, 0); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + + Console.WriteLine("Testing null files."); + caughtEx = null; + try + { + engine.Pack(streamContext, null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + + Console.WriteLine("Testing null files."); + caughtEx = null; + try + { + engine.Pack(streamContext, null, 0); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + + + Console.WriteLine("Testing null stream."); + caughtEx = null; + try + { + engine.IsArchive(null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + engine.FindArchiveOffset(null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + engine.GetFiles(null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + engine.GetFileInfo(null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + engine.Unpack(null, "testUnpack.txt"); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + Console.WriteLine("Testing null streamContext."); + caughtEx = null; + try + { + engine.GetFiles(null, null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + engine.GetFileInfo(null, null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + caughtEx = null; + try + { + engine.Unpack((IUnpackStreamContext) null, null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(ArgumentNullException), "Caught exception: " + caughtEx); + } + + public static void TestBadPackStreamContexts( + CompressionEngine engine, string archiveName, string[] testFiles) + { + Exception caughtEx; + + Console.WriteLine("Testing streamContext that returns null from GetName."); + caughtEx = null; + try + { + engine.Pack( + new MisbehavingStreamContext(archiveName, null, null, false, false, true, true, true, true), + testFiles); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsTrue(caughtEx is FileNotFoundException, "Caught exception: " + caughtEx); + Console.WriteLine("Testing streamContext that returns null from OpenArchive."); + caughtEx = null; + try + { + engine.Pack( + new MisbehavingStreamContext(archiveName, null, null, false, true, false, true, true, true), + testFiles); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsTrue(caughtEx is FileNotFoundException, "Caught exception: " + caughtEx); + Console.WriteLine("Testing streamContext that returns null from OpenFile."); + caughtEx = null; + try + { + engine.Pack( + new MisbehavingStreamContext(archiveName, null, null, false, true, true, true, false, true), + testFiles); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsNull(caughtEx, "Caught exception: " + caughtEx); + Console.WriteLine("Testing streamContext that throws on GetName."); + caughtEx = null; + try + { + engine.Pack( + new MisbehavingStreamContext(archiveName, null, null, true, false, true, true, true, true), + testFiles); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); + Console.WriteLine("Testing streamContext that throws on OpenArchive."); + caughtEx = null; + try + { + engine.Pack( + new MisbehavingStreamContext(archiveName, null, null, true, true, false, true, true, true), + testFiles); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); + Console.WriteLine("Testing streamContext that throws on CloseArchive."); + caughtEx = null; + try + { + engine.Pack( + new MisbehavingStreamContext(archiveName, null, null, true, true, true, false, true, true), + testFiles); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); + Console.WriteLine("Testing streamContext that throws on OpenFile."); + caughtEx = null; + try + { + engine.Pack( + new MisbehavingStreamContext(archiveName, null, null, true, true, true, true, false, true), + testFiles); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); + Console.WriteLine("Testing streamContext that throws on CloseFile."); + caughtEx = null; + try + { + engine.Pack( + new MisbehavingStreamContext(archiveName, null, null, true, true, true, true, true, false), + testFiles); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); + } + + public static void TestBadUnpackStreamContexts( + CompressionEngine engine, string archiveName) + { + Exception caughtEx; + + Console.WriteLine("Testing streamContext that returns null from OpenArchive."); + caughtEx = null; + try + { + engine.Unpack(new MisbehavingStreamContext(archiveName, null, null, false, true, false, true, true, true), null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsInstanceOfType(caughtEx, typeof(FileNotFoundException), "Caught exception: " + caughtEx); + Console.WriteLine("Testing streamContext that returns null from OpenFile."); + caughtEx = null; + try + { + engine.Unpack(new MisbehavingStreamContext(archiveName, null, null, false, true, true, true, false, true), null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsNull(caughtEx, "Caught exception: " + caughtEx); + Console.WriteLine("Testing streamContext that throws on OpenArchive."); + caughtEx = null; + try + { + engine.Unpack(new MisbehavingStreamContext(archiveName, null, null, true, true, false, true, true, true), null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); + Console.WriteLine("Testing streamContext that throws on CloseArchive."); + caughtEx = null; + try + { + engine.Unpack(new MisbehavingStreamContext(archiveName, null, null, true, true, true, false, true, true), null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); + Console.WriteLine("Testing streamContext that throws on OpenFile."); + caughtEx = null; + try + { + engine.Unpack(new MisbehavingStreamContext(archiveName, null, null, true, true, true, true, false, true), null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); + Console.WriteLine("Testing streamContext that throws on CloseFile."); + caughtEx = null; + try + { + engine.Unpack(new MisbehavingStreamContext(archiveName, null, null, true, true, true, true, true, false), null); + } + catch (Exception ex) { caughtEx = ex; } + Assert.IsTrue(caughtEx != null && caughtEx.Message == MisbehavingStreamContext.EXCEPTION, "Caught exception: " + caughtEx); + } + + public static void TestTruncatedArchive( + ArchiveInfo archiveInfo, Type expectedExceptionType) + { + for (long len = archiveInfo.Length - 1; len >= 0; len--) + { + string testArchive = String.Format("{0}.{1:d06}", + archiveInfo.FullName, len); + if (File.Exists(testArchive)) + { + File.Delete(testArchive); + } + + archiveInfo.CopyTo(testArchive); + using (FileStream truncateStream = + File.Open(testArchive, FileMode.Open, FileAccess.ReadWrite)) + { + truncateStream.SetLength(len); + } + + ArchiveInfo testArchiveInfo = (ArchiveInfo) archiveInfo.GetType() + .GetConstructor(new Type[] { typeof(string) }).Invoke(new object[] { testArchive }); + + Exception caughtEx = null; + try + { + testArchiveInfo.GetFiles(); + } + catch (Exception ex) { caughtEx = ex; } + File.Delete(testArchive); + + if (caughtEx != null) + { + Assert.IsInstanceOfType(caughtEx, expectedExceptionType, + String.Format("Caught exception listing archive truncated to {0}/{1} bytes", + len, archiveInfo.Length)); + } + } + } + } +} -- cgit v1.2.3-55-g6feb