blob: 4a32eff1f79de008ec5d096c5cf7a2b092af27b2 [file]
// // Licensed to the Apache Software Foundation (ASF) under one
// // or more contributor license agreements. See the NOTICE file
// // distributed with this work for additional information
// // regarding copyright ownership. The ASF licenses this file
// // to you under the Apache License, Version 2.0 (the
// // "License"); you may not use this file except in compliance
// // with the License. You may obtain a copy of the License at
// //
// // http://www.apache.org/licenses/LICENSE-2.0
// //
// // Unless required by applicable law or agreed to in writing,
// // software distributed under the License is distributed on an
// // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// // KIND, either express or implied. See the License for the
// // specific language governing permissions and limitations
// // under the License.
using System.Text;
using Apache.Iggy.Contracts;
using Apache.Iggy.Enums;
using Apache.Iggy.Exceptions;
using Apache.Iggy.Headers;
using Apache.Iggy.IggyClient;
using Apache.Iggy.Kinds;
using Apache.Iggy.Messages;
using Apache.Iggy.Tests.Integrations.Fixtures;
using Shouldly;
using Partitioning = Apache.Iggy.Kinds.Partitioning;
namespace Apache.Iggy.Tests.Integrations;
public class FetchMessagesTests
{
private const int MessageCount = 20;
private const string TopicName = "topic";
private const string HeadersTopicName = "headers-topic";
[ClassDataSource<IggyServerFixture>(Shared = SharedType.PerAssembly)]
public required IggyServerFixture Fixture { get; init; }
private async Task<(IIggyClient client, string streamName)> CreateStreamWithMessages(Protocol protocol)
{
var client = await Fixture.CreateAuthenticatedClient(protocol);
var streamName = $"fetch-msg-{Guid.NewGuid():N}";
await client.CreateStreamAsync(streamName);
await client.CreateTopicAsync(Identifier.String(streamName), TopicName, 1);
await client.CreateTopicAsync(Identifier.String(streamName), HeadersTopicName, 1);
await client.SendMessagesAsync(Identifier.String(streamName),
Identifier.String(TopicName), Partitioning.None(),
CreateMessagesWithoutHeader(MessageCount));
await client.SendMessagesAsync(Identifier.String(streamName),
Identifier.String(HeadersTopicName), Partitioning.None(),
CreateMessagesWithHeader(MessageCount));
return (client, streamName);
}
[Test]
[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
public async Task PollMessages_WithNoHeaders_Should_PollMessages_Successfully(Protocol protocol)
{
var (client, streamName) = await CreateStreamWithMessages(protocol);
var response = await client.PollMessagesAsync(new MessageFetchRequest
{
Count = 10,
AutoCommit = true,
Consumer = Consumer.New(1),
PartitionId = 0,
PollingStrategy = PollingStrategy.Next(),
StreamId = Identifier.String(streamName),
TopicId = Identifier.String(TopicName)
});
response.Messages.Count.ShouldBe(10);
response.PartitionId.ShouldBe(0);
response.CurrentOffset.ShouldBe(19u);
foreach (var responseMessage in response.Messages)
{
responseMessage.UserHeaders.ShouldBeNull();
responseMessage.Payload.ShouldNotBeNull();
responseMessage.Payload.Length.ShouldBeGreaterThan(0);
}
}
[Test]
[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
public async Task PollMessages_InvalidTopic_Should_Throw_InvalidResponse(Protocol protocol)
{
var (client, streamName) = await CreateStreamWithMessages(protocol);
var invalidFetchRequest = new MessageFetchRequest
{
Count = 10,
AutoCommit = true,
Consumer = Consumer.New(1),
PartitionId = 0,
PollingStrategy = PollingStrategy.Next(),
StreamId = Identifier.String(streamName),
TopicId = Identifier.Numeric(2137)
};
await Should.ThrowAsync<IggyInvalidStatusCodeException>(() =>
client.PollMessagesAsync(invalidFetchRequest));
}
[Test]
[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
public async Task PollMessages_WithHeaders_Should_PollMessages_Successfully(Protocol protocol)
{
var (client, streamName) = await CreateStreamWithMessages(protocol);
var headersMessageFetchRequest = new MessageFetchRequest
{
Count = 10,
AutoCommit = true,
Consumer = Consumer.New(1),
PartitionId = 0,
PollingStrategy = PollingStrategy.Next(),
StreamId = Identifier.String(streamName),
TopicId = Identifier.String(HeadersTopicName)
};
var response = await client.PollMessagesAsync(headersMessageFetchRequest);
response.Messages.Count.ShouldBe(10);
response.PartitionId.ShouldBe(0);
response.CurrentOffset.ShouldBe(19u);
foreach (var responseMessage in response.Messages)
{
responseMessage.UserHeaders.ShouldNotBeNull();
responseMessage.UserHeaders.Count.ShouldBe(2);
responseMessage.UserHeaders[HeaderKey.FromString("header1")].ToString().ShouldBe("value1");
responseMessage.UserHeaders[HeaderKey.FromString("header2")].ToInt32().ShouldBeGreaterThan(0);
}
}
private static Message[] CreateMessagesWithoutHeader(int count)
{
var messages = new List<Message>();
for (var i = 0; i < count; i++)
{
var dummyJson = $$"""
{
"userId": {{i + 1}},
"id": {{i + 1}},
"title": "delete",
"completed": false
}
""";
messages.Add(new Message(Guid.NewGuid(), Encoding.UTF8.GetBytes(dummyJson)));
}
return messages.ToArray();
}
private static Message[] CreateMessagesWithHeader(int count)
{
var messages = new List<Message>();
for (var i = 0; i < count; i++)
{
var dummyJson = $$"""
{
"userId": {{i + 1}},
"id": {{i + 1}},
"title": "delete",
"completed": false
}
""";
messages.Add(new Message(Guid.NewGuid(), Encoding.UTF8.GetBytes(dummyJson),
new Dictionary<HeaderKey, HeaderValue>
{
{ HeaderKey.FromString("header1"), HeaderValue.FromString("value1") },
{ HeaderKey.FromString("header2"), HeaderValue.FromInt32(14 + i) }
}));
}
return messages.ToArray();
}
}