Skip to content

Commit 8dcd5b0

Browse files
committed
Added tests that can be implemented for any provider to ensure consistency
Partly to allow me to get a better understanding of the code, partly so we can have a better idea that all the providers work in a consistent manner. Part of aspnet/Configuration#559 I will file issues for things found.
1 parent 1575632 commit 8dcd5b0

20 files changed

+958
-4
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Collections;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using Microsoft.Azure.KeyVault;
8+
using Microsoft.Azure.KeyVault.Models;
9+
using Microsoft.Extensions.Configuration.Test;
10+
using Microsoft.Rest.Azure;
11+
using Moq;
12+
13+
namespace Microsoft.Extensions.Configuration.AzureKeyVault.Test
14+
{
15+
public class ConfigurationProviderKeyVaultTest : ConfigurationProviderTestBase
16+
{
17+
protected override (IConfigurationProvider Provider, System.Action Initializer) LoadThroughProvider(
18+
TestSection testConfig)
19+
{
20+
var values = new List<KeyValuePair<string, string>>();
21+
SectionToValues(testConfig, "", values);
22+
23+
return (FromKeyVault(values), () => {});
24+
}
25+
26+
private IConfigurationProvider FromKeyVault(IEnumerable<KeyValuePair<string, string>> data)
27+
{
28+
const string vaultUri = "https://vault";
29+
30+
var client = new Mock<IKeyVaultClient>(MockBehavior.Strict);
31+
var rawData = data.ToList();
32+
var nextPageLink = vaultUri;
33+
34+
for (var i = 0; i < rawData.Count; i++)
35+
{
36+
var currentPageLink = nextPageLink;
37+
nextPageLink = i < (rawData.Count - 1) ? $"next{i}" : null;
38+
39+
var secretId = new SecretIdentifier(vaultUri, rawData[i].Key).Identifier;
40+
41+
var pageMock = new PageMock
42+
{
43+
NextPageLink = nextPageLink,
44+
Value = new[] { new SecretItem { Id = secretId, Attributes = new SecretAttributes { Enabled = true } } }
45+
};
46+
47+
if (i == 0)
48+
{
49+
client.Setup(c => c.GetSecretsAsync(currentPageLink)).ReturnsAsync(pageMock);
50+
}
51+
else
52+
{
53+
client.Setup(c => c.GetSecretsNextAsync(currentPageLink)).ReturnsAsync(pageMock);
54+
}
55+
56+
client.Setup(c => c.GetSecretAsync(secretId)).ReturnsAsync(new SecretBundle() { Value = rawData[i].Value, Id = secretId });
57+
}
58+
59+
return new AzureKeyVaultConfigurationProvider(
60+
client.Object,
61+
vaultUri,
62+
new DefaultKeyVaultSecretManager());
63+
}
64+
65+
private class PageMock : IPage<SecretItem>
66+
{
67+
public IEnumerable<SecretItem> Value { get; set; }
68+
public IEnumerator<SecretItem> GetEnumerator() => Value.GetEnumerator();
69+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
70+
public string NextPageLink { get; set; }
71+
}
72+
}
73+
}

src/Configuration/Config.AzureKeyVault/test/Microsoft.Extensions.Configuration.AzureKeyVault.Tests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
<TargetFramework>net461</TargetFramework>
55
</PropertyGroup>
66

