Skip to content

Commit

Permalink
Make sure we write all our files in binary mode.
Browse files Browse the repository at this point in the history
- Supports transactions.
- Includes tests.
- Closes #205
  • Loading branch information
pjf committed Oct 30, 2014
1 parent 0297b27 commit ee84dbd
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 10 deletions.
11 changes: 9 additions & 2 deletions CKAN/CKAN/ModuleInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Threading;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
using System.Transactions;
using ChinhDo.Transactions;
Expand Down Expand Up @@ -755,11 +756,17 @@ internal static void CopyZipEntry(ZipFile zipfile, ZipEntry entry, string fullPa
file_transaction.CreateDirectory(directory);
}

// Snapshot whatever was there before. If there's nothing, this will just
// remove our file on rollback.
file_transaction.Snapshot(fullPath);

// It's a file! Prepare the streams
using (Stream zipStream = zipfile.GetInputStream(entry))
using (StreamReader reader = new StreamReader(zipStream))
using (FileStream writer = File.Create(fullPath))
{
file_transaction.WriteAllText(fullPath, reader.ReadToEnd());
// 4k is the block size on practically every disk and OS.
byte[] buffer = new byte[4096];
StreamUtils.Copy(zipStream, writer, buffer);
}
}

Expand Down
44 changes: 36 additions & 8 deletions CKAN/Tests/CKAN/ModuleInstaller.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using NUnit.Framework;
using System;
using System.IO;
using System.Transactions;
using System.Collections.Generic;
using ICSharpCode.SharpZipLib.Zip;
using CKAN;
Expand Down Expand Up @@ -100,14 +101,9 @@ public void No_Installable_Files()
// GH #205, make sure we write in *binary*, not text.
public void BinaryNotText_205()
{
string dogezip = Tests.TestData.DogeCoinFlagZip();
ZipFile zipfile = new ZipFile(dogezip);

ZipEntry entry = zipfile.GetEntry("DogeCoinFlag-1.01/GameData/DogeCoinFlag/Flags/dogecoin.png");
string tmpfile = Path.GetTempFileName();

CKAN.ModuleInstaller.CopyZipEntry(zipfile, entry, tmpfile, false);

// Use CopyZipEntry (via CopyDogeFromZip) and make sure it
// comes out the right size.
string tmpfile = CopyDogeFromZip();
long size = new System.IO.FileInfo(tmpfile).Length;

try
Expand All @@ -122,6 +118,38 @@ public void BinaryNotText_205()
}
}

[Test()]
// Make sure when we roll-back a transaction, files written with CopyZipEntry go
// back to their pre-transaction state.
public void FileSysRollBack()
{
string file;

using (var scope = new TransactionScope())
{
file = CopyDogeFromZip();
Assert.IsTrue(new System.IO.FileInfo(file).Length > 0);
scope.Dispose(); // Rollback
}

// CopyDogeFromZip creates a tempfile, so we check to make sure it's empty
// again on transaction rollback.
Assert.AreEqual(0, new System.IO.FileInfo(file).Length);
}

private static string CopyDogeFromZip()
{
string dogezip = Tests.TestData.DogeCoinFlagZip();
ZipFile zipfile = new ZipFile(dogezip);

ZipEntry entry = zipfile.GetEntry("DogeCoinFlag-1.01/GameData/DogeCoinFlag/Flags/dogecoin.png");
string tmpfile = Path.GetTempFileName();

CKAN.ModuleInstaller.CopyZipEntry(zipfile, entry, tmpfile, false);

return tmpfile;
}

private void TestDogeCoinStanza(ModuleInstallDescriptor stanza)
{
Assert.AreEqual("GameData", stanza.install_to);
Expand Down
1 change: 1 addition & 0 deletions CKAN/Tests/Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<Reference Include="ICSharpCode.SharpZipLib">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="System.Transactions" />
</ItemGroup>
<ItemGroup>
<Compile Include="TestData.cs" />
Expand Down

0 comments on commit ee84dbd

Please sign in to comment.