Streams.cs :  » Development » DotNetZip » Ionic » Zip » Tests » Streams » 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 » Streams » Streams.cs
// Streams.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-February-10 12:13:27>
//
// ------------------------------------------------------------------
//
// This module defines tests for Streams interfaces into DotNetZip.
// ZipOutputStream, ZipInputStream, etc
//
// ------------------------------------------------------------------

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

using Ionic.Zip;
using Ionic.Zip.Tests.Utilities;


namespace Ionic.Zip.Tests.Streams{
    /// <summary>
    /// Summary description for StreamsTests
    /// </summary>
    [TestClass]
    public class StreamsTests : IonicTestClass
    {
        Ionic.CopyData.Transceiver _txrx;


        public StreamsTests() : base() { }


        // Use TestCleanup to run code after each test has run
        [TestCleanup()]
        public void MyTestCleanupEx()
        {
            if (_txrx!=null)
            {
                try
                {
                    _txrx.Send("stop");
                    _txrx = null;
                }
                catch { }
            }
        }


        EncryptionAlgorithm[] crypto =
            {
                EncryptionAlgorithm.None,
                EncryptionAlgorithm.PkzipWeak,
                EncryptionAlgorithm.WinZipAes128,
                EncryptionAlgorithm.WinZipAes256,
            };

#if NOT
        EncryptionAlgorithm[] cryptoNoPkzip =
            {
                EncryptionAlgorithm.None,
                EncryptionAlgorithm.WinZipAes128,
                EncryptionAlgorithm.WinZipAes256,
            };
#endif

        Ionic.Zlib.CompressionLevel[] compLevels =
            {
                Ionic.Zlib.CompressionLevel.None,
                Ionic.Zlib.CompressionLevel.BestSpeed,
                Ionic.Zlib.CompressionLevel.Default,
                Ionic.Zlib.CompressionLevel.BestCompression,
            };

        Zip64Option[] z64 =
            {
                Zip64Option.Never,
                Zip64Option.AsNecessary,
                Zip64Option.Always,
            };




