Skip to content

Commit 44897c3

Browse files
committed
migrated extension model unit tests
This is the first set of unit tests migrated over to .NET Core/Standard 2.0. * re-org the tests to better show the relationship of what is being tested. * verified changes in .NET Core/Standard 2.0 now allows us to have one, consistent code path for both .NET Core and .NET Framework with identical results.
1 parent 69b6ec7 commit 44897c3

File tree

14 files changed

+677
-0
lines changed

14 files changed

+677
-0
lines changed

TugDSC.sln

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TugDSC.Server.Abstractions"
1111
EndProject
1212
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TugDSC.Server.WebAppHost", "src\TugDSC.Server.WebAppHost\TugDSC.Server.WebAppHost.csproj", "{77F0AAAE-3518-46A7-A0E2-E09A36630300}"
1313
EndProject
14+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testing", "testing", "{B12685F6-BE1B-4F03-B872-D4FB5ED7FCA2}"
15+
EndProject
16+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TugDSC.Testing.MSTest", "src\testing\TugDSC.Testing.MSTest\TugDSC.Testing.MSTest.csproj", "{1592EC10-E626-4764-BA29-2190DD2FAA80}"
17+
EndProject
18+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{76F0F40C-622E-453C-A012-6A26C1F97F41}"
19+
EndProject
20+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "server", "server", "{6CA6E17D-22E1-4192-A7D9-2E8E13335C82}"
21+
EndProject
22+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ext", "ext", "{B69FF573-F0CC-4B73-B732-60CBBA9D8548}"
23+
EndProject
24+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.TestExt.Thingy", "test\server\ext\Sample.TestExt.Thingy\Sample.TestExt.Thingy.csproj", "{D5A99A98-07B3-483D-83A3-A16E3523D23C}"
25+
EndProject
26+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.TestExt.DynamicThingy", "test\server\ext\Sample.TestExt.DynamicThingy\Sample.TestExt.DynamicThingy.csproj", "{0B6F807E-76B2-4F65-B9DD-09F06551E073}"
27+
EndProject
28+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TugDSC.Ext-tests", "test\server\ext\TugDSC.Ext-tests\TugDSC.Ext-tests.csproj", "{350618B2-A593-4B0A-8786-335B8C060739}"
29+
EndProject
1430
Global
1531
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1632
Debug|Any CPU = Debug|Any CPU
@@ -60,10 +76,65 @@ Global
6076
{77F0AAAE-3518-46A7-A0E2-E09A36630300}.Release|x64.Build.0 = Release|x64
6177
{77F0AAAE-3518-46A7-A0E2-E09A36630300}.Release|x86.ActiveCfg = Release|x86
6278
{77F0AAAE-3518-46A7-A0E2-E09A36630300}.Release|x86.Build.0 = Release|x86
79+
{1592EC10-E626-4764-BA29-2190DD2FAA80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
80+
{1592EC10-E626-4764-BA29-2190DD2FAA80}.Debug|Any CPU.Build.0 = Debug|Any CPU
81+
{1592EC10-E626-4764-BA29-2190DD2FAA80}.Debug|x64.ActiveCfg = Debug|x64
82+
{1592EC10-E626-4764-BA29-2190DD2FAA80}.Debug|x64.Build.0 = Debug|x64
83+
{1592EC10-E626-4764-BA29-2190DD2FAA80}.Debug|x86.ActiveCfg = Debug|x86
84+
{1592EC10-E626-4764-BA29-2190DD2FAA80}.Debug|x86.Build.0 = Debug|x86
85+
{1592EC10-E626-4764-BA29-2190DD2FAA80}.Release|Any CPU.ActiveCfg = Release|Any CPU
86+
{1592EC10-E626-4764-BA29-2190DD2FAA80}.Release|Any CPU.Build.0 = Release|Any CPU
87+
{1592EC10-E626-4764-BA29-2190DD2FAA80}.Release|x64.ActiveCfg = Release|x64
88+
{1592EC10-E626-4764-BA29-2190DD2FAA80}.Release|x64.Build.0 = Release|x64
89+
{1592EC10-E626-4764-BA29-2190DD2FAA80}.Release|x86.ActiveCfg = Release|x86
90+
{1592EC10-E626-4764-BA29-2190DD2FAA80}.Release|x86.Build.0 = Release|x86
91+
{D5A99A98-07B3-483D-83A3-A16E3523D23C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
92+
{D5A99A98-07B3-483D-83A3-A16E3523D23C}.Debug|Any CPU.Build.0 = Debug|Any CPU
93+
{D5A99A98-07B3-483D-83A3-A16E3523D23C}.Debug|x64.ActiveCfg = Debug|x64
94+
{D5A99A98-07B3-483D-83A3-A16E3523D23C}.Debug|x64.Build.0 = Debug|x64
95+
{D5A99A98-07B3-483D-83A3-A16E3523D23C}.Debug|x86.ActiveCfg = Debug|x86
96+
{D5A99A98-07B3-483D-83A3-A16E3523D23C}.Debug|x86.Build.0 = Debug|x86
97+
{D5A99A98-07B3-483D-83A3-A16E3523D23C}.Release|Any CPU.ActiveCfg = Release|Any CPU
98+
{D5A99A98-07B3-483D-83A3-A16E3523D23C}.Release|Any CPU.Build.0 = Release|Any CPU
99+
{D5A99A98-07B3-483D-83A3-A16E3523D23C}.Release|x64.ActiveCfg = Release|x64
100+
{D5A99A98-07B3-483D-83A3-A16E3523D23C}.Release|x64.Build.0 = Release|x64
101+
{D5A99A98-07B3-483D-83A3-A16E3523D23C}.Release|x86.ActiveCfg = Release|x86
102+
{D5A99A98-07B3-483D-83A3-A16E3523D23C}.Release|x86.Build.0 = Release|x86
103+
{0B6F807E-76B2-4F65-B9DD-09F06551E073}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
104+
{0B6F807E-76B2-4F65-B9DD-09F06551E073}.Debug|Any CPU.Build.0 = Debug|Any CPU
105+
{0B6F807E-76B2-4F65-B9DD-09F06551E073}.Debug|x64.ActiveCfg = Debug|x64
106+
{0B6F807E-76B2-4F65-B9DD-09F06551E073}.Debug|x64.Build.0 = Debug|x64
107+
{0B6F807E-76B2-4F65-B9DD-09F06551E073}.Debug|x86.ActiveCfg = Debug|x86
108+
{0B6F807E-76B2-4F65-B9DD-09F06551E073}.Debug|x86.Build.0 = Debug|x86
109+
{0B6F807E-76B2-4F65-B9DD-09F06551E073}.Release|Any CPU.ActiveCfg = Release|Any CPU
110+
{0B6F807E-76B2-4F65-B9DD-09F06551E073}.Release|Any CPU.Build.0 = Release|Any CPU
111+
{0B6F807E-76B2-4F65-B9DD-09F06551E073}.Release|x64.ActiveCfg = Release|x64
112+
{0B6F807E-76B2-4F65-B9DD-09F06551E073}.Release|x64.Build.0 = Release|x64
113+
{0B6F807E-76B2-4F65-B9DD-09F06551E073}.Release|x86.ActiveCfg = Release|x86
114+
{0B6F807E-76B2-4F65-B9DD-09F06551E073}.Release|x86.Build.0 = Release|x86
115+
{350618B2-A593-4B0A-8786-335B8C060739}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
116+
{350618B2-A593-4B0A-8786-335B8C060739}.Debug|Any CPU.Build.0 = Debug|Any CPU
117+
{350618B2-A593-4B0A-8786-335B8C060739}.Debug|x64.ActiveCfg = Debug|x64
118+
{350618B2-A593-4B0A-8786-335B8C060739}.Debug|x64.Build.0 = Debug|x64
119+
{350618B2-A593-4B0A-8786-335B8C060739}.Debug|x86.ActiveCfg = Debug|x86
120+
{350618B2-A593-4B0A-8786-335B8C060739}.Debug|x86.Build.0 = Debug|x86
121+
{350618B2-A593-4B0A-8786-335B8C060739}.Release|Any CPU.ActiveCfg = Release|Any CPU
122+
{350618B2-A593-4B0A-8786-335B8C060739}.Release|Any CPU.Build.0 = Release|Any CPU
123+
{350618B2-A593-4B0A-8786-335B8C060739}.Release|x64.ActiveCfg = Release|x64
124+
{350618B2-A593-4B0A-8786-335B8C060739}.Release|x64.Build.0 = Release|x64
125+
{350618B2-A593-4B0A-8786-335B8C060739}.Release|x86.ActiveCfg = Release|x86
126+
{350618B2-A593-4B0A-8786-335B8C060739}.Release|x86.Build.0 = Release|x86
63127
EndGlobalSection
64128
GlobalSection(NestedProjects) = preSolution
65129
{97DECA03-C0C3-4F41-A0FE-F51CA949D501} = {BA29CE93-33EE-419B-A855-DA934573FA83}
66130
{8BAD111C-0371-4F65-BAD7-1B88FADC84E0} = {BA29CE93-33EE-419B-A855-DA934573FA83}
67131
{77F0AAAE-3518-46A7-A0E2-E09A36630300} = {BA29CE93-33EE-419B-A855-DA934573FA83}
132+
{B12685F6-BE1B-4F03-B872-D4FB5ED7FCA2} = {BA29CE93-33EE-419B-A855-DA934573FA83}
133+
{1592EC10-E626-4764-BA29-2190DD2FAA80} = {B12685F6-BE1B-4F03-B872-D4FB5ED7FCA2}
134+
{6CA6E17D-22E1-4192-A7D9-2E8E13335C82} = {76F0F40C-622E-453C-A012-6A26C1F97F41}
135+
{B69FF573-F0CC-4B73-B732-60CBBA9D8548} = {6CA6E17D-22E1-4192-A7D9-2E8E13335C82}
136+
{D5A99A98-07B3-483D-83A3-A16E3523D23C} = {B69FF573-F0CC-4B73-B732-60CBBA9D8548}
137+
{0B6F807E-76B2-4F65-B9DD-09F06551E073} = {B69FF573-F0CC-4B73-B732-60CBBA9D8548}
138+
{350618B2-A593-4B0A-8786-335B8C060739} = {B69FF573-F0CC-4B73-B732-60CBBA9D8548}
68139
EndGlobalSection
69140
EndGlobal

test/server/ext/README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Testing `TugDSC.Ext`
2+
3+
This folder contains a collection of projects supporting testing of the TugDSC extension model.
4+
5+
We define a *fake* extension hierarchy sample in the `Sample.TestExt` namespace.
6+
7+
There are two supporting library projects:
8+
9+
* `Sample.TestExt.Thingy` - defines the extension interface and its corresponding provider;
10+
also defines a default implementation (`basic`)
11+
* `Sample.TestExt.DynamicThingy` - defines a second implementation of the extension interface
12+
and associated provider to be used for dynamic discovery and loading (`dynaThingy`).
13+
14+
Across these two projects, the hierarchy of components is as follows:
15+
16+
* `Sample.TestExt.Thingy`:
17+
* `IThingy`
18+
* `IThingyProvider`
19+
* `SimpleThingyProviderManager` - a provider manager that tests out static
20+
references (build-time) to extension
21+
* `DynamicThingyProviderManager` - a provider manager that tests out dynamic
22+
discovery and loading of extensions
23+
24+
* `Sample.TestExt.Thingy.Impl`:
25+
* `BasicThingy`
26+
* `BasicThingyProvider`
27+
28+
* `Sample.TestExt.DynamicThingy.Impl`:
29+
* `DynamicThingy`
30+
* `DynamicThingyProvider`
31+
32+
33+
The main testing project `TugDSC.Ext-tests` has an explicit, build-time project reference
34+
to the `Sample.TestExt.Thingy` library project and no reference at all to the
35+
`Sample.TestExt.DynamicThingy` library project.
36+
37+
The first set of tests all focus on verifying the core functions of discovery and resolution
38+
against the statically referenced provider (`basic`).
39+
40+
The latter set of tests add dynamic paths and library references to the second implementation
41+
(`dynaThingy`) to test out dynamic discovery and load features.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright © The DevOps Collective, Inc. All rights reserved.
3+
* Licensed under GNU GPL v3. See top-level LICENSE.txt for more details.
4+
*/
5+
6+
using System;
7+
using Sample.TestExt.Thingy;
8+
9+
namespace Sample.TestExt.DynamicThingy.Impl
10+
{
11+
public class DynamicThingy : IThingy
12+
{
13+
private string _thing;
14+
15+
public Func<string, string> Func
16+
{ get; set; }
17+
18+
public bool IsDisposed
19+
{ get; private set; }
20+
21+
public void SetThing(string value)
22+
{
23+
_thing = Func(_thing);
24+
}
25+
26+
public string GetThing()
27+
{
28+
return _thing;
29+
}
30+
31+
#region IDisposable Support
32+
33+
protected virtual void Dispose(bool disposing)
34+
{
35+
if (!IsDisposed)
36+
{
37+
if (disposing)
38+
{
39+
// TODO: dispose managed state (managed objects).
40+
}
41+
42+
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
43+
// TODO: set large fields to null.
44+
45+
IsDisposed = true;
46+
}
47+
}
48+
49+
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
50+
// ~FuncThingy() {
51+
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
52+
// Dispose(false);
53+
// }
54+
55+
// This code added to correctly implement the disposable pattern.
56+
public void Dispose()
57+
{
58+
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
59+
Dispose(true);
60+
// TODO: uncomment the following line if the finalizer is overridden above.
61+
// GC.SuppressFinalize(this);
62+
}
63+
64+
#endregion
65+
}
66+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright © The DevOps Collective, Inc. All rights reserved.
3+
* Licensed under GNU GPL v3. See top-level LICENSE.txt for more details.
4+
*/
5+
6+
using System;
7+
using System.Collections.Generic;
8+
using Sample.TestExt.Thingy;
9+
using TugDSC.Ext;
10+
11+
namespace Sample.TestExt.DynamicThingy.Impl
12+
{
13+
public class DynamicThingyProvider : IThingyProvider
14+
{
15+
private Func<string, string> _func;
16+
17+
private static readonly ProviderInfo INFO = new ProviderInfo("dynaThingy");
18+
private static readonly IEnumerable<ProviderParameterInfo> PARAMS = new[]
19+
{
20+
new ProviderParameterInfo(nameof(DynamicThingy.Func),
21+
label: "Thingy Func",
22+
description: "A Func that will be applied to derive a new thingy",
23+
isRequired: true),
24+
};
25+
26+
public ProviderInfo Describe() => INFO;
27+
public IEnumerable<ProviderParameterInfo> DescribeParameters() => PARAMS;
28+
29+
public void SetParameters(IDictionary<string, object> productParams)
30+
{
31+
if (productParams.ContainsKey(nameof(DynamicThingy.Func)))
32+
throw new KeyNotFoundException("missing required parameter 'Func'");
33+
34+
_func = (Func<string, string>)productParams[nameof(DynamicThingy.Func)];
35+
}
36+
37+
public IThingy Produce()
38+
{
39+
if (_func == null)
40+
throw new InvalidOperationException("parameters have not been set");
41+
42+
return new DynamicThingy
43+
{
44+
Func = _func,
45+
};
46+
}
47+
}
48+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<ProjectReference Include="..\..\..\src\TugDSC.Abstractions\TugDSC.Abstractions.csproj" />
9+
<ProjectReference Include="..\Sample.TestExt.Thingy\Sample.TestExt.Thingy.csproj" />
10+
</ItemGroup>
11+
12+
</Project>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright © The DevOps Collective, Inc. All rights reserved.
3+
* Licensed under GNU GPL v3. See top-level LICENSE.txt for more details.
4+
*/
5+
6+
using System.Collections.Generic;
7+
using System.Reflection;
8+
using Microsoft.Extensions.Logging;
9+
using TugDSC.Ext.Util;
10+
11+
namespace Sample.TestExt.Thingy
12+
{
13+
/// <summary>
14+
/// A test provider manager implementation that is based on MEF
15+
/// support for dynamic discovery and loading of provider implementations.
16+
/// </summary>
17+
public class DynamicThingyProviderManager : ProviderManagerBase<IThingyProvider, IThingy>
18+
{
19+
private static readonly ILogger LOG = new LoggerFactory()
20+
.CreateLogger<DynamicThingyProviderManager>();
21+
22+
public DynamicThingyProviderManager(
23+
IEnumerable<Assembly> searchAssemblies = null,
24+
IEnumerable<string> searchPaths = null,
25+
bool resetBuiltIns = false,
26+
bool resetSearchAssemblies = false,
27+
bool resetSearchPaths = false)
28+
: base(LOG)
29+
{
30+
// Check if any of the default search
31+
// collections should be cleared
32+
if (resetBuiltIns)
33+
base.ClearBuiltIns();
34+
if (resetSearchAssemblies)
35+
base.ClearSearchAssemblies();
36+
if (resetSearchPaths)
37+
base.ClearSearchPaths();
38+
39+
// Add to the searchable assembly collection
40+
if (searchAssemblies != null)
41+
base.AddSearchAssemblies(searchAssemblies);
42+
43+
// Add to the searchable path collection
44+
if (searchPaths != null)
45+
base.AddSearchPath(searchPaths);
46+
}
47+
}
48+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright © The DevOps Collective, Inc. All rights reserved.
3+
* Licensed under GNU GPL v3. See top-level LICENSE.txt for more details.
4+
*/
5+
6+
namespace Sample.TestExt.Thingy
7+
{
8+
public interface IThingy : TugDSC.Ext.IProviderProduct
9+
{
10+
void SetThing(string value);
11+
12+
string GetThing();
13+
}
14+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
* Copyright © The DevOps Collective, Inc. All rights reserved.
3+
* Licensed under GNU GPL v3. See top-level LICENSE.txt for more details.
4+
*/
5+
6+
namespace Sample.TestExt.Thingy
7+
{
8+
public interface IThingyProvider : TugDSC.Ext.IProvider<IThingy>
9+
{ }
10+
}

0 commit comments

Comments
 (0)