diff --git a/src/Hosting/TestHost/src/ITestServer.cs b/src/Hosting/TestHost/src/ITestServer.cs
new file mode 100644
index 000000000000..6940074601a7
--- /dev/null
+++ b/src/Hosting/TestHost/src/ITestServer.cs
@@ -0,0 +1,31 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Net.Http;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Hosting.Server;
+
+namespace Microsoft.AspNetCore.TestHost;
+
+///
+/// A contract for a test server implementation.
+///
+public interface ITestServer : IServer
+{
+ ///
+ /// Gets the web host associated with the test server.
+ ///
+ IWebHost Host { get; }
+
+ ///
+ /// Creates a new for processing HTTP requests against the test server.
+ ///
+ /// A new instance.
+ HttpMessageHandler CreateHandler();
+
+ ///
+ /// Creates a new for processing HTTP requests against the test server.
+ ///
+ ///
+ HttpClient CreateClient();
+}
diff --git a/src/Hosting/TestHost/src/PublicAPI.Unshipped.txt b/src/Hosting/TestHost/src/PublicAPI.Unshipped.txt
index 7dc5c58110bf..96a756e2b17a 100644
--- a/src/Hosting/TestHost/src/PublicAPI.Unshipped.txt
+++ b/src/Hosting/TestHost/src/PublicAPI.Unshipped.txt
@@ -1 +1,5 @@
#nullable enable
+Microsoft.AspNetCore.TestHost.ITestServer
+Microsoft.AspNetCore.TestHost.ITestServer.CreateClient() -> System.Net.Http.HttpClient!
+Microsoft.AspNetCore.TestHost.ITestServer.CreateHandler() -> System.Net.Http.HttpMessageHandler!
+Microsoft.AspNetCore.TestHost.ITestServer.Host.get -> Microsoft.AspNetCore.Hosting.IWebHost!
diff --git a/src/Hosting/TestHost/src/TestServer.cs b/src/Hosting/TestHost/src/TestServer.cs
index 1c9c295406ee..72550e58c6a4 100644
--- a/src/Hosting/TestHost/src/TestServer.cs
+++ b/src/Hosting/TestHost/src/TestServer.cs
@@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.TestHost;
///
/// An implementation for executing tests.
///
-public class TestServer : IServer
+public class TestServer : ITestServer
{
private readonly IWebHost? _hostInstance;
private bool _disposed;
diff --git a/src/Identity/test/Identity.FunctionalTests/Infrastructure/ServerFactory.cs b/src/Identity/test/Identity.FunctionalTests/Infrastructure/ServerFactory.cs
index 91aef38de10b..4d04c04dbcbc 100644
--- a/src/Identity/test/Identity.FunctionalTests/Infrastructure/ServerFactory.cs
+++ b/src/Identity/test/Identity.FunctionalTests/Infrastructure/ServerFactory.cs
@@ -63,9 +63,9 @@ protected override IHost CreateHost(IHostBuilder builder)
return result;
}
- protected override TestServer CreateServer(IWebHostBuilder builder)
+ protected override ITestServer CreateTestServer(IWebHostBuilder builder)
{
- var result = base.CreateServer(builder);
+ var result = base.CreateTestServer(builder);
EnsureDatabaseCreated(result.Host.Services);
return result;
}
diff --git a/src/Mvc/Mvc.Testing.Tasks/src/GenerateMvcTestManifestTask.cs b/src/Mvc/Mvc.Testing.Tasks/src/GenerateMvcTestManifestTask.cs
index d5adc6fae699..8b8df20de470 100644
--- a/src/Mvc/Mvc.Testing.Tasks/src/GenerateMvcTestManifestTask.cs
+++ b/src/Mvc/Mvc.Testing.Tasks/src/GenerateMvcTestManifestTask.cs
@@ -1,8 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Runtime.Serialization.Json;
using System.Text;
using Microsoft.Build.Framework;
@@ -33,11 +35,14 @@ public override bool Execute()
{
using var fileStream = File.Create(ManifestPath);
var output = new Dictionary();
+ var manifestDirectory = Path.GetDirectoryName(ManifestPath);
+
foreach (var project in Projects)
{
var contentRoot = project.GetMetadata("ContentRoot");
var assemblyName = project.GetMetadata("Identity");
- output[assemblyName] = contentRoot;
+ var relativeContentRoot = GetRelativePath(manifestDirectory, contentRoot);
+ output[assemblyName] = relativeContentRoot;
}
var serializer = new DataContractJsonSerializer(typeof(Dictionary), new DataContractJsonSerializerSettings
@@ -49,4 +54,44 @@ public override bool Execute()
return !Log.HasLoggedErrors;
}
+
+ private static string GetRelativePath(string? relativeTo, string path)
+ {
+ if (string.IsNullOrEmpty(relativeTo))
+ {
+ return path;
+ }
+
+ // Ensure the paths are absolute
+ string absoluteRelativeTo = Path.GetFullPath(relativeTo);
+ string absolutePath = Path.GetFullPath(path);
+
+ // Split the paths into their components
+ string[] relativeToParts = absoluteRelativeTo.TrimEnd(Path.DirectorySeparatorChar).Split(Path.DirectorySeparatorChar);
+ string[] pathParts = absolutePath.TrimEnd(Path.DirectorySeparatorChar).Split(Path.DirectorySeparatorChar);
+
+ // Find the common base path length
+ int commonLength = 0;
+ while (commonLength < relativeToParts.Length && commonLength < pathParts.Length &&
+ string.Equals(relativeToParts[commonLength], pathParts[commonLength], StringComparison.OrdinalIgnoreCase))
+ {
+ commonLength++;
+ }
+
+ // Calculate the number of directories to go up from the relativeTo path
+ int upDirectories = relativeToParts.Length - commonLength;
+
+ // Build the relative path
+ string relativePath = string.Join(Path.DirectorySeparatorChar.ToString(), new string[upDirectories].Select(_ => "..").ToArray());
+ if (commonLength < pathParts.Length)
+ {
+ if (relativePath.Length > 0)
+ {
+ relativePath += Path.DirectorySeparatorChar;
+ }
+ relativePath += string.Join(Path.DirectorySeparatorChar.ToString(), pathParts.Skip(commonLength));
+ }
+
+ return relativePath;
+ }
}
diff --git a/src/Mvc/Mvc.Testing/src/PublicAPI.Unshipped.txt b/src/Mvc/Mvc.Testing/src/PublicAPI.Unshipped.txt
index 7dc5c58110bf..5137f91f4690 100644
--- a/src/Mvc/Mvc.Testing/src/PublicAPI.Unshipped.txt
+++ b/src/Mvc/Mvc.Testing/src/PublicAPI.Unshipped.txt
@@ -1 +1,7 @@
#nullable enable
+Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory.Initialize() -> void
+*REMOVED*Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory.Server.get -> Microsoft.AspNetCore.TestHost.TestServer!
+Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory.Server.get -> Microsoft.AspNetCore.TestHost.TestServer?
+Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory.TestServer.get -> Microsoft.AspNetCore.TestHost.ITestServer?
+virtual Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory.CreateTestServer(Microsoft.AspNetCore.Hosting.IWebHostBuilder! builder) -> Microsoft.AspNetCore.TestHost.ITestServer!
+
diff --git a/src/Mvc/Mvc.Testing/src/Resources.resx b/src/Mvc/Mvc.Testing/src/Resources.resx
index 84ce491ca5ed..1c1ec82845da 100644
--- a/src/Mvc/Mvc.Testing/src/Resources.resx
+++ b/src/Mvc/Mvc.Testing/src/Resources.resx
@@ -1,4 +1,4 @@
-
+