7+
<ItemGroup>
8+
<ProjectReference Include="..\..\Config\test\Microsoft.Extensions.Configuration.Tests.csproj" />
9+
</ItemGroup>
10+
711
<ItemGroup>
812
<Reference Include="Microsoft.Extensions.Configuration.AzureKeyVault" />
913
<Reference Include="Microsoft.Extensions.Configuration.Test.Common" />
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using Microsoft.Extensions.Configuration.Test;
8+
using Xunit;
9+
10+
namespace Microsoft.Extensions.Configuration.CommandLine.Test
11+
{
12+
public class ConfigurationProviderCommandLineTest : ConfigurationProviderTestBase
13+
{
14+
protected override (IConfigurationProvider Provider, Action Initializer) LoadThroughProvider(
15+
TestSection testConfig)
16+
{
17+
var args = new List<string>();
18+
SectionToArgs(args, "", testConfig);
19+
20+
var provider = new CommandLineConfigurationProvider(args);
21+
22+
return (provider, () => { });
23+
}
24+
25+
private void SectionToArgs(List<string> args, string sectionName, TestSection section)
26+
{
27+
foreach (var tuple in section.Values.SelectMany(e => e.Value.Expand(e.Key)))
28+
{
29+
args.Add($"--{sectionName}{tuple.Key}={tuple.Value}");
30+
}
31+
32+
foreach (var tuple in section.Sections)
33+
{
34+
SectionToArgs(args, sectionName + tuple.Key + ":", tuple.Section);
35+
}
36+
}
37+
38+
[Fact]
39+
public override void Load_from_single_provider_with_duplicates_throws()
40+
{
41+
AssertConfig(BuildConfigRoot(LoadThroughProvider(TestSection.DuplicatesTestConfig)));
42+
}
43+
44+
[Fact]
45+
public override void Load_from_single_provider_with_differing_case_duplicates_throws()
46+
{
47+
AssertConfig(BuildConfigRoot(LoadThroughProvider(TestSection.DuplicatesDifferentCaseTestConfig)));
48+
}
49+
}
50+
}

src/Configuration/Config.CommandLine/test/Microsoft.Extensions.Configuration.CommandLine.Tests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
55
</PropertyGroup>
66

7+
<ItemGroup>
8+
<ProjectReference Include="..\..\Config\test\Microsoft.Extensions.Configuration.Tests.csproj" />
9+
</ItemGroup>
10+
711
<ItemGroup>
812
<Reference Include="Microsoft.Extensions.Configuration.CommandLine" />
913
<Reference Include="Microsoft.Extensions.Configuration.Test.Common" />
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections;
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
using Microsoft.Extensions.Configuration.Test;
9+
10+
namespace Microsoft.Extensions.Configuration.EnvironmentVariables.Test
11+
{
12+
public class ConfigurationProviderEnvironmentVariablesTest : ConfigurationProviderTestBase
13+
{
14+
protected override (IConfigurationProvider Provider, Action Initializer) LoadThroughProvider(
15+
TestSection testConfig)
16+
{
17+
var values = new List<KeyValuePair<string, string>>();
18+
SectionToValues(testConfig, "", values);
19+
20+
var provider = new EnvironmentVariablesConfigurationProvider(null);
21+
22+
return (provider, () => provider.Load(new Hashtable(values.ToDictionary(e => e.Key, e => e.Value))));
23+
}
24+
25+
public override void Load_from_single_provider_with_differing_case_duplicates_throws()
26+
{
27+
AssertConfig(BuildConfigRoot(LoadThroughProvider(TestSection.DuplicatesDifferentCaseTestConfig)));
28+
}
29+
}
30+
}

src/Configuration/Config.EnvironmentVariables/test/EnvironmentVariablesTest.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4-
using System;
54
using System.Collections;
65
using Microsoft.Extensions.Configuration.Test;
76
using Xunit;

src/Configuration/Config.EnvironmentVariables/test/Microsoft.Extensions.Configuration.EnvironmentVariables.Tests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
55
</PropertyGroup>
66