        [TestMethod]
        public void ReadZip_OpenReader()
        {
            string[] passwords = { null, Path.GetRandomFileName(), "EE", "***()" };

            for (int j = 0; j < compLevels.Length; j++)
            {
                for (int k = 0; k < passwords.Length; k++)
                {
                    string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("ReadZip_OpenReader-{0}-{1}.zip", j, k));

                    int entriesAdded = 0;
                    String filename = null;

                    string subdir = Path.Combine(TopLevelDir, String.Format("A{0}{1}", j, k));
                    Directory.CreateDirectory(subdir);

                    int fileCount = _rnd.Next(10) + 10;
                    for (int i = 0; i < fileCount; i++)
                    {
                        filename = Path.Combine(subdir, String.Format("file{0:D2}.txt", i));
                        int filesize = _rnd.Next(34000) + 5000;
                        TestUtilities.CreateAndFillFileText(filename, filesize);
                        entriesAdded++;
                    }

                    using (ZipFile zip1 = new ZipFile())
                    {
                        zip1.CompressionLevel = compLevels[j];
                        zip1.Password = passwords[k];
                        zip1.AddDirectory(subdir, Path.GetFileName(subdir));
                        zip1.Save(zipFileToCreate);
                    }

                    // Verify the files are in the zip
                    Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entriesAdded,
                                         String.Format("Trial {0}-{1}: The Zip file has the wrong number of entries.", j, k));

                    // now extract the files and verify their contents
                    using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
                    {

                        for (int i = 0; i < 3; i++)
                        {
                            // try once with Password set on ZipFile,
                            // another with password on the entry, and
                            // a third time with password passed into the OpenReader() method.
                            if (i == 0)
                                zip2.Password = passwords[k];

                            foreach (string eName in zip2.EntryFileNames)
                            {
                                ZipEntry e1 = zip2[eName];

                                if (!e1.IsDirectory)
                                {

                                    Ionic.Zlib.CrcCalculatorStream s = null;
                                    try
                                    {
                                        if (i == 0)
                                            s = e1.OpenReader();
                                        else if (i == 1)
                                            s = e1.OpenReader(passwords[k]);
                                        else
                                        {
                                            e1.Password = passwords[k];
                                            s = e1.OpenReader();
                                        }
                                        string outFile = Path.Combine(TopLevelDir, String.Format("{0}.{1}.out", eName, i));
                                        using (var output = File.Create(outFile))
                                        {
                                            byte[] buffer = new byte[4096];
                                            int n, totalBytesRead = 0;
                                            do
                                            {
                                                n = s.Read(buffer, 0, buffer.Length);
                                                totalBytesRead += n;
                                                output.Write(buffer, 0, n);
                                            } while (n > 0);

                                            output.Flush();
                                            output.Close();
                                            TestContext.WriteLine("CRC expected({0:X8}) actual({1:X8})",
                                                                  e1.Crc, s.Crc);

                                            Assert.AreEqual<Int32>(s.Crc, e1.Crc,
                                                                   string.Format("The Entry {0} failed the CRC Check.", eName));

                                            Assert.AreEqual<Int32>(totalBytesRead, (int)e1.UncompressedSize,
                                                                   string.Format("We read an unexpected number of bytes. ({0})", eName));
                                        }
                                    }
                                    finally
                                    {
                                        if (s != null)
                                            s.Close();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }




        [TestMethod]
        public void AddEntry_JitProvided()
        {
            for (int i = 0; i < crypto.Length; i++)
            {
                for (int k = 0; k < compLevels.Length; k++)
                {
                    string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("AddEntry_JitProvided.{0}.{1}.zip", i, k));

                    string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
                    var files = TestUtilities.GenerateFilesFlat(dirToZip);

                    string password = Path.GetRandomFileName();

                    using (var zip = new ZipFile())
                    {
                        TestContext.WriteLine("=================================");
                        TestContext.WriteLine("Creating {0}...", Path.GetFileName(zipFileToCreate));
                        TestContext.WriteLine("Encryption({0})  Compression({1})  pw({2})",
                                              crypto[i].ToString(), compLevels[k].ToString(), password);

                        zip.Password = password;
                        zip.Encryption = crypto[i];
                        zip.CompressionLevel = compLevels[k];

                        foreach (var file in files)
                            zip.AddEntry(file,
                                         (name) => File.Open(name, FileMode.Open, FileAccess.Read, FileShare.ReadWrite),
                                         (name, stream) => stream.Close()
                                         );
                        zip.Save(zipFileToCreate);
                    }

                    if (crypto[i] == EncryptionAlgorithm.None)
                        BasicVerifyZip(zipFileToCreate);
                    else
                        BasicVerifyZip(zipFileToCreate, password);

                    Assert.AreEqual<int>(files.Length, TestUtilities.CountEntries(zipFileToCreate),
                                         "Trial ({0},{1}): The zip file created has the wrong number of entries.", i, k);
                }
            }
        }



        private delegate void TestCompressionLevels(string[] files, EncryptionAlgorithm crypto, bool seekable, int cycle, string format, int fileOutputOption);

        private void _TestDriver(TestCompressionLevels test, string label, bool seekable, bool zero)
        {
            _TestDriver(test, label, seekable, zero, 0);
        }


        private void _TestDriver(TestCompressionLevels test, string label, bool seekable, bool zero, int fileOutputOption)
        {
            int[] fileCounts = new int[] { 1, 2, _rnd.Next(14) + 13 };

            for (int j = 0; j < fileCounts.Length; j++)
            {
                string dirToZip = String.Format("subdir{0}", j);
                string[] files = null;
                if (zero)
                {
                    // zero length files
                    Directory.CreateDirectory(dirToZip);
                    files = new string[fileCounts[j]];
                    for (int i = 0; i < fileCounts[j]; i++)
                        files[i] = TestUtilities.CreateUniqueFile("zerolength", dirToZip);
                }
                else
                    files = TestUtilities.GenerateFilesFlat(dirToZip, fileCounts[j], 40000, 72000);


                for (int i = 0; i < crypto.Length; i++)
                {
                    string format = String.Format("{0}.{1}.filecount{2}.Encryption.{3}.{4}seekable.{5}.zip",
                                                  label,
                                                  (zero) ? "ZeroBytes" : "regular",
                                                  fileCounts[j],
                                                  crypto[i].ToString(),
                                                  seekable ? "" : "non",
                                                  "{0}");

                    test(files, crypto[i], seekable, i, format, fileOutputOption);
                }
            }
        }



        private void _Internal_AddEntry_WriteDelegate(string[] files,
                                                      EncryptionAlgorithm crypto,
                                                      bool seekable,
                                                      int cycle,
                                                      string format,
                                                      int ignored)
        {
            int BufferSize = 2048;


            for (int k = 0; k < compLevels.Length; k++)
            {
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format(format, k));
                string password = Path.GetRandomFileName();

                using (var zip = new ZipFile())
                {
                    TestContext.WriteLine("=================================");
                    TestContext.WriteLine("Creating {0}...", Path.GetFileName(zipFileToCreate));
                    TestContext.WriteLine("Encryption({0})  Compression({1})  pw({2})",
                                          crypto.ToString(), compLevels[k].ToString(), password);

                    zip.Password = password;
                    zip.Encryption = crypto;
                    zip.CompressionLevel = compLevels[k];

                    foreach (var file in files)
                    {
                        zip.AddEntry(file, (name, output) =>
                            {
                                using (var input = File.Open(name, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                                {
                                    byte[] buffer = new byte[BufferSize];
                                    int n;
                                    while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
                                    {
                                        output.Write(buffer, 0, n);
                                    }
                                }
                            });
                    }


                    if (!seekable)
                    {
                        // conditionally use a non-seekable output stream
                        using (Stream raw = File.Open(zipFileToCreate, FileMode.Create, FileAccess.ReadWrite))
                        {
                            using (var ns = new Ionic.Zip.Tests.NonSeekableOutputStream(raw))
                            {
                                zip.Save(ns);
                            }
                        }
                    }
                    else
                        zip.Save(zipFileToCreate);
                }

                BasicVerifyZip(zipFileToCreate, password);

                Assert.AreEqual<int>(files.Length, TestUtilities.CountEntries(zipFileToCreate),
                                     "Trial ({0},{1}): The zip file created has the wrong number of entries.", cycle, k);
            }
        }



        [TestMethod]
        public void AddEntry_WriteDelegate()
        {
            _TestDriver(new TestCompressionLevels(_Internal_AddEntry_WriteDelegate), "WriteDelegate", true, false);
        }


        [TestMethod]
        public void AddEntry_WriteDelegate_NonSeekable()
        {
            _TestDriver(new TestCompressionLevels(_Internal_AddEntry_WriteDelegate), "WriteDelegate", false, false);
        }


        [TestMethod]
        public void AddEntry_WriteDelegate_ZeroBytes_wi8931()
        {
            _TestDriver(new TestCompressionLevels(_Internal_AddEntry_WriteDelegate), "WriteDelegate", true, true);
        }



        [TestMethod]
        public void Create_ZipOutputStream_ZeroBytes_Encrypt_NonSeekable()
        {
            // There was a moment when using ZipOutputStream with Encryption and a
            // non-seekable output stream, did not work.  DotNetZip was changed to be
            // smarter, so that works now. This test used to verify that the combination
            // of stuff failed.  It now should succeed.

            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
            Directory.CreateDirectory(dirToZip);
            int fileCount = _rnd.Next(4)+1;
            string[] files = new string[fileCount];
            for (int i = 0; i < fileCount; i++)
                files[i] = TestUtilities.CreateUniqueFile("zerolength", dirToZip);

            for (int i = 0; i < crypto.Length; i++)
            {
                string format = String.Format("ZipOutputStream.ZeroBytes.filecount{0}.Encryption.{1}.NonSeekable.{2}.zip",
                                              fileCount,
                                              crypto[i],
                                              "{0}");

                _Internal_Create_ZipOutputStream(files, EncryptionAlgorithm.PkzipWeak, false, 99, format);
            }
        }



        [TestMethod, Timeout(1800000)]  // timeout is in milliseconds, (3600 * 1000) = 1 hour;
        public void ZipOutputStream_over_65534_Entries_PkZipEncryption_DefaultCompression_AsNecessary()
        {
            _Internal_ZipOutputStream_Zip64_over_65534_Entries(Zip64Option.AsNecessary, EncryptionAlgorithm.PkzipWeak, Ionic.Zlib.CompressionLevel.Default);
        }

        [TestMethod, Timeout(7200000)]  // timeout is in milliseconds, (3600 * 1000) = 1 hour;
        public void ZipOutputStream_over_65534_Entries_WinZipEncryption_DefaultCompression_AsNecessary()
        {
            _Internal_ZipOutputStream_Zip64_over_65534_Entries(Zip64Option.AsNecessary, EncryptionAlgorithm.WinZipAes256, Ionic.Zlib.CompressionLevel.Default);
        }

        [TestMethod, Timeout(1800000)]  // timeout is in milliseconds, (3600 * 1000) = 1 hour;
        public void ZipOutputStream_over_65534_Entries_NoEncryption_DefaultCompression_AsNecessary()
        {
            _Internal_ZipOutputStream_Zip64_over_65534_Entries(Zip64Option.AsNecessary, EncryptionAlgorithm.None, Ionic.Zlib.CompressionLevel.Default);
        }


        [TestMethod, Timeout(30 * 60 * 1000)]  // timeout is in milliseconds, (30 * 60 * 1000) = 30 mins
[ExpectedException(typeof(System.InvalidOperationException))]
public void ZipOutputStream_Zip64_over_65534_Entries_FAIL()
        {
            _Internal_ZipOutputStream_Zip64_over_65534_Entries(Zip64Option.Never, EncryptionAlgorithm.PkzipWeak, Ionic.Zlib.CompressionLevel.Default);
        }


        int fileCount;
        private void _Internal_ZipOutputStream_Zip64_over_65534_Entries(Zip64Option z64option, EncryptionAlgorithm encryption, Ionic.Zlib.CompressionLevel compression)
        {
            // Emitting a zip file with > 65534 entries requires the use of ZIP64 in the central directory.
            fileCount = _rnd.Next(7616)+65534;
            string txrxLabel = String.Format("ZipOutputStream #({0}) E({1}) C({2})",
                                             fileCount,encryption.ToString(), compression.ToString());
            string zipFileToCreate = String.Format("ZipOutputStream.Zip64.over_65534_Entries.{0}.{1}.{2}.zip",
                                                   z64option.ToString(), encryption.ToString(), compression.ToString());

            StartProgressMonitor(zipFileToCreate);
            StartProgressClient(zipFileToCreate, txrxLabel, "starting up...");

            _txrx.Send("pb 0 max 2"); // 2 stages: Write, Verify
            _txrx.Send("pb 0 value 0");

            string password = Path.GetRandomFileName();

            string statusString = String.Format("status Encryption:{0} Compression:{1}...",
                                                encryption.ToString(),
                                                compression.ToString());
            _txrx.Send(statusString);

            int dirCount= 0;

            using (FileStream fs = File.Open(zipFileToCreate, FileMode.Create, FileAccess.ReadWrite))
            {
                using (var output = new ZipOutputStream(fs))
                {
                    _txrx.Send("test " + txrxLabel);
                    System.Threading.Thread.Sleep(400);
                    _txrx.Send(String.Format("pb 1 max {0}", fileCount/4));
                    _txrx.Send("pb 1 value 0");

                    output.Password = password;
                    output.Encryption = encryption;
                    output.CompressionLevel = compression;
                    output.EnableZip64 = z64option;
                    for (int k=0; k<fileCount;  k++)
                    {
                        if (_rnd.Next(7)==0)
                        {
                            // make it a directory
                            string entryName = String.Format("{0:D4}/", k);
                            output.PutNextEntry(entryName);
                            dirCount++;
                        }
                        else
                        {
                            string entryName = String.Format("{0:D4}.txt", k);
                            output.PutNextEntry(entryName);

                            if (_rnd.Next(8)==0)
                            {
                                string content = String.Format("This is the content for entry #{0}.", k);
                                byte[] buffer = Encoding.ASCII.GetBytes(content);
                                output.Write(buffer, 0, buffer.Length);
                            }
                        }
                        if (k % 4 == 0)
                            _txrx.Send("pb 1 step");

                        if (k % 128 == 0)
                            _txrx.Send(String.Format("{0} ({1}/{2}) {3:N0}%",
                                                     statusString, k, fileCount,
                                                     ((double)k)/(0.01 * fileCount)));
                    }
                }
            }

            _txrx.Send("pb 1 max 1");
            _txrx.Send("pb 1 value 1");
            _txrx.Send("pb 0 step");

            System.Threading.Thread.Sleep(400);
            _txrx.Send(statusString + " Verifying...");

            // exec WinZip. But the output is really large, so we pass emitOutput=false .
            BasicVerifyZip(zipFileToCreate, password, false);

            Assert.AreEqual<int>(fileCount-dirCount, TestUtilities.CountEntries(zipFileToCreate),
                                 "{0}: The zip file created has the wrong number of entries.", zipFileToCreate);
            _txrx.Send("stop");
        }




        void StartProgressMonitor(string progressChannel)
        {
            string testBin = TestUtilities.GetTestBinDir(CurrentDir);
            string progressMonitorTool = Path.Combine(testBin, "Resources\\UnitTestProgressMonitor.exe");
            string requiredDll = Path.Combine(testBin, "Resources\\Ionic.CopyData.dll");
            Assert.IsTrue(File.Exists(progressMonitorTool), "progress monitor tool does not exist ({0})",  progressMonitorTool);
            Assert.IsTrue(File.Exists(requiredDll), "required DLL does not exist ({0})",  requiredDll);

            // start the progress monitor
            string ignored;
            //this.Exec(progressMonitorTool, String.Format("-channel {0}", progressChannel), false);
            TestUtilities.Exec_NoContext(progressMonitorTool, String.Format("-channel {0}", progressChannel), false, out ignored);
        }



        void StartProgressClient(string progressChannel, string title, string initialStatus)
        {
            _txrx = new Ionic.CopyData.Transceiver();
            System.Threading.Thread.Sleep(1000);
            _txrx.Channel = progressChannel;
            System.Threading.Thread.Sleep(450);
            _txrx.Send("test " + title);
            System.Threading.Thread.Sleep(120);
            _txrx.Send("status " + initialStatus);
        }




        [TestMethod]
        [ExpectedException(typeof(System.InvalidOperationException))]
        public void Create_ZipOutputStream_WriteBeforePutNextEntry()
        {
            string zipFileToCreate = "Create_ZipOutputStream_WriteBeforePutNextEntry.zip";
            using (FileStream fs = File.Open(zipFileToCreate, FileMode.Create, FileAccess.ReadWrite))
            {
                using (var output = new ZipOutputStream(fs))
                {
                    //output.PutNextEntry("entry1.txt");
                    byte[] buffer = Encoding.ASCII.GetBytes("This is the content for entry #1.");
                    output.Write(buffer, 0, buffer.Length);
                }
            }
        }




        [TestMethod]
        public void Create_ZipOutputStream_Directories()
        {
            for (int i = 0; i < crypto.Length; i++)
            {
                for (int j = 0; j < compLevels.Length; j++)
                {
                    string password = Path.GetRandomFileName();

                    for (int k = 0; k < 2; k++)
                    {
                        string zipFileToCreate = String.Format("Create_ZipOutputStream_Directories.Encryption.{0}.{1}.{2}.zip",
                                                               crypto[i].ToString(), compLevels[j].ToString(), k);

                        using (FileStream fs = File.Open(zipFileToCreate, FileMode.Create, FileAccess.ReadWrite))
                        {
                            using (var output = new ZipOutputStream(fs))
                            {
                                byte[] buffer;
                                output.Password = password;
                                output.Encryption = crypto[i];
                                output.CompressionLevel = compLevels[j];
                                output.PutNextEntry("entry1.txt");
                                if (k == 0)
                                {
                                    buffer = Encoding.ASCII.GetBytes("This is the content for entry #1.");
                                    output.Write(buffer, 0, buffer.Length);
                                }

                                output.PutNextEntry("entry2/");  // this will be a directory
                                output.PutNextEntry("entry3.txt");
                                if (k == 0)
                                {
                                    buffer = Encoding.ASCII.GetBytes("This is the content for entry #3.");
                                    output.Write(buffer, 0, buffer.Length);
                                }
                                output.PutNextEntry("entry4.txt");  // this will be zero length
                                output.PutNextEntry("entry5.txt");  // this will be zero length
                            }
                        }

                        BasicVerifyZip(zipFileToCreate, password);

                        Assert.AreEqual<int>(4, TestUtilities.CountEntries(zipFileToCreate),
                                             "Trial ({0},{1}): The zip file created has the wrong number of entries.", i, j);
                    }
                }
            }
        }





        [TestMethod]
        [ExpectedException(typeof(System.InvalidOperationException))]
        public void Create_ZipOutputStream_Directories_Write()
        {
            for (int k = 0; k < 2; k++)
            {
                string zipFileToCreate = String.Format("Create_ZipOutputStream_Directories.{0}.zip", k);

                using (FileStream fs = File.Open(zipFileToCreate, FileMode.Create, FileAccess.ReadWrite))
                {
                    using (var output = new ZipOutputStream(fs))
                    {
                        byte[] buffer;
                        output.Encryption = EncryptionAlgorithm.None;
                        output.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;
                        output.PutNextEntry("entry1/");
                        if (k == 0)
                        {
                            buffer = Encoding.ASCII.GetBytes("This is the content for entry #1.");
                            // this should fail
                            output.Write(buffer, 0, buffer.Length);
                        }

                        output.PutNextEntry("entry2/");  // this will be a directory
                        output.PutNextEntry("entry3.txt");
                        if (k == 0)
                        {
                            buffer = Encoding.ASCII.GetBytes("This is the content for entry #3.");
                            output.Write(buffer, 0, buffer.Length);
                        }
                        output.PutNextEntry("entry4.txt");  // this will be zero length
                        output.PutNextEntry("entry5.txt");  // this will be zero length
                    }
                }
            }
        }



        [TestMethod]
        public void Create_ZipOutputStream_EmptyEntries()
        {
            for (int i = 0; i < crypto.Length; i++)
            {
                for (int j = 0; j < compLevels.Length; j++)
                {
                    string password = Path.GetRandomFileName();

                    for (int k = 0; k < 2; k++)
                    {

                        string zipFileToCreate = String.Format("Create_ZipOutputStream_EmptyEntries.Encryption.{0}.{1}.{2}.zip",
                                                               crypto[i].ToString(), compLevels[j].ToString(), k);

                        using (FileStream fs = File.Open(zipFileToCreate, FileMode.Create, FileAccess.ReadWrite))
                        {
                            using (var output = new ZipOutputStream(fs))
                            {
                                byte[] buffer;
                                output.Password = password;
                                output.Encryption = crypto[i];
                                output.CompressionLevel = compLevels[j];
                                output.PutNextEntry("entry1.txt");
                                if (k == 0)
                                {
                                    buffer = Encoding.ASCII.GetBytes("This is the content for entry #1.");
                                    output.Write(buffer, 0, buffer.Length);
                                }

                                output.PutNextEntry("entry2.txt");  // this will be zero length
                                output.PutNextEntry("entry3.txt");
                                if (k == 0)
                                {
                                    buffer = Encoding.ASCII.GetBytes("This is the content for entry #3.");
                                    output.Write(buffer, 0, buffer.Length);
                                }
                                output.PutNextEntry("entry4.txt");  // this will be zero length
                                output.PutNextEntry("entry5.txt");  // this will be zero length
                            }
                        }

                        BasicVerifyZip(zipFileToCreate, password);

                        Assert.AreEqual<int>(5, TestUtilities.CountEntries(zipFileToCreate),
                                             "Trial ({0},{1}): The zip file created has the wrong number of entries.", i, j);
                    }
                }
            }
        }




        [TestMethod]
        [ExpectedException(typeof(System.ArgumentException))]
        public void Create_ZipOutputStream_DuplicateEntry()
        {
            string zipFileToCreate = "Create_ZipOutputStream_DuplicateEntry.zip";

            string entryName = Path.GetRandomFileName();

            using (FileStream fs = File.Open(zipFileToCreate, FileMode.Create, FileAccess.ReadWrite))
            {
                using (var output = new ZipOutputStream(fs))
                {
                    output.PutNextEntry(entryName);
                    output.PutNextEntry(entryName);
                }
            }
        }



        [TestMethod]
        public void Create_ZipOutputStream()
        {
            bool seekable = true;
            bool zero = false;
            _TestDriver(new TestCompressionLevels(_Internal_Create_ZipOutputStream), "ZipOutputStream", seekable, zero);
        }

        [TestMethod]
        public void Create_ZipOutputStream_file()
        {
            bool seekable = true;
            bool zero = false;
            int fileOutputOption = 1;
            _TestDriver(new TestCompressionLevels(_Internal_Create_ZipOutputStream), "ZipOutputStream", seekable, zero, fileOutputOption);
        }

        [TestMethod]
        public void Create_ZipOutputStream_NonSeekable()
        {
            bool seekable = false;
            bool zero = false;
            _TestDriver(new TestCompressionLevels(_Internal_Create_ZipOutputStream), "ZipOutputStream", seekable, zero);
        }

        [TestMethod]
        public void Create_ZipOutputStream_ZeroLength_wi8933()
        {
            bool seekable = true;
            bool zero = true;
            _TestDriver(new TestCompressionLevels(_Internal_Create_ZipOutputStream), "ZipOutputStream", seekable, zero);
        }

        [TestMethod]
        public void Create_ZipOutputStream_ZeroLength_wi8933_file()
        {
            bool seekable = true;
            bool zero = true;
            int fileOutputOption = 1;
            _TestDriver(new TestCompressionLevels(_Internal_Create_ZipOutputStream), "ZipOutputStream", seekable, zero, fileOutputOption);
        }


        private void _Internal_Create_ZipOutputStream(string[] files,
                                                      EncryptionAlgorithm crypto,
                                                      bool seekable,
                                                      int cycle,
                                                      string format)
        {
            _Internal_Create_ZipOutputStream(files, crypto, seekable, cycle, format, 0);
        }


        private void _Internal_Create_ZipOutputStream(string[] files,
                                                      EncryptionAlgorithm crypto,
                                                      bool seekable,
                                                      int cycle,
                                                      string format,
                                                      int fileOutputOption)
        {
            int BufferSize = 2048;

            for (int k = 0; k < compLevels.Length; k++)
            {
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format(format, k));
                string password = Path.GetRandomFileName();

                TestContext.WriteLine("=================================");
                TestContext.WriteLine("Creating {0}...", Path.GetFileName(zipFileToCreate));
                TestContext.WriteLine("Encryption({0})  Compression({1})  pw({2})",
                                      crypto.ToString(), compLevels[k].ToString(), password);

                using (ZipOutputStream output = GetZipOutputStream(seekable, fileOutputOption, zipFileToCreate))
                {
                    if (crypto != EncryptionAlgorithm.None)
                    {
                        output.Password = password;
                        output.Encryption = crypto;
                    }
                    output.CompressionLevel = compLevels[k];

                    byte[] buffer = new byte[BufferSize];
                    int n;
                    foreach (var file in files)
                    {
                        TestContext.WriteLine("file: {0}", file);

                        output.PutNextEntry(file);
                        using (var input = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Write))
                        {
                            while ((n = input.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                output.Write(buffer, 0, n);
                            }
                        }
                    }
                }

                BasicVerifyZip(zipFileToCreate, password);

                Assert.AreEqual<int>(files.Length, TestUtilities.CountEntries(zipFileToCreate),
                                     "Trial ({0},{1}): The zip file created has the wrong number of entries.", cycle, k);
            }
        }

        private static ZipOutputStream GetZipOutputStream(bool seekable, int fileOutputOption, string zipFileToCreate)
        {
            ZipOutputStream output = null;
            if (fileOutputOption == 0)
            {
                Stream raw = File.Open(zipFileToCreate, FileMode.Create, FileAccess.ReadWrite);

                // conditionally use a non-seekable output stream
                if (!seekable)
                    raw = new Ionic.Zip.Tests.NonSeekableOutputStream(raw);

                output = new ZipOutputStream(raw);
            }
            else
            {
                output = new ZipOutputStream(zipFileToCreate);
            }
            return output;
        }



        bool _pb2Set;
        bool _pb1Set;
        int _numSaving;
        int _totalToSave;

        private void streams_SaveProgress(object sender, SaveProgressEventArgs e)
        {
            string msg;
            switch (e.EventType)
            {
                case ZipProgressEventType.Saving_Started:
                    //_txrx.Send("status saving started...");
                    _pb1Set = false;
                    _numSaving= 1;
                    break;

                case ZipProgressEventType.Saving_BeforeWriteEntry:
                    //_txrx.Send(String.Format("status Compressing {0}", e.CurrentEntry.FileName));
                    if (!_pb1Set)
                    {
                        _txrx.Send(String.Format("pb 1 max {0}", e.EntriesTotal));
                        _pb1Set = true;
                    }
                    _totalToSave = e.EntriesTotal;
                    _pb2Set = false;
                    break;

                case ZipProgressEventType.Saving_EntryBytesRead:
                    if (!_pb2Set)
                    {
                        _txrx.Send(String.Format("pb 2 max {0}", e.TotalBytesToTransfer));
                        _pb2Set = true;
                    }

//                     _txrx.Send(String.Format("status Saving entry {0}/{1} :: {2} :: {3}/{4}mb {5:N0}%",
//                                              _numSaving, _totalToSave,
//                                              e.CurrentEntry.FileName,
//                                              e.BytesTransferred/(1024*1024), e.TotalBytesToTransfer/(1024*1024),
//                                              ((double)e.BytesTransferred) / (0.01 * e.TotalBytesToTransfer)));
                    msg = String.Format("pb 2 value {0}", e.BytesTransferred);
                    _txrx.Send(msg);
                    //System.Threading.Thread.Sleep(40);
                    break;

                case ZipProgressEventType.Saving_AfterWriteEntry:
                    _txrx.Send("pb 1 step");
                    _numSaving++;
                    break;

                case ZipProgressEventType.Saving_Completed:
                    //_txrx.Send("status Save completed");
                    _pb1Set = false;
                    _pb2Set = false;
                    _txrx.Send("pb 1 max 1");
                    _txrx.Send("pb 1 value 1");
                    break;
            }
        }


        [TestMethod, Timeout(1800000)]  // timeout is in milliseconds, (1800 * 1000) = 1/2 hour;
        public void ZipFile_Parallel_wi10030()
        {
            // Test memory growth over many many cycles.
            // There was a leak in the ParallelDeflateOutputStream, where
            // the PDOS was not being GC'd.  This test checks for that.
            //
            // If the error is present, this test will either timeout or
            // throw an InsufficientMemoryException (or whatever).  The
            // timeout occurs because GC begins to get verrrrry
            // sloooooow.  IF the error is not present, this test will
            // complete successfully, in about 20 minutes.
            //

            string zipFileToCreate = "ZipFile_Parallel_wi10030.zip";
            int nCycles = 4096;
            int nFiles = 3;
            int sizeBase = 384 * 1024;
            int sizeRange = 32 * 1024;
            int count = 0;
            int BufferSize = 1024;
            byte[] buffer = new byte[BufferSize];
            int n;

            // fill a couple memory streams with random text
            MemoryStream[] ms = new MemoryStream[nFiles];
            for (int i=0; i < ms.Length;  i++)
            {
                ms[i] = new MemoryStream();
                int sz = sizeBase + _rnd.Next(sizeRange);
                using (Stream rtg = new Ionic.Zip.Tests.Utilities.RandomTextInputStream(sz))
                {
                    while ((n = rtg.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        ms[i].Write(buffer, 0, n);
                    }
                }
            }
            buffer= null;

            OpenDelegate opener = (x) =>
                {
                    Stream s = ms[count%ms.Length];
                    s.Seek(0L,SeekOrigin.Begin);
                    count++;
                    return s;
                };

            CloseDelegate closer = (e,s) =>
                {
                    //s.Close();
                };

            string channel = "ZipFile_Parallel_wi10030";
            string txrxLabel = "PDOS Leak Test";
            StartProgressMonitor(channel);
            StartProgressClient(channel, txrxLabel, "starting up...");

            TestContext.WriteLine("Testing for leaks....");

            _txrx.Send(String.Format("pb 0 max {0}", nCycles));
            _txrx.Send("pb 0 value 0");

            for (int x=0; x < nCycles; x++)
            {
                if (x!=0 && x%16 == 0)
                    TestContext.WriteLine("Cycle {0}...", x);

                string status = String.Format("status Cycle {0}/{1}", x+1, nCycles);
                _txrx.Send(status);

                using (ZipFile zip = new ZipFile())
                {
                    zip.ParallelDeflateThreshold = 128 * 1024;
                    zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;
                    //zip.SaveProgress += streams_SaveProgress;
                    for (int y=0; y < nFiles;  y++)
                    {
                        zip.AddEntry("Entry" + y + ".txt", opener, closer);
                    }
                    zip.Comment = "Produced at " + System.DateTime.UtcNow.ToString("G");
                    zip.Save(zipFileToCreate);
                }

                _txrx.Send("pb 0 step");
            }

            for (int i=0; i < ms.Length;  i++)
            {
                ms[i].Close();
                ms[i].Dispose();
                ms[i]=null;
            }
            ms=null;
        }



        [TestMethod]
        public void ZipOutputStream_Parallel()
        {
            int _sizeBase      = 1024 * 1024;
            int _sizeRange     = 256 * 1024;
            //int _sizeBase      = 1024 * 256;
            //int _sizeRange     = 256 * 12;
            var sw             = new System.Diagnostics.Stopwatch();
            byte[] buffer      = new byte[0x8000];
            int n              = 0;
            TimeSpan[] ts      = new TimeSpan[2];
            int nFiles         = _rnd.Next(8) + 8;
            //int nFiles         = 2;
            string[] filenames = new string[nFiles];
            string dirToZip    = Path.Combine(TopLevelDir, "dirToZip");


            string channel = String.Format("ZOS_Parallel{0:000}",_rnd.Next(1000));
            string txrxLabel = "ZipOutputStream Parallel";
            StartProgressMonitor(channel);
            StartProgressClient(channel, txrxLabel, "starting up...");

            TestContext.WriteLine("Creating {0} fodder files...", nFiles);
            Directory.CreateDirectory(dirToZip);

            _txrx.Send(String.Format("pb 0 max {0}", nFiles));
            _txrx.Send("pb 0 value 0");

            sw.Start();

            for (int x=0; x < nFiles; x++)
            {
                string status = String.Format("status Creating file {0}/{1}", x+1, nFiles);
                _txrx.Send(status);

                filenames[x] = Path.Combine(dirToZip, String.Format("file{0:000}.txt", x));
                using (var output = File.Create(filenames[x]))
                {
                    using (Stream input = new Ionic.Zip.Tests.Utilities.RandomTextInputStream(_sizeBase + _rnd.Next(_sizeRange)))
                    {
                        while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            output.Write(buffer, 0, n);
                        }
                    }
                }
                _txrx.Send("pb 0 step");
            }
            sw.Stop();
            TestContext.WriteLine("file generation took {0}", sw.Elapsed);

            _txrx.Send(String.Format("pb 0 max {0}", crypto.Length));
            _txrx.Send("pb 0 value 0");

            for (int i = 0; i < crypto.Length; i++)
            {
                //int c = i;
                int c = (i + 2) % crypto.Length;

                _txrx.Send(String.Format("pb 1 max {0}", compLevels.Length));
                _txrx.Send("pb 1 value 0");

                for (int j = 0; j < compLevels.Length; j++)
                {
                    string password = Path.GetRandomFileName();

                    // I wanna do 2 cycles if there is compression, so I can compare MT
                    // vs 1T compression.  The first cycle will ALWAYS use the threaded
                    // compression, the 2nd will NEVER use it.  If
                    // CompressionLevel==None, then just do one cycle.
                    //
                    int kCycles = (compLevels[j] == Ionic.Zlib.CompressionLevel.None)
                        ? 1
                        : 2;

                    for (int k = 0; k < kCycles; k++)
                    {
                        // Also, I use Stopwatch to time the compression, and compare.
                        // In light of that, I wanna do one warmup, and then one timed
                        // trial (for t==0..2).  But here again, if CompressionLevel==None, then I
                        // don't want to do a timing comparison, so I don't need 2 trials.
                        // Therefore, in that case, the "warmup" is the only trial I want to do.
                        // So when k==1 and Compression==None, do no cycles at all.
                        //
                        int tCycles = (compLevels[j] == Ionic.Zlib.CompressionLevel.None)
                            ? ((k==0) ? 1 : 0)
                            : 2;

                        if (k==0)
                        {
                        _txrx.Send(String.Format("pb 2 max {0}", kCycles*tCycles));
                        _txrx.Send("pb 2 value 0");
                        }

                        for (int t=0; t < tCycles;  t++)
                        {
                            TestContext.WriteLine(new String('-', 72));
                            string zipFileToCreate = String.Format("ZipOutputStream_Parallel.E-{0}.C-{1}.{2}.{3}timed.zip",
                                                                   crypto[c].ToString(), compLevels[j].ToString(),
                                                                   (compLevels[j] == Ionic.Zlib.CompressionLevel.None)
                                                                   ? "NA"
                                                                   : (k==0)?"1T":"MT",
                                                                   (t==0)?"not-":"");

                            TestContext.WriteLine("Trial {0}.{1}.{2}.{3}", i,j,k,t);
                            TestContext.WriteLine("Create zip file {0}", zipFileToCreate);

                            _txrx.Send("status " + zipFileToCreate);

                            sw.Reset();
                            sw.Start();
                            using (var output = new ZipOutputStream(zipFileToCreate))
                            {
                                if (k==0)
                                    output.ParallelDeflateThreshold = -1L;   // never
                                else
                                    output.ParallelDeflateThreshold = 0L; // always

                                output.Password = password;
                                output.Encryption = crypto[c]; // maybe "None"
                                output.CompressionLevel = compLevels[j];

                                _txrx.Send(String.Format("pb 3 max {0}", nFiles));
                                _txrx.Send("pb 3 value 0");

                                for (int x=0; x < nFiles; x++)
                                {
                                    output.PutNextEntry(Path.GetFileName(filenames[x]));
                                    using (var input = File.Open(filenames[x], FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Write))
                                    {
                                        while ((n = input.Read(buffer, 0, buffer.Length)) > 0)
                                        {
                                            output.Write(buffer, 0, n);
                                        }
                                    }
                                    _txrx.Send("pb 3 step");
                                }
                            }

                            sw.Stop();
                            ts[k]= sw.Elapsed;
                            TestContext.WriteLine("compression took {0}", ts[k]);

                            //if (t==0)
                            BasicVerifyZip(zipFileToCreate, password);

                            Assert.AreEqual<int>(nFiles, TestUtilities.CountEntries(zipFileToCreate),
                                                 "Trial ({0}.{1}.{2}.{3}): The zip file created has the wrong number of entries.", i, j, k, t);

                            _txrx.Send("pb 2 step");
                        }

                    }

#if NOT_DEBUGGING
                    // parallel is not always faster!
                    if (_sizeBase > 256 * 1024 &&
                        compLevels[j] != Ionic.Zlib.CompressionLevel.None &&
                        compLevels[j] != Ionic.Zlib.CompressionLevel.BestSpeed &&
                        crypto[c] != EncryptionAlgorithm.WinZipAes256  &&
                        crypto[c] != EncryptionAlgorithm.WinZipAes128 )
                        Assert.IsTrue(ts[0]>ts[1], "Whoops! Cycle {0}.{1} (crypto({4}) Comp({5})): Parallel deflate is slower ({2}<{3})",
                                      i, j, ts[0], ts[1],
                                      crypto[c],
                                      compLevels[j]);
#endif
                    _txrx.Send("pb 1 step");
                }
                _txrx.Send("pb 0 step");
            }

            _txrx.Send("stop");
        }





        [TestMethod]
        public void Streams_7z_Zip_ZeroLength()
        {
            _Internal_Streams_7z_Zip(0, "zero");
        }

        [TestMethod]
        public void Streams_7z_Zip()
        {
            _Internal_Streams_7z_Zip(1, "nonzero");
        }

        [TestMethod]
        public void Streams_7z_Zip_Mixed()
        {
            _Internal_Streams_7z_Zip(2, "mixed");
        }

        [TestMethod]
        public void Streams_Winzip_Zip_Mixed_Password()
        {
            string password = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
            _Internal_Streams_WinZip_Zip(2, password, "mixed");
        }

        [TestMethod]
        public void Streams_Winzip_Zip()
        {
            _Internal_Streams_WinZip_Zip(1, null, "nonzero");
        }

        private string CreateZeroLengthFile(int ix, string directory)
        {
            string nameOfFileToCreate = Path.Combine(directory, String.Format("ZeroLength{0:D4}.txt", ix));
            using (var fs = File.Create(nameOfFileToCreate)) { }
            return nameOfFileToCreate;
        }


        public void _Internal_Streams_7z_Zip(int flavor, string label)
        {
            if (!SevenZipIsPresent)
            {
                TestContext.WriteLine("skipping test [_Internal_Streams_7z_Zip] : SevenZip is not present");
                return;
            }

            int[] fileCounts = { 1, 2, _rnd.Next(8) + 6, _rnd.Next(18) + 16, _rnd.Next(48) + 56 } ;

            for (int m=0; m < fileCounts.Length; m++)
            {
                string dirToZip = String.Format("trial{0:D2}",m);
                if (!Directory.Exists(dirToZip)) Directory.CreateDirectory(dirToZip);

                int fileCount = fileCounts[m];
                string zipFileToCreate = Path.Combine(TopLevelDir,
                                                      String.Format("Streams_7z_Zip.{0}.{1}.{2}.zip", flavor, label, m));

                string[] files = null;
                if (flavor == 0)
                {
                    // zero length files
                    files = new string[fileCount];
                    for (int i = 0; i < fileCount; i++)
                        files[i] = CreateZeroLengthFile(i,dirToZip);
                }
                else if (flavor == 1)
                    files = TestUtilities.GenerateFilesFlat(dirToZip, fileCount, 100, 72000);
                else
                {
                    // mixed
                    files = new string[fileCount];
                    for (int i = 0; i < fileCount; i++)
                    {
                        if (_rnd.Next(3) == 0)
                            files[i] = CreateZeroLengthFile(i,dirToZip);
                        else
                        {
                            files[i] = Path.Combine(dirToZip, String.Format("nonzero{0:D4}.txt", i));
                            TestUtilities.CreateAndFillFileText(files[i], _rnd.Next(60000)+100);
                        }
                    }
                }

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

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

                // extract the files
                string extractDir = String.Format("extract{0:D2}",m);
                byte[] buffer= new byte[2048];
                int n;
                using (var raw = File.Open(zipFileToCreate, FileMode.Open, FileAccess.Read ))
                {
                    using (var input= new ZipInputStream(raw))
                    {
                        ZipEntry e;
                        while (( e = input.GetNextEntry()) != null)
                        {
                            TestContext.WriteLine("entry: {0}", e.FileName);

                            string outputPath = Path.Combine(extractDir, e.FileName);

                            if (e.IsDirectory)
                            {
                                // create the directory
                                Directory.CreateDirectory(outputPath);
                            }
                            else
                            {
                                // create the file
                                using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite ))
                                {
                                    while ((n= input.Read(buffer,0,buffer.Length)) > 0)
                                    {
                                        output.Write(buffer,0,n);
                                    }
                                }
                            }

                            // we don't set the timestamps or attributes on the file/directory.
                        }
                    }
                }

                // winzip does not include the base path in the filename;
                // 7zip does.
                string[] filesUnzipped = Directory.GetFiles(Path.Combine(extractDir, dirToZip));

                // Verify the number of files extracted
                Assert.AreEqual<int>(files.Length, filesUnzipped.Length,
                                     "Incorrect number of files extracted.");
            }
        }


        public void _Internal_Streams_WinZip_Zip(int fodderOption, string password, string label)
        {
            if (!WinZipIsPresent)
            {
                TestContext.WriteLine("skipping test [_Internal_Streams_WinZip_Zip] : winzip is not present");
                return;
            }

            int[] fileCounts = { 1, 2, _rnd.Next(8) + 6, _rnd.Next(18) + 16, _rnd.Next(48) + 56 } ;

            for (int m=0; m < fileCounts.Length; m++)
            {
                string dirToZip = String.Format("trial{0:D2}",m);
                if (!Directory.Exists(dirToZip)) Directory.CreateDirectory(dirToZip);

                int fileCount = fileCounts[m];
                string zipFileToCreate = Path.Combine(TopLevelDir,
                                                      String.Format("Streams_Winzip_Zip.{0}.{1}.{2}.zip", fodderOption, label, m));

                string[] files = null;
                if (fodderOption == 0)
                {
                    // zero length files
                    files = new string[fileCount];
                    for (int i = 0; i < fileCount; i++)
                        files[i] = CreateZeroLengthFile(i,dirToZip);
                }
                else if (fodderOption == 1)
                    files = TestUtilities.GenerateFilesFlat(dirToZip, fileCount, 100, 72000);
                else
                {
                    // mixed
                    files = new string[fileCount];
                    for (int i = 0; i < fileCount; i++)
                    {
                        if (_rnd.Next(3) == 0)
                            files[i] = CreateZeroLengthFile(i,dirToZip);
                        else
                        {
                            files[i] = Path.Combine(dirToZip, String.Format("nonzero{0:D4}.txt", i));
                            TestUtilities.CreateAndFillFileText(files[i], _rnd.Next(60000)+100);
                        }
                    }
                }

                // Create the zip archive via WinZip.exe
                string pwdOption = String.IsNullOrEmpty(password) ? "" : "-s"+password;
                string formatString = "-a -p {0} -yx {1} {2}\\*.*";
                string wzzipOut = this.Exec(wzzip, String.Format(formatString, pwdOption, zipFileToCreate, dirToZip));

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

                // extract the files
                string extractDir = String.Format("extract{0:D2}",m);
                Directory.CreateDirectory(extractDir);
                byte[] buffer= new byte[2048];
                int n;

                using (var raw = File.Open(zipFileToCreate, FileMode.Open, FileAccess.Read ))
                {
                    using (var input= new ZipInputStream(raw))
                    {
                        input.Password = password;
                        ZipEntry e;
                        while (( e = input.GetNextEntry()) != null)
                        {
                            TestContext.WriteLine("entry: {0}", e.FileName);

                            string outputPath = Path.Combine(extractDir, e.FileName);

                            if (e.IsDirectory)
                            {
                                // create the directory
                                Directory.CreateDirectory(outputPath);
                            }
                            else
                            {
                                // create the file
                                using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite ))
                                {
                                    while ((n= input.Read(buffer,0,buffer.Length)) > 0)
                                    {
                                        output.Write(buffer,0,n);
                                    }
                                }
                            }

                            // we don't set the timestamps or attributes on the file/directory.
                        }
                    }
                }

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

                // Verify the number of files extracted
                Assert.AreEqual<int>(files.Length, filesUnzipped.Length,
                                     "Incorrect number of files extracted.");
            }
        }




        [TestMethod]
        public void Streams_ZipInput_Encryption_zero()
        {
            _Internal_Streams_ZipInput_Encryption(0);
        }

        [TestMethod]
        public void Streams_ZipInput_Encryption_zero_subdir()
        {
            _Internal_Streams_ZipInput_Encryption(3);
        }

        [TestMethod]
        public void Streams_ZipInput_Encryption_nonzero()
        {
            _Internal_Streams_ZipInput_Encryption(1);
        }


        [TestMethod]
        public void Streams_ZipInput_Encryption_nonzero_subdir()
        {
            _Internal_Streams_ZipInput_Encryption(4);
        }


        [TestMethod]
        public void Streams_ZipInput_Encryption_mixed()
        {
            _Internal_Streams_ZipInput_Encryption(2);
        }


        [TestMethod]
        public void Streams_ZipInput_Encryption_mixed_subdir()
        {
            _Internal_Streams_ZipInput_Encryption(5);
        }





        [TestMethod]
        public void Streams_ZipInput_Encryption_zero_file()
        {
            _Internal_Streams_ZipInput_Encryption(0,1);
        }

        [TestMethod]
        public void Streams_ZipInput_Encryption_zero_subdir_file()
        {
            _Internal_Streams_ZipInput_Encryption(3,1);
        }

