Skip to content
This repository was archived by the owner on Sep 10, 2024. It is now read-only.

Commit 1592d10

Browse files
authored
test: restructure and rename integration configuration tokens (#110)
* test: restructure and rename integration configuration tokens * pr-fix: use the correct topic connection string for invalidating az key vault secrets * pr-fix: use correct topic connection string * pr-fix: az key vault restructure appsettings * pr-fix: az key vault restructure appsettings * pr-fix: moved to az keyvault connection string * pr-fix: increase timeout bc it would otherwise succeed
1 parent afead6f commit 1592d10

19 files changed

+498
-722
lines changed

src/Arcus.BackgroundJobs.Tests.Integration/AzureActiveDirectory/ClientSecretExpirationJobTests.cs

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
using Arcus.BackgroundJobs.Tests.Integration.Hosting;
99
using Arcus.EventGrid;
1010
using Arcus.EventGrid.Contracts;
11-
using Arcus.EventGrid.Publishing;
12-
using Arcus.EventGrid.Publishing.Interfaces;
1311
using Arcus.Testing.Logging;
1412
using CloudNative.CloudEvents;
1513
using Microsoft.Extensions.DependencyInjection;
@@ -39,15 +37,17 @@ public async Task CheckExpiredOrAboutToExpireClientSecretsInAzureActiveDirectory
3937
{
4038
// Arrange
4139
int expirationThreshold = 14;
42-
IEventGridPublisher eventGridPublisher = CreateEventGridPublisher();
4340
var options = new WorkerOptions();
4441
options.ConfigureLogging(_logger)
45-
.AddSingleton<IEventGridPublisher>(eventGridPublisher)
46-
.AddClientSecretExpirationJob(opt =>
42+
.ConfigureServices(services =>
4743
{
48-
opt.RunImmediately = true;
49-
opt.ExpirationThreshold = expirationThreshold;
50-
opt.EventUri = new Uri("https://github.com/arcus-azure/arcus.backgroundjobs");
44+
services.AddEventGridPublisher(_config);
45+
services.AddClientSecretExpirationJob(opt =>
46+
{
47+
opt.RunImmediately = true;
48+
opt.ExpirationThreshold = expirationThreshold;
49+
opt.EventUri = new Uri("https://github.com/arcus-azure/arcus.backgroundjobs");
50+
});
5151
});
5252

5353
AzureActiveDirectoryConfig activeDirectoryConfig = _config.GetActiveDirectoryConfig();
@@ -82,19 +82,5 @@ public async Task CheckExpiredOrAboutToExpireClientSecretsInAzureActiveDirectory
8282
}
8383
}
8484
}
85-
86-
private IEventGridPublisher CreateEventGridPublisher()
87-
{
88-
string topicEndpoint = _config.GetTestInfraEventGridTopicUri();
89-
string topicEndpointSecret = _config.GetTestInfraEventGridAuthKey();
90-
91-
IEventGridPublisher eventGridPublisher =
92-
EventGridPublisherBuilder
93-
.ForTopic(topicEndpoint)
94-
.UsingAuthenticationKey(topicEndpointSecret)
95-
.Build();
96-
97-
return eventGridPublisher;
98-
}
9985
}
10086
}

src/Arcus.BackgroundJobs.Tests.Integration/CloudEvents/CloudEventBackgroundJobTests.cs

Lines changed: 75 additions & 75 deletions
Large diffs are not rendered by default.

src/Arcus.BackgroundJobs.Tests.Integration/CloudEvents/Fixture/TestServiceBusEventProducer.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ private TestServiceBusEventProducer(string connectionString)
2323
/// <summary>
2424
/// Creates an <see cref="TestServiceBusEventProducer"/> instance which sends events to an Azure Service Bus.
2525
/// </summary>
26-
/// <param name="configurationKey">The Azure Service Bus entity-scoped connection string.</param>
26+
/// <param name="configurationKey">The configuration key towards the Azure Service Bus entity-scoped connection string.</param>
2727
/// <param name="configuration">The test configuration used in this test suite.</param>
2828
/// <exception cref="ArgumentException">Thrown when the <paramref name="configurationKey" /> is blank.</exception>
2929
/// <exception cref="ArgumentNullException">Thrown when the <paramref name="configuration"/> is <c>null</c>.</exception>
@@ -33,7 +33,20 @@ public static TestServiceBusEventProducer Create(string configurationKey, TestCo
3333
Guard.NotNull(configuration, nameof(configuration), "Requires a test configuration to retrieve the Azure Service Bus entity-scoped connection string");
3434

3535
var connectionString = configuration.GetValue<string>(configurationKey);
36-
return new TestServiceBusEventProducer(connectionString);
36+
TestServiceBusEventProducer producer = Create(connectionString);
37+
38+
return producer;
39+
}
40+
41+
/// <summary>
42+
/// Creates an <see cref="TestServiceBusEventProducer"/> instance which sends events to an Azure Service Bus.
43+
/// </summary>
44+
/// <param name="entityScopedConnectionString">The Azure Service Bus entity-scoped connection string.</param>
45+
/// <exception cref="ArgumentException">Thrown when the <paramref name="entityScopedConnectionString" /> is blank.</exception>
46+
public static TestServiceBusEventProducer Create(string entityScopedConnectionString)
47+
{
48+
Guard.NotNullOrWhitespace(entityScopedConnectionString, nameof(entityScopedConnectionString), "Requires a non-blank Azure Service Bus entity-scoped connection string");
49+
return new TestServiceBusEventProducer(entityScopedConnectionString);
3750
}
3851

