From 9dce3dc942341be7e908f220a1601f78cbefa47a Mon Sep 17 00:00:00 2001 From: Kaloyan Raev Date: Sat, 9 Nov 2019 01:38:06 +0200 Subject: [PATCH] installer/windows: unit tests for C# custom actions (part 1) (#3521) --- installer/windows/.gitignore | 3 + installer/windows/Storj/CustomAction.cs | 295 ++++++++++++------ .../ExpectedExceptionWithMessage.cs | 47 +++ .../StorjTests/ExtractInstallDirTests.cs | 35 +++ .../StorjTests/Properties/AssemblyInfo.cs | 20 ++ .../windows/StorjTests/StorjTests.csproj | 89 ++++++ .../StorjTests/ValidateBandwidthTests.cs | 44 +++ .../StorjTests/ValidateIdentityDirTests.cs | 33 ++ .../StorjTests/ValidateStorageDirTests.cs | 26 ++ .../StorjTests/ValidateStorageTests.cs | 68 ++++ .../windows/StorjTests/ValidateWalletTests.cs | 51 +++ installer/windows/StorjTests/packages.config | 5 + installer/windows/build.bat | 3 + installer/windows/unittests.bat | 8 + installer/windows/windows.sln | 23 ++ 15 files changed, 648 insertions(+), 102 deletions(-) create mode 100644 installer/windows/StorjTests/ExpectedExceptionWithMessage.cs create mode 100644 installer/windows/StorjTests/ExtractInstallDirTests.cs create mode 100644 installer/windows/StorjTests/Properties/AssemblyInfo.cs create mode 100644 installer/windows/StorjTests/StorjTests.csproj create mode 100644 installer/windows/StorjTests/ValidateBandwidthTests.cs create mode 100644 installer/windows/StorjTests/ValidateIdentityDirTests.cs create mode 100644 installer/windows/StorjTests/ValidateStorageDirTests.cs create mode 100644 installer/windows/StorjTests/ValidateStorageTests.cs create mode 100644 installer/windows/StorjTests/ValidateWalletTests.cs create mode 100644 installer/windows/StorjTests/packages.config create mode 100644 installer/windows/unittests.bat diff --git a/installer/windows/.gitignore b/installer/windows/.gitignore index f149fd0a5..563afe951 100644 --- a/installer/windows/.gitignore +++ b/installer/windows/.gitignore @@ -1,6 +1,9 @@ /.vs/ /bin/ +*/bin/ /obj/ +*/obj/ +/packages/ *.exe *.msi *.wixobj diff --git a/installer/windows/Storj/CustomAction.cs b/installer/windows/Storj/CustomAction.cs index 5cbe332a5..508055ca5 100644 --- a/installer/windows/Storj/CustomAction.cs +++ b/installer/windows/Storj/CustomAction.cs @@ -8,48 +8,20 @@ namespace Storj { public class CustomActions { - private const long GB = 1000 * 1000 * 1000; - private const long TB = (long) 1000 * 1000 * 1000 * 1000; - private const long MinFreeSpace = 550 * GB; // (500 GB + 10% overhead) [CustomAction] public static ActionResult ValidateIdentityDir(Session session) { string identityDir = session["IDENTITYDIR"]; - if (string.IsNullOrEmpty(identityDir)) + try { - session["STORJ_IDENTITYDIR_VALID"] = "You must select an identity folder."; - return ActionResult.Success; + CustomActionRunner.ValidateIdentityDir(identityDir); } - - if (!Directory.Exists(identityDir)) + catch (ArgumentException e) { - session["STORJ_IDENTITYDIR_VALID"] = string.Format("Folder '{0}' does not exist.", identityDir); - return ActionResult.Success; - } - - if (!File.Exists(Path.Combine(identityDir, "ca.cert"))) - { - session["STORJ_IDENTITYDIR_VALID"] = "File 'ca.cert' not found in the selected folder."; - return ActionResult.Success; - } - - if (!File.Exists(Path.Combine(identityDir, "ca.key"))) - { - session["STORJ_IDENTITYDIR_VALID"] = "File 'ca.key' not found in the selected folder."; - return ActionResult.Success; - } - - if (!File.Exists(Path.Combine(identityDir, "identity.cert"))) - { - session["STORJ_IDENTITYDIR_VALID"] = "File 'identity.cert' not found in the selected folder."; - return ActionResult.Success; - } - - if (!File.Exists(Path.Combine(identityDir, "identity.key"))) - { - session["STORJ_IDENTITYDIR_VALID"] = "File 'identity.key' not found in the selected folder."; + // Identity dir is invalid + session["STORJ_IDENTITYDIR_VALID"] = e.Message; return ActionResult.Success; } @@ -63,52 +35,34 @@ namespace Storj { string wallet = session["STORJ_WALLET"]; - if (string.IsNullOrEmpty(wallet)) + try { - session["STORJ_WALLET_VALID"] = "The payout address cannot be empty."; + CustomActionRunner.ValidateWallet(wallet); + } catch (ArgumentException e) + { + // Wallet is invalid + session["STORJ_WALLET_VALID"] = e.Message; return ActionResult.Success; } - if (!wallet.StartsWith("0x")) - { - session["STORJ_WALLET_VALID"] = "The payout address must start with a '0x' prefix."; - return ActionResult.Success; - } - - // Remove 0x prefix - wallet = wallet.Substring(2); - - if (wallet.Length != 40) - { - session["STORJ_WALLET_VALID"] = "The payout address must have 40 characters after the '0x' prefix."; - return ActionResult.Success; - } - - // TODO validate address checksum - // Wallet is valid session["STORJ_WALLET_VALID"] = "1"; return ActionResult.Success; } + [CustomAction] public static ActionResult ValidateStorageDir(Session session) { - string identityDir = session["STORAGEDIR"]; + string storageDir = session["STORAGEDIR"]; - if (string.IsNullOrEmpty(identityDir)) + try { - session["STORJ_STORAGEDIR_VALID"] = "You must select a storage folder."; - return ActionResult.Success; + CustomActionRunner.ValidateStorageDir(storageDir); } - - DirectoryInfo dir = new DirectoryInfo(identityDir); - DriveInfo drive = new DriveInfo(dir.Root.FullName); - - // TODO: Find a way to calculate the available free space + total size of existing pieces - if (drive.TotalSize < MinFreeSpace) + catch (ArgumentException e) { - session["STORJ_STORAGEDIR_VALID"] = string.Format("The selected drive '{0}' has only {1:0.##} GB disk size. The minimum required is 550 GB.", - drive.Name, decimal.Divide(drive.TotalSize, GB)); + // Storage dir is invalid + session["STORJ_STORAGEDIR_VALID"] = e.Message; return ActionResult.Success; } @@ -121,33 +75,16 @@ namespace Storj public static ActionResult ValidateStorage(Session session) { string storageStr = session["STORJ_STORAGE"]; + string storageDir = session["STORAGEDIR"]; - if (string.IsNullOrEmpty(storageStr)) + try { - session["STORJ_STORAGE_VALID"] = "The value cannot be empty."; - return ActionResult.Success; + CustomActionRunner.ValidateStorage(storageStr, storageDir); } - - if (!double.TryParse(storageStr, NumberStyles.Number, CultureInfo.CreateSpecificCulture("en-US"), out double storage)) + catch (ArgumentException e) { - session["STORJ_STORAGE_VALID"] = string.Format("'{0}' is not a valid number.", storageStr); - return ActionResult.Success; - } - - if (storage < 0.5) { - session["STORJ_STORAGE_VALID"] = "The allocated disk space cannot be less than 0.5 TB."; - return ActionResult.Success; - } - - DirectoryInfo dir = new DirectoryInfo(session["STORAGEDIR"]); - DriveInfo drive = new DriveInfo(dir.Root.FullName); - long storagePlusOverhead = Convert.ToInt64(storage * 1.1 * TB); - - // TODO: Find a way to calculate the available free space + total size of existing pieces - if (drive.TotalSize < storagePlusOverhead) - { - session["STORJ_STORAGE_VALID"] = string.Format("The disk size ({0:0.##} TB) on the selected drive {1} is less than the allocated disk space plus the 10% overhead ({2:0.##} TB total).", - decimal.Divide(drive.TotalSize, TB), drive.Name, decimal.Divide(storagePlusOverhead, TB)); + // Allocated Storage is invalid + session["STORJ_STORAGE_VALID"] = e.Message; return ActionResult.Success; } @@ -161,21 +98,14 @@ namespace Storj { string bandwidthStr = session["STORJ_BANDWIDTH"]; - if (string.IsNullOrEmpty(bandwidthStr)) + try { - session["STORJ_BANDWIDTH_VALID"] = "The value cannot be empty."; - return ActionResult.Success; + CustomActionRunner.ValidateBandwidth(bandwidthStr); } - - if (!double.TryParse(bandwidthStr, NumberStyles.Number, CultureInfo.CreateSpecificCulture("en-US"), out double bandwidth)) + catch (ArgumentException e) { - session["STORJ_BANDWIDTH_VALID"] = string.Format("'{0}' is not a valid number.", bandwidthStr); - return ActionResult.Success; - } - - if (bandwidth < 2.0) - { - session["STORJ_BANDWIDTH_VALID"] = "The allocated bandwidth cannot be less than 2 TB."; + // Allocated Bandwidth is invalid + session["STORJ_BANDWIDTH_VALID"] = e.Message; return ActionResult.Success; } @@ -190,13 +120,174 @@ namespace Storj string line = session["STORJ_SERVICE_COMMAND"]; session.Log($"ExtractInstallDir registry value: {line}"); - Regex pattern = new Regex(@"--config-dir ""(?.*)"""); - Match match = pattern.Match(line); - string path = match.Groups["installDir"].Value; + string path = CustomActionRunner.ExtractInstallDir(line); session.Log($"ExtractInstallDir extracted path: {path}"); session["STORJ_INSTALLDIR"] = path; return ActionResult.Success; } } + + public class CustomActionRunner + { + private const long GB = 1000 * 1000 * 1000; + private const long TB = (long)1000 * 1000 * 1000 * 1000; + private const long MinFreeSpace = 550 * GB; // (500 GB + 10% overhead) + + public static void ValidateIdentityDir(string identityDir) + { + if (string.IsNullOrEmpty(identityDir)) + { + throw new ArgumentException("You must select an identity folder."); + } + + if (!Directory.Exists(identityDir)) + { + throw new ArgumentException(string.Format("Folder '{0}' does not exist.", identityDir)); + } + + if (!File.Exists(Path.Combine(identityDir, "ca.cert"))) + { + throw new ArgumentException("File 'ca.cert' not found in the selected folder."); + } + + if (!File.Exists(Path.Combine(identityDir, "ca.key"))) + { + throw new ArgumentException("File 'ca.key' not found in the selected folder."); + } + + if (!File.Exists(Path.Combine(identityDir, "identity.cert"))) + { + throw new ArgumentException("File 'identity.cert' not found in the selected folder."); + } + + if (!File.Exists(Path.Combine(identityDir, "identity.key"))) + { + throw new ArgumentException("File 'identity.key' not found in the selected folder."); + } + } + + public static void ValidateWallet(string wallet) + { + if (string.IsNullOrEmpty(wallet)) + { + throw new ArgumentException("The payout address cannot be empty."); + } + + if (!wallet.StartsWith("0x")) + { + throw new ArgumentException("The payout address must start with a '0x' prefix."); + } + + // Remove 0x prefix + wallet = wallet.Substring(2); + + if (wallet.Length != 40) + { + throw new ArgumentException("The payout address must have 40 characters after the '0x' prefix."); + } + + // TODO validate address checksum + } + + public static void ValidateStorageDir(string storageDir) + { + if (string.IsNullOrEmpty(storageDir)) + { + throw new ArgumentException("You must select a storage folder."); + } + + DirectoryInfo dir = new DirectoryInfo(storageDir); + DriveInfo drive = new DriveInfo(dir.Root.FullName); + + // TODO: Find a way to calculate the available free space + total size of existing pieces + if (drive.TotalSize < MinFreeSpace) + { + throw new ArgumentException(string.Format("The selected drive '{0}' has only {1:0.##} GB disk size. The minimum required is 550 GB.", + drive.Name, decimal.Divide(drive.TotalSize, GB))); + } + } + + public static void ValidateStorage(string storageStr, string storageDir) + { + if (string.IsNullOrEmpty(storageStr)) + { + throw new ArgumentException("The value cannot be empty."); + } + + if (!double.TryParse(storageStr, NumberStyles.Number, CultureInfo.CreateSpecificCulture("en-US"), out double storage)) + { + throw new ArgumentException(string.Format("'{0}' is not a valid number.", storageStr)); + } + + if (storage < 0.5) + { + throw new ArgumentException("The allocated disk space cannot be less than 0.5 TB."); + } + + if (string.IsNullOrEmpty(storageDir)) + { + throw new ArgumentException("The storage directory cannot be empty"); + } + + long storagePlusOverhead; + try + { + storagePlusOverhead = Convert.ToInt64(storage * 1.1 * TB); + } + catch (OverflowException) + { + throw new ArgumentException(string.Format("{0} TB is too large value for allocated storage.", storage)); + } + + DirectoryInfo dir = new DirectoryInfo(storageDir); + DriveInfo drive = new DriveInfo(dir.Root.FullName); + + // TODO: Find a way to calculate the available free space + total size of existing pieces + if (drive.TotalSize < storagePlusOverhead) + { + throw new ArgumentException(string.Format("The disk size ({0:0.##} TB) on the selected drive {1} is less than the allocated disk space plus the 10% overhead ({2:0.##} TB total).", + decimal.Divide(drive.TotalSize, TB), drive.Name, decimal.Divide(storagePlusOverhead, TB))); + } + } + + public static void ValidateBandwidth(string bandwidthStr) + { + if (string.IsNullOrEmpty(bandwidthStr)) + { + throw new ArgumentException("The value cannot be empty."); + } + + if (!double.TryParse(bandwidthStr, NumberStyles.Number, CultureInfo.CreateSpecificCulture("en-US"), out double bandwidth)) + { + throw new ArgumentException(string.Format("'{0}' is not a valid number.", bandwidthStr)); + } + + if (bandwidth < 2.0) + { + throw new ArgumentException("The allocated bandwidth cannot be less than 2 TB."); + } + } + + public static string ExtractInstallDir(string serviceCmd) + { + if (string.IsNullOrEmpty(serviceCmd)) + { + return null; + } + + Regex pattern = new Regex(@"--config-dir ""(?.*)"""); + Match match = pattern.Match(serviceCmd); + string installDir = match.Groups["installDir"].Value; + + if (string.IsNullOrEmpty(installDir)) + { + return null; + } + + return installDir; + } + } + + } diff --git a/installer/windows/StorjTests/ExpectedExceptionWithMessage.cs b/installer/windows/StorjTests/ExpectedExceptionWithMessage.cs new file mode 100644 index 000000000..5ae11e283 --- /dev/null +++ b/installer/windows/StorjTests/ExpectedExceptionWithMessage.cs @@ -0,0 +1,47 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +/// +/// Helper class that allows checking both the type and the message of the thrown exception. +/// +public class ExpectedExceptionWithMessageAttribute : ExpectedExceptionBaseAttribute +{ + public Type ExceptionType { get; set; } + + public string ExpectedMessage { get; set; } + + public ExpectedExceptionWithMessageAttribute(Type exceptionType) + { + this.ExceptionType = exceptionType; + } + + public ExpectedExceptionWithMessageAttribute(Type exceptionType, string expectedMessage) + { + this.ExceptionType = exceptionType; + this.ExpectedMessage = expectedMessage; + } + + protected override void Verify(Exception e) + { + if (e.GetType() != this.ExceptionType) + { + throw new AssertFailedException(string.Format( + "Test method threw exception {0}, but exception {1} was expected. Exception message: {1}: {2}", + this.ExceptionType.FullName, + e.GetType().FullName, + e.Message + )); + } + + var actualMessage = e.Message.Trim(); + + if (this.ExpectedMessage != null && !this.ExpectedMessage.Equals(actualMessage)) + { + throw new AssertFailedException(string.Format( + "Test method threw exception with message '{0}', but message '{1}' was expected.", + actualMessage, + this.ExpectedMessage + )); + } + } +} \ No newline at end of file diff --git a/installer/windows/StorjTests/ExtractInstallDirTests.cs b/installer/windows/StorjTests/ExtractInstallDirTests.cs new file mode 100644 index 000000000..52cd02bf8 --- /dev/null +++ b/installer/windows/StorjTests/ExtractInstallDirTests.cs @@ -0,0 +1,35 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Storj; + +namespace StorjTests +{ + [TestClass] + public class ExtractInstallDirTests + { + [TestMethod] + public void NullServiceCmd() + { + Assert.IsNull(CustomActionRunner.ExtractInstallDir(null)); + } + + [TestMethod] + public void EmptyServiceCmd() + { + Assert.IsNull(CustomActionRunner.ExtractInstallDir("")); + } + + [TestMethod] + public void MissingConfigDirFlag() + { + Assert.IsNull(CustomActionRunner.ExtractInstallDir("\"C:\\Program Files\\Storj\\Storage Node\\storagenode.exe\" run")); + } + + [TestMethod] + public void ValidServiceCmd() + { + Assert.AreEqual("C:\\Program Files\\Storj\\Storage Node\\\\", + CustomActionRunner.ExtractInstallDir("\"C:\\Program Files\\Storj\\Storage Node\\storagenode.exe\" run --config-dir \"C:\\Program Files\\Storj\\Storage Node\\\\\"")); + } + } +} diff --git a/installer/windows/StorjTests/Properties/AssemblyInfo.cs b/installer/windows/StorjTests/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..ef63bce49 --- /dev/null +++ b/installer/windows/StorjTests/Properties/AssemblyInfo.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("StorjTests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("StorjTests")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("a3bae3d4-cc1f-4b10-a75f-fcb97f63ef3a")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/installer/windows/StorjTests/StorjTests.csproj b/installer/windows/StorjTests/StorjTests.csproj new file mode 100644 index 000000000..62ab8063e --- /dev/null +++ b/installer/windows/StorjTests/StorjTests.csproj @@ -0,0 +1,89 @@ + + + + + + Debug + AnyCPU + {A3BAE3D4-CC1F-4B10-A75F-FCB97F63EF3A} + Library + Properties + StorjTests + StorjTests + v4.5.2 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + + + + 15.0 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + + ..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + + + + + + + + + + + + + + + + + + {DDD766C6-0AED-44C9-B61A-2D752D811B56} + Storj + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/installer/windows/StorjTests/ValidateBandwidthTests.cs b/installer/windows/StorjTests/ValidateBandwidthTests.cs new file mode 100644 index 000000000..6d820d285 --- /dev/null +++ b/installer/windows/StorjTests/ValidateBandwidthTests.cs @@ -0,0 +1,44 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Storj; + +namespace StorjTests +{ + [TestClass] + public class ValidateBandwidthTests + { + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "The value cannot be empty.")] + public void NullBandwidth() + { + CustomActionRunner.ValidateBandwidth(null); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "The value cannot be empty.")] + public void EmptyBandwidth() + { + CustomActionRunner.ValidateBandwidth(""); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "'some random text' is not a valid number.")] + public void InvalidNumber() + { + CustomActionRunner.ValidateBandwidth("some random text"); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "The allocated bandwidth cannot be less than 2 TB.")] + public void TooSmall() + { + CustomActionRunner.ValidateBandwidth("1.41"); + } + + [TestMethod] + public void ValidBandwidth() + { + CustomActionRunner.ValidateBandwidth("3.14"); + } + } +} diff --git a/installer/windows/StorjTests/ValidateIdentityDirTests.cs b/installer/windows/StorjTests/ValidateIdentityDirTests.cs new file mode 100644 index 000000000..b9426338b --- /dev/null +++ b/installer/windows/StorjTests/ValidateIdentityDirTests.cs @@ -0,0 +1,33 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Storj; + +namespace StorjTests +{ + [TestClass] + public class ValidateIdentityDirTests + { + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "You must select an identity folder.")] + public void NullIdentityDir() + { + CustomActionRunner.ValidateIdentityDir(null); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "You must select an identity folder.")] + public void EmptyIdentityDir() + { + CustomActionRunner.ValidateIdentityDir(""); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "Folder 'X:\\Some\\Nonexistent\\Folder' does not exist.")] + public void NonexistentIdentityDir() + { + CustomActionRunner.ValidateIdentityDir("X:\\Some\\Nonexistent\\Folder"); + } + + // TODO: add tests that mock the file system + } +} diff --git a/installer/windows/StorjTests/ValidateStorageDirTests.cs b/installer/windows/StorjTests/ValidateStorageDirTests.cs new file mode 100644 index 000000000..1b417524f --- /dev/null +++ b/installer/windows/StorjTests/ValidateStorageDirTests.cs @@ -0,0 +1,26 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Storj; + +namespace StorjTests +{ + [TestClass] + public class ValidateStorageDirTests + { + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "You must select a storage folder.")] + public void NullStorageDir() + { + CustomActionRunner.ValidateStorageDir(null); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "You must select a storage folder.")] + public void EmptyStorageDir() + { + CustomActionRunner.ValidateStorageDir(""); + } + + // TODO: add tests that mock the file system + } +} diff --git a/installer/windows/StorjTests/ValidateStorageTests.cs b/installer/windows/StorjTests/ValidateStorageTests.cs new file mode 100644 index 000000000..e1e58dc89 --- /dev/null +++ b/installer/windows/StorjTests/ValidateStorageTests.cs @@ -0,0 +1,68 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Storj; + +namespace StorjTests +{ + [TestClass] + public class ValidateStorageTests + { + private const string StorageDir = "X:\\storage"; + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "The value cannot be empty.")] + public void NullStorage() + { + CustomActionRunner.ValidateStorage(null, StorageDir); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "The value cannot be empty.")] + public void EmptyStorage() + { + CustomActionRunner.ValidateStorage("", StorageDir); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "'some random text' is not a valid number.")] + public void InvalidNumber() + { + CustomActionRunner.ValidateStorage("some random text", StorageDir); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "The allocated disk space cannot be less than 0.5 TB.")] + public void TooSmall() + { + CustomActionRunner.ValidateStorage("0.41", StorageDir); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "10000000 TB is too large value for allocated storage.")] + public void TooLarge() + { + CustomActionRunner.ValidateStorage("10000000", StorageDir); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "The storage directory cannot be empty")] + public void NullStorageDir() + { + CustomActionRunner.ValidateStorage("3.14", null); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "The storage directory cannot be empty")] + public void EmptyStorageDir() + { + CustomActionRunner.ValidateStorage("3.14", ""); + } + + // TODO: add tests that mock the file system + // [TestMethod] + // public void ValidStorage() + // { + // CustomActionRunner.ValidateStorage("3.14", StorageDir); + // } + } +} diff --git a/installer/windows/StorjTests/ValidateWalletTests.cs b/installer/windows/StorjTests/ValidateWalletTests.cs new file mode 100644 index 000000000..c38045293 --- /dev/null +++ b/installer/windows/StorjTests/ValidateWalletTests.cs @@ -0,0 +1,51 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Storj; + +namespace StorjTests +{ + [TestClass] + public class ValidateWalletTests + { + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "The payout address cannot be empty.")] + public void NullWallet() + { + CustomActionRunner.ValidateWallet(null); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "The payout address cannot be empty.")] + public void EmptyWallet() + { + CustomActionRunner.ValidateWallet(""); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "The payout address must start with a '0x' prefix.")] + public void PrefixMissing() + { + CustomActionRunner.ValidateWallet("e857955cfCd98bAe1073d4e314c3F9526799357A"); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "The payout address must have 40 characters after the '0x' prefix.")] + public void TooShortWallet() + { + CustomActionRunner.ValidateWallet("0xe857955cfCd98bAe1073d4e314c3F9526799357"); + } + + [TestMethod] + [ExpectedExceptionWithMessage(typeof(ArgumentException), "The payout address must have 40 characters after the '0x' prefix.")] + public void TooLongWallet() + { + CustomActionRunner.ValidateWallet("0xe857955cfCd98bAe1073d4e314c3F9526799357A0"); + } + + [TestMethod] + public void ValidWallet() + { + CustomActionRunner.ValidateWallet("0xe857955cfCd98bAe1073d4e314c3F9526799357A"); + } + } +} diff --git a/installer/windows/StorjTests/packages.config b/installer/windows/StorjTests/packages.config new file mode 100644 index 000000000..d2da0eb1d --- /dev/null +++ b/installer/windows/StorjTests/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/installer/windows/build.bat b/installer/windows/build.bat index 53352e909..840f4ae4c 100644 --- a/installer/windows/build.bat +++ b/installer/windows/build.bat @@ -5,6 +5,9 @@ rem copy the storagenode binaries to the installer project copy release\%TAG%\storagenode_windows_amd64.exe installer\windows\storagenode.exe copy release\%TAG%\storagenode-updater_windows_amd64.exe installer\windows\storagenode-updater.exe +rem install NuGet packages +nuget install installer\windows\StorjTests\packages.config -o installer\windows\packages + rem build the installer msbuild installer\windows\windows.sln /t:Build /p:Configuration=Release diff --git a/installer/windows/unittests.bat b/installer/windows/unittests.bat new file mode 100644 index 000000000..432a5295f --- /dev/null +++ b/installer/windows/unittests.bat @@ -0,0 +1,8 @@ +rem install NuGet packages +nuget install installer\windows\StorjTests\packages.config -o installer\windows\packages + +rem build the test project +msbuild installer\windows\StorjTests + +rem run the unit tests +vstest.console installer\windows\StorjTests\bin\Debug\StorjTests.dll diff --git a/installer/windows/windows.sln b/installer/windows/windows.sln index 45f0e396f..5c022b3e7 100644 --- a/installer/windows/windows.sln +++ b/installer/windows/windows.sln @@ -4,23 +4,46 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 16.0.29215.179 MinimumVisualStudioVersion = 10.0.40219.1 Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "windows", "windows.wixproj", "{1FDEF912-9783-4E0B-B656-FB80AA4B5F68}" + ProjectSection(ProjectDependencies) = postProject + {A3BAE3D4-CC1F-4B10-A75F-FCB97F63EF3A} = {A3BAE3D4-CC1F-4B10-A75F-FCB97F63EF3A} + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Storj", "Storj\Storj.csproj", "{DDD766C6-0AED-44C9-B61A-2D752D811B56}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StorjTests", "StorjTests\StorjTests.csproj", "{A3BAE3D4-CC1F-4B10-A75F-FCB97F63EF3A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1FDEF912-9783-4E0B-B656-FB80AA4B5F68}.Debug|Any CPU.ActiveCfg = Debug|x86 + {1FDEF912-9783-4E0B-B656-FB80AA4B5F68}.Debug|Any CPU.Build.0 = Debug|x86 {1FDEF912-9783-4E0B-B656-FB80AA4B5F68}.Debug|x86.ActiveCfg = Debug|x86 {1FDEF912-9783-4E0B-B656-FB80AA4B5F68}.Debug|x86.Build.0 = Debug|x86 + {1FDEF912-9783-4E0B-B656-FB80AA4B5F68}.Release|Any CPU.ActiveCfg = Release|x86 + {1FDEF912-9783-4E0B-B656-FB80AA4B5F68}.Release|Any CPU.Build.0 = Release|x86 {1FDEF912-9783-4E0B-B656-FB80AA4B5F68}.Release|x86.ActiveCfg = Release|x86 {1FDEF912-9783-4E0B-B656-FB80AA4B5F68}.Release|x86.Build.0 = Release|x86 + {DDD766C6-0AED-44C9-B61A-2D752D811B56}.Debug|Any CPU.ActiveCfg = Debug|x86 + {DDD766C6-0AED-44C9-B61A-2D752D811B56}.Debug|Any CPU.Build.0 = Debug|x86 {DDD766C6-0AED-44C9-B61A-2D752D811B56}.Debug|x86.ActiveCfg = Debug|x86 {DDD766C6-0AED-44C9-B61A-2D752D811B56}.Debug|x86.Build.0 = Debug|x86 + {DDD766C6-0AED-44C9-B61A-2D752D811B56}.Release|Any CPU.ActiveCfg = Release|x86 + {DDD766C6-0AED-44C9-B61A-2D752D811B56}.Release|Any CPU.Build.0 = Release|x86 {DDD766C6-0AED-44C9-B61A-2D752D811B56}.Release|x86.ActiveCfg = Release|x86 {DDD766C6-0AED-44C9-B61A-2D752D811B56}.Release|x86.Build.0 = Release|x86 + {A3BAE3D4-CC1F-4B10-A75F-FCB97F63EF3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A3BAE3D4-CC1F-4B10-A75F-FCB97F63EF3A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A3BAE3D4-CC1F-4B10-A75F-FCB97F63EF3A}.Debug|x86.ActiveCfg = Debug|Any CPU + {A3BAE3D4-CC1F-4B10-A75F-FCB97F63EF3A}.Debug|x86.Build.0 = Debug|Any CPU + {A3BAE3D4-CC1F-4B10-A75F-FCB97F63EF3A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A3BAE3D4-CC1F-4B10-A75F-FCB97F63EF3A}.Release|Any CPU.Build.0 = Release|Any CPU + {A3BAE3D4-CC1F-4B10-A75F-FCB97F63EF3A}.Release|x86.ActiveCfg = Release|Any CPU + {A3BAE3D4-CC1F-4B10-A75F-FCB97F63EF3A}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE