Skip to content

Commit 3e865dd

Browse files
committed
Add tests for FastZip file times
1 parent 181e30f commit 3e865dd

File tree

4 files changed

+182
-3
lines changed

4 files changed

+182
-3
lines changed

src/ICSharpCode.SharpZipLib/Zip/FastZip.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ public FastZip()
200200
/// Initialise a new instance of <see cref="FastZip"/> using the specified <see cref="TimeSetting"/>
201201
/// </summary>
202202
/// <param name="timeSetting">The <see cref="TimeSetting">time setting</see> to use when creating or extracting <see cref="ZipEntry">Zip entries</see>.</param>
203+
/// <remarks>Using <see cref="TimeSetting.LastAccessTime">TimeSetting.LastAccessTime</see><see cref="TimeSetting.LastAccessTimeUtc">[Utc]</see> when
204+
/// creating an archive will set the file time to the moment of reading.
205+
/// </remarks>
203206
public FastZip(TimeSetting timeSetting)
204207
{
205208
entryFactory_ = new ZipEntryFactory(timeSetting);
@@ -209,7 +212,7 @@ public FastZip(TimeSetting timeSetting)
209212
/// <summary>
210213
/// Initialise a new instance of <see cref="FastZip"/> using the specified <see cref="DateTime"/>
211214
/// </summary>
212-
/// <param name="time">The time to set all <see cref="ZipEntry.DateTime"/> values to created or extracted <see cref="ZipEntry">Zip Entries</see>.</param>
215+
/// <param name="time">The time to set all <see cref="ZipEntry.DateTime"/> values for created or extracted <see cref="ZipEntry">Zip Entries</see>.</param>
213216
public FastZip(DateTime time)
214217
{
215218
entryFactory_ = new ZipEntryFactory(time);

src/ICSharpCode.SharpZipLib/Zip/IEntryFactory.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ public interface IEntryFactory
5959
TimeSetting Setting { get; }
6060

6161
/// <summary>
62-
/// Get the <see cref="DateTime"/> value to use when <see cref="Setting"/> is set to <see cref="TimeSetting.Fixed"/>
62+
/// Get the <see cref="DateTime"/> value to use when <see cref="Setting"/> is set to <see cref="TimeSetting.Fixed"/>,
63+
/// or if not specified, the value of <see cref="DateTime.Now"/> when the class was the initialized
6364
/// </summary>
6465
DateTime FixedDateTime { get; }
6566
}

src/ICSharpCode.SharpZipLib/Zip/ZipEntryFactory.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ public ZipEntry MakeDirectoryEntry(string directoryName, bool useFileSystem)
364364

365365
private INameTransform nameTransform_;
366366
private DateTime fixedDateTime_ = DateTime.Now;
367-
private TimeSetting timeSetting_;
367+
private TimeSetting timeSetting_ = TimeSetting.LastWriteTime;
368368
private bool isUnicodeText_;
369369

370370
private int getAttributes_ = -1;

test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs

+175
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.IO;
77
using System.Linq;
88
using System.Text;
9+
using TimeSetting = ICSharpCode.SharpZipLib.Zip.ZipEntryFactory.TimeSetting;
910

1011
namespace ICSharpCode.SharpZipLib.Tests.Zip
1112
{
@@ -686,5 +687,179 @@ public void CreateZipShouldLeaveOutputStreamOpenIfRequested(bool leaveOpen)
686687
}
687688
}
688689
}
690+
691+
[Category("Zip")]
692+
[Category("CreatesTempFile")]
693+
[Test]
694+
public void CreateZipShouldSetTimeOnEntriesFromConstructorDateTime()
695+
{
696+
var targetTime = TestTargetTime(TimeSetting.Fixed);
697+
var fastZip = new FastZip(targetTime);
698+
var target = CreateFastZipTestArchiveWithAnEntry(fastZip);
699+
var archive = new MemoryStream(target.ToArray());
700+
using (var zf = new ZipFile(archive))
701+
{
702+
Assert.AreEqual(targetTime, zf[0].DateTime);
703+
}
704+
}
705+
706+
[Category("Zip")]
707+
[Category("CreatesTempFile")]
708+
[TestCase(TimeSetting.CreateTimeUtc), TestCase(TimeSetting.LastWriteTimeUtc), TestCase(TimeSetting.LastAccessTimeUtc)]
709+
[TestCase(TimeSetting.CreateTime), TestCase(TimeSetting.LastWriteTime), TestCase(TimeSetting.LastAccessTime)]
710+
public void CreateZipShouldSetTimeOnEntriesFromConstructorTimeSetting(TimeSetting timeSetting)
711+
{
712+
var targetTime = TestTargetTime(timeSetting);
713+
var fastZip = new FastZip(timeSetting);
714+
715+
var alterTime = (Action<FileInfo>) null;
716+
switch(timeSetting)
717+
{
718+
case TimeSetting.LastWriteTime: alterTime = fi => fi.LastWriteTime = targetTime; break;
719+
case TimeSetting.LastWriteTimeUtc: alterTime = fi => fi.LastWriteTimeUtc = targetTime; break;
720+
case TimeSetting.CreateTime: alterTime = fi => fi.CreationTime = targetTime; break;
721+
case TimeSetting.CreateTimeUtc: alterTime = fi => fi.CreationTimeUtc = targetTime; break;
722+
}
723+
724+
var target = CreateFastZipTestArchiveWithAnEntry(fastZip, alterTime);
725+
// Check that the file contents are correct in both cases
726+
var archive = new MemoryStream(target.ToArray());
727+
using (var zf = new ZipFile(archive))
728+
{
729+
Assert.AreEqual(TestTargetTime(timeSetting), zf[0].DateTime);
730+
}
731+
}
732+
733+
[Category("Zip")]
734+
[Category("CreatesTempFile")]
735+
[TestCase(TimeSetting.CreateTimeUtc), TestCase(TimeSetting.LastWriteTimeUtc), TestCase(TimeSetting.LastAccessTimeUtc)]
736+
[TestCase(TimeSetting.CreateTime), TestCase(TimeSetting.LastWriteTime), TestCase(TimeSetting.LastAccessTime)]
737+
[TestCase(TimeSetting.Fixed)]
738+
public void ExtractZipShouldSetTimeOnFilesFromConstructorTimeSetting(TimeSetting timeSetting)
739+
{
740+
var targetTime = ExpectedFixedTime();
741+
var archiveStream = CreateFastZipTestArchiveWithAnEntry(new FastZip(targetTime));
742+
743+
if (timeSetting == TimeSetting.Fixed)
744+
{
745+
Assert.Ignore("Fixed time without specifying a time is undefined");
746+
}
747+
748+
var fastZip = new FastZip(timeSetting);
749+
using (var extractDir = new Utils.TempDir())
750+
{
751+
fastZip.ExtractZip(archiveStream, extractDir.Fullpath, FastZip.Overwrite.Always,
752+
_ => true, "", "", true, true, false);
753+
var fi = new FileInfo(Path.Combine(extractDir.Fullpath, SingleEntryFileName));
754+
Assert.AreEqual(targetTime, FileTimeFromTimeSetting(fi, timeSetting));
755+
}
756+
}
757+
758+
[Category("Zip")]
759+
[Category("CreatesTempFile")]
760+
[TestCase(DateTimeKind.Local), TestCase(DateTimeKind.Utc)]
761+
public void ExtractZipShouldSetTimeOnFilesFromConstructorDateTime(DateTimeKind dtk)
762+
{
763+
// Create the archive with a fixed "bad" datetime
764+
var target = CreateFastZipTestArchiveWithAnEntry(new FastZip(UnexpectedFixedTime(dtk)));
765+
766+
// Extract the archive with a fixed time override
767+
var targetTime = ExpectedFixedTime(dtk);
768+
var fastZip = new FastZip(targetTime);
769+
using (var extractDir = new Utils.TempDir())
770+
{
771+
fastZip.ExtractZip(target, extractDir.Fullpath, FastZip.Overwrite.Always,
772+
_ => true, "", "", true, true, false);
773+
var fi = new FileInfo(Path.Combine(extractDir.Fullpath, SingleEntryFileName));
774+
var fileTime = FileTimeFromTimeSetting(fi, TimeSetting.Fixed);
775+
if (fileTime.Kind != dtk) fileTime = fileTime.ToUniversalTime();
776+
Assert.AreEqual(targetTime, fileTime);
777+
}
778+
}
779+
780+
[Category("Zip")]
781+
[Category("CreatesTempFile")]
782+
[TestCase(DateTimeKind.Local), TestCase(DateTimeKind.Utc)]
783+
public void ExtractZipShouldSetTimeOnFilesWithEmptyConstructor(DateTimeKind dtk)
784+
{
785+
// Create the archive with a fixed datetime
786+
var targetTime = ExpectedFixedTime(dtk);
787+
var target = CreateFastZipTestArchiveWithAnEntry(new FastZip(targetTime));
788+
789+
// Extract the archive with an empty constructor
790+
var fastZip = new FastZip();
791+
using (var extractDir = new Utils.TempDir())
792+
{
793+
fastZip.ExtractZip(target, extractDir.Fullpath, FastZip.Overwrite.Always,
794+
_ => true, "", "", true, true, false);
795+
var fi = new FileInfo(Path.Combine(extractDir.Fullpath, SingleEntryFileName));
796+
Assert.AreEqual(targetTime, FileTimeFromTimeSetting(fi, TimeSetting.Fixed));
797+
}
798+
}
799+
800+
private static bool IsLastAccessTime(TimeSetting ts)
801+
=> ts == TimeSetting.LastAccessTime || ts == TimeSetting.LastAccessTimeUtc;
802+
803+
private static DateTime FileTimeFromTimeSetting(FileInfo fi, TimeSetting timeSetting)
804+
{
805+
switch (timeSetting)
806+
{
807+
case TimeSetting.LastWriteTime: return fi.LastWriteTime;
808+
case TimeSetting.LastWriteTimeUtc: return fi.LastWriteTimeUtc;
809+
case TimeSetting.CreateTime: return fi.CreationTime;
810+
case TimeSetting.CreateTimeUtc: return fi.CreationTimeUtc;
811+
case TimeSetting.LastAccessTime: return fi.LastAccessTime;
812+
case TimeSetting.LastAccessTimeUtc: return fi.LastAccessTimeUtc;
813+
case TimeSetting.Fixed: return fi.LastWriteTime;
814+
}
815+
816+
throw new ArgumentException("Invalid TimeSetting", nameof(timeSetting));
817+
}
818+
819+
private static DateTime TestTargetTime(TimeSetting ts)
820+
{
821+
var dtk = ts == TimeSetting.CreateTimeUtc
822+
|| ts == TimeSetting.LastWriteTimeUtc
823+
|| ts == TimeSetting.LastAccessTimeUtc
824+
? DateTimeKind.Utc
825+
: DateTimeKind.Local;
826+
827+
return IsLastAccessTime(ts)
828+
// AccessTime will be altered by reading/writing the file entry
829+
? CurrentTime(dtk)
830+
: ExpectedFixedTime(dtk);
831+
}
832+
833+
private static DateTime CurrentTime(DateTimeKind kind)
834+
{
835+
var now = kind == DateTimeKind.Utc ? DateTime.UtcNow : DateTime.Now;
836+
return new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, (now.Second / 2) * 2, kind);
837+
}
838+
839+
private static DateTime ExpectedFixedTime(DateTimeKind dtk = DateTimeKind.Unspecified)
840+
=> new DateTime(2010, 5, 30, 16, 22, 50, dtk);
841+
private static DateTime UnexpectedFixedTime(DateTimeKind dtk = DateTimeKind.Unspecified)
842+
=> new DateTime(1980, 10, 11, 22, 39, 30, dtk);
843+
844+
private const string SingleEntryFileName = "testEntry.dat";
845+
846+
private static TrackedMemoryStream CreateFastZipTestArchiveWithAnEntry(FastZip fastZip, Action<FileInfo> alterFile = null)
847+
{
848+
var target = new TrackedMemoryStream();
849+
850+
using (var tempFolder = new Utils.TempDir())
851+
{
852+
853+
// Create test input file
854+
var addFile = Path.Combine(tempFolder.Fullpath, SingleEntryFileName);
855+
MakeTempFile(addFile, 16);
856+
var fi = new FileInfo(addFile);
857+
alterFile?.Invoke(fi);
858+
859+
fastZip.CreateZip(target, tempFolder.Fullpath, false, SingleEntryFileName, null, leaveOpen: true);
860+
}
861+
862+
return target;
863+
}
689864
}
690865
}

0 commit comments

Comments
 (0)