Skip to content

Commit 6a3689f

Browse files
committed
Adding modules for Server and Mongo
1 parent 2fd08e1 commit 6a3689f

File tree

15 files changed

+481
-3
lines changed

15 files changed

+481
-3
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace Samples.Specifications.Tests.Contracts
2+
{
3+
public interface IProcessManagementService
4+
{
5+
int Start(string tool, string args);
6+
void Stop(int processId);
7+
}
8+
}

Samples.Specifications.Tests.Infra.Launcher/Bootstrapper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ internal sealed class Bootstrapper :
2222
Prefixes = new[]
2323
{
2424
"Samples.Specifications.Tests", "Samples.Specifications.Client.Tests",
25-
"Samples.Specifications.Tests.Steps"
25+
"Samples.Specifications.Tests.Steps", "Samples.Specifications.Tests.Infra"
2626
},
2727
ModulesPath = "."
2828
});

Samples.Specifications.Tests.Infra.Launcher/Samples.Specifications.Tests.Infra.Launcher.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>netstandard2.0</TargetFramework>
5-
<RootNamespace>Samples.Specifications.Tests.Infra.Launcher</RootNamespace>
4+
<TargetFramework>netstandard2.0</TargetFramework>
65
</PropertyGroup>
76

87
<PropertyGroup>
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System;
2+
using System.Linq;
3+
using System.Threading.Tasks;
4+
5+
namespace Samples.Specifications.Tests.Infra
6+
{
7+
public static class DelegateExtensions
8+
{
9+
public static void Execute(this Action action) =>
10+
Execute<Exception>(action, 20, TimeSpan.FromMilliseconds(200));
11+
12+
public static void Execute<TException>(this Action action)
13+
where TException : Exception => Execute<TException>(action, 20, TimeSpan.FromMilliseconds(200));
14+
15+
public static TResult ExecuteWithResult<TException, TResult>(this Func<TResult> func,
16+
Func<TResult, string> valueExtractor = null, string[] unacceptedValues = null)
17+
where TException : Exception => ExecuteWithResult<TException, TResult>(func, 20,
18+
TimeSpan.FromMilliseconds(200), valueExtractor, unacceptedValues);
19+
20+
public static TResult ExecuteWithResult<TResult>(this Func<TResult> func,
21+
Func<TResult, string> valueExtractor = null, string[] unacceptedValues = null) =>
22+
ExecuteWithResult<Exception, TResult>(func, 20, TimeSpan.FromMilliseconds(200), valueExtractor,
23+
unacceptedValues);
24+
25+
public static TResult ExecuteWithResult<TResult>(this Func<TResult> func, int numberOfRetries,
26+
TimeSpan waitingInterval) => ExecuteWithResult<Exception, TResult>(func, numberOfRetries, waitingInterval);
27+
28+
public static void Execute<TException>(this Action action, int numberOfRetries, TimeSpan waitingInterval)
29+
where TException : Exception
30+
{
31+
TException lastException = null;
32+
for (int i = 0; i < numberOfRetries; i++)
33+
{
34+
try
35+
{
36+
action();
37+
return;
38+
}
39+
catch (TException ex)
40+
{
41+
lastException = ex;
42+
Task.Delay(waitingInterval);
43+
}
44+
}
45+
if (lastException != null)
46+
{
47+
throw lastException;
48+
}
49+
}
50+
51+
public static TResult ExecuteWithResult<TException, TResult>(
52+
this Func<TResult> func,
53+
int numberOfRetries,
54+
TimeSpan waitingInterval,
55+
Func<TResult, string> valueExtractor = null,
56+
string[] unacceptedValues = null)
57+
where TException : Exception
58+
{
59+
TException lastException = null;
60+
for (int i = 0; i < numberOfRetries; i++)
61+
{
62+
try
63+
{
64+
var result = func();
65+
if (valueExtractor != null && unacceptedValues != null)
66+
{
67+
var value = valueExtractor(result);
68+
if (unacceptedValues.Contains(value))
69+
{
70+
throw new Exception($"Unaccepted value {value}");
71+
}
72+
}
73+
return result;
74+
}
75+
catch (TException ex)
76+
{
77+
lastException = ex;
78+
Task.Delay(waitingInterval);
79+
}
80+
}
81+
if (lastException != null)
82+
{
83+
throw lastException;
84+
}
85+
return default(TResult);
86+
}
87+
}
88+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using JetBrains.Annotations;
2+
using Samples.Specifications.Tests.Contracts;
3+
using Solid.Practices.IoC;
4+
using Solid.Practices.Modularity;
5+
6+
namespace Samples.Specifications.Tests.Infra
7+
{
8+
[UsedImplicitly]
9+
internal sealed class Module : ICompositionModule<IDependencyRegistrator>
10+
{
11+
public void RegisterModule(IDependencyRegistrator dependencyRegistrator)
12+
{
13+
dependencyRegistrator
14+
.AddSingleton<IProcessManagementService, WindowsProcessManagementService>();
15+
}
16+
}
17+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<Configurations>Debug;Release;EndToEndWithFake;IntegrationWithFake;EndToEndWithReal;IntegrationWithReal</Configurations>
6+
</PropertyGroup>
7+
8+
<PropertyGroup>
9+
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
10+
</PropertyGroup>
11+
12+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='EndToEndWithFake|AnyCPU'">
13+
<OutputPath>..\Bin\EndToEndWithFake\Infra\</OutputPath>
14+
<DefineConstants>TRACE;NETSTANDARD2_0;</DefineConstants>
15+
</PropertyGroup>
16+
17+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='EndToEndWithReal|AnyCPU'">
18+
<OutputPath>..\Bin\EndToEndWithReal\Infra\</OutputPath>
19+
<DefineConstants>TRACE;NETSTANDARD2_0;</DefineConstants>
20+
</PropertyGroup>
21+
22+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='IntegrationWithFake|AnyCPU'">
23+
<OutputPath>..\Bin\IntegrationWithFake\</OutputPath>
24+
<DefineConstants>TRACE;NETSTANDARD2_0;</DefineConstants>
25+
</PropertyGroup>
26+
27+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='IntegrationWithReal|AnyCPU'">
28+
<OutputPath>..\Bin\IntegrationWithReal\</OutputPath>
29+
<DefineConstants>TRACE</DefineConstants>
30+
</PropertyGroup>
31+
32+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
33+
<DebugType>full</DebugType>
34+
<DebugSymbols>true</DebugSymbols>
35+
</PropertyGroup>
36+
37+
<ItemGroup>
38+
<PackageReference Include="JetBrains.Annotations" Version="2018.2.1" />
39+
<PackageReference Include="Solid.Practices.Modularity" Version="2.0.0-rc1" />
40+
<PackageReference Include="System.Management" Version="4.5.0" />
41+
</ItemGroup>
42+
43+
<ItemGroup>
44+
<ProjectReference Include="..\Samples.Specifications.Tests.Contracts\Samples.Specifications.Tests.Contracts.csproj" />
45+
</ItemGroup>
46+
47+
</Project>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using System.Diagnostics;
3+
using System.Management;
4+
using JetBrains.Annotations;
5+
using Samples.Specifications.Tests.Contracts;
6+
7+
namespace Samples.Specifications.Tests.Infra
8+
{
9+
[UsedImplicitly]
10+
internal sealed class WindowsProcessManagementService : IProcessManagementService
11+
{
12+
public int Start(string tool, string args)
13+
{
14+
var process = new Process
15+
{
16+
StartInfo =
17+
{
18+
UseShellExecute = false,
19+
RedirectStandardOutput = false,
20+
RedirectStandardError = false,
21+
FileName = "cmd.exe",
22+
Arguments = $"/k {tool} {args}"
23+
}
24+
};
25+
process.Start();
26+
return process.Id;
27+
}
28+
29+
public void Stop(int processId)
30+
{
31+
Action killAction = () => KillProcessAndChildren(processId);
32+
killAction.Execute();
33+
}
34+
35+
private static void KillProcessAndChildren(int pid)
36+
{
37+
// Cannot close 'system idle process'.
38+
if (pid == 0)
39+
{
40+
return;
41+
}
42+
ManagementObjectSearcher searcher = new ManagementObjectSearcher
43+
("Select * From Win32_Process Where ParentProcessID=" + pid);
44+
ManagementObjectCollection moc = searcher.Get();
45+
foreach (ManagementObject mo in moc)
46+
{
47+
KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
48+
}
49+
try
50+
{
51+
Process proc = Process.GetProcessById(pid);
52+
proc.Kill();
53+
}
54+
catch (ArgumentException)
55+
{
56+
// Process already exited.
57+
}
58+
}
59+
}
60+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using Attest.Testing.Contracts;
4+
using JetBrains.Annotations;
5+
using Samples.Specifications.Tests.Contracts;
6+
7+
namespace Samples.Specifications.Tests.Modules.Mongo
8+
{
9+
[UsedImplicitly]
10+
internal sealed class MongoApplicationModule : IStaticApplicationModule
11+
{
12+
private readonly IProcessManagementService _processManagementService;
13+
private const string MongoDbService = @"cd C:\\Program Files\\MongoDB\\Server\\3.4\\bin\\&mongod";
14+
private const string MongoDbRoot = @"c:\\data\\db";
15+
16+
public MongoApplicationModule(IProcessManagementService processManagementService)
17+
{
18+
_processManagementService = processManagementService;
19+
}
20+
21+
public string Id => "Mongo";
22+
public string RelativePath => string.Empty;
23+
24+
public int Start()
25+
{
26+
var handle = _processManagementService.Start(MongoDbService,$"--dbpath {MongoDbRoot}");
27+
//TODO: Wait while the process starts - Application.WaitWhileBusy()...
28+
Task.Delay(TimeSpan.FromSeconds(5)).Wait();
29+
return handle;
30+
}
31+
32+
public void Stop(int handle)
33+
{
34+
_processManagementService.Stop(handle);
35+
}
36+
}
37+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<Configurations>Debug;Release;EndToEndWithFake;IntegrationWithFake;EndToEndWithReal;IntegrationWithReal</Configurations>
6+
</PropertyGroup>
7+
8+
<PropertyGroup>
9+
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
10+
</PropertyGroup>
11+
12+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='EndToEndWithFake|AnyCPU'">
13+
<OutputPath>..\Bin\EndToEndWithFake\Infra\</OutputPath>
14+
<DefineConstants>TRACE;NETSTANDARD2_0;</DefineConstants>
15+
</PropertyGroup>
16+
17+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='EndToEndWithReal|AnyCPU'">
18+
<OutputPath>..\Bin\EndToEndWithReal\Infra\</OutputPath>
19+
<DefineConstants>TRACE;NETSTANDARD2_0;</DefineConstants>
20+
</PropertyGroup>
21+
22+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='IntegrationWithFake|AnyCPU'">
23+
<OutputPath>..\Bin\IntegrationWithFake\</OutputPath>
24+
<DefineConstants>TRACE;NETSTANDARD2_0;</DefineConstants>
25+
</PropertyGroup>
26+
27+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='IntegrationWithReal|AnyCPU'">
28+
<OutputPath>..\Bin\IntegrationWithReal\</OutputPath>
29+
<DefineConstants>TRACE</DefineConstants>
30+
</PropertyGroup>
31+
32+
<ItemGroup>
33+
<PackageReference Include="Attest.Testing.Contracts" Version="2.0.0-rc1" />
34+
<PackageReference Include="JetBrains.Annotations" Version="2018.2.1" />
35+
</ItemGroup>
36+
37+
<ItemGroup>
38+
<ProjectReference Include="..\Samples.Specifications.Tests.Contracts\Samples.Specifications.Tests.Contracts.csproj" />
39+
</ItemGroup>
40+
41+
</Project>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using Attest.Testing.Contracts;
4+
using JetBrains.Annotations;
5+
using Samples.Specifications.Tests.Contracts;
6+
7+
namespace Samples.Specifications.Tests.Modules.Server
8+
{
9+
[UsedImplicitly]
10+
internal sealed class ApplicationFacade : IApplicationFacade
11+
{
12+
private readonly IProcessManagementService _processManagementService;
13+
private int _applicationHandle;
14+
15+
public ApplicationFacade(IProcessManagementService processManagementService) =>
16+
_processManagementService = processManagementService;
17+
18+
public void Start(string startupPath)
19+
{
20+
_applicationHandle = _processManagementService.Start("dotnet", $"{startupPath}");
21+
//TODO: Wait while the process starts - Application.WaitWhileBusy()...
22+
Task.Delay(TimeSpan.FromSeconds(5)).Wait();
23+
}
24+
25+
public void Stop() => _processManagementService.Stop(_applicationHandle);
26+
}
27+
}

0 commit comments

Comments
 (0)