Index: Application/Ringtoets/src/Application.Ringtoets.Storage/Application.Ringtoets.Storage.csproj
===================================================================
diff -u -r3ddadfbc5e096c8df7d709be0d9a9057cf4b8dd6 -r3456261423844a9f804b352472ac08feb22485ac
--- Application/Ringtoets/src/Application.Ringtoets.Storage/Application.Ringtoets.Storage.csproj (.../Application.Ringtoets.Storage.csproj) (revision 3ddadfbc5e096c8df7d709be0d9a9057cf4b8dd6)
+++ Application/Ringtoets/src/Application.Ringtoets.Storage/Application.Ringtoets.Storage.csproj (.../Application.Ringtoets.Storage.csproj) (revision 3456261423844a9f804b352472ac08feb22485ac)
@@ -323,7 +323,7 @@
-
+
Index: Application/Ringtoets/src/Application.Ringtoets.Storage/BackedUpFileWriter.cs
===================================================================
diff -u
--- Application/Ringtoets/src/Application.Ringtoets.Storage/BackedUpFileWriter.cs (revision 0)
+++ Application/Ringtoets/src/Application.Ringtoets.Storage/BackedUpFileWriter.cs (revision 3456261423844a9f804b352472ac08feb22485ac)
@@ -0,0 +1,231 @@
+// Copyright (C) Stichting Deltares 2016. All rights reserved.
+//
+// This file is part of Ringtoets.
+//
+// Ringtoets is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.IO;
+using Application.Ringtoets.Storage.Properties;
+using Core.Common.Utils;
+
+namespace Application.Ringtoets.Storage
+{
+ ///
+ /// Class for providing a safe way of writing files by creating a temporary backup file of targeted files.
+ ///
+ public class BackedUpFileWriter
+ {
+ private const string temporarySuffix = "~";
+
+ private readonly string temporaryFilePath;
+ private readonly string targetFilePath;
+ private bool createTemporaryFile;
+
+ ///
+ /// Creates an instance of .
+ ///
+ /// The path of the file which will be overwritten.
+ /// is not a valid path.
+ public BackedUpFileWriter(string targetFilePath)
+ {
+ FileUtils.ValidateFilePath(targetFilePath);
+
+ this.targetFilePath = targetFilePath;
+ temporaryFilePath = targetFilePath + temporarySuffix;
+ }
+
+ ///
+ /// Performs the in a safe way by backing up the targeted file provided when
+ /// constructing the . It is expected that the
+ /// will throw an exception when the operation fails, so that the backed up target file can be restored.
+ ///
+ /// The action to perform after backing up the targeted file.
+ /// Thrown when:
+ ///
+ /// - The temporary file already exists and cannot be deleted.
+ /// - The temporary file cannot be created from the target file.
+ /// - When reverting, the original file cannot be restored.
+ /// - When cleaning up, the temporary file cannot be removed.
+ ///
+ ///
+ /// Any thrown by will be rethrown.
+ public void Perform(Action writeAction)
+ {
+ CreateTemporaryFile();
+
+ try
+ {
+ writeAction();
+ }
+ catch
+ {
+ Revert();
+ throw;
+ }
+ Finish();
+ }
+
+ ///
+ /// Removes the temporary file if it was created.
+ ///
+ /// The temporary file cannot be removed.
+ private void Finish()
+ {
+ if (createTemporaryFile)
+ {
+ DeleteTemporaryFile();
+ }
+ }
+
+ ///
+ /// Reverts the target file to the temporary file if it was created. If the operation fails,
+ /// the temporary file will remain in the directory of the target file.
+ ///
+ /// The original file cannot be restored.
+ private void Revert()
+ {
+ if (createTemporaryFile)
+ {
+ RestoreOriginalFile();
+ }
+ }
+
+ ///
+ /// Creates a temporary file from the target file, if there is any. Creates a new file at the target
+ /// file path.
+ ///
+ /// Thrown when either:
+ ///
+ /// - The temporary file already exists and cannot be deleted.
+ /// - The temporary file cannot be created from the target file.
+ ///
+ ///
+ private void CreateTemporaryFile()
+ {
+ createTemporaryFile = File.Exists(targetFilePath);
+
+ if (createTemporaryFile)
+ {
+ RemoveAlreadyExistingTemporaryFile();
+ CreateNewTemporaryFile();
+ }
+ }
+
+ ///
+ /// Removes the temporary file for the target file if it already exists.
+ ///
+ /// The temporary file already exists and cannot be deleted.
+ private void RemoveAlreadyExistingTemporaryFile()
+ {
+ if (File.Exists(temporaryFilePath))
+ {
+ try
+ {
+ File.Delete(temporaryFilePath);
+ }
+ catch (Exception e)
+ {
+ if (e is ArgumentException || e is IOException || e is SystemException)
+ {
+ var message = string.Format(
+ Resources.SafeOverwriteFileHelper_RemoveAlreadyExistingTemporaryFile_Already_existing_temporary_file_at_FilePath_0_could_not_be_removed,
+ temporaryFilePath);
+ throw new IOException(message, e);
+ }
+ throw;
+ }
+ }
+ }
+
+ ///
+ /// Creates a temporary file from the target file.
+ ///
+ /// The temporary file cannot be created from the target file.
+ private void CreateNewTemporaryFile()
+ {
+ try
+ {
+ File.Move(targetFilePath, temporaryFilePath);
+ }
+ catch (Exception e)
+ {
+ if (e is ArgumentException || e is IOException || e is SystemException)
+ {
+ var message = string.Format(
+ Resources.SafeOverwriteFileHelper_CreateNewTemporaryFile_Cannot_create_temporary_FilePath_0_Try_change_save_location,
+ targetFilePath);
+ throw new IOException(message, e);
+ }
+ throw;
+ }
+ }
+
+ ///
+ /// Moves the temporary file back to the original path. If the operation fails, the temporary file
+ /// will remain.
+ ///
+ /// Thrown when either:
+ ///
+ /// - The new file could not be deleted.
+ /// - The temporary file could not be moved to its original place.
+ ///
+ private void RestoreOriginalFile()
+ {
+ try
+ {
+ File.Delete(targetFilePath);
+ File.Move(temporaryFilePath, targetFilePath);
+ }
+ catch (Exception e)
+ {
+ if (e is ArgumentException || e is IOException || e is SystemException)
+ {
+ var message = string.Format(
+ Resources.SafeOverwriteFileHelper_RestoreOriginalFile_Cannot_revert_to_original_FilePath_0_Try_reverting_manually,
+ targetFilePath);
+ throw new IOException(message, e);
+ }
+ throw;
+ }
+ }
+
+ ///
+ /// Deletes the created temporary file.
+ ///
+ /// The temporary file cannot be removed.
+ private void DeleteTemporaryFile()
+ {
+ try
+ {
+ File.Delete(temporaryFilePath);
+ }
+ catch (Exception e)
+ {
+ if (e is ArgumentException || e is IOException || e is SystemException)
+ {
+ var message = string.Format(
+ Resources.SafeOverwriteFileHelper_DeleteTemporaryFile_Cannot_remove_temporary_FilePath_0_Try_removing_manually,
+ temporaryFilePath);
+ throw new IOException(message, e);
+ }
+ throw;
+ }
+ }
+ }
+}
\ No newline at end of file
Index: Application/Ringtoets/src/Application.Ringtoets.Storage/Properties/Resources.Designer.cs
===================================================================
diff -u -r669853e6468fcf1301a64f5df1400456fe6929eb -r3456261423844a9f804b352472ac08feb22485ac
--- Application/Ringtoets/src/Application.Ringtoets.Storage/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 669853e6468fcf1301a64f5df1400456fe6929eb)
+++ Application/Ringtoets/src/Application.Ringtoets.Storage/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 3456261423844a9f804b352472ac08feb22485ac)
@@ -63,7 +63,7 @@
///
/// Looks up a localized string similar to /* ---------------------------------------------------- */
////* Generated by Enterprise Architect Version 12.0 */
- ////* Created On : 19-jul-2016 13:22:41 */
+ ////* Created On : 21-jul-2016 11:30:42 */
////* DBMS : SQLite */
////* ---------------------------------------------------- */
///
@@ -135,79 +135,52 @@
}
///
- /// Looks up a localized string similar to Kan geen nieuw doelbestand maken ({0}). Probeer ergens anders op te slaan..
+ /// Looks up a localized string similar to Kan geen tijdelijk bestand maken van het originele bestand ({0})..
///
- internal static string SafeOverwriteFileHelper_CreateNewTargetFile_Cannot_create_target_file_0_Try_change_save_location {
+ internal static string SafeOverwriteFileHelper_CreateNewTemporaryFile_Cannot_create_temporary_FilePath_0_Try_change_save_location {
get {
- return ResourceManager.GetString("SafeOverwriteFileHelper_CreateNewTargetFile_Cannot_create_target_file_0_Try_chang" +
- "e_save_location", resourceCulture);
+ return ResourceManager.GetString("SafeOverwriteFileHelper_CreateNewTemporaryFile_Cannot_create_temporary_FilePath_0" +
+ "_Try_change_save_location", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Kan geen tijdelijk bestand maken van het originele bestand ({0}). Probeer ergens anders op te slaan..
+ /// Looks up a localized string similar to Kan het tijdelijke bestand ({0}) niet opruimen. Het tijdelijke bestand dient handmatig verwijderd te worden..
///
- internal static string SafeOverwriteFileHelper_CreateTemporaryFile_Cannot_create_temporary_file_0_Try_change_save_location {
+ internal static string SafeOverwriteFileHelper_DeleteTemporaryFile_Cannot_remove_temporary_FilePath_0_Try_removing_manually {
get {
- return ResourceManager.GetString("SafeOverwriteFileHelper_CreateTemporaryFile_Cannot_create_temporary_file_0_Try_ch" +
- "ange_save_location", resourceCulture);
+ return ResourceManager.GetString("SafeOverwriteFileHelper_DeleteTemporaryFile_Cannot_remove_temporary_FilePath_0_Tr" +
+ "y_removing_manually", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Kan het tijdelijke bestand ({0}) niet opruimen. Het tijdelijke bestand dient handmatig verwijderd te worden..
+ /// Looks up a localized string similar to Er bestaat al een tijdelijk bestand ({0}) dat niet verwijderd kan worden. Het bestaande tijdelijke bestand dient handmatig verwijderd te worden..
///
- internal static string SafeOverwriteFileHelper_CreateTemporaryFile_Cannot_remove_temporary_file_0_Try_removing_manually {
+ internal static string SafeOverwriteFileHelper_RemoveAlreadyExistingTemporaryFile_Already_existing_temporary_file_at_FilePath_0_could_not_be_removed {
get {
- return ResourceManager.GetString("SafeOverwriteFileHelper_CreateTemporaryFile_Cannot_remove_temporary_file_0_Try_re" +
- "moving_manually", resourceCulture);
+ return ResourceManager.GetString("SafeOverwriteFileHelper_RemoveAlreadyExistingTemporaryFile_Already_existing_tempo" +
+ "rary_file_at_FilePath_0_could_not_be_removed", resourceCulture);
}
}
///
/// Looks up a localized string similar to Kan het originele bestand ({0}) niet herstellen. Het tijdelijke bestand dient handmatig hersteld worden..
///
- internal static string SafeOverwriteFileHelper_CreateTemporaryFile_Cannot_rever_to_original_file_0_Try_removing_manually {
+ internal static string SafeOverwriteFileHelper_RestoreOriginalFile_Cannot_revert_to_original_FilePath_0_Try_reverting_manually {
get {
- return ResourceManager.GetString("SafeOverwriteFileHelper_CreateTemporaryFile_Cannot_rever_to_original_file_0_Try_r" +
- "emoving_manually", resourceCulture);
+ return ResourceManager.GetString("SafeOverwriteFileHelper_RestoreOriginalFile_Cannot_revert_to_original_FilePath_0_" +
+ "Try_reverting_manually", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Kon het bestand '{0}' niet aanmaken op de aangewezen locatie..
- ///
- internal static string StorageSqLite_CreateNewFile_Could_not_create_file_at_path_0 {
- get {
- return ResourceManager.GetString("StorageSqLite_CreateNewFile_Could_not_create_file_at_path_0", resourceCulture);
- }
- }
-
- ///
/// Looks up a localized string similar to Het bestand is geen geldig Ringtoets bestand..
///
internal static string StorageSqLite_LoadProject_Invalid_Ringtoets_database_file {
get {
return ResourceManager.GetString("StorageSqLite_LoadProject_Invalid_Ringtoets_database_file", resourceCulture);
}
}
-
- ///
- /// Looks up a localized string similar to Kon het bestand '{0}' niet verplaatsen naar '{1}'..
- ///
- internal static string StorageSqLite_MoveTargetToTemporaryFile_Could_not_move_file_0_to_1 {
- get {
- return ResourceManager.GetString("StorageSqLite_MoveTargetToTemporaryFile_Could_not_move_file_0_to_1", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Kon het reeds bestaande tijdelijk bestand '{0}' niet verwijderen..
- ///
- internal static string StorageSqLite_TryDeleteExistingTemporaryFile_Could_not_delete_existing_file_0 {
- get {
- return ResourceManager.GetString("StorageSqLite_TryDeleteExistingTemporaryFile_Could_not_delete_existing_file_0", resourceCulture);
- }
- }
}
}
Index: Application/Ringtoets/src/Application.Ringtoets.Storage/Properties/Resources.resx
===================================================================
diff -u -r669853e6468fcf1301a64f5df1400456fe6929eb -r3456261423844a9f804b352472ac08feb22485ac
--- Application/Ringtoets/src/Application.Ringtoets.Storage/Properties/Resources.resx (.../Resources.resx) (revision 669853e6468fcf1301a64f5df1400456fe6929eb)
+++ Application/Ringtoets/src/Application.Ringtoets.Storage/Properties/Resources.resx (.../Resources.resx) (revision 3456261423844a9f804b352472ac08feb22485ac)
@@ -139,25 +139,16 @@
Het bestand is geen geldig Ringtoets bestand.
-
- Kon het reeds bestaande tijdelijk bestand '{0}' niet verwijderen.
+
+ Kan geen tijdelijk bestand maken van het originele bestand ({0}).
-
- Kon het bestand '{0}' niet aanmaken op de aangewezen locatie.
-
-
- Kon het bestand '{0}' niet verplaatsen naar '{1}'.
-
-
- Kan geen nieuw doelbestand maken ({0}). Probeer ergens anders op te slaan.
-
-
- Kan geen tijdelijk bestand maken van het originele bestand ({0}). Probeer ergens anders op te slaan.
-
-
+
Kan het originele bestand ({0}) niet herstellen. Het tijdelijke bestand dient handmatig hersteld worden.
-
+
Kan het tijdelijke bestand ({0}) niet opruimen. Het tijdelijke bestand dient handmatig verwijderd te worden.
+
+ Er bestaat al een tijdelijk bestand ({0}) dat niet verwijderd kan worden. Het bestaande tijdelijke bestand dient handmatig verwijderd te worden.
+
\ No newline at end of file
Fisheye: Tag 3456261423844a9f804b352472ac08feb22485ac refers to a dead (removed) revision in file `Application/Ringtoets/src/Application.Ringtoets.Storage/SafeOverwriteFileHelper.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Index: Application/Ringtoets/src/Application.Ringtoets.Storage/StorageSqLite.cs
===================================================================
diff -u -r1c18575a6c396cd3c2d9d6079e4ed593871fc5f4 -r3456261423844a9f804b352472ac08feb22485ac
--- Application/Ringtoets/src/Application.Ringtoets.Storage/StorageSqLite.cs (.../StorageSqLite.cs) (revision 1c18575a6c396cd3c2d9d6079e4ed593871fc5f4)
+++ Application/Ringtoets/src/Application.Ringtoets.Storage/StorageSqLite.cs (.../StorageSqLite.cs) (revision 3456261423844a9f804b352472ac08feb22485ac)
@@ -61,14 +61,12 @@
/// to save.
/// Thrown when is null.
/// is invalid.
- /// No file is present at
- /// at the time a connection is made.
/// Thrown when
///
- /// - The database does not contain the table version
- /// - The file was not created.
- /// - Saving the to the database failed.
+ /// - No backup file could be created or restored when overwriting an existing file.
+ /// - The file at cannot be created.
/// - The connection to the database file failed.
+ /// - Saving the to the database failed.
///
///
public void SaveProjectAs(string databaseFilePath, IProject project)
@@ -78,20 +76,19 @@
throw new ArgumentNullException("project");
}
- SafeOverwriteFileHelper overwriteHelper = GetSafeOverwriteFileHelper(databaseFilePath);
- if (overwriteHelper != null)
+ try
{
- try
+ BackedUpFileWriter writer = new BackedUpFileWriter(databaseFilePath);
+ writer.Perform(() =>
{
SetConnectionToNewFile(databaseFilePath);
SaveProjectInDatabase(databaseFilePath, (RingtoetsProject) project);
- }
- catch
- {
- CleanUpTemporaryFile(overwriteHelper, true);
- }
- CleanUpTemporaryFile(overwriteHelper, false);
+ });
}
+ catch (IOException e)
+ {
+ throw new StorageException(e.Message, e);
+ }
}
///
@@ -218,46 +215,6 @@
}
}
- ///
- /// Cleans up a new .
- ///
- /// The to use for cleaning up.
- /// Value indicating whether the should revert to
- /// original file or keep the new file.
- /// A file IO operation fails while cleaning up using the
- /// .
- private void CleanUpTemporaryFile(SafeOverwriteFileHelper overwriteHelper, bool revert)
- {
- try
- {
- overwriteHelper.Finish(revert);
- }
- catch (IOException e)
- {
- throw new StorageException(e.Message, e);
- }
- }
-
- ///
- /// Creates a new .
- ///
- /// The path for which to create the .
- /// A new
- /// is invalid.
- /// A file IO operation fails while initializing the
- /// .
- private SafeOverwriteFileHelper GetSafeOverwriteFileHelper(string databaseFilePath)
- {
- try
- {
- return new SafeOverwriteFileHelper(databaseFilePath);
- }
- catch (IOException e)
- {
- throw new StorageException(e.Message, e);
- }
- }
-
private void SaveProjectInDatabase(string databaseFilePath, RingtoetsProject project)
{
using (var dbContext = new RingtoetsEntities(connectionString))
@@ -337,16 +294,15 @@
/// Sets the connection to a newly created (empty) Ringtoets database file.
///
/// Path to database file.
- /// is invalid.
- /// No file is present at
- /// at the time a connection is made.
+ /// Thrown when:
+ ///
+ /// - is invalid
+ /// - points to an existing file
+ ///
/// Thrown when:
- /// - was not created
/// - executing DatabaseStructure script failed
///
///
- /// Thrown when the could not
- /// be overwritten.
private void SetConnectionToNewFile(string databaseFilePath)
{
FileUtils.ValidateFilePath(databaseFilePath);
Index: Application/Ringtoets/src/Application.Ringtoets.Storage/StorageSqliteCreator.cs
===================================================================
diff -u -r233ccdab7d2f44be39fd95e1f7617f4c72ee0df1 -r3456261423844a9f804b352472ac08feb22485ac
--- Application/Ringtoets/src/Application.Ringtoets.Storage/StorageSqliteCreator.cs (.../StorageSqliteCreator.cs) (revision 233ccdab7d2f44be39fd95e1f7617f4c72ee0df1)
+++ Application/Ringtoets/src/Application.Ringtoets.Storage/StorageSqliteCreator.cs (.../StorageSqliteCreator.cs) (revision 3456261423844a9f804b352472ac08feb22485ac)
@@ -19,6 +19,7 @@
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
+using System;
using System.Data.SQLite;
using System.IO;
using Application.Ringtoets.Storage.Properties;
@@ -34,19 +35,27 @@
public static class StorageSqliteCreator
{
///
- /// Creates the basic database structure for a Ringtoets database file.
+ /// Creates a new file with the basic database structure for a Ringtoets database at
+ /// .
///
- /// Path to database file.
- /// is invalid.
+ /// Path of the new database file.
+ /// Thrown when either:
+ ///
+ /// - is invalid
+ /// - points to an existing file
+ ///
/// Thrown when executing DatabaseStructure script fails.
public static void CreateDatabaseStructure(string databaseFilePath)
{
FileUtils.ValidateFilePath(databaseFilePath);
- if (!File.Exists(databaseFilePath))
+ if (File.Exists(databaseFilePath))
{
- SQLiteConnection.CreateFile(databaseFilePath);
+ var message = string.Format("File '{0}' already exists.", databaseFilePath);
+ throw new ArgumentException(message);
}
+
+ SQLiteConnection.CreateFile(databaseFilePath);
var connectionString = SqLiteConnectionStringBuilder.BuildSqLiteConnectionString(databaseFilePath);
try
{
Index: Application/Ringtoets/test/Application.Ringtoets.Storage.Test/Application.Ringtoets.Storage.Test.csproj
===================================================================
diff -u -r3ddadfbc5e096c8df7d709be0d9a9057cf4b8dd6 -r3456261423844a9f804b352472ac08feb22485ac
--- Application/Ringtoets/test/Application.Ringtoets.Storage.Test/Application.Ringtoets.Storage.Test.csproj (.../Application.Ringtoets.Storage.Test.csproj) (revision 3ddadfbc5e096c8df7d709be0d9a9057cf4b8dd6)
+++ Application/Ringtoets/test/Application.Ringtoets.Storage.Test/Application.Ringtoets.Storage.Test.csproj (.../Application.Ringtoets.Storage.Test.csproj) (revision 3456261423844a9f804b352472ac08feb22485ac)
@@ -193,7 +193,7 @@
-
+
Index: Application/Ringtoets/test/Application.Ringtoets.Storage.Test/BackedUpFileWriterTest.cs
===================================================================
diff -u
--- Application/Ringtoets/test/Application.Ringtoets.Storage.Test/BackedUpFileWriterTest.cs (revision 0)
+++ Application/Ringtoets/test/Application.Ringtoets.Storage.Test/BackedUpFileWriterTest.cs (revision 3456261423844a9f804b352472ac08feb22485ac)
@@ -0,0 +1,399 @@
+// Copyright (C) Stichting Deltares 2016. All rights reserved.
+//
+// This file is part of Ringtoets.
+//
+// Ringtoets is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.IO;
+using System.Security.AccessControl;
+using System.Security.Principal;
+using NUnit.Framework;
+
+namespace Application.Ringtoets.Storage.Test
+{
+ [TestFixture]
+ public class BackedUpFileWriterTest
+ {
+ private string testWorkDir = Path.Combine(".", "SafeOverwriteFileHelperTest");
+
+ [TestFixtureSetUp]
+ public void SetUpFixture()
+ {
+ Directory.CreateDirectory(testWorkDir);
+ }
+
+ [TestFixtureTearDown]
+ public void TearDownFixture()
+ {
+ Directory.Delete(testWorkDir);
+ }
+
+ [Test]
+ [TestCase("")]
+ [TestCase(null)]
+ [TestCase("\"")]
+ [TestCase("/")]
+ public void Constructor_InvalidPath_ThrowsArgumentException(string path)
+ {
+ // Call
+ TestDelegate test = () => new BackedUpFileWriter(path);
+
+ // Assert
+ Assert.Throws(test);
+ }
+
+ [Test]
+ public void Perform_ValidFile_TemporaryFileCreatedFromOriginalAndDeletedAfterwards()
+ {
+ // Setup
+ var writableDirectory = Path.Combine(testWorkDir, "Writable");
+ var filePath = Path.Combine(writableDirectory, "iDoExist.txt");
+ var temporaryFilePath = filePath + "~";
+ var testContent = "Some test text to write into file.";
+
+ Directory.CreateDirectory(writableDirectory);
+ File.WriteAllText(filePath, testContent);
+
+ var writer = new BackedUpFileWriter(filePath);
+
+ try
+ {
+ // Precondition
+ Assert.IsTrue(File.Exists(filePath));
+
+ // Call
+ writer.Perform(() =>
+ {
+ // Assert
+ Assert.IsFalse(File.Exists(filePath));
+ Assert.IsTrue(File.Exists(temporaryFilePath));
+ Assert.AreEqual(testContent, File.ReadAllText(temporaryFilePath));
+ });
+ Assert.False(File.Exists(temporaryFilePath));
+ }
+ finally
+ {
+ Directory.Delete(writableDirectory, true);
+ }
+ }
+
+ [Test]
+ public void Perform_ActionThrowsExceptionValidPathFileExists_OriginalFileRevertedAndExceptionThrown()
+ {
+ // Setup
+ var writableDirectory = Path.Combine(testWorkDir, "Writable");
+ var filePath = Path.Combine(writableDirectory, "iDoExist.txt");
+ var temporaryFilePath = filePath + "~";
+ var testContent = "Some test text to write into file.";
+
+ Directory.CreateDirectory(writableDirectory);
+ File.WriteAllText(filePath, testContent);
+
+ var writer = new BackedUpFileWriter(filePath);
+ var exception = new IOException();
+
+ // Precondition
+ Assert.IsTrue(File.Exists(filePath));
+
+ try
+ {
+ // Call
+ TestDelegate test = () => writer.Perform(() =>
+ {
+ throw exception;
+ });
+
+ var actualException = Assert.Throws(exception.GetType(), test);
+ Assert.AreSame(exception, actualException);
+
+ Assert.IsFalse(File.Exists(temporaryFilePath));
+ Assert.IsTrue(File.Exists(filePath));
+ Assert.AreEqual(testContent, File.ReadAllText(filePath));
+ }
+ finally
+ {
+ Directory.Delete(writableDirectory, true);
+ }
+ }
+
+ [Test]
+ public void Perform_ValidPathFileExistsTemporaryFileExistsAndCannotBeDeleted_ThrowsIOException()
+ {
+ // Setup
+ var filePath = Path.Combine(testWorkDir, "iDoExist.txt");
+ var temporaryFilePath = filePath + "~";
+
+ using (File.Create(filePath)) { }
+ var temporaryFileStream = File.Create(temporaryFilePath);
+
+ var writer = new BackedUpFileWriter(filePath);
+
+ // Precondition
+ Assert.IsTrue(File.Exists(filePath));
+ Assert.IsTrue(File.Exists(temporaryFilePath));
+
+ // Call
+ TestDelegate test = () =>
+ {
+ writer.Perform(() => { });
+ };
+
+ try
+ {
+ // Assert
+ var message = Assert.Throws(test).Message;
+ var expectedMessage = string.Format(
+ "Er bestaat al een tijdelijk bestand ({0}) dat niet verwijderd kan worden. Het bestaande tijdelijke bestand dient handmatig verwijderd te worden.",
+ temporaryFilePath);
+ Assert.AreEqual(message, expectedMessage);
+ temporaryFileStream.Dispose();
+ }
+ finally
+ {
+ File.Delete(filePath);
+ File.Delete(temporaryFilePath);
+ }
+ }
+
+ [Test]
+ public void Perform_ValidPathFileExistsDirectoryNotWritable_ThrowsIOException()
+ {
+ // Setup
+ var notWritableDirectory = Path.Combine(testWorkDir, "NotWritable");
+ var filePath = Path.Combine(notWritableDirectory, "iDoExist.txt");
+
+ Directory.CreateDirectory(notWritableDirectory);
+ using (File.Create(filePath)) {}
+ DenyDirectoryRight(notWritableDirectory, FileSystemRights.Write);
+
+ var writer = new BackedUpFileWriter(filePath);
+
+ // Precondition
+ Assert.IsTrue(File.Exists(filePath));
+
+ // Call
+ TestDelegate test = () =>
+ {
+ writer.Perform(() => { });
+ };
+
+ try
+ {
+ // Assert
+ var expectedMessage = string.Format(
+ "Kan geen tijdelijk bestand maken van het originele bestand ({0}).",
+ filePath);
+ var message = Assert.Throws(test).Message;
+ Assert.AreEqual(expectedMessage, message);
+ }
+ finally
+ {
+ Directory.Delete(notWritableDirectory, true);
+ }
+ }
+
+ [Test]
+ public void Perform_TargetFileDoesNotExistAccessRightsRevoked_DoesNotThrow()
+ {
+ // Setup
+ var noAccessDirectory = Path.Combine(testWorkDir, "NoAccess");
+ var filePath = Path.Combine(noAccessDirectory, "iDoNotExist.txt");
+
+ Directory.CreateDirectory(noAccessDirectory);
+ var helper = new BackedUpFileWriter(filePath);
+
+ var right = FileSystemRights.FullControl;
+ DenyDirectoryRight(noAccessDirectory, right);
+
+ // Call
+ TestDelegate test = () => helper.Perform(() => { });
+
+ try
+ {
+ // Assert
+ Assert.DoesNotThrow(test);
+ }
+ finally
+ {
+ RevertDenyDirectoryRight(noAccessDirectory, right);
+ Directory.Delete(noAccessDirectory, true);
+ }
+ }
+
+ [Test]
+ public void Perform_TargetFileExistsCannotDeleteFile_ThrowsIOException()
+ {
+ // Setup
+ var noAccessDirectory = Path.Combine(testWorkDir, "Access");
+ var filePath = Path.Combine(noAccessDirectory, "iDoExist.txt");
+ var temporaryFilePath = filePath + "~";
+
+ Directory.CreateDirectory(noAccessDirectory);
+ using (File.Create(filePath)) {}
+
+ var helper = new BackedUpFileWriter(filePath);
+
+ FileStream fileStream = null;
+
+ try
+ {
+ // Call
+ TestDelegate test = () => helper.Perform(() =>
+ {
+ fileStream = File.Open(temporaryFilePath, FileMode.Open);
+ });
+
+ // Assert
+ var expectedMessage = string.Format(
+ "Kan het tijdelijke bestand ({0}) niet opruimen. Het tijdelijke bestand dient handmatig verwijderd te worden.",
+ temporaryFilePath);
+ var message = Assert.Throws(test).Message;
+ Assert.AreEqual(expectedMessage, message);
+ }
+ finally
+ {
+ if (fileStream != null)
+ {
+ fileStream.Dispose();
+ }
+ Directory.Delete(noAccessDirectory, true);
+ }
+ }
+
+ [Test]
+ public void Perform_ActionThrowsExceptionTargetFileExistsCannotDeleteFile_ThrowsIOException()
+ {
+ // Setup
+ var noAccessDirectory = Path.Combine(testWorkDir, "Access");
+ var filePath = Path.Combine(noAccessDirectory, "iDoExist.txt");
+ var temporaryFilePath = filePath + "~";
+
+ Directory.CreateDirectory(noAccessDirectory);
+ using (File.Create(filePath)) {}
+
+ var helper = new BackedUpFileWriter(filePath);
+
+ FileStream fileStream = null;
+
+ try
+ {
+ // Call
+ TestDelegate test = () => helper.Perform(() =>
+ {
+ fileStream = File.Open(temporaryFilePath, FileMode.Open);
+ throw new Exception();
+ });
+
+ // Assert
+ var expectedMessage = string.Format(
+ "Kan het originele bestand ({0}) niet herstellen. Het tijdelijke bestand dient handmatig hersteld worden.",
+ filePath);
+ var message = Assert.Throws(test).Message;
+ Assert.AreEqual(expectedMessage, message);
+ }
+ finally
+ {
+ if (fileStream != null)
+ {
+ fileStream.Dispose();
+ }
+ Directory.Delete(noAccessDirectory, true);
+ }
+ }
+
+ [Test]
+ public void Perform_ActionThrowsExceptionTargetFileFileExistsCannotMoveFile_ThrowsIOException()
+ {
+ // Setup
+ var noAccessDirectory = Path.Combine(testWorkDir, "NoAccess");
+ var filePath = Path.Combine(noAccessDirectory, "iDoExist.txt");
+
+ Directory.CreateDirectory(noAccessDirectory);
+ using (File.Create(filePath)) {}
+
+ var helper = new BackedUpFileWriter(filePath);
+
+ var right = FileSystemRights.FullControl;
+
+ try
+ {
+ // Call
+ TestDelegate test = () => helper.Perform(() =>
+ {
+ DenyDirectoryRight(noAccessDirectory, right);
+ throw new Exception();
+ });
+
+ // Assert
+ var expectedMessage = string.Format(
+ "Kan het originele bestand ({0}) niet herstellen. Het tijdelijke bestand dient handmatig hersteld worden.",
+ filePath);
+ var message = Assert.Throws(test).Message;
+ Assert.AreEqual(expectedMessage, message);
+ }
+ finally
+ {
+ RevertDenyDirectoryRight(noAccessDirectory, right);
+ Directory.Delete(noAccessDirectory, true);
+ }
+ }
+
+ ///
+ /// Adds a of type to the access
+ /// rule set for the file at .
+ ///
+ /// The path of the file to change the right for.
+ /// The right to deny.
+ private static void DenyDirectoryRight(string filePath, FileSystemRights rights)
+ {
+ var sid = GetSecurityIdentifier();
+
+ DirectoryInfo directoryInfo = new DirectoryInfo(filePath);
+ DirectorySecurity directorySecurity = directoryInfo.GetAccessControl();
+
+ directorySecurity.AddAccessRule(new FileSystemAccessRule(sid, rights, AccessControlType.Deny));
+
+ directoryInfo.SetAccessControl(directorySecurity);
+ }
+
+ ///
+ /// Removes a of type from the
+ /// access rule set for the file at .
+ ///
+ /// The path of the file to change the right for.
+ /// The right to revert.
+ private static void RevertDenyDirectoryRight(string filePath, FileSystemRights rights)
+ {
+ var sid = GetSecurityIdentifier();
+
+ DirectoryInfo directoryInfo = new DirectoryInfo(filePath);
+ DirectorySecurity directorySecurity = directoryInfo.GetAccessControl();
+
+ directorySecurity.RemoveAccessRule(new FileSystemAccessRule(sid, rights, AccessControlType.Deny));
+
+ directoryInfo.SetAccessControl(directorySecurity);
+ }
+
+ private static SecurityIdentifier GetSecurityIdentifier()
+ {
+ SecurityIdentifier id = WindowsIdentity.GetCurrent().User.AccountDomainSid;
+ return new SecurityIdentifier(WellKnownSidType.WorldSid, id);
+ }
+ }
+}
\ No newline at end of file
Fisheye: Tag 3456261423844a9f804b352472ac08feb22485ac refers to a dead (removed) revision in file `Application/Ringtoets/test/Application.Ringtoets.Storage.Test/SafeOverwriteFileHelperTest.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Index: Application/Ringtoets/test/Application.Ringtoets.Storage.Test/StorageSqLiteTest.cs
===================================================================
diff -u -r1c18575a6c396cd3c2d9d6079e4ed593871fc5f4 -r3456261423844a9f804b352472ac08feb22485ac
--- Application/Ringtoets/test/Application.Ringtoets.Storage.Test/StorageSqLiteTest.cs (.../StorageSqLiteTest.cs) (revision 1c18575a6c396cd3c2d9d6079e4ed593871fc5f4)
+++ Application/Ringtoets/test/Application.Ringtoets.Storage.Test/StorageSqLiteTest.cs (.../StorageSqLiteTest.cs) (revision 3456261423844a9f804b352472ac08feb22485ac)
@@ -291,7 +291,7 @@
{
// Setup
var expectedMessage = string.Format(
- @"Kan geen tijdelijk bestand maken van het originele bestand ({0}). Probeer ergens anders op te slaan.",
+ @"Kan geen tijdelijk bestand maken van het originele bestand ({0}).",
tempRingtoetsFile);
var project = new RingtoetsProject();
var storage = new StorageSqLite();
Index: Application/Ringtoets/test/Application.Ringtoets.Storage.Test/StorageSqliteCreatorTest.cs
===================================================================
diff -u -r8293556a04e3650c9978df7a50f8f8ad0d792ed8 -r3456261423844a9f804b352472ac08feb22485ac
--- Application/Ringtoets/test/Application.Ringtoets.Storage.Test/StorageSqliteCreatorTest.cs (.../StorageSqliteCreatorTest.cs) (revision 8293556a04e3650c9978df7a50f8f8ad0d792ed8)
+++ Application/Ringtoets/test/Application.Ringtoets.Storage.Test/StorageSqliteCreatorTest.cs (.../StorageSqliteCreatorTest.cs) (revision 3456261423844a9f804b352472ac08feb22485ac)
@@ -21,7 +21,6 @@
using System;
using System.IO;
-using Core.Common.Base.Storage;
using Core.Common.TestUtil;
using NUnit.Framework;
@@ -56,8 +55,8 @@
// Precondition
Assert.IsFalse(File.Exists(fullPath));
-
- using (new FileDisposeHelper(fullPath))
+
+ try
{
// Call
TestDelegate call = () => StorageSqliteCreator.CreateDatabaseStructure(fullPath);
@@ -67,6 +66,13 @@
Assert.IsTrue(File.Exists(fullPath));
}
+ finally
+ {
+ if (File.Exists(fullPath))
+ {
+ File.Delete(fullPath);
+ }
+ }
}
[Test]
@@ -80,7 +86,7 @@
// Precondition
Assert.IsFalse(File.Exists(fullPath));
- using (new FileDisposeHelper(fullPath))
+ try
{
// Call
TestDelegate call = () => StorageSqliteCreator.CreateDatabaseStructure(uncPath);
@@ -90,26 +96,31 @@
Assert.IsTrue(File.Exists(fullPath));
}
+ finally
+ {
+ if (File.Exists(fullPath))
+ {
+ File.Delete(fullPath);
+ }
+ }
}
[Test]
- public void CreateDatabaseStructure_ValidPathToLockedFile_ThrowsUpdateStorageException()
+ public void CreateDatabaseStructure_ValidExistingFile_ThrowsStorageException()
{
using (new FileDisposeHelper(tempRingtoetsFile))
{
// Call
TestDelegate call = () => StorageSqliteCreator.CreateDatabaseStructure(tempRingtoetsFile);
- StorageException exception;
+ ArgumentException exception;
using (File.Create(tempRingtoetsFile)) // Locks file
{
- exception = Assert.Throws(call);
+ exception = Assert.Throws(call);
}
// Assert
- Assert.IsInstanceOf(exception.InnerException);
- var expectedMessage = String.Format(@"Fout bij het schrijven naar bestand '{0}': " +
- "Een fout is opgetreden met schrijven naar het nieuwe Ringtoets bestand.", tempRingtoetsFile);
+ var expectedMessage = String.Format(@"File '{0}' already exists.", tempRingtoetsFile);
Assert.AreEqual(expectedMessage, exception.Message);
}
}