7+
<ItemGroup>
8+
<ProjectReference Include="..\..\Config\test\Microsoft.Extensions.Configuration.Tests.csproj" />
9+
</ItemGroup>
10+
711
<ItemGroup>
812
<Reference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
913
<Reference Include="Microsoft.Extensions.Configuration.Test.Common" />
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Linq;
6+
using System.Text;
7+
using Microsoft.Extensions.Configuration.Test;
8+
9+
namespace Microsoft.Extensions.Configuration.Ini.Test
10+
{
11+
public class ConfigurationProviderIniTest : ConfigurationProviderTestBase
12+
{
13+
protected override (IConfigurationProvider Provider, Action Initializer) LoadThroughProvider(
14+
TestSection testConfig)
15+
{
16+
var iniBuilder = new StringBuilder();
17+
SectionToIni(iniBuilder, "", testConfig);
18+
19+
var provider = new IniConfigurationProvider(
20+
new IniConfigurationSource
21+
{
22+
Optional = true
23+
});
24+
25+
var ini = iniBuilder.ToString();
26+
return (provider, () => provider.Load(TestStreamHelpers.StringToStream(ini)));
27+
}
28+
29+
private void SectionToIni(StringBuilder iniBuilder, string sectionName, TestSection section)
30+
{
31+
foreach (var tuple in section.Values.SelectMany(e => e.Value.Expand(e.Key)))
32+
{
33+
iniBuilder.AppendLine($"{tuple.Key}={tuple.Value}");
34+
}
35+
36+
foreach (var tuple in section.Sections)
37+
{
38+
iniBuilder.AppendLine($"[{sectionName}{tuple.Key}]");
39+
SectionToIni(iniBuilder, tuple.Key + ":", tuple.Section);
40+
}
41+
}
42+
}
43+
}

src/Configuration/Config.Ini/test/Microsoft.Extensions.Configuration.Ini.Tests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
<TargetFrameworks>$(StandardTestTfms)</TargetFrameworks>
55
</PropertyGroup>
66

7+
<ItemGroup>
8+
<ProjectReference Include="..\..\Config\test\Microsoft.Extensions.Configuration.Tests.csproj" />
9+
</ItemGroup>
10+
711
<ItemGroup>
812
<Reference Include="Microsoft.Extensions.Configuration.Ini" />
913
<Reference Include="Microsoft.Extensions.Configuration.Test.Common" />
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Linq;
6+
using System.Text;
7+
using Microsoft.Extensions.Configuration.Json;
8+
using Microsoft.Extensions.Configuration.Test;
9+
10+
namespace Microsoft.Extensions.Configuration
11+
{
12+
public class ConfigurationProviderJsonTest : ConfigurationProviderTestBase
13+
{
14+
public override void Load_from_single_provider_with_duplicates_throws()
15+
{
16+
// JSON provider doesn't throw for duplicate values with the same case
17+
AssertConfig(BuildConfigRoot(LoadThroughProvider(TestSection.DuplicatesTestConfig)));
18+
}
19+
20+
protected override (IConfigurationProvider Provider, Action Initializer) LoadThroughProvider(TestSection testConfig)
21+
{
22+
var jsonBuilder = new StringBuilder();
23+
SectionToJson(jsonBuilder, testConfig);
24+
25+
var provider = new JsonConfigurationProvider(
26+
new JsonConfigurationSource
27+
{
28+
Optional = true
29+
});
30+
31+
var json = jsonBuilder.ToString();
32+
33+
return (provider, () => provider.Load(TestStreamHelpers.StringToStream(json)));
34+
}
35+
36+
private void SectionToJson(StringBuilder jsonBuilder, TestSection section)
37+
{
38+
jsonBuilder.AppendLine("{");
39+
40+
foreach (var tuple in section.Values)
41+
{
42+
jsonBuilder.AppendLine(tuple.Value.AsArray != null
43+
? $"'{tuple.Key}': [{string.Join(", ", tuple.Value.AsArray.Select(v => $"'{v}'"))}],"
44+
: $"'{tuple.Key}': '{tuple.Value.AsString}',");
45+
}
46+
47+
foreach (var tuple in section.Sections)
48+
{
49+
jsonBuilder.Append($"'{tuple.Key}': ");
50+
SectionToJson(jsonBuilder, tuple.Section);
51+
}
52+
53+
jsonBuilder.AppendLine("},");
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)