3952
/// <summary>

src/Arcus.BackgroundJobs.Tests.Integration/Databricks/DatabricksJobMetricsJobTests.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@
33
using System.Linq;
44
using System.Threading.Tasks;
55
using Arcus.BackgroundJobs.Tests.Integration.Hosting;
6-
using Arcus.Security.Core;
76
using Arcus.Testing.Logging;
87
using Microsoft.Azure.Databricks.Client;
98
using Microsoft.Extensions.Configuration;
109
using Microsoft.Extensions.DependencyInjection;
1110
using Microsoft.Extensions.Hosting;
1211
using Microsoft.Extensions.Logging;
13-
using Microsoft.Graph;
14-
using Moq;
1512
using Polly;
1613
using Xunit;
1714
using Xunit.Abstractions;
@@ -45,9 +42,12 @@ public async Task FinishedDatabricksJobRun_GetsNoticedByRepeatedlyDatabricksJob_
4542
var options = new WorkerOptions();
4643
options.ConfigureLogging(spyLogger);
4744
options.ConfigureLogging(_logger);
48-
options.AddSecretStore(stores => stores.AddInMemory(tokenSecretKey, token));
49-
options.AddDatabricksJobMetricsJob(baseUrl, tokenSecretKey, opt => opt.IntervalInMinutes = 1);
50-
45+
options.ConfigureServices(services =>
46+
{
47+
services.AddSecretStore(stores => stores.AddInMemory(tokenSecretKey, token));
48+
services.AddDatabricksJobMetricsJob(baseUrl, tokenSecretKey, opt => opt.IntervalInMinutes = 1);
49+
});
50+
5151
using (var client = DatabricksClient.CreateClient(baseUrl, token))
5252
{
5353
JobSettings settings = CreateEmptyJobSettings();
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using GuardNet;
3+
4+
namespace Arcus.BackgroundJobs.Tests.Integration.Fixture
5+
{
6+
/// <summary>
7+
/// Represents a location in Azure where the test resources are located.
8+
/// </summary>
9+
public class AzureEnvironment
10+
{
11+
/// <summary>
12+
/// Initializes a new instance of the <see cref="AzureEnvironment"/> class.
13+
/// </summary>
14+
/// <param name="subscriptionId">The unique identifier for the global subscription that is linked to the test Azure resources.</param>
15+
/// <param name="tenantId">The tenant identifier within the Azure subscription where the test Azure resources are located.</param>
16+
/// <param name="resourceGroupName">The name of the Azure resource group inside the Azure tenant where the test Azure resources are located.</param>
17+
/// <exception cref="ArgumentException">
18+
/// Thrown when the <paramref name="subscriptionId"/>, <paramref name="tenantId"/>, or the <paramref name="resourceGroupName"/> is blank.
19+
/// </exception>
20+
public AzureEnvironment(string subscriptionId, string tenantId, string resourceGroupName)
21+
{
22+
Guard.NotNullOrWhitespace(subscriptionId, nameof(subscriptionId), "Requires an Azure subscription ID to create an Azure environment instance");
23+
Guard.NotNullOrWhitespace(tenantId, nameof(tenantId), "Requires an Azure tenant ID to create an Azure environment instance");
24+
Guard.NotNullOrWhitespace(resourceGroupName, nameof(resourceGroupName), "Requires an Azure resource group name to create an Azure environment instance");
25+
26+
SubscriptionId = subscriptionId;
27+
TenantId = tenantId;
28+
ResourceGroupName = resourceGroupName;
29+
}
30+
31+
/// <summary>
32+
/// Gets the unique identifier for the global subscription that is linked to the test Azure resources.
33+
/// </summary>
34+
public string SubscriptionId { get; }
35+
36+
/// <summary>
37+
/// Gets the tenant identifier within the Azure subscription where the test Azure resources are located.
38+
/// </summary>
39+
public string TenantId { get; }
40+
41+
/// <summary>
42+
/// Gets the name of the Azure resource group inside the Azure tenant where the test Azure resources are located.
43+
/// </summary>
44+
public string ResourceGroupName { get; }
45+
}
46+
}

src/Arcus.BackgroundJobs.Tests.Integration/Fixture/ServiceBus/ServiceBusConfiguration.cs

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Threading.Tasks;
4+
using Arcus.BackgroundJobs.Tests.Integration.Hosting;
35
using Arcus.BackgroundJobs.Tests.Integration.KeyVault.Fixture;
46
using GuardNet;
57
using Microsoft.Azure.Management.ServiceBus;
68
using Microsoft.Azure.Management.ServiceBus.Models;
79
using Microsoft.Extensions.Logging;
10+
using Microsoft.Extensions.Logging.Abstractions;
811
using Microsoft.IdentityModel.Clients.ActiveDirectory;
912
using Microsoft.Rest;
1013

@@ -15,38 +18,41 @@ namespace Arcus.BackgroundJobs.Tests.Integration.Fixture.ServiceBus
1518
/// </summary>
1619
public class ServiceBusConfiguration
1720
{
18-
private readonly KeyRotationConfig _configuration;
21+
private readonly AzureEnvironment _environment;
22+
private readonly ServicePrincipal _servicePrincipal;
23+
private readonly KeyRotationConfig _rotationConfig;
1924
private readonly ILogger _logger;
2025

21-
/// <summary>
22-
/// Initializes a new instance of the <see cref="ServiceBusConfiguration"/> class.
23-
/// </summary>
24-
/// <param name="configuration">The configuration instance to provide the necessary information during authentication with the correct Azure Service Bus instance.</param>
25-
/// <param name="logger">The instance to log diagnostic messages during the interaction with the Azure Service Bus instance.</param>
26-
/// <exception cref="ArgumentNullException">Thrown when the <paramref name="configuration"/> or the <paramref name="logger"/> is <c>null</c>.</exception>
27-
public ServiceBusConfiguration(KeyRotationConfig configuration, ILogger logger)
26+
private ServiceBusConfiguration(
27+
AzureEnvironment environment,
28+
ServicePrincipal servicePrincipal,
29+
KeyRotationConfig rotationConfig,
30+
ILogger logger)
2831
{
29-
Guard.NotNull(configuration, nameof(configuration));
30-
Guard.NotNull(logger, nameof(logger));
32+
Guard.NotNull(rotationConfig, nameof(rotationConfig));
3133

32-
_configuration = configuration;
33-
_logger = logger;
34+
_environment = environment;
35+
_servicePrincipal = servicePrincipal;
36+
_rotationConfig = rotationConfig;
37+
_logger = logger ?? NullLogger.Instance;
3438
}
3539

3640
/// <summary>
37-
/// Gets the connection string keys for the Azure Service Bus Topic tested in the integration test suite.
41+
/// Creates an <see cref="ServiceBusConfiguration"/> instance based on the test configuration values of the current test run.
3842
/// </summary>
39-
public async Task<AccessKeys> GetConnectionStringKeysForTopicAsync()
43+
/// <param name="config">The current integration test configuration.</param>
44+
/// <param name="logger">The logger instance to write diagnostic trace messages during the interaction with Azure Service Bus.</param>
45+
/// <exception cref="ArgumentNullException">Thrown when the <paramref name="config"/> is <c>null</c>.</exception>
46+
/// <exception cref="KeyNotFoundException">Thrown when one or more configuration values cannot be found in the given test <paramref name="config"/> instance.</exception>
47+
public static ServiceBusConfiguration CreateFrom(TestConfig config, ILogger logger)
4048
{
41-
using IServiceBusManagementClient client = await CreateServiceManagementClientAsync();
49+
Guard.NotNull(config, nameof(config), "Requires a test configuration instance to retrieve the details to interact with Azure Service Bus");
4250

43-
AccessKeys accessKeys = await client.Topics.ListKeysAsync(
44-
_configuration.ServiceBusNamespace.ResourceGroup,
45-
_configuration.ServiceBusNamespace.Namespace,
46-
_configuration.ServiceBusNamespace.TopicName,
47-
_configuration.ServiceBusNamespace.AuthorizationRuleName);
51+
AzureEnvironment environment = config.GetAzureEnvironment();
52+
ServicePrincipal servicePrincipal = config.GetServicePrincipal();
53+
KeyRotationConfig rotationConfig = config.GetKeyRotationConfig();
4854

49-
return accessKeys;
55+
return new ServiceBusConfiguration(environment, servicePrincipal, rotationConfig, logger);
5056
}
5157

5258
/// <summary>
@@ -56,66 +62,62 @@ public async Task<AccessKeys> GetConnectionStringKeysForTopicAsync()
5662
/// <returns>
5763
/// The new connection string according to the <paramref name="keyType"/>.
5864
/// </returns>
59-
/// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="keyType"/> is not within the bounds of the enumration.</exception>
65+
/// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="keyType"/> is not within the bounds of the enumeration.</exception>
6066
public async Task<string> RotateConnectionStringKeysForQueueAsync(KeyType keyType)
6167
{
6268
Guard.For<ArgumentOutOfRangeException>(
6369
() => !Enum.IsDefined(typeof(KeyType), keyType),
6470
$"Requires a KeyType that is either '{nameof(KeyType.PrimaryKey)}' or '{nameof(KeyType.SecondaryKey)}'");
6571

6672
var parameters = new RegenerateAccessKeyParameters(keyType);
67-
string queueName = _configuration.ServiceBusNamespace.QueueName;
73+
string queueName = _rotationConfig.ServiceBusNamespace.QueueName;
6874
const ServiceBusEntityType entity = ServiceBusEntityType.Queue;
6975

7076
try
7177
{
72-
using IServiceBusManagementClient client = await CreateServiceManagementClientAsync();
73-
74-
_logger.LogTrace(
75-
"Start rotating {KeyType} connection string of Azure Service Bus {EntityType} '{EntityName}'...",
76-
keyType, entity, queueName);
77-
78-
AccessKeys accessKeys = await client.Queues.RegenerateKeysAsync(
79-
_configuration.ServiceBusNamespace.ResourceGroup,
80-
_configuration.ServiceBusNamespace.Namespace,
81-
queueName,
82-
_configuration.ServiceBusNamespace.AuthorizationRuleName,
83-
parameters);
84-
85-
_logger.LogInformation(
86-
"Rotated {KeyType} connection string of Azure Service Bus {EntityType} '{EntityName}'",
87-
keyType, entity, queueName);
88-
89-
switch (keyType)
78+
using (IServiceBusManagementClient client = await CreateServiceManagementClientAsync())
9079
{
91-
case KeyType.PrimaryKey: return accessKeys.PrimaryConnectionString;
92-
case KeyType.SecondaryKey: return accessKeys.SecondaryConnectionString;
93-
default:
94-
throw new ArgumentOutOfRangeException(nameof(keyType), keyType, "Unknown key type");
80+
_logger.LogTrace("Start rotating {KeyType} connection string of Azure Service Bus {EntityType} '{EntityName}'...", keyType, entity, queueName);
81+
82+
AccessKeys accessKeys = await client.Queues.RegenerateKeysAsync(
83+
_environment.ResourceGroupName,
84+
_rotationConfig.ServiceBusNamespace.NamespaceName,
85+
queueName,
86+
_rotationConfig.ServiceBusNamespace.AuthorizationRuleName,
87+
parameters);
88+
89+
_logger.LogInformation("Rotated {KeyType} connection string of Azure Service Bus {EntityType} '{EntityName}'", keyType, entity, queueName);
90+
91+
switch (keyType)
92+
{
93+
case KeyType.PrimaryKey: return accessKeys.PrimaryConnectionString;
94+
case KeyType.SecondaryKey: return accessKeys.SecondaryConnectionString;
95+
default:
96+
throw new ArgumentOutOfRangeException(nameof(keyType), keyType, "Unknown key type");
97+
}
9598
}
9699
}
97100
catch (Exception exception)
98101
{
99-
_logger.LogError(
100-
exception, "Failed to rotate the {KeyType} connection string of the Azure Service Bus {EntityType} '{EntityName}'", keyType, entity, queueName);
102+
_logger.LogError(exception, "Failed to rotate the {KeyType} connection string of the Azure Service Bus {EntityType} '{EntityName}'", keyType, entity, queueName);
101103

102104
throw;
103105
}
104106
}
105107

106108
private async Task<IServiceBusManagementClient> CreateServiceManagementClientAsync()
107109
{
108-
string tenantId = _configuration.ServiceBusNamespace.TenantId;
110+
string tenantId = _environment.TenantId;
109111
var context = new AuthenticationContext($"https://login.microsoftonline.com/{tenantId}");
110112

111-
ClientCredential clientCredentials = _configuration.ServicePrincipal.CreateCredentials();
113+
ClientCredential clientCredentials = _servicePrincipal.CreateCredentials();
112114
AuthenticationResult result =
113115
await context.AcquireTokenAsync(
114116
"https://management.azure.com/",
115117
clientCredentials);
116118

117119
var tokenCredentials = new TokenCredentials(result.AccessToken);
118-
string subscriptionId = _configuration.ServiceBusNamespace.SubscriptionId;
120+
string subscriptionId = _environment.SubscriptionId;
119121

120122
var client = new ServiceBusManagementClient(tokenCredentials) { SubscriptionId = subscriptionId };
121123
return client;

0 commit comments

Comments
 (0)