Compatibility.cs :  » Development » DotNetZip » Ionic » Zip » Tests » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Development » DotNetZip 
DotNetZip » Ionic » Zip » Tests » Compatibility.cs
// Compatibility.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009-2010 Dino Chiesa .
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2010-March-29 21:12:51>
//
// ------------------------------------------------------------------
//
// This module defines the tests for compatibility for DotNetZip.  The
// idea is to verify that DotNetZip can read the zip files produced by
// other tools, and that other tools can read the output produced
// by DotNetZip. The tools and libraries tested are:
//  - WinZip,
//  - 7zip
//  - zipfldr.dll (via script)
//  - the Visual Studio DLL
//  - MS-Word
//
// ------------------------------------------------------------------


using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using Ionic.Zip;
using Ionic.Zip.Tests.Utilities;
using System.IO;


namespace Ionic.Zip.Tests{
    /// <summary>
    /// Summary description for Compatibility
    /// </summary>
    [TestClass]
    public class Compatibility : IonicTestClass
    {
        public Compatibility()
            : base()
        {
        }

        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
            // get the path to the DotNetZip DLL
            string SourceDir = System.IO.Directory.GetCurrentDirectory();
            for (int i = 0; i < 3; i++)
                SourceDir = Path.GetDirectoryName(SourceDir);

            IonicZipDll = Path.Combine(SourceDir, "Zip Full DLL\\bin\\Debug\\Ionic.Zip.dll");

            Assert.IsTrue(File.Exists(IonicZipDll), "DLL ({0}) does not exist", IonicZipDll);

            // register it for COM interop
            string output;

            int rc = TestUtilities.Exec_NoContext(RegAsm, String.Format("\"{0}\" /codebase /verbose", IonicZipDll), out output);
            if (rc != 0)
            {
                string cmd = String.Format("{0} \"{1}\" /codebase /verbose", RegAsm, IonicZipDll);
                throw new Exception(String.Format("Failed to register DotNetZip with COM rc({0}) cmd({1}) out({2})", rc, cmd, output));
            }
        }


        [ClassCleanup()]
        public static void MyClassCleanup()
        {
            string output;
            // unregister the DLL for COM interop
            int rc = TestUtilities.Exec_NoContext(RegAsm, String.Format("\"{0}\" /unregister /verbose", IonicZipDll), out output);
            if (rc != 0)
                throw new Exception(String.Format("Failed to unregister DotNetZip with COM  rc({0}) ({1})", rc, output));
        }


        private static string IonicZipDll;
        private static string RegAsm = "c:\\windows\\Microsoft.NET\\Framework\\v2.0.50727\\regasm.exe";



        private System.Reflection.Assembly _myself;
        private System.Reflection.Assembly myself
        {
            get
            {
                if (_myself == null)
                {
                    _myself = System.Reflection.Assembly.GetExecutingAssembly();
                }
                return _myself;
            }
        }


        private string _windir = null;
        private string windir
        {
            get
            {
                if (_windir == null)
                {
                    _windir = System.Environment.GetEnvironmentVariable("Windir");
                    Assert.IsTrue(Directory.Exists(_windir), "%windir% does not exist ({0})", _windir);
                }
                return _windir;
            }
        }

        private string _cscriptExe = null;
        private string cscriptExe
        {
            get
            {
                if (_cscriptExe == null)
                {
                    _cscriptExe = Path.Combine(Path.Combine(windir, "system32"), "cscript.exe");
                    Assert.IsTrue(File.Exists(_cscriptExe), "cscript.exe does not exist ({0})", _cscriptExe);
                }
                return _cscriptExe;
            }
        }


        private string GetScript(string scriptName)
        {
            // check existence of script and script engine
            string testBin = TestUtilities.GetTestBinDir(CurrentDir);
            string script = Path.Combine(testBin, String.Format("Resources\\{0}", scriptName));
            Assert.IsTrue(File.Exists(script), "script ({0}) does not exist", script);
            return script;
        }

        private void VerifyFileTimes(string extractDir,
                                            System.Collections.Generic.IEnumerable<String> filesToCheck,
                                     bool checkNtfsTimes,

                                     bool applyShellAllowance)
        {
            TimeSpan threshold = (checkNtfsTimes)
                ? new TimeSpan(10000)     // 0.01 s?  for NTFS
                : new TimeSpan(0, 0, 2);  // 2 seconds for DOS times

            TestContext.WriteLine("Using threshold: ({0})", threshold.ToString());

            foreach (var fqPath in filesToCheck)
            {
                var f = Path.GetFileName(fqPath);
                var extractedFile = Path.Combine(extractDir, f);
                Assert.IsTrue(File.Exists(extractedFile), "File does not exist ({0})", extractedFile);

                // check times
                DateTime t1 = File.GetLastWriteTimeUtc(fqPath);
                DateTime t2 = File.GetLastWriteTimeUtc(extractedFile);
                TestContext.WriteLine("{0} lastwrite orig({1})  extracted({2})",
                                      Path.GetFileName(fqPath),
                                      t1.ToString("G"),
                                      t2.ToString("G"));

                TimeSpan delta = (t1 > t2) ? t1 - t2 : t2 - t1;
                if (checkNtfsTimes)
                {
                    Assert.AreEqual<DateTime>(t1, t2, "LastWriteTime delta actual({0}) expected({1})", delta.ToString(), threshold.ToString());
                    t1 = File.GetCreationTimeUtc(fqPath);
                    t2 = File.GetCreationTimeUtc(extractedFile);
                    delta = (t1 > t2) ? t1 - t2 : t2 - t1;
                    Assert.IsTrue(delta <= threshold, "CreationTime delta actual({0}) expected({1})", delta.ToString(), threshold.ToString());
                }
                else
                {
                    if (applyShellAllowance)
                    {
                        if (delta > threshold)
                        {
                            // In some cases - specifically when the file lastmod time
                            // is on the other side of a DST event - extracting with the
                            // shell gets a time on the extracted file that is 1 hour
                            // off the expected value. This doesn't happen when WinZip
                            // or DotNetZip is used for extraction - only when using the
                            // shell extension.  In those cases we can allow for the
                            // extra hour.
                            TestContext.WriteLine("Adjusting delta for shell allowance...");
                            delta -= new TimeSpan(1, 0, 0);  // 1 hour
                        }
                    }

                    Assert.IsTrue(delta <= threshold,
                                  "LastWriteTime delta actual({0}) expected({1})",
                                  delta.ToString(),
                                  threshold.ToString());
                }
            }
        }


        private void VerifyNtfsTimes(string extractDir,
            System.Collections.Generic.IEnumerable<String> filesToCheck)
        {
            VerifyFileTimes(extractDir, filesToCheck, true, false);
        }

        private void VerifyDosTimes(string extractDir,
            System.Collections.Generic.IEnumerable<String> filesToCheck)
        {
            VerifyFileTimes(extractDir, filesToCheck, false, false);
        }


