Skip to content

Commit e056789

Browse files
authored
Merge pull request #6 from Fresa/add-tests-for-kafka-2-5-0
Add tests for kafka 2 5 0
2 parents 15acdc3 + 2516213 commit e056789

26 files changed

+1038
-178
lines changed

Kafka.TestFramework.sln

+14
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kafka.TestFramework", "src\
1919
EndProject
2020
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Confluent.Kafka.1.1.0.Tests", "tests\Confluent.Kafka.1.1.0.Tests\Confluent.Kafka.1.1.0.Tests.csproj", "{12646283-CC9E-4D45-8E89-F52337C790B6}"
2121
EndProject
22+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kafka.TestSpecification", "tests\Kafka.TestSpecification\Kafka.TestSpecification.csproj", "{4676B0E5-6641-426B-986D-49D336B0E5E6}"
23+
EndProject
24+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Confluent.Kafka.2.4.0.Tests", "tests\Confluent.Kafka.2.4.0.Tests\Confluent.Kafka.2.4.0.Tests.csproj", "{B06C41D0-DB18-47F2-A280-0104FE5843CC}"
25+
EndProject
2226
Global
2327
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2428
Debug|Any CPU = Debug|Any CPU
@@ -37,13 +41,23 @@ Global
3741
{12646283-CC9E-4D45-8E89-F52337C790B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
3842
{12646283-CC9E-4D45-8E89-F52337C790B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
3943
{12646283-CC9E-4D45-8E89-F52337C790B6}.Release|Any CPU.Build.0 = Release|Any CPU
44+
{4676B0E5-6641-426B-986D-49D336B0E5E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
45+
{4676B0E5-6641-426B-986D-49D336B0E5E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
46+
{4676B0E5-6641-426B-986D-49D336B0E5E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
47+
{4676B0E5-6641-426B-986D-49D336B0E5E6}.Release|Any CPU.Build.0 = Release|Any CPU
48+
{B06C41D0-DB18-47F2-A280-0104FE5843CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49+
{B06C41D0-DB18-47F2-A280-0104FE5843CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
50+
{B06C41D0-DB18-47F2-A280-0104FE5843CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
51+
{B06C41D0-DB18-47F2-A280-0104FE5843CC}.Release|Any CPU.Build.0 = Release|Any CPU
4052
EndGlobalSection
4153
GlobalSection(SolutionProperties) = preSolution
4254
HideSolutionNode = FALSE
4355
EndGlobalSection
4456
GlobalSection(NestedProjects) = preSolution
4557
{FCFCC73C-B0A6-4D4E-A765-9A94303D00AD} = {0EEC4A41-7C67-4580-8A21-BFA01B2415F1}
4658
{12646283-CC9E-4D45-8E89-F52337C790B6} = {0EEC4A41-7C67-4580-8A21-BFA01B2415F1}
59+
{4676B0E5-6641-426B-986D-49D336B0E5E6} = {0EEC4A41-7C67-4580-8A21-BFA01B2415F1}
60+
{B06C41D0-DB18-47F2-A280-0104FE5843CC} = {0EEC4A41-7C67-4580-8A21-BFA01B2415F1}
4761
EndGlobalSection
4862
GlobalSection(ExtensibilityGlobals) = postSolution
4963
SolutionGuid = {B432BD60-300C-4955-9D44-011413D52F2D}
+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<SolutionConfiguration>
22
<Settings>
33
<AllowParallelTestExecution>True</AllowParallelTestExecution>
4+
<EnableRDI>True</EnableRDI>
5+
<RdiConfigured>True</RdiConfigured>
46
<SolutionConfigured>True</SolutionConfigured>
57
</Settings>
68
</SolutionConfiguration>

src/Kafka.TestFramework/SocketServer.cs

+21-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,27 @@ private void StartAcceptingClients()
5757
var clientSocket = await _clientAcceptingSocket
5858
.AcceptAsync()
5959
.ConfigureAwait(false);
60-
Logger.Debug("Client connected {@clientSocket}", clientSocket);
60+
Logger.Debug("Client connected {@clientSocket}", new
61+
{
62+
clientSocket.AddressFamily,
63+
clientSocket.Available,
64+
clientSocket.Connected,
65+
clientSocket.ProtocolType,
66+
clientSocket.ReceiveTimeout,
67+
clientSocket.ReceiveBufferSize,
68+
clientSocket.Ttl,
69+
clientSocket.SendBufferSize,
70+
clientSocket.SendTimeout,
71+
RemoteEndPoint = new
72+
{
73+
clientSocket.RemoteEndPoint.AddressFamily
74+
},
75+
clientSocket.SocketType,
76+
LocalEndPoint = new
77+
{
78+
clientSocket.LocalEndPoint.AddressFamily
79+
}
80+
});
6181

6282
await _waitingClients
6383
.SendAsync(

tests/Confluent.Kafka.1.1.0.Tests/BytesExtensions.cs

-13
This file was deleted.

tests/Confluent.Kafka.1.1.0.Tests/Confluent.Kafka.1.1.0.Tests.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<PackageReference Include="Confluent.Kafka" Version="1.1.0" />
10+
<PackageReference Include="Confluent.Kafka" Version="1.8.2" />
1111
<PackageReference Include="FluentAssertions" Version="5.9.0" />
1212
<PackageReference Include="Kafka.Protocol" Version="2.0.3" />
1313
<PackageReference Include="Log.It.With.NLog" Version="2.0.0" />
1414
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.0.0" />
1515
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.0.0" />
1616
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
17-
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.1" />
1817
<PackageReference Include="System.Linq.Async" Version="4.1.1" />
1918
<PackageReference Include="Test.It" Version="2.2.0" />
2019
<PackageReference Include="Test.It.With.XUnit" Version="2.2.4" />
@@ -24,6 +23,7 @@
2423

2524
<ItemGroup>
2625
<ProjectReference Include="..\..\src\Kafka.TestFramework\Kafka.TestFramework.csproj" />
26+
<ProjectReference Include="..\Kafka.TestSpecification\Kafka.TestSpecification.csproj" />
2727
</ItemGroup>
2828

2929
<ItemGroup>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
using Confluent.Kafka;
8+
using FluentAssertions;
9+
using Kafka.Protocol;
10+
using Kafka.Protocol.Records;
11+
using Xunit;
12+
using Xunit.Abstractions;
13+
using Int32 = Kafka.Protocol.Int32;
14+
using Record = Kafka.Protocol.Records.Record;
15+
16+
namespace Kafka.TestFramework.Tests
17+
{
18+
public partial class Given_a_socket_based_test_server
19+
{
20+
public class When_connecting_to_the_server_and_consuming_a_message : TestSpecificationAsync
21+
{
22+
private SocketBasedKafkaTestFramework _testServer;
23+
private readonly List<string> _result = new List<string>();
24+
private const int NumberOfMessage = 5;
25+
26+
public When_connecting_to_the_server_and_consuming_a_message(
27+
ITestOutputHelper testOutputHelper)
28+
: base(testOutputHelper)
29+
{
30+
}
31+
32+
protected override Task GivenAsync()
33+
{
34+
_testServer = KafkaTestFramework.WithSocket();
35+
36+
_testServer.On<ApiVersionsRequest, ApiVersionsResponse>(
37+
request => request.Respond()
38+
.WithAllApiKeys());
39+
40+
_testServer.On<MetadataRequest, MetadataResponse>(
41+
request => request.Respond()
42+
.WithTopicsCollection(
43+
request.TopicsCollection?.Select(topic =>
44+
new Func<MetadataResponse.MetadataResponseTopic,
45+
MetadataResponse.MetadataResponseTopic>(
46+
responseTopic =>
47+
responseTopic
48+
.WithName(topic.Name)
49+
.WithPartitionsCollection(partition =>
50+
partition
51+
.WithLeaderId(0)
52+
.WithPartitionIndex(0))))
53+
.ToArray() ??
54+
Array.Empty<Func<MetadataResponse.MetadataResponseTopic,
55+
MetadataResponse.MetadataResponseTopic>>())
56+
.WithBrokersCollection(broker => broker
57+
.WithHost("localhost")
58+
.WithPort(_testServer.Port))
59+
);
60+
61+
_testServer.On<FindCoordinatorRequest, FindCoordinatorResponse>(
62+
request => request.Respond()
63+
.WithHost("localhost")
64+
.WithPort(_testServer.Port)
65+
);
66+
67+
_testServer.On<JoinGroupRequest, JoinGroupResponse>(
68+
request => request.Respond()
69+
.WithProtocolName(request.ProtocolsCollection.First().Value.Name));
70+
71+
_testServer.On<SyncGroupRequest, SyncGroupResponse>(
72+
async (request, cancellationToken) => request.Respond()
73+
.WithAssignment(
74+
await new ConsumerProtocolAssignment(ConsumerProtocolAssignment.MaxVersion)
75+
.WithAssignedPartitionsCollection(partition => partition
76+
.WithTopic("topic1")
77+
.WithPartitionsCollection(new Int32[] { 0 }))
78+
.ToBytesAsync(cancellationToken)
79+
.ConfigureAwait(false))
80+
);
81+
82+
_testServer.On<OffsetFetchRequest, OffsetFetchResponse>(request => request.Respond()
83+
.WithTopicsCollection(
84+
request.TopicsCollection?.Select(topic =>
85+
new Func<OffsetFetchResponse.OffsetFetchResponseTopic,
86+
OffsetFetchResponse.OffsetFetchResponseTopic>(responseTopic =>
87+
responseTopic
88+
.WithName(topic.Name)
89+
.WithPartitionsCollection(topic.PartitionIndexesCollection
90+
.Select(partitionIndex =>
91+
new Func<OffsetFetchResponse.OffsetFetchResponseTopic.
92+
OffsetFetchResponsePartition,
93+
OffsetFetchResponse.OffsetFetchResponseTopic.
94+
OffsetFetchResponsePartition>(
95+
partition => partition
96+
.WithPartitionIndex(partitionIndex)))
97+
.ToArray())))
98+
.ToArray() ??
99+
Array.Empty<Func<OffsetFetchResponse.OffsetFetchResponseTopic,
100+
OffsetFetchResponse.OffsetFetchResponseTopic>>()));
101+
102+
var records = new Dictionary<long, Record>();
103+
for (var i = 0; i < NumberOfMessage; i++)
104+
{
105+
records.Add(i, new Record
106+
{
107+
OffsetDelta = i,
108+
Value = Encoding.UTF8.GetBytes(
109+
$"data{i} fetched from broker")
110+
});
111+
}
112+
113+
_testServer.On<FetchRequest, FetchResponse>(async (request, cancellationToken) =>
114+
{
115+
var returnsData = false;
116+
var response = request.Respond()
117+
.WithResponsesCollection(
118+
request.TopicsCollection.Select(topic =>
119+
new Func<FetchResponse.FetchableTopicResponse, FetchResponse.FetchableTopicResponse>(
120+
response => response
121+
.WithTopic(topic.Topic)
122+
.WithPartitionsCollection(topic.PartitionsCollection.Select(partition =>
123+
new Func<FetchResponse.FetchableTopicResponse.PartitionData,
124+
FetchResponse.FetchableTopicResponse.PartitionData>(data =>
125+
{
126+
var recordBatch = new NullableRecordBatch
127+
{
128+
LastOffsetDelta = (int)partition.FetchOffset,
129+
Magic = 2,
130+
Records = records.TryGetValue(partition.FetchOffset.Value,
131+
out var record)
132+
? new NullableArray<Record>(record)
133+
: NullableArray<Record>.Default
134+
};
135+
returnsData = recordBatch.Records != NullableArray<Record>.Default;
136+
return returnsData ? data.WithRecords(recordBatch) : data;
137+
})).ToArray()
138+
))).ToArray());
139+
if (!returnsData)
140+
{
141+
await Task.Delay(request.MaxWaitMs, cancellationToken)
142+
.ConfigureAwait(false);
143+
}
144+
145+
return response;
146+
});
147+
148+
_testServer.On<OffsetCommitRequest, OffsetCommitResponse>(request => request.Respond()
149+
.WithTopicsCollection(request.TopicsCollection.Select(topic =>
150+
new Func<OffsetCommitResponse.OffsetCommitResponseTopic,
151+
OffsetCommitResponse.OffsetCommitResponseTopic>(responseTopic => responseTopic
152+
.WithName(topic.Name)
153+
.WithPartitionsCollection(topic.PartitionsCollection.Select(partition =>
154+
new Func<OffsetCommitResponse.OffsetCommitResponseTopic.
155+
OffsetCommitResponsePartition,
156+
OffsetCommitResponse.OffsetCommitResponseTopic.
157+
OffsetCommitResponsePartition>(responsePartition => responsePartition
158+
.WithPartitionIndex(partition.PartitionIndex))).ToArray())
159+
)).ToArray()
160+
));
161+
162+
_testServer.On<LeaveGroupRequest, LeaveGroupResponse>(request => request.Respond());
163+
_testServer.On<HeartbeatRequest, HeartbeatResponse>(request => request.Respond());
164+
165+
return Task.CompletedTask;
166+
}
167+
168+
protected override async Task WhenAsync()
169+
{
170+
await using (_testServer.Start()
171+
.ConfigureAwait(false))
172+
{
173+
ConsumeMessages("localhost", _testServer.Port, _testServer.Stopping);
174+
}
175+
}
176+
177+
[Fact]
178+
public void It_should_have_read_the_messages_sent()
179+
{
180+
_result.Should().HaveCount(NumberOfMessage);
181+
for (var i = 0; i < NumberOfMessage; i++)
182+
{
183+
_result.Should().Contain($"data{i} fetched from broker");
184+
}
185+
}
186+
187+
private void ConsumeMessages(string host,
188+
int port, CancellationToken testServerStopping)
189+
{
190+
var consumerConfig = new ConsumerConfig(new Dictionary<string, string>
191+
{
192+
{ "log_level", "7" }
193+
})
194+
{
195+
BootstrapServers = $"{host}:{port}",
196+
ApiVersionRequestTimeoutMs = 30000,
197+
Debug = "all",
198+
GroupId = "group1",
199+
};
200+
201+
using var consumer = new ConsumerBuilder<Ignore, string>(consumerConfig)
202+
.SetLogHandler(this.Log)
203+
.Build();
204+
205+
consumer.Subscribe("topic1");
206+
var cancellationToken = CancellationTokenSource
207+
.CreateLinkedTokenSource(testServerStopping, TimeoutCancellationToken).Token;
208+
try
209+
{
210+
for (var i = 0; i < NumberOfMessage; i++)
211+
{
212+
_result.Add(consumer.Consume(cancellationToken).Message.Value);
213+
}
214+
}
215+
finally
216+
{
217+
consumer.Close();
218+
}
219+
}
220+
}
221+
}
222+
}

tests/Confluent.Kafka.1.1.0.Tests/Given_a_socket_based_test_server.When_connecting_to_the_server_and_producing_a_message.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public void It_should_have_read_the_message_sent()
113113
_records.First().Value.EncodeToString(Encoding.UTF8).Should().Be("test");
114114
}
115115

116-
private static async Task ProduceMessageFromClientAsync(string host,
116+
private async Task ProduceMessageFromClientAsync(string host,
117117
int port, CancellationToken testServerStopping)
118118
{
119119
var producerConfig = new ProducerConfig(new Dictionary<string, string>
@@ -129,12 +129,12 @@ private static async Task ProduceMessageFromClientAsync(string host,
129129

130130
using var producer =
131131
new ProducerBuilder<Null, string>(producerConfig)
132-
.SetLogHandler(LogExtensions.UseLogIt)
132+
.SetLogHandler(this.Log)
133133
.Build();
134134

135135
var report = await producer
136136
.ProduceAsync("my-topic",
137-
new Message<Null, string> { Value = "test" })
137+
new Message<Null, string> { Value = "test" }, testServerStopping)
138138
.ConfigureAwait(false);
139139
LogFactory.Create("producer").Info("Produce report {@report}", report);
140140

0 commit comments

Comments
 (0)