Skip to content

Commit

Permalink
Support dedicated installation package directory
Browse files Browse the repository at this point in the history
Introduced PackagesCrawler to encapsulate logic that will read all
installation packages full file paths. It enables the DeployClient to
read installation packages from a defined directory. It's no more
necessary to save installation packages beside the DeployClient.exe.

Encapsulated code in own method, that will write packages information to
console and cancels the execution if no packages were found in packages
directory, to get better readable code.

Added unit tests for new PackagesCrawler component.

Migrated Solution to Visual Studio 2019.

Updated DeployClient project to .Net Framework 4.8 to get it up to date.

Related issue: DNNCommunity#26
  • Loading branch information
HaGGi13 committed Jun 7, 2020
1 parent ab2e194 commit a8c6517
Show file tree
Hide file tree
Showing 11 changed files with 484 additions and 32 deletions.
87 changes: 87 additions & 0 deletions DeployClient.Tests/DeployClient.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2F81EBF7-A395-4716-8B1C-23FE9EE8B7CD}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DeployClient.Tests</RootNamespace>
<AssemblyName>DeployClient.Tests</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="FluentAssertions, Version=5.10.3.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.5.10.3\lib\net47\FluentAssertions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\MSTest.TestFramework.2.1.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\MSTest.TestFramework.2.1.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Abstractions, Version=11.0.0.0, Culture=neutral, PublicKeyToken=96bf224d23c43e59, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.Abstractions.11.0.7\lib\net461\System.IO.Abstractions.dll</HintPath>
</Reference>
<Reference Include="System.IO.Abstractions.TestingHelpers, Version=11.0.0.0, Culture=neutral, PublicKeyToken=96bf224d23c43e59, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.Abstractions.TestingHelpers.11.0.7\lib\net461\System.IO.Abstractions.TestingHelpers.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="PackageCrawlerTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DeployClient\DeployClient.csproj">
<Project>{b6122ccd-75f9-4def-8daa-e11789d6d6d8}</Project>
<Name>DeployClient</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props'))" />
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets'))" />
</Target>
<Import Project="..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets')" />
</Project>
245 changes: 245 additions & 0 deletions DeployClient.Tests/PackageCrawlerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Abstractions;
using System.IO.Abstractions.TestingHelpers;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace DeployClient.Tests
{
[TestClass]
public class PackageCrawlerTests
{
private string _currentExecutionPath;


[TestInitialize]
public void Initialize()
{
_currentExecutionPath = $@"{Environment.CurrentDirectory}\DeployClient";
}


#region constructor tests

[TestMethod]
public void FileCrawler_Should_Use_Execution_Directory_When_Null_Argument()
{
// Arrange
var mockFileSystem = GetBasicPreparedMockFileSystem(_currentExecutionPath);

// Act
var fileCrawler = new PackageCrawler(mockFileSystem, null);

// Assert
fileCrawler.PackageDirectoryPath.Should().Be(_currentExecutionPath);
}

[TestMethod]
public void FileCrawler_Should_Use_Execution_Directory_When_Empty_String_Argument()
{
// Arrange
var mockFileSystem = GetBasicPreparedMockFileSystem(_currentExecutionPath);

// Act
var fileCrawler = new PackageCrawler(mockFileSystem, string.Empty);

// Assert
fileCrawler.PackageDirectoryPath.Should().Be(_currentExecutionPath);
}

[TestMethod]
public void FileCrawler_Should_Use_Execution_Directory_When_Whitespaces_Argument()
{
// Arrange
var mockFileSystem = GetBasicPreparedMockFileSystem(_currentExecutionPath);

// Act
var fileCrawler = new PackageCrawler(mockFileSystem, " ");

// Assert
fileCrawler.PackageDirectoryPath.Should().Be(_currentExecutionPath);
}

[TestMethod]
public void FileCrawler_Should_Throw_Exception_When_Directory_Not_Exist()
{
// Arrange
var mockFileSystem = GetBasicPreparedMockFileSystem(_currentExecutionPath);

// Act
// ReSharper disable once ObjectCreationAsStatement
Action initialization = () => new PackageCrawler(mockFileSystem, "FooBar");

// Assert
initialization.Should().Throw<DirectoryNotFoundException>();
}

[TestMethod]
public void FileCrawler_Should_Initialize_With_Provided_Directory_When_Directory_Exist()
{
// Arrange
const string directoryName = "Packages";

var mockFileSystem = GetBasicPreparedMockFileSystem(_currentExecutionPath);
mockFileSystem.Directory.CreateDirectory(directoryName);

// Act
var fileCrawler = new PackageCrawler(mockFileSystem, directoryName);

// Assert
fileCrawler.PackageDirectoryPath.Should().Be($@"{_currentExecutionPath}\{directoryName}");
}



[TestMethod]
public void FileCrawler_Should_Initialize_With_Provided_Directory_When_Directory_Exist_And_Full_Path()
{
// Arrange
const string directoryName = "Packages";

var mockFileSystem = GetBasicPreparedMockFileSystem(_currentExecutionPath);
var directory = mockFileSystem.Directory.CreateDirectory(directoryName);

var packageDirectoryPath = directory.FullName;

// Act
var fileCrawler = new PackageCrawler(mockFileSystem, packageDirectoryPath);

// Assert
fileCrawler.PackageDirectoryPath.Should().Be(packageDirectoryPath);
}

#endregion

#region GetPackagesFullPaths tests

[TestMethod]
public void GetPackagesFullPaths_Should_Return_Empty_Enumerable_When_Directory_Empty()
{
// Arrange
const string directoryName = "Packages";

var mockFileSystem = GetBasicPreparedMockFileSystem(_currentExecutionPath);
mockFileSystem.Directory.CreateDirectory(directoryName);

var packageCrawler = new PackageCrawler(mockFileSystem, directoryName);

// Act
var packages = packageCrawler.GetPackagesFullPaths();

// Assert
packages.Should().BeEmpty();
}

[TestMethod]
public void GetPackagesFullPaths_Should_Return_Zip_Files_Full_Paths_When_Directory_Contains_Zip_Files_Only()
{
// Arrange
const string directoryName = "Packages";

var mockFiles = GetBasicMockFiles();
mockFiles.Add($@"{_currentExecutionPath}\Packages\TestPackage_1.zip", new MockFileData("#1 fake zip file."));
mockFiles.Add($@"{_currentExecutionPath}\Packages\TestPackage_2.zip", new MockFileData("#2 fake zip file."));
mockFiles.Add($@"{_currentExecutionPath}\Packages\TestPackage_3.zip", new MockFileData("#3 fake zip file."));

var mockFileSystem = new MockFileSystem(mockFiles, _currentExecutionPath);

var packageCrawler = new PackageCrawler(mockFileSystem, directoryName);

// Act
var packages = packageCrawler.GetPackagesFullPaths();

// Assert
packages.Should().HaveCount(3);
}

[TestMethod]
public void GetPackagesFullPaths_Should_Return_Only_Zip_Files_Full_Paths_When_Directory_Contains_Different_File_Kinds()
{
// Arrange
const string directoryName = "Packages";

var mockFiles = GetBasicMockFiles();
mockFiles.Add($@"{_currentExecutionPath}\Packages\TestPackage.zip", new MockFileData("A fake zip file."));
mockFiles.Add($@"{_currentExecutionPath}\Packages\TestTextFile.txt", new MockFileData("Just a text file."));

var mockFileSystem = new MockFileSystem(mockFiles, _currentExecutionPath);

var packageCrawler = new PackageCrawler(mockFileSystem, directoryName);

// Act
var packages = packageCrawler.GetPackagesFullPaths();

// Assert
packages.Should().HaveCount(1);
}

[TestMethod]
public void GetPackagesFullPaths_Should_Return_Zip_Files_Full_Paths_When_Directory_Contains_Different_File_Kinds_And_Full_Path_Initialization()
{
// Arrange
var packageDirectoryPath = $@"{_currentExecutionPath}\Packages";

var mockFiles = GetBasicMockFiles();
mockFiles.Add($@"{packageDirectoryPath}\TestPackage.zip", new MockFileData("A fake zip file."));
mockFiles.Add($@"{packageDirectoryPath}\TestTextFile.txt", new MockFileData("Just a text file."));

var mockFileSystem = new MockFileSystem(mockFiles, _currentExecutionPath);

var packageCrawler = new PackageCrawler(mockFileSystem, packageDirectoryPath);

// Act
var packages = packageCrawler.GetPackagesFullPaths();

// Assert
packages.Should().HaveCount(1);
}

[TestMethod]
public void GetPackagesFullPaths_Should_Return_Zip_Files_Of_Top_Directory_Only_When_Sub_Directory_Exists_With_Zip_Files()
{
// Arrange
const string directoryName = "Packages";

var mockFiles = GetBasicMockFiles();
mockFiles.Add($@"{_currentExecutionPath}\Packages\TestPackage.zip", new MockFileData("A fake zip file."));
mockFiles.Add($@"{_currentExecutionPath}\Packages\SubDirectory\SubDir_TestPackage.zip", new MockFileData("A fake zip file from sub-directory."));

var mockFileSystem = new MockFileSystem(mockFiles, _currentExecutionPath);

var packageCrawler = new PackageCrawler(mockFileSystem, directoryName);

// Act
var packages = packageCrawler.GetPackagesFullPaths();

// Assert
packages.Should().HaveCount(1);
}

#endregion


#region helper methods

private IFileSystem GetBasicPreparedMockFileSystem(string currentDirectoryPath)
{
return new MockFileSystem(GetBasicMockFiles(), currentDirectoryPath);
}

private IDictionary<string, MockFileData> GetBasicMockFiles()
{
return new Dictionary<string, MockFileData>
{
{
$@"{_currentExecutionPath}\DeployClient_dummy.txt",
new MockFileData("Represents the executable to know where we are.")
}
};
}

#endregion
}
}
20 changes: 20 additions & 0 deletions DeployClient.Tests/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[assembly: AssemblyTitle("DeployClient.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DeployClient.Tests")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: ComVisible(false)]

[assembly: Guid("2f81ebf7-a395-4716-8b1c-23fe9ee8b7cd")]

// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
8 changes: 8 additions & 0 deletions DeployClient.Tests/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentAssertions" version="5.10.3" targetFramework="net48" />
<package id="MSTest.TestAdapter" version="2.1.1" targetFramework="net472" />
<package id="MSTest.TestFramework" version="2.1.1" targetFramework="net472" />
<package id="System.IO.Abstractions" version="11.0.7" targetFramework="net48" />
<package id="System.IO.Abstractions.TestingHelpers" version="11.0.7" targetFramework="net48" />
</packages>
2 changes: 1 addition & 1 deletion DeployClient/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
</startup>
<applicationSettings>
<DeployClient.Properties.Settings>
Expand Down
Loading

0 comments on commit a8c6517

Please sign in to comment.