        [TestMethod]
        [ExpectedException(typeof(Ionic.Zip.ZipException))]
        public void Compat_ZipFile_Initialize_Error()
        {
            string notaZipFile = GetScript("VbsUnzip-ShellApp.vbs");

            // try to read a bogus zip archive
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.Initialize(notaZipFile);
            }
        }




        [TestMethod]
        public void Compat_ShellApplication_Unzip()
        {
            // get a set of files to zip up
            string subdir = Path.Combine(TopLevelDir, "files");
            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            var script = GetScript("VbsUnzip-ShellApp.vbs");

            var compressionLevels = Enum.GetValues(typeof(Ionic.Zlib.CompressionLevel));
            int i = 0;
            foreach (var compLevel in compressionLevels)
            {
                // create and fill the directories
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Compat_ShellApplication_Unzip.{0}.zip", i));
                string extractDir = Path.Combine(TopLevelDir, String.Format("extract.{0}", i));

                // Create the zip archive
                //Directory.SetCurrentDirectory(TopLevelDir);
                using (ZipFile zip1 = new ZipFile())
                {
                    zip1.CompressionLevel = (Ionic.Zlib.CompressionLevel)compLevel;
                    //zip.StatusMessageTextWriter = System.Console.Out;
                    for (int j = 0; j < filesToZip.Length; j++)
                        zip1.AddItem(filesToZip[j], "files");
                    zip1.Save(zipFileToCreate);
                }

                // Verify the number of files in the zip
                Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                     "Incorrect number of entries in the zip file.");

                // run the unzip script
                this.Exec(cscriptExe,
                          String.Format("\"{0}\" {1} {2}", script, zipFileToCreate, extractDir));

                // check the files in the extract dir
                VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums);

                // verify the file times
                VerifyDosTimes(Path.Combine(extractDir, "files"), filesToZip);
                i++;
            }
        }


        [TestMethod]
        public void Compat_ShellApplication_Unzip_NonSeekableOutput()
        {
            // get a set of files to zip up
            string subdir = Path.Combine(TopLevelDir, "files");
            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            var script = GetScript("VbsUnzip-ShellApp.vbs");

            var compressionLevels = Enum.GetValues(typeof(Ionic.Zlib.CompressionLevel));
            int i = 0;
            foreach (var compLevel in compressionLevels)
            {
                // create and fill the directories
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Compat_ShellApplication_Unzip_NonSeekableOutput.{0}.zip", i));
                string extractDir = Path.Combine(TopLevelDir, String.Format("extract.{0}", i));

                // Create the zip archive
                //Directory.SetCurrentDirectory(TopLevelDir);

                // Want to test the library when saving to non-seekable output streams.  Like
                // stdout or ASPNET's Response.OutputStream.  This simulates it.
                using (var rawOut = System.IO.File.Create(zipFileToCreate))
                {
                    using (var nonSeekableOut = new Ionic.Zip.Tests.NonSeekableOutputStream(rawOut))
                    {
                        using (ZipFile zip1 = new ZipFile())
                        {
                            zip1.CompressionLevel = (Ionic.Zlib.CompressionLevel)compLevel;
                            for (int j = 0; j < filesToZip.Length; j++)
                                zip1.AddItem(filesToZip[j], "files");
                            zip1.Save(nonSeekableOut);
                        }
                    }
                }

                // Verify the number of files in the zip
                Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                     "Incorrect number of entries in the zip file.");

                // run the unzip script
                this.Exec(cscriptExe,
                          String.Format("\"{0}\" {1} {2}", script, zipFileToCreate, extractDir));

                // check the files in the extract dir
                VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums);

                // verify the file times
                VerifyFileTimes(Path.Combine(extractDir, "files"), filesToZip, false, true);
                //VerifyDosTimes(Path.Combine(extractDir, "files"), filesToZip);
                i++;
            }
        }


#if SHELLAPP_UNZIP_SFX

        [TestMethod]
        public void Compat_ShellApplication_Unzip_SFX()
        {
            // get a set of files to zip up
            string subdir = Path.Combine(TopLevelDir, "files");
            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            var script = GetScript("VbsUnzip-ShellApp.vbs");

            var compressionLevels = Enum.GetValues(typeof(Ionic.Zlib.CompressionLevel));
            int i=0;
            foreach (var compLevel in compressionLevels)
            {
                // create and fill the directories
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Compat_ShellApp_Unzip_SFX.{0}.exe", i));
                string extractDir = Path.Combine(TopLevelDir, String.Format("extract.{0}",i));

                // Create the zip archive
                //Directory.SetCurrentDirectory(TopLevelDir);
                using (ZipFile zip1 = new ZipFile())
                {
                    zip1.CompressionLevel = (Ionic.Zlib.CompressionLevel) compLevel;
                    //zip.StatusMessageTextWriter = System.Console.Out;
                    for (int j = 0; j < filesToZip.Length; j++)
                        zip1.AddItem(filesToZip[j], "files");
                    zip1.SaveSelfExtractor(zipFileToCreate, SelfExtractorFlavor.ConsoleApplication);
                }

                // Verify the number of files in the zip
                Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                     "Incorrect number of entries in the zip file.");

                // run the unzip script
                this.Exec(cscriptExe,
                          String.Format("\"{0}\" {1} {2}", script, zipFileToCreate, extractDir));

                // check the files in the extract dir
                VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums);

                // verify the file times
                VerifyDosTimes(Path.Combine(extractDir, "files"), filesToZip);
                i++;
            }
        }