        [TestMethod]
        public void Streams_ZipInput_Encryption_nonzero_file()
        {
            _Internal_Streams_ZipInput_Encryption(1,1);
        }


        [TestMethod]
        public void Streams_ZipInput_Encryption_nonzero_subdir_file()
        {
            _Internal_Streams_ZipInput_Encryption(4,1);
        }


        [TestMethod]
        public void Streams_ZipInput_Encryption_mixed_file()
        {
            _Internal_Streams_ZipInput_Encryption(2,1);
        }


        [TestMethod]
        public void Streams_ZipInput_Encryption_mixed_subdir_file()
        {
            _Internal_Streams_ZipInput_Encryption(5,1);
        }





        public void _Internal_Streams_ZipInput_Encryption(int fodderOption)
        {
            _Internal_Streams_ZipInput_Encryption(fodderOption, 0);
        }

        public void _Internal_Streams_ZipInput_Encryption(int fodderOption, int fileReadOption)
        {
            int[] fileCounts = { 1, 2, _rnd.Next(8) + 6, _rnd.Next(18) + 16, _rnd.Next(48) + 56 } ;

            for (int m=0; m < fileCounts.Length; m++)
            {
                string password = Path.GetRandomFileName();
                string dirToZip = String.Format("trial{0:D2}",m);
                if (!Directory.Exists(dirToZip)) Directory.CreateDirectory(dirToZip);

                int fileCount = fileCounts[m];

                string[] files = null;
                if (fodderOption == 0)
                {
                    // zero length files
                    files = new string[fileCount];
                    for (int i = 0; i < fileCount; i++)
                        files[i] = CreateZeroLengthFile(i,dirToZip);
                }
                else if (fodderOption == 1)
                    files = TestUtilities.GenerateFilesFlat(dirToZip, fileCount, 100, 72000);
                else
                {
                    // mixed = some zero and some not
                    files = new string[fileCount];
                    for (int i = 0; i < fileCount; i++)
                    {
                        if (_rnd.Next(3) == 0)
                            files[i] = CreateZeroLengthFile(i,dirToZip);
                        else
                        {
                            files[i] = Path.Combine(dirToZip, String.Format("nonzero{0:D4}.txt", i));
                            TestUtilities.CreateAndFillFileText(files[i], _rnd.Next(60000)+100);
                        }
                    }
                }

                for (int i = 0; i < crypto.Length; i++)
                {
                    EncryptionAlgorithm c = crypto[i];

                    string zipFileToCreate = Path.Combine(TopLevelDir,
                                                          String.Format("Streams_ZipInput_AES.{0}.count.{1:D2}.{2}.zip",
                                                                        c.ToString(), fileCounts[m], fodderOption));
                    // Create the zip archive
                    using (var zip = new ZipFile())
                    {
                        zip.Password = password;
                        zip.Encryption = c;
                        if (fodderOption > 2)
                        {
                            zip.AddDirectoryByName("subdir");
                            zip.AddDirectory(dirToZip, "subdir");
                        }
                        else
                            zip.AddDirectory(dirToZip);

                        zip.Save(zipFileToCreate);
                    }


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

                    // extract the files
                    string extractDir = String.Format("extract{0:D2}.{1:D2}", m, i);
                    Directory.CreateDirectory(extractDir);

                    byte[] buffer= new byte[2048];
                    int n;

                    ZipInputStream input = null;
                    if (fileReadOption == 0)
                    {
                        var raw = File.Open(zipFileToCreate, FileMode.Open, FileAccess.Read );
                        input= new ZipInputStream(raw);
                    }
                    else
                    {
                        input= new ZipInputStream(zipFileToCreate);
                    }

                    using (input)
                    {
                        // set password if necessary
                        if (crypto[i] != EncryptionAlgorithm.None)
                            input.Password = password;

                        ZipEntry e;
                        while (( e = input.GetNextEntry()) != null)
                        {
                            TestContext.WriteLine("entry: {0}", e.FileName);

                            string outputPath = Path.Combine(extractDir, e.FileName);

                            if (e.IsDirectory)
                            {
                                // create the directory
                                Directory.CreateDirectory(outputPath);
                            }
                            else
                            {
                                // emit the file
                                using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite ))
                                {
                                    while ((n= input.Read(buffer,0,buffer.Length)) > 0)
                                    {
                                        output.Write(buffer,0,n);
                                    }
                                }
                            }
                        }

                    }

                    string[] filesUnzipped = (fodderOption > 2)
                        ? Directory.GetFiles(Path.Combine(extractDir, "subdir" ))
                        : Directory.GetFiles(extractDir);

                    // Verify the number of files extracted
                    Assert.AreEqual<int>(files.Length, filesUnzipped.Length,
                                         "Incorrect number of files extracted. ({0}!={1})", files.Length, filesUnzipped.Length);
                }
            }
        }



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