Skip to content

Commit 60c5246

Browse files
committed
fix integration tests to account for new AppHost setup
1 parent 2b1e311 commit 60c5246

File tree

8 files changed

+73
-35
lines changed

8 files changed

+73
-35
lines changed

aspire/AppHost.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Elastic.Documentation;
88
using Elastic.Documentation.Configuration;
99
using Microsoft.Extensions.Logging;
10+
using static Elastic.Documentation.Aspire.ResourceNames;
1011

1112
// ReSharper disable UnusedVariable
1213
// ReSharper disable RedundantAssignment
@@ -28,35 +29,34 @@
2829
return;
2930

3031
// ReSharper disable once RedundantLambdaParameterType
31-
async Task BuildAspireHost(bool startElasticsearch, bool cloneAlways, bool skipPrivateRepositories, Cancel ctx)
32+
async Task BuildAspireHost(bool startElasticsearch, bool assumeCloned, bool skipPrivateRepositories, Cancel ctx)
3233
{
3334
var builder = DistributedApplication.CreateBuilder(args);
35+
skipPrivateRepositories = globalArguments.Contains("--skip-private-repositories");
3436

3537
var llmUrl = builder.AddParameter("LlmGatewayUrl", secret: true);
3638
var llmServiceAccountPath = builder.AddParameter("LlmGatewayServiceAccountPath", secret: true);
3739

3840
var elasticsearchUrl = builder.AddParameter("DocumentationElasticUrl", secret: true);
3941
var elasticsearchApiKey = builder.AddParameter("DocumentationElasticApiKey", secret: true);
4042

41-
var cloneAll = builder.AddProject<Projects.docs_assembler>("assembler-clone");
42-
var cloneDirectory = Path.Combine(Paths.GetSolutionDirectory()!.FullName, ".artifacts", "checkouts", "current");
43-
cloneAll = cloneAlways || !Directory.Exists(cloneDirectory)
44-
? cloneAll.WithArgs(["repo", "clone-all", .. globalArguments])
45-
: cloneAll.WithArgs(["repo", "clone-all", "--help"]);
43+
var cloneAll = builder.AddProject<Projects.docs_assembler>(AssemblerClone);
44+
string[] cloneArgs = assumeCloned ? ["--assume-cloned"] : [];
45+
cloneAll = cloneAll.WithArgs(["repo", "clone-all", .. globalArguments, .. cloneArgs]);
4646

47-
var buildAll = builder.AddProject<Projects.docs_assembler>("assembler-build")
47+
var buildAll = builder.AddProject<Projects.docs_assembler>(AssemblerBuild)
4848
.WithArgs(["repo", "build-all", .. globalArguments])
4949
.WaitForCompletion(cloneAll)
5050
.WithParentRelationship(cloneAll);
5151

52-
var elasticsearchLocal = builder.AddElasticsearch("elasticsearch-local")
52+
var elasticsearchLocal = builder.AddElasticsearch(ElasticsearchLocal)
5353
.WithEnvironment("LICENSE", "trial");
5454
if (!startElasticsearch)
5555
elasticsearchLocal = elasticsearchLocal.WithExplicitStart();
5656

57-
var elasticsearchRemote = builder.AddExternalService("elasticsearch-remote", elasticsearchUrl);
57+
var elasticsearchRemote = builder.AddExternalService(ElasticsearchRemote, elasticsearchUrl);
5858

59-
var api = builder.AddProject<Projects.Elastic_Documentation_Api_Lambda>("api-lambda")
59+
var api = builder.AddProject<Projects.Elastic_Documentation_Api_Lambda>(LambdaApi)
6060
.WithArgs(globalArguments)
6161
.WithEnvironment("ENVIRONMENT", "dev")
6262
.WithEnvironment("LLM_GATEWAY_FUNCTION_URL", llmUrl)
@@ -74,7 +74,7 @@ async Task BuildAspireHost(bool startElasticsearch, bool cloneAlways, bool skipP
7474
.WithEnvironment("DOCUMENTATION_ELASTIC_URL", elasticsearchUrl)
7575
.WithEnvironment("DOCUMENTATION_ELASTIC_APIKEY", elasticsearchApiKey);
7676

77-
var indexElasticsearch = builder.AddProject<Projects.docs_assembler>("elasticsearch-indexer-plain")
77+
var indexElasticsearch = builder.AddProject<Projects.docs_assembler>(ElasticsearchIndexerPlain)
7878
.WithArgs(["repo", "build-all", "--exporters", "elasticsearch", .. globalArguments])
7979
.WithExplicitStart()
8080
.WaitForCompletion(cloneAll);
@@ -91,7 +91,7 @@ async Task BuildAspireHost(bool startElasticsearch, bool cloneAlways, bool skipP
9191
.WithEnvironment("DOCUMENTATION_ELASTIC_APIKEY", elasticsearchApiKey)
9292
.WithParentRelationship(elasticsearchRemote);
9393

94-
var indexElasticsearchSemantic = builder.AddProject<Projects.docs_assembler>("elasticsearch-indexer-semantic")
94+
var indexElasticsearchSemantic = builder.AddProject<Projects.docs_assembler>(ElasticsearchIndexerSemantic)
9595
.WithArgs(["repo", "build-all", "--exporters", "semantic", .. globalArguments])
9696
.WithEnvironment("DOCUMENTATION_ELASTIC_URL", elasticsearchLocal.GetEndpoint("http"))
9797
.WithEnvironment(context => context.EnvironmentVariables["DOCUMENTATION_ELASTIC_PASSWORD"] = elasticsearchLocal.Resource.PasswordParameter)
@@ -110,7 +110,7 @@ async Task BuildAspireHost(bool startElasticsearch, bool cloneAlways, bool skipP
110110
.WithEnvironment("DOCUMENTATION_ELASTIC_APIKEY", elasticsearchApiKey)
111111
.WithParentRelationship(elasticsearchRemote);
112112

113-
var serveStatic = builder.AddProject<Projects.docs_builder>("assembler-serve")
113+
var serveStatic = builder.AddProject<Projects.docs_builder>(AssemblerServe)
114114
.WithEnvironment("LLM_GATEWAY_FUNCTION_URL", llmUrl)
115115
.WithEnvironment("LLM_GATEWAY_SERVICE_ACCOUNT_KEY_PATH", llmServiceAccountPath)
116116
.WithHttpEndpoint(port: 4000, isProxied: false)

aspire/README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,21 @@ We do not use Aspire to generate production deployment scripts since [this is no
1111

1212
## Run all services locally
1313

14+
You may need to install the Aspire workload first. We also recommend installing the aspire plugin
15+
16+
* [For Rider](https://plugins.jetbrains.com/plugin/23289--net-aspire)
17+
18+
```bash
19+
sudo dotnet workload install aspire
20+
```
21+
22+
Aspire is just another CLI program so can be run like all the other tools
23+
1424
```bash
1525
dotnet run --project aspire
1626
```
1727

18-
Will automatically:
28+
This will automatically:
1929

2030
* clone all repositories according to `config/assembler.yml` using `docs-assembler repo clone-all`
2131
* do a full site build of all repositories using `docs-assembler repo build-all`
@@ -58,7 +68,6 @@ Furthermore, it makes the following indexers available in the Aspire UI
5868

5969
These have to be run manually and can be run multiple times.
6070

61-
6271
## User secrets
6372

6473
We use dotnet user secrets to provide parameters to aspire. These are all optional but needed if you want

aspire/ResourceNames.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
namespace Elastic.Documentation.Aspire;
6+
7+
public static class ResourceNames
8+
{
9+
public const string AssemblerClone = "assembler-clone";
10+
public const string AssemblerBuild = "assembler-build";
11+
public const string AssemblerServe = "assembler-serve";
12+
public const string ElasticsearchLocal = "elasticsearch-local";
13+
public const string ElasticsearchRemote = "elasticsearch-remote";
14+
public const string LambdaApi = "lambda-api";
15+
public const string ElasticsearchIndexerPlain = "elasticsearch-indexer-plain";
16+
public const string ElasticsearchIndexerSemantic = "elasticsearch-indexer-semantic";
17+
}

aspire/aspire.csproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
</ItemGroup>
2121

2222
<ItemGroup>
23-
<ProjectReference Include="$(SolutionRoot)\src\api\Elastic.Documentation.Api.Lambda\Elastic.Documentation.Api.Lambda.csproj" />
24-
<ProjectReference Include="$(SolutionRoot)\src\tooling\docs-assembler\docs-assembler.csproj"/>
25-
<ProjectReference Include="$(SolutionRoot)\src\tooling\docs-builder\docs-builder.csproj"/>
23+
<ProjectReference Include="..\src\api\Elastic.Documentation.Api.Lambda\Elastic.Documentation.Api.Lambda.csproj" />
24+
<ProjectReference Include="..\src\tooling\docs-assembler\docs-assembler.csproj"/>
25+
<ProjectReference Include="..\src\tooling\docs-builder\docs-builder.csproj"/>
2626

27-
<ProjectReference Include="$(SolutionRoot)\src\tooling\Elastic.Documentation.Tooling\Elastic.Documentation.Tooling.csproj" IsAspireProjectResource="false" />
28-
<ProjectReference Include="$(SolutionRoot)\src\Elastic.Documentation\Elastic.Documentation.csproj" IsAspireProjectResource="false" />
27+
<ProjectReference Include="..\src\tooling\Elastic.Documentation.Tooling\Elastic.Documentation.Tooling.csproj" IsAspireProjectResource="false" />
28+
<ProjectReference Include="..\src\Elastic.Documentation\Elastic.Documentation.csproj" IsAspireProjectResource="false" />
2929
</ItemGroup>
3030

3131
</Project>

src/Elastic.Documentation/GlobalCommandLine.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@ public static void Process(ref string[] args, ref LogLevel defaultLogLevel, out
2121
i++;
2222
}
2323
else if (args[i] == "--skip-private-repositories")
24-
{
2524
skipPrivateRepositories = true;
26-
i++;
27-
}
2825
else
2926
newArgs.Add(args[i]);
3027
}

src/tooling/docs-assembler/Cli/RepositoryCommands.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,14 @@ public async Task<int> CloneConfigurationFolder(string? gitRef = null, Cancel ct
7878
/// <param name="strict"> Treat warnings as errors and fail the build on warnings</param>
7979
/// <param name="environment"> The environment to build</param>
8080
/// <param name="fetchLatest"> If true, fetch the latest commit of the branch instead of the link registry entry ref</param>
81+
/// <param name="assumeCloned"> If true, assume the repository folder already exists on disk assume it's cloned already, primarily used for testing</param>
8182
/// <param name="ctx"></param>
8283
[Command("clone-all")]
8384
public async Task<int> CloneAll(
8485
bool? strict = null,
8586
string? environment = null,
8687
bool? fetchLatest = null,
88+
bool? assumeCloned = null,
8789
Cancel ctx = default
8890
)
8991
{
@@ -97,7 +99,7 @@ public async Task<int> CloneAll(
9799
var assembleContext = new AssembleContext(assemblyConfiguration, configurationContext, environment, collector, fs, fs, null, null);
98100
var cloner = new AssemblerRepositorySourcer(logFactory, assembleContext);
99101

100-
_ = await cloner.CloneAll(fetchLatest ?? false, ctx);
102+
_ = await cloner.CloneAll(fetchLatest ?? false, assumeCloned ?? false, ctx);
101103

102104
await collector.StopAsync(ctx);
103105

src/tooling/docs-assembler/Sourcing/RepositorySourcesFetcher.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public CheckoutResult GetAll()
5757
};
5858
}
5959

60-
public async Task<CheckoutResult> CloneAll(bool fetchLatest, Cancel ctx = default)
60+
public async Task<CheckoutResult> CloneAll(bool fetchLatest, bool assumeCloned, Cancel ctx = default)
6161
{
6262
_logger.LogInformation("Cloning all repositories for environment {EnvironmentName} using '{ContentSourceStrategy}' content sourcing strategy",
6363
PublishEnvironment.Name,
@@ -93,7 +93,9 @@ await Task.Run(() =>
9393
}
9494
gitRef = entryInfo.GitReference;
9595
}
96-
checkouts.Add(RepositorySourcer.CloneRef(repo.Value, gitRef, fetchLatest));
96+
97+
var cloneInformation = RepositorySourcer.CloneRef(repo.Value, gitRef, fetchLatest, assumeCloned: assumeCloned);
98+
checkouts.Add(cloneInformation);
9799
}, c);
98100
}).ConfigureAwait(false);
99101
await context.WriteFileSystem.File.WriteAllTextAsync(
@@ -125,13 +127,24 @@ public class RepositorySourcer(ILoggerFactory logFactory, IDirectoryInfo checkou
125127
// </summary>
126128
// <param name="repository">The repository to clone.</param>
127129
// <param name="gitRef">The git reference to check out. Branch, commit or tag</param>
128-
public Checkout CloneRef(Repository repository, string gitRef, bool pull = false, int attempt = 1, bool appendRepositoryName = true)
130+
public Checkout CloneRef(Repository repository, string gitRef, bool pull = false, int attempt = 1, bool appendRepositoryName = true, bool assumeCloned = false)
129131
{
130132
var checkoutFolder =
131133
appendRepositoryName
132134
? readFileSystem.DirectoryInfo.New(Path.Combine(checkoutDirectory.FullName, repository.Name))
133135
: checkoutDirectory;
134136
IGitRepository git = new SingleCommitOptimizedGitRepository(collector, checkoutFolder);
137+
if (assumeCloned && checkoutFolder.Exists)
138+
{
139+
_logger.LogInformation("{RepositoryName}: Assuming {RepositoryName}@{Commit} is already checked out to {CheckoutFolder}", repository.Name, repository.Name, gitRef, checkoutFolder.FullName);
140+
return new Checkout
141+
{
142+
Directory = checkoutFolder,
143+
HeadReference = git.GetCurrentCommit(),
144+
Repository = repository,
145+
};
146+
}
147+
135148
if (attempt > 3)
136149
{
137150
collector.EmitError("", $"Failed to clone repository {repository.Name}@{gitRef} after 3 attempts");

tests-integration/Elastic.Assembler.IntegrationTests/AssembleFixture.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using InMemLogger;
1010
using Microsoft.Extensions.DependencyInjection;
1111
using Microsoft.Extensions.Logging;
12+
using static Elastic.Documentation.Aspire.ResourceNames;
1213

1314
[assembly: CaptureConsole, AssemblyFixture(typeof(Elastic.Assembler.IntegrationTests.DocumentationFixture))]
1415

@@ -24,22 +25,23 @@ public class DocumentationFixture : IAsyncLifetime
2425
public async ValueTask InitializeAsync()
2526
{
2627
var builder = await DistributedApplicationTestingBuilder.CreateAsync<Projects.aspire>(
27-
["--skip-private-repositories"],
28+
["--skip-private-repositories", "--assume-cloned"],
2829
(options, settings) =>
2930
{
3031
options.DisableDashboard = true;
3132
options.AllowUnsecuredTransport = true;
33+
options.EnableResourceLogging = true;
3234
}
3335
);
3436
_ = builder.Services.AddElasticDocumentationLogging(LogLevel.Information);
3537
_ = builder.Services.AddLogging(c => c.AddXUnit());
3638
_ = builder.Services.AddLogging(c => c.AddInMemory());
37-
// TODO expose this as secrets for now not needed integration tests
38-
_ = builder.AddParameter("LlmGatewayUrl", "");
39-
_ = builder.AddParameter("LlmGatewayServiceAccountPath", "");
4039
DistributedApplication = await builder.BuildAsync();
4140
InMemoryLogger = DistributedApplication.Services.GetService<InMemoryLogger>()!;
42-
await DistributedApplication.StartAsync();
41+
_ = DistributedApplication.StartAsync().WaitAsync(TimeSpan.FromMinutes(5), TestContext.Current.CancellationToken);
42+
_ = await DistributedApplication.ResourceNotifications
43+
.WaitForResourceHealthyAsync(AssemblerServe, cancellationToken: TestContext.Current.CancellationToken)
44+
.WaitAsync(TimeSpan.FromMinutes(5), TestContext.Current.CancellationToken);
4345
}
4446

4547
/// <inheritdoc />
@@ -56,9 +58,7 @@ public class ServeStaticTests(DocumentationFixture fixture, ITestOutputHelper ou
5658
[Fact]
5759
public async Task AssertRequestToRootReturnsData()
5860
{
59-
_ = await fixture.DistributedApplication.ResourceNotifications
60-
.WaitForResourceHealthyAsync("DocsBuilderServeStatic", cancellationToken: TestContext.Current.CancellationToken);
61-
var client = fixture.DistributedApplication.CreateHttpClient("DocsBuilderServeStatic", "http");
61+
var client = fixture.DistributedApplication.CreateHttpClient(AssemblerServe, "http");
6262
var root = await client.GetStringAsync("/", TestContext.Current.CancellationToken);
6363
_ = root.Should().NotBeNullOrEmpty();
6464
}

0 commit comments

Comments
 (0)