#endif



        [TestMethod]
        public void Compat_ShellApplication_Unzip_2()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_ShellApplication_Unzip-2.zip");
            //Directory.SetCurrentDirectory(TopLevelDir);

            // create and fill the directories
            string extractDir = Path.Combine(TopLevelDir, "extract");
            //string subdir = Path.Combine(TopLevelDir, "files");

            var checksums = new Dictionary<string, byte[]>();
            var filesToZip = GetSelectionOfTempFiles(_rnd.Next(13) + 8, checksums);

            // Create the zip archive
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.AddFiles(filesToZip, "files");
                zip1.Save(zipFileToCreate);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Count,
                                 "Incorrect number of entries in the zip file.");

            // run the unzip script
            string script = GetScript("VbsUnzip-ShellApp.vbs");

            this.Exec(cscriptExe,
                      String.Format("\"{0}\" {1} {2}", script, zipFileToCreate, extractDir));

            // check the files in the extract dir
            VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums);

            // verify the file times
            VerifyDosTimes(Path.Combine(extractDir, "files"), filesToZip);
        }



        [TestMethod]
        public void Compat_ShellApplication_SelectedFiles_Unzip()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_ShellApplication_SelectedFiles_Unzip.zip");

            TestContext.WriteLine("ZipFile version:  {0}", ZipFile.LibraryVersion);

            // create and fill the directories
            string extractDir = "extract";
            string dirToZip = "files";
            TestContext.WriteLine("creating dir '{0}' with files", dirToZip);
            Directory.CreateDirectory(dirToZip);

            int numFilesToAdd = _rnd.Next(5) + 6;
            int numFilesAdded = 0;
            int baseSize = _rnd.Next(0x100ff) + 8000;
            int nFilesInSubfolders = 0;
            Dictionary<string, byte[]> checksums = new Dictionary<string, byte[]>();
            var flist = new List<string>();
            for (int i = 0; i < numFilesToAdd && nFilesInSubfolders < 2; i++)
            {
                string fileName = string.Format("Test{0}.txt", i);
                if (i != 0)
                {
                    int x = _rnd.Next(4);
                    if (x != 0)
                    {
                        string folderName = string.Format("folder{0}", x);
                        fileName = Path.Combine(folderName, fileName);
                        if (!Directory.Exists(Path.Combine(dirToZip, folderName)))
                            Directory.CreateDirectory(Path.Combine(dirToZip, folderName));
                        nFilesInSubfolders++;
                    }
                }
                fileName = Path.Combine(dirToZip, fileName);
                TestUtilities.CreateAndFillFileBinary(fileName, baseSize + _rnd.Next(28000));
                var key = Path.GetFileName(fileName);
                var chk = TestUtilities.ComputeChecksum(fileName);
                checksums.Add(key, chk);
                flist.Add(fileName);
                numFilesAdded++;
            }

            // Create the zip archive
            var sw = new System.IO.StringWriter();
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.StatusMessageTextWriter = sw;
                //zip1.StatusMessageTextWriter = Console.Out;
                zip1.AddSelectedFiles("*.*", dirToZip, "", true);
                zip1.Save(zipFileToCreate);
            }
            TestContext.WriteLine(sw.ToString());


            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), numFilesAdded,
                                 "Incorrect number of entries in the zip file.");

            // run the unzip script
            string script = GetScript("VbsUnzip-ShellApp.vbs");

            this.Exec(cscriptExe,
                      String.Format("\"{0}\" {1} {2}", script, zipFileToCreate, Path.Combine(TopLevelDir, extractDir)));

            // check the files in the extract dir
            foreach (var fqPath in flist)
            {
                var f = Path.GetFileName(fqPath);
                var extractedFile = fqPath.Replace("files", "extract");
                Assert.IsTrue(File.Exists(extractedFile), "File does not exist ({0})", extractedFile);
                var chk = TestUtilities.ComputeChecksum(extractedFile);
                Assert.AreEqual<String>(TestUtilities.CheckSumToString(checksums[f]),
                                        TestUtilities.CheckSumToString(chk),
                                        String.Format("Checksums for file {0} do not match.", f));
                checksums.Remove(f);
            }

            Assert.AreEqual<Int32>(0, checksums.Count, "Not all of the expected files were found in the extract directory.");
        }




        [TestMethod]
        public void Compat_ShellApplication_Zip()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_ShellApplication_Zip.zip");
            //Directory.SetCurrentDirectory(TopLevelDir);

            string subdir = Path.Combine(TopLevelDir, "files");
            string extractDir = "extract";

            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            // Create the zip archive via script
            string script = GetScript("VbsCreateZip-ShellApp.vbs");

            this.Exec(cscriptExe,
                      String.Format("\"{0}\" {1} {2}", script, zipFileToCreate, subdir));

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");

            // unzip
            using (ZipFile zip1 = ZipFile.Read(zipFileToCreate))
            {
                zip1.ExtractAll(extractDir);
            }

            // check the files in the extract dir
            VerifyChecksums(extractDir, filesToZip, checksums);

            VerifyDosTimes(extractDir, filesToZip);
        }


        [TestMethod]
        public void Compat_ShellApplication_Zip_2()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_ShellApplication_Zip.zip");
            string subdir = Path.Combine(TopLevelDir, "files");
            string extractDir = "extract";

            TestContext.WriteLine("==================================================================");

            Dictionary<string, byte[]> checksums = new Dictionary<string, byte[]>();
            var filesToZip = GetSelectionOfTempFiles(_rnd.Next(33) + 11, checksums);

            Directory.CreateDirectory(subdir);
            Directory.SetCurrentDirectory(subdir);
            var w = System.Environment.GetEnvironmentVariable("Windir");
            Assert.IsTrue(Directory.Exists(w), "%windir% does not exist ({0})", w);
            var fsutil = Path.Combine(Path.Combine(w, "system32"), "fsutil.exe");
            Assert.IsTrue(File.Exists(fsutil), "fsutil.exe does not exist ({0})", fsutil);
            string ignored;

            TestContext.WriteLine("validating the list of files...");
            List<String> markedForRemoval = new List<String> ();
            // remove those with spaces in the names.  The ShellApp (zipfldr.dll) doesn't
            // deal with these files very well.  Or something.
            foreach (var f in filesToZip)
            {
                if (Path.GetFileName(f).IndexOf(' ') > 0)
                    markedForRemoval.Add(f);
            }

            foreach (var f in markedForRemoval)
            {
                TestContext.WriteLine("removing  {0}...", Path.GetFileName(f));
                filesToZip.Remove(f);
                checksums.Remove(Path.GetFileName(f));
            }


            TestContext.WriteLine("--------------------------------------------");
            TestContext.WriteLine("creating links...");
            foreach (var f in filesToZip)
            {
                string shortfile= Path.GetFileName(f);
                Assert.IsTrue(File.Exists(f));
                string cmd = String.Format("hardlink create \"{0}\" \"{1}\"", shortfile, f);
                TestUtilities.Exec_NoContext(fsutil, cmd, out ignored);
            }

            TestContext.WriteLine("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            // Create the zip archive via script
            Directory.SetCurrentDirectory(TopLevelDir);
            string script = GetScript("VbsCreateZip-ShellApp.vbs");

            this.Exec(cscriptExe,
                      String.Format("\"{0}\" {1} {2}", script, zipFileToCreate, subdir));

            // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            // DEBUGGING!
            if (TestUtilities.CountEntries(zipFileToCreate) != filesToZip.Count)
            {
                string[] linkedFiles = Directory.GetFiles(subdir);

                Action<IEnumerable<String>, string> ListFiles = (list, name) =>
                {
                    TestContext.WriteLine("**********************************");
                    TestContext.WriteLine("files in ({0})", name);
                    foreach (var s in list)
                    {
                        TestContext.WriteLine("  {0}", Path.GetFileName(s));
                    }
                    TestContext.WriteLine("----------------------------------");
                    TestContext.WriteLine("  {0} total files", list.Count());
                };

                ListFiles(linkedFiles, "Linked Files");
                ListFiles(filesToZip, "selected Files");

                IEnumerable<String> selection = null;
                using (var zip = ZipFile.Read(zipFileToCreate))
                {
                    selection = from e in zip.Entries select e.FileName;
                }

                ListFiles(selection, "zipped Files");

                foreach (var file in linkedFiles)
                {
                    if (!selection.Contains(Path.GetFileName(file)))
                    {
                        TestContext.WriteLine("Missing: {0}", Path.GetFileName(file));
                    }
                }
            }
            // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Count,
                                 "Incorrect number of entries in the zip file.");

            // unzip
            using (ZipFile zip1 = ZipFile.Read(zipFileToCreate))
            {
                zip1.ExtractAll(extractDir);
            }

            // check the files in the extract dir
            VerifyChecksums(extractDir, filesToZip, checksums);

            VerifyDosTimes(extractDir, filesToZip);
        }



        [TestMethod]
        public void Compat_VStudio_Zip()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_VStudio_Zip.zip");
            string subdir = Path.Combine(TopLevelDir, "files");
            string extractDir = "extract";

            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            //Directory.SetCurrentDirectory(TopLevelDir);

            String[] a = Array.ConvertAll(filesToZip, x => Path.GetFileName(x));
            Microsoft.VisualStudio.Zip.ZipFileCompressor zfc = new Microsoft.VisualStudio.Zip.ZipFileCompressor(zipFileToCreate, "files", a, true);

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");

            // unzip
            using (ZipFile zip1 = ZipFile.Read(zipFileToCreate))
            {
                zip1.ExtractAll(extractDir);
            }

            // check the files in the extract dir
            VerifyChecksums(extractDir, filesToZip, checksums);

            // visual Studio's ZIP library doesn't bother with times...
            //VerifyNtfsTimes(extractDir, filesToZip);
        }



        [TestMethod]
        public void Compat_VStudio_UnZip()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_VStudio_UnZip.zip");
            string subdir = Path.Combine(TopLevelDir, "files");
            string extractDir = "extract";

            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            // Create the zip archive
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                for (int i = 0; i < filesToZip.Length; i++)
                    zip1.AddItem(filesToZip[i], "files");
                zip1.Save(zipFileToCreate);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");

            // unzip
            var decompressor = new Microsoft.VisualStudio.Zip.ZipFileDecompressor(zipFileToCreate, false, true, false);
            decompressor.UncompressToFolder(extractDir, false);

            // check the files in the extract dir
            VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums);

            // visual Studio's ZIP library doesn't bother with times...
            //VerifyNtfsTimes(Path.Combine(extractDir, "files"), filesToZip);
        }



        [TestMethod]
        public void Compat_COM_Zip()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_COM_Zip.zip");
            string subdir = Path.Combine(TopLevelDir, "files");
            string extractDir = "extract";

            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            // run the COM script to create the ZIP archive
            string script = GetScript("VbsCreateZip-DotNetZip.vbs");

            this.Exec(cscriptExe,
                      String.Format("\"{0}\" {1} {2}", script, zipFileToCreate, subdir));

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");

            // unzip
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = ZipFile.Read(zipFileToCreate))
            {
                zip1.ExtractAll(extractDir);
            }

            // check the files in the extract dir
            VerifyChecksums(extractDir, filesToZip, checksums);

            VerifyNtfsTimes(extractDir, filesToZip);
        }



        [TestMethod]
        public void Compat_COM_Unzip()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_COM_Unzip.zip");

            // construct the directories
            //string ExtractDir = Path.Combine(TopLevelDir, "extract");
            string extractDir = "extract";
            string subdir = Path.Combine(TopLevelDir, "files");

            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            // Create the zip archive
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                for (int i = 0; i < filesToZip.Length; i++)
                    zip1.AddItem(filesToZip[i], "files");
                zip1.Save(zipFileToCreate);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");


            // run the COM script to unzip the ZIP archive
            string script = GetScript("VbsUnzip-DotNetZip.vbs");
            this.Exec(cscriptExe,
                      String.Format("\"{0}\" {1} {2}", script, zipFileToCreate, extractDir));


            // check the files in the extract dir
            VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums);

            VerifyNtfsTimes(Path.Combine(extractDir, "files"), filesToZip);
        }


        [TestMethod]
        public void Compat_COM_Check()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_COM_Check.zip");

            // create and fill the directories
            string subdir = Path.Combine(TopLevelDir, "files");
            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            // Create the zip archive
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                for (int i = 0; i < filesToZip.Length; i++)
                    zip1.AddItem(filesToZip[i], "files");
                zip1.Save(zipFileToCreate);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");

            // run the COM script to check the ZIP archive
            string script = GetScript("TestCheckZip.js");

            string testOut = this.Exec(cscriptExe,
                                      String.Format("\"{0}\" {1}", script, zipFileToCreate));

            Assert.IsTrue(testOut.StartsWith("That zip is OK"));
        }


        [TestMethod]
        public void Compat_COM_CheckWithExtract()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_COM_CheckWithExtract.zip");

            // create and fill the directories
            string subdir = Path.Combine(TopLevelDir, "files");
            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            // Create the zip archive
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                for (int i = 0; i < filesToZip.Length; i++)
                    zip1.AddItem(filesToZip[i], "files");
                zip1.Save(zipFileToCreate);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");

            // run the COM script to check and test-extract the ZIP archive
            string script = GetScript("TestCheckZip.js");

            string testOut = this.Exec(cscriptExe,
                                      String.Format("\"{0}\" -x {1}", script, zipFileToCreate));

            Assert.IsTrue(testOut.StartsWith("That zip is OK"), "output: {0}", testOut);
        }


        [TestMethod]
        public void Compat_COM_CheckError()
        {
            //Directory.SetCurrentDirectory(TopLevelDir);

            // run the COM script to check the (not) ZIP archive
            string script = GetScript("TestCheckZip.js");

            string testOut = this.Exec(cscriptExe,
                                      String.Format("\"{0}\" {1}", script, cscriptExe));

            Assert.IsTrue(testOut.StartsWith("That zip is not OK"));
        }


        [TestMethod]
        public void Compat_7z_Zip_1()
        {
            if (!SevenZipIsPresent)
            {
                TestContext.WriteLine("skipping test [Compat_7z_Zip_1] : SevenZip is not present");
                return;
            }

            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_7z_Zip_COM_Unzip.zip");

            //Directory.SetCurrentDirectory(TopLevelDir);


            // create and fill the directories
            //string ExtractDir = Path.Combine(TopLevelDir, "extract");
            string extractDir = "extract";
            string subdir = Path.Combine(TopLevelDir, "files");

            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            // Create the zip archive via 7z.exe
            this.Exec(sevenZip, String.Format("a {0} {1}", zipFileToCreate, subdir));

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");


            // run the COM script to unzip the ZIP archive
            string script = GetScript("VbsUnZip-DotNetZip.vbs");

            this.Exec(cscriptExe,
                      String.Format("\"{0}\" {1} {2}", script, zipFileToCreate, extractDir));

            // check the files in the extract dir
            VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums);

            VerifyNtfsTimes(Path.Combine(extractDir, "files"), filesToZip);

        }



        [TestMethod]
        public void Compat_7z_Zip_2()
        {
            if (!SevenZipIsPresent)
            {
                TestContext.WriteLine("skipping test [Compat_7z_Zip_2] : SevenZip is not present");
                return;
            }

            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_7z_Zip_2.zip");

            // create and fill the directories
            string extractDir = "extract";
            string subdir = Path.Combine(TopLevelDir, "files");

            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            // Create the zip archive via 7z.exe
            //Directory.SetCurrentDirectory(TopLevelDir);

            this.Exec(sevenZip, String.Format("a {0} {1}", zipFileToCreate, subdir));

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");

            // unzip
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = ZipFile.Read(zipFileToCreate))
            {
                zip1.ExtractAll(extractDir);
            }

            // check the files in the extract dir
            VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums);

            VerifyNtfsTimes(Path.Combine(extractDir, "files"), filesToZip);
        }



        [TestMethod]
        public void Compat_7z_Unzip()
        {
            if (!SevenZipIsPresent)
            {
                TestContext.WriteLine("skipping test [Compat_7z_Unzip] : SevenZip is not present");
                return;
            }

            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_7z_Unzip.zip");

            // create and fill the directories
            string subdir = Path.Combine(TopLevelDir, "files");

            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            // Create the zip archive with DotNetZip
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                for (int i = 0; i < filesToZip.Length; i++)
                    zip1.AddItem(filesToZip[i], "files");
                zip1.Save(zipFileToCreate);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");

            // unpack the zip archive via 7z.exe
            Directory.CreateDirectory("extract");
            Directory.SetCurrentDirectory("extract");
            this.Exec(sevenZip, String.Format("x {0}", zipFileToCreate));

            // check the files in the extract dir
            Directory.SetCurrentDirectory(TopLevelDir);

            VerifyChecksums(Path.Combine("extract", "files"), filesToZip, checksums);
        }


        [TestMethod]
        public void Compat_7z_Unzip_Password()
        {
            if (!SevenZipIsPresent)
            {
                TestContext.WriteLine("skipping test [Compat_7z_Unzip_Password] : SevenZip is not present");
                return;
            }

            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_7z_Unzip_Password.zip");
            string password = Path.GetRandomFileName();
            string subdir = Path.Combine(TopLevelDir, "files");

            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            // Create the zip archive with DotNetZip
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.Password = password;
                zip1.AddFiles(filesToZip, "files");
                zip1.Save(zipFileToCreate);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");

            // unpack the zip archive via 7z.exe
            Directory.CreateDirectory("extract");
            Directory.SetCurrentDirectory("extract");
            this.Exec(sevenZip, String.Format("x -p{0} {1}", password, zipFileToCreate));

            // check the files in the extract dir
            Directory.SetCurrentDirectory(TopLevelDir);

            VerifyChecksums(Path.Combine("extract", "files"), filesToZip, checksums);
        }




        [TestMethod]
        public void Compat_7z_Unzip_Password_NonSeekableOutput()
        {
            if (!SevenZipIsPresent)
            {
                TestContext.WriteLine("skipping test [Compat_7z_Unzip_Password_NonSeekableOutput] : SevenZip is not present");
                return;
            }

            string subdir = Path.Combine(TopLevelDir, "files");

            string[] filesToZip;
            Dictionary<string, byte[]> checksums = null;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);
            //CreateFilesAndChecksums(subdir, 2, 32, out filesToZip, out checksums);

