You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iggy.apache.org by pi...@apache.org on 2025/06/26 06:29:40 UTC
(iggy) branch master updated: chore(csharp): update integration tests (#1913)
This is an automated email from the ASF dual-hosted git repository.
piotr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iggy.git
The following commit(s) were added to refs/heads/master by this push:
new 99a21a18 chore(csharp): update integration tests (#1913)
99a21a18 is described below
commit 99a21a18738badeb9cd897897a15454404fa40a7
Author: Łukasz Zborek <lu...@gmail.com>
AuthorDate: Thu Jun 26 08:29:36 2025 +0200
chore(csharp): update integration tests (#1913)
- change integration tests to TUnit for better visibility of tests and a
better debugging experience (mostly for "DependsOn" attribute)
- change package references to central package management
---
.gitignore | 1 +
foreign/csharp/.editorconfig | 153 ++++++++++++
foreign/csharp/Benchmarks/Benchmarks.csproj | 3 +-
foreign/csharp/Benchmarks/Program.cs | 14 +-
foreign/csharp/DEPENDENCIES.md | 16 +-
foreign/csharp/Directory.Packages.props | 22 ++
.../Attributes/SkipHttpAttribute.cs | 36 +++
.../Attributes/SkipTcpAttribute.cs | 36 +++
.../ConsumerGroupTests.cs | 225 +++++++++++++++++
.../FetchMessagesTests.cs | 185 ++++++++++++++
.../Fixtures/ConsumerGroupFixture.cs | 38 +++
.../Fixtures/FetchMessagesFixture.cs | 148 ++++++++++++
.../Fixtures/FlushMessageFixture.cs | 54 +++++
.../Fixtures/IggyServerFixture.cs | 145 +++++++++++
.../Fixtures/OffsetFixtures.cs | 54 +++++
.../Fixtures/PartitionsFixture.cs | 38 +++
.../Fixtures/PollMessagesFixture.cs | 70 ++++++
.../Fixtures/SendMessageFixture.cs | 38 +++
.../Fixtures/SystemFixture.cs | 89 +++++++
.../FlushMessagesTests.cs | 69 ++++++
.../Helpers/StreamFactory.cs | 32 +++
.../Helpers/TopicFactory.cs | 34 +++
.../Iggy_SDK.Tests.Integration.csproj | 29 +++
.../Models/DummyMessage.cs | 45 ++++
.../Iggy_SDK.Tests.Integration/OffsetTests.cs | 104 ++++++++
.../Iggy_SDK.Tests.Integration/PartitionsTests.cs | 88 +++++++
.../PersonalAccessTokenTests.cs | 98 ++++++++
.../PollMessagesTests.cs | 60 +++++
.../SendMessagesTests.cs | 118 +++++++++
.../Iggy_SDK.Tests.Integration/StreamsTests.cs | 209 ++++++++++++++++
.../Iggy_SDK.Tests.Integration/SystemTests.cs | 195 +++++++++++++++
.../Iggy_SDK.Tests.Integration/TopicsTests.cs | 243 +++++++++++++++++++
.../Iggy_SDK.Tests.Integration/UsersTests.cs | 266 +++++++++++++++++++++
foreign/csharp/Iggy_SDK.sln | 15 ++
foreign/csharp/Iggy_SDK.sln.DotSettings | 23 +-
.../Iggy_SDK/Configuration/TlsConfiguration.cs | 4 +-
.../Iggy_SDK/Contracts/Http/Auth/AuthResponse.cs | 2 +-
.../csharp/Iggy_SDK/Contracts/Http/ClientInfo.cs | 2 +-
.../Iggy_SDK/Contracts/Http/ConsumerGroupInfo.cs | 2 +-
.../Contracts/Http/ConsumerGroupMembers.cs | 2 +-
.../Iggy_SDK/Contracts/Http/MessageResponse.cs | 2 +-
foreign/csharp/Iggy_SDK/Contracts/Http/Stats.cs | 2 +-
.../Iggy_SDK/Contracts/Http/StatsResponse.cs | 4 +-
.../Iggy_SDK/Contracts/Http/StreamResponse.cs | 2 +-
.../csharp/Iggy_SDK/Contracts/Http/TopicRequest.cs | 42 +++-
.../csharp/Iggy_SDK/Contracts/Tcp/TcpContracts.cs | 12 -
.../Exceptions/InvalidResponseException.cs | 2 +-
foreign/csharp/Iggy_SDK/IggyClient/IIggyOffset.cs | 2 +-
.../Implementations/HttpMessageStream.cs | 4 +-
.../IggyClient/Implementations/TcpMessageStream.cs | 16 +-
foreign/csharp/Iggy_SDK/Iggy_SDK.csproj | 13 +-
.../JsonConfiguration/AuthResponseConverter.cs | 6 +-
.../JsonConfiguration/MessagesConverter.cs | 3 +-
.../JsonConfiguration/StatsResponseConverter.cs | 62 ++---
.../JsonConfiguration/StreamResponseConverter.cs | 27 ++-
.../JsonConfiguration/TopicResponseConverter.cs | 73 +++---
.../JsonConfiguration/UserResponseConverter.cs | 35 ---
foreign/csharp/Iggy_SDK/Mappers/BinaryMapper.cs | 23 +-
.../Iggy_SDK_Tests/ContractTests/TcpContract.cs | 7 +-
.../Iggy_SDK_Tests/E2ETests/ConsumerGroupE2E.cs | 199 ---------------
.../Iggy_SDK_Tests/E2ETests/FetchMessagesE2E.cs | 158 ------------
.../Bootstraps/ConsumerGroupFixtureBootstrap.cs | 38 ---
.../Bootstraps/FetchMessagesFixtureBootstrap.cs | 66 -----
.../Bootstraps/FlushMessagesFixtureBootstrap.cs | 59 -----
.../Fixtures/Bootstraps/GeneralFixtureBootstrap.cs | 28 ---
.../Fixtures/Bootstraps/OffsetFixtureBootstrap.cs | 37 ---
.../Fixtures/Bootstraps/PATFixtureBootstrap.cs | 34 ---
.../Bootstraps/PartitionsFixtureBootstrap.cs | 37 ---
.../Bootstraps/PollMessagesFixtureBootstrap.cs | 70 ------
.../Bootstraps/SendMessagesFixtureBootstrap.cs | 47 ----
.../Fixtures/Bootstraps/StreamsFixtureBootstrap.cs | 32 ---
.../Fixtures/Bootstraps/SystemFixtureBootstrap.cs | 72 ------
.../Fixtures/Bootstraps/TopicsFixtureBootstrap.cs | 38 ---
.../Fixtures/Bootstraps/UsersFixtureBootstrap.cs | 34 ---
.../Fixtures/Configs/IggyFixtureClientConfigs.cs | 60 -----
.../E2ETests/Fixtures/IIggyBootstrap.cs | 25 --
.../E2ETests/Fixtures/IggyBaseFixture.cs | 122 ----------
.../E2ETests/Fixtures/IggyConsumerGroupFixture.cs | 29 ---
.../E2ETests/Fixtures/IggyFetchMessagesFixture.cs | 29 ---
.../E2ETests/Fixtures/IggyFlushMessagesFixture.cs | 29 ---
.../E2ETests/Fixtures/IggyGeneralFixture.cs | 30 ---
.../E2ETests/Fixtures/IggyOffsetFixture.cs | 30 ---
.../E2ETests/Fixtures/IggyPATFixture.cs | 30 ---
.../E2ETests/Fixtures/IggyPartitionFixture.cs | 31 ---
.../E2ETests/Fixtures/IggyPollMessagesFixture.cs | 30 ---
.../E2ETests/Fixtures/IggySendMessagesFixture.cs | 30 ---
.../E2ETests/Fixtures/IggyStreamFixture.cs | 30 ---
.../E2ETests/Fixtures/IggySystemFixture.cs | 29 ---
.../E2ETests/Fixtures/IggyTcpUsersFixture.cs | 30 ---
.../E2ETests/Fixtures/IggyTopicFixture.cs | 30 ---
.../E2ETests/Fixtures/Models/IggyClientModel.cs | 28 ---
.../Iggy_SDK_Tests/E2ETests/FlushMessagesE2E.cs | 106 --------
.../csharp/Iggy_SDK_Tests/E2ETests/OffsetE2E.cs | 76 ------
foreign/csharp/Iggy_SDK_Tests/E2ETests/PATE2E.cs | 122 ----------
.../Iggy_SDK_Tests/E2ETests/PartitionsE2E.cs | 103 --------
.../Iggy_SDK_Tests/E2ETests/PollMessagesE2E.cs | 64 -----
.../Iggy_SDK_Tests/E2ETests/SendMessagesE2E.cs | 114 ---------
.../csharp/Iggy_SDK_Tests/E2ETests/StreamsE2E.cs | 153 ------------
.../csharp/Iggy_SDK_Tests/E2ETests/SystemE2E.cs | 119 ---------
.../csharp/Iggy_SDK_Tests/E2ETests/TopicsE2E.cs | 209 ----------------
foreign/csharp/Iggy_SDK_Tests/E2ETests/UsersE2E.cs | 226 -----------------
.../csharp/Iggy_SDK_Tests/Iggy_SDK_Tests.csproj | 30 +--
.../Iggy_SDK_Tests/MapperTests/BinaryMapper.cs | 3 +-
.../csharp/Iggy_SDK_Tests/Utils/PriorityOrderer.cs | 13 +-
.../Iggy_SDK_Tests/Utils/Topics/TopicFactory.cs | 28 +--
.../Iggy_Sample_Consumer.csproj | 2 +-
foreign/csharp/Iggy_Sample_Consumer/Program.cs | 16 +-
.../Iggy_Sample_Producer.csproj | 6 +-
foreign/csharp/Iggy_Sample_Producer/Program.cs | 14 +-
foreign/csharp/README.md | 16 +-
110 files changed, 3194 insertions(+), 3139 deletions(-)
diff --git a/.gitignore b/.gitignore
index d4da1bae..0e722dca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
target*
.idea/
.vscode/
+.vs/
.zed/
.DS_Store
.gradle
diff --git a/foreign/csharp/.editorconfig b/foreign/csharp/.editorconfig
new file mode 100644
index 00000000..96d0b569
--- /dev/null
+++ b/foreign/csharp/.editorconfig
@@ -0,0 +1,153 @@
+[*]
+charset = utf-8-bom
+end_of_line = crlf
+trim_trailing_whitespace = false
+insert_final_newline = false
+indent_style = space
+indent_size = 4
+
+# Microsoft .NET properties
+csharp_new_line_before_members_in_object_initializers = false
+csharp_preferred_modifier_order = public, private, protected, internal, file, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async, required:suggestion
+csharp_style_prefer_utf8_string_literals = true:suggestion
+csharp_style_var_for_built_in_types = true:suggestion
+dotnet_naming_rule.interfaces_rule.import_to_resharper = True
+dotnet_naming_rule.interfaces_rule.resharper_description = Interfaces
+dotnet_naming_rule.interfaces_rule.resharper_guid = a7a3339e-4e89-4319-9735-a9dc4cb74cc7
+dotnet_naming_rule.interfaces_rule.severity = warning
+dotnet_naming_rule.interfaces_rule.style = i_upper_camel_case_style
+dotnet_naming_rule.interfaces_rule.symbols = interfaces_symbols
+dotnet_naming_rule.private_constants_rule.import_to_resharper = True
+dotnet_naming_rule.private_constants_rule.resharper_description = Constant fields (private)
+dotnet_naming_rule.private_constants_rule.resharper_guid = 236f7aa5-7b06-43ca-bf2a-9b31bfcff09a
+dotnet_naming_rule.private_constants_rule.severity = warning
+dotnet_naming_rule.private_constants_rule.style = upper_camel_case_style
+dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols
+dotnet_naming_rule.private_instance_fields_rule.import_to_resharper = True
+dotnet_naming_rule.private_instance_fields_rule.resharper_description = Instance fields (private)
+dotnet_naming_rule.private_instance_fields_rule.resharper_guid = 4a98fdf6-7d98-4f5a-afeb-ea44ad98c70c
+dotnet_naming_rule.private_instance_fields_rule.severity = warning
+dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style
+dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols
+dotnet_naming_rule.private_static_fields_rule.import_to_resharper = True
+dotnet_naming_rule.private_static_fields_rule.resharper_description = Static fields (private)
+dotnet_naming_rule.private_static_fields_rule.resharper_exclusive_prefixes_suffixes = true
+dotnet_naming_rule.private_static_fields_rule.resharper_guid = f9fce829-e6f4-4cb2-80f1-5497c44f51df
+dotnet_naming_rule.private_static_fields_rule.severity = warning
+dotnet_naming_rule.private_static_fields_rule.style = lower_camel_case_style
+dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols
+dotnet_naming_rule.private_static_readonly_rule.import_to_resharper = True
+dotnet_naming_rule.private_static_readonly_rule.resharper_description = Static readonly fields (private)
+dotnet_naming_rule.private_static_readonly_rule.resharper_guid = 15b5b1f1-457c-4ca6-b278-5615aedc07d3
+dotnet_naming_rule.private_static_readonly_rule.severity = warning
+dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style
+dotnet_naming_rule.private_static_readonly_rule.symbols = private_static_readonly_symbols
+dotnet_naming_rule.unity_serialized_field_rule.import_to_resharper = True
+dotnet_naming_rule.unity_serialized_field_rule.resharper_description = Unity serialized field
+dotnet_naming_rule.unity_serialized_field_rule.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
+dotnet_naming_rule.unity_serialized_field_rule.severity = warning
+dotnet_naming_rule.unity_serialized_field_rule.style = lower_camel_case_style_1
+dotnet_naming_rule.unity_serialized_field_rule.symbols = unity_serialized_field_symbols
+dotnet_naming_style.i_upper_camel_case_style.capitalization = pascal_case
+dotnet_naming_style.i_upper_camel_case_style.required_prefix = I
+dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
+dotnet_naming_style.lower_camel_case_style.required_prefix = _
+dotnet_naming_style.lower_camel_case_style_1.capitalization = camel_case
+dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case
+dotnet_naming_symbols.interfaces_symbols.applicable_accessibilities = *
+dotnet_naming_symbols.interfaces_symbols.applicable_kinds = interface
+dotnet_naming_symbols.interfaces_symbols.resharper_applicable_kinds = interface
+dotnet_naming_symbols.interfaces_symbols.resharper_required_modifiers = any
+dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private
+dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field
+dotnet_naming_symbols.private_constants_symbols.required_modifiers = const
+dotnet_naming_symbols.private_constants_symbols.resharper_applicable_kinds = constant_field
+dotnet_naming_symbols.private_constants_symbols.resharper_required_modifiers = any
+dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private
+dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field
+dotnet_naming_symbols.private_instance_fields_symbols.resharper_applicable_kinds = field, readonly_field
+dotnet_naming_symbols.private_instance_fields_symbols.resharper_required_modifiers = instance
+dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private
+dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field
+dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static
+dotnet_naming_symbols.private_static_fields_symbols.resharper_applicable_kinds = field
+dotnet_naming_symbols.private_static_fields_symbols.resharper_required_modifiers = static
+dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private
+dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field
+dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = readonly, static
+dotnet_naming_symbols.private_static_readonly_symbols.resharper_applicable_kinds = readonly_field
+dotnet_naming_symbols.private_static_readonly_symbols.resharper_required_modifiers = static
+dotnet_naming_symbols.unity_serialized_field_symbols.applicable_accessibilities = *
+dotnet_naming_symbols.unity_serialized_field_symbols.applicable_kinds =
+dotnet_naming_symbols.unity_serialized_field_symbols.resharper_applicable_kinds = unity_serialised_field
+dotnet_naming_symbols.unity_serialized_field_symbols.resharper_required_modifiers = instance
+dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none
+dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
+dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:suggestion
+dotnet_style_qualification_for_event = false:suggestion
+dotnet_style_qualification_for_field = false:suggestion
+dotnet_style_qualification_for_method = false:suggestion
+dotnet_style_qualification_for_property = false:suggestion
+dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
+file_header_template = // Licensed to the Apache Software Foundation (ASF) under one\n// or more contributor license agreements.See the NOTICE file\n// distributed with this work for additional information\n// regarding copyright ownership.The ASF licenses this file\n// to you under the Apache License, Version 2.0 (the\n// "License") ; you may not use this file except in compliance\n// with the License. You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LIC [...]
+
+# ReSharper properties
+resharper_autodetect_indent_settings = true
+resharper_braces_for_for = required
+resharper_braces_for_foreach = required
+resharper_braces_for_ifelse = required
+resharper_braces_for_while = required
+resharper_csharp_stick_comment = false
+resharper_csharp_wrap_lines = false
+resharper_formatter_off_tag = @formatter:off
+resharper_formatter_on_tag = @formatter:on
+resharper_formatter_tags_enabled = true
+resharper_for_other_types = use_var_when_evident
+resharper_use_indent_from_vs = false
+
+# ReSharper inspection severities
+resharper_arrange_redundant_parentheses_highlighting = hint
+resharper_arrange_this_qualifier_highlighting = hint
+resharper_arrange_type_member_modifiers_highlighting = hint
+resharper_arrange_type_modifiers_highlighting = hint
+resharper_built_in_type_reference_style_for_member_access_highlighting = hint
+resharper_built_in_type_reference_style_highlighting = hint
+resharper_check_namespace_highlighting = error
+resharper_mvc_action_not_resolved_highlighting = warning
+resharper_mvc_area_not_resolved_highlighting = warning
+resharper_mvc_controller_not_resolved_highlighting = warning
+resharper_mvc_masterpage_not_resolved_highlighting = warning
+resharper_mvc_partial_view_not_resolved_highlighting = warning
+resharper_mvc_template_not_resolved_highlighting = warning
+resharper_mvc_view_component_not_resolved_highlighting = warning
+resharper_mvc_view_component_view_not_resolved_highlighting = warning
+resharper_mvc_view_not_resolved_highlighting = warning
+resharper_razor_assembly_not_resolved_highlighting = warning
+resharper_redundant_base_qualifier_highlighting = warning
+resharper_suggest_var_or_type_simple_types_highlighting = suggestion
+resharper_web_config_module_not_resolved_highlighting = warning
+resharper_web_config_type_not_resolved_highlighting = warning
+resharper_web_config_wrong_module_highlighting = warning
+
+[{*.yaml,*.yml}]
+indent_style = space
+indent_size = 2
+
+[{*.bash,*.sh,*.zsh}]
+indent_style = space
+indent_size = 2
+
+[{*.har,*.jsb2,*.jsb3,*.json,*.jsonc,*.postman_collection,*.postman_collection.json,*.postman_environment,*.postman_environment.json,*.sonarlint/*.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,.ws-context,connectedMode.json,jest.config}]
+indent_style = space
+indent_size = 2
+
+[{tsconfig.app.json,tsconfig.base.json,tsconfig.e2e.json,tsconfig.editor.json,tsconfig.json,tsconfig.lib.json,tsconfig.spec.json,tsconfig.test.json}]
+indent_style = space
+indent_size = 2
+
+[*.{appxmanifest,asax,ascx,aspx,axaml,blockshader,build,c,c++,c++m,cc,ccm,cginc,compute,cp,cpp,cppm,cs,cshtml,cu,cuh,cxx,cxxm,dtd,fs,fsi,fsscript,fsx,fx,fxh,h,h++,hh,hlsl,hlsli,hlslinc,hp,hpp,hxx,icc,inc,inl,ino,ipp,ixx,master,ml,mli,mpp,mq4,mq5,mqh,mxx,nuspec,paml,razor,resw,resx,shader,shaderFoundry,skin,tcc,tpp,urtshader,usf,ush,uxml,vb,xaml,xamlx,xoml,xsd}]
+indent_style = space
+indent_size = 4
+tab_width = 4
diff --git a/foreign/csharp/Benchmarks/Benchmarks.csproj b/foreign/csharp/Benchmarks/Benchmarks.csproj
index 9cec0126..7754912b 100644
--- a/foreign/csharp/Benchmarks/Benchmarks.csproj
+++ b/foreign/csharp/Benchmarks/Benchmarks.csproj
@@ -14,7 +14,7 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
+ <PackageReference Include="Microsoft.Extensions.Logging.Console" />
</ItemGroup>
<PropertyGroup Condition="$([MSBuild]::IsOSPlatform('Windows'))">
<DefineConstants>OS_WINDOWS</DefineConstants>
@@ -29,5 +29,4 @@
<DefineConstants>OS_MAC</DefineConstants>
</PropertyGroup>
-
</Project>
diff --git a/foreign/csharp/Benchmarks/Program.cs b/foreign/csharp/Benchmarks/Program.cs
index bbf33aa4..54c2f785 100644
--- a/foreign/csharp/Benchmarks/Program.cs
+++ b/foreign/csharp/Benchmarks/Program.cs
@@ -81,13 +81,13 @@ try
});
await clients[0].CreateTopicAsync(Identifier.Numeric(startingStreamId + i), new TopicRequest(
- TopicId: topicId,
- Name: $"Test bench topic_{i}",
- CompressionAlgorithm: CompressionAlgorithm.None,
- MessageExpiry: 0,
- MaxTopicSize: 2_000_000_000,
- ReplicationFactor: 3,
- PartitionsCount: 1));
+ topicId: topicId,
+ name: $"Test bench topic_{i}",
+ compressionAlgorithm: CompressionAlgorithm.None,
+ messageExpiry: 0,
+ maxTopicSize: 2_000_000_000,
+ replicationFactor: 3,
+ partitionsCount: 1));
}
}
catch
diff --git a/foreign/csharp/DEPENDENCIES.md b/foreign/csharp/DEPENDENCIES.md
index bf37d349..c311316d 100644
--- a/foreign/csharp/DEPENDENCIES.md
+++ b/foreign/csharp/DEPENDENCIES.md
@@ -1,12 +1,16 @@
# Dependencies
+coverlet.collector: "6.0.4", "MIT",
FluentAssertions: "6.12.0", "Apache-2.0",
+Microsoft.Extensions.Logging: "8.0.1", "MIT",
+Microsoft.Extensions.Logging.Console: "8.0.1", "MIT",
Microsoft.NET.Test.Sdk: "17.14.1", "MIT",
+Microsoft.Testing.Extensions.CodeCoverage: "17.14.2", "MIT",
+Microsoft.Testing.Extensions.TrxReport: "1.7.3", "MIT",
Moq: "4.20.72", "BSD-3-Clause",
-Testcontainers: "4.5.0", "MIT",
+Shouldly: "4.3.0", "BSD-3-Clause",
+System.IO.Hashing: "8.0.0", "MIT",
+Testcontainers: "4.6.0", "MIT",
+TUnit: "0.25.21", "MIT",
xunit: "2.9.3", "Apache-2.0",
-xunit.runner.visualstudio: "3.1.0", "Apache-2.0",
-coverlet.collector: "6.0.4", "MIT" ,
-Microsoft.Extensions.Logging: "8.0.0", "MIT",
-Microsoft.Extensions.Logging.Console:"7.0.0", "MIT"
-System.IO.Hashing: "9.0.5", "MIT",
+xunit.runner.visualstudio: "3.1.1", "Apache-2.0",
diff --git a/foreign/csharp/Directory.Packages.props b/foreign/csharp/Directory.Packages.props
new file mode 100644
index 00000000..02c84e79
--- /dev/null
+++ b/foreign/csharp/Directory.Packages.props
@@ -0,0 +1,22 @@
+<Project>
+ <PropertyGroup>
+ <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
+ <CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled>
+ </PropertyGroup>
+ <ItemGroup>
+ <PackageVersion Include="coverlet.collector" Version="6.0.4" />
+ <PackageVersion Include="FluentAssertions" Version="6.12.0" />
+ <PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.1" />
+ <PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
+ <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
+ <PackageVersion Include="Microsoft.Testing.Extensions.CodeCoverage" Version="17.14.2" />
+ <PackageVersion Include="Microsoft.Testing.Extensions.TrxReport" Version="1.7.3" />
+ <PackageVersion Include="Moq" Version="4.20.72" />
+ <PackageVersion Include="Shouldly" Version="4.3.0" />
+ <PackageVersion Include="System.IO.Hashing" Version="8.0.0" />
+ <PackageVersion Include="Testcontainers" Version="4.6.0" />
+ <PackageVersion Include="TUnit" Version="0.25.21" />
+ <PackageVersion Include="xunit" Version="2.9.3" />
+ <PackageVersion Include="xunit.runner.visualstudio" Version="3.1.1" />
+ </ItemGroup>
+</Project>
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Attributes/SkipHttpAttribute.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Attributes/SkipHttpAttribute.cs
new file mode 100644
index 00000000..dc5c5654
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Attributes/SkipHttpAttribute.cs
@@ -0,0 +1,36 @@
+// // 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 Apache.Iggy.Enums;
+
+namespace Apache.Iggy.Tests.Integrations.Attributes;
+
+internal class SkipHttpAttribute() : SkipAttribute("This test is skipped for HTTP protocol")
+{
+ public override Task<bool> ShouldSkip(BeforeTestContext context)
+ {
+ foreach (var argument in context.TestDetails.TestClassArguments)
+ {
+ if (argument is Protocol.Http)
+ {
+ return Task.FromResult(true);
+ }
+ }
+
+ return Task.FromResult(false);
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Attributes/SkipTcpAttribute.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Attributes/SkipTcpAttribute.cs
new file mode 100644
index 00000000..bb2f4d36
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Attributes/SkipTcpAttribute.cs
@@ -0,0 +1,36 @@
+// // 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 Apache.Iggy.Enums;
+
+namespace Apache.Iggy.Tests.Integrations.Attributes;
+
+internal class SkipTcpAttribute() : SkipAttribute("This test is skipped for TCP protocol")
+{
+ public override Task<bool> ShouldSkip(BeforeTestContext context)
+ {
+ foreach (var argument in context.TestDetails.TestClassArguments)
+ {
+ if (argument is Protocol.Tcp)
+ {
+ return Task.FromResult(true);
+ }
+ }
+
+ return Task.FromResult(false);
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/ConsumerGroupTests.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/ConsumerGroupTests.cs
new file mode 100644
index 00000000..7619b175
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/ConsumerGroupTests.cs
@@ -0,0 +1,225 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Contracts.Http.Auth;
+using Apache.Iggy.Enums;
+using Apache.Iggy.Exceptions;
+using Apache.Iggy.IggyClient;
+using Apache.Iggy.Tests.Integrations.Attributes;
+using Apache.Iggy.Tests.Integrations.Fixtures;
+using Shouldly;
+
+namespace Apache.Iggy.Tests.Integrations;
+
+[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
+public class ConsumerGroupTests(Protocol protocol)
+{
+ private static readonly int GroupId = 1;
+
+ private readonly CreateConsumerGroupRequest _createConsumerGroupRequest = new()
+ {
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(1),
+ ConsumerGroupId = GroupId,
+ Name = "test_consumer_group"
+ };
+
+ [ClassDataSource<ConsumerGroupFixture>(Shared = SharedType.PerClass)]
+ public required ConsumerGroupFixture Fixture { get; init; }
+
+ [Test]
+ public async Task CreateConsumerGroup_HappyPath_Should_CreateConsumerGroup_Successfully()
+ {
+ var consumerGroup = await Fixture.Clients[protocol].CreateConsumerGroupAsync(_createConsumerGroupRequest);
+
+ consumerGroup.ShouldNotBeNull();
+ consumerGroup.Id.ShouldBe(_createConsumerGroupRequest.ConsumerGroupId);
+ consumerGroup.PartitionsCount.ShouldBe(Fixture.TopicRequest.PartitionsCount);
+ consumerGroup.MembersCount.ShouldBe(0);
+ consumerGroup.Name.ShouldBe(_createConsumerGroupRequest.Name);
+ }
+
+ [Test]
+ [DependsOn(nameof(CreateConsumerGroup_HappyPath_Should_CreateConsumerGroup_Successfully))]
+ public async Task CreateConsumerGroup_Should_Throw_InvalidResponse()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(() => Fixture.Clients[protocol].CreateConsumerGroupAsync(_createConsumerGroupRequest));
+ }
+
+ [Test]
+ [DependsOn(nameof(CreateConsumerGroup_Should_Throw_InvalidResponse))]
+ public async Task GetConsumerGroupById_Should_Return_ValidResponse()
+ {
+ var response = await Fixture.Clients[protocol].GetConsumerGroupByIdAsync(_createConsumerGroupRequest.StreamId,
+ _createConsumerGroupRequest.TopicId, Identifier.Numeric(1));
+
+ response.ShouldNotBeNull();
+ response.Id.ShouldBe(GroupId);
+ response.Name.ShouldBe(_createConsumerGroupRequest.Name);
+ response.PartitionsCount.ShouldBe(Fixture.TopicRequest.PartitionsCount);
+ response.MembersCount.ShouldBe(0);
+ }
+
+ [Test]
+ [DependsOn(nameof(GetConsumerGroupById_Should_Return_ValidResponse))]
+ public async Task GetConsumerGroups_Should_Return_ValidResponse()
+ {
+ IReadOnlyList<ConsumerGroupResponse> response = await Fixture.Clients[protocol].GetConsumerGroupsAsync(
+ _createConsumerGroupRequest.StreamId, _createConsumerGroupRequest.TopicId);
+
+ response.ShouldNotBeNull();
+ response.Count.ShouldBe(1);
+
+ var group = response.FirstOrDefault();
+ group.ShouldNotBeNull();
+ group.Id.ShouldBe(GroupId);
+ group.Name.ShouldBe(_createConsumerGroupRequest.Name);
+ group.PartitionsCount.ShouldBe(Fixture.TopicRequest.PartitionsCount);
+ group.MembersCount.ShouldBe(0);
+ }
+
+ [Test]
+ [SkipHttp]
+ [DependsOn(nameof(GetConsumerGroups_Should_Return_ValidResponse))]
+ public async Task JoinConsumerGroup_Tcp_Should_JoinConsumerGroup_Successfully()
+ {
+ await Should.NotThrowAsync(() => Fixture.Clients[protocol].JoinConsumerGroupAsync(new JoinConsumerGroupRequest
+ {
+ TopicId = _createConsumerGroupRequest.TopicId,
+ StreamId = _createConsumerGroupRequest.StreamId,
+ ConsumerGroupId = Identifier.Numeric(GroupId)
+ }));
+ }
+
+ [Test]
+ [SkipTcp]
+ [DependsOn(nameof(GetConsumerGroups_Should_Return_ValidResponse))]
+ public async Task JoinConsumerGroup_Http_Should_Throw_FeatureUnavailable()
+ {
+ await Should.ThrowAsync<FeatureUnavailableException>(() => Fixture.Clients[protocol].JoinConsumerGroupAsync(new JoinConsumerGroupRequest
+ {
+ TopicId = _createConsumerGroupRequest.TopicId,
+ StreamId = _createConsumerGroupRequest.StreamId,
+ ConsumerGroupId = Identifier.Numeric(GroupId)
+ }));
+ }
+
+ [Test]
+ [SkipHttp]
+ [DependsOn(nameof(JoinConsumerGroup_Tcp_Should_JoinConsumerGroup_Successfully))]
+ public async Task LeaveConsumerGroup_Tcp_Should_LeaveConsumerGroup_Successfully()
+ {
+ await Should.NotThrowAsync(() => Fixture.Clients[protocol].LeaveConsumerGroupAsync(new LeaveConsumerGroupRequest
+ {
+ TopicId = _createConsumerGroupRequest.TopicId,
+ StreamId = _createConsumerGroupRequest.StreamId,
+ ConsumerGroupId = Identifier.Numeric(GroupId)
+ }));
+ }
+
+ [Test]
+ [SkipTcp]
+ [DependsOn(nameof(JoinConsumerGroup_Http_Should_Throw_FeatureUnavailable))]
+ public async Task LeaveConsumerGroup_Http_Should_Throw_FeatureUnavailable()
+ {
+ await Should.ThrowAsync<FeatureUnavailableException>(() => Fixture.Clients[protocol].LeaveConsumerGroupAsync(new LeaveConsumerGroupRequest
+ {
+ TopicId = _createConsumerGroupRequest.TopicId,
+ StreamId = _createConsumerGroupRequest.StreamId,
+ ConsumerGroupId = Identifier.Numeric(GroupId)
+ }));
+ }
+
+ [Test]
+ [DependsOn(nameof(LeaveConsumerGroup_Http_Should_Throw_FeatureUnavailable))]
+ [DependsOn(nameof(LeaveConsumerGroup_Tcp_Should_LeaveConsumerGroup_Successfully))]
+ public async Task GetConsumerGroupById_WithMembers_Should_Return_ValidResponse()
+ {
+ var clientIds = new List<uint>();
+ var clients = new List<IIggyClient>();
+ for (var i = 0; i < 2; i++)
+ {
+ var client = Fixture.CreateClient(Protocol.Tcp, protocol);
+ clients.Add(client);
+ await client.LoginUser(new LoginUserRequest
+ {
+ Username = "iggy",
+ Password = "iggy"
+ });
+ var me = await client.GetMeAsync();
+ clientIds.Add(me!.ClientId);
+ await client.JoinConsumerGroupAsync(new JoinConsumerGroupRequest
+ {
+ ConsumerGroupId = Identifier.Numeric(_createConsumerGroupRequest.ConsumerGroupId),
+ StreamId = _createConsumerGroupRequest.StreamId,
+ TopicId = _createConsumerGroupRequest.TopicId
+ });
+ }
+
+ var response = await Fixture.Clients[protocol].GetConsumerGroupByIdAsync(_createConsumerGroupRequest.StreamId,
+ _createConsumerGroupRequest.TopicId, Identifier.Numeric(1));
+
+ response.ShouldNotBeNull();
+ response.Id.ShouldBe(GroupId);
+ response.PartitionsCount.ShouldBe(Fixture.TopicRequest.PartitionsCount);
+ response.MembersCount.ShouldBe(2);
+ response.Members.ShouldNotBeNull();
+ response.Members.Count.ShouldBe(2);
+ response.Members.ShouldAllBe(m => clientIds.Contains(m.Id));
+ response.Members.ShouldAllBe(x => x.PartitionsCount == 5);
+ response.Members.ShouldAllBe(x => x.Partitions.Count == 5);
+ }
+
+ [Test]
+ [DependsOn(nameof(GetConsumerGroupById_WithMembers_Should_Return_ValidResponse))]
+ public async Task DeleteConsumerGroup_Should_DeleteConsumerGroup_Successfully()
+ {
+ await Should.NotThrowAsync(() => Fixture.Clients[protocol].DeleteConsumerGroupAsync(new DeleteConsumerGroupRequest
+ {
+ TopicId = _createConsumerGroupRequest.TopicId,
+ StreamId = _createConsumerGroupRequest.StreamId,
+ ConsumerGroupId = Identifier.Numeric(GroupId)
+ }));
+ }
+
+ [Test]
+ [SkipHttp]
+ [DependsOn(nameof(DeleteConsumerGroup_Should_DeleteConsumerGroup_Successfully))]
+ public async Task JoinConsumerGroup_Tcp_Should_Throw_InvalidResponse()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(() => Fixture.Clients[protocol].JoinConsumerGroupAsync(new JoinConsumerGroupRequest
+ {
+ TopicId = _createConsumerGroupRequest.TopicId,
+ StreamId = _createConsumerGroupRequest.StreamId,
+ ConsumerGroupId = Identifier.Numeric(GroupId)
+ }));
+ }
+
+
+ [Test]
+ [DependsOn(nameof(JoinConsumerGroup_Tcp_Should_Throw_InvalidResponse))]
+ public async Task DeleteConsumerGroup_Should_Throw_InvalidResponse()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(() => Fixture.Clients[protocol].DeleteConsumerGroupAsync(new DeleteConsumerGroupRequest
+ {
+ TopicId = _createConsumerGroupRequest.TopicId,
+ StreamId = _createConsumerGroupRequest.StreamId,
+ ConsumerGroupId = Identifier.Numeric(GroupId)
+ }));
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/FetchMessagesTests.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/FetchMessagesTests.cs
new file mode 100644
index 00000000..b13032b3
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/FetchMessagesTests.cs
@@ -0,0 +1,185 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Enums;
+using Apache.Iggy.Exceptions;
+using Apache.Iggy.Headers;
+using Apache.Iggy.Kinds;
+using Apache.Iggy.Tests.Integrations.Fixtures;
+using Apache.Iggy.Tests.Integrations.Models;
+using Shouldly;
+
+namespace Apache.Iggy.Tests.Integrations;
+
+[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
+public class FetchMessagesTests(Protocol protocol)
+{
+ [ClassDataSource<FetchMessagesFixture>(Shared = SharedType.PerClass)]
+ public required FetchMessagesFixture Fixture { get; init; }
+
+
+ [Test]
+ public async Task PollMessagesTMessage_WithNoHeaders_Should_PollMessages_Successfully()
+ {
+ PolledMessages<DummyMessage> response = await Fixture.Clients[protocol].FetchMessagesAsync(new MessageFetchRequest
+ {
+ Count = 10,
+ AutoCommit = true,
+ Consumer = Consumer.New(1),
+ PartitionId = 1,
+ PollingStrategy = PollingStrategy.Next(),
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(Fixture.TopicDummyRequest.TopicId!.Value)
+ }, DummyMessage.DeserializeDummyMessage);
+
+ response.Messages.Count.ShouldBe(10);
+ response.PartitionId.ShouldBe(1);
+ response.CurrentOffset.ShouldBe(19u);
+ uint offset = 0;
+ foreach (MessageResponse<DummyMessage> responseMessage in response.Messages)
+ {
+ responseMessage.UserHeaders.ShouldBeNull();
+ responseMessage.Message.Text.ShouldNotBeNullOrEmpty();
+ responseMessage.Message.Text.ShouldContain("Dummy message");
+ responseMessage.Header.Checksum.ShouldNotBe(0u);
+ responseMessage.Header.Id.ShouldNotBe(0u);
+ responseMessage.Header.Offset.ShouldBe(offset++);
+ responseMessage.Header.PayloadLength.ShouldNotBe(0);
+ responseMessage.Header.UserHeadersLength.ShouldBe(0);
+ }
+ }
+
+ [Test]
+ [DependsOn(nameof(PollMessagesTMessage_WithNoHeaders_Should_PollMessages_Successfully))]
+ public async Task PollMessagesTMessage_Should_Throw_InvalidResponse()
+ {
+ var invalidFetchRequest = new MessageFetchRequest
+ {
+ Count = 10,
+ AutoCommit = true,
+ Consumer = Consumer.New(1),
+ PartitionId = 1,
+ PollingStrategy = PollingStrategy.Next(),
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(55)
+ };
+ await Should.ThrowAsync<InvalidResponseException>(() => Fixture.Clients[protocol].FetchMessagesAsync(invalidFetchRequest, DummyMessage.DeserializeDummyMessage));
+ }
+
+ [Test]
+ [DependsOn(nameof(PollMessagesTMessage_Should_Throw_InvalidResponse))]
+ public async Task PollMessages_WithNoHeaders_Should_PollMessages_Successfully()
+ {
+ var response = await Fixture.Clients[protocol].FetchMessagesAsync(new MessageFetchRequest
+ {
+ Count = 10,
+ AutoCommit = true,
+ Consumer = Consumer.New(1),
+ PartitionId = 1,
+ PollingStrategy = PollingStrategy.Next(),
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(Fixture.TopicRequest.TopicId!.Value)
+ });
+
+ response.Messages.Count.ShouldBe(10);
+ response.PartitionId.ShouldBe(1);
+ response.CurrentOffset.ShouldBe(19u);
+
+ foreach (var responseMessage in response.Messages)
+ {
+ responseMessage.UserHeaders.ShouldBeNull();
+ responseMessage.Payload.ShouldNotBeNull();
+ responseMessage.Payload.Length.ShouldBeGreaterThan(0);
+ }
+ }
+
+ [Test]
+ [DependsOn(nameof(PollMessages_WithNoHeaders_Should_PollMessages_Successfully))]
+ public async Task PollMessages_Should_Throw_InvalidResponse()
+ {
+ var invalidFetchRequest = new MessageFetchRequest
+ {
+ Count = 10,
+ AutoCommit = true,
+ Consumer = Consumer.New(1),
+ PartitionId = 1,
+ PollingStrategy = PollingStrategy.Next(),
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(55)
+ };
+
+ await Should.ThrowAsync<InvalidResponseException>(() => Fixture.Clients[protocol].FetchMessagesAsync(invalidFetchRequest));
+ }
+
+ [Test]
+ [DependsOn(nameof(PollMessages_Should_Throw_InvalidResponse))]
+ public async Task PollMessages_WithHeaders_Should_PollMessages_Successfully()
+ {
+ var headersMessageFetchRequest = new MessageFetchRequest
+ {
+ Count = 10,
+ AutoCommit = true,
+ Consumer = Consumer.New(1),
+ PartitionId = 1,
+ PollingStrategy = PollingStrategy.Next(),
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(Fixture.HeadersTopicRequest.TopicId!.Value)
+ };
+
+
+ var response = await Fixture.Clients[protocol].FetchMessagesAsync(headersMessageFetchRequest);
+ response.Messages.Count.ShouldBe(10);
+ response.PartitionId.ShouldBe(1);
+ response.CurrentOffset.ShouldBe(19u);
+ foreach (var responseMessage in response.Messages)
+ {
+ responseMessage.UserHeaders.ShouldNotBeNull();
+ responseMessage.UserHeaders.Count.ShouldBe(2);
+ responseMessage.UserHeaders[HeaderKey.New("header1")].ToString().ShouldBe("value1");
+ responseMessage.UserHeaders[HeaderKey.New("header2")].ToInt32().ShouldBeGreaterThan(0);
+ }
+ }
+
+ [Test]
+ [DependsOn(nameof(PollMessages_WithHeaders_Should_PollMessages_Successfully))]
+ public async Task PollMessagesTMessage_WithHeaders_Should_PollMessages_Successfully()
+ {
+ var headersMessageFetchRequest = new MessageFetchRequest
+ {
+ Count = 10,
+ AutoCommit = true,
+ Consumer = Consumer.New(1),
+ PartitionId = 1,
+ PollingStrategy = PollingStrategy.Next(),
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(Fixture.TopicDummyHeaderRequest.TopicId!.Value)
+ };
+
+ PolledMessages<DummyMessage> response = await Fixture.Clients[protocol].FetchMessagesAsync(headersMessageFetchRequest, DummyMessage.DeserializeDummyMessage);
+ response.Messages.Count.ShouldBe(10);
+ response.PartitionId.ShouldBe(1);
+ response.CurrentOffset.ShouldBe(19u);
+ foreach (MessageResponse<DummyMessage> responseMessage in response.Messages)
+ {
+ responseMessage.UserHeaders.ShouldNotBeNull();
+ responseMessage.UserHeaders.Count.ShouldBe(2);
+ responseMessage.UserHeaders[HeaderKey.New("header1")].ToString().ShouldBe("value1");
+ responseMessage.UserHeaders[HeaderKey.New("header2")].ToInt32().ShouldBeGreaterThan(0);
+ }
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/ConsumerGroupFixture.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/ConsumerGroupFixture.cs
new file mode 100644
index 00000000..1aba2447
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/ConsumerGroupFixture.cs
@@ -0,0 +1,38 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Tests.Integrations.Helpers;
+
+namespace Apache.Iggy.Tests.Integrations.Fixtures;
+
+public class ConsumerGroupFixture : IggyServerFixture
+{
+ public readonly StreamRequest StreamRequest = StreamFactory.CreateStream();
+ public readonly TopicRequest TopicRequest = TopicFactory.CreateTopic(partitionsCount: 10);
+
+ public override async Task InitializeAsync()
+ {
+ await base.InitializeAsync();
+
+ foreach (var client in Clients.Values)
+ {
+ await client.CreateStreamAsync(StreamRequest);
+ await client.CreateTopicAsync(Identifier.Numeric(StreamRequest.StreamId!.Value), TopicRequest);
+ }
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/FetchMessagesFixture.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/FetchMessagesFixture.cs
new file mode 100644
index 00000000..a67d70c6
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/FetchMessagesFixture.cs
@@ -0,0 +1,148 @@
+// // 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.Http;
+using Apache.Iggy.Headers;
+using Apache.Iggy.Kinds;
+using Apache.Iggy.Messages;
+using Apache.Iggy.Tests.Integrations.Helpers;
+using Apache.Iggy.Tests.Integrations.Models;
+
+namespace Apache.Iggy.Tests.Integrations.Fixtures;
+
+public class FetchMessagesFixture : IggyServerFixture
+{
+ public readonly TopicRequest HeadersTopicRequest = TopicFactory.CreateTopic(2);
+ public readonly int MessageCount = 20;
+ public readonly StreamRequest StreamRequest = StreamFactory.CreateStream();
+ public readonly TopicRequest TopicDummyHeaderRequest = TopicFactory.CreateTopic(4);
+ public readonly TopicRequest TopicDummyRequest = TopicFactory.CreateTopic(3);
+ public readonly TopicRequest TopicRequest = TopicFactory.CreateTopic();
+
+ public override async Task InitializeAsync()
+ {
+ await base.InitializeAsync();
+
+ var request = new MessageSendRequest
+ {
+ StreamId = Identifier.Numeric(StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(TopicRequest.TopicId!.Value),
+ Partitioning = Partitioning.None(),
+ Messages = CreateMessagesWithoutHeader(MessageCount)
+ };
+
+ var requestWithHeaders = new MessageSendRequest
+ {
+ StreamId = Identifier.Numeric(StreamRequest.StreamId.Value),
+ TopicId = Identifier.Numeric(HeadersTopicRequest.TopicId!.Value),
+ Partitioning = Partitioning.None(),
+ Messages = CreateMessagesWithHeader(MessageCount)
+ };
+
+ var requestDummyMessage = new MessageSendRequest<DummyMessage>
+ {
+ StreamId = Identifier.Numeric(StreamRequest.StreamId.Value),
+ TopicId = Identifier.Numeric(TopicDummyRequest.TopicId!.Value),
+ Partitioning = Partitioning.None(),
+ Messages = CreateDummyMessagesWithoutHeader(MessageCount)
+ };
+
+ var requestDummyMessageWithHeaders = new MessageSendRequest<DummyMessage>
+ {
+ StreamId = Identifier.Numeric(StreamRequest.StreamId.Value),
+ TopicId = Identifier.Numeric(TopicDummyHeaderRequest.TopicId!.Value),
+ Partitioning = Partitioning.None(),
+ Messages = CreateDummyMessagesWithoutHeader(MessageCount)
+ };
+
+ foreach (var client in Clients.Values)
+ {
+ await client.CreateStreamAsync(StreamRequest);
+ await client.CreateTopicAsync(Identifier.Numeric(StreamRequest.StreamId.Value), TopicRequest);
+ await client.CreateTopicAsync(Identifier.Numeric(StreamRequest.StreamId.Value), TopicDummyRequest);
+ await client.CreateTopicAsync(Identifier.Numeric(StreamRequest.StreamId.Value), HeadersTopicRequest);
+ await client.CreateTopicAsync(Identifier.Numeric(StreamRequest.StreamId.Value), TopicDummyHeaderRequest);
+
+ await client.SendMessagesAsync(request);
+ await client.SendMessagesAsync(requestDummyMessage, message => message.SerializeDummyMessage());
+ await client.SendMessagesAsync(requestWithHeaders);
+ await client.SendMessagesAsync(requestDummyMessageWithHeaders, message => message.SerializeDummyMessage(), headers: new Dictionary<HeaderKey, HeaderValue>
+ {
+ { HeaderKey.New("header1"), HeaderValue.FromString("value1") },
+ { HeaderKey.New("header2"), HeaderValue.FromInt32(14) }
+ });
+ }
+ }
+
+ private static List<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;
+ }
+
+ private static List<DummyMessage> CreateDummyMessagesWithoutHeader(int count)
+ {
+ var messages = new List<DummyMessage>();
+ for (var i = 0; i < count; i++)
+ {
+ messages.Add(new DummyMessage
+ {
+ Text = $"Dummy message {i}",
+ Id = i
+ });
+ }
+
+ return messages;
+ }
+
+ private static List<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.New("header1"), HeaderValue.FromString("value1") },
+ { HeaderKey.New("header2"), HeaderValue.FromInt32(14 + i) }
+ }));
+ }
+
+ return messages;
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/FlushMessageFixture.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/FlushMessageFixture.cs
new file mode 100644
index 00000000..36e3aa1c
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/FlushMessageFixture.cs
@@ -0,0 +1,54 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Kinds;
+using Apache.Iggy.Messages;
+using Apache.Iggy.Tests.Integrations.Helpers;
+
+namespace Apache.Iggy.Tests.Integrations.Fixtures;
+
+public class FlushMessageFixture : IggyServerFixture
+{
+ public readonly StreamRequest StreamRequest = StreamFactory.CreateStream();
+ public readonly TopicRequest TopicRequest = TopicFactory.CreateTopic();
+
+ public override async Task InitializeAsync()
+ {
+ await base.InitializeAsync();
+
+ foreach (var client in Clients.Values)
+ {
+ await client.CreateStreamAsync(StreamRequest);
+ await client.CreateTopicAsync(Identifier.Numeric(StreamRequest.StreamId!.Value), TopicRequest);
+
+ await client.SendMessagesAsync(new MessageSendRequest
+ {
+ Partitioning = Partitioning.None(),
+ StreamId = Identifier.Numeric(StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(TopicRequest.TopicId!.Value),
+ Messages = new List<Message>
+ {
+ new(Guid.NewGuid(), "Test message 1"u8.ToArray()),
+ new(Guid.NewGuid(), "Test message 2"u8.ToArray()),
+ new(Guid.NewGuid(), "Test message 3"u8.ToArray()),
+ new(Guid.NewGuid(), "Test message 4"u8.ToArray())
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/IggyServerFixture.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/IggyServerFixture.cs
new file mode 100644
index 00000000..562660ff
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/IggyServerFixture.cs
@@ -0,0 +1,145 @@
+// // 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 Apache.Iggy.Configuration;
+using Apache.Iggy.Contracts.Http.Auth;
+using Apache.Iggy.Enums;
+using Apache.Iggy.Factory;
+using Apache.Iggy.IggyClient;
+using DotNet.Testcontainers.Builders;
+using DotNet.Testcontainers.Containers;
+using Microsoft.Extensions.Logging.Abstractions;
+using TUnit.Core.Interfaces;
+
+namespace Apache.Iggy.Tests.Integrations.Fixtures;
+
+public class IggyServerFixture : IAsyncInitializer, IAsyncDisposable
+{
+ private readonly IContainer _httpContainer = new ContainerBuilder().WithImage("apache/iggy:edge")
+ // Container name is just to be used locally for debbuging effects
+ //.WithName($"SutIggyContainerHTTP")
+ .WithPortBinding(3000, true)
+ .WithPortBinding(8090, true)
+ .WithOutputConsumer(Consume.RedirectStdoutAndStderrToConsole())
+ .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(3000))
+ .WithName($"HTTP_{Guid.NewGuid()}")
+ //.WithEnvironment("IGGY_SYSTEM_LOGGING_LEVEL", "trace")
+ //.WithEnvironment("RUST_LOG", "trace")
+ .WithCleanUp(true)
+ .Build();
+
+ private readonly IContainer _tcpContainer = new ContainerBuilder().WithImage("apache/iggy:edge")
+ // Container name is just to be used locally for debbuging effects
+ //.WithName($"SutIggyContainerTCP")
+ .WithPortBinding(3000, true)
+ .WithPortBinding(8090, true)
+ .WithOutputConsumer(Consume.RedirectStdoutAndStderrToConsole())
+ .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(8090))
+ .WithName($"TCP_{Guid.NewGuid()}")
+ //.WithEnvironment("IGGY_SYSTEM_LOGGING_LEVEL", "trace")
+ //.WithEnvironment("RUST_LOG", "trace")
+ .WithCleanUp(true)
+ .Build();
+
+ public Dictionary<Protocol, IIggyClient> Clients { get; } = new();
+
+ private Action<MessageBatchingSettings> BatchingSettings { get; } = options =>
+ {
+ options.Enabled = false;
+ options.Interval = TimeSpan.FromMilliseconds(100);
+ options.MaxMessagesPerBatch = 1000;
+ options.MaxRequests = 4096;
+ };
+
+ private Action<MessagePollingSettings> PollingSettings { get; } = options =>
+ {
+ options.Interval = TimeSpan.FromMilliseconds(100);
+ options.StoreOffsetStrategy = StoreOffset.WhenMessagesAreReceived;
+ };
+
+ public async ValueTask DisposeAsync()
+ {
+ await Task.WhenAll(_tcpContainer.StopAsync(), _httpContainer.StopAsync());
+ }
+
+ public virtual async Task InitializeAsync()
+ {
+ await Task.WhenAll(_tcpContainer.StartAsync(), _httpContainer.StartAsync());
+
+ await CreateTcpClient();
+ await CreateHttpClient();
+ }
+
+ public async Task CreateTcpClient()
+ {
+ var tcpClient = CreateClient(Protocol.Tcp);
+
+ await tcpClient.LoginUser(new LoginUserRequest
+ {
+ Password = "iggy",
+ Username = "iggy"
+ });
+
+ Clients[Protocol.Tcp] = tcpClient;
+ }
+
+ public async Task CreateHttpClient()
+ {
+ var client = CreateClient(Protocol.Http);
+
+ await client.LoginUser(new LoginUserRequest
+ {
+ Password = "iggy",
+ Username = "iggy"
+ });
+
+ Clients[Protocol.Http] = client;
+ }
+
+ public IIggyClient CreateClient(Protocol protocol, Protocol? targetContainer = null)
+ {
+ var port = protocol == Protocol.Tcp
+ ? _tcpContainer.GetMappedPublicPort(8090)
+ : _httpContainer.GetMappedPublicPort(3000);
+
+ if (targetContainer != null
+ && targetContainer != protocol)
+ {
+ port = targetContainer == Protocol.Tcp
+ ? _tcpContainer.GetMappedPublicPort(3000)
+ : _httpContainer.GetMappedPublicPort(8090);
+ }
+
+ var address = protocol == Protocol.Tcp
+ ? $"127.0.0.1:{port}"
+ : $"http://127.0.0.1:{port}";
+
+ return MessageStreamFactory.CreateMessageStream(options =>
+ {
+ options.BaseAdress = address;
+ options.Protocol = protocol;
+ options.MessageBatchingSettings = BatchingSettings;
+ options.MessagePollingSettings = PollingSettings;
+ }, NullLoggerFactory.Instance);
+ }
+
+ public static IEnumerable<Func<Protocol>> ProtocolData()
+ {
+ yield return () => Protocol.Http;
+ yield return () => Protocol.Tcp;
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/OffsetFixtures.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/OffsetFixtures.cs
new file mode 100644
index 00000000..a1e4d866
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/OffsetFixtures.cs
@@ -0,0 +1,54 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Kinds;
+using Apache.Iggy.Messages;
+using Apache.Iggy.Tests.Integrations.Helpers;
+
+namespace Apache.Iggy.Tests.Integrations.Fixtures;
+
+public class OffsetFixtures : IggyServerFixture
+{
+ public readonly StreamRequest StreamRequest = StreamFactory.CreateStream();
+ public readonly TopicRequest TopicRequest = TopicFactory.CreateTopic();
+
+ public override async Task InitializeAsync()
+ {
+ await base.InitializeAsync();
+
+ foreach (var client in Clients.Values)
+ {
+ await client.CreateStreamAsync(StreamRequest);
+ await client.CreateTopicAsync(Identifier.Numeric(StreamRequest.StreamId!.Value), TopicRequest);
+
+ await client.SendMessagesAsync(new MessageSendRequest
+ {
+ Partitioning = Partitioning.None(),
+ StreamId = Identifier.Numeric(StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(TopicRequest.TopicId!.Value),
+ Messages = new List<Message>
+ {
+ new(Guid.NewGuid(), "Test message 1"u8.ToArray()),
+ new(Guid.NewGuid(), "Test message 2"u8.ToArray()),
+ new(Guid.NewGuid(), "Test message 3"u8.ToArray()),
+ new(Guid.NewGuid(), "Test message 4"u8.ToArray())
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/PartitionsFixture.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/PartitionsFixture.cs
new file mode 100644
index 00000000..85031a21
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/PartitionsFixture.cs
@@ -0,0 +1,38 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Tests.Integrations.Helpers;
+
+namespace Apache.Iggy.Tests.Integrations.Fixtures;
+
+public class PartitionsFixture : IggyServerFixture
+{
+ public readonly StreamRequest StreamRequest = StreamFactory.CreateStream();
+ public readonly TopicRequest TopicRequest = TopicFactory.CreateTopic();
+
+ public override async Task InitializeAsync()
+ {
+ await base.InitializeAsync();
+
+ foreach (var client in Clients.Values)
+ {
+ await client.CreateStreamAsync(StreamRequest);
+ await client.CreateTopicAsync(Identifier.Numeric(StreamRequest.StreamId!.Value), TopicRequest);
+ }
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/PollMessagesFixture.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/PollMessagesFixture.cs
new file mode 100644
index 00000000..31fb08c9
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/PollMessagesFixture.cs
@@ -0,0 +1,70 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Headers;
+using Apache.Iggy.Kinds;
+using Apache.Iggy.Tests.Integrations.Helpers;
+using Apache.Iggy.Tests.Integrations.Models;
+
+namespace Apache.Iggy.Tests.Integrations.Fixtures;
+
+public class PollMessagesFixture : IggyServerFixture
+{
+ public readonly int MessageCount = 10;
+ public readonly StreamRequest StreamRequest = StreamFactory.CreateStream();
+ public readonly TopicRequest TopicRequest = TopicFactory.CreateTopic();
+
+ public override async Task InitializeAsync()
+ {
+ await base.InitializeAsync();
+
+ foreach (var client in Clients.Values)
+ {
+ await client.CreateStreamAsync(StreamRequest);
+ await client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
+ await client.SendMessagesAsync(new MessageSendRequest<DummyMessage>
+ {
+ Messages = CreateDummyMessagesWithoutHeader(MessageCount),
+ Partitioning = Partitioning.None(),
+ StreamId = Identifier.Numeric(StreamRequest.StreamId.Value),
+ TopicId = Identifier.Numeric(TopicRequest.TopicId!.Value)
+ },
+ message => message.SerializeDummyMessage(),
+ headers: new Dictionary<HeaderKey, HeaderValue>
+ {
+ { HeaderKey.New("header1"), HeaderValue.FromString("value1") },
+ { HeaderKey.New("header2"), HeaderValue.FromInt32(14) }
+ });
+ }
+ }
+
+ private static List<DummyMessage> CreateDummyMessagesWithoutHeader(int count)
+ {
+ var messages = new List<DummyMessage>();
+ for (var i = 0; i < count; i++)
+ {
+ messages.Add(new DummyMessage
+ {
+ Text = $"Dummy message {i}",
+ Id = i
+ });
+ }
+
+ return messages;
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/SendMessageFixture.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/SendMessageFixture.cs
new file mode 100644
index 00000000..3c1e70f4
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/SendMessageFixture.cs
@@ -0,0 +1,38 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Tests.Integrations.Helpers;
+
+namespace Apache.Iggy.Tests.Integrations.Fixtures;
+
+public class SendMessageFixture : IggyServerFixture
+{
+ public readonly StreamRequest StreamRequest = StreamFactory.CreateStream();
+ public readonly TopicRequest TopicRequest = TopicFactory.CreateTopic();
+
+ public override async Task InitializeAsync()
+ {
+ await base.InitializeAsync();
+
+ foreach (var client in Clients.Values)
+ {
+ await client.CreateStreamAsync(StreamRequest);
+ await client.CreateTopicAsync(Identifier.Numeric(StreamRequest.StreamId!.Value), TopicRequest);
+ }
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/SystemFixture.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/SystemFixture.cs
new file mode 100644
index 00000000..6bc96573
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Fixtures/SystemFixture.cs
@@ -0,0 +1,89 @@
+// // 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 Apache.Iggy.Contracts.Http.Auth;
+using Apache.Iggy.Enums;
+using Apache.Iggy.IggyClient;
+
+namespace Apache.Iggy.Tests.Integrations.Fixtures;
+
+public class SystemFixture : IggyServerFixture
+{
+ public readonly int TotalClientsCount = 10;
+
+ private List<IIggyClient> AdditionalClients { get; } = new();
+
+ public override async Task InitializeAsync()
+ {
+ await base.InitializeAsync();
+
+ await CreateClientsAsync();
+ }
+
+ private async Task CreateClientsAsync()
+ {
+ for (var i = 0; i < TotalClientsCount; i++)
+ {
+ await Clients[Protocol.Http].CreateUser(new CreateUserRequest
+ {
+ Username = $"iggy{i}",
+ Password = "iggy",
+ Status = UserStatus.Active
+ });
+
+ var client = CreateClient(Protocol.Tcp, Protocol.Http);
+ AdditionalClients.Add(client);
+ var login = await client.LoginUser(new LoginUserRequest
+ {
+ Password = "iggy",
+ Username = $"iggy{i}"
+ });
+
+ if (login!.UserId == 0)
+ {
+ throw new Exception("Failed to login user 'iggy'.");
+ }
+
+ await client.PingAsync();
+ }
+
+ // One client less for tcp due to a default client
+ for (var i = 0; i < TotalClientsCount - 1; i++)
+ {
+ await Clients[Protocol.Tcp].CreateUser(new CreateUserRequest
+ {
+ Username = $"iggy{i}",
+ Password = "iggy",
+ Status = UserStatus.Active
+ });
+
+ var client = CreateClient(Protocol.Tcp, Protocol.Tcp);
+ AdditionalClients.Add(client);
+ var login = await client.LoginUser(new LoginUserRequest
+ {
+ Password = "iggy",
+ Username = $"iggy{i}"
+ });
+ if (login!.UserId == 0)
+ {
+ throw new Exception("Failed to login user 'iggy'.");
+ }
+
+ await client.PingAsync();
+ }
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/FlushMessagesTests.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/FlushMessagesTests.cs
new file mode 100644
index 00000000..e5d33800
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/FlushMessagesTests.cs
@@ -0,0 +1,69 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Enums;
+using Apache.Iggy.Exceptions;
+using Apache.Iggy.Tests.Integrations.Fixtures;
+using Shouldly;
+
+namespace Apache.Iggy.Tests.Integrations;
+
+[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
+public class FlushMessagesTests(Protocol protocol)
+{
+ [ClassDataSource<FlushMessageFixture>(Shared = SharedType.PerClass)]
+ public required FlushMessageFixture Fixture { get; init; }
+
+ [Test]
+ public async Task FlushUnsavedBuffer_WithFsync_Should_Flush_Successfully()
+ {
+ await Should.NotThrowAsync(() => Fixture.Clients[protocol].FlushUnsavedBufferAsync(new FlushUnsavedBufferRequest
+ {
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(Fixture.TopicRequest.TopicId!.Value),
+ PartitionId = 1,
+ Fsync = true
+ }));
+ }
+
+ [Test]
+ [DependsOn(nameof(FlushUnsavedBuffer_WithFsync_Should_Flush_Successfully))]
+ public async Task FlushUnsavedBuffer_WithOutFsync_Should_Flush_Successfully()
+ {
+ await Should.NotThrowAsync(() => Fixture.Clients[protocol].FlushUnsavedBufferAsync(new FlushUnsavedBufferRequest
+ {
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(Fixture.TopicRequest.TopicId!.Value),
+ PartitionId = 1,
+ Fsync = false
+ }));
+ }
+
+ [Test]
+ [DependsOn(nameof(FlushUnsavedBuffer_WithOutFsync_Should_Flush_Successfully))]
+ public async Task FlushUnsavedBuffer_Should_Throw_WhenStream_DoesNotExist()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(() => Fixture.Clients[protocol].FlushUnsavedBufferAsync(new FlushUnsavedBufferRequest
+ {
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(55),
+ PartitionId = 1,
+ Fsync = true
+ }));
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Helpers/StreamFactory.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Helpers/StreamFactory.cs
new file mode 100644
index 00000000..a89edda1
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Helpers/StreamFactory.cs
@@ -0,0 +1,32 @@
+// // 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 Apache.Iggy.Contracts.Http;
+
+namespace Apache.Iggy.Tests.Integrations.Helpers;
+
+public static class StreamFactory
+{
+ public static StreamRequest CreateStream(int streamId = 1)
+ {
+ return new StreamRequest
+ {
+ StreamId = streamId,
+ Name = "TestStream"
+ };
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Helpers/TopicFactory.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Helpers/TopicFactory.cs
new file mode 100644
index 00000000..3e4f0777
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Helpers/TopicFactory.cs
@@ -0,0 +1,34 @@
+// // 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 Apache.Iggy.Contracts.Http;
+
+namespace Apache.Iggy.Tests.Integrations.Helpers;
+
+public static class TopicFactory
+{
+ public static TopicRequest CreateTopic(int topicId = 1, int partitionsCount = 1, ulong messageExpiry = 0)
+ {
+ return new TopicRequest
+ {
+ TopicId = topicId,
+ Name = $"TestTopic {topicId}",
+ PartitionsCount = partitionsCount,
+ MessageExpiry = messageExpiry
+ };
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Iggy_SDK.Tests.Integration.csproj b/foreign/csharp/Iggy_SDK.Tests.Integration/Iggy_SDK.Tests.Integration.csproj
new file mode 100644
index 00000000..1fc29287
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Iggy_SDK.Tests.Integration.csproj
@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <Nullable>enable</Nullable>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net8.0</TargetFramework>
+ <AssemblyName>Apache.Iggy.Tests.Integrations</AssemblyName>
+ <RootNamespace>Apache.Iggy.Tests.Integrations</RootNamespace>
+ <IsTestingPlatformApplication>true</IsTestingPlatformApplication>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="coverlet.collector">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+ </PackageReference>
+ <PackageReference Include="Microsoft.Testing.Extensions.CodeCoverage" />
+ <PackageReference Include="Microsoft.Testing.Extensions.TrxReport" />
+ <PackageReference Include="Shouldly" />
+ <PackageReference Include="Testcontainers" />
+ <PackageReference Include="TUnit" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Iggy_SDK\Iggy_SDK.csproj" />
+ </ItemGroup>
+
+</Project>
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/Models/DummyMessage.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/Models/DummyMessage.cs
new file mode 100644
index 00000000..4db4bb4f
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/Models/DummyMessage.cs
@@ -0,0 +1,45 @@
+// // 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.Buffers.Binary;
+using System.Text;
+
+namespace Apache.Iggy.Tests.Integrations.Models;
+
+public sealed class DummyMessage
+{
+ public int Id { get; set; }
+ public required string Text { get; set; }
+
+ internal static Func<byte[], DummyMessage> DeserializeDummyMessage
+ => bytes =>
+ {
+ var id = BinaryPrimitives.ReadInt32LittleEndian(bytes.AsSpan()[..4]);
+ var textLength = BinaryPrimitives.ReadInt32LittleEndian(bytes.AsSpan()[4..8]);
+ var text = Encoding.UTF8.GetString(bytes.AsSpan()[8..(8 + textLength)]);
+ return new DummyMessage { Id = id, Text = text };
+ };
+
+ internal byte[] SerializeDummyMessage()
+ {
+ var bytes = new byte[4 + 4 + Text.Length];
+ BinaryPrimitives.WriteInt32LittleEndian(bytes.AsSpan()[..4], Id);
+ BinaryPrimitives.WriteInt32LittleEndian(bytes.AsSpan()[4..8], Text.Length);
+ Encoding.UTF8.GetBytes(Text).CopyTo(bytes.AsSpan()[8..]);
+ return bytes;
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/OffsetTests.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/OffsetTests.cs
new file mode 100644
index 00000000..614efcfd
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/OffsetTests.cs
@@ -0,0 +1,104 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Enums;
+using Apache.Iggy.Kinds;
+using Apache.Iggy.Tests.Integrations.Fixtures;
+using Shouldly;
+
+namespace Apache.Iggy.Tests.Integrations;
+
+[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
+public class OffsetTests(Protocol protocol)
+{
+ private const ulong SetOffset = 2;
+
+ [ClassDataSource<OffsetFixtures>(Shared = SharedType.PerClass)]
+ public required OffsetFixtures Fixture { get; init; }
+
+ [Test]
+ public async Task StoreOffset_IndividualConsumer_Should_StoreOffset_Successfully()
+ {
+ await Fixture.Clients[protocol].StoreOffsetAsync(new StoreOffsetRequest
+ {
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(1),
+ PartitionId = 1,
+ Offset = SetOffset,
+ Consumer = Consumer.New(1)
+ });
+ }
+
+ [Test]
+ [DependsOn(nameof(StoreOffset_IndividualConsumer_Should_StoreOffset_Successfully))]
+ public async Task GetOffset_IndividualConsumer_Should_GetOffset_Successfully()
+ {
+ var offset = await Fixture.Clients[protocol].GetOffsetAsync(new OffsetRequest
+ {
+ Consumer = Consumer.New(1),
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(1),
+ PartitionId = 1
+ });
+
+ offset.ShouldNotBeNull();
+ offset.StoredOffset.ShouldBe(SetOffset);
+ offset.PartitionId.ShouldBe(1);
+ offset.CurrentOffset.ShouldBe(3u);
+ }
+
+ [Test]
+ [DependsOn(nameof(GetOffset_IndividualConsumer_Should_GetOffset_Successfully))]
+ public async Task StoreOffset_ConsumerGroup_Should_StoreOffset_Successfully()
+ {
+ await Fixture.Clients[protocol].CreateConsumerGroupAsync(new CreateConsumerGroupRequest
+ {
+ Name = "test_consumer_group",
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(1),
+ ConsumerGroupId = 1
+ });
+
+ await Fixture.Clients[protocol].StoreOffsetAsync(new StoreOffsetRequest
+ {
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(1),
+ PartitionId = 1,
+ Offset = SetOffset,
+ Consumer = Consumer.Group(1)
+ });
+ }
+
+ [Test]
+ [DependsOn(nameof(StoreOffset_ConsumerGroup_Should_StoreOffset_Successfully))]
+ public async Task GetOffset_ConsumerGroup_Should_GetOffset_Successfully()
+ {
+ var offset = await Fixture.Clients[protocol].GetOffsetAsync(new OffsetRequest
+ {
+ Consumer = Consumer.Group(1),
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(1),
+ PartitionId = 1
+ });
+
+ offset.ShouldNotBeNull();
+ offset.StoredOffset.ShouldBe(SetOffset);
+ offset.PartitionId.ShouldBe(1);
+ offset.CurrentOffset.ShouldBe(3u);
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/PartitionsTests.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/PartitionsTests.cs
new file mode 100644
index 00000000..e5b04ec9
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/PartitionsTests.cs
@@ -0,0 +1,88 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Enums;
+using Apache.Iggy.Exceptions;
+using Apache.Iggy.Tests.Integrations.Fixtures;
+using Shouldly;
+
+namespace Apache.Iggy.Tests.Integrations;
+
+[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
+public class PartitionsTests(Protocol protocol)
+{
+ [ClassDataSource<PartitionsFixture>(Shared = SharedType.PerClass)]
+ public required PartitionsFixture Fixture { get; init; }
+
+ [Test]
+ public async Task CreatePartition_HappyPath_Should_CreatePartition_Successfully()
+ {
+ await Should.NotThrowAsync(() => Fixture.Clients[protocol].CreatePartitionsAsync(new CreatePartitionsRequest
+ {
+ PartitionsCount = 3,
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(Fixture.TopicRequest.TopicId!.Value)
+ }));
+
+ var response = await Fixture.Clients[protocol].GetTopicByIdAsync(Identifier.Numeric(1), Identifier.Numeric(1));
+ response.ShouldNotBeNull();
+ response.PartitionsCount.ShouldBe(4);
+ }
+
+ [Test]
+ [DependsOn(nameof(CreatePartition_HappyPath_Should_CreatePartition_Successfully))]
+ public async Task DeletePartition_Should_DeletePartition_Successfully()
+ {
+ await Should.NotThrowAsync(() => Fixture.Clients[protocol].DeletePartitionsAsync(new DeletePartitionsRequest
+ {
+ PartitionsCount = 1,
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(Fixture.TopicRequest.TopicId!.Value)
+ }));
+
+ var response = await Fixture.Clients[protocol].GetTopicByIdAsync(Identifier.Numeric(1), Identifier.Numeric(1));
+ response.ShouldNotBeNull();
+ response.PartitionsCount.ShouldBe(3);
+ }
+
+ [Test]
+ [DependsOn(nameof(DeletePartition_Should_DeletePartition_Successfully))]
+ public async Task DeletePartition_Should_Throw_WhenTopic_DoesNotExist()
+ {
+ await Fixture.Clients[protocol].DeleteTopicAsync(Identifier.Numeric(1), Identifier.Numeric(1));
+ await Should.ThrowAsync<InvalidResponseException>(() => Fixture.Clients[protocol].DeletePartitionsAsync(new DeletePartitionsRequest
+ {
+ PartitionsCount = 1,
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(Fixture.TopicRequest.TopicId!.Value)
+ }));
+ }
+
+ [Test]
+ [DependsOn(nameof(DeletePartition_Should_Throw_WhenTopic_DoesNotExist))]
+ public async Task DeletePartition_Should_Throw_WhenStream_DoesNotExist()
+ {
+ await Fixture.Clients[protocol].DeleteStreamAsync(Identifier.Numeric(1));
+ await Should.ThrowAsync<InvalidResponseException>(() => Fixture.Clients[protocol].DeletePartitionsAsync(new DeletePartitionsRequest
+ {
+ PartitionsCount = 1,
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(Fixture.TopicRequest.TopicId!.Value)
+ }));
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/PersonalAccessTokenTests.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/PersonalAccessTokenTests.cs
new file mode 100644
index 00000000..eb14ea2d
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/PersonalAccessTokenTests.cs
@@ -0,0 +1,98 @@
+// // 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 Apache.Iggy.Contracts.Http.Auth;
+using Apache.Iggy.Enums;
+using Apache.Iggy.Exceptions;
+using Apache.Iggy.Tests.Integrations.Fixtures;
+using Shouldly;
+
+namespace Apache.Iggy.Tests.Integrations;
+
+[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
+public class PersonalAccessTokenTests(Protocol protocol)
+{
+ private static readonly CreatePersonalAccessTokenRequest CreatePersonalAccessTokenRequest = new()
+ {
+ Name = "test-pat",
+ Expiry = 100_000_000
+ };
+
+ [ClassDataSource<IggyServerFixture>(Shared = SharedType.PerClass)]
+ public required IggyServerFixture Fixture { get; init; }
+
+
+ [Test]
+ public async Task CreatePersonalAccessToken_HappyPath_Should_CreatePersonalAccessToken_Successfully()
+ {
+ var result = await Fixture.Clients[protocol].CreatePersonalAccessTokenAsync(CreatePersonalAccessTokenRequest);
+
+ result.ShouldNotBeNull();
+ result.Token.ShouldNotBeNullOrEmpty();
+ }
+
+ [Test]
+ [DependsOn(nameof(CreatePersonalAccessToken_HappyPath_Should_CreatePersonalAccessToken_Successfully))]
+ public async Task CreatePersonalAccessToken_Duplicate_Should_Throw_InvalidResponse()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(() => Fixture.Clients[protocol].CreatePersonalAccessTokenAsync(CreatePersonalAccessTokenRequest));
+ }
+
+ [Test]
+ [DependsOn(nameof(CreatePersonalAccessToken_Duplicate_Should_Throw_InvalidResponse))]
+ public async Task GetPersonalAccessTokens_Should_ReturnValidResponse()
+ {
+ IReadOnlyList<PersonalAccessTokenResponse> response = await Fixture.Clients[protocol].GetPersonalAccessTokensAsync();
+
+ response.ShouldNotBeNull();
+ response.Count.ShouldBe(1);
+ response[0].Name.ShouldBe(CreatePersonalAccessTokenRequest.Name);
+ var tokenExpiryDateTimeOffset = DateTimeOffset.UtcNow.AddMicroseconds((double)CreatePersonalAccessTokenRequest.Expiry!);
+ response[0].ExpiryAt!.Value.ToUniversalTime().ShouldBe(tokenExpiryDateTimeOffset, TimeSpan.FromMinutes(1));
+ }
+
+ [Test]
+ [DependsOn(nameof(GetPersonalAccessTokens_Should_ReturnValidResponse))]
+ public async Task LoginWithPersonalAccessToken_Should_Be_Successfully()
+ {
+ var response = await Fixture.Clients[protocol].CreatePersonalAccessTokenAsync(new CreatePersonalAccessTokenRequest
+ {
+ Name = "test-pat-login",
+ Expiry = 100_000_000
+ });
+
+ var client = Fixture.CreateClient(protocol);
+
+ var authResponse = await client.LoginWithPersonalAccessToken(new LoginWithPersonalAccessToken
+ {
+ Token = response!.Token
+ });
+
+ authResponse.ShouldNotBeNull();
+ authResponse.UserId.ShouldBe(1);
+ }
+
+ [Test]
+ [DependsOn(nameof(LoginWithPersonalAccessToken_Should_Be_Successfully))]
+ public async Task DeletePersonalAccessToken_Should_DeletePersonalAccessToken_Successfully()
+ {
+ await Should.NotThrowAsync(() => Fixture.Clients[protocol].DeletePersonalAccessTokenAsync(new DeletePersonalAccessTokenRequest
+ {
+ Name = CreatePersonalAccessTokenRequest.Name
+ }));
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/PollMessagesTests.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/PollMessagesTests.cs
new file mode 100644
index 00000000..91064a41
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/PollMessagesTests.cs
@@ -0,0 +1,60 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Enums;
+using Apache.Iggy.Kinds;
+using Apache.Iggy.Tests.Integrations.Fixtures;
+using Apache.Iggy.Tests.Integrations.Models;
+using Shouldly;
+
+namespace Apache.Iggy.Tests.Integrations;
+
+[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
+public class PollMessagesTests(Protocol protocol)
+{
+ [ClassDataSource<PollMessagesFixture>(Shared = SharedType.PerClass)]
+ public required PollMessagesFixture Fixture { get; init; }
+
+ [Test]
+ [Timeout(60_000)]
+ public async Task PollMessagesTMessage_Should_PollMessages_Successfully(CancellationToken token)
+ {
+ var messageCount = 0;
+ await foreach (MessageResponse<DummyMessage> msgResponse in Fixture.Clients[protocol].PollMessagesAsync(new PollMessagesRequest
+ {
+ Consumer = Consumer.New(1),
+ Count = 10,
+ PartitionId = 1,
+ PollingStrategy = PollingStrategy.Next(),
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(Fixture.TopicRequest.TopicId!.Value)
+ }, DummyMessage.DeserializeDummyMessage, token: token))
+ {
+ msgResponse.UserHeaders.ShouldNotBeNull();
+ msgResponse.UserHeaders.Count.ShouldBe(2);
+ msgResponse.Message.Text.ShouldContain("Dummy message");
+ messageCount++;
+ if (messageCount == Fixture.MessageCount)
+ {
+ break;
+ }
+ }
+
+ messageCount.ShouldBe(Fixture.MessageCount);
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/SendMessagesTests.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/SendMessagesTests.cs
new file mode 100644
index 00000000..3b4ee9e0
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/SendMessagesTests.cs
@@ -0,0 +1,118 @@
+// // 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.Http;
+using Apache.Iggy.Enums;
+using Apache.Iggy.Exceptions;
+using Apache.Iggy.Headers;
+using Apache.Iggy.Messages;
+using Apache.Iggy.Tests.Integrations.Fixtures;
+using Shouldly;
+using Partitioning = Apache.Iggy.Kinds.Partitioning;
+
+namespace Apache.Iggy.Tests.Integrations;
+
+[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
+public class SendMessagesTests(Protocol protocol)
+{
+ private static Message[] _messagesWithoutHeaders = [];
+ private static Message[] _messagesWithHeaders = [];
+
+ [ClassDataSource<SendMessageFixture>(Shared = SharedType.PerClass)]
+ public required SendMessageFixture Fixture { get; set; }
+
+ [Before(Class)]
+ public static Task Before()
+ {
+ var dummyJson = """
+ {
+ "userId": 1,
+ "id": 1,
+ "title": "delete",
+ "completed": false
+ }
+ """;
+ _messagesWithoutHeaders = [new Message(Guid.NewGuid(), Encoding.UTF8.GetBytes(dummyJson)), new Message(Guid.NewGuid(), Encoding.UTF8.GetBytes(dummyJson))];
+ _messagesWithHeaders =
+ [
+ new Message(Guid.NewGuid(), Encoding.UTF8.GetBytes(dummyJson), new Dictionary<HeaderKey, HeaderValue>
+ {
+ { HeaderKey.New("header1"), HeaderValue.FromString("value1") },
+ { HeaderKey.New("header2"), HeaderValue.FromInt32(444) }
+ }),
+ new Message(Guid.NewGuid(), Encoding.UTF8.GetBytes(dummyJson), new Dictionary<HeaderKey, HeaderValue>
+ {
+ { HeaderKey.New("header1"), HeaderValue.FromString("value1") },
+ { HeaderKey.New("header2"), HeaderValue.FromInt32(444) }
+ })
+ ];
+
+ return Task.CompletedTask;
+ }
+
+ [Test]
+ public async Task SendMessages_NoHeaders_Should_SendMessages_Successfully()
+ {
+ await Should.NotThrowAsync(() => Fixture.Clients[protocol].SendMessagesAsync(new MessageSendRequest
+ {
+ Messages = _messagesWithoutHeaders,
+ Partitioning = Partitioning.None(),
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(Fixture.TopicRequest.TopicId!.Value)
+ }));
+ }
+
+ [Test]
+ [DependsOn(nameof(SendMessages_NoHeaders_Should_SendMessages_Successfully))]
+ public async Task SendMessages_NoHeaders_Should_Throw_InvalidResponse()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(() => Fixture.Clients[protocol].SendMessagesAsync(new MessageSendRequest
+ {
+ Messages = _messagesWithoutHeaders,
+ Partitioning = Partitioning.None(),
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(69)
+ }));
+ }
+
+ [Test]
+ [DependsOn(nameof(SendMessages_NoHeaders_Should_Throw_InvalidResponse))]
+ public async Task SendMessages_WithHeaders_Should_SendMessages_Successfully()
+ {
+ await Should.NotThrowAsync(() => Fixture.Clients[protocol].SendMessagesAsync(new MessageSendRequest
+ {
+ Messages = _messagesWithHeaders,
+ Partitioning = Partitioning.None(),
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(Fixture.TopicRequest.TopicId!.Value)
+ }));
+ }
+
+ [Test]
+ [DependsOn(nameof(SendMessages_WithHeaders_Should_SendMessages_Successfully))]
+ public async Task SendMessages_WithHeaders_Should_Throw_InvalidResponse()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(() => Fixture.Clients[protocol].SendMessagesAsync(new MessageSendRequest
+ {
+ Messages = _messagesWithHeaders,
+ Partitioning = Partitioning.None(),
+ StreamId = Identifier.Numeric(Fixture.StreamRequest.StreamId!.Value),
+ TopicId = Identifier.Numeric(69)
+ }));
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/StreamsTests.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/StreamsTests.cs
new file mode 100644
index 00000000..a3f7e643
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/StreamsTests.cs
@@ -0,0 +1,209 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Enums;
+using Apache.Iggy.Exceptions;
+using Apache.Iggy.Messages;
+using Apache.Iggy.Tests.Integrations.Fixtures;
+using Apache.Iggy.Tests.Integrations.Helpers;
+using Shouldly;
+using Partitioning = Apache.Iggy.Kinds.Partitioning;
+
+namespace Apache.Iggy.Tests.Integrations;
+
+[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
+public class StreamsTests(Protocol protocol)
+{
+ private static readonly StreamRequest StreamRequest = new()
+ {
+ Name = "test-stream",
+ StreamId = 1
+ };
+
+ private static readonly UpdateStreamRequest UpdateStreamRequest = new()
+ {
+ Name = "updated-test-stream"
+ };
+
+ [ClassDataSource<IggyServerFixture>(Shared = SharedType.PerClass)]
+ public required IggyServerFixture Fixture { get; init; }
+
+ [Test]
+ public async Task CreateStream_HappyPath_Should_CreateStream_Successfully()
+ {
+ var response = await Fixture.Clients[protocol].CreateStreamAsync(StreamRequest);
+
+ response.ShouldNotBeNull();
+ response.Id.ShouldBe(StreamRequest.StreamId!.Value);
+ response.Name.ShouldBe(StreamRequest.Name);
+ response.Size.ShouldBe(0u);
+ response.CreatedAt.UtcDateTime.ShouldBe(DateTimeOffset.UtcNow.UtcDateTime, TimeSpan.FromSeconds(20));
+ response.MessagesCount.ShouldBe(0u);
+ response.TopicsCount.ShouldBe(0);
+ response.Topics.ShouldBeEmpty();
+ }
+
+ [Test]
+ [DependsOn(nameof(CreateStream_HappyPath_Should_CreateStream_Successfully))]
+ public async Task CreateStream_Duplicate_Should_Throw_InvalidResponse()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(Fixture.Clients[protocol].CreateStreamAsync(StreamRequest));
+ }
+
+ [Test]
+ [DependsOn(nameof(CreateStream_Duplicate_Should_Throw_InvalidResponse))]
+ public async Task GetStreams_Should_ReturnValidResponse()
+ {
+ var secondStreamRequest = StreamFactory.CreateStream(2);
+ await Fixture.Clients[protocol].CreateStreamAsync(secondStreamRequest);
+
+ IReadOnlyList<StreamResponse> response = await Fixture.Clients[protocol].GetStreamsAsync();
+
+ response.ShouldNotBeNull();
+ response.Count.ShouldBe(2);
+ response.ShouldContain(x => x.Id == StreamRequest.StreamId!.Value);
+ response.ShouldContain(x => x.Id == secondStreamRequest.StreamId!.Value);
+ }
+
+ [Test]
+ [DependsOn(nameof(GetStreams_Should_ReturnValidResponse))]
+ public async Task GetStreamById_Should_ReturnValidResponse()
+ {
+ var response = await Fixture.Clients[protocol].GetStreamByIdAsync(Identifier.Numeric(StreamRequest.StreamId!.Value));
+ response.ShouldNotBeNull();
+ response.Id.ShouldBe(StreamRequest.StreamId.Value);
+ response.Name.ShouldBe(StreamRequest.Name);
+ response.Size.ShouldBe(0u);
+ response.CreatedAt.UtcDateTime.ShouldBe(DateTimeOffset.UtcNow.UtcDateTime, TimeSpan.FromSeconds(20));
+ response.MessagesCount.ShouldBe(0u);
+ response.TopicsCount.ShouldBe(0);
+ response.Topics.ShouldBeEmpty();
+ }
+
+ [Test]
+ [DependsOn(nameof(GetStreamById_Should_ReturnValidResponse))]
+ public async Task GetStreamById_WithTopics_Should_ReturnValidResponse()
+ {
+ var topicRequest1 = TopicFactory.CreateTopic(messageExpiry: 100_000);
+ var topicRequest2 = TopicFactory.CreateTopic(2, messageExpiry: 100_000);
+
+ await Fixture.Clients[protocol].CreateTopicAsync(Identifier.Numeric(StreamRequest.StreamId!.Value), topicRequest1);
+ await Fixture.Clients[protocol].CreateTopicAsync(Identifier.Numeric(StreamRequest.StreamId!.Value), topicRequest2);
+
+
+ await Fixture.Clients[protocol].SendMessagesAsync(new MessageSendRequest
+ {
+ Partitioning = Partitioning.None(),
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(topicRequest1.TopicId!.Value),
+ Messages = new List<Message>
+ {
+ new(Guid.NewGuid(), "Test message 1"u8.ToArray()),
+ new(Guid.NewGuid(), "Test message 2"u8.ToArray()),
+ new(Guid.NewGuid(), "Test message 3"u8.ToArray())
+ }
+ });
+
+ await Fixture.Clients[protocol].SendMessagesAsync(new MessageSendRequest
+ {
+ Partitioning = Partitioning.None(),
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(2),
+ Messages = new List<Message>
+ {
+ new(Guid.NewGuid(), "Test message 4"u8.ToArray()),
+ new(Guid.NewGuid(), "Test message 5"u8.ToArray()),
+ new(Guid.NewGuid(), "Test message 6"u8.ToArray()),
+ new(Guid.NewGuid(), "Test message 7"u8.ToArray())
+ }
+ });
+
+ var response = await Fixture.Clients[protocol].GetStreamByIdAsync(Identifier.Numeric(StreamRequest.StreamId!.Value));
+ response.ShouldNotBeNull();
+ response.Id.ShouldBe(StreamRequest.StreamId.Value);
+ response.Name.ShouldBe(StreamRequest.Name);
+ response.Size.ShouldBe(490u);
+ response.CreatedAt.UtcDateTime.ShouldBe(DateTimeOffset.UtcNow.UtcDateTime, TimeSpan.FromSeconds(20));
+ response.MessagesCount.ShouldBe(7u);
+ response.TopicsCount.ShouldBe(2);
+ response.Topics.Count().ShouldBe(2);
+
+ var topic = response.Topics.First(x => x.Id == topicRequest1.TopicId!.Value);
+ topic.Id.ShouldBe(topicRequest1.TopicId!.Value);
+ topic.CreatedAt.UtcDateTime.ShouldBe(DateTimeOffset.UtcNow.UtcDateTime, TimeSpan.FromSeconds(10));
+ topic.Name.ShouldBe(topicRequest1.Name);
+ topic.CompressionAlgorithm.ShouldBe(topicRequest1.CompressionAlgorithm);
+ topic.Partitions.ShouldBeNull();
+ topic.MessageExpiry.ShouldBe(topicRequest1.MessageExpiry);
+ topic.Size.ShouldBe(210u);
+ topic.PartitionsCount.ShouldBe(topicRequest1.PartitionsCount);
+ topic.ReplicationFactor.ShouldBe(topicRequest1.ReplicationFactor);
+ topic.MaxTopicSize.ShouldBeGreaterThan(0u);
+ topic.MessagesCount.ShouldBe(3u);
+ }
+
+ [Test]
+ [DependsOn(nameof(GetStreamById_WithTopics_Should_ReturnValidResponse))]
+ public async Task UpdateStream_Should_UpdateStream_Successfully()
+ {
+ await Fixture.Clients[protocol].UpdateStreamAsync(Identifier.Numeric(StreamRequest.StreamId!.Value), UpdateStreamRequest);
+
+ var result = await Fixture.Clients[protocol].GetStreamByIdAsync(Identifier.Numeric(StreamRequest.StreamId!.Value));
+ result.ShouldNotBeNull();
+ result.Name.ShouldBe(UpdateStreamRequest.Name);
+ }
+
+ [Test]
+ [DependsOn(nameof(UpdateStream_Should_UpdateStream_Successfully))]
+ public async Task PurgeStream_Should_PurgeStream_Successfully()
+ {
+ // Ensure the stream has messages (created in previous steps) before purging
+ var stream = await Fixture.Clients[protocol].GetStreamByIdAsync(Identifier.Numeric(StreamRequest.StreamId!.Value));
+ stream.ShouldNotBeNull();
+ stream.MessagesCount.ShouldBe(7u);
+ stream.TopicsCount.ShouldBe(2);
+
+ await Should.NotThrowAsync(() => Fixture.Clients[protocol].PurgeStreamAsync(Identifier.Numeric(StreamRequest.StreamId!.Value)));
+
+ stream = await Fixture.Clients[protocol].GetStreamByIdAsync(Identifier.Numeric(StreamRequest.StreamId!.Value));
+ stream.ShouldNotBeNull();
+ stream.MessagesCount.ShouldBe(0u);
+ stream.TopicsCount.ShouldBe(2);
+ }
+
+ [Test]
+ [DependsOn(nameof(PurgeStream_Should_PurgeStream_Successfully))]
+ public async Task DeleteStream_Should_DeleteStream_Successfully()
+ {
+ await Should.NotThrowAsync(() => Fixture.Clients[protocol].DeleteStreamAsync(Identifier.Numeric(StreamRequest.StreamId!.Value)));
+ }
+
+ [Test]
+ [DependsOn(nameof(DeleteStream_Should_DeleteStream_Successfully))]
+ public async Task DeleteStream_NotExists_Should_Throw_InvalidResponse()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(() => Fixture.Clients[protocol].DeleteStreamAsync(Identifier.Numeric(StreamRequest.StreamId!.Value)));
+ }
+
+ [Test]
+ [DependsOn(nameof(DeleteStream_NotExists_Should_Throw_InvalidResponse))]
+ public async Task GetStreamById_AfterDelete_Should_Throw_InvalidResponse()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(() => Fixture.Clients[protocol].GetStreamByIdAsync(Identifier.Numeric(StreamRequest.StreamId!.Value)));
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/SystemTests.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/SystemTests.cs
new file mode 100644
index 00000000..576b72d3
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/SystemTests.cs
@@ -0,0 +1,195 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Contracts.Http.Auth;
+using Apache.Iggy.Enums;
+using Apache.Iggy.Exceptions;
+using Apache.Iggy.Kinds;
+using Apache.Iggy.Messages;
+using Apache.Iggy.Tests.Integrations.Attributes;
+using Apache.Iggy.Tests.Integrations.Fixtures;
+using Apache.Iggy.Tests.Integrations.Helpers;
+using Shouldly;
+using Partitioning = Apache.Iggy.Kinds.Partitioning;
+
+namespace Apache.Iggy.Tests.Integrations;
+
+[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
+public class SystemTests(Protocol protocol)
+{
+ [ClassDataSource<SystemFixture>(Shared = SharedType.PerClass)]
+ public required SystemFixture Fixture { get; init; }
+
+ [Test]
+ public async Task GetClients_Should_Return_CorrectClientsCount()
+ {
+ IReadOnlyList<ClientResponse> clients = await Fixture.Clients[protocol].GetClientsAsync();
+
+ clients.Count.ShouldBe(Fixture.TotalClientsCount);
+ foreach (var client in clients)
+ {
+ client.ClientId.ShouldNotBe(0u);
+ client.UserId.ShouldBeGreaterThan(0u);
+ client.Address.ShouldNotBeNullOrEmpty();
+ client.Transport.ShouldBe("TCP");
+ }
+ }
+
+ [Test]
+ [DependsOn(nameof(GetClients_Should_Return_CorrectClientsCount))]
+ public async Task GetClient_Should_Return_CorrectClient()
+ {
+ IReadOnlyList<ClientResponse> clients = await Fixture.Clients[protocol].GetClientsAsync();
+
+ clients.Count.ShouldBe(Fixture.TotalClientsCount);
+ var id = clients[0].ClientId;
+ var response = await Fixture.Clients[protocol].GetClientByIdAsync(id);
+ response.ShouldNotBeNull();
+ response.ClientId.ShouldBe(id);
+ response.UserId.ShouldBeGreaterThan(0u);
+ response.Address.ShouldNotBeNullOrEmpty();
+ response.Transport.ShouldBe("TCP");
+ response.ConsumerGroupsCount.ShouldBe(0);
+ response.ConsumerGroups.ShouldBeEmpty();
+ }
+
+ [Test]
+ [SkipHttp]
+ [DependsOn(nameof(GetClient_Should_Return_CorrectClient))]
+ public async Task GetMe_Tcp_Should_Return_MyClient()
+ {
+ var me = await Fixture.Clients[protocol].GetMeAsync();
+ me.ShouldNotBeNull();
+ me.ClientId.ShouldNotBe(0u);
+ me.UserId.ShouldBe(1u);
+ me.Address.ShouldNotBeNullOrEmpty();
+ me.Transport.ShouldBe("TCP");
+ }
+
+ [Test]
+ [SkipTcp]
+ [DependsOn(nameof(GetClient_Should_Return_CorrectClient))]
+ public async Task GetMe_HTTP_Should_Throw_FeatureUnavailableException()
+ {
+ await Should.ThrowAsync<FeatureUnavailableException>(() => Fixture.Clients[protocol].GetMeAsync());
+ }
+
+ [Test]
+ [DependsOn(nameof(GetMe_HTTP_Should_Throw_FeatureUnavailableException))]
+ [DependsOn(nameof(GetMe_Tcp_Should_Return_MyClient))]
+ public async Task GetClient_WithConsumerGroup_Should_Return_CorrectClient()
+ {
+ var client = Fixture.CreateClient(Protocol.Tcp, protocol);
+ await client.LoginUser(new LoginUserRequest
+ {
+ Password = "iggy",
+ Username = "iggy"
+ });
+ await client.CreateStreamAsync(StreamFactory.CreateStream());
+ await client.CreateTopicAsync(Identifier.Numeric(1), new TopicRequest
+ {
+ Name = "test_topic",
+ PartitionsCount = 2
+ });
+ var consumerGroup = await client.CreateConsumerGroupAsync(new CreateConsumerGroupRequest
+ {
+ Name = "test_consumer_group",
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(1),
+ ConsumerGroupId = 1
+ });
+ await client.JoinConsumerGroupAsync(new JoinConsumerGroupRequest
+ {
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(1),
+ ConsumerGroupId = Identifier.Numeric(consumerGroup!.Id)
+ });
+ var me = await client.GetMeAsync();
+
+
+ var response = await Fixture.Clients[protocol].GetClientByIdAsync(me!.ClientId);
+ response.ShouldNotBeNull();
+ response.UserId.ShouldBe(1u);
+ response.Address.ShouldNotBeNullOrEmpty();
+ response.Transport.ShouldBe("TCP");
+ response.ConsumerGroupsCount.ShouldBe(1);
+ response.ConsumerGroups.ShouldNotBeEmpty();
+ response.ConsumerGroups.ShouldContain(x => x.GroupId == consumerGroup.Id);
+ response.ConsumerGroups.ShouldContain(x => x.TopicId == 1);
+ response.ConsumerGroups.ShouldContain(x => x.StreamId == 1);
+ }
+
+
+ [Test]
+ [DependsOn(nameof(GetClient_WithConsumerGroup_Should_Return_CorrectClient))]
+ public async Task GetStats_Should_ReturnValidResponse()
+ {
+ await Fixture.Clients[protocol].SendMessagesAsync(new MessageSendRequest
+ {
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(1),
+ Partitioning = Partitioning.None(),
+ Messages = [new Message(Guid.NewGuid(), "Test message"u8.ToArray())]
+ });
+
+ await Fixture.Clients[protocol].FetchMessagesAsync(new MessageFetchRequest
+ {
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(1),
+ AutoCommit = true,
+ Consumer = Consumer.New(1),
+ Count = 1,
+ PartitionId = 1,
+ PollingStrategy = PollingStrategy.First()
+ });
+
+ var response = await Fixture.Clients[protocol].GetStatsAsync();
+ response.ShouldNotBeNull();
+ response.ProcessId.ShouldBeGreaterThanOrEqualTo(0);
+ response.CpuUsage.ShouldBeGreaterThanOrEqualTo(0);
+ response.TotalCpuUsage.ShouldBeGreaterThanOrEqualTo(0);
+ response.MemoryUsage.ShouldBeGreaterThanOrEqualTo(0u);
+ response.TotalMemory.ShouldBeGreaterThanOrEqualTo(0u);
+ response.AvailableMemory.ShouldNotBe(0u);
+ response.RunTime.ShouldBeGreaterThanOrEqualTo(0u);
+ response.StartTime.ShouldBe(DateTimeOffset.UtcNow, TimeSpan.FromMinutes(5));
+ response.ReadBytes.ShouldBeGreaterThanOrEqualTo(0u);
+ response.WrittenBytes.ShouldBeGreaterThanOrEqualTo(0u);
+ response.MessagesSizeBytes.ShouldBeGreaterThanOrEqualTo(0u);
+ response.StreamsCount.ShouldNotBe(0);
+ response.TopicsCount.ShouldNotBe(0);
+ response.PartitionsCount.ShouldNotBe(0);
+ response.SegmentsCount.ShouldNotBe(0);
+ response.MessagesCount.ShouldNotBe(0u);
+ response.ClientsCount.ShouldNotBe(0);
+ response.ConsumerGroupsCount.ShouldNotBe(0);
+ response.Hostname.ShouldNotBeNullOrEmpty();
+ response.OsName.ShouldNotBeNullOrEmpty();
+ response.OsVersion.ShouldNotBeNullOrEmpty();
+ response.KernelVersion.ShouldNotBeNullOrEmpty();
+ response.IggyServerVersion.ShouldNotBeNullOrEmpty();
+ response.IggyServerSemver.ShouldNotBe(0u);
+ }
+
+ [Test]
+ [DependsOn(nameof(GetStats_Should_ReturnValidResponse))]
+ public async Task Ping_Should_Pong()
+ {
+ await Should.NotThrowAsync(Fixture.Clients[protocol].PingAsync());
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/TopicsTests.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/TopicsTests.cs
new file mode 100644
index 00000000..30b926ba
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/TopicsTests.cs
@@ -0,0 +1,243 @@
+// // 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.Http;
+using Apache.Iggy.Enums;
+using Apache.Iggy.Exceptions;
+using Apache.Iggy.Messages;
+using Apache.Iggy.Tests.Integrations.Fixtures;
+using Apache.Iggy.Tests.Integrations.Helpers;
+using Shouldly;
+using Partitioning = Apache.Iggy.Kinds.Partitioning;
+
+namespace Apache.Iggy.Tests.Integrations;
+
+[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
+public class TopicsTests(Protocol protocol)
+{
+ private static readonly TopicRequest TopicRequest = new(1, "Test Topic", CompressionAlgorithm.Gzip, 1000, 1, 2, 2_000_000_000);
+ private static readonly TopicRequest TopicRequestSecond = new(2, "Test Topic 2", CompressionAlgorithm.Gzip, 1000, 1, 2, 2_000_000_000);
+ private static readonly UpdateTopicRequest UpdateTopicRequest = new("Updated Topic", CompressionAlgorithm.Gzip, 3_000_000_000, 2000, 3);
+
+ [ClassDataSource<IggyServerFixture>(Shared = SharedType.PerClass)]
+ public required IggyServerFixture Fixture { get; init; }
+
+ [Test]
+ public async Task Create_NewTopic_Should_Return_Successfully()
+ {
+ await Fixture.Clients[protocol].CreateStreamAsync(StreamFactory.CreateStream());
+
+ var response = await Fixture.Clients[protocol].CreateTopicAsync(Identifier.Numeric(1), TopicRequest);
+
+ response.ShouldNotBeNull();
+ response.Id.ShouldBe(TopicRequest.TopicId!.Value);
+ response.CreatedAt.UtcDateTime.ShouldBe(DateTimeOffset.UtcNow.UtcDateTime, TimeSpan.FromSeconds(10));
+ response.Name.ShouldBe(TopicRequest.Name);
+ response.CompressionAlgorithm.ShouldBe(TopicRequest.CompressionAlgorithm);
+ response.Partitions!.Count().ShouldBe(TopicRequest.PartitionsCount);
+ response.MessageExpiry.ShouldBe(TopicRequest.MessageExpiry);
+ response.Size.ShouldBe(0u);
+ response.PartitionsCount.ShouldBe(TopicRequest.PartitionsCount);
+ response.ReplicationFactor.ShouldBe(TopicRequest.ReplicationFactor);
+ response.MaxTopicSize.ShouldBe(TopicRequest.MaxTopicSize);
+ response.MessagesCount.ShouldBe(0u);
+ }
+
+ [Test]
+ [DependsOn(nameof(Create_NewTopic_Should_Return_Successfully))]
+ public async Task Create_DuplicateTopic_Should_Throw_InvalidResponse()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(Fixture.Clients[protocol].CreateTopicAsync(Identifier.Numeric(1), TopicRequest));
+ }
+
+ [Test]
+ [DependsOn(nameof(Create_DuplicateTopic_Should_Throw_InvalidResponse))]
+ public async Task Get_ExistingTopic_Should_ReturnValidResponse()
+ {
+ var response = await Fixture.Clients[protocol].GetTopicByIdAsync(Identifier.Numeric(1), Identifier.Numeric(1));
+
+ response.ShouldNotBeNull();
+ response.Id.ShouldBe(TopicRequest.TopicId!.Value);
+ response.CreatedAt.UtcDateTime.ShouldBe(DateTimeOffset.UtcNow.UtcDateTime, TimeSpan.FromSeconds(10));
+ response.Name.ShouldBe(TopicRequest.Name);
+ response.CompressionAlgorithm.ShouldBe(TopicRequest.CompressionAlgorithm);
+ response.Partitions!.Count().ShouldBe(TopicRequest.PartitionsCount);
+ response.MessageExpiry.ShouldBe(TopicRequest.MessageExpiry);
+ response.Size.ShouldBe(0u);
+ response.PartitionsCount.ShouldBe(TopicRequest.PartitionsCount);
+ response.ReplicationFactor.ShouldBe(TopicRequest.ReplicationFactor);
+ response.MaxTopicSize.ShouldBe(TopicRequest.MaxTopicSize);
+ response.MessagesCount.ShouldBe(0u);
+ }
+
+ [Test]
+ [DependsOn(nameof(Get_ExistingTopic_Should_ReturnValidResponse))]
+ public async Task Get_ExistingTopics_Should_ReturnValidResponse()
+ {
+ await Fixture.Clients[protocol].CreateTopicAsync(Identifier.Numeric(1), TopicRequestSecond);
+
+ IReadOnlyList<TopicResponse> response = await Fixture.Clients[protocol].GetTopicsAsync(Identifier.Numeric(1));
+
+ response.ShouldNotBeNull();
+ response.Count().ShouldBe(2);
+ response.Select(x => x.Id).ShouldContain(TopicRequest.TopicId!.Value);
+ response.Select(x => x.Id).ShouldContain(TopicRequestSecond.TopicId!.Value);
+
+ var firstTopic = response.First(x => x.Id == TopicRequest.TopicId!.Value);
+ firstTopic.Id.ShouldBe(TopicRequest.TopicId!.Value);
+ firstTopic.CreatedAt.UtcDateTime.ShouldBe(DateTimeOffset.UtcNow.UtcDateTime, TimeSpan.FromSeconds(10));
+ firstTopic.Name.ShouldBe(TopicRequest.Name);
+ firstTopic.CompressionAlgorithm.ShouldBe(TopicRequest.CompressionAlgorithm);
+ firstTopic.Partitions.ShouldBeNull();
+ firstTopic.MessageExpiry.ShouldBe(TopicRequest.MessageExpiry);
+ firstTopic.Size.ShouldBe(0u);
+ firstTopic.PartitionsCount.ShouldBe(TopicRequest.PartitionsCount);
+ firstTopic.ReplicationFactor.ShouldBe(TopicRequest.ReplicationFactor);
+ firstTopic.MaxTopicSize.ShouldBe(TopicRequest.MaxTopicSize);
+ firstTopic.MessagesCount.ShouldBe(0u);
+
+ var secondTopic = response.First(x => x.Id == TopicRequestSecond.TopicId!.Value);
+ secondTopic.Id.ShouldBe(TopicRequestSecond.TopicId!.Value);
+ secondTopic.CreatedAt.UtcDateTime.ShouldBe(DateTimeOffset.UtcNow.UtcDateTime, TimeSpan.FromSeconds(10));
+ secondTopic.Name.ShouldBe(TopicRequestSecond.Name);
+ secondTopic.CompressionAlgorithm.ShouldBe(TopicRequestSecond.CompressionAlgorithm);
+ secondTopic.Partitions.ShouldBeNull();
+ secondTopic.MessageExpiry.ShouldBe(TopicRequestSecond.MessageExpiry);
+ secondTopic.Size.ShouldBe(0u);
+ secondTopic.PartitionsCount.ShouldBe(TopicRequestSecond.PartitionsCount);
+ secondTopic.ReplicationFactor.ShouldBe(TopicRequestSecond.ReplicationFactor);
+ secondTopic.MaxTopicSize.ShouldBe(TopicRequestSecond.MaxTopicSize);
+ secondTopic.MessagesCount.ShouldBe(0u);
+ }
+
+ [Test]
+ [DependsOn(nameof(Get_ExistingTopics_Should_ReturnValidResponse))]
+ public async Task Get_Topic_WithPartitions_Should_ReturnValidResponse()
+ {
+ await Fixture.Clients[protocol].CreatePartitionsAsync(new CreatePartitionsRequest
+ {
+ PartitionsCount = 2,
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(1)
+ });
+
+ for (var i = 0; i < 3; i++)
+ {
+ await Fixture.Clients[protocol].SendMessagesAsync(new MessageSendRequest
+ {
+ StreamId = Identifier.Numeric(1),
+ TopicId = Identifier.Numeric(1),
+ Partitioning = Partitioning.None(),
+ Messages = GetMessages(i + 2)
+ });
+ }
+
+ var response = await Fixture.Clients[protocol].GetTopicByIdAsync(Identifier.Numeric(1), Identifier.Numeric(1));
+
+ response.ShouldNotBeNull();
+ response.Id.ShouldBe(TopicRequest.TopicId!.Value);
+ response.CreatedAt.UtcDateTime.ShouldBe(DateTimeOffset.UtcNow.UtcDateTime, TimeSpan.FromSeconds(10));
+ response.Name.ShouldBe(TopicRequest.Name);
+ response.CompressionAlgorithm.ShouldBe(TopicRequest.CompressionAlgorithm);
+ response.Partitions!.Count().ShouldBe(3);
+ response.MessageExpiry.ShouldBe(TopicRequest.MessageExpiry);
+ response.Size.ShouldBe(630u);
+ response.PartitionsCount.ShouldBe(3);
+ response.ReplicationFactor.ShouldBe(TopicRequest.ReplicationFactor);
+ response.MaxTopicSize.ShouldBe(TopicRequest.MaxTopicSize);
+ response.MessagesCount.ShouldBe(9u);
+ response.Partitions.ShouldNotBeNull();
+ response.Partitions!.ShouldAllBe(x => x.MessagesCount > 0);
+ response.Partitions.ShouldAllBe(x => x.CreatedAt > DateTimeOffset.UtcNow.AddMinutes(-5));
+ response.Partitions.ShouldAllBe(x => x.SegmentsCount > 0);
+ response.Partitions.ShouldAllBe(x => x.CurrentOffset > 0);
+ response.Partitions.ShouldAllBe(x => x.Size > 0);
+ response.Partitions.ShouldAllBe(x => x.Id > 0);
+ }
+
+ private static List<Message> GetMessages(int count)
+ {
+ var messages = new List<Message>();
+ for (var i = 0; i < count; i++)
+ {
+ messages.Add(new Message(Guid.NewGuid(), Encoding.UTF8.GetBytes($"Test message {i + 1}")));
+ }
+
+ return messages;
+ }
+
+ [Test]
+ [DependsOn(nameof(Get_Topic_WithPartitions_Should_ReturnValidResponse))]
+ public async Task Update_ExistingTopic_Should_UpdateTopic_Successfully()
+ {
+ await Should.NotThrowAsync(Fixture.Clients[protocol].UpdateTopicAsync(Identifier.Numeric(1),
+ Identifier.Numeric(TopicRequest.TopicId!.Value), UpdateTopicRequest));
+
+ var result = await Fixture.Clients[protocol].GetTopicByIdAsync(Identifier.Numeric(1),
+ Identifier.Numeric(TopicRequest.TopicId!.Value));
+ result.ShouldNotBeNull();
+ result!.Name.ShouldBe(UpdateTopicRequest.Name);
+ result.MessageExpiry.ShouldBe(UpdateTopicRequest.MessageExpiry);
+ result.CompressionAlgorithm.ShouldBe(UpdateTopicRequest.CompressionAlgorithm);
+ result.MaxTopicSize.ShouldBe(UpdateTopicRequest.MaxTopicSize);
+ result.ReplicationFactor.ShouldBe(UpdateTopicRequest.ReplicationFactor);
+ }
+
+ [Test]
+ [DependsOn(nameof(Update_ExistingTopic_Should_UpdateTopic_Successfully))]
+ public async Task Purge_ExistingTopic_Should_PurgeTopic_Successfully()
+ {
+ var beforePurge = await Fixture.Clients[protocol].GetTopicByIdAsync(Identifier.Numeric(1), Identifier.Numeric(TopicRequest.TopicId!.Value));
+
+ beforePurge.ShouldNotBeNull();
+ beforePurge.MessagesCount.ShouldBe(9u);
+ beforePurge.Size.ShouldBeGreaterThan(0u);
+
+ await Should.NotThrowAsync(Fixture.Clients[protocol].PurgeTopicAsync(Identifier.Numeric(1),
+ Identifier.Numeric(TopicRequest.TopicId!.Value)));
+
+ var afterPurge = await Fixture.Clients[protocol].GetTopicByIdAsync(Identifier.Numeric(1), Identifier.Numeric(TopicRequest.TopicId!.Value));
+ afterPurge.ShouldNotBeNull();
+ afterPurge!.MessagesCount.ShouldBe(0u);
+ afterPurge.Size.ShouldBe(0u);
+ }
+
+ [Test]
+ [DependsOn(nameof(Purge_ExistingTopic_Should_PurgeTopic_Successfully))]
+ public async Task Delete_ExistingTopic_Should_DeleteTopic_Successfully()
+ {
+ await Should.NotThrowAsync(Fixture.Clients[protocol].DeleteTopicAsync(Identifier.Numeric(1),
+ Identifier.Numeric(TopicRequest.TopicId!.Value)));
+ }
+
+ [Test]
+ [DependsOn(nameof(Delete_ExistingTopic_Should_DeleteTopic_Successfully))]
+ public async Task Delete_NonExistingTopic_Should_Throw_InvalidResponse()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(Fixture.Clients[protocol].DeleteTopicAsync(Identifier.Numeric(1),
+ Identifier.Numeric(TopicRequest.TopicId!.Value)));
+ }
+
+ [Test]
+ [DependsOn(nameof(Delete_NonExistingTopic_Should_Throw_InvalidResponse))]
+ public async Task Get_NonExistingTopic_Should_Throw_InvalidResponse()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(Fixture.Clients[protocol].GetTopicByIdAsync(Identifier.Numeric(1),
+ Identifier.Numeric(TopicRequest.TopicId!.Value)));
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/UsersTests.cs b/foreign/csharp/Iggy_SDK.Tests.Integration/UsersTests.cs
new file mode 100644
index 00000000..abdd39f8
--- /dev/null
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/UsersTests.cs
@@ -0,0 +1,266 @@
+// // 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 Apache.Iggy.Contracts.Http;
+using Apache.Iggy.Contracts.Http.Auth;
+using Apache.Iggy.Enums;
+using Apache.Iggy.Exceptions;
+using Apache.Iggy.Tests.Integrations.Fixtures;
+using Shouldly;
+
+namespace Apache.Iggy.Tests.Integrations;
+
+[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
+public class UsersTests(Protocol protocol)
+{
+ private const string Username = "test_user_1";
+ private const string NewUsername = "new_user_name";
+
+ [ClassDataSource<IggyServerFixture>(Shared = SharedType.PerClass)]
+ public required IggyServerFixture Fixture { get; init; }
+
+ [Test]
+ public async Task CreateUser_Should_CreateUser_Successfully()
+ {
+ var request = new CreateUserRequest
+ {
+ Username = Username,
+ Password = "test_password_1",
+ Status = UserStatus.Active
+ };
+
+ var result = await Fixture.Clients[protocol].CreateUser(request);
+ result.ShouldNotBeNull();
+ result.Username.ShouldBe(request.Username);
+ result.Status.ShouldBe(request.Status);
+ result.Id.ShouldBeGreaterThan(0u);
+ result.CreatedAt.ShouldBeGreaterThan(0u);
+ }
+
+ [Test]
+ [DependsOn(nameof(CreateUser_Should_CreateUser_Successfully))]
+ public async Task CreateUser_Duplicate_Should_Throw_InvalidResponse()
+ {
+ var request = new CreateUserRequest
+ {
+ Username = Username,
+ Password = "test1",
+ Status = UserStatus.Active
+ };
+
+ await Should.ThrowAsync<InvalidResponseException>(Fixture.Clients[protocol].CreateUser(request));
+ }
+
+ [Test]
+ [DependsOn(nameof(CreateUser_Duplicate_Should_Throw_InvalidResponse))]
+ public async Task GetUser_WithoutPermissions_Should_ReturnValidResponse()
+ {
+ var response = await Fixture.Clients[protocol].GetUser(Identifier.Numeric(2));
+
+ response.ShouldNotBeNull();
+ response.Id.ShouldBe((uint)2);
+ response.Username.ShouldBe(Username);
+ response.Status.ShouldBe(UserStatus.Active);
+ response.CreatedAt.ShouldBeGreaterThan(0u);
+ response.Permissions.ShouldBeNull();
+ }
+
+ [Test]
+ [DependsOn(nameof(GetUser_WithoutPermissions_Should_ReturnValidResponse))]
+ public async Task GetUsers_Should_ReturnValidResponse()
+ {
+ IReadOnlyList<UserResponse> response = await Fixture.Clients[protocol].GetUsers();
+
+ response.ShouldNotBeNull();
+ response.ShouldNotBeEmpty();
+ response.ShouldContain(user => user.Id == 2 && user.Username == Username && user.Status == UserStatus.Active);
+ response.ShouldAllBe(user => user.CreatedAt > 0u);
+ response.ShouldAllBe(user => user.Permissions == null);
+ }
+
+ [Test]
+ [DependsOn(nameof(GetUsers_Should_ReturnValidResponse))]
+ public async Task UpdateUser_Should_UpdateUser_Successfully()
+ {
+ await Should.NotThrowAsync(Fixture.Clients[protocol].UpdateUser(new UpdateUserRequest
+ {
+ UserId = Identifier.Numeric(2), Username = "new_user_name", UserStatus = UserStatus.Active
+ }));
+
+ var user = await Fixture.Clients[protocol].GetUser(Identifier.Numeric(2));
+
+ user.ShouldNotBeNull();
+ user.Id.ShouldBe(2u);
+ user.Username.ShouldBe("new_user_name");
+ user.Status.ShouldBe(UserStatus.Active);
+ user.CreatedAt.ShouldBeGreaterThan(0u);
+ user.Permissions.ShouldBeNull();
+ }
+
+ [Test]
+ [DependsOn(nameof(UpdateUser_Should_UpdateUser_Successfully))]
+ public async Task UpdatePermissions_Should_UpdatePermissions_Successfully()
+ {
+ var permissions = CreatePermissions();
+ await Should.NotThrowAsync(Fixture.Clients[protocol].UpdatePermissions(new UpdateUserPermissionsRequest
+ {
+ UserId = Identifier.Numeric(2),
+ Permissions = permissions
+ }));
+
+ var user = await Fixture.Clients[protocol].GetUser(Identifier.Numeric(2));
+
+ user.ShouldNotBeNull();
+ user.Id.ShouldBe(2u);
+ user.Permissions.ShouldNotBeNull();
+ user.Permissions!.Global.ShouldNotBeNull();
+ user.Permissions.Global.ManageServers.ShouldBeTrue();
+ user.Permissions.Global.ManageUsers.ShouldBeTrue();
+ user.Permissions.Global.ManageStreams.ShouldBeTrue();
+ user.Permissions.Global.ManageTopics.ShouldBeTrue();
+ user.Permissions.Global.PollMessages.ShouldBeTrue();
+ user.Permissions.Global.ReadServers.ShouldBeTrue();
+ user.Permissions.Global.ReadStreams.ShouldBeTrue();
+ user.Permissions.Global.ReadTopics.ShouldBeTrue();
+ user.Permissions.Global.ReadUsers.ShouldBeTrue();
+ user.Permissions.Global.SendMessages.ShouldBeTrue();
+ user.Permissions.Streams.ShouldNotBeNull();
+ user.Permissions.Streams.ShouldContainKey(1);
+ user.Permissions.Streams[1].ManageStream.ShouldBeTrue();
+ user.Permissions.Streams[1].ManageTopics.ShouldBeTrue();
+ user.Permissions.Streams[1].ReadStream.ShouldBeTrue();
+ user.Permissions.Streams[1].SendMessages.ShouldBeTrue();
+ user.Permissions.Streams[1].ReadTopics.ShouldBeTrue();
+ user.Permissions.Streams[1].PollMessages.ShouldBeTrue();
+ user.Permissions.Streams[1].Topics.ShouldNotBeNull();
+ user.Permissions.Streams[1].Topics!.ShouldContainKey(1);
+ user.Permissions.Streams[1].Topics![1].ManageTopic.ShouldBeTrue();
+ user.Permissions.Streams[1].Topics![1].PollMessages.ShouldBeTrue();
+ user.Permissions.Streams[1].Topics![1].ReadTopic.ShouldBeTrue();
+ user.Permissions.Streams[1].Topics![1].SendMessages.ShouldBeTrue();
+ }
+
+ [Test]
+ [DependsOn(nameof(UpdatePermissions_Should_UpdatePermissions_Successfully))]
+ public async Task ChangePassword_Should_ChangePassword_Successfully()
+ {
+ await Should.NotThrowAsync(Fixture.Clients[protocol].ChangePassword(new ChangePasswordRequest
+ {
+ UserId = Identifier.Numeric(2),
+ CurrentPassword = "test_password_1",
+ NewPassword = "user2"
+ }));
+ }
+
+ [Test]
+ [DependsOn(nameof(ChangePassword_Should_ChangePassword_Successfully))]
+ public async Task ChangePassword_WrongCurrentPassword_Should_Throw_InvalidResponse()
+ {
+ await Should.ThrowAsync<InvalidResponseException>(Fixture.Clients[protocol].ChangePassword(new ChangePasswordRequest
+ {
+ UserId = Identifier.Numeric(2),
+ CurrentPassword = "test_password_1",
+ NewPassword = "user2"
+ }));
+ }
+
+ [Test]
+ [DependsOn(nameof(ChangePassword_WrongCurrentPassword_Should_Throw_InvalidResponse))]
+ public async Task LoginUser_Should_LoginUser_Successfully()
+ {
+ var client = Fixture.CreateClient(protocol);
+
+ var response = await client.LoginUser(new LoginUserRequest
+ {
+ Username = NewUsername,
+ Password = "user2"
+ });
+
+ response.ShouldNotBeNull();
+ response.UserId.ShouldBe(2);
+ switch (protocol)
+ {
+ case Protocol.Tcp:
+ response.AccessToken.ShouldBeNull();
+ break;
+ case Protocol.Http:
+ response.AccessToken.ShouldNotBeNull();
+ break;
+ }
+ }
+
+ [Test]
+ [DependsOn(nameof(LoginUser_Should_LoginUser_Successfully))]
+ public async Task DeleteUser_Should_DeleteUser_Successfully()
+ {
+ await Should.NotThrowAsync(Fixture.Clients[protocol].DeleteUser(Identifier.Numeric(2)));
+ }
+
+ [Test]
+ [DependsOn(nameof(DeleteUser_Should_DeleteUser_Successfully))]
+ public async Task LogoutUser_Should_LogoutUser_Successfully()
+ {
+ // act & assert
+ await Should.NotThrowAsync(Fixture.Clients[protocol].LogoutUser());
+ }
+
+ private static Permissions CreatePermissions()
+ {
+ return new Permissions
+ {
+ Global = new GlobalPermissions
+ {
+ ManageServers = true,
+ ManageUsers = true,
+ ManageStreams = true,
+ ManageTopics = true,
+ PollMessages = true,
+ ReadServers = true,
+ ReadStreams = true,
+ ReadTopics = true,
+ ReadUsers = true,
+ SendMessages = true
+ },
+ Streams = new Dictionary<int, StreamPermissions>
+ {
+ {
+ 1, new StreamPermissions
+ {
+ ManageStream = true,
+ ManageTopics = true,
+ ReadStream = true,
+ SendMessages = true,
+ ReadTopics = true,
+ PollMessages = true,
+ Topics = new Dictionary<int, TopicPermissions>
+ {
+ {
+ 1, new TopicPermissions
+ {
+ ManageTopic = true,
+ PollMessages = true,
+ ReadTopic = true,
+ SendMessages = true
+ }
+ }
+ }
+ }
+ }
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK.sln b/foreign/csharp/Iggy_SDK.sln
index cffbef77..536284bf 100644
--- a/foreign/csharp/Iggy_SDK.sln
+++ b/foreign/csharp/Iggy_SDK.sln
@@ -12,6 +12,17 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{466C54AD-A5FA-401C-9300-8FE21D3C355A}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Iggy_SDK.Tests.Integration", "Iggy_SDK.Tests.Integration\Iggy_SDK.Tests.Integration.csproj", "{59661E1B-1D5E-4D58-AE7B-10E8ABB9839A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionFolder", "SolutionFolder", "{3A9B7D3B-EFA9-4652-A647-C72F84616114}"
+ ProjectSection(SolutionItems) = preProject
+ DEPENDENCIES.md = DEPENDENCIES.md
+ Directory.Packages.props = Directory.Packages.props
+ LICENSE = LICENSE
+ NOTICE = NOTICE
+ README.md = README.md
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -42,5 +53,9 @@ Global
{466C54AD-A5FA-401C-9300-8FE21D3C355A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{466C54AD-A5FA-401C-9300-8FE21D3C355A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{466C54AD-A5FA-401C-9300-8FE21D3C355A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {59661E1B-1D5E-4D58-AE7B-10E8ABB9839A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {59661E1B-1D5E-4D58-AE7B-10E8ABB9839A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {59661E1B-1D5E-4D58-AE7B-10E8ABB9839A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {59661E1B-1D5E-4D58-AE7B-10E8ABB9839A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/foreign/csharp/Iggy_SDK.sln.DotSettings b/foreign/csharp/Iggy_SDK.sln.DotSettings
index 7479ae10..9709c09a 100644
--- a/foreign/csharp/Iggy_SDK.sln.DotSettings
+++ b/foreign/csharp/Iggy_SDK.sln.DotSettings
@@ -1,13 +1,21 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+ <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceIfStatementBraces/@EntryIndexedValue"></s:String>
+ <s:Boolean x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceIfStatementBraces/@EntryIndexRemoved">True</s:Boolean>
+ <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceUsingStatementBraces/@EntryIndexedValue"></s:String>
+ <s:Boolean x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceUsingStatementBraces/@EntryIndexRemoved">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FBuiltInTypes/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FElsewhere/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">SUGGESTION</s:String>
- <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">NotRequired</s:String>
- <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_USING/@EntryValue">NotRequired</s:String>
+ <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String>
+ <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String>
+ <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String>
+ <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_USING/@EntryValue">Required</s:String>
+ <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String>
+ <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/STICK_COMMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINES/@EntryValue">False</s:Boolean>
- <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseVarWhenEvident</s:String>
+ <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseVar</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForOtherTypes/@EntryValue">UseVarWhenEvident</s:String>
- <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseVarWhenEvident</s:String>
+ <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseVar</s:String>
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">// 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
@@ -24,8 +32,13 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.</s:String>
+ <s:String x:Key="/Default/Environment/Hierarchy/Build/SolBuilderDuo/CustomGlobalProperties/=PreferredUILang/@EntryIndexedValue">en-US</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002ECodeCleanup_002EFileHeader_002EFileHeaderSettingsMigrate/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
- <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
+ <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
+ <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EUnitTestFramework_002EMigrations_002EEnableDisabledProvidersMigration/@EntryIndexedValue">True</s:Boolean>
+ <s:Boolean x:Key="/Default/Environment/UnitTesting/DisabledProviders/=Testing_0020Platform/@EntryIndexedValue">False</s:Boolean>
+ <s:Boolean x:Key="/Default/Environment/UnitTesting/DisabledProviders/=VsTest/@EntryIndexedValue">True</s:Boolean>
+ </wpf:ResourceDictionary>
diff --git a/foreign/csharp/Iggy_SDK/Configuration/TlsConfiguration.cs b/foreign/csharp/Iggy_SDK/Configuration/TlsConfiguration.cs
index ad7ce9a0..7e2f4735 100644
--- a/foreign/csharp/Iggy_SDK/Configuration/TlsConfiguration.cs
+++ b/foreign/csharp/Iggy_SDK/Configuration/TlsConfiguration.cs
@@ -19,7 +19,7 @@ namespace Apache.Iggy.Configuration;
public class TlsSettings
{
- public bool Enabled { get; set; }
- public string Hostname { get; set; }
+ public bool Enabled { get; set; }
+ public string Hostname { get; set; } = string.Empty;
public bool Authenticate { get; set; } = false;
}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK/Contracts/Http/Auth/AuthResponse.cs b/foreign/csharp/Iggy_SDK/Contracts/Http/Auth/AuthResponse.cs
index 8f581e9c..0595a2e2 100644
--- a/foreign/csharp/Iggy_SDK/Contracts/Http/Auth/AuthResponse.cs
+++ b/foreign/csharp/Iggy_SDK/Contracts/Http/Auth/AuthResponse.cs
@@ -17,4 +17,4 @@
namespace Apache.Iggy.Contracts.Http.Auth;
-public record AuthResponse(int UserId, TokenInfo AccessToken);
+public record AuthResponse(int UserId, TokenInfo? AccessToken);
diff --git a/foreign/csharp/Iggy_SDK/Contracts/Http/ClientInfo.cs b/foreign/csharp/Iggy_SDK/Contracts/Http/ClientInfo.cs
index 084f89d4..4b7ecb6f 100644
--- a/foreign/csharp/Iggy_SDK/Contracts/Http/ClientInfo.cs
+++ b/foreign/csharp/Iggy_SDK/Contracts/Http/ClientInfo.cs
@@ -24,5 +24,5 @@ public sealed class ClientResponse
public required uint UserId { get; init; }
public required string Transport { get; init; }
public required int ConsumerGroupsCount { get; init; }
- public IEnumerable<ConsumerGroupInfo>? ConsumerGroups { get; init; }
+ public IEnumerable<ConsumerGroupInfo> ConsumerGroups { get; init; } = [];
}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK/Contracts/Http/ConsumerGroupInfo.cs b/foreign/csharp/Iggy_SDK/Contracts/Http/ConsumerGroupInfo.cs
index 37497d72..3dddb9d0 100644
--- a/foreign/csharp/Iggy_SDK/Contracts/Http/ConsumerGroupInfo.cs
+++ b/foreign/csharp/Iggy_SDK/Contracts/Http/ConsumerGroupInfo.cs
@@ -21,5 +21,5 @@ public sealed class ConsumerGroupInfo
{
public required int StreamId { get; init; }
public required int TopicId { get; init; }
- public required int ConsumerGroupId { get; init; }
+ public required int GroupId { get; init; }
}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK/Contracts/Http/ConsumerGroupMembers.cs b/foreign/csharp/Iggy_SDK/Contracts/Http/ConsumerGroupMembers.cs
index 8b4478e7..83e38319 100644
--- a/foreign/csharp/Iggy_SDK/Contracts/Http/ConsumerGroupMembers.cs
+++ b/foreign/csharp/Iggy_SDK/Contracts/Http/ConsumerGroupMembers.cs
@@ -19,7 +19,7 @@ namespace Apache.Iggy.Contracts.Http;
public sealed class ConsumerGroupMember
{
- public required int Id { get; init; }
+ public required uint Id { get; init; }
public required int PartitionsCount { get; init; }
public required List<int> Partitions { get; init; }
}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK/Contracts/Http/MessageResponse.cs b/foreign/csharp/Iggy_SDK/Contracts/Http/MessageResponse.cs
index ba2e06ca..11fcc432 100644
--- a/foreign/csharp/Iggy_SDK/Contracts/Http/MessageResponse.cs
+++ b/foreign/csharp/Iggy_SDK/Contracts/Http/MessageResponse.cs
@@ -23,6 +23,6 @@ namespace Apache.Iggy.Contracts.Http;
public sealed class MessageResponse
{
public MessageHeader Header { get; set; }
- public byte[] Payload { get; set; }
+ public byte[] Payload { get; set; } = [];
public Dictionary<HeaderKey, HeaderValue>? UserHeaders { get; init; }
}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK/Contracts/Http/Stats.cs b/foreign/csharp/Iggy_SDK/Contracts/Http/Stats.cs
index de2cc185..f51419cd 100644
--- a/foreign/csharp/Iggy_SDK/Contracts/Http/Stats.cs
+++ b/foreign/csharp/Iggy_SDK/Contracts/Http/Stats.cs
@@ -43,5 +43,5 @@ public sealed class Stats
public required string KernelVersion { get; init; }
public required string IggyServerVersion { get; init; }
public uint IggyServerSemver { get; init; }
- public List<CacheMetrics> CacheMetrics { get; set; }
+ public List<CacheMetrics> CacheMetrics { get; set; } = [];
}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK/Contracts/Http/StatsResponse.cs b/foreign/csharp/Iggy_SDK/Contracts/Http/StatsResponse.cs
index f9e0fb44..8addbc2c 100644
--- a/foreign/csharp/Iggy_SDK/Contracts/Http/StatsResponse.cs
+++ b/foreign/csharp/Iggy_SDK/Contracts/Http/StatsResponse.cs
@@ -45,7 +45,8 @@ public sealed class StatsResponse
public required string OsVersion { get; init; }
public required string KernelVersion { get; init; }
public required string IggyVersion { get; init; }
- public List<CacheMetrics> CacheMetrics { get; init; }
+ public uint IggyServerSemver { get; init; }
+ public List<CacheMetrics> CacheMetrics { get; init; } = [];
internal Stats ToStats()
{
@@ -74,6 +75,7 @@ public sealed class StatsResponse
OsVersion = OsVersion,
KernelVersion = KernelVersion,
IggyServerVersion = IggyVersion,
+ IggyServerSemver = IggyServerSemver,
CacheMetrics = CacheMetrics
};
}
diff --git a/foreign/csharp/Iggy_SDK/Contracts/Http/StreamResponse.cs b/foreign/csharp/Iggy_SDK/Contracts/Http/StreamResponse.cs
index c92319ec..ffac3a96 100644
--- a/foreign/csharp/Iggy_SDK/Contracts/Http/StreamResponse.cs
+++ b/foreign/csharp/Iggy_SDK/Contracts/Http/StreamResponse.cs
@@ -26,5 +26,5 @@ public sealed class StreamResponse
public required DateTimeOffset CreatedAt { get; init; }
public required ulong MessagesCount { get; init; }
public required int TopicsCount { get; init; }
- public IEnumerable<TopicResponse>? Topics { get; init; }
+ public IEnumerable<TopicResponse> Topics { get; init; } = [];
}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK/Contracts/Http/TopicRequest.cs b/foreign/csharp/Iggy_SDK/Contracts/Http/TopicRequest.cs
index 74cd21c1..cba72ad0 100644
--- a/foreign/csharp/Iggy_SDK/Contracts/Http/TopicRequest.cs
+++ b/foreign/csharp/Iggy_SDK/Contracts/Http/TopicRequest.cs
@@ -15,15 +15,41 @@
// specific language governing permissions and limitations
// under the License.
+using System.Diagnostics.CodeAnalysis;
using Apache.Iggy.Enums;
namespace Apache.Iggy.Contracts.Http;
-public record TopicRequest(
- int? TopicId, // If not provided, the Iggy server will generate one automatically
- string Name,
- CompressionAlgorithm CompressionAlgorithm,
- ulong MessageExpiry,
- int PartitionsCount,
- byte ReplicationFactor,
- ulong MaxTopicSize);
\ No newline at end of file
+public sealed class TopicRequest
+{
+ public int? TopicId { get; set; }
+ public required string Name { get; set; }
+ public CompressionAlgorithm CompressionAlgorithm { get; set; } = CompressionAlgorithm.None;
+ public ulong MessageExpiry { get; set; } = 0;
+ public int PartitionsCount { get; set; } = 1;
+ public byte ReplicationFactor { get; set; } = 1;
+ public ulong MaxTopicSize { get; set; } = 0;
+
+ public TopicRequest()
+ {
+
+ }
+
+ [SetsRequiredMembers]
+ public TopicRequest(int? topicId,
+ string name,
+ CompressionAlgorithm compressionAlgorithm,
+ ulong messageExpiry,
+ int partitionsCount,
+ byte replicationFactor,
+ ulong maxTopicSize)
+ {
+ TopicId = topicId;
+ Name = name;
+ CompressionAlgorithm = compressionAlgorithm;
+ MessageExpiry = messageExpiry;
+ PartitionsCount = partitionsCount;
+ ReplicationFactor = replicationFactor;
+ MaxTopicSize = maxTopicSize;
+ }
+}
diff --git a/foreign/csharp/Iggy_SDK/Contracts/Tcp/TcpContracts.cs b/foreign/csharp/Iggy_SDK/Contracts/Tcp/TcpContracts.cs
index 182aa71a..540af6c4 100644
--- a/foreign/csharp/Iggy_SDK/Contracts/Tcp/TcpContracts.cs
+++ b/foreign/csharp/Iggy_SDK/Contracts/Tcp/TcpContracts.cs
@@ -766,18 +766,6 @@ internal static class TcpContracts
};
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static byte GetPartitioningKindByte(Partitioning kind)
- {
- return kind switch
- {
- Partitioning.Balanced => 1,
- Partitioning.PartitionId => 2,
- Partitioning.MessageKey => 3,
- _ => throw new ArgumentOutOfRangeException()
- };
- }
-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static byte GetPollingStrategyByte(MessagePolling pollingStrategy)
{
diff --git a/foreign/csharp/Iggy_SDK/Exceptions/InvalidResponseException.cs b/foreign/csharp/Iggy_SDK/Exceptions/InvalidResponseException.cs
index 76ceb135..6b3febda 100644
--- a/foreign/csharp/Iggy_SDK/Exceptions/InvalidResponseException.cs
+++ b/foreign/csharp/Iggy_SDK/Exceptions/InvalidResponseException.cs
@@ -17,7 +17,7 @@
namespace Apache.Iggy.Exceptions;
-internal sealed class InvalidResponseException : Exception
+public sealed class InvalidResponseException : Exception
{
internal InvalidResponseException(string message) : base(message)
{
diff --git a/foreign/csharp/Iggy_SDK/IggyClient/IIggyOffset.cs b/foreign/csharp/Iggy_SDK/IggyClient/IIggyOffset.cs
index c1194db2..ffc4c3cf 100644
--- a/foreign/csharp/Iggy_SDK/IggyClient/IIggyOffset.cs
+++ b/foreign/csharp/Iggy_SDK/IggyClient/IIggyOffset.cs
@@ -21,6 +21,6 @@ namespace Apache.Iggy.IggyClient;
public interface IIggyOffset
{
- Task StoreOffsetAsync(StoreOffsetRequest contract, CancellationToken token = default);
+ Task StoreOffsetAsync(StoreOffsetRequest contract, CancellationToken token = default);
Task<OffsetResponse?> GetOffsetAsync(OffsetRequest request, CancellationToken token = default);
}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK/IggyClient/Implementations/HttpMessageStream.cs b/foreign/csharp/Iggy_SDK/IggyClient/Implementations/HttpMessageStream.cs
index 178e07c1..c2de8630 100644
--- a/foreign/csharp/Iggy_SDK/IggyClient/Implementations/HttpMessageStream.cs
+++ b/foreign/csharp/Iggy_SDK/IggyClient/Implementations/HttpMessageStream.cs
@@ -399,7 +399,7 @@ public class HttpMessageStream : IIggyClient
}
catch(Exception e)
{
- _logger.LogError("Error encountered while polling messages - Stream ID: {streamId}, Topic ID: {topicId}, Partition ID: {partitionId}",
+ _logger.LogError(e, "Error encountered while polling messages - Stream ID: {StreamId}, Topic ID: {TopicId}, Partition ID: {PartitionId}",
request.StreamId, request.TopicId, request.PartitionId);
}
@@ -481,7 +481,7 @@ public class HttpMessageStream : IIggyClient
public Task<ClientResponse?> GetMeAsync(CancellationToken token = default)
{
- throw new NotImplementedException();
+ throw new FeatureUnavailableException();
}
public async Task<Stats?> GetStatsAsync(CancellationToken token = default)
diff --git a/foreign/csharp/Iggy_SDK/IggyClient/Implementations/TcpMessageStream.cs b/foreign/csharp/Iggy_SDK/IggyClient/Implementations/TcpMessageStream.cs
index da67c342..62f3a40f 100644
--- a/foreign/csharp/Iggy_SDK/IggyClient/Implementations/TcpMessageStream.cs
+++ b/foreign/csharp/Iggy_SDK/IggyClient/Implementations/TcpMessageStream.cs
@@ -270,6 +270,7 @@ public sealed class TcpMessageStream : IIggyClient, IDisposable
await _channel!.Writer.WriteAsync(request, token);
}
+ // TODO: Change TMessage implementation
public async Task SendMessagesAsync<TMessage>(MessageSendRequest<TMessage> request,
Func<TMessage, byte[]> serializer,
Func<byte[], byte[]>? encryptor = null,
@@ -543,16 +544,7 @@ public sealed class TcpMessageStream : IIggyClient, IDisposable
await _stream.SendAsync(payload, token);
await _stream.FlushAsync(token);
- var buffer = new byte[BufferSizes.ExpectedResponseSize];
- await _stream.ReadAsync(buffer, token);
-
- var response = TcpMessageStreamHelpers.GetResponseLengthAndStatus(buffer);
- if (response.Status != 0)
- {
- var errorBuffer = new byte[response.Length];
- await _stream.ReadAsync(errorBuffer, token);
- throw new InvalidResponseException(Encoding.UTF8.GetString(errorBuffer));
- }
+ await CheckResponseAsync(token);
}
public async Task<OffsetResponse?> GetOffsetAsync(OffsetRequest request, CancellationToken token = default)
@@ -614,7 +606,7 @@ public sealed class TcpMessageStream : IIggyClient, IDisposable
return BinaryMapper.MapConsumerGroup(responseBuffer);
}
- public async Task<ConsumerGroupResponse> CreateConsumerGroupAsync(CreateConsumerGroupRequest request, CancellationToken token = default)
+ public async Task<ConsumerGroupResponse?> CreateConsumerGroupAsync(CreateConsumerGroupRequest request, CancellationToken token = default)
{
var message = TcpContracts.CreateGroup(request);
var payload = new byte[4 + BufferSizes.InitialBytesLength + message.Length];
@@ -906,7 +898,7 @@ public sealed class TcpMessageStream : IIggyClient, IDisposable
var userId = BinaryPrimitives.ReadInt32LittleEndian(responseBuffer.AsSpan()[..(responseBuffer.Length)]);
//TODO: Figure out how to solve this workaround about default of TokenInfo
- return new AuthResponse(userId, default);
+ return new AuthResponse(userId, null);
}
public async Task LogoutUser(CancellationToken token = default)
diff --git a/foreign/csharp/Iggy_SDK/Iggy_SDK.csproj b/foreign/csharp/Iggy_SDK/Iggy_SDK.csproj
index bd8f0624..daa94fde 100644
--- a/foreign/csharp/Iggy_SDK/Iggy_SDK.csproj
+++ b/foreign/csharp/Iggy_SDK/Iggy_SDK.csproj
@@ -18,6 +18,14 @@
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
+
+ <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+ </PropertyGroup>
+
+ <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+ </PropertyGroup>
<ItemGroup>
<None Include="../README.md" Pack="true" PackagePath="">
@@ -29,8 +37,8 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
- <PackageReference Include="System.IO.Hashing" Version="9.0.5" />
+ <PackageReference Include="Microsoft.Extensions.Logging" />
+ <PackageReference Include="System.IO.Hashing" />
</ItemGroup>
<ItemGroup>
@@ -38,4 +46,5 @@
<Link>Properties\DEPENDENCIES.md</Link>
</Content>
</ItemGroup>
+
</Project>
diff --git a/foreign/csharp/Iggy_SDK/JsonConfiguration/AuthResponseConverter.cs b/foreign/csharp/Iggy_SDK/JsonConfiguration/AuthResponseConverter.cs
index 6e498f8f..eb1806cb 100644
--- a/foreign/csharp/Iggy_SDK/JsonConfiguration/AuthResponseConverter.cs
+++ b/foreign/csharp/Iggy_SDK/JsonConfiguration/AuthResponseConverter.cs
@@ -24,7 +24,6 @@ namespace Apache.Iggy.JsonConfiguration;
public sealed class AuthResponseConverter : JsonConverter<AuthResponse>
{
-
public override AuthResponse? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using var doc = JsonDocument.ParseValue(ref reader);
@@ -35,6 +34,11 @@ public sealed class AuthResponseConverter : JsonConverter<AuthResponse>
var token = accessToken.GetProperty(nameof(TokenInfo.Token).ToSnakeCase()).GetString();
var accessTokenExpiry = accessToken.GetProperty(nameof(TokenInfo.Expiry).ToSnakeCase()).GetInt64();
+ if(token is null)
+ {
+ throw new JsonException("Access token is null");
+ }
+
return new AuthResponse(
userId,
new TokenInfo(token, DateTimeOffset.FromUnixTimeSeconds(accessTokenExpiry).LocalDateTime)
diff --git a/foreign/csharp/Iggy_SDK/JsonConfiguration/MessagesConverter.cs b/foreign/csharp/Iggy_SDK/JsonConfiguration/MessagesConverter.cs
index 75d67bba..a8123553 100644
--- a/foreign/csharp/Iggy_SDK/JsonConfiguration/MessagesConverter.cs
+++ b/foreign/csharp/Iggy_SDK/JsonConfiguration/MessagesConverter.cs
@@ -35,13 +35,12 @@ internal sealed class MessagesConverter : JsonConverter<MessageSendRequest>
{
if (value.Messages.Any())
{
-
writer.WriteStartObject();
writer.WriteStartObject("partitioning");
writer.WriteString(nameof(MessageSendRequest.Partitioning.Kind).ToSnakeCase(), value: value.Partitioning.Kind switch
{
- Partitioning.Balanced => "none",
+ Partitioning.Balanced => "balanced",
Partitioning.MessageKey => "entity_id",
Partitioning.PartitionId => "partition_id",
_ => throw new InvalidEnumArgumentException()
diff --git a/foreign/csharp/Iggy_SDK/JsonConfiguration/StatsResponseConverter.cs b/foreign/csharp/Iggy_SDK/JsonConfiguration/StatsResponseConverter.cs
index 7a1c92a7..c265e175 100644
--- a/foreign/csharp/Iggy_SDK/JsonConfiguration/StatsResponseConverter.cs
+++ b/foreign/csharp/Iggy_SDK/JsonConfiguration/StatsResponseConverter.cs
@@ -35,35 +35,15 @@ public class StatsResponseConverter : JsonConverter<StatsResponse>
float cpuUsage = root.GetProperty(nameof(Stats.CpuUsage).ToSnakeCase()).GetSingle();
float totalCpuUsage = root.GetProperty(nameof(Stats.TotalCpuUsage).ToSnakeCase()).GetSingle();
- string? memoryUsageString = root.GetProperty(nameof(Stats.MemoryUsage).ToSnakeCase()).GetString();
- string[] memoryUsageStringSplit = memoryUsageString.Split(' ');
- (float memoryUsageBytesVal, string memoryUnit) = (ParseFloat(memoryUsageStringSplit[0]), memoryUsageStringSplit[1]);
- ulong memoryUsage = ConvertStringBytesToUlong(memoryUnit, memoryUsageBytesVal);
-
- string? totalMemoryString = root.GetProperty(nameof(Stats.TotalMemory).ToSnakeCase()).GetString();
- string[] totalMemoryStringSplit = totalMemoryString.Split(' ');
- (float totalMemoryUsageBytesVal, string totalMemoryUnit) = (ParseFloat(totalMemoryStringSplit[0]), totalMemoryStringSplit[1]);
- ulong totalMemoryUsage = ConvertStringBytesToUlong(totalMemoryUnit, totalMemoryUsageBytesVal);
-
- string? availableMemoryString = root.GetProperty(nameof(Stats.AvailableMemory).ToSnakeCase()).GetString();
- string[] availableMemoryStringSplit = availableMemoryString.Split(' ');
- (float availableMemoryBytesVal, string availableMemoryUnit) = (ParseFloat(availableMemoryStringSplit[0]), availableMemoryStringSplit[1]);
- ulong availableMemory = ConvertStringBytesToUlong(availableMemoryUnit, availableMemoryBytesVal);
+ ulong memoryUsage = ConvertStringToUlong(root.GetProperty(nameof(Stats.MemoryUsage).ToSnakeCase()).GetString());
+ ulong totalMemoryUsage = ConvertStringToUlong(root.GetProperty(nameof(Stats.TotalMemory).ToSnakeCase()).GetString());
+ ulong availableMemory = ConvertStringToUlong(root.GetProperty(nameof(Stats.AvailableMemory).ToSnakeCase()).GetString());
var runtime = root.GetProperty(nameof(Stats.RunTime).ToSnakeCase()).GetUInt64();
ulong startTime = root.GetProperty(nameof(Stats.StartTime).ToSnakeCase()).GetUInt64();
- string? readBytesString = root.GetProperty(nameof(Stats.ReadBytes).ToSnakeCase()).GetString();
- string[] readBytesStringSplit = readBytesString.Split(' ');
- (float readBytesVal, string readBytesUnit) = (ParseFloat(readBytesStringSplit[0]), readBytesStringSplit[1]);
- ulong readBytes = ConvertStringBytesToUlong(readBytesUnit, readBytesVal);
- string? writtenBytesString = root.GetProperty(nameof(Stats.WrittenBytes).ToSnakeCase()).GetString();
- string[] writtenBytesStringSplit = writtenBytesString.Split(' ');
- (float writtenBytesVal, string writtenBytesUnit) = (ParseFloat(writtenBytesStringSplit[0]), writtenBytesStringSplit[1]);
- ulong writtenBytes = ConvertStringBytesToUlong(writtenBytesUnit, writtenBytesVal);
- string? messageWrittenSizeBytesString = root.GetProperty(nameof(Stats.MessagesSizeBytes).ToSnakeCase()).GetString();
- string[] messageWrittenSizeBytesStringSplit = messageWrittenSizeBytesString.Split(' ');
- (float messageWrittenSizeBytesVal, string messageWrittenSizeBytesUnit) = (ParseFloat(messageWrittenSizeBytesStringSplit[0]), messageWrittenSizeBytesStringSplit[1]);
- ulong messageWrittenSizeBytes = ConvertStringBytesToUlong(messageWrittenSizeBytesUnit, messageWrittenSizeBytesVal);
+ ulong readBytes = ConvertStringToUlong(root.GetProperty(nameof(Stats.ReadBytes).ToSnakeCase()).GetString());
+ ulong writtenBytes = ConvertStringToUlong(root.GetProperty(nameof(Stats.WrittenBytes).ToSnakeCase()).GetString());
+ ulong messageWrittenSizeBytes = ConvertStringToUlong(root.GetProperty(nameof(Stats.MessagesSizeBytes).ToSnakeCase()).GetString());
int streamsCount = root.GetProperty(nameof(Stats.StreamsCount).ToSnakeCase()).GetInt32();
int topicsCount = root.GetProperty(nameof(Stats.TopicsCount).ToSnakeCase()).GetInt32();
int partitionsCount = root.GetProperty(nameof(Stats.PartitionsCount).ToSnakeCase()).GetInt32();
@@ -76,6 +56,8 @@ public class StatsResponseConverter : JsonConverter<StatsResponse>
string? osVersion = root.GetProperty(nameof(Stats.OsVersion).ToSnakeCase()).GetString();
string? kernelVersion = root.GetProperty(nameof(Stats.KernelVersion).ToSnakeCase()).GetString();
string? iggyVersion = root.GetProperty(nameof(Stats.IggyServerVersion).ToSnakeCase()).GetString();
+ uint iggyServerSemver = root.GetProperty(nameof(Stats.IggyServerSemver).ToSnakeCase()).GetUInt32();
+
return new StatsResponse
{
@@ -83,13 +65,13 @@ public class StatsResponseConverter : JsonConverter<StatsResponse>
ClientsCount = clientsCount,
ConsumerGroupsCount = consumerGroupsCount,
CpuUsage = cpuUsage,
- Hostname = hostname,
- KernelVersion = kernelVersion,
+ Hostname = hostname ?? string.Empty,
+ KernelVersion = kernelVersion ?? string.Empty,
MemoryUsage = memoryUsage,
MessagesCount = messagesCount,
MessagesSizeBytes = messageWrittenSizeBytes,
- OsName = osName,
- OsVersion = osVersion,
+ OsName = osName ?? string.Empty,
+ OsVersion = osVersion ?? string.Empty,
PartitionsCount = partitionsCount,
ProcessId = processId,
ReadBytes = readBytes,
@@ -101,11 +83,29 @@ public class StatsResponseConverter : JsonConverter<StatsResponse>
TotalCpuUsage = totalCpuUsage,
TotalMemory = totalMemoryUsage,
WrittenBytes = writtenBytes,
- IggyVersion = iggyVersion
+ IggyVersion = iggyVersion ?? string.Empty,
+ IggyServerSemver = iggyServerSemver
};
}
+ private ulong ConvertStringToUlong(string? usage)
+ {
+ if(usage is null)
+ {
+ return 0;
+ }
+
+ var usageStringSplit = usage.Split(' ');
+ if (usageStringSplit.Length != 2)
+ {
+ throw new InvalidEnumArgumentException($"Error Wrong format when deserializing MemoryUsage: {usage}");
+ }
+
+ var (memoryUsageBytesVal, memoryUnit) = (ParseFloat(usageStringSplit[0]), usageStringSplit[1]);
+ return ConvertStringBytesToUlong(memoryUnit, memoryUsageBytesVal);
+ }
+
private static ulong ConvertStringBytesToUlong(string memoryUnit, float memoryUsageBytesVal)
{
float memoryUsage = memoryUnit switch
diff --git a/foreign/csharp/Iggy_SDK/JsonConfiguration/StreamResponseConverter.cs b/foreign/csharp/Iggy_SDK/JsonConfiguration/StreamResponseConverter.cs
index 3c7dd200..894b6466 100644
--- a/foreign/csharp/Iggy_SDK/JsonConfiguration/StreamResponseConverter.cs
+++ b/foreign/csharp/Iggy_SDK/JsonConfiguration/StreamResponseConverter.cs
@@ -33,17 +33,22 @@ public sealed class StreamResponseConverter : JsonConverter<StreamResponse>
var createdAt = root.GetProperty(nameof(StreamResponse.CreatedAt).ToSnakeCase()).GetUInt64();
var name = root.GetProperty(nameof(StreamResponse.Name).ToSnakeCase()).GetString();
var sizeBytesString = root.GetProperty(nameof(StreamResponse.Size).ToSnakeCase()).GetString();
- var sizeBytesStringSplit = sizeBytesString.Split(' ');
- var (sizeBytesVal, Unit) = (ulong.Parse(sizeBytesStringSplit[0]), sizeBytesStringSplit[1]);
- var sizeBytes = Unit switch
+ ulong sizeBytes = 0;
+ if (sizeBytesString is not null)
{
- "B" => sizeBytesVal,
- "KB" => sizeBytesVal * (ulong)1e03,
- "MB" => sizeBytesVal * (ulong)1e06,
- "GB" => sizeBytesVal * (ulong)1e09,
- "TB" => sizeBytesVal * (ulong)1e12,
- _ => throw new InvalidEnumArgumentException("Error Wrong Unit when deserializing SizeBytes")
- };
+ var sizeBytesStringSplit = sizeBytesString.Split(' ');
+ var (sizeBytesVal, unit) = (ulong.Parse(sizeBytesStringSplit[0]), sizeBytesStringSplit[1]);
+ sizeBytes = unit switch
+ {
+ "B" => sizeBytesVal,
+ "KB" => sizeBytesVal * (ulong)1e03,
+ "MB" => sizeBytesVal * (ulong)1e06,
+ "GB" => sizeBytesVal * (ulong)1e09,
+ "TB" => sizeBytesVal * (ulong)1e12,
+ _ => throw new InvalidEnumArgumentException("Error Wrong Unit when deserializing SizeBytes")
+ };
+ }
+
var messagesCount = root.GetProperty(nameof(StreamResponse.MessagesCount).ToSnakeCase()).GetUInt64();
var topicsCount = root.GetProperty(nameof(StreamResponse.TopicsCount).ToSnakeCase()).GetInt32();
root.TryGetProperty(nameof(StreamResponse.Topics).ToSnakeCase(), out var topicsProperty);
@@ -63,7 +68,7 @@ public sealed class StreamResponseConverter : JsonConverter<StreamResponse>
CreatedAt = DateTimeOffsetUtils.FromUnixTimeMicroSeconds(createdAt).LocalDateTime,
MessagesCount = messagesCount,
TopicsCount = topicsCount,
- Topics = topics
+ Topics = topics ?? []
};
}
diff --git a/foreign/csharp/Iggy_SDK/JsonConfiguration/TopicResponseConverter.cs b/foreign/csharp/Iggy_SDK/JsonConfiguration/TopicResponseConverter.cs
index 9a52dcd1..b77a0d40 100644
--- a/foreign/csharp/Iggy_SDK/JsonConfiguration/TopicResponseConverter.cs
+++ b/foreign/csharp/Iggy_SDK/JsonConfiguration/TopicResponseConverter.cs
@@ -26,13 +26,6 @@ namespace Apache.Iggy.JsonConfiguration;
internal sealed class TopicResponseConverter : JsonConverter<TopicResponse>
{
- private readonly JsonSerializerOptions _options;
- public TopicResponseConverter()
- {
- _options = new JsonSerializerOptions();
- _options.PropertyNamingPolicy = new ToSnakeCaseNamingPolicy();
- }
-
public override TopicResponse? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using var doc = JsonDocument.ParseValue(ref reader);
@@ -42,35 +35,24 @@ internal sealed class TopicResponseConverter : JsonConverter<TopicResponse>
var name = root.GetProperty(nameof(TopicResponse.Name).ToSnakeCase()).GetString();
var compressionAlgorithm = Enum.Parse<CompressionAlgorithm>(root.GetProperty(nameof(TopicResponse.CompressionAlgorithm).ToSnakeCase()).GetString()!, true);
var sizeBytesString = root.GetProperty(nameof(TopicResponse.Size).ToSnakeCase()).GetString();
- var sizeBytesStringSplit = sizeBytesString.Split(' ');
- var (sizeBytesVal, Unit) = (ulong.Parse(sizeBytesStringSplit[0]), sizeBytesStringSplit[1]);
- var sizeBytes = Unit switch
+ ulong sizeBytes = 0;
+ if (sizeBytesString is not null)
{
- "B" => sizeBytesVal,
- "KB" => sizeBytesVal * (ulong)1e03,
- "MB" => sizeBytesVal * (ulong)1e06,
- "GB" => sizeBytesVal * (ulong)1e09,
- "TB" => sizeBytesVal * (ulong)1e12,
- _ => throw new InvalidEnumArgumentException("Error Wrong Unit when deserializing SizeBytes")
- };
+ var sizeBytesStringSplit = sizeBytesString.Split(' ');
+ var (sizeBytesVal, unit) = (ulong.Parse(sizeBytesStringSplit[0]), sizeBytesStringSplit[1]);
+ sizeBytes = unit switch
+ {
+ "B" => sizeBytesVal,
+ "KB" => sizeBytesVal * (ulong)1e03,
+ "MB" => sizeBytesVal * (ulong)1e06,
+ "GB" => sizeBytesVal * (ulong)1e09,
+ "TB" => sizeBytesVal * (ulong)1e12,
+ _ => throw new InvalidEnumArgumentException("Error Wrong Unit when deserializing SizeBytes")
+ };
+ }
+
var replicationFactor = root.GetProperty(nameof(TopicResponse.ReplicationFactor).ToSnakeCase()).GetUInt16();
var maxTopicSize = root.GetProperty(nameof(TopicResponse.MaxTopicSize).ToSnakeCase()).GetUInt64();
- // var maxTopicSizeString = root.GetProperty(nameof(TopicResponse.MaxTopicSize).ToSnakeCase()).GetUInt64();
- // ulong maxTopicSize = 0;
- // if (maxTopicSizeString is not null)
- // {
- // var maxTopicSizeStringSplit = maxTopicSizeString.Split(' ');
- // (ulong maxTopicSizeVal, string maxTopicUnit) = (ulong.Parse(maxTopicSizeStringSplit[0]), maxTopicSizeStringSplit[1]);
- // maxTopicSize = Unit switch
- // {
- // "B" => maxTopicSizeVal,
- // "KB" => maxTopicSizeVal * (ulong)1e03,
- // "MB" => maxTopicSizeVal * (ulong)1e06,
- // "GB" => maxTopicSizeVal * (ulong)1e09,
- // "TB" => maxTopicSizeVal * (ulong)1e12,
- // _ => throw new InvalidEnumArgumentException("Error Wrong Unit when deserializing SizeBytes")
- // };
- // }
var messageExpiryProperty = root.GetProperty(nameof(TopicResponse.MessageExpiry).ToSnakeCase());
var messageExpiry = messageExpiryProperty.ValueKind switch
@@ -118,17 +100,22 @@ internal sealed class TopicResponseConverter : JsonConverter<TopicResponse>
var currentOffset = partition.GetProperty(nameof(PartitionContract.CurrentOffset).ToSnakeCase())
.GetUInt64();
var sizeBytesString = partition.GetProperty(nameof(PartitionContract.Size).ToSnakeCase()).GetString();
- var sizeBytesStringSplit = sizeBytesString.Split(' ');
- var (sizeBytesVal, Unit) = (ulong.Parse(sizeBytesStringSplit[0]), sizeBytesStringSplit[1]);
- ulong sizeBytes = Unit switch
+ ulong sizeBytes = 0;
+ if (sizeBytesString is not null)
{
- "B" => sizeBytesVal,
- "KB" => sizeBytesVal * (ulong)1e03,
- "MB" => sizeBytesVal * (ulong)1e06,
- "GB" => sizeBytesVal * (ulong)1e09,
- "TB" => sizeBytesVal * (ulong)1e12,
- _ => throw new InvalidEnumArgumentException("Error Wrong Unit when deserializing SizeBytes")
- };
+ var sizeBytesStringSplit = sizeBytesString.Split(' ');
+ var (sizeBytesVal, unit) = (ulong.Parse(sizeBytesStringSplit[0]), sizeBytesStringSplit[1]);
+ sizeBytes = unit switch
+ {
+ "B" => sizeBytesVal,
+ "KB" => sizeBytesVal * (ulong)1e03,
+ "MB" => sizeBytesVal * (ulong)1e06,
+ "GB" => sizeBytesVal * (ulong)1e09,
+ "TB" => sizeBytesVal * (ulong)1e12,
+ _ => throw new InvalidEnumArgumentException("Error Wrong Unit when deserializing SizeBytes")
+ };
+ }
+
var messagesCount = partition.GetProperty(nameof(PartitionContract.MessagesCount).ToSnakeCase())
.GetUInt64();
partitions.Add(new PartitionContract
diff --git a/foreign/csharp/Iggy_SDK/JsonConfiguration/UserResponseConverter.cs b/foreign/csharp/Iggy_SDK/JsonConfiguration/UserResponseConverter.cs
deleted file mode 100644
index 7ea50ca9..00000000
--- a/foreign/csharp/Iggy_SDK/JsonConfiguration/UserResponseConverter.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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.Json;
-using System.Text.Json.Serialization;
-using Apache.Iggy.Contracts.Http.Auth;
-
-namespace Apache.Iggy.JsonConfiguration;
-
-public sealed class UserResponseConverter : JsonConverter<UserResponse>
-{
-
- public override UserResponse? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- {
- throw new NotImplementedException();
- }
- public override void Write(Utf8JsonWriter writer, UserResponse value, JsonSerializerOptions options)
- {
- throw new NotImplementedException();
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK/Mappers/BinaryMapper.cs b/foreign/csharp/Iggy_SDK/Mappers/BinaryMapper.cs
index f4a1a5ad..4dc89310 100644
--- a/foreign/csharp/Iggy_SDK/Mappers/BinaryMapper.cs
+++ b/foreign/csharp/Iggy_SDK/Mappers/BinaryMapper.cs
@@ -238,7 +238,7 @@ internal static class BinaryMapper
{
StreamId = streamId,
TopicId = topicId,
- ConsumerGroupId = consumerGroupId
+ GroupId = consumerGroupId
};
consumerGroups.Add(consumerGroup);
position += 12;
@@ -258,7 +258,7 @@ internal static class BinaryMapper
{
if (payload.Length == 0)
{
- return Array.Empty<ClientResponse>();
+ return [];
}
var response = new List<ClientResponse>();
@@ -316,19 +316,6 @@ internal static class BinaryMapper
};
}
- private static MessageState MapMessageState(ReadOnlySpan<byte> payload, int position)
- {
- var state = payload[position + 8] switch
- {
- 1 => MessageState.Available,
- 10 => MessageState.Unavailable,
- 20 => MessageState.Poisoned,
- 30 => MessageState.MarkedForDeletion,
- _ => throw new ArgumentOutOfRangeException()
- };
- return state;
- }
-
internal static PolledMessages MapMessages(ReadOnlySpan<byte> payload,
Func<byte[], byte[]>? decryptor = null)
{
@@ -669,7 +656,7 @@ internal static class BinaryMapper
ulong createdAt = BinaryPrimitives.ReadUInt64LittleEndian(payload[(position + 4)..(position + 12)]);
int partitionsCount = BinaryPrimitives.ReadInt32LittleEndian(payload[(position + 12)..(position + 16)]);
ulong messageExpiry = BinaryPrimitives.ReadUInt64LittleEndian(payload[(position + 16)..(position + 24)]);
- byte complessionAlgoritm = payload[position + 24];
+ byte compressionAlgorithm = payload[position + 24];
ulong maxTopicSize = BinaryPrimitives.ReadUInt64LittleEndian(payload[(position + 25)..(position + 33)]);
byte replicationFactor = payload[position + 33];
ulong sizeBytes = BinaryPrimitives.ReadUInt64LittleEndian(payload[(position + 34)..(position + 42)]);
@@ -684,7 +671,7 @@ internal static class BinaryMapper
Id = id,
PartitionsCount = partitionsCount,
Name = name,
- CompressionAlgorithm = (CompressionAlgorithm)complessionAlgoritm,
+ CompressionAlgorithm = (CompressionAlgorithm)compressionAlgorithm,
MessagesCount = messagesCount,
Size = sizeBytes,
CreatedAt = DateTimeOffsetUtils.FromUnixTimeMicroSeconds(createdAt).LocalDateTime,
@@ -842,7 +829,7 @@ internal static class BinaryMapper
private static (ConsumerGroupMember, int readBytes) MapToMember(ReadOnlySpan<byte> payload, int position)
{
- var id = BinaryPrimitives.ReadInt32LittleEndian(payload[position..(position + 4)]);
+ var id = BinaryPrimitives.ReadUInt32LittleEndian(payload[position..(position + 4)]);
var partitionsCount = BinaryPrimitives.ReadInt32LittleEndian(payload[(position + 4)..(position + 8)]);
var partitions = new List<int>();
for (int i = 0; i < partitionsCount; i++)
diff --git a/foreign/csharp/Iggy_SDK_Tests/ContractTests/TcpContract.cs b/foreign/csharp/Iggy_SDK_Tests/ContractTests/TcpContract.cs
index cbc03c24..a5bb9759 100644
--- a/foreign/csharp/Iggy_SDK_Tests/ContractTests/TcpContract.cs
+++ b/foreign/csharp/Iggy_SDK_Tests/ContractTests/TcpContract.cs
@@ -180,7 +180,7 @@ public sealed class TcpContract
{
UserId = Identifier.Numeric(1),
Username = "newusername",
- UserStatus = UserStatus.Active
+ UserStatus = UserStatus.Inactive
};
// Act
@@ -214,10 +214,11 @@ public sealed class TcpContract
position += 1;
if (statusFlag == 1)
{
- var userStatus = statusFlag switch
+ var userStatus = result[position] switch
{
1 => UserStatus.Active,
- 2 => UserStatus.Inactive
+ 2 => UserStatus.Inactive,
+ _ => throw new ArgumentOutOfRangeException()
};
Assert.Equal(request.UserStatus, userStatus);
}
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/ConsumerGroupE2E.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/ConsumerGroupE2E.cs
deleted file mode 100644
index 4f6bb240..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/ConsumerGroupE2E.cs
+++ /dev/null
@@ -1,199 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Exceptions;
-using Apache.Iggy.Tests.E2ETests.Fixtures;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.Utils;
-using Apache.Iggy.Tests.Utils.Groups;
-using FluentAssertions;
-
-namespace Apache.Iggy.Tests.E2ETests;
-
-[TestCaseOrderer("Apache.Iggy.Tests.Utils.PriorityOrderer", "Apache.Iggy.Tests")]
-public sealed class ConsumerGroupE2E : IClassFixture<IggyConsumerGroupFixture>
-{
- private const string SkipMessage = "TCP implementation needs to be aligned with Iggy core changes";
-
- private readonly IggyConsumerGroupFixture _fixture;
-
- private const int GROUP_ID = 1;
-
- private static readonly CreateConsumerGroupRequest _createConsumerGroupRequest =
- ConsumerGroupFactory.CreateRequest(
- (int)ConsumerGroupFixtureBootstrap.StreamRequest.StreamId!,
- (int)ConsumerGroupFixtureBootstrap.TopicRequest.TopicId!, GROUP_ID);
-
- private static readonly JoinConsumerGroupRequest _joinConsumerGroupRequest =
- ConsumerGroupFactory.CreateJoinGroupRequest(
- (int)ConsumerGroupFixtureBootstrap.StreamRequest.StreamId,
- (int)ConsumerGroupFixtureBootstrap.TopicRequest.TopicId, GROUP_ID);
-
- private static readonly LeaveConsumerGroupRequest _leaveConsumerGroupRequest =
- ConsumerGroupFactory.CreateLeaveGroupRequest(
- (int)ConsumerGroupFixtureBootstrap.StreamRequest.StreamId,
- (int)ConsumerGroupFixtureBootstrap.TopicRequest.TopicId, GROUP_ID);
-
- private static readonly DeleteConsumerGroupRequest _deleteConsumerGroupRequest =
- ConsumerGroupFactory.CreateDeleteGroupRequest(
- (int)ConsumerGroupFixtureBootstrap.StreamRequest.StreamId,
- (int)ConsumerGroupFixtureBootstrap.TopicRequest.TopicId, GROUP_ID);
-
- private Identifier ConsumerGroupId = Identifier.Numeric(GROUP_ID);
-
- public ConsumerGroupE2E(IggyConsumerGroupFixture fixture)
- {
- _fixture = fixture;
- }
-
- [Fact, TestPriority(1)]
- public async Task CreateConsumerGroup_HappyPath_Should_CreateConsumerGroup_Successfully()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var consumerGroup = await sut.Client.CreateConsumerGroupAsync(_createConsumerGroupRequest);
- consumerGroup.Should().NotBeNull();
- consumerGroup!.Id.Should().Be(GROUP_ID);
- consumerGroup.PartitionsCount.Should().Be(ConsumerGroupFixtureBootstrap.TopicRequest.PartitionsCount);
- consumerGroup.MembersCount.Should().Be(0);
- consumerGroup.Name.Should().Be(_createConsumerGroupRequest.Name);
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(2)]
- public async Task CreateConsumerGroup_Should_Throw_InvalidResponse()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.CreateConsumerGroupAsync(_createConsumerGroupRequest))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(3)]
- public async Task GetConsumerGroupById_Should_Return_ValidResponse()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var response = await sut.Client.GetConsumerGroupByIdAsync(
- Identifier.Numeric((int)ConsumerGroupFixtureBootstrap.StreamRequest.StreamId!), Identifier.Numeric((int)ConsumerGroupFixtureBootstrap.TopicRequest.TopicId!),
- ConsumerGroupId);
-
- response.Should().NotBeNull();
- response!.Id.Should().Be(GROUP_ID);
- response.PartitionsCount.Should().Be(ConsumerGroupFixtureBootstrap.TopicRequest.PartitionsCount);
- response.MembersCount.Should().Be(0);
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(4)]
- public async Task GetConsumerGroups_Should_Return_ValidResponse()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var response = await sut.Client.GetConsumerGroupsAsync(
- Identifier.Numeric((int)ConsumerGroupFixtureBootstrap.StreamRequest.StreamId!), Identifier.Numeric((int)ConsumerGroupFixtureBootstrap.TopicRequest.TopicId!));
-
- response.Should().NotBeNull();
- response.Count.Should().Be(1);
- var group = response.FirstOrDefault();
- group!.Id.Should().Be(GROUP_ID);
- group.PartitionsCount.Should().Be(ConsumerGroupFixtureBootstrap.TopicRequest.PartitionsCount);
- group.MembersCount.Should().Be(0);
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(5)]
- public async Task JoinConsumerGroup_Should_JoinConsumerGroup_Successfully()
- {
- // act & assert
- await _fixture.HttpClient.Client.Invoking(y =>
- y.JoinConsumerGroupAsync(_joinConsumerGroupRequest)
- ).Should()
- .ThrowExactlyAsync<FeatureUnavailableException>();
-
- await _fixture.TcpClient.Client.Invoking(x => x.JoinConsumerGroupAsync(_joinConsumerGroupRequest))
- .Should()
- .NotThrowAsync();
- }
-
- [Fact, TestPriority(6)]
- public async Task LeaveConsumerGroup_Should_LeaveConsumerGroup_Successfully()
- {
- // act & assert
- await _fixture.HttpClient.Client.Invoking(x => x.LeaveConsumerGroupAsync(_leaveConsumerGroupRequest))
- .Should()
- .ThrowAsync<FeatureUnavailableException>();
-
- await _fixture.TcpClient.Client.Invoking(x => x.LeaveConsumerGroupAsync(_leaveConsumerGroupRequest))
- .Should()
- .NotThrowAsync();
- }
-
- [Fact, TestPriority(7)]
- public async Task DeleteConsumerGroup_Should_DeleteConsumerGroup_Successfully()
- {
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.DeleteConsumerGroupAsync(_deleteConsumerGroupRequest))
- .Should()
- .NotThrowAsync();
- })).ToArray();
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(8)]
- public async Task JoinConsumerGroup_Should_Throw_InvalidResponse()
- {
- // act & assert
- await _fixture.HttpClient.Client.Invoking(x => x.LeaveConsumerGroupAsync(_leaveConsumerGroupRequest))
- .Should()
- .ThrowAsync<FeatureUnavailableException>();
-
- await _fixture.TcpClient.Client.Invoking(x => x.JoinConsumerGroupAsync(_joinConsumerGroupRequest))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- }
-
- [Fact, TestPriority(9)]
- public async Task DeleteConsumerGroup_Should_Throw_InvalidResponse()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.DeleteConsumerGroupAsync(_deleteConsumerGroupRequest))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-}
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/FetchMessagesE2E.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/FetchMessagesE2E.cs
deleted file mode 100644
index 5061b775..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/FetchMessagesE2E.cs
+++ /dev/null
@@ -1,158 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Exceptions;
-using Apache.Iggy.Tests.E2ETests.Fixtures;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.Utils;
-using Apache.Iggy.Tests.Utils.Messages;
-using FluentAssertions;
-
-namespace Apache.Iggy.Tests.E2ETests;
-
-[TestCaseOrderer("Apache.Iggy.Tests.Utils.PriorityOrderer", "Apache.Iggy.Tests")]
-public sealed class FetchMessagesE2E : IClassFixture<IggyFetchMessagesFixture>
-{
- private const string SkipMessage = "TCP implementation needs to be aligned with Iggy core changes";
- private readonly IggyFetchMessagesFixture _fixture;
-
- private static readonly MessageFetchRequest _messageFetchRequest =
- MessageFactory.CreateMessageFetchRequestConsumer(10, FetchMessagesFixtureBootstrap.StreamId,
- FetchMessagesFixtureBootstrap.TopicId, FetchMessagesFixtureBootstrap.PartitionId);
-
- private static readonly MessageFetchRequest _headersMessageFetchRequest =
- MessageFactory.CreateMessageFetchRequestConsumer(10, FetchMessagesFixtureBootstrap.StreamId,
- FetchMessagesFixtureBootstrap.HeadersTopicId, FetchMessagesFixtureBootstrap.PartitionId);
-
- private static readonly MessageFetchRequest _invalidFetchRequest =
- MessageFactory.CreateMessageFetchRequestConsumer(10, FetchMessagesFixtureBootstrap.InvalidStreamId,
- FetchMessagesFixtureBootstrap.InvalidTopicId, FetchMessagesFixtureBootstrap.PartitionId);
- public FetchMessagesE2E(IggyFetchMessagesFixture fixture)
- {
- _fixture = fixture;
- }
-
- [Fact, TestPriority(1)]
- public async Task PollMessagesTMessage_WithNoHeaders_Should_PollMessages_Successfully()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var response = await sut.Client.FetchMessagesAsync(_messageFetchRequest, MessageFactory.DeserializeDummyMessage);
- response.Messages.Count.Should().Be(10);
- response.PartitionId.Should().Be(FetchMessagesFixtureBootstrap.PartitionId);
- response.CurrentOffset.Should().Be(19);
- foreach (var responseMessage in response.Messages)
- {
- responseMessage.UserHeaders.Should().BeNull();
- responseMessage.Message.Text.Should().NotBeNullOrEmpty();
- }
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(2)]
- public async Task PollMessagesTMessage_Should_Throw_InvalidResponse()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.FetchMessagesAsync(_invalidFetchRequest, MessageFactory.DeserializeDummyMessage))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(3)]
- public async Task PollMessages_WithNoHeaders_Should_PollMessages_Successfully()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var response = await sut.Client.FetchMessagesAsync(_messageFetchRequest);
- response.Messages.Count.Should().Be(10);
- response.PartitionId.Should().Be(FetchMessagesFixtureBootstrap.PartitionId);
- response.CurrentOffset.Should().Be(19);
- foreach (var responseMessage in response.Messages)
- {
- responseMessage.UserHeaders.Should().BeNull();
- responseMessage.Payload.Should().NotBeNull();
- responseMessage.Payload.Length.Should().BeGreaterThan(0);
- }
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(4)]
- public async Task PollMessages_Should_Throw_InvalidResponse()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.FetchMessagesAsync(_invalidFetchRequest))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(5)]
- public async Task PollMessages_WithHeaders_Should_PollMessages_Successfully()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var response = await sut.Client.FetchMessagesAsync(_headersMessageFetchRequest);
- response.Messages.Count.Should().Be(10);
- response.PartitionId.Should().Be(FetchMessagesFixtureBootstrap.PartitionId);
- response.CurrentOffset.Should().Be(19);
- foreach (var responseMessage in response.Messages)
- {
- responseMessage.UserHeaders.Should().NotBeNull();
- responseMessage.UserHeaders!.Count.Should().Be(3);
- }
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(6)]
- public async Task PollMessagesTMessage_WithHeaders_Should_PollMessages_Successfully()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var response = await sut.Client.FetchMessagesAsync(_headersMessageFetchRequest, MessageFactory.DeserializeDummyMessage);
- response.Messages.Count.Should().Be(10);
- response.PartitionId.Should().Be(FetchMessagesFixtureBootstrap.PartitionId);
- response.CurrentOffset.Should().Be(19);
- foreach (var responseMessage in response.Messages)
- {
- responseMessage.UserHeaders.Should().NotBeNull();
- responseMessage.UserHeaders!.Count.Should().Be(3);
- }
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-}
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/ConsumerGroupFixtureBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/ConsumerGroupFixtureBootstrap.cs
deleted file mode 100644
index a663bb80..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/ConsumerGroupFixtureBootstrap.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-using Apache.Iggy.Tests.Utils.Streams;
-using Apache.Iggy.Tests.Utils.Topics;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-
-public class ConsumerGroupFixtureBootstrap : IIggyBootstrap
-{
- public static readonly StreamRequest StreamRequest = StreamFactory.CreateStreamRequest();
- public static readonly TopicRequest TopicRequest = TopicFactory.CreateTopicRequest();
-
- public async Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient)
- {
- await tcpClient.Client.CreateStreamAsync(StreamRequest);
- await tcpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
-
- await httpClient.Client.CreateStreamAsync(StreamRequest);
- await httpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/FetchMessagesFixtureBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/FetchMessagesFixtureBootstrap.cs
deleted file mode 100644
index 589f58eb..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/FetchMessagesFixtureBootstrap.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-using Apache.Iggy.Tests.Utils.Messages;
-using Apache.Iggy.Tests.Utils.Streams;
-using Apache.Iggy.Tests.Utils.Topics;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-
-public class FetchMessagesFixtureBootstrap : IIggyBootstrap
-{
- private static readonly StreamRequest StreamRequest = StreamFactory.CreateStreamRequest();
- private static readonly StreamRequest NonExistingStreamRequest = StreamFactory.CreateStreamRequest();
- private static readonly TopicRequest NonExistingTopicRequest = TopicFactory.CreateTopicRequest(3000);
- private static readonly TopicRequest TopicRequest = TopicFactory.CreateTopicRequest();
- private static readonly TopicRequest HeadersTopicRequest = TopicFactory.CreateTopicRequest();
-
- public static readonly int StreamId = (int)StreamRequest.StreamId!;
- public static readonly int TopicId = (int)TopicRequest.TopicId!;
- public static readonly int HeadersTopicId = (int)HeadersTopicRequest.TopicId!;
-
- public static readonly int InvalidStreamId = (int)NonExistingStreamRequest.StreamId!;
- public static readonly int InvalidTopicId = (int)NonExistingTopicRequest.TopicId!;
- public const int PartitionId = 1;
-
- public async Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient)
- {
- await tcpClient.Client.CreateStreamAsync(StreamRequest);
- await tcpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
- await tcpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId), HeadersTopicRequest);
-
- var request = MessageFactory.CreateMessageSendRequest(
- (int)StreamRequest.StreamId, (int)TopicRequest.TopicId!, PartitionId,
- MessageFactory.GenerateMessages(20));
- var requestWithHeaders = MessageFactory.CreateMessageSendRequest(
- (int)StreamRequest.StreamId, (int)HeadersTopicRequest.TopicId!, PartitionId,
- MessageFactory.GenerateMessages(20, MessageFactory.GenerateMessageHeaders(3)));
- await tcpClient.Client.SendMessagesAsync(request);
- await tcpClient.Client.SendMessagesAsync(requestWithHeaders);
- await Task.Delay(1000);
-
- await httpClient.Client.CreateStreamAsync(StreamRequest);
- await httpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
- await httpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId), HeadersTopicRequest);
-
- await httpClient.Client.SendMessagesAsync(request);
- await httpClient.Client.SendMessagesAsync(requestWithHeaders);
- await Task.Delay(1000);
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/FlushMessagesFixtureBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/FlushMessagesFixtureBootstrap.cs
deleted file mode 100644
index bf4f8b74..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/FlushMessagesFixtureBootstrap.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-using Apache.Iggy.Tests.Utils.Messages;
-using Apache.Iggy.Tests.Utils.Streams;
-using Apache.Iggy.Tests.Utils.Topics;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-
-public class FlushMessagesFixtureBootstrap : IIggyBootstrap
-{
- private static readonly StreamRequest StreamRequest = StreamFactory.CreateStreamRequest();
- private static readonly StreamRequest NonExistingStreamRequest = StreamFactory.CreateStreamRequest();
- private static readonly TopicRequest NonExistingTopicRequest = TopicFactory.CreateTopicRequest(3000);
- private static readonly TopicRequest TopicRequest = TopicFactory.CreateTopicRequest();
- private static readonly TopicRequest HeadersTopicRequest = TopicFactory.CreateTopicRequest();
-
- public static readonly int StreamId = (int)StreamRequest.StreamId!;
- public static readonly int TopicId = (int)TopicRequest.TopicId!;
- public static readonly int HeadersTopicId = (int)HeadersTopicRequest.TopicId!;
-
- public static readonly int InvalidStreamId = (int)NonExistingStreamRequest.StreamId!;
- public static readonly int InvalidTopicId = (int)NonExistingTopicRequest.TopicId!;
- public const int PartitionId = 1;
-
- public async Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient)
- {
- await tcpClient.Client.CreateStreamAsync(StreamRequest);
- await tcpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
-
- var request = MessageFactory.CreateMessageSendRequest(
- (int)StreamRequest.StreamId, (int)TopicRequest.TopicId!, PartitionId,
- MessageFactory.GenerateMessages(20));
- await tcpClient.Client.SendMessagesAsync(request);
- await Task.Delay(1000);
-
- await httpClient.Client.CreateStreamAsync(StreamRequest);
- await httpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
-
- await httpClient.Client.SendMessagesAsync(request);
- await Task.Delay(1000);
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/GeneralFixtureBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/GeneralFixtureBootstrap.cs
deleted file mode 100644
index ad00699b..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/GeneralFixtureBootstrap.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-
-public class GeneralFixtureBootstrap : IIggyBootstrap
-{
- public Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient)
- {
- return Task.CompletedTask;
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/OffsetFixtureBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/OffsetFixtureBootstrap.cs
deleted file mode 100644
index 98f58366..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/OffsetFixtureBootstrap.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-using Apache.Iggy.Tests.Utils.Streams;
-using Apache.Iggy.Tests.Utils.Topics;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-
-public class OffsetFixtureBootstrap : IIggyBootstrap
-{
- public static readonly StreamRequest StreamRequest = StreamFactory.CreateStreamRequest();
- public static readonly TopicRequest TopicRequest = TopicFactory.CreateTopicRequest();
- public async Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient)
- {
- await tcpClient.Client.CreateStreamAsync(StreamRequest);
- await tcpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
-
- await httpClient.Client.CreateStreamAsync(StreamRequest);
- await httpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/PATFixtureBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/PATFixtureBootstrap.cs
deleted file mode 100644
index 6d17e6f3..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/PATFixtureBootstrap.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http.Auth;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-
-public class PATFixtureBootstrap : IIggyBootstrap
-{
- public static readonly CreatePersonalAccessTokenRequest CreatePersonalAccessTokenRequest = new()
- {
- Name = "test",
- Expiry = 694200000
- };
- public Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient)
- {
- return Task.CompletedTask;
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/PartitionsFixtureBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/PartitionsFixtureBootstrap.cs
deleted file mode 100644
index 593f82fa..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/PartitionsFixtureBootstrap.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-using Apache.Iggy.Tests.Utils.Streams;
-using Apache.Iggy.Tests.Utils.Topics;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-
-public class PartitionsFixtureBootstrap : IIggyBootstrap
-{
- public static readonly StreamRequest StreamRequest = StreamFactory.CreateStreamRequest();
- public static readonly TopicRequest TopicRequest = TopicFactory.CreateTopicRequest();
- public async Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient)
- {
- await tcpClient.Client.CreateStreamAsync(StreamRequest);
- await tcpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
-
- await httpClient.Client.CreateStreamAsync(StreamRequest);
- await httpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/PollMessagesFixtureBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/PollMessagesFixtureBootstrap.cs
deleted file mode 100644
index e6f286ea..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/PollMessagesFixtureBootstrap.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Kinds;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-using Apache.Iggy.Tests.Utils.DummyObj;
-using Apache.Iggy.Tests.Utils.Messages;
-using Apache.Iggy.Tests.Utils.Streams;
-using Apache.Iggy.Tests.Utils.Topics;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-
-public class PollMessagesFixtureBootstrap : IIggyBootstrap
-{
- private static readonly StreamRequest StreamRequest = StreamFactory.CreateStreamRequest();
- private static readonly TopicRequest TopicRequest = TopicFactory.CreateTopicRequest();
- private static readonly TopicRequest HeadersTopicRequest = TopicFactory.CreateTopicRequest();
- public const int MessageCount = 100;
-
- public static readonly int StreamId = (int)StreamRequest.StreamId!;
- public static readonly int TopicId = (int)TopicRequest.TopicId!;
- public static readonly int HeadersTopicId = (int)HeadersTopicRequest.TopicId!;
-
- public const int PartitionId = 1;
- public const int HeadersCount = 3;
-
- public async Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient)
- {
- await tcpClient.Client.CreateStreamAsync(StreamRequest);
- await tcpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
- await tcpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId), HeadersTopicRequest);
- await tcpClient.Client.SendMessagesAsync(new MessageSendRequest<DummyMessage>
- {
- Messages = MessageFactory.GenerateDummyMessages(MessageCount),
- Partitioning = Partitioning.PartitionId(PartitionId),
- StreamId = Identifier.Numeric(StreamId),
- TopicId = Identifier.Numeric(TopicId)
- },
- MessageFactory.Serializer,
- headers: MessageFactory.GenerateMessageHeaders(HeadersCount));
-
- await httpClient.Client.CreateStreamAsync(StreamRequest);
- await httpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
- await httpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId), HeadersTopicRequest);
- await httpClient.Client.SendMessagesAsync(new MessageSendRequest<DummyMessage>
- {
- Messages = MessageFactory.GenerateDummyMessages(MessageCount),
- Partitioning = Partitioning.PartitionId(PartitionId),
- StreamId = Identifier.Numeric(StreamId),
- TopicId = Identifier.Numeric(TopicId)
- },
- MessageFactory.Serializer,
- headers: MessageFactory.GenerateMessageHeaders(HeadersCount));
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/SendMessagesFixtureBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/SendMessagesFixtureBootstrap.cs
deleted file mode 100644
index 2cb50886..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/SendMessagesFixtureBootstrap.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-using Apache.Iggy.Tests.Utils.Streams;
-using Apache.Iggy.Tests.Utils.Topics;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-
-public class SendMessagesFixtureBootstrap : IIggyBootstrap
-{
- private static readonly StreamRequest StreamRequest = StreamFactory.CreateStreamRequest();
- private static readonly StreamRequest NonExistingStreamRequest = StreamFactory.CreateStreamRequest();
- private static readonly TopicRequest NonExistingTopicRequest = TopicFactory.CreateTopicRequest();
- private static readonly TopicRequest TopicRequest = TopicFactory.CreateTopicRequest();
-
- public static readonly int StreamId = (int)StreamRequest.StreamId!;
- public static readonly int TopicId = (int)TopicRequest.TopicId!;
-
- public static readonly int InvalidStreamId = (int)NonExistingStreamRequest.StreamId!;
- public static readonly int InvalidTopicId = (int)NonExistingTopicRequest.TopicId!;
-
- public const int PartitionId = 1;
- public async Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient)
- {
- await tcpClient.Client.CreateStreamAsync(StreamRequest);
- await tcpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
-
- await httpClient.Client.CreateStreamAsync(StreamRequest);
- await httpClient.Client.CreateTopicAsync(Identifier.Numeric((int)StreamRequest.StreamId!), TopicRequest);
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/StreamsFixtureBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/StreamsFixtureBootstrap.cs
deleted file mode 100644
index 056ff939..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/StreamsFixtureBootstrap.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-using Apache.Iggy.Tests.Utils.Streams;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-
-public class StreamsFixtureBootstrap : IIggyBootstrap
-{
- public static readonly StreamRequest StreamRequest = StreamFactory.CreateStreamRequest();
- public static readonly UpdateStreamRequest UpdateStreamRequest = StreamFactory.CreateUpdateStreamRequest();
- public Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient)
- {
- return Task.CompletedTask;
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/SystemFixtureBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/SystemFixtureBootstrap.cs
deleted file mode 100644
index af0d3993..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/SystemFixtureBootstrap.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http.Auth;
-using Apache.Iggy.Enums;
-using Apache.Iggy.Factory;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-using Microsoft.Extensions.Logging.Abstractions;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-
-public class SystemFixtureBootstrap : IIggyBootstrap
-{
- private const int FRESH_CLIENTS_COUNT = 6;
-
- public const int TotalClientsCount = FRESH_CLIENTS_COUNT + 1;
-
- public async Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient)
- {
- for (int i = 0; i < FRESH_CLIENTS_COUNT; i++)
- {
- var client = MessageStreamFactory.CreateMessageStream(options =>
- {
- options.BaseAdress = $"127.0.0.1:{tcpClient.TcpPort}";
- options.Protocol = Protocol.Tcp;
- options.MessageBatchingSettings = x =>
- {
- x.MaxMessagesPerBatch = 1000;
- x.Interval = TimeSpan.FromMilliseconds(100);
- };
- }, NullLoggerFactory.Instance);
- await client.LoginUser(new LoginUserRequest
- {
- Password = "iggy",
- Username = "iggy"
- });
- }
-
- for (int i = 0; i < TotalClientsCount; i++)
- {
- var client = MessageStreamFactory.CreateMessageStream(options =>
- {
- options.BaseAdress = $"127.0.0.1:{httpClient.TcpPort}";
- options.Protocol = Protocol.Tcp;
- options.MessageBatchingSettings = x =>
- {
- x.MaxMessagesPerBatch = 1000;
- x.Interval = TimeSpan.FromMilliseconds(100);
- };
- }, NullLoggerFactory.Instance);
- await client.LoginUser(new LoginUserRequest
- {
- Password = "iggy",
- Username = "iggy"
- });
- }
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/TopicsFixtureBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/TopicsFixtureBootstrap.cs
deleted file mode 100644
index 6547f0df..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/TopicsFixtureBootstrap.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-using Apache.Iggy.Tests.Utils.Streams;
-using Apache.Iggy.Tests.Utils.Topics;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-
-public class TopicsFixtureBootstrap : IIggyBootstrap
-{
- public static readonly StreamRequest StreamRequest = StreamFactory.CreateStreamRequest();
- public static readonly TopicRequest TopicRequest = TopicFactory.CreateTopicRequest();
- public static readonly TopicRequest TopicRequestSecond = TopicFactory.CreateTopicRequest();
- public static readonly UpdateTopicRequest UpdateTopicRequest = TopicFactory.CreateUpdateTopicRequest();
-
-
- public async Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient)
- {
- await tcpClient.Client.CreateStreamAsync(StreamRequest);
- await httpClient.Client.CreateStreamAsync(StreamRequest);
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/UsersFixtureBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/UsersFixtureBootstrap.cs
deleted file mode 100644
index 58219c65..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Bootstraps/UsersFixtureBootstrap.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http.Auth;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-using Apache.Iggy.Tests.Utils.Users;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-
-public class UsersFixtureBootstrap : IIggyBootstrap
-{
- public static CreateUserRequest UserRequest = UsersFactory.CreateUserRequest("user1", "user1");
- public static Permissions UpdatePermissionsRequest = UsersFactory.CreatePermissions();
- public const string NewUsername = "new_username";
-
- public Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient)
- {
- return Task.CompletedTask;
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Configs/IggyFixtureClientConfigs.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Configs/IggyFixtureClientConfigs.cs
deleted file mode 100644
index bc9109bc..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Configs/IggyFixtureClientConfigs.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-// 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 Apache.Iggy.Configuration;
-using Apache.Iggy.Enums;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-public static class IggyFixtureClientMessagingSettings
-{
- public static Action<MessagePollingSettings> PollingSettings { get; set; } = options =>
- {
- options.Interval = TimeSpan.FromMilliseconds(100);
- options.StoreOffsetStrategy = StoreOffset.WhenMessagesAreReceived;
- };
- public static Action<MessageBatchingSettings> BatchingSettings { get; set; } = options =>
- {
- options.Interval = TimeSpan.FromMilliseconds(100);
- options.MaxMessagesPerBatch = 1000;
- options.MaxRequests = 4096;
- };
-
- public static Action<MessageBatchingSettings> BatchingSettingsSendFixture { get; set; } = options =>
- {
- options.Enabled = false;
- options.Interval = TimeSpan.FromMilliseconds(100);
- options.MaxMessagesPerBatch = 1000;
- options.MaxRequests = 4096;
- };
-
- public static Action<MessageBatchingSettings> BatchingSettingsFetchFixture { get; set; } = options =>
- {
- options.Enabled = false;
- options.Interval = TimeSpan.FromMilliseconds(100);
- options.MaxMessagesPerBatch = 1000;
- options.MaxRequests = 8912;
- };
-
- public static Action<MessageBatchingSettings> BatchingSettingsPollMessagesFixture { get; set; } = options =>
- {
- options.Enabled = true;
- options.Interval = TimeSpan.FromMilliseconds(99);
- options.MaxMessagesPerBatch = 1000;
- options.MaxRequests = 8912;
- };
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IIggyBootstrap.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IIggyBootstrap.cs
deleted file mode 100644
index 23986cf1..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IIggyBootstrap.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public interface IIggyBootstrap
-{
- public Task BootstrapResourcesAsync(IggyClientModel httpClient, IggyClientModel tcpClient);
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyBaseFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyBaseFixture.cs
deleted file mode 100644
index 840fe486..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyBaseFixture.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-// 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 Apache.Iggy.Configuration;
-using Apache.Iggy.Contracts.Http.Auth;
-using Apache.Iggy.Enums;
-using Apache.Iggy.Factory;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-using DotNet.Testcontainers.Builders;
-using DotNet.Testcontainers.Containers;
-using Microsoft.Extensions.Logging.Abstractions;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public abstract class IggyBaseFixture : IAsyncLifetime
-{
- private readonly IIggyBootstrap _bootstraper;
- private readonly Action<MessagePollingSettings> _pollingSettings;
- private readonly Action<MessageBatchingSettings> _batchingSettings;
-
- private readonly IContainer _tcpContainer = new ContainerBuilder().WithImage("apache/iggy:edge")
- // Container name is just to be used locally for debbuging effects
- //.WithName($"SutIggyContainerTCP")
- .WithPortBinding(3000, true)
- .WithPortBinding(8090, true)
- .WithOutputConsumer(Consume.RedirectStdoutAndStderrToConsole())
- .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(8090))
- //.WithEnvironment("IGGY_SYSTEM_LOGGING_LEVEL", "debug")
- //.WithEnvironment("RUST_LOG", "trace")
- .WithCleanUp(true)
- .Build();
-
- private readonly IContainer _httpContainer = new ContainerBuilder().WithImage("apache/iggy:edge")
- // Container name is just to be used locally for debbuging effects
- //.WithName($"SutIggyContainerHTTP")
- .WithPortBinding(3000, true)
- .WithPortBinding(8090, true)
- .WithOutputConsumer(Consume.RedirectStdoutAndStderrToConsole())
- .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(3000))
- //.WithEnvironment("IGGY_SYSTEM_LOGGING_LEVEL", "debug")
- //.WithEnvironment("RUST_LOG", "trace")
- .WithCleanUp(true)
- .Build();
-
- public IggyClientModel[] SubjectsUnderTest { get; } = new IggyClientModel[2];
- public IggyClientModel TcpClient => SubjectsUnderTest[0];
- public IggyClientModel HttpClient => SubjectsUnderTest[1];
-
- protected IggyBaseFixture(IIggyBootstrap bootstraper, Action<MessagePollingSettings> pollingSettings,
- Action<MessageBatchingSettings> batchingSettings)
- {
- _bootstraper = bootstraper;
- _pollingSettings = pollingSettings;
- _batchingSettings = batchingSettings;
- }
-
- public async Task InitializeAsync()
- {
- await _tcpContainer.StartAsync();
- await _httpContainer.StartAsync();
- var tcpClient = new IggyClientModel { Name = "Tcp" };
- var httpClient = new IggyClientModel { Name = "Http" };
-
- tcpClient.TcpPort = _tcpContainer.GetMappedPublicPort(8090);
- tcpClient.HttpPort = _tcpContainer.GetMappedPublicPort(3000);
-
- httpClient.TcpPort = _httpContainer.GetMappedPublicPort(8090);
- httpClient.HttpPort = _httpContainer.GetMappedPublicPort(3000);
-
- tcpClient.Client = MessageStreamFactory.CreateMessageStream(options =>
- {
- options.BaseAdress = $"127.0.0.1:{tcpClient.TcpPort}";
- options.Protocol = Protocol.Tcp;
- options.MessageBatchingSettings = _batchingSettings;
- options.MessagePollingSettings = _pollingSettings;
- }, NullLoggerFactory.Instance);
-
- await tcpClient.Client.LoginUser(new LoginUserRequest
- {
- Password = "iggy",
- Username = "iggy"
- });
-
- httpClient.Client = MessageStreamFactory.CreateMessageStream(options =>
- {
- options.BaseAdress = $"http://127.0.0.1:{httpClient.HttpPort}";
- options.Protocol = Protocol.Http;
- options.MessageBatchingSettings = _batchingSettings;
- options.MessagePollingSettings = _pollingSettings;
- }, NullLoggerFactory.Instance);
- await httpClient.Client.LoginUser(new LoginUserRequest
- {
- Password = "iggy",
- Username = "iggy"
- });
-
- SubjectsUnderTest[0] = tcpClient;
- SubjectsUnderTest[1] = httpClient;
-
- await _bootstraper.BootstrapResourcesAsync(httpClient, tcpClient);
- }
-
- public async Task DisposeAsync()
- {
- await _tcpContainer.StopAsync();
- await _httpContainer.StopAsync();
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyConsumerGroupFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyConsumerGroupFixture.cs
deleted file mode 100644
index af2e1c4e..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyConsumerGroupFixture.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public sealed class IggyConsumerGroupFixture : IggyBaseFixture
-{
- public IggyConsumerGroupFixture() : base(new ConsumerGroupFixtureBootstrap(),
- IggyFixtureClientMessagingSettings.PollingSettings, IggyFixtureClientMessagingSettings.BatchingSettings)
- {
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyFetchMessagesFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyFetchMessagesFixture.cs
deleted file mode 100644
index 4dd15e54..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyFetchMessagesFixture.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public sealed class IggyFetchMessagesFixture : IggyBaseFixture
-{
- public IggyFetchMessagesFixture() : base(new FetchMessagesFixtureBootstrap(),
- IggyFixtureClientMessagingSettings.PollingSettings, IggyFixtureClientMessagingSettings.BatchingSettingsFetchFixture)
- {
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyFlushMessagesFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyFlushMessagesFixture.cs
deleted file mode 100644
index df7d05f5..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyFlushMessagesFixture.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public sealed class IggyFlushMessagesFixture : IggyBaseFixture
-{
- public IggyFlushMessagesFixture() : base(new FlushMessagesFixtureBootstrap(),
- IggyFixtureClientMessagingSettings.PollingSettings, IggyFixtureClientMessagingSettings.BatchingSettingsFetchFixture)
- {
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyGeneralFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyGeneralFixture.cs
deleted file mode 100644
index 42f06ff5..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyGeneralFixture.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public sealed class IggyGeneralFixture : IggyBaseFixture
-{
- public IggyGeneralFixture() : base(new GeneralFixtureBootstrap(),
- IggyFixtureClientMessagingSettings.PollingSettings,
- IggyFixtureClientMessagingSettings.BatchingSettings)
- {
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyOffsetFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyOffsetFixture.cs
deleted file mode 100644
index 0b5636ec..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyOffsetFixture.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public sealed class IggyOffsetFixture : IggyBaseFixture
-{
- public IggyOffsetFixture() : base(new OffsetFixtureBootstrap(),
- IggyFixtureClientMessagingSettings.PollingSettings,
- IggyFixtureClientMessagingSettings.BatchingSettings)
- {
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyPATFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyPATFixture.cs
deleted file mode 100644
index 8b7a3334..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyPATFixture.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public sealed class IggyPATFixture : IggyBaseFixture
-{
- public IggyPATFixture() : base(new PATFixtureBootstrap(),
- IggyFixtureClientMessagingSettings.PollingSettings,
- IggyFixtureClientMessagingSettings.BatchingSettings)
- {
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyPartitionFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyPartitionFixture.cs
deleted file mode 100644
index cb312ddf..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyPartitionFixture.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public sealed class IggyPartitionFixture : IggyBaseFixture
-{
- public IggyPartitionFixture() : base(new PartitionsFixtureBootstrap(),
- IggyFixtureClientMessagingSettings.PollingSettings,
- IggyFixtureClientMessagingSettings.BatchingSettings
- )
- {
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyPollMessagesFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyPollMessagesFixture.cs
deleted file mode 100644
index 26a22141..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyPollMessagesFixture.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public sealed class IggyPollMessagesFixture : IggyBaseFixture
-{
- public IggyPollMessagesFixture() : base(new PollMessagesFixtureBootstrap(),
- IggyFixtureClientMessagingSettings.PollingSettings,
- IggyFixtureClientMessagingSettings.BatchingSettingsPollMessagesFixture)
- {
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggySendMessagesFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggySendMessagesFixture.cs
deleted file mode 100644
index 5416c247..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggySendMessagesFixture.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public sealed class IggySendMessagesFixture : IggyBaseFixture
-{
- public IggySendMessagesFixture() : base(new SendMessagesFixtureBootstrap(),
- IggyFixtureClientMessagingSettings.PollingSettings,
- IggyFixtureClientMessagingSettings.BatchingSettingsSendFixture)
- {
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyStreamFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyStreamFixture.cs
deleted file mode 100644
index ef47c351..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyStreamFixture.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public sealed class IggyStreamFixture : IggyBaseFixture
-{
- public IggyStreamFixture() : base(new StreamsFixtureBootstrap(),
- IggyFixtureClientMessagingSettings.PollingSettings,
- IggyFixtureClientMessagingSettings.BatchingSettings)
- {
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggySystemFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggySystemFixture.cs
deleted file mode 100644
index 54cc39ce..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggySystemFixture.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public sealed class IggySystemFixture : IggyBaseFixture
-{
- public IggySystemFixture() : base(new SystemFixtureBootstrap(),
- IggyFixtureClientMessagingSettings.PollingSettings, IggyFixtureClientMessagingSettings.BatchingSettings)
- {
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyTcpUsersFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyTcpUsersFixture.cs
deleted file mode 100644
index 818480ee..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyTcpUsersFixture.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public sealed class IggyTcpUsersFixture : IggyBaseFixture
-{
- public IggyTcpUsersFixture() : base(new UsersFixtureBootstrap(),
- IggyFixtureClientMessagingSettings.PollingSettings,
- IggyFixtureClientMessagingSettings.BatchingSettings)
- {
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyTopicFixture.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyTopicFixture.cs
deleted file mode 100644
index c33993ca..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/IggyTopicFixture.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Configs;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures;
-
-public sealed class IggyTopicFixture : IggyBaseFixture
-{
- public IggyTopicFixture() : base(new TopicsFixtureBootstrap(),
- IggyFixtureClientMessagingSettings.PollingSettings,
- IggyFixtureClientMessagingSettings.BatchingSettings)
- {
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Models/IggyClientModel.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Models/IggyClientModel.cs
deleted file mode 100644
index 426e8706..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/Fixtures/Models/IggyClientModel.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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 Apache.Iggy.IggyClient;
-
-namespace Apache.Iggy.Tests.E2ETests.Fixtures.Models;
-
-public class IggyClientModel
-{
- public string Name { get; set; }
- public IIggyClient Client { get; set; }
- public int HttpPort { get; set; }
- public int TcpPort { get; set; }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/FlushMessagesE2E.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/FlushMessagesE2E.cs
deleted file mode 100644
index daafe1a2..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/FlushMessagesE2E.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Exceptions;
-using Apache.Iggy.Tests.E2ETests.Fixtures;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.Utils;
-using FluentAssertions;
-
-namespace Apache.Iggy.Tests.E2ETests;
-
-[TestCaseOrderer("Apache.Iggy.Tests.Utils.PriorityOrderer", "Apache.Iggy.Tests")]
-public sealed class FlushMessagesE2E : IClassFixture<IggyFlushMessagesFixture>
-{
- private const string SkipMessage = "TCP implementation needs to be aligned with Iggy core changes";
- private readonly IggyFlushMessagesFixture _fixture;
-
- private static readonly FlushUnsavedBufferRequest _flushRequestFsync = new()
- {
- StreamId = Identifier.Numeric(FlushMessagesFixtureBootstrap.StreamId),
- TopicId = Identifier.Numeric(FlushMessagesFixtureBootstrap.TopicId),
- PartitionId = FlushMessagesFixtureBootstrap.PartitionId,
- Fsync = true
- };
-
- private static readonly FlushUnsavedBufferRequest _flushRequest = new()
- {
- StreamId = Identifier.Numeric(FlushMessagesFixtureBootstrap.StreamId),
- TopicId = Identifier.Numeric(FlushMessagesFixtureBootstrap.TopicId),
- PartitionId = FlushMessagesFixtureBootstrap.PartitionId,
- Fsync = false
- };
-
- private static readonly FlushUnsavedBufferRequest _flushInvalidStreamRequest = new()
- {
- StreamId = Identifier.Numeric(FlushMessagesFixtureBootstrap.InvalidStreamId),
- TopicId = Identifier.Numeric(FlushMessagesFixtureBootstrap.TopicId),
- PartitionId = FlushMessagesFixtureBootstrap.PartitionId,
- Fsync = false
- };
-
-
- public FlushMessagesE2E(IggyFlushMessagesFixture fixture)
- {
- _fixture = fixture;
- }
-
- [Fact, TestPriority(1)]
- public async Task FlushUnsavedBuffer_WithFsync_Should_Flush_Successfully()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.FlushUnsavedBufferAsync(_flushRequestFsync))
- .Should()
- .NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(2)]
- public async Task FlushUnsavedBuffer_WithOutFsync_Should_Flush_Successfully()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.FlushUnsavedBufferAsync(_flushRequest))
- .Should()
- .NotThrowAsync();
-
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(3)]
- public async Task FlushUnsavedBuffer_Should_Throw_WhenStream_DoesNotExist()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.FlushUnsavedBufferAsync(_flushInvalidStreamRequest))
- .Should()
- .ThrowAsync<InvalidResponseException>();
-
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-}
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/OffsetE2E.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/OffsetE2E.cs
deleted file mode 100644
index d8b8abd6..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/OffsetE2E.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Tests.E2ETests.Fixtures;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.Utils;
-using Apache.Iggy.Tests.Utils.Offsets;
-using FluentAssertions;
-
-namespace Apache.Iggy.Tests.E2ETests;
-
-[TestCaseOrderer("Apache.Iggy.Tests.Utils.PriorityOrderer", "Apache.Iggy.Tests")]
-public sealed class OffsetE2E : IClassFixture<IggyOffsetFixture>
-{
- private const string SkipMessage = "TCP implementation needs to be aligned with Iggy core changes";
- private readonly IggyOffsetFixture _fixture;
- private readonly StoreOffsetRequest _storeOffsetIndividualConsumer;
- private readonly OffsetRequest _offsetIndividualConsumer;
-
- private const int GET_INDIVIDUAL_CONSUMER_ID = 1;
- private const int GET_PARTITION_ID = 1;
- private const ulong GET_OFFSET = 0;
-
- public OffsetE2E(IggyOffsetFixture fixture)
- {
- _fixture = fixture;
- _storeOffsetIndividualConsumer = OffsetFactory.CreateOffsetContract(
- (int)OffsetFixtureBootstrap.StreamRequest.StreamId!, (int)OffsetFixtureBootstrap.TopicRequest.TopicId!, GET_INDIVIDUAL_CONSUMER_ID, GET_OFFSET,
- GET_PARTITION_ID);
- _offsetIndividualConsumer = OffsetFactory.CreateOffsetRequest((int)OffsetFixtureBootstrap.StreamRequest.StreamId,
- (int)OffsetFixtureBootstrap.TopicRequest.TopicId, GET_PARTITION_ID, GET_INDIVIDUAL_CONSUMER_ID);
- }
-
- [Fact, TestPriority(1)]
- public async Task StoreOffset_IndividualConsumer_Should_StoreOffset_Successfully()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select( sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.StoreOffsetAsync(_storeOffsetIndividualConsumer))
- .Should()
- .NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(2)]
- public async Task GetOffset_IndividualConsumer_Should_GetOffset_Successfully()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select( sut => Task.Run(async () =>
- {
- var offset = await sut.Client.GetOffsetAsync(_offsetIndividualConsumer);
- offset.Should().NotBeNull();
- offset!.StoredOffset.Should().Be(_storeOffsetIndividualConsumer.Offset);
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-}
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/PATE2E.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/PATE2E.cs
deleted file mode 100644
index fe8520a0..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/PATE2E.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http.Auth;
-using Apache.Iggy.Exceptions;
-using Apache.Iggy.Tests.E2ETests.Fixtures;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.Utils;
-using FluentAssertions;
-using FluentAssertions.Common;
-
-namespace Apache.Iggy.Tests.E2ETests;
-
-
-[TestCaseOrderer("Apache.Iggy.Tests.Utils.PriorityOrderer", "Apache.Iggy.Tests")]
-public sealed class PATE2E : IClassFixture<IggyPATFixture>
-{
- private const string SkipMessage = "TCP implementation needs to be aligned with Iggy core changes";
- private readonly IggyPATFixture _fixture;
-
- public PATE2E(IggyPATFixture fixture)
- {
- _fixture = fixture;
- }
-
- [Fact, TestPriority(1)]
- public async Task CreatePersonalAccessToken_HappyPath_Should_CreatePersonalAccessToken_Successfully()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.CreatePersonalAccessTokenAsync(PATFixtureBootstrap.CreatePersonalAccessTokenRequest))
- .Should()
- .NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(2)]
- public async Task CreatePersonalAccessToken_Duplicate_Should_Throw_InvalidResponse()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.CreatePersonalAccessTokenAsync(PATFixtureBootstrap.CreatePersonalAccessTokenRequest))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(3)]
- public async Task GetPersonalAccessTokens_Should_ReturnValidResponse()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select( sut => Task.Run(async () =>
- {
- var response = await sut.Client.GetPersonalAccessTokensAsync();
- response.Should().NotBeNull();
- response.Count.Should().Be(1);
- response[0].Name.Should().Be(PATFixtureBootstrap.CreatePersonalAccessTokenRequest.Name);
- var tokenExpiryDateTimeOffset = DateTime.UtcNow.AddMicroseconds((double)PATFixtureBootstrap.CreatePersonalAccessTokenRequest.Expiry!).ToDateTimeOffset();
- response[0].ExpiryAt!.Value.Date.Should().Be(tokenExpiryDateTimeOffset.LocalDateTime.Date);
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(4)]
- public async Task LoginWithPersonalAccessToken_Should_Be_Successfull()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var response = await sut.Client.CreatePersonalAccessTokenAsync(new CreatePersonalAccessTokenRequest
- {
- Name = "test-login",
- Expiry = 69420
- });
- await sut.Client.LogoutUser();
- await sut.Invoking(x => x.Client.LoginWithPersonalAccessToken(new LoginWithPersonalAccessToken
- {
- Token = response!.Token
- })).Should().NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(5)]
- public async Task DeletePersonalAccessToken_Should_DeletePersonalAccessToken_Successfully()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.DeletePersonalAccessTokenAsync(new DeletePersonalAccessTokenRequest
- {
- Name = PATFixtureBootstrap.CreatePersonalAccessTokenRequest.Name
- }))
- .Should()
- .NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-}
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/PartitionsE2E.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/PartitionsE2E.cs
deleted file mode 100644
index 05d904e1..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/PartitionsE2E.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Exceptions;
-using Apache.Iggy.Tests.E2ETests.Fixtures;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.Utils;
-using Apache.Iggy.Tests.Utils.Partitions;
-using FluentAssertions;
-
-namespace Apache.Iggy.Tests.E2ETests;
-
-[TestCaseOrderer("Apache.Iggy.Tests.Utils.PriorityOrderer", "Apache.Iggy.Tests")]
-public sealed class PartitionsE2E : IClassFixture<IggyPartitionFixture>
-{
- private readonly IggyPartitionFixture _fixture;
- private readonly CreatePartitionsRequest _partitionsRequest;
- private readonly DeletePartitionsRequest _deletePartitionsRequest;
- public PartitionsE2E(IggyPartitionFixture fixture)
- {
- _fixture = fixture;
- _partitionsRequest =
- PartitionFactory.CreatePartitionsRequest((int)PartitionsFixtureBootstrap.StreamRequest.StreamId!, (int)PartitionsFixtureBootstrap.TopicRequest.TopicId!);
- _deletePartitionsRequest = PartitionFactory.CreateDeletePartitionsRequest((int)PartitionsFixtureBootstrap.StreamRequest.StreamId,
- (int)PartitionsFixtureBootstrap.TopicRequest.TopicId, _partitionsRequest.PartitionsCount);
- }
-
- [Fact, TestPriority(1)]
- public async Task CreatePartition_HappyPath_Should_CreatePartition_Successfully()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select( sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.CreatePartitionsAsync(_partitionsRequest))
- .Should()
- .NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(2)]
- public async Task DeletePartition_Should_DeletePartition_Successfully()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select( sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.DeletePartitionsAsync(_deletePartitionsRequest))
- .Should()
- .NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(3)]
- public async Task DeletePartition_Should_Throw_WhenTopic_DoesNotExist()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select( sut => Task.Run(async () =>
- {
- await sut.Client.CreatePartitionsAsync(_partitionsRequest);
- await sut.Client.DeleteTopicAsync(Identifier.Numeric((int)PartitionsFixtureBootstrap.StreamRequest.StreamId!),
- Identifier.Numeric((int)PartitionsFixtureBootstrap.TopicRequest.TopicId!));
- await sut.Invoking(x => x.Client.DeletePartitionsAsync(_deletePartitionsRequest))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(4)]
- public async Task DeletePartition_Should_Throw_WhenStream_DoesNotExist()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select( sut => Task.Run(async () =>
- {
- await sut.Client.CreateTopicAsync(Identifier.Numeric((int)PartitionsFixtureBootstrap.StreamRequest.StreamId!), PartitionsFixtureBootstrap.TopicRequest);
- await sut.Client.DeleteStreamAsync(Identifier.Numeric((int)PartitionsFixtureBootstrap.StreamRequest.StreamId));
- await sut.Client.Invoking(x => x.DeletePartitionsAsync(_deletePartitionsRequest))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/PollMessagesE2E.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/PollMessagesE2E.cs
deleted file mode 100644
index a1e67102..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/PollMessagesE2E.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Kinds;
-using Apache.Iggy.Tests.E2ETests.Fixtures;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.Utils;
-using Apache.Iggy.Tests.Utils.Messages;
-using FluentAssertions;
-
-namespace Apache.Iggy.Tests.E2ETests;
-
-[TestCaseOrderer("Apache.Iggy.Tests.Utils.PriorityOrderer", "Apache.Iggy.Tests")]
-public sealed class PollMessagesE2E(IggyPollMessagesFixture fixture) : IClassFixture<IggyPollMessagesFixture>
-{
-
- [Fact, TestPriority(1)]
- public async Task PollMessagesTMessage_Should_PollMessages_Successfully()
- {
-
- var tasks = fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var i = 0;
- await foreach (var msgResponse in sut.Client.PollMessagesAsync(new PollMessagesRequest
- {
- Consumer = Consumer.New(1),
- Count = 10,
- PartitionId = PollMessagesFixtureBootstrap.PartitionId,
- PollingStrategy = PollingStrategy.Next(),
- StreamId = Identifier.Numeric(PollMessagesFixtureBootstrap.StreamId),
- TopicId = Identifier.Numeric(PollMessagesFixtureBootstrap.TopicId)
- }, MessageFactory.DeserializeDummyMessage))
- {
- msgResponse.UserHeaders.Should().NotBeNull();
- msgResponse.UserHeaders.Should().HaveCount(PollMessagesFixtureBootstrap.HeadersCount);
- i++;
- if (i == PollMessagesFixtureBootstrap.MessageCount)
- {
- break;
- }
- }
-
- i.Should().Be(PollMessagesFixtureBootstrap.MessageCount);
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/SendMessagesE2E.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/SendMessagesE2E.cs
deleted file mode 100644
index 3ecfe3e0..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/SendMessagesE2E.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http;
-using Apache.Iggy.Exceptions;
-using Apache.Iggy.Tests.E2ETests.Fixtures;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.Utils;
-using Apache.Iggy.Tests.Utils.Messages;
-using FluentAssertions;
-
-namespace Apache.Iggy.Tests.E2ETests;
-
-[TestCaseOrderer("Apache.Iggy.Tests.Utils.PriorityOrderer", "Apache.Iggy.Tests")]
-public sealed class SendMessagesE2E : IClassFixture<IggySendMessagesFixture>
-{
- private const string SkipMessage = "TCP implementation needs to be aligned with Iggy core changes";
- private readonly IggySendMessagesFixture _fixture;
-
- private readonly MessageSendRequest _messageNoHeadersSendRequest;
- private readonly MessageSendRequest _messageWithHeadersSendRequest;
- private readonly MessageSendRequest _invalidMessageNoHeadersSendRequest;
- private readonly MessageSendRequest _invalidMessageWithHeadersSendRequest;
-
- public SendMessagesE2E(IggySendMessagesFixture fixture)
- {
- _fixture = fixture;
-
- var messageWithHeaders = MessageFactory.GenerateDummyMessages(
- Random.Shared.Next(20, 50),
- Random.Shared.Next(69, 420),
- MessageFactory.GenerateMessageHeaders(2));
-
- _messageNoHeadersSendRequest = MessageFactory.CreateMessageSendRequest(SendMessagesFixtureBootstrap.StreamId,
- SendMessagesFixtureBootstrap.TopicId, SendMessagesFixtureBootstrap.PartitionId);
- _invalidMessageNoHeadersSendRequest = MessageFactory.CreateMessageSendRequest(SendMessagesFixtureBootstrap.InvalidStreamId,
- SendMessagesFixtureBootstrap.InvalidTopicId, SendMessagesFixtureBootstrap.PartitionId);
-
- _messageWithHeadersSendRequest = MessageFactory.CreateMessageSendRequest(SendMessagesFixtureBootstrap.StreamId,
- SendMessagesFixtureBootstrap.TopicId, SendMessagesFixtureBootstrap.PartitionId, messageWithHeaders);
- _invalidMessageWithHeadersSendRequest = MessageFactory.CreateMessageSendRequest(SendMessagesFixtureBootstrap.InvalidStreamId,
- SendMessagesFixtureBootstrap.InvalidTopicId, SendMessagesFixtureBootstrap.PartitionId, messageWithHeaders);
- }
-
- [Fact, TestPriority(1)]
- public async Task SendMessages_NoHeaders_Should_SendMessages_Successfully()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.SendMessagesAsync(_messageNoHeadersSendRequest))
- .Should()
- .NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(2)]
- public async Task SendMessages_NoHeaders_Should_Throw_InvalidResponse()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.SendMessagesAsync(_invalidMessageNoHeadersSendRequest))
- .Should()
- .ThrowAsync<InvalidResponseException>();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(3)]
- public async Task SendMessages_WithHeaders_Should_SendMessages_Successfully()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.SendMessagesAsync(_messageWithHeadersSendRequest))
- .Should()
- .NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(4)]
- public async Task SendMessages_WithHeaders_Should_Throw_InvalidResponse()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(x => x.Client.SendMessagesAsync(_invalidMessageWithHeadersSendRequest))
- .Should()
- .ThrowAsync<InvalidResponseException>();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-}
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/StreamsE2E.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/StreamsE2E.cs
deleted file mode 100644
index 5e7f4d0e..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/StreamsE2E.cs
+++ /dev/null
@@ -1,153 +0,0 @@
-// 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 Apache.Iggy.Exceptions;
-using Apache.Iggy.Tests.E2ETests.Fixtures;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.Utils;
-using FluentAssertions;
-
-namespace Apache.Iggy.Tests.E2ETests;
-
-[TestCaseOrderer("Apache.Iggy.Tests.Utils.PriorityOrderer", "Apache.Iggy.Tests")]
-public sealed class StreamsE2E : IClassFixture<IggyStreamFixture>
-{
- private readonly IggyStreamFixture _fixture;
-
- public StreamsE2E(IggyStreamFixture fixture)
- {
- _fixture = fixture;
- }
-
- [Fact, TestPriority(1)]
- public async Task CreateStream_HappyPath_Should_CreateStream_Successfully()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var response = await sut.Client.CreateStreamAsync(StreamsFixtureBootstrap.StreamRequest);
-
- response.Should().NotBeNull();
- response!.Id.Should().Be(StreamsFixtureBootstrap.StreamRequest.StreamId);
- response.Name.Should().Be(StreamsFixtureBootstrap.StreamRequest.Name);
- response.Size.Should().Be(0);
- response.CreatedAt.UtcDateTime.Should().BeAfter(DateTimeOffset.UtcNow.UtcDateTime.AddSeconds(-20));
- response.MessagesCount.Should().Be(0);
- response.TopicsCount.Should().Be(0);
- response.Topics.Should().BeEmpty();
- })).ToArray();
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(2)]
- public async Task CreateStream_Duplicate_Should_Throw_InvalidResponse()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x => await x.Client.CreateStreamAsync(StreamsFixtureBootstrap.StreamRequest))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- })).ToArray();
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(3)]
- public async Task GetStreamById_Should_ReturnValidResponse()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var response = await sut.Client.GetStreamByIdAsync(Identifier.Numeric((int)StreamsFixtureBootstrap.StreamRequest.StreamId!));
- response.Should().NotBeNull();
- response!.Id.Should().Be(StreamsFixtureBootstrap.StreamRequest.StreamId);
- response.Name.Should().Be(StreamsFixtureBootstrap.StreamRequest.Name);
- })).ToArray();
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(4)]
- public async Task UpdateStream_Should_UpdateStream_Successfully()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x => await x.Client.UpdateStreamAsync(Identifier.Numeric((int)StreamsFixtureBootstrap.StreamRequest.StreamId!), StreamsFixtureBootstrap.UpdateStreamRequest))
- .Should()
- .NotThrowAsync();
-
- var result = await sut.Client.GetStreamByIdAsync(Identifier.Numeric((int)StreamsFixtureBootstrap.StreamRequest.StreamId!));
- result.Should().NotBeNull();
- result!.Name.Should().Be(StreamsFixtureBootstrap.UpdateStreamRequest.Name);
- })).ToArray();
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(5)]
- public async Task PurgeStream_Should_PurgeStream_Successfully()
- {
- // act
- // TODO: Check if the stream is empty after purging
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x => await x.Client.PurgeStreamAsync(Identifier.Numeric((int)StreamsFixtureBootstrap.StreamRequest.StreamId!)))
- .Should()
- .NotThrowAsync();
- })).ToArray();
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(6)]
- public async Task DeleteStream_Should_DeleteStream_Successfully()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x => await x.Client.DeleteStreamAsync(Identifier.Numeric((int)StreamsFixtureBootstrap.StreamRequest.StreamId!)))
- .Should()
- .NotThrowAsync();
- })).ToArray();
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(7)]
- public async Task DeleteStream_Should_Throw_InvalidResponse()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x => await x.Client.DeleteStreamAsync(Identifier.Numeric((int)StreamsFixtureBootstrap.StreamRequest.StreamId!)))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- })).ToArray();
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(8)]
- public async Task GetStreamById_Should_Throw_InvalidResponse()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x =>
- await x.Client.GetStreamByIdAsync(Identifier.Numeric((int)StreamsFixtureBootstrap.StreamRequest.StreamId!)))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- })).ToArray();
- await Task.WhenAll(tasks);
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/SystemE2E.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/SystemE2E.cs
deleted file mode 100644
index c5d5e0f4..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/SystemE2E.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-// 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 Apache.Iggy.Tests.E2ETests.Fixtures;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.Utils;
-using FluentAssertions;
-
-namespace Apache.Iggy.Tests.E2ETests;
-
-[TestCaseOrderer("Apache.Iggy.Tests.Utils.PriorityOrderer", "Apache.Iggy.Tests")]
-public sealed class SystemE2E : IClassFixture<IggySystemFixture>
-{
- private readonly IggySystemFixture _fixture;
-
- public SystemE2E(IggySystemFixture fixture)
- {
- _fixture = fixture;
- }
-
- [Fact, TestPriority(1)]
- public async Task GetClients_Should_Return_CorrectClientsCount()
- {
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var clients = await sut.Client.GetClientsAsync();
- clients.Count.Should().Be(SystemFixtureBootstrap.TotalClientsCount);
- foreach (var client in clients)
- {
- client.ClientId.Should().NotBe(0);
- client.UserId.Should().Be(1);
- client.Address.Should().NotBeNullOrEmpty();
- client.Transport.Should().Be("TCP");
- }
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(2)]
- public async Task GetClient_Should_Return_CorrectClient()
- {
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var clients = await sut.Client.GetClientsAsync();
- clients.Count.Should().Be(SystemFixtureBootstrap.TotalClientsCount);
- uint id = clients[0].ClientId;
- var response = await sut.Client.GetClientByIdAsync(id);
- response!.ClientId.Should().Be(id);
- response.UserId.Should().Be(1);
- response.Address.Should().NotBeNullOrEmpty();
- response.Transport.Should().Be("TCP");
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(3)]
- public async Task GetMe_Should_Return_MyClient()
- {
- await _fixture.Invoking(x=>x.HttpClient.Client.GetMeAsync())
- .Should()
- .ThrowAsync<NotImplementedException>();
-
-
- var me = await _fixture.TcpClient.Client.GetMeAsync();
- me.Should().NotBeNull();
- me.ClientId.Should().NotBe(0);
- me.UserId.Should().Be(1);
- me.Address.Should().NotBeNullOrEmpty();
- me.Transport.Should().Be("TCP");
- }
-
- [Fact, TestPriority(4)]
- public async Task GetStats_Should_ReturnValidResponse()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var response = await sut.Client.GetStatsAsync();
- response.Should().NotBeNull();
- response!.MessagesCount.Should().Be(0);
- response.PartitionsCount.Should().Be(0);
- response.StreamsCount.Should().Be(0);
- response.TopicsCount.Should().Be(0);
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(5)]
- public async Task Ping_Should_Pong()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x => await x.Client.PingAsync())
- .Should()
- .NotThrowAsync();
-
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/TopicsE2E.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/TopicsE2E.cs
deleted file mode 100644
index 825d4da4..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/TopicsE2E.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-// 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 Apache.Iggy.Exceptions;
-using Apache.Iggy.Tests.E2ETests.Fixtures;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.Utils;
-using FluentAssertions;
-
-namespace Apache.Iggy.Tests.E2ETests;
-
-[TestCaseOrderer("Apache.Iggy.Tests.Utils.PriorityOrderer", "Apache.Iggy.Tests")]
-public sealed class TopicsE2E : IClassFixture<IggyTopicFixture>
-{
- private readonly IggyTopicFixture _fixture;
-
- public TopicsE2E(IggyTopicFixture fixture)
- {
- _fixture = fixture;
- }
-
- [Fact, TestPriority(1)]
- public async Task Create_NewTopic_Should_Return_Successfully()
- {
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var response = await sut.Client.CreateTopicAsync(Identifier.Numeric((int)TopicsFixtureBootstrap.StreamRequest.StreamId!), TopicsFixtureBootstrap.TopicRequest);
-
- response.Should().NotBeNull();
- response!.Id.Should().Be(TopicsFixtureBootstrap.TopicRequest.TopicId);
- response.Name.Should().Be(TopicsFixtureBootstrap.TopicRequest.Name);
- response.CompressionAlgorithm.Should().Be(TopicsFixtureBootstrap.TopicRequest.CompressionAlgorithm);
- response.Partitions.Should().HaveCount(TopicsFixtureBootstrap.TopicRequest.PartitionsCount);
- response.MessageExpiry.Should().Be(TopicsFixtureBootstrap.TopicRequest.MessageExpiry);
- response.Size.Should().Be(0);
- response.CreatedAt.UtcDateTime.Should().BeAfter(DateTimeOffset.UtcNow.UtcDateTime.AddSeconds(-20));
- })).ToArray();
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(2)]
- public async Task Create_DuplicateTopic_Should_Throw_InvalidResponse()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x =>
- await x.Client.CreateTopicAsync(Identifier.Numeric((int)TopicsFixtureBootstrap.StreamRequest.StreamId!), TopicsFixtureBootstrap.TopicRequest))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(3)]
- public async Task Get_ExistingTopic_Should_ReturnValidResponse()
- {
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var response = await sut.Client.GetTopicByIdAsync(Identifier.Numeric((int)TopicsFixtureBootstrap.StreamRequest.StreamId!),
- Identifier.Numeric((int)TopicsFixtureBootstrap.TopicRequest.TopicId!));
- response.Should().NotBeNull();
- response!.Id.Should().Be(TopicsFixtureBootstrap.TopicRequest.TopicId);
- response.Name.Should().Be(TopicsFixtureBootstrap.TopicRequest.Name);
- response.CompressionAlgorithm.Should().Be(TopicsFixtureBootstrap.TopicRequest.CompressionAlgorithm);
- response.Partitions.Should().HaveCount(TopicsFixtureBootstrap.TopicRequest.PartitionsCount);
- response.MessageExpiry.Should().Be(TopicsFixtureBootstrap.TopicRequest.MessageExpiry);
- response.Size.Should().Be(0);
- response.MessagesCount.Should().Be(0);
- response.MaxTopicSize.Should().Be(TopicsFixtureBootstrap.TopicRequest.MaxTopicSize);
- response.MessageExpiry.Should().Be(TopicsFixtureBootstrap.TopicRequest.MessageExpiry);
- response.CreatedAt.UtcDateTime.Year.Should().Be(DateTimeOffset.UtcNow.Year);
- response.CreatedAt.UtcDateTime.Month.Should().Be(DateTimeOffset.UtcNow.Month);
- response.CreatedAt.UtcDateTime.Day.Should().Be(DateTimeOffset.UtcNow.Day);
- response.CreatedAt.UtcDateTime.Minute.Should().Be(DateTimeOffset.UtcNow.Minute);
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(4)]
- public async Task Get_ExistingTopics_Should_ReturnValidResponse()
- {
- var createTasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x =>
- await x.Client.CreateTopicAsync(Identifier.Numeric((int)TopicsFixtureBootstrap.StreamRequest.StreamId!), TopicsFixtureBootstrap.TopicRequestSecond))
- .Should()
- .NotThrowAsync();
- })).ToArray();
- await Task.WhenAll(createTasks);
-
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- var response = await sut.Client.GetTopicsAsync(Identifier.Numeric((int)TopicsFixtureBootstrap.StreamRequest.StreamId!));
- response.Should().NotBeNull();
- response.Count.Should().Be(2);
- response.Select(x=>x.Id).Should().ContainSingle(x=> x== TopicsFixtureBootstrap.TopicRequest.TopicId);
- response.Select(x=>x.Id).Should().ContainSingle(x=> x== TopicsFixtureBootstrap.TopicRequestSecond.TopicId);
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(5)]
- public async Task Update_ExistingTopic_Should_UpdateTopic_Successfully()
- {
- // act
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x =>
- await x.Client.UpdateTopicAsync(Identifier.Numeric((int)TopicsFixtureBootstrap.StreamRequest.StreamId!),
- Identifier.Numeric((int)TopicsFixtureBootstrap.TopicRequest.TopicId!), TopicsFixtureBootstrap.UpdateTopicRequest))
- .Should()
- .NotThrowAsync();
-
- var result = await sut.Client.GetTopicByIdAsync(Identifier.Numeric((int)TopicsFixtureBootstrap.StreamRequest.StreamId!),
- Identifier.Numeric((int)TopicsFixtureBootstrap.TopicRequest.TopicId!));
- result.Should().NotBeNull();
- result!.Name.Should().Be(TopicsFixtureBootstrap.UpdateTopicRequest.Name);
- result.MessageExpiry.Should().Be(TopicsFixtureBootstrap.UpdateTopicRequest.MessageExpiry);
- result.CompressionAlgorithm.Should().Be(TopicsFixtureBootstrap.UpdateTopicRequest.CompressionAlgorithm);
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(6)]
- public async Task Purge_ExistingTopic_Should_PurgeTopic_Successfully()
- {
- // act
- // TODO: Check if the topic is empty after purge
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x =>
- await x.Client.PurgeTopicAsync(Identifier.Numeric((int)TopicsFixtureBootstrap.StreamRequest.StreamId!),
- Identifier.Numeric((int)TopicsFixtureBootstrap.TopicRequest.TopicId!)))
- .Should()
- .NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(7)]
- public async Task Delete_ExistingTopic_Should_DeleteTopic_Successfully()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x =>
- await x.Client.DeleteTopicAsync(Identifier.Numeric((int)TopicsFixtureBootstrap.StreamRequest.StreamId!),
- Identifier.Numeric((int)TopicsFixtureBootstrap.TopicRequest.TopicId!)))
- .Should()
- .NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(8)]
- public async Task Delete_NonExistingTopic_Should_Throw_InvalidResponse()
- {
- // act & assert
-
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x =>
- await x.Client.DeleteTopicAsync(Identifier.Numeric((int)TopicsFixtureBootstrap.StreamRequest.StreamId!),
- Identifier.Numeric((int)TopicsFixtureBootstrap.TopicRequest.TopicId!)))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(9)]
- public async Task Get_NonExistingTopic_Should_Throw_InvalidResponse()
- {
- // act & assert
-
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Invoking(async x =>
- await x.Client.GetTopicByIdAsync(Identifier.Numeric((int)TopicsFixtureBootstrap.StreamRequest.StreamId!),
- Identifier.Numeric((int)TopicsFixtureBootstrap.TopicRequest.TopicId!)))
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-}
\ No newline at end of file
diff --git a/foreign/csharp/Iggy_SDK_Tests/E2ETests/UsersE2E.cs b/foreign/csharp/Iggy_SDK_Tests/E2ETests/UsersE2E.cs
deleted file mode 100644
index 1da63c37..00000000
--- a/foreign/csharp/Iggy_SDK_Tests/E2ETests/UsersE2E.cs
+++ /dev/null
@@ -1,226 +0,0 @@
-// 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 Apache.Iggy.Contracts.Http.Auth;
-using Apache.Iggy.Enums;
-using Apache.Iggy.Exceptions;
-using Apache.Iggy.Tests.E2ETests.Fixtures;
-using Apache.Iggy.Tests.E2ETests.Fixtures.Bootstraps;
-using Apache.Iggy.Tests.Utils;
-using FluentAssertions;
-
-namespace Apache.Iggy.Tests.E2ETests;
-
-[TestCaseOrderer("Apache.Iggy.Tests.Utils.PriorityOrderer", "Apache.Iggy.Tests")]
-public sealed class UsersE2E : IClassFixture<IggyTcpUsersFixture>
-{
- private readonly IggyTcpUsersFixture _fixture;
- public UsersE2E(IggyTcpUsersFixture fixture)
- {
- _fixture = fixture;
- }
-
- [Fact, TestPriority(1)]
- public async Task CreateUser_Should_CreateUser_Successfully()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Client.Invoking(async x =>
- await x.CreateUser(UsersFixtureBootstrap.UserRequest)
- )
- .Should()
- .NotThrowAsync();
- }));
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(2)]
- public async Task CreateUser_Duplicate_Should_Throw_InvalidResponse()
- {
- // act & assert
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- await sut.Client.Invoking(async x =>
- await x.CreateUser(UsersFixtureBootstrap.UserRequest)
- )
- .Should()
- .ThrowExactlyAsync<InvalidResponseException>();
- }));
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(3)]
- public async Task GetUser_Should_ReturnValidResponse()
- {
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- // act
- var response = await sut.Client.GetUser(Identifier.Numeric(2));
-
- // assert
- response.Should().NotBeNull();
- response!.Id.Should().Be(2);
- response.Username.Should().Be(UsersFixtureBootstrap.UserRequest.Username);
- response.Status.Should().Be(UsersFixtureBootstrap.UserRequest.Status);
- response.Permissions!.Global.Should().NotBeNull();
- response.Permissions.Global.Should().BeEquivalentTo(UsersFixtureBootstrap.UserRequest.Permissions!.Global);
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(4)]
- public async Task GetUsers_Should_ReturnValidResponse()
- {
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- // act
- var response = await sut.Client.GetUsers();
-
- // assert
- response.Should().NotBeEmpty();
- response.Should().HaveCount(2);
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(5)]
- public async Task UpdateUser_Should_UpdateUser_Successfully()
- {
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- //act
- await sut.Client.Invoking(async x =>
- await x.UpdateUser(new UpdateUserRequest
- {
- UserId = Identifier.Numeric(2), Username = UsersFixtureBootstrap.NewUsername, UserStatus = UserStatus.Active
- })).Should().NotThrowAsync();
-
- var user = await sut.Client.GetUser(Identifier.Numeric(2));
-
- // assert
- user!.Username.Should().Be(UsersFixtureBootstrap.NewUsername);
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(6)]
- public async Task UpdatePermissions_Should_UpdatePermissions_Successfully()
- {
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- // act
- await sut.Client.Invoking(async x =>
- await x.UpdatePermissions(new UpdateUserPermissionsRequest
- {
- UserId = Identifier.Numeric(2), Permissions = UsersFixtureBootstrap.UpdatePermissionsRequest
- })).Should().NotThrowAsync();
-
- var user = await sut.Client.GetUser(Identifier.Numeric(2));
-
- // assert
- user!.Permissions!.Global.Should().NotBeNull();
- user.Permissions.Should().BeEquivalentTo(UsersFixtureBootstrap.UpdatePermissionsRequest);
- user.Permissions!.Streams.Should().NotBeNull();
- user.Permissions.Streams.Should().HaveCount(1);
-
- user.Permissions.Global.ManageServers.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Global!.ManageServers);
- user.Permissions.Global.ManageUsers.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Global!.ManageUsers);
- user.Permissions.Global.ManageStreams.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Global!.ManageStreams);
- user.Permissions.Global.ManageTopics.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Global!.ManageTopics);
- user.Permissions.Global.PollMessages.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Global!.PollMessages);
- user.Permissions.Global.ReadServers.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Global!.ReadServers);
- user.Permissions.Global.ReadStreams.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Global!.ReadStreams);
- user.Permissions.Global.ReadTopics.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Global!.ReadTopics);
- user.Permissions.Global.ReadUsers.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Global!.ReadUsers);
-
- var stream = user.Permissions.Streams!.FirstOrDefault();
- stream.Should().NotBeNull();
- stream!.Key.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Streams!.First().Key);
- stream.Value.Should().NotBeNull();
- stream.Value.ManageStream.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Streams!.First().Value.ManageStream);
- stream.Value.ManageTopics.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Streams!.First().Value.ManageTopics);
- stream.Value.ReadStream.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Streams!.First().Value.ReadStream);
- stream.Value.SendMessages.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Streams!.First().Value.SendMessages);
- stream.Value.ReadTopics.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Streams!.First().Value.ReadTopics);
- stream.Value.PollMessages.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Streams!.First().Value.PollMessages);
- stream.Value.Topics.Should().NotBeNull();
-
- stream.Value.Topics!.Should().HaveCount(1);
- stream.Value.Topics!.Should().ContainKey(UsersFixtureBootstrap.UpdatePermissionsRequest.Streams!.First().Value.Topics!.First().Key);
- stream.Value.Topics!.First().Value.Should().NotBeNull();
- stream.Value.Topics!.First().Key.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Streams!.First().Value.Topics!.First().Key);
- stream.Value.Topics!.First().Value.ManageTopic.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Streams!.First().Value.Topics!.First().Value.ManageTopic);
- stream.Value.Topics!.First().Value.PollMessages.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Streams!.First().Value.Topics!.First().Value.PollMessages);
- stream.Value.Topics!.First().Value.ReadTopic.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Streams!.First().Value.Topics!.First().Value.ReadTopic);
- stream.Value.Topics!.First().Value.SendMessages.Should().Be(UsersFixtureBootstrap.UpdatePermissionsRequest.Streams!.First().Value.Topics!.First().Value.SendMessages);
-
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(7)]
- public async Task ChangePassword_Should_ChangePassword_Successfully()
- {
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- // act
- await sut.Client.Invoking(async x =>
- await x.ChangePassword(new ChangePasswordRequest()
- {
- UserId = Identifier.Numeric(2),
- CurrentPassword = "user1",
- NewPassword = "user2"
- })).Should().NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-
- [Fact, TestPriority(8)]
- public async Task DeleteUser_Should_DeleteUser_Successfully()
- {
- var task = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- // act & assert
- await sut.Client.Invoking(async x =>
- await x.DeleteUser(Identifier.Numeric(2))).Should().NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(task);
- }
-
- [Fact, TestPriority(8)]
- public async Task LogoutUser_Should_LogoutUser_Successfully()
- {
- var tasks = _fixture.SubjectsUnderTest.Select(sut => Task.Run(async () =>
- {
- // act & assert
- await sut.Client.Invoking(async x =>
- await x.LogoutUser()).Should().NotThrowAsync();
- })).ToArray();
-
- await Task.WhenAll(tasks);
- }
-}
-
diff --git a/foreign/csharp/Iggy_SDK_Tests/Iggy_SDK_Tests.csproj b/foreign/csharp/Iggy_SDK_Tests/Iggy_SDK_Tests.csproj
index eb2319b1..6efde3b3 100644
--- a/foreign/csharp/Iggy_SDK_Tests/Iggy_SDK_Tests.csproj
+++ b/foreign/csharp/Iggy_SDK_Tests/Iggy_SDK_Tests.csproj
@@ -12,16 +12,16 @@
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="FluentAssertions" Version="6.12.0" />
- <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
- <PackageReference Include="Moq" Version="4.20.72" />
- <PackageReference Include="Testcontainers" Version="4.5.0" />
- <PackageReference Include="xunit" Version="2.9.3" />
- <PackageReference Include="xunit.runner.visualstudio" Version="3.1.0">
+ <PackageReference Include="FluentAssertions" />
+ <PackageReference Include="Microsoft.NET.Test.Sdk" />
+ <PackageReference Include="Moq" />
+ <PackageReference Include="Testcontainers" />
+ <PackageReference Include="xunit" />
+ <PackageReference Include="xunit.runner.visualstudio">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
- <PackageReference Include="coverlet.collector" Version="6.0.4">
+ <PackageReference Include="coverlet.collector">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
@@ -32,20 +32,4 @@
<ProjectReference Include="..\Shared\Shared.csproj" />
</ItemGroup>
-
- <ItemGroup>
- <Reference Include="Microsoft.Extensions.Logging">
- <HintPath>..\..\..\.nuget\packages\microsoft.extensions.logging\7.0.0\lib\net7.0\Microsoft.Extensions.Logging.dll</HintPath>
- </Reference>
- </ItemGroup>
-
- <ItemGroup>
- <Reference Include="Microsoft.Extensions.Logging">
- <HintPath>..\..\..\.nuget\packages\microsoft.extensions.logging\7.0.0\lib\net7.0\Microsoft.Extensions.Logging.dll</HintPath>
- </Reference>
- </ItemGroup>
-
-
-
-
</Project>
diff --git a/foreign/csharp/Iggy_SDK_Tests/MapperTests/BinaryMapper.cs b/foreign/csharp/Iggy_SDK_Tests/MapperTests/BinaryMapper.cs
index f6968fc4..77801907 100644
--- a/foreign/csharp/Iggy_SDK_Tests/MapperTests/BinaryMapper.cs
+++ b/foreign/csharp/Iggy_SDK_Tests/MapperTests/BinaryMapper.cs
@@ -340,7 +340,8 @@ public sealed class BinaryMapper
Assert.Equal(membersCount, response.MembersCount);
Assert.Equal(partitionsCount, response.PartitionsCount);
Assert.Equal(memberPartitions.Count, partitionsCount);
- Assert.Equal(response.Members.Count, 1);
+ Assert.NotNull(response.Members);
+ Assert.Single(response.Members);
}
[Fact]
diff --git a/foreign/csharp/Iggy_SDK_Tests/Utils/PriorityOrderer.cs b/foreign/csharp/Iggy_SDK_Tests/Utils/PriorityOrderer.cs
index 8a70a9cc..b7fa4193 100644
--- a/foreign/csharp/Iggy_SDK_Tests/Utils/PriorityOrderer.cs
+++ b/foreign/csharp/Iggy_SDK_Tests/Utils/PriorityOrderer.cs
@@ -39,17 +39,22 @@ public class PriorityOrderer : ITestCaseOrderer
foreach (var list in sortedMethods.Keys.Select(priority => sortedMethods[priority]))
{
list.Sort((x, y) => StringComparer.OrdinalIgnoreCase.Compare(x.TestMethod.Method.Name, y.TestMethod.Method.Name));
- foreach (TTestCase testCase in list) yield return testCase;
-
+ foreach (TTestCase testCase in list)
+ {
+ yield return testCase;
+ }
}
}
static TValue GetOrCreate<TKey, TValue>(IDictionary<TKey, TValue> dictionary, TKey key)
where TValue : new()
{
- TValue result;
+ TValue? result;
- if (dictionary.TryGetValue(key, out result)) return result;
+ if (dictionary.TryGetValue(key, out result))
+ {
+ return result;
+ }
result = new TValue();
dictionary[key] = result;
diff --git a/foreign/csharp/Iggy_SDK_Tests/Utils/Topics/TopicFactory.cs b/foreign/csharp/Iggy_SDK_Tests/Utils/Topics/TopicFactory.cs
index de74c04d..84eb20ff 100644
--- a/foreign/csharp/Iggy_SDK_Tests/Utils/Topics/TopicFactory.cs
+++ b/foreign/csharp/Iggy_SDK_Tests/Utils/Topics/TopicFactory.cs
@@ -41,13 +41,13 @@ internal static class TopicFactory
internal static TopicRequest CreateTopicRequest()
{
return new TopicRequest(
- TopicId: Random.Shared.Next(1, 9999),
- Name: "test_topic" + Random.Shared.Next(1, 69) + Utility.RandomString(12).ToLower(),
- CompressionAlgorithm: CompressionAlgorithm.Gzip,
- MessageExpiry: (ulong)Random.Shared.Next(1, 69),
- MaxTopicSize: (ulong)Random.Shared.NextInt64(2_000_000_000, 10_000_000_000),
- ReplicationFactor: (byte)Random.Shared.Next(1, 8),
- PartitionsCount: Random.Shared.Next(5, 25));
+ topicId: Random.Shared.Next(1, 9999),
+ name: "test_topic" + Random.Shared.Next(1, 69) + Utility.RandomString(12).ToLower(),
+ compressionAlgorithm: CompressionAlgorithm.Gzip,
+ messageExpiry: (ulong)Random.Shared.Next(1, 69),
+ maxTopicSize: (ulong)Random.Shared.NextInt64(2_000_000_000, 10_000_000_000),
+ replicationFactor: (byte)Random.Shared.Next(1, 8),
+ partitionsCount: Random.Shared.Next(5, 25));
}
internal static UpdateTopicRequest CreateUpdateTopicRequest()
@@ -63,13 +63,13 @@ internal static class TopicFactory
internal static TopicRequest CreateTopicRequest(int topicId)
{
return new TopicRequest(
- TopicId: topicId,
- Name: "test_topic" + Random.Shared.Next(1, 69) + Utility.RandomString(12).ToLower(),
- CompressionAlgorithm: CompressionAlgorithm.None,
- MessageExpiry: (ulong)Random.Shared.Next(1, 69),
- MaxTopicSize: (ulong)Random.Shared.NextInt64(2_000_000_000, 10_000_000_000),
- ReplicationFactor: (byte)Random.Shared.Next(1, 8),
- PartitionsCount: Random.Shared.Next(5, 25));
+ topicId: topicId,
+ name: "test_topic" + Random.Shared.Next(1, 69) + Utility.RandomString(12).ToLower(),
+ compressionAlgorithm: CompressionAlgorithm.None,
+ messageExpiry: (ulong)Random.Shared.Next(1, 69),
+ maxTopicSize: (ulong)Random.Shared.NextInt64(2_000_000_000, 10_000_000_000),
+ replicationFactor: (byte)Random.Shared.Next(1, 8),
+ partitionsCount: Random.Shared.Next(5, 25));
}
internal static TopicResponse CreateTopicsResponse()
diff --git a/foreign/csharp/Iggy_Sample_Consumer/Iggy_Sample_Consumer.csproj b/foreign/csharp/Iggy_Sample_Consumer/Iggy_Sample_Consumer.csproj
index 4bcfe602..902d2c6d 100644
--- a/foreign/csharp/Iggy_Sample_Consumer/Iggy_Sample_Consumer.csproj
+++ b/foreign/csharp/Iggy_Sample_Consumer/Iggy_Sample_Consumer.csproj
@@ -15,7 +15,7 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
+ <PackageReference Include="Microsoft.Extensions.Logging.Console" />
</ItemGroup>
</Project>
diff --git a/foreign/csharp/Iggy_Sample_Consumer/Program.cs b/foreign/csharp/Iggy_Sample_Consumer/Program.cs
index e67e2c9d..0619d469 100644
--- a/foreign/csharp/Iggy_Sample_Consumer/Program.cs
+++ b/foreign/csharp/Iggy_Sample_Consumer/Program.cs
@@ -189,7 +189,7 @@ async Task ValidateSystem(Identifier streamId, Identifier topicId, int partition
var result = await bus.GetStreamByIdAsync(streamId);
- Console.WriteLine(result.Name);
+ Console.WriteLine(result!.Name);
Console.WriteLine($"Validating if topic exists.. {topicId}");
@@ -214,13 +214,13 @@ async Task ValidateSystem(Identifier streamId, Identifier topicId, int partition
Console.WriteLine($"Creating topic with {topicId}");
await bus.CreateTopicAsync(streamId, new TopicRequest(
- TopicId: topicIdVal,
- Name: "Test Consumer Topic",
- CompressionAlgorithm: CompressionAlgorithm.None,
- MessageExpiry: 0,
- MaxTopicSize: 1_000_000_000,
- ReplicationFactor: 3,
- PartitionsCount: 3));
+ topicId: topicIdVal,
+ name: "Test Consumer Topic",
+ compressionAlgorithm: CompressionAlgorithm.None,
+ messageExpiry: 0,
+ maxTopicSize: 1_000_000_000,
+ replicationFactor: 3,
+ partitionsCount: 3));
var topicRes = await bus.GetTopicByIdAsync(streamId, topicId);
diff --git a/foreign/csharp/Iggy_Sample_Producer/Iggy_Sample_Producer.csproj b/foreign/csharp/Iggy_Sample_Producer/Iggy_Sample_Producer.csproj
index c492c7d6..dff32fb2 100644
--- a/foreign/csharp/Iggy_Sample_Producer/Iggy_Sample_Producer.csproj
+++ b/foreign/csharp/Iggy_Sample_Producer/Iggy_Sample_Producer.csproj
@@ -15,9 +15,7 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
+ <PackageReference Include="Microsoft.Extensions.Logging.Console" />
</ItemGroup>
-
-
-
+
</Project>
diff --git a/foreign/csharp/Iggy_Sample_Producer/Program.cs b/foreign/csharp/Iggy_Sample_Producer/Program.cs
index c528760b..1198ca9c 100644
--- a/foreign/csharp/Iggy_Sample_Producer/Program.cs
+++ b/foreign/csharp/Iggy_Sample_Producer/Program.cs
@@ -151,13 +151,13 @@ catch
Console.WriteLine($"Creating topic with id:{topicId}");
await bus.CreateTopicAsync(streamId, new TopicRequest(
- TopicId: topicIdVal,
- Name: "producer-topic",
- CompressionAlgorithm: CompressionAlgorithm.None,
- MessageExpiry: 0,
- MaxTopicSize: 0,
- ReplicationFactor: 3,
- PartitionsCount: 3));
+ topicId: topicIdVal,
+ name: "producer-topic",
+ compressionAlgorithm: CompressionAlgorithm.None,
+ messageExpiry: 0,
+ maxTopicSize: 0,
+ replicationFactor: 3,
+ partitionsCount: 3));
}
var actualStream = await bus.GetStreamByIdAsync(streamId);
diff --git a/foreign/csharp/README.md b/foreign/csharp/README.md
index af1dfac1..c072eaa9 100644
--- a/foreign/csharp/README.md
+++ b/foreign/csharp/README.md
@@ -1,4 +1,4 @@
-# C# SDK for [Iggy](https://github.com/spetz/iggy)
+# C# SDK for [Iggy](https://github.com/apache/iggy)
<div align="center">
@@ -228,8 +228,20 @@ The `Message` struct has two fields `Id` and `Payload`.
```c#
struct Message
{
- public required Guid Id { get; init; }
+ public required MessageHeader Header { get; init; }
public required byte[] Payload { get; init; }
+ public Dictionary<HeaderKey, HeaderValue>? UserHeaders { get; init; }
+}
+
+public readonly struct MessageHeader
+{
+ public ulong Checksum { get; init; }
+ public UInt128 Id { get; init; }
+ public ulong Offset { get; init; }
+ public DateTimeOffset Timestamp { get; init; }
+ public ulong OriginTimestamp { get; init; }
+ public int UserHeadersLength { get; init; }
+ public int PayloadLength { get; init; }
}
```