diff --git a/elastic-transport-net.sln b/elastic-transport-net.sln
index 8b1389d..ca9c4ae 100644
--- a/elastic-transport-net.sln
+++ b/elastic-transport-net.sln
@@ -42,6 +42,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elastic.Transport.Profiling
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Playground", "Playground\Playground.csproj", "{5EE4DC72-B337-448B-802A-6158F4D90667}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Elasticsearch.IntegrationTests", "tests\Elastic.Elasticsearch.IntegrationTests\Elastic.Elasticsearch.IntegrationTests.csproj", "{317C118F-FA1E-499A-B7F2-DC932DE66CB8}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -80,6 +82,10 @@ Global
{5EE4DC72-B337-448B-802A-6158F4D90667}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5EE4DC72-B337-448B-802A-6158F4D90667}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5EE4DC72-B337-448B-802A-6158F4D90667}.Release|Any CPU.Build.0 = Release|Any CPU
+ {317C118F-FA1E-499A-B7F2-DC932DE66CB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {317C118F-FA1E-499A-B7F2-DC932DE66CB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {317C118F-FA1E-499A-B7F2-DC932DE66CB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {317C118F-FA1E-499A-B7F2-DC932DE66CB8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -93,6 +99,7 @@ Global
{3B27DE76-1188-4078-8828-67AFD39BAC10} = {3582B07D-C2B0-49CC-B676-EAF806EB010E}
{ED4E89BE-FBE9-4876-979C-63A0E3BC5419} = {BBB0AC81-F09D-4895-84E2-7E933D608E78}
{5EE4DC72-B337-448B-802A-6158F4D90667} = {7610B796-BB3E-4CB2-8296-79BBFF6D23FC}
+ {317C118F-FA1E-499A-B7F2-DC932DE66CB8} = {3582B07D-C2B0-49CC-B676-EAF806EB010E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7F60C4BB-6216-4E50-B1E4-9C38EB484843}
diff --git a/tests/Elastic.Elasticsearch.IntegrationTests/DefaultCluster.cs b/tests/Elastic.Elasticsearch.IntegrationTests/DefaultCluster.cs
new file mode 100644
index 0000000..67257a9
--- /dev/null
+++ b/tests/Elastic.Elasticsearch.IntegrationTests/DefaultCluster.cs
@@ -0,0 +1,57 @@
+// Licensed to Elasticsearch B.V under one or more agreements.
+// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information
+
+using Elastic.Elasticsearch.Ephemeral;
+using Elastic.Elasticsearch.Xunit;
+using Elastic.Transport;
+using Xunit;
+using Xunit.Abstractions;
+using static Elastic.Elasticsearch.Ephemeral.ClusterAuthentication;
+
+[assembly: TestFramework("Elastic.Elasticsearch.Xunit.Sdk.ElasticTestFramework", "Elastic.Elasticsearch.Xunit")]
+
+namespace Elastic.Elasticsearch.IntegrationTests;
+
+/// Declare our cluster that we want to inject into our test classes
+public class DefaultCluster : XunitClusterBase
+{
+ protected static string Version = "8.7.0";
+ public DefaultCluster() : this(new XunitClusterConfiguration(Version) { StartingPortNumber = 9202 }) { }
+ public DefaultCluster(XunitClusterConfiguration xunitClusterConfiguration) : base(xunitClusterConfiguration) { }
+
+ public DefaultHttpTransport CreateClient(ITestOutputHelper output) =>
+ this.GetOrAddClient(_ =>
+ {
+ var hostName = (System.Diagnostics.Process.GetProcessesByName("mitmproxy").Any()
+ ? "ipv4.fiddler"
+ : "localhost");
+ var nodes = NodesUris(hostName);
+ var connectionPool = new StaticNodePool(nodes);
+ var settings = new TransportConfiguration(connectionPool)
+ .Proxy(new Uri("http://ipv4.fiddler:8080"), null!, null!)
+ .RequestTimeout(TimeSpan.FromSeconds(5))
+ .ServerCertificateValidationCallback(CertificateValidations.AllowAll)
+ .OnRequestCompleted(d =>
+ {
+ try { output.WriteLine(d.DebugInformation);}
+ catch
+ {
+ // ignored
+ }
+ })
+ .EnableDebugMode();
+ if (ClusterConfiguration.Features.HasFlag(ClusterFeatures.Security))
+ settings = settings.Authentication(new BasicAuthentication(Admin.Username, Admin.Password));
+ return new DefaultHttpTransport(settings);
+ });
+}
+
+public class SecurityCluster : DefaultCluster
+{
+ public SecurityCluster() : base(new XunitClusterConfiguration(Version, ClusterFeatures.Security | ClusterFeatures.SSL | ClusterFeatures.XPack)
+ {
+ StartingPortNumber = 9202
+ //, TrialMode = XPackTrialMode.Trial
+ }) { }
+}
diff --git a/tests/Elastic.Elasticsearch.IntegrationTests/DefaultClusterTests.cs b/tests/Elastic.Elasticsearch.IntegrationTests/DefaultClusterTests.cs
new file mode 100644
index 0000000..8aaf145
--- /dev/null
+++ b/tests/Elastic.Elasticsearch.IntegrationTests/DefaultClusterTests.cs
@@ -0,0 +1,32 @@
+// Licensed to Elasticsearch B.V under one or more agreements.
+// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information
+
+using Elastic.Transport;
+using FluentAssertions;
+using Xunit;
+using Xunit.Abstractions;
+using static Elastic.Transport.HttpMethod;
+
+namespace Elastic.Elasticsearch.IntegrationTests;
+
+public class DefaultClusterTests : IntegrationTestBase
+{
+ public DefaultClusterTests(DefaultCluster cluster, ITestOutputHelper output) : base(cluster, output) { }
+
+ [Fact]
+ public async Task AsyncRequestDoesNotThrow()
+ {
+ var response = await Transport.RequestAsync(GET, "/");
+ response.ApiCallDetails.Should().NotBeNull();
+ response.ApiCallDetails.HasSuccessfulStatusCode.Should().BeTrue();
+ }
+
+ [Fact]
+ public void SyncRequestDoesNotThrow()
+ {
+ var response = Transport.Request(GET, "/");
+ response.ApiCallDetails.Should().NotBeNull();
+ response.ApiCallDetails.HasSuccessfulStatusCode.Should().BeTrue();
+ }
+}
diff --git a/tests/Elastic.Elasticsearch.IntegrationTests/Elastic.Elasticsearch.IntegrationTests.csproj b/tests/Elastic.Elasticsearch.IntegrationTests/Elastic.Elasticsearch.IntegrationTests.csproj
new file mode 100644
index 0000000..4728769
--- /dev/null
+++ b/tests/Elastic.Elasticsearch.IntegrationTests/Elastic.Elasticsearch.IntegrationTests.csproj
@@ -0,0 +1,30 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
+
diff --git a/tests/Elastic.Elasticsearch.IntegrationTests/IntegrationTestBase.cs b/tests/Elastic.Elasticsearch.IntegrationTests/IntegrationTestBase.cs
new file mode 100644
index 0000000..e416633
--- /dev/null
+++ b/tests/Elastic.Elasticsearch.IntegrationTests/IntegrationTestBase.cs
@@ -0,0 +1,27 @@
+// Licensed to Elasticsearch B.V under one or more agreements.
+// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information
+
+using Elastic.Elasticsearch.Xunit.XunitPlumbing;
+using Elastic.Transport;
+using Xunit.Abstractions;
+
+namespace Elastic.Elasticsearch.IntegrationTests;
+
+public abstract class IntegrationTestBase : IntegrationTestBase
+{
+ protected IntegrationTestBase(DefaultCluster cluster, ITestOutputHelper output) : base(cluster, output) { }
+}
+public abstract class IntegrationTestBase : IClusterFixture
+ where TCluster : DefaultCluster, new()
+{
+ protected TCluster Cluster { get; }
+ protected DefaultHttpTransport Transport { get; }
+
+
+ protected IntegrationTestBase(TCluster cluster, ITestOutputHelper output)
+ {
+ Cluster = cluster;
+ Transport = cluster.CreateClient(output);
+ }
+}
diff --git a/tests/Elastic.Elasticsearch.IntegrationTests/SecurityClusterTests.cs b/tests/Elastic.Elasticsearch.IntegrationTests/SecurityClusterTests.cs
new file mode 100644
index 0000000..c3bbd99
--- /dev/null
+++ b/tests/Elastic.Elasticsearch.IntegrationTests/SecurityClusterTests.cs
@@ -0,0 +1,32 @@
+// Licensed to Elasticsearch B.V under one or more agreements.
+// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information
+
+using Elastic.Transport;
+using FluentAssertions;
+using Xunit;
+using Xunit.Abstractions;
+using static Elastic.Transport.HttpMethod;
+
+namespace Elastic.Elasticsearch.IntegrationTests;
+
+public class SecurityClusterTests : IntegrationTestBase
+{
+ public SecurityClusterTests(SecurityCluster cluster, ITestOutputHelper output) : base(cluster, output) { }
+
+ [Fact]
+ public async Task AsyncRequestDoesNotThrow()
+ {
+ var response = await Transport.RequestAsync(GET, "/");
+ response.ApiCallDetails.Should().NotBeNull();
+ response.ApiCallDetails.HasSuccessfulStatusCode.Should().BeTrue();
+ }
+
+ [Fact]
+ public void SyncRequestDoesNotThrow()
+ {
+ var response = Transport.Request(GET, "/");
+ response.ApiCallDetails.Should().NotBeNull();
+ response.ApiCallDetails.HasSuccessfulStatusCode.Should().BeTrue();
+ }
+}