// SplitArchives.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009-2011 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: <2011-July-14 11:07:00>
//
// ------------------------------------------------------------------
//
// This module defines tests for split (or 'spanned') archives.
//
// ------------------------------------------------------------------
// define REMOTE_FILESYSTEM in order to use a remote filesystem for storage of
// the ZIP64 large archive (which can beb huge). Leave it undefined to simply
// use the local TEMP directory.
//#define REMOTE_FILESYSTEM
using System;
using System.IO;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Interop=System.Runtime.InteropServices;
using Ionic.Zip.Tests.Utilities;
namespace Ionic.Zip.Tests.Split
{
///
/// Summary description for ErrorTests
///
[TestClass]
public class Split : IonicTestClass
{
[Interop.DllImport("kernel32.dll",
EntryPoint="CreateSymbolicLinkW",
CharSet=Interop.CharSet.Unicode)]
public static extern int CreateSymbolicLink(string lpSymlinkFileName,
string lpTargetFileName,
int dwFlags);
[TestMethod, Timeout(6 * 60*1000)]
public void Spanned_Create()
{
string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
_txrx = TestUtilities.StartProgressMonitor("segmentedzip",
"Segmented Zips",
"Creating files");
_txrx.Send("pb 0 max 2");
int numFiles = _rnd.Next(10) + 8;
int overflows = 0;
string msg;
_txrx.Send("pb 1 max " + numFiles);
var update = new Action( (x,y,z) => {
switch (x)
{
case 0:
_txrx.Send(String.Format("pb 2 max {0}", ((int)z)));
break;
case 1:
msg = String.Format("pb 2 value {0}", ((int)z));
_txrx.Send(msg);
break;
case 2:
_txrx.Send("pb 1 step");
_txrx.Send("pb 2 value 0");
msg = String.Format("status created {0}/{1} files",
y+1,
((int)z));
_txrx.Send(msg);
break;
}
});
_txrx.Send("status creating " + numFiles + " files...");
string[] filesToZip;
Dictionary checksums;
CreateLargeFilesWithChecksums(dirToZip, numFiles, update,
out filesToZip, out checksums);
_txrx.Send("pb 0 step");
int[] segmentSizes = { 0, 64*1024, 128*1024, 512*1024, 1024*1024,
2*1024*1024, 8*1024*1024, 16*1024*1024,
1024*1024*1024 };
_txrx.Send("status zipping...");
_txrx.Send(String.Format("pb 1 max {0}", segmentSizes.Length));
System.EventHandler sp = (sender1, e1) =>
{
switch (e1.EventType)
{
case ZipProgressEventType.Saving_Started:
_txrx.Send(String.Format("pb 2 max {0}", filesToZip.Length));
_txrx.Send("pb 2 value 0");
break;
case ZipProgressEventType.Saving_AfterWriteEntry:
TestContext.WriteLine("Saved entry {0}, {1} bytes",
e1.CurrentEntry.FileName,
e1.CurrentEntry.UncompressedSize);
_txrx.Send("pb 2 step");
break;
}
};
for (int m=0; m < segmentSizes.Length; m++)
{
string trialDir = String.Format("trial{0}", m);
Directory.CreateDirectory(trialDir);
string zipFileToCreate = Path.Combine(trialDir,
String.Format("Archive-{0}.zip",m));
int maxSegSize = segmentSizes[m];
msg = String.Format("status trial {0}/{1} (max seg size {2}k)",
m+1, segmentSizes.Length, maxSegSize/1024);
_txrx.Send(msg);
TestContext.WriteLine("=======");
TestContext.WriteLine("Trial {0}", m);
if (maxSegSize > 0)
TestContext.WriteLine("Creating a segmented zip...segsize({0})", maxSegSize);
else
TestContext.WriteLine("Creating a regular zip...");
var sw = new StringWriter();
bool aok = false;
try
{
using (var zip = new ZipFile())
{
zip.StatusMessageTextWriter = sw;
zip.BufferSize = 0x8000;
zip.CodecBufferSize = 0x8000;
zip.AddDirectory(dirToZip, "files");
zip.MaxOutputSegmentSize = maxSegSize;
zip.SaveProgress += sp;
zip.Save(zipFileToCreate);
}
aok = true;
}
catch (OverflowException)
{
TestContext.WriteLine("Overflow - too many segments...");
overflows++;
}
if (aok)
{
TestContext.WriteLine("{0}", sw.ToString());
// // If you want to see the diskNumber for each entry,
// // uncomment the following:
// TestContext.WriteLine("Checking info...");
// sw = new StringWriter();
// //string extractDir = String.Format("ex{0}", m);
// using (var zip = ZipFile.Read(zipFileToCreate))
// {
// zip.StatusMessageTextWriter = sw;
// foreach (string s in zip.Info.Split('\r','\n'))
// {
// Console.WriteLine("{0}", s);
// }
//
// // unnecessary - BasicVerify does this
// //foreach (var e in zip)
// //e.Extract(extractDir);
// }
// TestContext.WriteLine("{0}", sw.ToString());
TestContext.WriteLine("Extracting...");
string extractDir = BasicVerifyZip(zipFileToCreate);
// also verify checksums
VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums);
}
_txrx.Send("pb 1 step");
}
_txrx.Send("pb 0 step");
Assert.IsTrue(overflows < 3, "Too many overflows. Check the test.");
}
bool _pb1Set;
bool _pb2Set;
int _numExtracted;
int _numFilesToExtract;
int _nCycles;
void ExtractProgress(object sender, ExtractProgressEventArgs e)
{
switch (e.EventType)
{
case ZipProgressEventType.Extracting_BeforeExtractEntry:
if (!_pb1Set)
{
_txrx.Send(String.Format("pb 1 max {0}", _numFilesToExtract));
_pb1Set = true;
}
_pb2Set = false;
_nCycles = 0;
break;
case ZipProgressEventType.Extracting_EntryBytesWritten:
if (!_pb2Set)
{
_txrx.Send(String.Format("pb 2 max {0}", e.TotalBytesToTransfer));
_pb2Set = true;
}
// for performance, don't update the progress monitor every time.
_nCycles++;
if (_nCycles % 64 == 0)
{
_txrx.Send(String.Format("status Extracting entry {0}/{1} :: {2} :: {3}/{4}mb :: {5:N0}%",
_numExtracted, _numFilesToExtract,
e.CurrentEntry.FileName,
e.BytesTransferred/(1024*1024),
e.TotalBytesToTransfer/(1024*1024),
((double)e.BytesTransferred) / (0.01 * e.TotalBytesToTransfer)
));
string msg = String.Format("pb 2 value {0}", e.BytesTransferred);
_txrx.Send(msg);
}
break;
case ZipProgressEventType.Extracting_AfterExtractEntry:
_numExtracted++;
_txrx.Send("pb 1 step");
break;
}
}
[TestMethod]
[Timeout(90 * 60*1000)]
public void Create_LargeSegmentedArchive()
{
// There was a claim that large archives (around or above
// 1gb) did not work well with archive splitting. This test
// covers that case.
#if REMOTE_FILESYSTEM
string parentDir = Path.Combine("t:\\tdir", Path.GetFileNameWithoutExtension(TopLevelDir));
_FilesToRemove.Add(parentDir);
Directory.CreateDirectory(parentDir);
string zipFileToCreate = Path.Combine(parentDir,
"Create_LargeSegmentedArchive.zip");
#else
string zipFileToCreate = Path.Combine(TopLevelDir, "Create_LargeSegmentedArchive.zip");
#endif
TestContext.WriteLine("Creating file {0}", zipFileToCreate);
// This file will "cache" the randomly generated text, so we
// don't have to generate more than once. You know, for
// speed.
string cacheFile = Path.Combine(TopLevelDir, "cacheFile.txt");
// int maxSegSize = 4*1024*1024;
// int sizeBase = 20 * 1024 * 1024;
// int sizeRandom = 1 * 1024 * 1024;
// int numFiles = 3;
// int maxSegSize = 80*1024*1024;
// int sizeBase = 320 * 1024 * 1024;
// int sizeRandom = 20 * 1024 * 1024 ;
// int numFiles = 5;
int maxSegSize = 120*1024*1024;
int sizeBase = 420 * 1024 * 1024;
int sizeRandom = 20 * 1024 * 1024;
int numFiles = _rnd.Next(5) + 11;
TestContext.WriteLine("The zip will contain {0} files", numFiles);
int numSaving= 0, totalToSave = 0, numSegs= 0;
long sz = 0;
// There are a bunch of Action's here. This test method originally
// used ZipFile.AddEntry overload that accepts an opener/closer pair.
// It conjured content for the files out of a RandomTextGenerator
// stream. This worked, but was very very slow. So I took a new
// approach to use a WriteDelegate, and still contrive the data, but
// cache it for entries after the first one. This makes things go much
// faster.
//
// But, when using the WriteDelegate, the SaveProgress events of
// flavor ZipProgressEventType.Saving_EntryBytesRead do not get
// called. Therefore the progress updates are done from within the
// WriteDelegate itself. The SaveProgress events for SavingStarted,
// BeforeWriteEntry, and AfterWriteEntry do get called. As a result
// this method uses 2 delegates: one for writing and one for the
// SaveProgress events.
WriteDelegate writer = (name, stream) =>
{
Stream input = null;
Stream cache = null;
try
{
// use a cahce file as the content. The entry
// name will vary but we'll get the content for
// each entry from the a single cache file.
if (File.Exists(cacheFile))
{
input = File.Open(cacheFile,
FileMode.Open,
FileAccess.ReadWrite,
FileShare.ReadWrite);
// Make the file slightly shorter with each
// successive entry, - just to shake things
// up a little. Also seek forward a little.
var fl = input.Length;
input.SetLength(fl - _rnd.Next(sizeRandom/2) + 5201);
input.Seek(_rnd.Next(sizeRandom/2), SeekOrigin.Begin);
}
else
{
sz = sizeBase + _rnd.Next(sizeRandom);
input = new Ionic.Zip.Tests.Utilities.RandomTextInputStream((int)sz);
cache = File.Create(cacheFile);
}
_txrx.Send(String.Format("pb 2 max {0}", sz));
_txrx.Send("pb 2 value 0");
var buffer = new byte[8192];
int n;
Int64 totalWritten = 0;
int nCycles = 0;
using (input)
{
while ((n= input.Read(buffer,0, buffer.Length))>0)
{
stream.Write(buffer,0,n);
if (cache!=null)
cache.Write(buffer,0,n);
totalWritten += n;
// for performance, don't update the
// progress monitor every time.
nCycles++;
if (nCycles % 312 == 0)
{
_txrx.Send(String.Format("pb 2 value {0}", totalWritten));
_txrx.Send(String.Format("status Saving entry {0}/{1} {2} :: {3}/{4}mb {5:N0}%",
numSaving, totalToSave,
name,
totalWritten/(1024*1024), sz/(1024*1024),
((double)totalWritten) / (0.01 * sz)));
}
}
}
}
finally
{
if (cache!=null) cache.Dispose();
}
};
EventHandler sp = (sender1, e1) =>
{
switch (e1.EventType)
{
case ZipProgressEventType.Saving_Started:
numSaving= 0;
break;
case ZipProgressEventType.Saving_BeforeWriteEntry:
_txrx.Send("test Large Segmented Zip");
_txrx.Send(String.Format("status saving {0}", e1.CurrentEntry.FileName));
totalToSave = e1.EntriesTotal;
numSaving++;
break;
// case ZipProgressEventType.Saving_EntryBytesRead:
// if (!_pb2Set)
// {
// _txrx.Send(String.Format("pb 2 max {0}", e1.TotalBytesToTransfer));
// _pb2Set = true;
// }
// _txrx.Send(String.Format("status Saving entry {0}/{1} {2} :: {3}/{4}mb {5:N0}%",
// numSaving, totalToSave,
// e1.CurrentEntry.FileName,
// e1.BytesTransferred/(1024*1024), e1.TotalBytesToTransfer/(1024*1024),
// ((double)e1.BytesTransferred) / (0.01 * e1.TotalBytesToTransfer)));
// string msg = String.Format("pb 2 value {0}", e1.BytesTransferred);
// _txrx.Send(msg);
// break;
case ZipProgressEventType.Saving_AfterWriteEntry:
TestContext.WriteLine("Saved entry {0}, {1} bytes", e1.CurrentEntry.FileName,
e1.CurrentEntry.UncompressedSize);
_txrx.Send("pb 1 step");
_pb2Set = false;
break;
}
};
_txrx = TestUtilities.StartProgressMonitor("largesegmentedzip", "Large Segmented ZIP", "Creating files");
_txrx.Send("bars 3");
_txrx.Send("pb 0 max 2");
_txrx.Send(String.Format("pb 1 max {0}", numFiles));
// build a large zip file out of thin air
var sw = new StringWriter();
using (ZipFile zip = new ZipFile())
{
zip.StatusMessageTextWriter = sw;
zip.BufferSize = 256 * 1024;
zip.CodecBufferSize = 128 * 1024;
zip.MaxOutputSegmentSize = maxSegSize;
zip.SaveProgress += sp;
for (int i = 0; i < numFiles; i++)
{
string filename = TestUtilities.GetOneRandomUppercaseAsciiChar() +
Path.GetFileNameWithoutExtension(Path.GetRandomFileName()) + ".txt";
zip.AddEntry(filename, writer);
}
zip.Save(zipFileToCreate);
numSegs = zip.NumberOfSegmentsForMostRecentSave;
}
#if REMOTE_FILESYSTEM
if (((long)numSegs*maxSegSize) < (long)(1024*1024*1024L))
{
_FilesToRemove.Remove(parentDir);
Assert.IsTrue(false, "There were not enough segments in that zip. numsegs({0}) maxsize({1}).", numSegs, maxSegSize);
}
#endif
_txrx.Send("status Verifying the zip ...");
_txrx.Send("pb 0 step");
_txrx.Send("pb 1 value 0");
_txrx.Send("pb 2 value 0");
ReadOptions options = new ReadOptions
{
StatusMessageWriter = new StringWriter()
};
string extractDir = "verify";
int c = 0;
while (Directory.Exists(extractDir + c)) c++;
extractDir += c;
using (ZipFile zip2 = ZipFile.Read(zipFileToCreate, options))
{
_numFilesToExtract = zip2.Entries.Count;
_numExtracted= 1;
_pb1Set= false;
zip2.ExtractProgress += ExtractProgress;
zip2.ExtractAll(extractDir);
}
string status = options.StatusMessageWriter.ToString();
TestContext.WriteLine("status:");
foreach (string line in status.Split('\n'))
TestContext.WriteLine(line);
}
[TestMethod]
[ExpectedException(typeof(Ionic.Zip.ZipException))]
public void Spanned_InvalidSegmentSize()
{
string zipFileToCreate = "InvalidSegmentSize.zip";
int segSize = 65536/3 + _rnd.Next(65536/2);
using (var zip = new ZipFile())
{
zip.MaxOutputSegmentSize = segSize;
zip.Save(zipFileToCreate);
}
}
string _fodderDir = null;
///
/// Finds or creates and fills a cache directory of fodder files.
///
/// the name of the cache directory
String CreateSomeFiles()
{
string fodderName = "fodder";
if (_fodderDir != null)
{
CreateSymbolicLink(fodderName, _fodderDir, 1);
return fodderName;
}
int baseNumFiles = 12;
int baseSize = 0x100000;
int numFilesToAdd = baseNumFiles + _rnd.Next(4);
string tmpDir = System.Environment.GetEnvironmentVariable("TEMP");
var oldDirs = Directory.GetDirectories(tmpDir, "*.SplitArchives");
string fodderDir;
foreach (var dir in oldDirs)
{
TestContext.WriteLine("Considering directory: {0}", dir);
fodderDir = Path.Combine(dir, fodderName);
if (!Directory.Exists(fodderDir))
{
Directory.Delete(dir, true);
}
else
{
var fodderFiles = Directory.GetFiles(fodderDir, "*.txt");
if (fodderFiles.Length < baseNumFiles)
{
Directory.Delete(dir, true);
}
else
{
_fodderDir = fodderDir;
CreateSymbolicLink(fodderName, _fodderDir, 1);
return fodderName;
}
}
}
// upon reaching here, no directories exist that contain suitable
// fodder for these tests. Create the directory, and a few
// fodder files.
string pname = Path.GetFileName(TestUtilities.GenerateUniquePathname("SplitArchives"));
string cacheDir = Path.Combine(tmpDir, pname);
Directory.CreateDirectory(cacheDir);
fodderDir = Path.Combine(cacheDir, fodderName);
Directory.CreateDirectory(fodderDir);
for (int i=0; i < numFilesToAdd; i++)
{
int fileSize = baseSize + _rnd.Next(baseSize/2);
string fileName = Path.Combine(fodderDir, string.Format("Pippo{0}.txt", i));
TestUtilities.CreateAndFillFileText(fileName, fileSize);
}
_fodderDir = fodderDir;
CreateSymbolicLink(fodderName, _fodderDir, 1);
return fodderName;
}
[TestMethod]
[Timeout(5 * 60*1000)] // to protect against stuck file locks
public void Spanned_Resave_wi13915()
{
TestContext.WriteLine("Creating fodder files... {0}",
DateTime.Now.ToString("G"));
var contentDir = CreateSomeFiles();
var filesToAdd = new List(Directory.GetFiles(contentDir));
int[] segSizes = { 128, 256, 512 };
// Three passes:
// pass 1: save as regular, then resave as segmented.
// pass 2: save as segmented, then resave as regular.
// pass 3: save as segmented, then resave as another segmented archive.
for (int m=0; m < 3; m++)
{
// for various segment sizes
for (int k=0; k < segSizes.Length; k++)
{
string trialDir = String.Format("trial.{0}.{1}", m, k);
Directory.CreateDirectory(trialDir);
string zipFile1 = Path.Combine(trialDir, "InitialSave."+m+"."+k+".zip");
string zipFile2 = Path.Combine(trialDir, "Updated."+m+"."+k+".zip");
TestContext.WriteLine("");
TestContext.WriteLine("Creating zip... T({0},{1})...{2}",
m, k, DateTime.Now.ToString("G"));
using (var zip1 = new ZipFile())
{
zip1.AddFiles(filesToAdd, "");
if (m!=0)
zip1.MaxOutputSegmentSize = segSizes[k] * 1024;
zip1.Save(zipFile1);
}
TestContext.WriteLine("");
TestContext.WriteLine("Re-saving...");
using (var zip2 = ZipFile.Read(zipFile1))
{
if (m==0)
zip2.MaxOutputSegmentSize = segSizes[k] * 1024;
else if (m==2)
zip2.MaxOutputSegmentSize = 1024 * (3 * segSizes[k])/2;
zip2.Save(zipFile2);
}
TestContext.WriteLine("");
TestContext.WriteLine("Extracting...");
string extractDir = Path.Combine(trialDir,"extract");
Directory.CreateDirectory(extractDir);
using (var zip3 = ZipFile.Read(zipFile2))
{
foreach (var e in zip3)
{
TestContext.WriteLine(" {0}", e.FileName);
e.Extract(extractDir);
}
}
string[] filesUnzipped = Directory.GetFiles(extractDir);
Assert.AreEqual(filesToAdd.Count, filesUnzipped.Length,
"Incorrect number of files extracted.");
}
}
}
[TestMethod]
[Timeout(5 * 60*1000)] // to protect against stuck file locks
public void Spanned_WinZip_Unzip_wi13691()
{
if (!WinZipIsPresent)
throw new Exception("winzip is not present");
TestContext.WriteLine("Creating fodder files... {0}",
DateTime.Now.ToString("G"));
var contentDir = CreateSomeFiles();
var filesToAdd = new List(Directory.GetFiles(contentDir));
int[] segSizes = { 128, 256, 512 };
// Save as segmented, then read/extract with winzip unzip
// for various segment sizes.
for (int k=0; k < segSizes.Length; k++)
{
string trialDir = String.Format("trial.{0}", k);
Directory.CreateDirectory(trialDir);
string zipFile1 = Path.Combine(trialDir, "InitialSave."+k+".zip");
TestContext.WriteLine("");
TestContext.WriteLine("Creating zip... T({0})...{1}",
k, DateTime.Now.ToString("G"));
using (var zip1 = new ZipFile())
{
zip1.AddFiles(filesToAdd, "");
zip1.MaxOutputSegmentSize = segSizes[k] * 1024;
zip1.Save(zipFile1);
}
TestContext.WriteLine("");
TestContext.WriteLine("Extracting...");
string extractDir = Path.Combine(trialDir,"extract");
Directory.CreateDirectory(extractDir);
string args = String.Format("-d -yx {0} \"{1}\"",
zipFile1, extractDir);
this.Exec(wzunzip, args);
string[] filesUnzipped = Directory.GetFiles(extractDir);
Assert.AreEqual(filesToAdd.Count, filesUnzipped.Length,
"Incorrect number of files extracted, trail {0}", k);
}
}
#if INFOZIP_UNZIP_SUPPORTS_SPLIT_ARCHIVES
[TestMethod]
[Timeout(5 * 60*1000)] // to protect against stuck file locks
public void Spanned_InfoZip_Unzip_wi13691()
{
if (!InfoZipIsPresent)
throw new Exception("InfoZip is not present");
TestContext.WriteLine("Creating fodder files... {0}",
DateTime.Now.ToString("G"));
var contentDir = CreateSomeFiles();
var filesToAdd = new List(Directory.GetFiles(contentDir));
int[] segSizes = { 128, 256, 512 };
// Save as segmented, then read/extract with winzip unzip
// for various segment sizes.
for (int k=0; k < segSizes.Length; k++)
{
string trialDir = String.Format("trial.{0}", k);
Directory.CreateDirectory(trialDir);
string zipFile1 = Path.Combine(trialDir, "InitialSave."+k+".zip");
TestContext.WriteLine("");
TestContext.WriteLine("Creating zip... T({0})...{1}",
k, DateTime.Now.ToString("G"));
using (var zip1 = new ZipFile())
{
zip1.AddFiles(filesToAdd, "");
zip1.MaxOutputSegmentSize = segSizes[k] * 1024;
zip1.Save(zipFile1);
}
TestContext.WriteLine("");
TestContext.WriteLine("Extracting...");
string extractDir = Path.Combine(trialDir,"extract");
Directory.CreateDirectory(extractDir);
string args = String.Format("{0} -d {1}",
zipFile1,
extractDir);
this.Exec(infoZipUnzip, args);
string[] filesUnzipped = Directory.GetFiles(extractDir);
Assert.AreEqual(filesToAdd.Count, filesUnzipped.Length,
"Incorrect number of files extracted, trail {0}", k);
}
}
#endif
[TestMethod]
[Timeout(5 * 60*1000)] // to protect against stuck file locks
public void Spanned_WinZip_Zip_wi13691()
{
if (!WinZipIsPresent)
throw new Exception("WinZip is not present");
TestContext.WriteLine("Creating fodder files... {0}",
DateTime.Now.ToString("G"));
var contentDir = CreateSomeFiles();
var filesToAdd = new List(Directory.GetFiles(contentDir));
int[] segSizes = { 128, 256, 512 };
// Save as segmented, then read/extract with winzip unzip
// for various segment sizes.
for (int k=0; k < segSizes.Length; k++)
{
string trialDir = String.Format("trial.{0}", k);
Directory.CreateDirectory(trialDir);
string nameOfParts = Path.Combine(trialDir, "InitialSave."+k);
string zipFile1 = nameOfParts + ".zip";
TestContext.WriteLine("");
TestContext.WriteLine("Creating zip... T({0})...{1}",
k, DateTime.Now.ToString("G"));
// with WinZip, must produce a segmented zip in two
// steps: first create the regular zip, then split it.
// step 1: create the regular zip
string args = String.Format("-a -p -r -yx step1.zip \"{0}\"", contentDir);
string wzzipOut = this.Exec(wzzip, args);
// step 2: split the existing zip
// "wzzip -ys[size] archivetosplit.zip nameofparts "
args = String.Format("-ys{0} step1.zip {1}",
segSizes[k], zipFile1 //nameOfParts
);
wzzipOut = this.Exec(wzzip, args);
TestContext.WriteLine("");
TestContext.WriteLine("Extracting...");
string extractDir = Path.Combine(trialDir,"extract");
Directory.CreateDirectory(extractDir);
using (var zip1 = ZipFile.Read(zipFile1))
{
foreach (var e in zip1)
{
TestContext.WriteLine(" {0}", e.FileName);
e.Extract(extractDir);
}
}
string[] filesUnzipped = Directory.GetFiles(extractDir);
Assert.AreEqual(filesToAdd.Count, filesUnzipped.Length,
"Incorrect number of files extracted, trail {0}", k);
}
}
[TestMethod]
[Timeout(5 * 60*1000)] // to protect against stuck file locks
public void Spanned_InfoZip_Zip_wi13691()
{
if (!InfoZipIsPresent)
throw new Exception("InfoZip is not present");
TestContext.WriteLine("Creating fodder files... {0}",
DateTime.Now.ToString("G"));
var contentDir = CreateSomeFiles();
var filesToAdd = new List(Directory.GetFiles(contentDir));
int[] segSizes = { 128, 256, 512 };
// Save as segmented, then read/extract with winzip unzip
// for various segment sizes.
for (int k=0; k < segSizes.Length; k++)
{
string trialDir = String.Format("trial.{0}", k);
Directory.CreateDirectory(trialDir);
string zipFile1 = Path.Combine(trialDir, "InitialSave."+k+".zip");
TestContext.WriteLine("");
TestContext.WriteLine("Creating zip... T({0})...{1}",
k, DateTime.Now.ToString("G"));
string args = String.Format("-s {0}k {1} -r {2}",
segSizes[k],
zipFile1,
contentDir);
this.Exec(infoZip, args);
TestContext.WriteLine("");
TestContext.WriteLine("Extracting...");
string extractDir = Path.Combine(trialDir,"extract");
Directory.CreateDirectory(extractDir);
using (var zip1 = ZipFile.Read(zipFile1))
{
foreach (var e in zip1)
{
TestContext.WriteLine(" {0}", e.FileName);
e.Extract(extractDir);
}
}
string[] filesUnzipped =
Directory.GetFiles(Path.Combine(extractDir, contentDir));
Assert.AreEqual(filesToAdd.Count, filesUnzipped.Length,
"Incorrect number of files extracted, trail {0}", k);
}
}
}
}