#if NOT
            // debugging
            Directory.CreateDirectory(subdir);
            DateTime atMidnight = new DateTime(DateTime.Now.Year,
                                               DateTime.Now.Month,
                                               DateTime.Now.Day,
                                               11,11,11);
            filesToZip = new String[2];
            for (int z=0; z < 2; z++)
            {
                string fname = Path.Combine(subdir, String.Format("file{0:D3}.txt", z));
                File.WriteAllText(fname, "12341234123412341234123412341234");
                File.SetLastWriteTime(fname, atMidnight);
                File.SetLastAccessTime(fname, atMidnight);
                File.SetCreationTime(fname, atMidnight);
                filesToZip[z]= fname;
            }
#endif
            TestContext.WriteLine("Test Unzip with 7zip");
            TestContext.WriteLine("============================================");

            // marker file
            // using (File.Create(Path.Combine(TopLevelDir, "DotNetZip-" + ZipFile.LibraryVersion.ToString()))) ;

            var compressionLevels = Enum.GetValues(typeof(Ionic.Zlib.CompressionLevel));
            int i = 0;
            foreach (var compLevel in compressionLevels)
            {
                TestContext.WriteLine("---------------------------------");
                TestContext.WriteLine("Trial {0}", i);
                TestContext.WriteLine("CompressionLevel = {0}", compLevel);
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Compat_7z_Unzip_Password_NonSeekableOutput.{0}.zip", i));
                string password = Path.GetRandomFileName();
                //string password = "0123456789ABCDEF";
                string extractDir = Path.Combine(TopLevelDir, String.Format("extract.{0}", i));

                TestContext.WriteLine("Password = {0}", password);

                // Create the zip archive with DotNetZip
                //Directory.SetCurrentDirectory(TopLevelDir);
                // Want to test the library when saving to non-seekable output streams.  Like
                // stdout or ASPNET's Response.OutputStream.  This simulates it.
                using (var rawOut = System.IO.File.Create(zipFileToCreate))
                {
                    using (var nonSeekableOut = new Ionic.Zip.Tests.NonSeekableOutputStream(rawOut))
                    {
                        using (ZipFile zip1 = new ZipFile())
                        {
                            zip1.CompressionLevel = (Ionic.Zlib.CompressionLevel)compLevel;
                            zip1.Password = password;
                            zip1.AddFiles(filesToZip, "files");
                            zip1.Save(nonSeekableOut);
                        }
                    }
                }

                // Verify the number of files in the zip
                Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                     "Incorrect number of entries in the zip file.");

                // unpack the zip archive via 7z.exe
                Directory.CreateDirectory(extractDir);
                this.Exec(sevenZip, String.Format("x -o{0} -p{1} {2}",
                                                  Path.GetFileName(extractDir),
                                                  password,
                                                  zipFileToCreate));

                // check the files in the extract dir
                //Directory.SetCurrentDirectory(TopLevelDir);

                VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums);
                i++;
            }
        }



        [TestMethod]
        public void Compat_7z_Unzip_SFX()
        {
            if (!SevenZipIsPresent)
            {
                TestContext.WriteLine("skipping test [Compat_7z_Unzip_SFX] : SevenZip is not present");
                return;
            }

            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_7z_Unzip_SFX.exe");

            // create and fill the directories
            string subdir = Path.Combine(TopLevelDir, "files");

            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            // Create the zip archive with DotNetZip
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                for (int i = 0; i < filesToZip.Length; i++)
                    zip1.AddItem(filesToZip[i], "files");
                zip1.SaveSelfExtractor(zipFileToCreate, SelfExtractorFlavor.ConsoleApplication);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");

            // unpack the zip archive via 7z.exe
            Directory.CreateDirectory("extract");
            Directory.SetCurrentDirectory("extract");
            this.Exec(sevenZip, String.Format("x {0}", zipFileToCreate));

            // check the files in the extract dir
            Directory.SetCurrentDirectory(TopLevelDir);

            VerifyChecksums(Path.Combine("extract", "files"), filesToZip, checksums);
        }



        [TestMethod]
        public void Compat_Winzip_Zip()
        {
            Compat_Winzip_Zip_Variable("");
        }


        [TestMethod]
        public void Compat_Winzip_Zip_Password()
        {
            if (!WinZipIsPresent)
            {
                TestContext.WriteLine("skipping test [Compat_Winzip_Zip_Password] : winzip is not present");
                return;
            }

            string password = Path.GetRandomFileName().Replace(".", "@");
            TestContext.WriteLine("creating zip with password ({0})", password);
            string zipfile = Compat_Winzip_Zip_Variable("-s" + password, false);
            string extractDir = "extract";

            // unzip with DotNetZip
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = ZipFile.Read(zipfile))
            {
                zip1.Password = password;
                zip1.ExtractAll(extractDir);
            }
        }


        [TestMethod]
        public void Compat_Winzip_Zip_Normal()
        {
            Compat_Winzip_Zip_Variable("-en");
        }

        [TestMethod]
        public void Compat_Winzip_Zip_Fast()
        {
            Compat_Winzip_Zip_Variable("-ef");
        }

        [TestMethod]
        public void Compat_Winzip_Zip_SuperFast()
        {
            Compat_Winzip_Zip_Variable("-es");
        }

        [TestMethod]
        [ExpectedException(typeof(Ionic.Zip.ZipException))]
        public void Compat_Winzip_Zip_EZ()
        {
            if (!WinZipIsPresent) throw new Ionic.Zip.ZipException("skipping test - no winzip");
            // Unsupported compression method
            Compat_Winzip_Zip_Variable("-ez");
        }

        [TestMethod]
        [ExpectedException(typeof(Ionic.Zip.ZipException))]
        public void Compat_Winzip_Zip_PPMd()
        {
            if (!WinZipIsPresent) throw new Ionic.Zip.ZipException("skipping test - no winzip");
            // Unsupported compression method
            Compat_Winzip_Zip_Variable("-ep");
        }

        [TestMethod]
        [ExpectedException(typeof(Ionic.Zip.ZipException))]
        public void Compat_Winzip_Zip_Bzip2()
        {
            if (!WinZipIsPresent) throw new Ionic.Zip.ZipException("skipping test - no winzip");
            // Unsupported compression method
            Compat_Winzip_Zip_Variable("-eb");
        }

        [TestMethod]
        [ExpectedException(typeof(Ionic.Zip.ZipException))]
        public void Compat_Winzip_Zip_Enhanced()
        {
            if (!WinZipIsPresent) throw new Ionic.Zip.ZipException("skipping test - no winzip");
            // Unsupported compression method
            Compat_Winzip_Zip_Variable("-ee");
        }


        [TestMethod]
        [ExpectedException(typeof(Ionic.Zip.ZipException))]
        public void Compat_Winzip_Zip_LZMA()
        {
            if (!WinZipIsPresent) throw new Ionic.Zip.ZipException("skipping test - no winzip");
            // Unsupported compression method
            Compat_Winzip_Zip_Variable("-el");
        }



        public string Compat_Winzip_Zip_Variable(string options)
        {
            return Compat_Winzip_Zip_Variable(options, true);
        }

        public string Compat_Winzip_Zip_Variable(string options, bool wantVerify)
        {
            if (!WinZipIsPresent)
            {
                TestContext.WriteLine("skipping test [options({0})] : winzip is not present", options);
                return "-n/a-";
            }

            // options:
            // -sPassword
            // -ep - PPMd compression.
            // -el - LZMA compression
            // -eb - bzip2 compression
            // -ee - "enhanced" compression.
            // -en - normal compression.
            // -ef - fast compression.
            // -es - superfast compression.
            // -ez - select best method at runtime. Requires WinZip12 to extract.
            // empty string = default
            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_Winzip_Zip.zip");

            string dirInZip = "files";
            string subdir = Path.Combine(TopLevelDir, dirInZip);

            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            // delay between file creation and unzip
            System.Threading.Thread.Sleep(1200);

            // exec wzzip.exe to create the zip file
            string formatString = "-a -p " + options + " -yx {0} {1}\\*.*";
            string wzzipOut = this.Exec(wzzip, String.Format(formatString, zipFileToCreate, subdir));

            if (wantVerify)
            {
                string extractDir = "extract";
                // unzip with DotNetZip
                //Directory.SetCurrentDirectory(TopLevelDir);
                using (ZipFile zip1 = ZipFile.Read(zipFileToCreate))
                {
                    zip1.ExtractAll(extractDir);
                }

                // check the files in the extract dir
                VerifyChecksums(extractDir, filesToZip, checksums);

                // verify the file times.
                VerifyNtfsTimes(extractDir, filesToZip);
            }

            return zipFileToCreate;
        }



        [TestMethod]
        public void Compat_Winzip_Unzip_2()
        {
            if (!WinZipIsPresent)
            {
                TestContext.WriteLine("skipping test [Compat_Winzip_Unzip_2] : winzip is not present");
                return;
            }

            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_Winzip_Unzip_2.zip");

            // create and fill the directories
            string extractDir = Path.Combine(TopLevelDir, "extract");
            string subdir = Path.Combine(TopLevelDir, "files");

            Dictionary<string, byte[]> checksums = new Dictionary<string, byte[]>();
            var filesToZip = GetSelectionOfTempFiles(_rnd.Next(13) + 8, checksums);

            // Create the zip archive
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.AddFiles(filesToZip, "files");
                zip1.Save(zipFileToCreate);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Count,
                                 "Incorrect number of entries in the zip file.");

            // now, extract the zip
            // eg, wzunzip.exe -d test.zip  <extractdir>
            Directory.CreateDirectory(extractDir);
            Directory.SetCurrentDirectory(extractDir);
            this.Exec(wzunzip, String.Format("-d -yx {0}", zipFileToCreate));

            // check the files in the extract dir
            VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums);

            // verify the file times
            VerifyDosTimes(Path.Combine(extractDir, "files"), filesToZip);
        }




        [TestMethod]
        public void Compat_Winzip_Unzip_ZeroLengthFile()
        {
            if (!WinZipIsPresent)
            {
                TestContext.WriteLine("skipping test [Compat_Winzip_Unzip_ZeroLengthFile] : winzip is not present");
                return;
            }

            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_Winzip_Unzip_ZeroLengthFile.zip");

            // create an empty file
            string filename = Path.Combine(TopLevelDir, Path.GetRandomFileName());
            using (StreamWriter sw = File.CreateText(filename)) { }

            // Create the zip archive
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.AddFile(filename, "");
                zip1.Save(zipFileToCreate);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(1, TestUtilities.CountEntries(zipFileToCreate),
                                 "Incorrect number of entries in the zip file.");

            // now, test the zip
            // eg, wzunzip.exe -t test.zip  <extractdir>
            string wzunzipOut = this.Exec(wzunzip, String.Format("-t {0}", zipFileToCreate));

            TestContext.WriteLine("{0}", wzunzipOut);
            Assert.IsTrue(wzunzipOut.Contains("No errors"));
            Assert.IsFalse(wzunzipOut.Contains("At least one error was detected"));
        }



        [TestMethod]
        public void Compat_Winzip_Unzip_Password()
        {
            if (!WinZipIsPresent)
            {
                TestContext.WriteLine("skipping test [Compat_Winzip_Unzip_Password] : winzip is not present");
                return;
            }

            //Directory.SetCurrentDirectory(TopLevelDir);
            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_Winzip_Unzip_Password.zip");
            string extractDir = "extract";
            string subdir = "fodder";
            // create a bunch of files
            var filesToZip = TestUtilities.GenerateFilesFlat(subdir);
            string password = Path.GetRandomFileName();

            // Create the zip archive
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.Password = password;
                zip1.AddFiles(filesToZip, "");
                zip1.Save(zipFileToCreate);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(filesToZip.Length, TestUtilities.CountEntries(zipFileToCreate),
                                 "Incorrect number of entries in the zip file.");

            // now, test the zip
            // eg, wzunzip.exe -t test.zip  <extractdir>
            string wzunzipOut = this.Exec(wzunzip, String.Format("-t -s{0} {1}", password, zipFileToCreate));
            TestContext.WriteLine("{0}", wzunzipOut);

            Assert.IsTrue(wzunzipOut.Contains("No errors"));
            Assert.IsFalse(wzunzipOut.Contains("At least one error was detected"));

            // extract the zip
            Directory.CreateDirectory(extractDir);
            // eg, wzunzip.exe -d -yx -sPassword  test.zip  <extractdir>
            wzunzipOut = this.Exec(wzunzip, String.Format("-d -yx -s{0} {1} {2}",
                                                                password, zipFileToCreate, extractDir));

            Assert.IsFalse(wzunzipOut.Contains("skipping"));
            Assert.IsFalse(wzunzipOut.Contains("incorrect"));
        }



        [TestMethod]
        public void Compat_Winzip_Unzip_Password_NonSeekableOutput()
        {
            if (!WinZipIsPresent)
            {
                TestContext.WriteLine("skipping test [Compat_Winzip_Unzip_Password_NonSeekableOutput] : winzip is not present");
                return;
            }

            // create a bunch of files
            //Directory.SetCurrentDirectory(TopLevelDir);
            string subdir = "fodder";
            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            var compressionLevels = Enum.GetValues(typeof(Ionic.Zlib.CompressionLevel));
            int i = 0;
            foreach (var compLevel in compressionLevels)
            {
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Compat_Winzip_Unzip_Password_NonSeekableOutput.{0}.zip", i));
                string extractDir = "extract" + i.ToString();
                string password = Path.GetRandomFileName();

                //Directory.SetCurrentDirectory(TopLevelDir);

                // Want to test the library when saving to non-seekable output streams.  Like
                // stdout or ASPNET's Response.OutputStream.  This simulates it.
                using (var rawOut = System.IO.File.Create(zipFileToCreate))
                {
                    using (var nonSeekableOut = new Ionic.Zip.Tests.NonSeekableOutputStream(rawOut))
                    {
                        // Create the zip archive
                        using (ZipFile zip1 = new ZipFile())
                        {
                            zip1.CompressionLevel = (Ionic.Zlib.CompressionLevel)compLevel;
                            zip1.Password = password;
                            zip1.AddFiles(filesToZip, "files");
                            zip1.Save(nonSeekableOut);
                        }
                    }
                }

                // Verify the number of files in the zip
                Assert.AreEqual<int>(filesToZip.Length, TestUtilities.CountEntries(zipFileToCreate),
                                     "Incorrect number of entries in the zip file.");

                // now, test the zip
                // eg, wzunzip.exe -t test.zip
                string wzunzipOut = this.Exec(wzunzip, String.Format("-t -s{0} {1}", password, zipFileToCreate));
                TestContext.WriteLine("{0}", wzunzipOut);

                Assert.IsTrue(wzunzipOut.Contains("No errors"));
                Assert.IsFalse(wzunzipOut.Contains("At least one error was detected"));

                // extract the zip
                Directory.CreateDirectory(extractDir);
                // eg, wzunzip.exe -d -yx -sPassword  test.zip  <extractdir>
                wzunzipOut = this.Exec(wzunzip, String.Format("-d -yx -s{0} {1} {2}",
                                                             password, zipFileToCreate, extractDir));
                Assert.IsFalse(wzunzipOut.Contains("skipping"));
                Assert.IsFalse(wzunzipOut.Contains("incorrect"));

                // check the files in the extract dir
                VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums);

                i++;
            }
        }



        [TestMethod]
        public void Compat_Winzip_Unzip_SFX()
        {
            if (!WinZipIsPresent)
            {
                TestContext.WriteLine("skipping test [Compat_Winzip_Unzip_SFX] : winzip is not present");
                return;
            }

            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_Winzip_Unzip_SFX.exe");

            // create and fill the directories
            string extractDir = Path.Combine(TopLevelDir, "extract");
            string subdir = Path.Combine(TopLevelDir, "files");

            Dictionary<string, byte[]> checksums = new Dictionary<string, byte[]>();
            var filesToZip = GetSelectionOfTempFiles(_rnd.Next(13) + 8, checksums);

            // Create the zip archive
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.AddFiles(filesToZip, "files");
                zip1.SaveSelfExtractor(zipFileToCreate, SelfExtractorFlavor.ConsoleApplication);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Count,
                                 "Incorrect number of entries in the zip file.");

            // now, extract the zip
            // eg, wzunzip.exe -d test.zip  <extractdir>
            Directory.CreateDirectory(extractDir);
            Directory.SetCurrentDirectory(extractDir);

            // -d = restore folder structure
            // -yx = restore extended timestamps to extracted files
            this.Exec(wzunzip, String.Format("-d -yx {0}", zipFileToCreate));

            // check the files in the extract dir
            VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums);

            // verify the file times
            VerifyDosTimes(Path.Combine(extractDir, "files"), filesToZip);
        }





        [TestMethod]
        public void Compat_Winzip_Unzip_Basic()
        {
            if (!WinZipIsPresent)
            {
                TestContext.WriteLine("skipping test [Compat_Winzip_Unzip_Basic] : winzip is not present");
                return;
            }

            string zipFileToCreate = Path.Combine(TopLevelDir, "Compat_Winzip_Unzip.zip");

            string dirInZip = "files";
            string extractDir = "extract";
            string subdir = Path.Combine(TopLevelDir, dirInZip);

            string[] filesToZip;
            Dictionary<string, byte[]> checksums;
            CreateFilesAndChecksums(subdir, out filesToZip, out checksums);

            var additionalFiles = GetSelectionOfTempFiles(checksums);

            int i = 0;
            // set R and S attributes on the first file
            if (!File.Exists(filesToZip[i])) throw new Exception("Something is berry berry wrong.");
            File.SetAttributes(filesToZip[i], FileAttributes.ReadOnly | FileAttributes.System);

            // set H attribute on the second file
            i++;
            if (i == filesToZip.Length) throw new Exception("Not enough files??.");
            if (!File.Exists(filesToZip[i])) throw new Exception("Something is berry berry wrong.");
            File.SetAttributes(filesToZip[i], FileAttributes.Hidden);


            // Now, Create the zip archive with DotNetZip
            //Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.AddFiles(filesToZip, dirInZip);
                zip1.AddFiles(additionalFiles, dirInZip);
                zip1.Save(zipFileToCreate);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate),
                                 filesToZip.Length + additionalFiles.Count,
                                 "Incorrect number of entries in the zip file.");

            // examine and unpack the zip archive via WinZip
            // first, examine the zip entry metadata:
            string wzzipOut = this.Exec(wzzip, String.Format("-vt {0}", zipFileToCreate));

            string[] expectedAttrStrings = { "s-r-", "-hw-", "--w-" };

            // example: Filename: folder5\Test8.txt
            for (i = 0; i < expectedAttrStrings.Length; i++)
            {
                var f = Path.GetFileName(filesToZip[i]);
                var fileInZip = Path.Combine(dirInZip, f);
                string textToLookFor = String.Format("Filename: {0}", fileInZip.Replace("/", "\\"));
                int x = wzzipOut.IndexOf(textToLookFor);
                Assert.IsTrue(x > 0, "Could not find expected text ({0}) in WZZIP output.", textToLookFor);
                textToLookFor = "Attributes: ";
                x = wzzipOut.IndexOf(textToLookFor, x);
                string attrs = wzzipOut.Substring(x + textToLookFor.Length, 4);
                Assert.AreEqual(expectedAttrStrings[i], attrs, "Unexpected attributes on File {0}.", i);
            }


            // now, extract the zip
            // eg, wzunzip.exe -d test.zip  <extractdir>
            Directory.CreateDirectory(extractDir);
            Directory.SetCurrentDirectory(extractDir);
            this.Exec(wzunzip, String.Format("-d -yx {0}", zipFileToCreate));

            // check the files in the extract dir
            Directory.SetCurrentDirectory(TopLevelDir);
            String[] filesToCheck = new String[filesToZip.Length + additionalFiles.Count];
            filesToZip.CopyTo(filesToCheck, 0);
            additionalFiles.ToArray().CopyTo(filesToCheck, filesToZip.Length);

            VerifyChecksums(Path.Combine("extract", dirInZip), filesToCheck, checksums);

            // verify the file times
            DateTime atMidnight = new DateTime(DateTime.Now.Year,
                                               DateTime.Now.Month,
                                               DateTime.Now.Day);
            DateTime fortyFiveDaysAgo = atMidnight - new TimeSpan(45, 0, 0, 0);

            string[] extractedFiles = Directory.GetFiles(extractDir);

            foreach (var fqPath in extractedFiles)
            {
                string filename = Path.GetFileName(fqPath);
                DateTime stamp = File.GetLastWriteTime(fqPath);
                if (filename.StartsWith("testfile"))
                {
                    Assert.IsTrue((stamp == atMidnight || stamp == fortyFiveDaysAgo),
                                  "The timestamp on the file {0} is incorrect ({1}).",
                                  fqPath, stamp.ToString("yyyy-MM-dd HH:mm:ss"));
                }
                else
                {
                    var orig = (from f in additionalFiles
                                where Path.GetFileName(f) == filename
                                select f)
                        .First();

                    DateTime t1 = File.GetLastWriteTime(filename);
                    DateTime t2 = File.GetLastWriteTime(orig);
                    Assert.AreEqual<DateTime>(t1, t2);
                    t1 = File.GetCreationTime(filename);
                    t2 = File.GetCreationTime(orig);
                    Assert.AreEqual<DateTime>(t1, t2);
                }
            }
        }


        private List<string> GetSelectionOfTempFiles(Dictionary<string, byte[]> checksums)
        {
            return GetSelectionOfTempFiles(_rnd.Next(23) + 9, checksums);
        }

        private List<string> excludedFilenames = new List<string>();


        private List<string> GetSelectionOfTempFiles(int numFilesWanted, Dictionary<string, byte[]> checksums)
        {
            string tmpPath = Environment.GetEnvironmentVariable("TEMP"); // C:\Users\dinoch\AppData\Local\Temp
            String[] candidates = Directory.GetFiles(tmpPath);
            var theChosenOnes = new List<String>();
            int trials = 0;
            int otherSide = 0;
            int minOtherSide = numFilesWanted / 3 + 1;
            do
            {
                if (theChosenOnes.Count > numFilesWanted && otherSide >= minOtherSide) break;

                // randomly select a candidate
                var f = candidates[_rnd.Next(candidates.Length)];
                if (excludedFilenames.Contains(f)) continue;

                try
                {
                    var fi = new FileInfo(f);
                    if (Path.GetFileName(f)[0] == '~'
                        || theChosenOnes.Contains(f)
                        || fi.Length > 10000000  // too large
                        || fi.Length < 100)      // too small
                    {
                        excludedFilenames.Add(f);
                    }
                    else
                    {
                        DateTime lastwrite = File.GetLastWriteTime(f);
                        bool onOtherSideOfDst =
                            (DateTime.Now.IsDaylightSavingTime() && !lastwrite.IsDaylightSavingTime()) ||
                            (!DateTime.Now.IsDaylightSavingTime() && lastwrite.IsDaylightSavingTime());

                        if (onOtherSideOfDst)
                            otherSide++;

                        // If it's on the other side of DST,
                        //   or
                        // there are zero or one on *this side*
                        //   or
                        // we can still reach the "other side" quota.
                        if (onOtherSideOfDst || (theChosenOnes.Count - otherSide < 2) ||
                            ((otherSide < minOtherSide) && (numFilesWanted - theChosenOnes.Count > minOtherSide - otherSide)))
                        {
                            var key = Path.GetFileName(f);
                            var chk = TestUtilities.ComputeChecksum(f);
                            checksums.Add(key, chk);
                            theChosenOnes.Add(f);
                        }
                    }
                }
                catch { /* gulp! */ }
                trials++;
            }
            while (trials < 1000);

            theChosenOnes.Sort();
            return theChosenOnes;
        }





        [TestMethod]
        public void Extract_WinZip_SelfExtractor()
        {
            _Extract_ZipFile("winzip-sfx.exe");
        }

        [TestMethod]
        public void Extract_Docx()
        {
            _Extract_ZipFile("Vanishing Oatmeal Cookies.docx");
        }

        [TestMethod]
        public void Extract_ZipWithDuplicateNames_wi10330()
        {
            Extract_ZipFile("BadZIP ID 305491847.zip");
        }

        [TestMethod]
        public void Extract_Xlsx()
        {
            _Extract_ZipFile("Book1.xlsx");
        }

        [TestMethod]
        public void Extract_DWF()
        {
            _Extract_ZipFile("plot.dwf");
        }

        [TestMethod]
        public void Extract_InfoZipAppNote()
        {
            _Extract_ZipFile("appnote-iz-latest.zip");
        }

        [TestMethod]
        public void Extract_AndroidApp()
        {
            _Extract_ZipFile("Calendar.apk");
        }


        private void _Extract_ZipFile(string fileName)
        {
            string SourceDir = CurrentDir;
            for (int i = 0; i < 3; i++)
                SourceDir = Path.GetDirectoryName(SourceDir);

            //Directory.SetCurrentDirectory(TopLevelDir);

            TestContext.WriteLine("Current Dir: {0}", CurrentDir);

            string filename = Path.Combine(SourceDir, "Zip Tests\\bin\\Debug\\zips\\" + fileName);

            TestContext.WriteLine("Reading zip file: '{0}'", filename);
            using (ZipFile zip = ZipFile.Read(filename))
            {
                string extractDir = "extract";
                foreach (ZipEntry e in zip)
                {

                    TestContext.WriteLine("{1,-22} {2,9} {3,5:F0}%   {4,9}  {5,3} {6:X8} {0}",
                                                                         e.FileName,
                                                                         e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
                                                                         e.UncompressedSize,
                                                                         e.CompressionRatio,
                                                                         e.CompressedSize,
                                                                         (e.UsesEncryption) ? "Y" : "N",
                                                                         e.Crc);
                    e.Extract(extractDir);
                }
            }
        }



    }


}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.