From 03623f81cf41226c16f44c9f5bf1cb480bc1b291 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Date: Sat, 12 Sep 2026 18:25:43 -0400 Subject: [PATCH 1/2] chore(tests): retire redundant TCP stream coverage Signed-off-by: Yordis Prieto --- .../workflows/build-container-ubuntu-lts.yml | 1 - scripts/test.sh | 27 +- .../concurrent_queue_wrapper_should.cs | 115 --- .../MiniNodeWithExistingRecords.cs | 181 ---- ...th_event_numbers_greater_than_2_billion.cs | 55 -- ...th_event_numbers_greater_than_2_billion.cs | 63 -- ...th_event_numbers_greater_than_2_billion.cs | 124 --- ..._event_number_greater_than_int_maxvalue.cs | 90 -- ..._event_number_greater_than_int_maxvalue.cs | 64 -- ...th_event_numbers_greater_than_2_billion.cs | 115 --- ...th_event_numbers_greater_than_2_billion.cs | 59 -- .../SpecificationWithLinkToToDeletedEvents.cs | 29 - ...cationWithLinkToToMaxCountDeletedEvents.cs | 33 - .../SystemData/clientapi_tcp_package.cs | 199 ----- .../ClientAPI/UserManagement/TestWithNode.cs | 77 -- .../ClientAPI/append_to_stream.cs | 798 ------------------ .../append_to_stream_with_hash_collision.cs | 86 -- .../appending_to_implicitly_created_stream.cs | 323 ------- ...icitly_created_stream_using_transaction.cs | 251 ------ .../appending_to_streams_across_restart.cs | 187 ---- .../catch_up_subscription_handles_errors.cs | 753 ----------------- .../catchup_filtered_subscription.cs | 358 -------- ..._subscription_handles_small_batch_sizes.cs | 106 --- .../ClientAPI/connect.cs | 166 ---- .../connecting_with_connection_string.cs | 68 -- .../ClientAPI/connection_string.cs | 69 -- .../ClientAPI/deleting_stream.cs | 106 --- .../event_store_connection_should.cs | 114 --- .../ClientAPI/isjson_flag_on_event.cs | 94 --- ...ead_all_events_backward_filtered_should.cs | 97 --- .../read_all_events_backward_should.cs | 95 --- .../read_all_events_filtered_paging_should.cs | 150 ---- ...read_all_events_forward_filtered_should.cs | 108 --- .../read_all_events_forward_should.cs | 94 --- ...forward_with_hard_deleted_stream_should.cs | 57 -- ...ts_forward_with_linkto_passed_max_count.cs | 24 - ...ts_forward_with_linkto_to_deleted_event.cs | 41 - ...forward_with_soft_deleted_stream_should.cs | 59 -- ...ents_backward_with_linkto_deleted_event.cs | 71 -- .../ClientAPI/read_event_should.cs | 122 --- .../read_event_stream_backward_should.cs | 243 ------ .../read_event_stream_forward_should.cs | 219 ----- .../read_event_with_hash_collision.cs | 82 -- ...eam_events_backward_with_hash_collision.cs | 84 -- ...ream_events_forward_with_hash_collision.cs | 83 -- ...ad_stream_events_with_unresolved_linkto.cs | 54 -- .../ClientAPI/soft_delete.cs | 385 --------- .../ClientAPI/subscribe_should.cs | 129 --- .../subscribe_to_all_catching_up_should.cs | 325 ------- .../subscribe_to_all_filtered_should.cs | 388 --------- .../ClientAPI/subscribe_to_all_should.cs | 119 --- .../subscribe_to_stream_catching_up_should.cs | 361 -------- .../ClientAPI/transaction.cs | 282 ------- .../when_committing_empty_transaction.cs | 126 --- .../when_having_max_count_set_for_stream.cs | 136 --- ...en_having_truncatebefore_set_for_stream.cs | 379 --------- .../ClientAPI/when_working_with_metadata.cs | 60 -- ...king_with_stream_metadata_as_byte_array.cs | 182 ---- ...with_stream_metadata_as_structured_info.cs | 384 --------- 59 files changed, 2 insertions(+), 9648 deletions(-) delete mode 100644 src/EventStore.Core.Tests/ClientAPI/DataStructures/concurrent_queue_wrapper_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/MiniNodeWithExistingRecords.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/append_to_stream_with_event_numbers_greater_than_2_billion.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/catchup_subscription_to_all_with_event_numbers_greater_than_2_billion.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/read_stream_with_event_numbers_greater_than_2_billion.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/read_stream_with_link_to_event_with_event_number_greater_than_int_maxvalue.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/subscribe_to_stream_with_link_to_event_with_event_number_greater_than_int_maxvalue.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/subscriptions_on_stream_with_event_numbers_greater_than_2_billion.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/transactions_on_stream_with_event_numbers_greater_than_2_billion.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/SpecificationWithLinkToToDeletedEvents.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/SpecificationWithLinkToToMaxCountDeletedEvents.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/SystemData/clientapi_tcp_package.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/UserManagement/TestWithNode.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/append_to_stream.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/append_to_stream_with_hash_collision.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/appending_to_implicitly_created_stream.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/appending_to_implicitly_created_stream_using_transaction.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/appending_to_streams_across_restart.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/catch_up_subscription_handles_errors.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/catchup_filtered_subscription.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/catchup_subscription_handles_small_batch_sizes.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/connect.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/connecting_with_connection_string.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/connection_string.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/deleting_stream.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/event_store_connection_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/isjson_flag_on_event.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_all_events_backward_filtered_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_all_events_backward_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_all_events_filtered_paging_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_filtered_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_hard_deleted_stream_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_linkto_passed_max_count.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_linkto_to_deleted_event.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_soft_deleted_stream_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_allevents_backward_with_linkto_deleted_event.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_event_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_event_stream_backward_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_event_stream_forward_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_event_with_hash_collision.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_stream_events_backward_with_hash_collision.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_stream_events_forward_with_hash_collision.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/read_stream_events_with_unresolved_linkto.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/soft_delete.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/subscribe_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/subscribe_to_all_catching_up_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/subscribe_to_all_filtered_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/subscribe_to_all_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/subscribe_to_stream_catching_up_should.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/transaction.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/when_committing_empty_transaction.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/when_having_max_count_set_for_stream.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/when_having_truncatebefore_set_for_stream.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/when_working_with_metadata.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/when_working_with_stream_metadata_as_byte_array.cs delete mode 100644 src/EventStore.Core.Tests/ClientAPI/when_working_with_stream_metadata_as_structured_info.cs diff --git a/.github/workflows/build-container-ubuntu-lts.yml b/.github/workflows/build-container-ubuntu-lts.yml index 7355e8fd5d..75ca248837 100644 --- a/.github/workflows/build-container-ubuntu-lts.yml +++ b/.github/workflows/build-container-ubuntu-lts.yml @@ -36,7 +36,6 @@ jobs: matrix: include: - test-group-name: core-grpc-security - - test-group-name: core-clientapi-streams - test-group-name: core-http - test-group-name: core-services - test-group-name: core-cluster-services diff --git a/scripts/test.sh b/scripts/test.sh index 6de3fed7f2..925f020b9a 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -5,10 +5,6 @@ set -o xtrace update-ca-certificates -core_clientapi_projects=( - EventStore.Core.Tests -) - core_grpc_security_projects=( EventStore.Core.Tests ) @@ -66,15 +62,9 @@ load_requested_projects() { all) requested_projects=() ;; - core-clientapi) - requested_projects=("${core_clientapi_projects[@]}") - ;; core-grpc-security) requested_projects=("${core_grpc_security_projects[@]}") ;; - core-clientapi-streams) - requested_projects=("${core_clientapi_projects[@]}") - ;; core-rest) requested_projects=("${core_rest_projects[@]}") ;; @@ -117,7 +107,6 @@ validate_shard_coverage() { declared_projects="$( printf '%s\n' \ - "${core_clientapi_projects[@]}" \ "${core_grpc_security_projects[@]}" \ "${core_rest_projects[@]}" \ "${core_services_projects[@]}" \ @@ -206,17 +195,11 @@ project_filter() { local proj="$1" case "${TEST_GROUP:-all}:$proj" in - core-clientapi:EventStore.Core.Tests) - printf '%s\n' "FullyQualifiedName~EventStore.Core.Tests.ClientAPI" - ;; core-grpc-security:EventStore.Core.Tests) printf '%s\n' "FullyQualifiedName~EventStore.Core.Tests.Services.Transport.Grpc.Security" ;; - core-clientapi-streams:EventStore.Core.Tests) - printf '%s\n' "FullyQualifiedName~EventStore.Core.Tests.ClientAPI&FullyQualifiedName!~persistent&FullyQualifiedName!~Persistent&FullyQualifiedName!~EventStore.Core.Tests.ClientAPI.Security" - ;; core-http:EventStore.Core.Tests) - printf '%s\n' "(FullyQualifiedName~EventStore.Core.Tests.Http|FullyQualifiedName~EventStore.Core.Tests.Services.Transport.Http)&FullyQualifiedName!~EventStore.Core.Tests.ClientAPI" + printf '%s\n' "(FullyQualifiedName~EventStore.Core.Tests.Http|FullyQualifiedName~EventStore.Core.Tests.Services.Transport.Http)" ;; core-services:EventStore.Core.Tests) printf '%s\n' "((FullyQualifiedName~EventStore.Core.Tests.Services&FullyQualifiedName!~EventStore.Core.Tests.Services.Storage&FullyQualifiedName!~EventStore.Core.Tests.Services.Transport.Http&FullyQualifiedName!~EventStore.Core.Tests.Services.Transport.Grpc.Security&FullyQualifiedName!~EventStore.Core.Tests.Services.Transport.Grpc.ServerFeaturesTests&FullyQualifiedName!~EventStore.Core.Tests.Services.ElectionsService)|FullyQualifiedName~EventStore.Core.Tests.Bus|FullyQualifiedName~EventStore.Core.Tests.Helpers|FullyQualifiedName~EventStore.Core.Tests.ClientOperations|FullyQualifiedName~EventStore.Core.Tests.Authentication|FullyQualifiedName~EventStore.Core.Tests.Authorization|FullyQualifiedName~EventStore.Core.Tests.Certificates|FullyQualifiedName~EventStore.Core.Tests.AwakeService|FullyQualifiedName~EventStore.Core.Tests.Settings|FullyQualifiedName~EventStore.Core.Tests.TcpApiTestPlugin)" @@ -234,7 +217,7 @@ project_filter() { printf '%s\n' "FullyQualifiedName~EventStore.Core.Tests.Transforms" ;; core-rest:EventStore.Core.Tests) - printf '%s\n' "FullyQualifiedName!~EventStore.Core.Tests.ClientAPI&FullyQualifiedName!~EventStore.Core.Tests.Http&FullyQualifiedName!~EventStore.Core.Tests.Services&FullyQualifiedName!~EventStore.Core.Tests.Integration&FullyQualifiedName!~EventStore.Core.Tests.Cluster&FullyQualifiedName!~EventStore.Core.Tests.Bus&FullyQualifiedName!~EventStore.Core.Tests.Helpers&FullyQualifiedName!~EventStore.Core.Tests.ClientOperations&FullyQualifiedName!~EventStore.Core.Tests.Authentication&FullyQualifiedName!~EventStore.Core.Tests.Authorization&FullyQualifiedName!~EventStore.Core.Tests.Certificates&FullyQualifiedName!~EventStore.Core.Tests.AwakeService&FullyQualifiedName!~EventStore.Core.Tests.Replication&FullyQualifiedName!~EventStore.Core.Tests.Settings&FullyQualifiedName!~EventStore.Core.Tests.Synchronization&FullyQualifiedName!~EventStore.Core.Tests.TcpApiTestPlugin&FullyQualifiedName!~EventStore.Core.Tests.Index&FullyQualifiedName!~EventStore.Core.Tests.TransactionLog&FullyQualifiedName!~EventStore.Core.Tests.Caching&FullyQualifiedName!~EventStore.Core.Tests.DataStructures&FullyQualifiedName!~EventStore.Core.Tests.Transforms&FullyQualifiedName!~EventStore.Core.Tests.Hashes" + printf '%s\n' "FullyQualifiedName!~EventStore.Core.Tests.Http&FullyQualifiedName!~EventStore.Core.Tests.Services&FullyQualifiedName!~EventStore.Core.Tests.Integration&FullyQualifiedName!~EventStore.Core.Tests.Cluster&FullyQualifiedName!~EventStore.Core.Tests.Bus&FullyQualifiedName!~EventStore.Core.Tests.Helpers&FullyQualifiedName!~EventStore.Core.Tests.ClientOperations&FullyQualifiedName!~EventStore.Core.Tests.Authentication&FullyQualifiedName!~EventStore.Core.Tests.Authorization&FullyQualifiedName!~EventStore.Core.Tests.Certificates&FullyQualifiedName!~EventStore.Core.Tests.AwakeService&FullyQualifiedName!~EventStore.Core.Tests.Replication&FullyQualifiedName!~EventStore.Core.Tests.Settings&FullyQualifiedName!~EventStore.Core.Tests.Synchronization&FullyQualifiedName!~EventStore.Core.Tests.TcpApiTestPlugin&FullyQualifiedName!~EventStore.Core.Tests.Index&FullyQualifiedName!~EventStore.Core.Tests.TransactionLog&FullyQualifiedName!~EventStore.Core.Tests.Caching&FullyQualifiedName!~EventStore.Core.Tests.DataStructures&FullyQualifiedName!~EventStore.Core.Tests.Transforms&FullyQualifiedName!~EventStore.Core.Tests.Hashes" ;; esac } @@ -243,15 +226,9 @@ project_timeout() { local proj="$1" case "${TEST_GROUP:-all}:$proj" in - core-clientapi:EventStore.Core.Tests) - printf '%s\n' "20m" - ;; core-grpc-security:EventStore.Core.Tests) printf '%s\n' "20m" ;; - core-clientapi-streams:EventStore.Core.Tests) - printf '%s\n' "20m" - ;; core-rest:EventStore.Core.Tests) printf '%s\n' "15m" ;; diff --git a/src/EventStore.Core.Tests/ClientAPI/DataStructures/concurrent_queue_wrapper_should.cs b/src/EventStore.Core.Tests/ClientAPI/DataStructures/concurrent_queue_wrapper_should.cs deleted file mode 100644 index 5acd1434dc..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/DataStructures/concurrent_queue_wrapper_should.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System; -using System.Threading; -using EventStore.ClientAPI.Common.Utils.Threading; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI.DataStructures; - -[TestFixture] -public class concurrent_queue_wrapper_should -{ - [Test] - public void return_correct_counts_and_values_1() - { - var queue = new ConcurrentQueueWrapper(); - Assert.AreEqual(0, queue.Count); - queue.Enqueue(1234); - Assert.AreEqual(1, queue.Count); - queue.Enqueue(12345); - Assert.AreEqual(2, queue.Count); - - int val; - Assert.AreEqual(true, queue.TryDequeue(out val)); - Assert.AreEqual(1234, val); - Assert.AreEqual(1, queue.Count); - - Assert.AreEqual(true, queue.TryDequeue(out val)); - Assert.AreEqual(12345, val); - Assert.AreEqual(0, queue.Count); - - Assert.AreEqual(false, queue.TryDequeue(out _)); - Assert.AreEqual(false, queue.TryDequeue(out _)); - } - - [Test] - public void return_correct_counts_and_values_2() - { - var queue = new ConcurrentQueueWrapper(); - for (int i = 1; i <= 1000; i++) - { - queue.Enqueue(i); - Assert.AreEqual(i, queue.Count); - } - - int x; - for (int i = 1; i <= 1000; i++) - { - Assert.AreEqual(true, queue.TryDequeue(out x)); - Assert.AreEqual(i, x); - Assert.AreEqual(1000 - i, queue.Count); - } - } -} - -[TestFixture] -public class concurrent_queue_wrapper_with_parallel_dequeues_should -{ - private ConcurrentQueueWrapper _concurrentQueue; - private const int TOTAL_ENQUEUED_ITEMS = 1000000; - private const int NUM_THREADS = 4; - private volatile bool _seenNegativeCount; - private volatile int _totalDequeued; - - public concurrent_queue_wrapper_with_parallel_dequeues_should() - { - _concurrentQueue = new ConcurrentQueueWrapper(); - _seenNegativeCount = false; - _totalDequeued = 0; - } - - private void DequeueThread() - { - while (_totalDequeued < TOTAL_ENQUEUED_ITEMS) - { - var dequeued = _concurrentQueue.TryDequeue(out _); - if (_concurrentQueue.Count < 0) - { - _seenNegativeCount = true; - } - - if (dequeued) - { - Interlocked.Increment(ref _totalDequeued); - } - } - } - - [Test] - public void always_return_non_negative_count() - { - var threads = new Thread[NUM_THREADS]; - for (int i = 0; i < NUM_THREADS; i++) - { - threads[i] = new Thread(DequeueThread); - threads[i].Start(); - } - - int x; - for (int i = 0; i < TOTAL_ENQUEUED_ITEMS; i++) - { - _concurrentQueue.Enqueue(1); - var dequeued = _concurrentQueue.TryDequeue(out x); - if (dequeued) - { - Interlocked.Increment(ref _totalDequeued); - } - } - - for (int i = 0; i < NUM_THREADS; i++) - { - threads[i].Join(TimeSpan.FromSeconds(5)); - } - - Assert.AreEqual(false, _seenNegativeCount); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/MiniNodeWithExistingRecords.cs b/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/MiniNodeWithExistingRecords.cs deleted file mode 100644 index 26d2a38dd5..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/MiniNodeWithExistingRecords.cs +++ /dev/null @@ -1,181 +0,0 @@ -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Common.Utils; -using EventStore.Core.Bus; -using EventStore.Core.Data; -using EventStore.Core.Helpers; -using EventStore.Core.Index; -using EventStore.Core.LogAbstraction; -using EventStore.Core.Messaging; -using EventStore.Core.Services.Storage.ReaderIndex; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using EventStore.Core.Tests.TransactionLog; -using EventStore.Core.TransactionLog.Checkpoint; -using EventStore.Core.TransactionLog.Chunks; -using EventStore.Core.TransactionLog.FileNamingStrategy; -using EventStore.Core.TransactionLog.LogRecords; -using EventStore.Core.Util; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI.ExpectedVersion64Bit; - -public abstract class MiniNodeWithExistingRecords : SpecificationWithDirectoryPerTestFixture -{ - private readonly TcpType _tcpType = TcpType.Ssl; - protected MiniNode Node; - - protected readonly int MaxEntriesInMemTable = 20; - protected readonly long MetastreamMaxCount = 1; - protected readonly bool PerformAdditionalCommitChecks = true; - protected readonly byte IndexBitnessVersion = Opts.IndexBitnessVersionDefault; - protected LogFormatAbstractor _logFormatFactory; - protected TableIndex TableIndex; - protected IReadIndex ReadIndex; - - protected TFChunkDb Db; - protected TFChunkWriter Writer; - protected ICheckpoint WriterCheckpoint; - protected ICheckpoint ChaserCheckpoint; - protected IODispatcher IODispatcher; - protected SynchronousScheduler Bus; - - protected IEventStoreConnection _store; - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.To(node, _tcpType); - } - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - string dbPath = Path.Combine(PathName, string.Format("mini-node-db-{0}", Guid.NewGuid())); - - _logFormatFactory = LogFormatHelper.LogFormatFactory.Create(new() - { - IndexDirectory = GetFilePathFor("index"), - }); - - Bus = new(); - IODispatcher = new IODispatcher(Bus, Bus); - - if (!Directory.Exists(dbPath)) - { - Directory.CreateDirectory(dbPath); - } - - var writerCheckFilename = Path.Combine(dbPath, Checkpoint.Writer + ".chk"); - var chaserCheckFilename = Path.Combine(dbPath, Checkpoint.Chaser + ".chk"); - - WriterCheckpoint = new MemoryMappedFileCheckpoint(writerCheckFilename, Checkpoint.Writer); - ChaserCheckpoint = new MemoryMappedFileCheckpoint(chaserCheckFilename, Checkpoint.Chaser); - - Db = new TFChunkDb(TFChunkHelper.CreateDbConfig(dbPath, WriterCheckpoint, ChaserCheckpoint, TFConsts.ChunkSize)); - await Db.Open(); - - // create DB - Writer = new TFChunkWriter(Db); - Writer.Open(); - - var pm = _logFormatFactory.CreatePartitionManager( - reader: new TFChunkReader(Db, WriterCheckpoint), - writer: Writer); - await pm.Initialize(CancellationToken.None); - - await WriteTestScenario(CancellationToken.None); - - await Writer.DisposeAsync(); - Writer = null; - WriterCheckpoint.Flush(); - ChaserCheckpoint.Write(WriterCheckpoint.Read()); - ChaserCheckpoint.Flush(); - await Db.DisposeAsync(); - - // start node with our created DB - Node = new MiniNode(PathName, dbPath: dbPath); - await Node.Start(); - - try - { - await Given().WithTimeout(); - } - catch (Exception ex) - { - throw new Exception("Given Failed", ex); - } - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - _store?.Dispose(); - _logFormatFactory?.Dispose(); - - await Node.Shutdown(); - await base.TestFixtureTearDown(); - } - - public abstract ValueTask WriteTestScenario(CancellationToken token); - public abstract Task Given(); - - protected async ValueTask WriteSingleEvent(string eventStreamName, - long eventNumber, - string data, - DateTime? timestamp = null, - Guid eventId = default(Guid), - string eventType = "some-type", - CancellationToken token = default) - { - - long pos = Writer.Position; - _logFormatFactory.StreamNameIndex.GetOrReserve( - _logFormatFactory.RecordFactory, - eventStreamName, - pos, - out var eventStreamId, - out var streamRecord); - - if (streamRecord != null) - { - (_, pos) = await Writer.Write(streamRecord, token); - } - - _logFormatFactory.EventTypeIndex.GetOrReserveEventType( - _logFormatFactory.RecordFactory, - eventType, - pos, - out var eventTypeId, - out var eventTypeRecord); - - if (eventTypeRecord != null) - { - (_, pos) = await Writer.Write(eventTypeRecord, token); - } - - var prepare = LogRecord.SingleWrite( - _logFormatFactory.RecordFactory, - pos, - eventId == default(Guid) ? Guid.NewGuid() : eventId, - Guid.NewGuid(), - eventStreamId, - eventNumber - 1, - eventTypeId, - Helper.UTF8NoBom.GetBytes(data), - null, - timestamp); - (var written, pos) = await Writer.Write(prepare, token); - Assert.IsTrue(written); - var commit = LogRecord.Commit(pos, prepare.CorrelationId, prepare.LogPosition, - eventNumber); - Assert.IsTrue(await Writer.Write(commit, token) is (true, _)); - Assert.AreEqual(eventStreamId, prepare.EventStreamId); - - var eventRecord = new EventRecord(eventNumber, prepare, eventStreamName, eventType); - return eventRecord; - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/append_to_stream_with_event_numbers_greater_than_2_billion.cs b/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/append_to_stream_with_event_numbers_greater_than_2_billion.cs deleted file mode 100644 index da9c333c08..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/append_to_stream_with_event_numbers_greater_than_2_billion.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Exceptions; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI.ExpectedVersion64Bit; - -[TestFixture(typeof(LogFormat.V2), typeof(string))] -[Category("ClientAPI"), Category("LongRunning")] -public class AppendToStreamWithEventNumbersGreaterThan2Billion - : MiniNodeWithExistingRecords -{ - private const string StreamName = "append_to_stream_with_event_numbers_greater_than_2_billion"; - private const long intMaxValue = int.MaxValue; - - public override async ValueTask WriteTestScenario(CancellationToken token) - { - await WriteSingleEvent(StreamName, intMaxValue + 1, new string('.', 3000), token: token); - await WriteSingleEvent(StreamName, intMaxValue + 2, new string('.', 3000), token: token); - await WriteSingleEvent(StreamName, intMaxValue + 3, new string('.', 3000), token: token); - await WriteSingleEvent(StreamName, intMaxValue + 4, new string('.', 3000), token: token); - await WriteSingleEvent(StreamName, intMaxValue + 5, new string('.', 3000), token: token); - } - - public override async Task Given() - { - _store = BuildConnection(Node); - await _store.ConnectAsync(); - await _store.SetStreamMetadataAsync(StreamName, EventStore.ClientAPI.ExpectedVersion.Any, - StreamMetadata.Create(truncateBefore: intMaxValue + 1)); - } - - [Test] - public async Task should_be_able_to_append_to_stream() - { - var evnt = new EventData(Guid.NewGuid(), "EventType", false, new byte[10], new byte[15]); - var writeResult = await _store.AppendToStreamAsync(StreamName, intMaxValue + 5, evnt); - Assert.AreEqual(intMaxValue + 6, writeResult.NextExpectedVersion); - - var readResult = await _store - .ReadStreamEventsForwardAsync(StreamName, intMaxValue + 6, 1, false, DefaultData.AdminCredentials); - Assert.AreEqual(SliceReadStatus.Success, readResult.Status); - Assert.AreEqual(evnt.EventId, readResult.Events[0].Event.EventId); - } - - [Test] - public async Task should_throw_wrong_expected_version_when_version_incorrect() - { - var evnt = new EventData(Guid.NewGuid(), "EventType", false, new byte[10], new byte[15]); - await AssertEx.ThrowsAsync(() => - _store.AppendToStreamAsync(StreamName, intMaxValue + 15, evnt)); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/catchup_subscription_to_all_with_event_numbers_greater_than_2_billion.cs b/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/catchup_subscription_to_all_with_event_numbers_greater_than_2_billion.cs deleted file mode 100644 index 5874a892a6..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/catchup_subscription_to_all_with_event_numbers_greater_than_2_billion.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Data; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI.ExpectedVersion64Bit; - -[TestFixture(typeof(LogFormat.V2), typeof(string))] -[Category("ClientAPI"), Category("LongRunning")] -public class CatchupSubscriptionToAllWithEventNumbersGreaterThan2Billion - : MiniNodeWithExistingRecords -{ - private const long intMaxValue = (long)int.MaxValue; - - private string _streamId = "subscriptions-catchup-all"; - - private EventRecord _r1, _r2; - - public override async ValueTask WriteTestScenario(CancellationToken token) - { - _r1 = await WriteSingleEvent(_streamId, intMaxValue + 1, new string('.', 3000), token: token); - _r2 = await WriteSingleEvent(_streamId, intMaxValue + 2, new string('.', 3000), token: token); - } - - public override async Task Given() - { - _store = BuildConnection(Node); - await _store.ConnectAsync(); - await _store.SetStreamMetadataAsync(_streamId, EventStore.ClientAPI.ExpectedVersion.Any, - EventStore.ClientAPI.StreamMetadata.Create(truncateBefore: intMaxValue + 1)); - } - - [Test] - public async Task should_be_able_to_subscribe_to_all_with_catchup_subscription() - { - var evnt = new EventData(Guid.NewGuid(), "EventType", false, new byte[10], new byte[15]); - List receivedEvents = new List(); - - var countdown = new CountdownEvent(3); - - _store.SubscribeToAllFrom(Position.Start, CatchUpSubscriptionSettings.Default, (s, e) => - { - if (e.Event.EventStreamId == _streamId) - { - receivedEvents.Add(e); - countdown.Signal(); - } - - return Task.CompletedTask; - }, userCredentials: DefaultData.AdminCredentials); - - await _store.AppendToStreamAsync(_streamId, intMaxValue + 2, evnt); - - Assert.That(countdown.Wait(TimeSpan.FromSeconds(10)), "Timed out waiting for events to appear"); - - Assert.AreEqual(_r1.EventId, receivedEvents[0].Event.EventId); - Assert.AreEqual(_r2.EventId, receivedEvents[1].Event.EventId); - Assert.AreEqual(evnt.EventId, receivedEvents[2].Event.EventId); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/read_stream_with_event_numbers_greater_than_2_billion.cs b/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/read_stream_with_event_numbers_greater_than_2_billion.cs deleted file mode 100644 index 2d9f3e5525..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/read_stream_with_event_numbers_greater_than_2_billion.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Data; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI.ExpectedVersion64Bit; - -[TestFixture(typeof(LogFormat.V2), typeof(string))] -[Category("ClientAPI"), Category("LongRunning")] -public class ReadStreamWithEventNumbersGreaterThan2Billion - : MiniNodeWithExistingRecords -{ - private const string StreamName = "read_stream_with_event_numbers_greater_than_2_billion"; - private const long intMaxValue = (long)int.MaxValue; - - private EventRecord _r1, _r2, _r3, _r4, _r5; - - public override async ValueTask WriteTestScenario(CancellationToken token) - { - _r1 = await WriteSingleEvent(StreamName, intMaxValue + 1, new string('.', 3000), token: token); - _r2 = await WriteSingleEvent(StreamName, intMaxValue + 2, new string('.', 3000), token: token); - _r3 = await WriteSingleEvent(StreamName, intMaxValue + 3, new string('.', 3000), token: token); - _r4 = await WriteSingleEvent(StreamName, intMaxValue + 4, new string('.', 3000), token: token); - _r5 = await WriteSingleEvent(StreamName, intMaxValue + 5, new string('.', 3000), token: token); - } - - public override async Task Given() - { - _store = BuildConnection(Node); - await _store.ConnectAsync(); - await _store.SetStreamMetadataAsync(StreamName, EventStore.ClientAPI.ExpectedVersion.Any, - EventStore.ClientAPI.StreamMetadata.Create(truncateBefore: intMaxValue + 1)); - } - - [Test] - public async Task read_forward_from_zero() - { - var result = await _store.ReadStreamEventsForwardAsync(StreamName, 0, 100, false); - Assert.AreEqual(0, result.Events.Length); - Assert.AreEqual(intMaxValue + 1, result.NextEventNumber); - } - - [Test] - public async Task should_be_able_to_read_stream_forward() - { - var result = await _store.ReadStreamEventsForwardAsync(StreamName, intMaxValue, 100, false); - Assert.AreEqual(5, result.Events.Count()); - Assert.AreEqual(_r1.EventId, result.Events[0].Event.EventId); - Assert.AreEqual(_r2.EventId, result.Events[1].Event.EventId); - Assert.AreEqual(_r3.EventId, result.Events[2].Event.EventId); - Assert.AreEqual(_r4.EventId, result.Events[3].Event.EventId); - Assert.AreEqual(_r5.EventId, result.Events[4].Event.EventId); - } - - [Test] - public async Task should_be_able_to_read_stream_backward() - { - var result = await _store.ReadStreamEventsBackwardAsync(StreamName, intMaxValue + 6, 100, false); - Assert.AreEqual(5, result.Events.Count()); - Assert.AreEqual(_r5.EventId, result.Events[0].Event.EventId); - Assert.AreEqual(_r4.EventId, result.Events[1].Event.EventId); - Assert.AreEqual(_r3.EventId, result.Events[2].Event.EventId); - Assert.AreEqual(_r2.EventId, result.Events[3].Event.EventId); - Assert.AreEqual(_r1.EventId, result.Events[4].Event.EventId); - } - - [Test] - public async Task should_be_able_to_read_each_event() - { - var record = await _store.ReadEventAsync(StreamName, intMaxValue + 1, false); - Assert.AreEqual(EventReadStatus.Success, record.Status); - Assert.AreEqual(_r1.EventId, record.Event.Value.Event.EventId); - - record = await _store.ReadEventAsync(StreamName, intMaxValue + 2, false); - Assert.AreEqual(EventReadStatus.Success, record.Status); - Assert.AreEqual(_r2.EventId, record.Event.Value.Event.EventId); - - record = await _store.ReadEventAsync(StreamName, intMaxValue + 3, false); - Assert.AreEqual(EventReadStatus.Success, record.Status); - Assert.AreEqual(_r3.EventId, record.Event.Value.Event.EventId); - - record = await _store.ReadEventAsync(StreamName, intMaxValue + 4, false); - Assert.AreEqual(EventReadStatus.Success, record.Status); - Assert.AreEqual(_r4.EventId, record.Event.Value.Event.EventId); - - record = await _store.ReadEventAsync(StreamName, intMaxValue + 5, false); - Assert.AreEqual(EventReadStatus.Success, record.Status); - Assert.AreEqual(_r5.EventId, record.Event.Value.Event.EventId); - } - - [Test] - public async Task should_be_able_to_read_all_forward() - { - var result = await _store.ReadAllEventsForwardAsync(Position.Start, 100, false, DefaultData.AdminCredentials) -; - Assert.IsTrue(result.Events.Count() > 5); - - var records = result.Events.Where(x => x.OriginalStreamId == StreamName).ToList(); - Assert.AreEqual(_r1.EventId, records[0].Event.EventId); - Assert.AreEqual(_r2.EventId, records[1].Event.EventId); - Assert.AreEqual(_r3.EventId, records[2].Event.EventId); - Assert.AreEqual(_r4.EventId, records[3].Event.EventId); - Assert.AreEqual(_r5.EventId, records[4].Event.EventId); - } - - [Test] - public async Task should_be_able_to_read_all_backward() - { - var result = await _store.ReadAllEventsBackwardAsync(Position.End, 100, false, DefaultData.AdminCredentials) -; - Assert.IsTrue(result.Events.Count() > 5); - - var records = result.Events.Where(x => x.OriginalStreamId == StreamName).ToList(); - Assert.AreEqual(_r5.EventId, records[0].Event.EventId); - Assert.AreEqual(_r4.EventId, records[1].Event.EventId); - Assert.AreEqual(_r3.EventId, records[2].Event.EventId); - Assert.AreEqual(_r2.EventId, records[3].Event.EventId); - Assert.AreEqual(_r1.EventId, records[4].Event.EventId); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/read_stream_with_link_to_event_with_event_number_greater_than_int_maxvalue.cs b/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/read_stream_with_link_to_event_with_event_number_greater_than_int_maxvalue.cs deleted file mode 100644 index ddc69ce017..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/read_stream_with_link_to_event_with_event_number_greater_than_int_maxvalue.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Data; -using EventStore.Core.Services; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI.ExpectedVersion64Bit; - -[TestFixture(typeof(LogFormat.V2), typeof(string))] -[Category("ClientAPI"), Category("LongRunning")] -public class - ReadStreamWithLinkToEventWithEventNumberGreaterThanIntMaxvalue - : MiniNodeWithExistingRecords -{ - private const string StreamName = "read_stream_with_link_to_event_with_event_number_greater_than_int_maxvalue"; - private const long intMaxValue = (long)int.MaxValue; - - private string _linkedStreamName = "linked-" + StreamName; - private EventRecord _event1, _event2; - - public override async ValueTask WriteTestScenario(CancellationToken token) - { - _event1 = await WriteSingleEvent(StreamName, intMaxValue + 1, new string('.', 3000), token: token); - _event2 = await WriteSingleEvent(StreamName, intMaxValue + 2, new string('.', 3000), token: token); - await WriteSingleEvent(_linkedStreamName, 0, string.Format("{0}@{1}", intMaxValue + 1, StreamName), - eventType: SystemEventTypes.LinkTo, token: token); - await WriteSingleEvent(_linkedStreamName, 1, string.Format("{0}@{1}", intMaxValue + 2, StreamName), - eventType: SystemEventTypes.LinkTo, token: token); - } - - public override async Task Given() - { - _store = BuildConnection(Node); - await _store.ConnectAsync(); - } - - [Test] - public async Task should_be_able_to_read_link_stream_forward_and_resolve_link_tos() - { - var readResult = await _store - .ReadStreamEventsForwardAsync(_linkedStreamName, 0, 100, true, DefaultData.AdminCredentials); - Assert.AreEqual(SliceReadStatus.Success, readResult.Status); - Assert.AreEqual(2, readResult.Events.Length); - Assert.AreEqual(_event1.EventId, readResult.Events[0].Event.EventId); - Assert.AreEqual(_event2.EventId, readResult.Events[1].Event.EventId); - Assert.AreEqual(intMaxValue + 1, readResult.Events[0].Event.EventNumber); - Assert.AreEqual(intMaxValue + 2, readResult.Events[1].Event.EventNumber); - } - - [Test] - public async Task should_be_able_to_read_link_stream_backward_and_resolve_link_tos() - { - var readResult = await _store - .ReadStreamEventsBackwardAsync(_linkedStreamName, 10, 100, true, DefaultData.AdminCredentials); - Assert.AreEqual(SliceReadStatus.Success, readResult.Status); - Assert.AreEqual(2, readResult.Events.Length); - Assert.AreEqual(_event2.EventId, readResult.Events[0].Event.EventId); - Assert.AreEqual(_event1.EventId, readResult.Events[1].Event.EventId); - Assert.AreEqual(intMaxValue + 2, readResult.Events[0].Event.EventNumber); - Assert.AreEqual(intMaxValue + 1, readResult.Events[1].Event.EventNumber); - } - - [Test] - public async Task should_be_able_to_read_all_stream_forward_and_resolve_link_tos() - { - var readResult = await _store.ReadAllEventsForwardAsync(Position.Start, 100, true, DefaultData.AdminCredentials) - ; - var linkedEvents = readResult.Events.Where(x => x.OriginalStreamId == _linkedStreamName).ToList(); - Assert.AreEqual(2, linkedEvents.Count()); - Assert.AreEqual(_event1.EventId, linkedEvents[0].Event.EventId); - Assert.AreEqual(_event2.EventId, linkedEvents[1].Event.EventId); - Assert.AreEqual(intMaxValue + 1, linkedEvents[0].Event.EventNumber); - Assert.AreEqual(intMaxValue + 2, linkedEvents[1].Event.EventNumber); - } - - [Test] - public async Task should_be_able_to_read_all_stream_backward_and_resolve_link_tos() - { - var readResult = await _store.ReadAllEventsBackwardAsync(Position.End, 100, true, DefaultData.AdminCredentials) - ; - var linkedEvents = readResult.Events.Where(x => x.OriginalStreamId == _linkedStreamName).ToList(); - Assert.AreEqual(2, linkedEvents.Count()); - Assert.AreEqual(_event2.EventId, linkedEvents[0].Event.EventId); - Assert.AreEqual(_event1.EventId, linkedEvents[1].Event.EventId); - Assert.AreEqual(intMaxValue + 2, linkedEvents[0].Event.EventNumber); - Assert.AreEqual(intMaxValue + 1, linkedEvents[1].Event.EventNumber); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/subscribe_to_stream_with_link_to_event_with_event_number_greater_than_int_maxvalue.cs b/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/subscribe_to_stream_with_link_to_event_with_event_number_greater_than_int_maxvalue.cs deleted file mode 100644 index 9914e058dc..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/subscribe_to_stream_with_link_to_event_with_event_number_greater_than_int_maxvalue.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Common.Utils; -using EventStore.Core.Services; -using NUnit.Framework; -using ResolvedEvent = EventStore.ClientAPI.ResolvedEvent; - -namespace EventStore.Core.Tests.ClientAPI.ExpectedVersion64Bit; - -[TestFixture(typeof(LogFormat.V2), typeof(string))] -[Category("ClientAPI"), Category("LongRunning")] -public class - SubscribeToStreamWithLinkToEventWithEventNumberGreaterThanIntMaxvalue : - MiniNodeWithExistingRecords -{ - private const string StreamName = - "subscribe_to_stream_with_link_to_event_with_event_number_greater_than_int_maxvalue"; - - private const long intMaxValue = (long)int.MaxValue; - - private string _linkedStreamName = "linked-" + StreamName; - private Guid _event1Id; - - private readonly AutoResetEvent _resetEvent = new AutoResetEvent(false); - private ResolvedEvent _receivedEvent; - - public override async ValueTask WriteTestScenario(CancellationToken token) - { - var event1 = await WriteSingleEvent(StreamName, intMaxValue + 1, new string('.', 3000), token: token); - await WriteSingleEvent(StreamName, intMaxValue + 2, new string('.', 3000), token: token); - _event1Id = event1.EventId; - } - - public override async Task Given() - { - _store = BuildConnection(Node); - await _store.ConnectAsync(); - - await _store.SubscribeToStreamAsync(_linkedStreamName, true, HandleEvent); - await _store.AppendToStreamAsync(_linkedStreamName, ExpectedVersion.NoStream, - new EventData(Guid.NewGuid(), - SystemEventTypes.LinkTo, false, Helper.UTF8NoBom.GetBytes( - $"{intMaxValue + 1}@{StreamName}" - ), null)); - } - - private Task HandleEvent(EventStoreSubscription sub, ResolvedEvent resolvedEvent) - { - _receivedEvent = resolvedEvent; - _resetEvent.Set(); - return Task.CompletedTask; - } - - [Test] - public void should_receive_and_resolve_the_linked_event() - { - Assert.IsTrue(_resetEvent.WaitOne(TimeSpan.FromSeconds(10))); - Assert.AreEqual(intMaxValue + 1, _receivedEvent.Event.EventNumber); - Assert.AreEqual(_event1Id, _receivedEvent.Event.EventId); - Assert.AreEqual(intMaxValue + 1, _receivedEvent.Event.EventNumber); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/subscriptions_on_stream_with_event_numbers_greater_than_2_billion.cs b/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/subscriptions_on_stream_with_event_numbers_greater_than_2_billion.cs deleted file mode 100644 index be53c8081a..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/subscriptions_on_stream_with_event_numbers_greater_than_2_billion.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Data; -using EventStore.Core.Services; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI.ExpectedVersion64Bit; - -[TestFixture(typeof(LogFormat.V2), typeof(string))] -[Category("ClientAPI"), Category("LongRunning")] -public class SubscriptionsOnStreamWithEventNumbersGreaterThan2Billion - : MiniNodeWithExistingRecords -{ - private const long intMaxValue = (long)int.MaxValue; - - private string _volatileStreamOne = "subscriptions-volatile-1"; - private string _volatileStreamTwo = "subscriptions-volatile-2"; - private string _catchupStreamOne = "subscriptions-catchup-1"; - - private EventRecord _c1, _c2; - - public override async ValueTask WriteTestScenario(CancellationToken token) - { - await WriteSingleEvent(_volatileStreamOne, intMaxValue + 1, new string('.', 3000), token: token); - await WriteSingleEvent(_volatileStreamOne, intMaxValue + 2, new string('.', 3000), token: token); - - await WriteSingleEvent(_volatileStreamTwo, intMaxValue + 1, new string('.', 3000), token: token); - await WriteSingleEvent(_volatileStreamTwo, intMaxValue + 2, new string('.', 3000), token: token); - - _c1 = await WriteSingleEvent(_catchupStreamOne, intMaxValue + 1, new string('.', 3000), token: token); - _c2 = await WriteSingleEvent(_catchupStreamOne, intMaxValue + 2, new string('.', 3000), token: token); - } - - public override async Task Given() - { - _store = BuildConnection(Node); - await _store.ConnectAsync(); - await _store.SetStreamMetadataAsync(_volatileStreamOne, EventStore.ClientAPI.ExpectedVersion.Any, - EventStore.ClientAPI.StreamMetadata.Create(truncateBefore: intMaxValue + 1)); - await _store.SetStreamMetadataAsync(_volatileStreamTwo, EventStore.ClientAPI.ExpectedVersion.Any, - EventStore.ClientAPI.StreamMetadata.Create(truncateBefore: intMaxValue + 1)); - await _store.SetStreamMetadataAsync(_catchupStreamOne, EventStore.ClientAPI.ExpectedVersion.Any, - EventStore.ClientAPI.StreamMetadata.Create(truncateBefore: intMaxValue + 1)); - } - - [Test] - public async Task should_be_able_to_subscribe_to_stream_with_volatile_subscription() - { - var evnt = new EventData(Guid.NewGuid(), "EventType", false, new byte[10], new byte[15]); - EventStore.ClientAPI.ResolvedEvent receivedEvent = new EventStore.ClientAPI.ResolvedEvent(); - var mre = new ManualResetEvent(false); - await _store.SubscribeToStreamAsync(_volatileStreamOne, true, (s, e) => - { - receivedEvent = e; - mre.Set(); - return Task.CompletedTask; - }); - - await _store.AppendToStreamAsync(_volatileStreamOne, intMaxValue + 2, evnt); - Assert.That(mre.WaitOne(TimeSpan.FromSeconds(5)), "Timed out waiting for events to appear"); - - Assert.AreEqual(evnt.EventId, receivedEvent.Event.EventId); - } - - [Test] - public async Task should_be_able_to_subscribe_to_all_with_volatile_subscription() - { - var evnt = new EventData(Guid.NewGuid(), "EventType", false, new byte[10], new byte[15]); - EventStore.ClientAPI.ResolvedEvent receivedEvent = new EventStore.ClientAPI.ResolvedEvent(); - var mre = new ManualResetEvent(false); - await _store.SubscribeToAllAsync(true, (s, e) => - { - if (SystemStreams.IsSystemStream(e.OriginalStreamId)) - { - return Task.CompletedTask; - } - - receivedEvent = e; - mre.Set(); - return Task.CompletedTask; - }, userCredentials: DefaultData.AdminCredentials); - - await _store.AppendToStreamAsync(_volatileStreamTwo, intMaxValue + 2, evnt); - Assert.That(mre.WaitOne(TimeSpan.FromSeconds(5)), "Timed out waiting for events to appear"); - - Assert.AreEqual(evnt.EventId, receivedEvent.Event.EventId); - } - - [Test] - public async Task should_be_able_to_subscribe_to_stream_with_catchup_subscription() - { - var evnt = new EventData(Guid.NewGuid(), "EventType", false, new byte[10], new byte[15]); - List receivedEvents = new List(); - - var countdown = new CountdownEvent(3); - _store.SubscribeToStreamFrom(_catchupStreamOne, 0, CatchUpSubscriptionSettings.Default, (s, e) => - { - receivedEvents.Add(e); - countdown.Signal(); - return Task.CompletedTask; - }); - - await _store.AppendToStreamAsync(_catchupStreamOne, intMaxValue + 2, evnt); - - Assert.That(countdown.Wait(TimeSpan.FromSeconds(5)), "Timed out waiting for events to appear"); - - Assert.AreEqual(3, receivedEvents.Count); - Assert.AreEqual(_c1.EventId, receivedEvents[0].Event.EventId); - Assert.AreEqual(_c2.EventId, receivedEvents[1].Event.EventId); - Assert.AreEqual(evnt.EventId, receivedEvents[2].Event.EventId); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/transactions_on_stream_with_event_numbers_greater_than_2_billion.cs b/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/transactions_on_stream_with_event_numbers_greater_than_2_billion.cs deleted file mode 100644 index f7c5c029ff..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/ExpectedVersion64Bit/transactions_on_stream_with_event_numbers_greater_than_2_billion.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Data; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI.ExpectedVersion64Bit; - -[TestFixture(typeof(LogFormat.V2), typeof(string))] -[Category("ClientAPI"), Category("LongRunning")] -public class TransactionsOnStreamWithEventNumbersGreaterThan2Billion - : MiniNodeWithExistingRecords -{ - private const string StreamName = "transactions_on_stream_with_event_numbers_greater_than_2_billion"; - private const long intMaxValue = (long)int.MaxValue; - - private EventRecord _r1, _r2, _r3, _r4, _r5; - - public override async ValueTask WriteTestScenario(CancellationToken token) - { - _r1 = await WriteSingleEvent(StreamName, intMaxValue + 1, new string('.', 3000), token: token); - _r2 = await WriteSingleEvent(StreamName, intMaxValue + 2, new string('.', 3000), token: token); - _r3 = await WriteSingleEvent(StreamName, intMaxValue + 3, new string('.', 3000), token: token); - _r4 = await WriteSingleEvent(StreamName, intMaxValue + 4, new string('.', 3000), token: token); - _r5 = await WriteSingleEvent(StreamName, intMaxValue + 5, new string('.', 3000), token: token); - } - - public override async Task Given() - { - _store = BuildConnection(Node); - await _store.ConnectAsync(); - await _store.SetStreamMetadataAsync(StreamName, EventStore.ClientAPI.ExpectedVersion.Any, - EventStore.ClientAPI.StreamMetadata.Create(truncateBefore: intMaxValue + 1)); - } - - [Test] - public async Task should_be_able_to_append_to_stream_in_a_transaction() - { - var evnt1 = new EventData(Guid.NewGuid(), "EventType", false, new byte[10], new byte[15]); - var evnt2 = new EventData(Guid.NewGuid(), "EventType", false, new byte[10], new byte[15]); - - var transaction = await _store.StartTransactionAsync(StreamName, intMaxValue + 5, DefaultData.AdminCredentials) -; - await transaction.WriteAsync(evnt1); - await transaction.WriteAsync(evnt2); - await transaction.CommitAsync(); - - var records = await _store.ReadStreamEventsForwardAsync(StreamName, intMaxValue, 10, false); - Assert.AreEqual(7, records.Events.Length); - Assert.AreEqual(_r1.EventId, records.Events[0].Event.EventId); - Assert.AreEqual(_r2.EventId, records.Events[1].Event.EventId); - Assert.AreEqual(_r3.EventId, records.Events[2].Event.EventId); - Assert.AreEqual(_r4.EventId, records.Events[3].Event.EventId); - Assert.AreEqual(_r5.EventId, records.Events[4].Event.EventId); - Assert.AreEqual(evnt1.EventId, records.Events[5].Event.EventId); - Assert.AreEqual(evnt2.EventId, records.Events[6].Event.EventId); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/SpecificationWithLinkToToDeletedEvents.cs b/src/EventStore.Core.Tests/ClientAPI/SpecificationWithLinkToToDeletedEvents.cs deleted file mode 100644 index 9b77af2ca7..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/SpecificationWithLinkToToDeletedEvents.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Text; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Common; -using EventStore.ClientAPI.SystemData; -using EventStore.Core.Messages; - -namespace EventStore.Core.Tests.ClientAPI; - -public abstract class SpecificationWithLinkToToDeletedEvents - : SpecificationWithMiniNode -{ - protected string LinkedStreamName; - protected string DeletedStreamName; - - protected override async Task Given() - { - var creds = DefaultData.AdminCredentials; - LinkedStreamName = Guid.NewGuid().ToString(); - DeletedStreamName = Guid.NewGuid().ToString(); - await _conn.AppendToStreamAsync(DeletedStreamName, ExpectedVersion.Any, creds, - new EventData(Guid.NewGuid(), "testing", true, Encoding.UTF8.GetBytes("{'foo' : 4}"), new byte[0])); - await _conn.AppendToStreamAsync(LinkedStreamName, ExpectedVersion.Any, creds, - new EventData(Guid.NewGuid(), SystemEventTypes.LinkTo, false, - Encoding.UTF8.GetBytes("0@" + DeletedStreamName), new byte[0])); - await _conn.DeleteStreamAsync(DeletedStreamName, ExpectedVersion.Any); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/SpecificationWithLinkToToMaxCountDeletedEvents.cs b/src/EventStore.Core.Tests/ClientAPI/SpecificationWithLinkToToMaxCountDeletedEvents.cs deleted file mode 100644 index 07b510971a..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/SpecificationWithLinkToToMaxCountDeletedEvents.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Text; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Common; -using EventStore.ClientAPI.SystemData; - -namespace EventStore.Core.Tests.ClientAPI; - -public abstract class SpecificationWithLinkToToMaxCountDeletedEvents - : SpecificationWithMiniNode -{ - protected string LinkedStreamName; - protected string DeletedStreamName; - - protected override async Task Given() - { - var creds = DefaultData.AdminCredentials; - DeletedStreamName = Guid.NewGuid().ToString(); - LinkedStreamName = Guid.NewGuid().ToString(); - await _conn.AppendToStreamAsync(DeletedStreamName, ExpectedVersion.Any, creds, - new EventData(Guid.NewGuid(), "testing1", true, Encoding.UTF8.GetBytes("{'foo' : 4}"), new byte[0])); - await _conn.SetStreamMetadataAsync(DeletedStreamName, ExpectedVersion.Any, - new StreamMetadata(2, null, null, null, null)); - await _conn.AppendToStreamAsync(DeletedStreamName, ExpectedVersion.Any, creds, - new EventData(Guid.NewGuid(), "testing2", true, Encoding.UTF8.GetBytes("{'foo' : 4}"), new byte[0])); - await _conn.AppendToStreamAsync(DeletedStreamName, ExpectedVersion.Any, creds, - new EventData(Guid.NewGuid(), "testing3", true, Encoding.UTF8.GetBytes("{'foo' : 4}"), new byte[0])); - await _conn.AppendToStreamAsync(LinkedStreamName, ExpectedVersion.Any, creds, - new EventData(Guid.NewGuid(), SystemEventTypes.LinkTo, false, - Encoding.UTF8.GetBytes("0@" + DeletedStreamName), new byte[0])); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/SystemData/clientapi_tcp_package.cs b/src/EventStore.Core.Tests/ClientAPI/SystemData/clientapi_tcp_package.cs deleted file mode 100644 index a9a6a61bf1..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/SystemData/clientapi_tcp_package.cs +++ /dev/null @@ -1,199 +0,0 @@ -using System; -using EventStore.ClientAPI.SystemData; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI.SystemData; - -[TestFixture, Category("ClientAPI")] -public class clientapi_tcp_package -{ - [Test] - public void should_throw_argument_null_exception_when_created_as_authorized_but_login_not_provided() - { - Assert.Throws(() => - new TcpPackage(TcpCommand.BadRequest, TcpFlags.Authenticated, Guid.NewGuid(), null, "pa$$", - new byte[] { 1, 2, 3 })); - } - - [Test] - public void should_throw_argument_null_exception_when_created_as_authorized_but_password_not_provided() - { - Assert.Throws(() => - new TcpPackage(TcpCommand.BadRequest, TcpFlags.Authenticated, Guid.NewGuid(), "login", null, - new byte[] { 1, 2, 3 })); - } - - [Test] - public void should_throw_argument_null_exception_when_created_as_authorized_but_token_not_provided() - { - Assert.Throws(() => - new TcpPackage(TcpCommand.BadRequest, TcpFlags.Authenticated, Guid.NewGuid(), null, - new byte[] { 1, 2, 3 })); - } - - [Test] - public void should_throw_argument_exception_when_created_as_not_authorized_but_login_is_provided() - { - Assert.Throws(() => - new TcpPackage(TcpCommand.BadRequest, TcpFlags.None, Guid.NewGuid(), "login", null, - new byte[] { 1, 2, 3 })); - } - - [Test] - public void should_throw_argument_exception_when_created_as_not_authorized_but_password_is_provided() - { - Assert.Throws(() => - new TcpPackage(TcpCommand.BadRequest, TcpFlags.None, Guid.NewGuid(), null, "pa$$", - new byte[] { 1, 2, 3 })); - } - - [Test] - public void should_throw_argument_exception_when_created_as_not_authorized_but_token_is_provided() - { - Assert.Throws(() => - new TcpPackage(TcpCommand.BadRequest, TcpFlags.None, Guid.NewGuid(), "token", - new byte[] { 1, 2, 3 })); - } - - [Test] - public void not_authorized_with_data_should_serialize_and_deserialize_correctly() - { - var corrId = Guid.NewGuid(); - var refPkg = new TcpPackage(TcpCommand.BadRequest, TcpFlags.None, corrId, null, null, new byte[] { 1, 2, 3 }); - var bytes = refPkg.AsArraySegment(); - - var pkg = TcpPackage.FromArraySegment(bytes); - Assert.AreEqual(TcpCommand.BadRequest, pkg.Command); - Assert.AreEqual(TcpFlags.None, pkg.Flags); - Assert.AreEqual(corrId, pkg.CorrelationId); - Assert.False(pkg.Tokens.TryGetValue("uid", out _)); - Assert.False(pkg.Tokens.TryGetValue("pwd", out _)); - Assert.False(pkg.Tokens.TryGetValue("jwt", out _)); - - Assert.AreEqual(3, pkg.Data.Count); - Assert.AreEqual(1, pkg.Data.Array[pkg.Data.Offset + 0]); - Assert.AreEqual(2, pkg.Data.Array[pkg.Data.Offset + 1]); - Assert.AreEqual(3, pkg.Data.Array[pkg.Data.Offset + 2]); - } - - [Test] - public void not_authorized_with_empty_data_should_serialize_and_deserialize_correctly() - { - var corrId = Guid.NewGuid(); - var refPkg = new TcpPackage(TcpCommand.BadRequest, TcpFlags.None, corrId, null, null, new byte[0]); - var bytes = refPkg.AsArraySegment(); - - var pkg = TcpPackage.FromArraySegment(bytes); - Assert.AreEqual(TcpCommand.BadRequest, pkg.Command); - Assert.AreEqual(TcpFlags.None, pkg.Flags); - Assert.AreEqual(corrId, pkg.CorrelationId); - Assert.False(pkg.Tokens.TryGetValue("uid", out _)); - Assert.False(pkg.Tokens.TryGetValue("pwd", out _)); - Assert.False(pkg.Tokens.TryGetValue("jwt", out _)); - - Assert.AreEqual(0, pkg.Data.Count); - } - - [Test] - public void authorized_with_data_should_serialize_and_deserialize_correctly() - { - var corrId = Guid.NewGuid(); - var refPkg = new TcpPackage(TcpCommand.BadRequest, TcpFlags.Authenticated, corrId, "login", "pa$$", - new byte[] { 1, 2, 3 }); - var bytes = refPkg.AsArraySegment(); - - var pkg = TcpPackage.FromArraySegment(bytes); - Assert.AreEqual(TcpCommand.BadRequest, pkg.Command); - Assert.AreEqual(TcpFlags.Authenticated, pkg.Flags); - Assert.AreEqual(corrId, pkg.CorrelationId); - Assert.AreEqual("login", pkg.Tokens["uid"]); - Assert.AreEqual("pa$$", pkg.Tokens["pwd"]); - Assert.False(pkg.Tokens.TryGetValue("jwt", out _)); - - Assert.AreEqual(3, pkg.Data.Count); - Assert.AreEqual(1, pkg.Data.Array[pkg.Data.Offset + 0]); - Assert.AreEqual(2, pkg.Data.Array[pkg.Data.Offset + 1]); - Assert.AreEqual(3, pkg.Data.Array[pkg.Data.Offset + 2]); - } - - [Test] - public void authorized_with_empty_data_should_serialize_and_deserialize_correctly() - { - var corrId = Guid.NewGuid(); - var refPkg = new TcpPackage(TcpCommand.BadRequest, TcpFlags.Authenticated, corrId, "login", "pa$$", - new byte[0]); - var bytes = refPkg.AsArraySegment(); - - var pkg = TcpPackage.FromArraySegment(bytes); - Assert.AreEqual(TcpCommand.BadRequest, pkg.Command); - Assert.AreEqual(TcpFlags.Authenticated, pkg.Flags); - Assert.AreEqual(corrId, pkg.CorrelationId); - Assert.AreEqual("login", pkg.Tokens["uid"]); - Assert.AreEqual("pa$$", pkg.Tokens["pwd"]); - Assert.False(pkg.Tokens.TryGetValue("jwt", out _)); - - Assert.AreEqual(0, pkg.Data.Count); - } - - [Test] - public void token_authorized_with_data_should_serialize_and_deserialize_correctly() - { - var corrId = Guid.NewGuid(); - var refPkg = new TcpPackage(TcpCommand.BadRequest, TcpFlags.Authenticated, corrId, "token", - new byte[] { 1, 2, 3 }); - var bytes = refPkg.AsArraySegment(); - - var pkg = TcpPackage.FromArraySegment(bytes); - Assert.AreEqual(TcpCommand.BadRequest, pkg.Command); - Assert.AreEqual(TcpFlags.Authenticated, pkg.Flags); - Assert.AreEqual(corrId, pkg.CorrelationId); - Assert.AreEqual("token", pkg.Tokens["jwt"]); - Assert.False(pkg.Tokens.TryGetValue("uid", out _)); - Assert.False(pkg.Tokens.TryGetValue("pwd", out _)); - - Assert.AreEqual(3, pkg.Data.Count); - Assert.AreEqual(1, pkg.Data.Array[pkg.Data.Offset + 0]); - Assert.AreEqual(2, pkg.Data.Array[pkg.Data.Offset + 1]); - Assert.AreEqual(3, pkg.Data.Array[pkg.Data.Offset + 2]); - } - - [Test] - public void token_authorized_with_empty_data_should_serialize_and_deserialize_correctly() - { - var corrId = Guid.NewGuid(); - var refPkg = new TcpPackage(TcpCommand.BadRequest, TcpFlags.Authenticated, corrId, "token", - new byte[0]); - var bytes = refPkg.AsArraySegment(); - - var pkg = TcpPackage.FromArraySegment(bytes); - Assert.AreEqual(TcpCommand.BadRequest, pkg.Command); - Assert.AreEqual(TcpFlags.Authenticated, pkg.Flags); - Assert.AreEqual(corrId, pkg.CorrelationId); - Assert.AreEqual("token", pkg.Tokens["jwt"]); - Assert.False(pkg.Tokens.TryGetValue("uid", out _)); - Assert.False(pkg.Tokens.TryGetValue("pwd", out _)); - - Assert.AreEqual(0, pkg.Data.Count); - } - - [Test] - public void should_throw_argument_exception_when_login_too_long() - { - Assert.Throws(() => new TcpPackage(TcpCommand.BadRequest, TcpFlags.Authenticated, - Guid.NewGuid(), new string('*', TcpPackage.MaxLoginLength + 1), "pa$$", new byte[] { 1, 2, 3 })); - } - - [Test] - public void should_throw_argument_exception_when_password_too_long() - { - Assert.Throws(() => new TcpPackage(TcpCommand.BadRequest, TcpFlags.Authenticated, - Guid.NewGuid(), "login", new string('*', TcpPackage.MaxPasswordLength + 1), new byte[] { 1, 2, 3 })); - } - - [Test] - public void should_throw_argument_exception_when_token_too_long() - { - Assert.Throws(() => new TcpPackage(TcpCommand.BadRequest, TcpFlags.Authenticated, - Guid.NewGuid(), new string('*', TcpPackage.MaxTokenLength + 1), new byte[] { 1, 2, 3 })); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/UserManagement/TestWithNode.cs b/src/EventStore.Core.Tests/ClientAPI/UserManagement/TestWithNode.cs deleted file mode 100644 index 3717bc41e6..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/UserManagement/TestWithNode.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Text; -using System.Threading.Tasks; -using EventStore.Client.Users; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Common.Log; -using EventStore.ClientAPI.SystemData; -using EventStore.ClientAPI.UserManagement; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using Grpc.Core; -using Grpc.Net.Client; -using NUnit.Framework; -using UsersClient = EventStore.Client.Users.Users.UsersClient; - -namespace EventStore.Core.Tests.ClientAPI.UserManagement; - -[Category("LongRunning"), Category("ClientAPI")] -public abstract class TestWithNode : SpecificationWithDirectoryPerTestFixture -{ - protected MiniNode _node; - protected UsersManager _manager; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - _manager = new UsersManager(new NoopLogger(), _node.HttpEndPoint, TimeSpan.FromSeconds(5), httpMessageHandler: _node.HttpMessageHandler); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - protected async Task CreateUserWithGrpc( - string loginName, - string fullName, - string[] groups, - string password, - UserCredentials credentials) - { - using var channel = GrpcChannel.ForAddress(new Uri($"https://{_node.HttpEndPoint}"), - new GrpcChannelOptions - { - HttpClient = _node.HttpClient, - DisposeHttpClient = false - }); - var users = new UsersClient(channel); - await users.CreateAsync(new CreateReq - { - Options = new CreateReq.Types.Options - { - LoginName = loginName, - FullName = fullName, - Groups = { groups }, - Password = password - } - }, new CallOptions(new Metadata { - {"authorization", BasicAuthHeader(credentials)} - })); - } - - private static string BasicAuthHeader(UserCredentials credentials) => - "Basic " + Convert.ToBase64String( - Encoding.ASCII.GetBytes($"{credentials.Username}:{credentials.Password}")); -} diff --git a/src/EventStore.Core.Tests/ClientAPI/append_to_stream.cs b/src/EventStore.Core.Tests/ClientAPI/append_to_stream.cs deleted file mode 100644 index 60c1bbdce9..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/append_to_stream.cs +++ /dev/null @@ -1,798 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Exceptions; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class append_to_stream : SpecificationWithDirectoryPerTestFixture -{ - private readonly TcpType _tcpType = TcpType.Ssl; - private MiniNode _node; - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.To(node, _tcpType); - } - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - [Test, Category("Network")] - public async Task should_allow_appending_zero_events_to_stream_with_no_problems() - { - const string stream1 = "should_allow_appending_zero_events_to_stream_with_no_problems1"; - const string stream2 = "should_allow_appending_zero_events_to_stream_with_no_problems2"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - Assert.AreEqual(-1, - (await store.AppendToStreamAsync(stream1, ExpectedVersion.Any)).NextExpectedVersion); - Assert.AreEqual(-1, - (await store.AppendToStreamAsync(stream1, ExpectedVersion.NoStream)).NextExpectedVersion); - Assert.AreEqual(-1, (await store.AppendToStreamAsync(stream1, ExpectedVersion.Any)).NextExpectedVersion); - Assert.AreEqual(-1, - (await store.AppendToStreamAsync(stream1, ExpectedVersion.NoStream)).NextExpectedVersion); - - var read1 = await store.ReadStreamEventsForwardAsync(stream1, 0, 2, resolveLinkTos: false); - Assert.That(read1.Events.Length, Is.EqualTo(0)); - - Assert.AreEqual(-1, (await store.AppendToStreamAsync(stream2, ExpectedVersion.NoStream)).NextExpectedVersion); - Assert.AreEqual(-1, (await store.AppendToStreamAsync(stream2, ExpectedVersion.Any)).NextExpectedVersion); - Assert.AreEqual(-1, (await store.AppendToStreamAsync(stream2, ExpectedVersion.NoStream)).NextExpectedVersion); - Assert.AreEqual(-1, (await store.AppendToStreamAsync(stream2, ExpectedVersion.Any)).NextExpectedVersion); - - var read2 = await store.ReadStreamEventsForwardAsync(stream2, 0, 2, resolveLinkTos: false); - Assert.That(read2.Events.Length, Is.EqualTo(0)); - } - } - - [Test, Category("Network")] - public async Task should_create_stream_with_no_stream_exp_ver_on_first_write_if_does_not_exist() - { - const string stream = "should_create_stream_with_no_stream_exp_ver_on_first_write_if_does_not_exist"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - Assert.AreEqual(0, (await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent())) - .NextExpectedVersion); - - var read = await store.ReadStreamEventsForwardAsync(stream, 0, 2, resolveLinkTos: false); - Assert.That(read.Events.Length, Is.EqualTo(1)); - } - } - - [Test] - [Category("Network")] - public async Task should_create_stream_with_any_exp_ver_on_first_write_if_does_not_exist() - { - const string stream = "should_create_stream_with_any_exp_ver_on_first_write_if_does_not_exist"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(0, (await store.AppendToStreamAsync(stream, ExpectedVersion.Any, TestEvent.NewTestEvent())).NextExpectedVersion); - - var read = await store.ReadStreamEventsForwardAsync(stream, 0, 2, resolveLinkTos: false); - Assert.That(read.Events.Length, Is.EqualTo(1)); - } - } - - [Test] - [Category("Network")] - public async Task multiple_idempotent_writes() - { - const string stream = "multiple_idempotent_writes"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = new[] { - TestEvent.NewTestEvent(), TestEvent.NewTestEvent(), TestEvent.NewTestEvent(), - TestEvent.NewTestEvent() - }; - Assert.AreEqual(3, - (await store.AppendToStreamAsync(stream, ExpectedVersion.Any, events)).NextExpectedVersion); - Assert.AreEqual(3, - (await store.AppendToStreamAsync(stream, ExpectedVersion.Any, events)).NextExpectedVersion); - } - } - - [Test] - [Category("Network")] - public async Task multiple_idempotent_writes_with_same_id_bug_case() - { - const string stream = "multiple_idempotent_writes_with_same_id_bug_case"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var x = TestEvent.NewTestEvent(); - var events = new[] { x, x, x, x, x, x }; - Assert.AreEqual(5, (await store.AppendToStreamAsync(stream, ExpectedVersion.Any, events)).NextExpectedVersion); - } - } - - [Test] - [Category("Network")] - public async Task - in_case_where_multiple_writes_of_multiple_events_with_the_same_ids_using_expected_version_any_then_next_expected_version_is_unreliable() - { - const string stream = "in_wtf_multiple_case_of_multiple_writes_expected_version_any_per_all_same_id"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var x = TestEvent.NewTestEvent(); - var events = new[] { x, x, x, x, x, x }; - Assert.AreEqual(5, (await store.AppendToStreamAsync(stream, ExpectedVersion.Any, events)).NextExpectedVersion); - var f = await store.AppendToStreamAsync(stream, ExpectedVersion.Any, events); - Assert.AreEqual(0, f.NextExpectedVersion); - } - } - - [Test] - [Category("Network")] - public async Task - in_case_where_multiple_writes_of_multiple_events_with_the_same_ids_using_expected_version_nostream_then_next_expected_version_is_correct() - { - const string stream = - "in_slightly_reasonable_multiple_case_of_multiple_writes_with_expected_version_per_all_same_id"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var x = TestEvent.NewTestEvent(); - var events = new[] { x, x, x, x, x, x }; - Assert.AreEqual(5, - (await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, events)).NextExpectedVersion); - var f = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, events); - Assert.AreEqual(5, f.NextExpectedVersion); - } - } - - [Test] - [Category("Network")] - public async Task should_fail_writing_with_correct_exp_ver_to_deleted_stream() - { - const string stream = "should_fail_writing_with_correct_exp_ver_to_deleted_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - await store.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - - await AssertEx.ThrowsAsync( - () => store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent())); - - } - } - - [Test] - [Category("Network")] - public async Task should_return_log_position_when_writing() - { - const string stream = "should_return_log_position_when_writing"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var result = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()); - Assert.IsTrue(0 < result.LogPosition.PreparePosition); - Assert.IsTrue(0 < result.LogPosition.CommitPosition); - } - } - - [Test] - [Category("Network")] - public async Task should_fail_writing_with_any_exp_ver_to_deleted_stream() - { - const string stream = "should_fail_writing_with_any_exp_ver_to_deleted_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - try - { - await store.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - } - catch (Exception exc) - { - Console.WriteLine(exc); - Assert.Fail(); - } - - await AssertEx.ThrowsAsync( - () => store.AppendToStreamAsync(stream, ExpectedVersion.Any, TestEvent.NewTestEvent())); - } - } - - [Test] - [Category("Network")] - public async Task should_fail_writing_with_invalid_exp_ver_to_deleted_stream() - { - const string stream = "should_fail_writing_with_invalid_exp_ver_to_deleted_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - await store.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - - await AssertEx.ThrowsAsync(() => store.AppendToStreamAsync(stream, 5, TestEvent.NewTestEvent())); - } - } - - [Test] - [Category("Network")] - public async Task should_append_with_correct_exp_ver_to_existing_stream() - { - const string stream = "should_append_with_correct_exp_ver_to_existing_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()); - - await store.AppendToStreamAsync(stream, 0, new[] { TestEvent.NewTestEvent() }); - } - } - - [Test] - [Category("Network")] - public async Task should_append_with_any_exp_ver_to_existing_stream() - { - const string stream = "should_append_with_any_exp_ver_to_existing_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(0, (await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent())).NextExpectedVersion); - Assert.AreEqual(1, (await store.AppendToStreamAsync(stream, ExpectedVersion.Any, TestEvent.NewTestEvent())).NextExpectedVersion); - } - } - - [Test] - [Category("Network")] - public async Task should_fail_appending_with_wrong_exp_ver_to_existing_stream() - { - const string stream = "should_fail_appending_with_wrong_exp_ver_to_existing_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var wev = await AssertEx.ThrowsAsync(() => - store.AppendToStreamAsync(stream, 1, new[] { TestEvent.NewTestEvent() })); - Assert.AreEqual(1, wev.ExpectedVersion); - Assert.AreEqual(ExpectedVersion.NoStream, wev.ActualVersion); - } - } - - [Test] - [Category("Network")] - public async Task should_append_with_stream_exists_exp_ver_to_existing_stream() - { - const string stream = "should_append_with_stream_exists_exp_ver_to_existing_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()); - - await store.AppendToStreamAsync(stream, ExpectedVersion.StreamExists, TestEvent.NewTestEvent()); - } - } - - [Test] - [Category("Network")] - public async Task should_append_with_stream_exists_exp_ver_to_stream_with_multiple_events() - { - const string stream = "should_append_with_stream_exists_exp_ver_to_stream_with_multiple_events"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - for (var i = 0; i < 5; i++) - { - await store.AppendToStreamAsync(stream, ExpectedVersion.Any, TestEvent.NewTestEvent()); - } - - await store.AppendToStreamAsync(stream, ExpectedVersion.StreamExists, TestEvent.NewTestEvent()); - } - } - - [Test] - [Category("Network")] - public async Task should_append_with_stream_exists_exp_ver_if_metadata_stream_exists() - { - const string stream = "should_append_with_stream_exists_exp_ver_if_metadata_stream_exists"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - await store.SetStreamMetadataAsync(stream, ExpectedVersion.Any, - new StreamMetadata(10, null, null, null, null)); - - await store.AppendToStreamAsync(stream, ExpectedVersion.StreamExists, TestEvent.NewTestEvent()); - } - } - - [Test] - [Category("Network")] - public async Task should_fail_appending_with_stream_exists_exp_ver_and_stream_does_not_exist() - { - const string stream = "should_fail_appending_with_stream_exists_exp_ver_and_stream_does_not_exist"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var wev = await AssertEx.ThrowsAsync( - () => store.AppendToStreamAsync(stream, ExpectedVersion.StreamExists, TestEvent.NewTestEvent())); - Assert.AreEqual(ExpectedVersion.StreamExists, wev.ExpectedVersion); - Assert.AreEqual(ExpectedVersion.NoStream, wev.ActualVersion); - } - } - - [Test] - [Category("Network")] - public async Task should_fail_appending_with_stream_exists_exp_ver_to_hard_deleted_stream() - { - const string stream = "should_fail_appending_with_stream_exists_exp_ver_to_hard_deleted_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - await store.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - - await AssertEx.ThrowsAsync( - () => store.AppendToStreamAsync(stream, ExpectedVersion.StreamExists, TestEvent.NewTestEvent())); - } - } - - [Test] - [Category("Network")] - public async Task should_fail_appending_with_stream_exists_exp_ver_to_soft_deleted_stream() - { - const string stream = "should_fail_appending_with_stream_exists_exp_ver_to_soft_deleted_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()); - - await store.DeleteStreamAsync(stream, ExpectedVersion.StreamExists, hardDelete: false); - - await AssertEx.ThrowsAsync( - () => store.AppendToStreamAsync(stream, ExpectedVersion.StreamExists, TestEvent.NewTestEvent())); - } - } - - [Test, Category("Network")] - public async Task can_append_multiple_events_at_once() - { - const string stream = "can_append_multiple_events_at_once"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 100).Select(i => TestEvent.NewTestEvent(i.ToString(), i.ToString())); - Assert.AreEqual(99, (await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, events)).NextExpectedVersion); - } - } - - [Test] - public async Task cannot_append_multiple_events_larger_than_chunk_size_at_once() - { - const string stream = "cannot_append_multiple_events_larger_than_chunk_size_at_once"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - // Create events with large payloads (20KB each) to exceed chunk size when combined - const int eventPayloadSize = 20_000; // 20KB per event - const int eventCount = 100; // Total: ~2MB, exceeding default 256MB chunk only if chunk is very small - var largeEventData = new string('X', eventPayloadSize); - var events = Enumerable.Range(0, eventCount).Select(i => TestEvent.NewTestEvent(largeEventData, $"event-{i}")); - - // First, write a small batch successfully (4 events) - const int initialBatchSize = 4; - var firstWriteResult = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, events.Take(initialBatchSize)); - Assert.AreEqual(initialBatchSize - 1, firstWriteResult.NextExpectedVersion, "First write should succeed"); - - // Attempt to write a transaction that's too large - should fail - await AssertEx.ThrowsAsync(async () => - await store.AppendToStreamAsync(stream, firstWriteResult.NextExpectedVersion, events)); - - // Verify that subsequent writes still work correctly with the expected version - // This tests that the missing return statement bug is fixed - without the fix, - // the expected version would be corrupted and this write would fail - var subsequentWriteResult = await store.AppendToStreamAsync(stream, firstWriteResult.NextExpectedVersion, events.Take(initialBatchSize)); - Assert.AreEqual(firstWriteResult.NextExpectedVersion + initialBatchSize, subsequentWriteResult.NextExpectedVersion, - "Subsequent write should succeed with correct expected version after failed large transaction"); - } - } - - [Test] - public async Task can_append_to_stream_with_long_name() - { - var stream = "can_append_to_stream_with_long_name" + new string('A', 300); - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(0, (await store.AppendToStreamAsync - (stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent())).NextExpectedVersion); - } - } - - [Test] - public async Task can_append_multiple_events_to_stream_with_long_name_at_once() - { - var stream = "can_append_multiple_events_to_stream_with_long_name_at_once" + new string('A', 300); - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var events = Enumerable.Range(0, 3).Select(i => TestEvent.NewTestEvent(i.ToString(), i.ToString())); - Assert.AreEqual(2, (await store.AppendToStreamAsync - (stream, ExpectedVersion.NoStream, events)).NextExpectedVersion); - } - } - - [Test] - public async Task can_append_event_with_long_event_type() - { - const string stream = "can_append_event_with_long_event_type"; - var eventType = new string('A', 300); - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(0, (await store.AppendToStreamAsync - (stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(eventName: eventType))).NextExpectedVersion); - } - } - - [Test] - public async Task can_append_multiple_events_with_long_event_type_at_once() - { - const string stream = "can_append_multiple_events_with_long_event_type_at_once"; - var eventType = new string('A', 300); - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var events = Enumerable.Range(0, 3).Select(i => - TestEvent.NewTestEvent(i.ToString(), i.ToString(), eventName: eventType)); - Assert.AreEqual(2, (await store.AppendToStreamAsync - (stream, ExpectedVersion.NoStream, events)).NextExpectedVersion); - } - } - - [Test, Category("Network")] - public async Task returns_failure_status_when_conditionally_appending_with_version_mismatch() - { - const string stream = "returns_failure_status_when_conditionally_appending_with_version_mismatch"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var result = await store.ConditionalAppendToStreamAsync(stream, 7, new[] { TestEvent.NewTestEvent() }); - - Assert.AreEqual(ConditionalWriteStatus.VersionMismatch, result.Status); - } - } - - [Test, Category("Network")] - public async Task returns_success_status_when_conditionally_appending_with_matching_version() - { - const string stream = "returns_success_status_when_conditionally_appending_with_matching_version"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var result = await store - .ConditionalAppendToStreamAsync(stream, ExpectedVersion.Any, new[] { TestEvent.NewTestEvent() }); - - Assert.AreEqual(ConditionalWriteStatus.Succeeded, result.Status); - Assert.IsNotNull(result.LogPosition); - Assert.IsNotNull(result.NextExpectedVersion); - } - } - - [Test, Category("Network")] - public async Task returns_failure_status_when_conditionally_appending_to_a_deleted_stream() - { - const string stream = "returns_failure_status_when_conditionally_appending_to_a_deleted_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - await store.AppendToStreamAsync(stream, ExpectedVersion.Any, TestEvent.NewTestEvent()); - await store.DeleteStreamAsync(stream, ExpectedVersion.Any, true); - - var result = await store - .ConditionalAppendToStreamAsync(stream, ExpectedVersion.Any, new[] { TestEvent.NewTestEvent() }); - - Assert.AreEqual(ConditionalWriteStatus.StreamDeleted, result.Status); - } - } -} - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class ssl_append_to_stream : SpecificationWithDirectoryPerTestFixture -{ - private readonly TcpType _tcpType = TcpType.Ssl; - protected MiniNode _node; - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.To(node, _tcpType); - } - - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - [Test] - public async Task should_allow_appending_zero_events_to_stream_with_no_problems() - { - const string stream = "should_allow_appending_zero_events_to_stream_with_no_problems"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(-1, - (await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream)).NextExpectedVersion); - - var read = await store.ReadStreamEventsForwardAsync(stream, 0, 2, resolveLinkTos: false); - Assert.That(read.Events.Length, Is.EqualTo(0)); - } - } - - [Test] - public async Task should_create_stream_with_no_stream_exp_ver_on_first_write_if_does_not_exist() - { - const string stream = "should_create_stream_with_no_stream_exp_ver_on_first_write_if_does_not_exist"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(0, - (await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent())).NextExpectedVersion); - - var read = await store.ReadStreamEventsForwardAsync(stream, 0, 2, resolveLinkTos: false); - Assert.That(read.Events.Length, Is.EqualTo(1)); - } - } - - [Test] - public async Task should_create_stream_with_any_exp_ver_on_first_write_if_does_not_exist() - { - const string stream = "should_create_stream_with_any_exp_ver_on_first_write_if_does_not_exist"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(0, - (await store.AppendToStreamAsync(stream, ExpectedVersion.Any, TestEvent.NewTestEvent())).NextExpectedVersion); - - var read = await store.ReadStreamEventsForwardAsync(stream, 0, 2, resolveLinkTos: false); - Assert.That(read.Events.Length, Is.EqualTo(1)); - } - } - - [Test] - public async Task should_fail_writing_with_correct_exp_ver_to_deleted_stream() - { - const string stream = "should_fail_writing_with_correct_exp_ver_to_deleted_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - await store.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - - await AssertEx.ThrowsAsync(() => - store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent())); - } - } - - [Test] - public async Task should_fail_writing_with_any_exp_ver_to_deleted_stream() - { - const string stream = "should_fail_writing_with_any_exp_ver_to_deleted_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - await store.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - - await AssertEx.ThrowsAsync(() => - store.AppendToStreamAsync(stream, ExpectedVersion.Any, TestEvent.NewTestEvent())); - } - } - - [Test] - public async Task should_fail_writing_with_invalid_exp_ver_to_deleted_stream() - { - const string stream = "should_fail_writing_with_invalid_exp_ver_to_deleted_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - await store.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - - await AssertEx.ThrowsAsync(() => - store.AppendToStreamAsync(stream, 5, new[] { TestEvent.NewTestEvent() })); - } - } - - [Test] - public async Task should_append_with_correct_exp_ver_to_existing_stream() - { - const string stream = "should_append_with_correct_exp_ver_to_existing_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(0, - (await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent())).NextExpectedVersion); - Assert.AreEqual(1, (await store.AppendToStreamAsync(stream, 0, TestEvent.NewTestEvent())).NextExpectedVersion); - } - } - - [Test] - public async Task should_append_with_any_exp_ver_to_existing_stream() - { - const string stream = "should_append_with_any_exp_ver_to_existing_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(0, - (await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent())).NextExpectedVersion); - Assert.AreEqual(1, (await store.AppendToStreamAsync(stream, ExpectedVersion.Any, TestEvent.NewTestEvent())).NextExpectedVersion); - } - } - - [Test] - public async Task should_return_log_position_when_writing() - { - const string stream = "should_return_log_position_when_writing"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var result = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()); - Assert.IsTrue(0 < result.LogPosition.PreparePosition); - Assert.IsTrue(0 < result.LogPosition.CommitPosition); - } - } - - [Test] - public async Task should_fail_appending_with_wrong_exp_ver_to_existing_stream() - { - const string stream = "should_fail_appending_with_wrong_exp_ver_to_existing_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(0, - (await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent())).NextExpectedVersion); - - var wev = await AssertEx.ThrowsAsync(() => - store.AppendToStreamAsync(stream, 1, TestEvent.NewTestEvent())); - Assert.AreEqual(1, wev.ExpectedVersion); - Assert.AreEqual(0, wev.ActualVersion.GetValueOrDefault(0)); - } - } - - [Test] - public async Task can_append_multiple_events_at_once() - { - const string stream = "can_append_multiple_events_at_once"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 100).Select(i => TestEvent.NewTestEvent(i.ToString(), i.ToString())); - Assert.AreEqual(99, (await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, events)).NextExpectedVersion); - } - } - - [Test] - public async Task cannot_append_multiple_events_larger_than_chunk_size_at_once() - { - const string stream = "cannot_append_multiple_events_larger_than_chunk_size_at_once"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - // Create events with large payloads (20KB each) to exceed chunk size when combined - const int eventPayloadSize = 20_000; // 20KB per event - const int eventCount = 100; // Total: ~2MB, exceeding default 256MB chunk only if chunk is very small - var largeEventData = new string('X', eventPayloadSize); - var events = Enumerable.Range(0, eventCount).Select(i => TestEvent.NewTestEvent(largeEventData, $"event-{i}")); - - // First, write a small batch successfully (4 events) - const int initialBatchSize = 4; - var firstWriteResult = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, events.Take(initialBatchSize)); - Assert.AreEqual(initialBatchSize - 1, firstWriteResult.NextExpectedVersion, "First write should succeed"); - - // Attempt to write a transaction that's too large - should fail - await AssertEx.ThrowsAsync(async () => - await store.AppendToStreamAsync(stream, firstWriteResult.NextExpectedVersion, events)); - - // Verify that subsequent writes still work correctly with the expected version - // This tests that the missing return statement bug is fixed - without the fix, - // the expected version would be corrupted and this write would fail - var subsequentWriteResult = await store.AppendToStreamAsync(stream, firstWriteResult.NextExpectedVersion, events.Take(initialBatchSize)); - Assert.AreEqual(firstWriteResult.NextExpectedVersion + initialBatchSize, subsequentWriteResult.NextExpectedVersion, - "Subsequent write should succeed with correct expected version after failed large transaction"); - } - } - - [Test] - public async Task can_append_to_stream_with_long_name() - { - var stream = "can_append_to_stream_with_long_name" + new string('A', 300); - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(0, (await store.AppendToStreamAsync - (stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent())).NextExpectedVersion); - } - } - - [Test] - public async Task can_append_multiple_events_to_stream_with_long_name_at_once() - { - var stream = "can_append_multiple_events_to_stream_with_long_name_at_once" + new string('A', 300); - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var events = Enumerable.Range(0, 3).Select(i => TestEvent.NewTestEvent(i.ToString(), i.ToString())); - Assert.AreEqual(2, (await store.AppendToStreamAsync - (stream, ExpectedVersion.NoStream, events)).NextExpectedVersion); - } - } - - [Test] - public async Task can_append_event_with_long_event_type() - { - const string stream = "can_append_event_with_long_event_type"; - var eventType = new string('A', 300); - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(0, (await store.AppendToStreamAsync - (stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(eventName: eventType))).NextExpectedVersion); - } - } - - [Test] - public async Task can_append_multiple_events_with_long_event_type_at_once() - { - const string stream = "can_append_multiple_events_with_long_event_type_at_once"; - var eventType = new string('A', 300); - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var events = Enumerable.Range(0, 3).Select(i => - TestEvent.NewTestEvent(i.ToString(), i.ToString(), eventName: eventType)); - Assert.AreEqual(2, (await store.AppendToStreamAsync - (stream, ExpectedVersion.NoStream, events)).NextExpectedVersion); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/append_to_stream_with_hash_collision.cs b/src/EventStore.Core.Tests/ClientAPI/append_to_stream_with_hash_collision.cs deleted file mode 100644 index 9fcd053034..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/append_to_stream_with_hash_collision.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Exceptions; -using EventStore.Core.Tests; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.Services.Storage.HashCollisions; - -[Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class append_to_stream_with_hash_collision : SpecificationWithDirectoryPerTestFixture -{ - private const int LongRunningTimeout = 1200000; - private static readonly TimeSpan StartupTimeout = TimeSpan.FromMinutes(10); - private MiniNode _node; - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.To(node, TcpType.Ssl); - } - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName, - memTableSize: 20, - hashCollisionReadLimit: 1, - indexBitnessVersion: EventStore.Core.Index.PTableVersions.IndexV4, - hash32bit: true, - streamExistenceFilterSize: 0); - await _node.Start(StartupTimeout); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - [Test, Timeout(LongRunningTimeout)] - public async Task should_throw_wrong_expected_version() - { - const string stream1 = "account--696193173"; - const string stream2 = "LPN-FC002_LPK51001"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - //Write event to stream 1 - Assert.AreEqual(0, (await store.AppendToStreamAsync(stream1, ExpectedVersion.NoStream, - new EventData(Guid.NewGuid(), "TestEvent", true, null, null))).NextExpectedVersion); - //Write 100 events to stream 2 which will have the same hash as stream 1. - for (int i = 0; i < 100; i++) - { - Assert.AreEqual(i, (await store.AppendToStreamAsync(stream2, ExpectedVersion.Any, - new EventData(Guid.NewGuid(), "TestEvent", true, null, null))).NextExpectedVersion); - } - } - - var tcpPort = _node.TcpEndPoint.Port; - var httpPort = _node.HttpEndPoint.Port; - await _node.Shutdown(keepDb: true); - - //Restart the node to ensure the read index stream info cache is empty - _node = new MiniNode(PathName, - tcpPort, httpPort, - memTableSize: 20, - hashCollisionReadLimit: 1, - indexBitnessVersion: EventStore.Core.Index.PTableVersions.IndexV4, - hash32bit: true, - streamExistenceFilterSize: 0); - await _node.Start(StartupTimeout); - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - await AssertEx.ThrowsAsync( - () => store.AppendToStreamAsync(stream1, ExpectedVersion.Any, - new EventData(Guid.NewGuid(), "TestEvent", true, null, null))); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/appending_to_implicitly_created_stream.cs b/src/EventStore.Core.Tests/ClientAPI/appending_to_implicitly_created_stream.cs deleted file mode 100644 index 28059a09c4..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/appending_to_implicitly_created_stream.cs +++ /dev/null @@ -1,323 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Exceptions; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class appending_to_implicitly_created_stream : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - /* - * sequence - events written so stream - * 0em1 - event number 0 written with exp version -1 (minus 1) - * 1any - event number 1 written with exp version any - * S_0em1_1em1_E - START bucket, two events in bucket, END bucket - */ - - [Test] - [Category("Network")] - public async Task sequence_0em1_1e0_2e1_3e2_4e3_5e4_0em1_idempotent() - { - const string stream = - "appending_to_implicitly_created_stream_sequence_0em1_1e0_2e1_3e2_4e3_5e4_0em1_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 6).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new StreamWriter(store, stream, -1); - - var tail = await writer.Append(events); - - await tail.Then(events[0], -1); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_1e0_2e1_3e2_4e3_4e4_0any_idempotent() - { - const string stream = - "appending_to_implicitly_created_stream_sequence_0em1_1e0_2e1_3e2_4e3_4e4_0any_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 6).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new StreamWriter(store, stream, -1); - - var tail = await writer.Append(events); - await tail.Then(events.First(), ExpectedVersion.Any); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_1e0_2e1_3e2_4e3_5e4_0e5_non_idempotent() - { - const string stream = - "appending_to_implicitly_created_stream_sequence_0em1_1e0_2e1_3e2_4e3_5e4_0e5_non_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 6).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new StreamWriter(store, stream, -1); - - var tail = await writer.Append(events); - await tail.Then(events.First(), 5); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length + 1)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_1e0_2e1_3e2_4e3_5e4_0e6_wev() - { - const string stream = "appending_to_implicitly_created_stream_sequence_0em1_1e0_2e1_3e2_4e3_5e4_0e6_wev"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 6).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new StreamWriter(store, stream, -1); - - var first6 = await writer.Append(events); - await AssertEx.ThrowsAsync( - () => first6.Then(events.First(), 6)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_1e0_2e1_3e2_4e3_5e4_0e4_wev() - { - const string stream = "appending_to_implicitly_created_stream_sequence_0em1_1e0_2e1_3e2_4e3_5e4_0e4_wev"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 6).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new StreamWriter(store, stream, -1); - - var first6 = await writer.Append(events); - await AssertEx.ThrowsAsync( - () => first6.Then(events.First(), 4)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_0e0_non_idempotent() - { - const string stream = "appending_to_implicitly_created_stream_sequence_0em1_0e0_non_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 1).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new StreamWriter(store, stream, -1); - - var tail = await writer.Append(events); - await tail.Then(events.First(), 0); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length + 1)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_0any_idempotent() - { - const string stream = "appending_to_implicitly_created_stream_sequence_0em1_0any_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 1).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new StreamWriter(store, stream, -1); - - var tail = await writer.Append(events); - - await tail.Then(events.First(), ExpectedVersion.Any); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_0em1_idempotent() - { - const string stream = "appending_to_implicitly_created_stream_sequence_0em1_0em1_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 1).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new StreamWriter(store, stream, -1); - - var tail = await writer.Append(events); - await tail.Then(events.First(), -1); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_1e0_2e1_1any_1any_idempotent() - { - const string stream = "appending_to_implicitly_created_stream_sequence_0em1_1e0_2e1_1any_1any_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 3).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new StreamWriter(store, stream, -1); - - - var tailWriter = await writer.Append(events); - tailWriter = await tailWriter.Then(events[1], ExpectedVersion.Any); - await tailWriter.Then(events[1], ExpectedVersion.Any); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_S_0em1_1em1_E_S_0em1_E_idempotent() - { - const string stream = "appending_to_implicitly_created_stream_sequence_S_0em1_1em1_E_S_0em1_E_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 2).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - await store.AppendToStreamAsync(stream, -1, events); - - await store.AppendToStreamAsync(stream, -1, events.First()); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_S_0em1_1em1_E_S_0any_E_idempotent() - { - const string stream = "appending_to_implicitly_created_stream_sequence_S_0em1_1em1_E_S_0any_E_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 2).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - await store.AppendToStreamAsync(stream, -1, events); - - await store.AppendToStreamAsync(stream, ExpectedVersion.Any, new[] { events.First() }); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_S_0em1_1em1_E_S_1e0_E_idempotent() - { - const string stream = "appending_to_implicitly_created_stream_sequence_S_0em1_1em1_E_S_1e0_E_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 2).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - await store.AppendToStreamAsync(stream, -1, events); - - await store.AppendToStreamAsync(stream, 0, events[1]); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_S_0em1_1em1_E_S_1any_E_idempotent() - { - const string stream = "appending_to_implicitly_created_stream_sequence_S_0em1_1em1_E_S_1any_E_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 2).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - await store.AppendToStreamAsync(stream, -1, events); - - await store.AppendToStreamAsync(stream, ExpectedVersion.Any, events[1]); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_S_0em1_1em1_E_S_0em1_1em1_2em1_E_idempotancy_fail() - { - const string stream = - "appending_to_implicitly_created_stream_sequence_S_0em1_1em1_E_S_0em1_1em1_2em1_E_idempotancy_fail"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 2).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - await store.AppendToStreamAsync(stream, -1, events); - - await AssertEx.ThrowsAsync( - () => store.AppendToStreamAsync(stream, -1, - events.Concat(new[] { TestEvent.NewTestEvent(Guid.NewGuid()) }))); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/appending_to_implicitly_created_stream_using_transaction.cs b/src/EventStore.Core.Tests/ClientAPI/appending_to_implicitly_created_stream_using_transaction.cs deleted file mode 100644 index efeb03aaf2..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/appending_to_implicitly_created_stream_using_transaction.cs +++ /dev/null @@ -1,251 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Exceptions; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class appending_to_implicitly_created_stream_using_transaction : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - virtual protected IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - /* - * sequence - events written so stream - * 0em1 - event number 0 written with exp version -1 (minus 1) - * 1any - event number 1 written with exp version any - * S_0em1_1em1_E - START bucket, two events in bucket, END bucket - */ - - [Test] - [Category("Network")] - public async Task sequence_0em1_1e0_2e1_3e2_4e3_5e4_0em1_idempotent() - { - const string stream = - "appending_to_implicitly_created_stream_using_transaction_sequence_0em1_1e0_2e1_3e2_4e3_5e4_0em1_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 6).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new TransactionalWriter(store, stream); - - Assert.AreEqual(5, (await (await (await writer.StartTransaction(-1)).Write(events)).Commit()).NextExpectedVersion); - Assert.AreEqual(0, (await (await (await writer.StartTransaction(-1)).Write(events.First())).Commit()).NextExpectedVersion); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_1e0_2e1_3e2_4e3_5e4_0any_idempotent() - { - const string stream = - "appending_to_implicitly_created_stream_using_transaction_sequence_0em1_1e0_2e1_3e2_4e3_5e4_0any_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 6).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new TransactionalWriter(store, stream); - - Assert.AreEqual(5, (await (await (await writer.StartTransaction(-1)).Write(events)).Commit()).NextExpectedVersion); - Assert.AreEqual(0, (await (await (await writer.StartTransaction(ExpectedVersion.Any)).Write(events.First())).Commit()).NextExpectedVersion); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_1e0_2e1_3e2_4e3_5e4_0e5_non_idempotent() - { - const string stream = - "appending_to_implicitly_created_stream_using_transaction_sequence_0em1_1e0_2e1_3e2_4e3_5e4_0e5_non_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 6).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new TransactionalWriter(store, stream); - - Assert.AreEqual(5, (await (await (await writer.StartTransaction(-1)).Write(events)).Commit()).NextExpectedVersion); - Assert.AreEqual(6, (await (await (await writer.StartTransaction(5)).Write(events.First())).Commit()).NextExpectedVersion); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length + 1)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_1e0_2e1_3e2_4e3_5e4_0e6_wev() - { - const string stream = - "appending_to_implicitly_created_stream_using_transaction_sequence_0em1_1e0_2e1_3e2_4e3_5e4_0e6_wev"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 6).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new TransactionalWriter(store, stream); - - Assert.AreEqual(5, (await (await (await writer.StartTransaction(-1)).Write(events)).Commit()).NextExpectedVersion); - await AssertEx.ThrowsAsync(async () => - await (await (await writer.StartTransaction(6)).Write(events.First())).Commit()); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_1e0_2e1_3e2_4e3_5e4_0e4_wev() - { - const string stream = - "appending_to_implicitly_created_stream_using_transaction_sequence_0em1_1e0_2e1_3e2_4e3_5e4_0e4_wev"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 6).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new TransactionalWriter(store, stream); - - Assert.AreEqual(5, (await (await (await writer.StartTransaction(-1)).Write(events)).Commit()).NextExpectedVersion); - await AssertEx.ThrowsAsync( - async () => await (await (await writer.StartTransaction(4)).Write(events.First())).Commit()); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_0e0_non_idempotent() - { - const string stream = - "appending_to_implicitly_created_stream_using_transaction_sequence_0em1_0e0_non_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 1).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new TransactionalWriter(store, stream); - - Assert.AreEqual(0, (await (await (await writer.StartTransaction(-1)).Write(events)).Commit()).NextExpectedVersion); - Assert.AreEqual(1, (await (await (await writer.StartTransaction(0)).Write(events.First())).Commit()).NextExpectedVersion); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length + 1)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_0any_idempotent() - { - const string stream = - "appending_to_implicitly_created_stream_using_transaction_sequence_0em1_0any_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 1).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new TransactionalWriter(store, stream); - - Assert.AreEqual(0, - (await (await (await writer.StartTransaction(-1)).Write(events)).Commit()).NextExpectedVersion); - Assert.AreEqual(0, - (await (await (await writer.StartTransaction(ExpectedVersion.Any)).Write(events.First())).Commit()) - .NextExpectedVersion); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_0em1_idempotent() - { - const string stream = - "appending_to_implicitly_created_stream_using_transaction_sequence_0em1_0em1_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 1).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new TransactionalWriter(store, stream); - - Assert.AreEqual(0, (await (await (await writer.StartTransaction(-1)).Write(events)).Commit()).NextExpectedVersion); - Assert.AreEqual(0, (await (await (await writer.StartTransaction(-1)).Write(events.First())).Commit()).NextExpectedVersion); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_0em1_1e0_2e1_1any_1any_idempotent() - { - const string stream = - "appending_to_implicitly_created_stream_using_transaction_sequence_0em1_1e0_2e1_1any_1any_idempotent"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 3).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new TransactionalWriter(store, stream); - - Assert.AreEqual(2, (await (await (await writer.StartTransaction(-1)).Write(events)).Commit()).NextExpectedVersion); - Assert.AreEqual(1, (await (await (await (await writer.StartTransaction(ExpectedVersion.Any)).Write(events[1])).Write(events[1])).Commit()).NextExpectedVersion); - - var total = await EventsStream.Count(store, stream); - Assert.That(total, Is.EqualTo(events.Length)); - } - } - - [Test] - [Category("Network")] - public async Task sequence_S_0em1_1em1_E_S_0em1_1em1_2em1_E_idempotancy_fail() - { - const string stream = - "appending_to_implicitly_created_stream_using_transaction_sequence_S_0em1_1em1_E_S_0em1_1em1_2em1_E_idempotancy_fail"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = Enumerable.Range(0, 2).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var writer = new TransactionalWriter(store, stream); - - Assert.AreEqual(1, (await (await (await writer.StartTransaction(-1)).Write(events)).Commit()).NextExpectedVersion); - await AssertEx.ThrowsAsync(async () => - await (await (await writer.StartTransaction(-1)).Write(events.Concat(new[] { TestEvent.NewTestEvent(Guid.NewGuid()) }).ToArray())).Commit()); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/appending_to_streams_across_restart.cs b/src/EventStore.Core.Tests/ClientAPI/appending_to_streams_across_restart.cs deleted file mode 100644 index 6ffbfdbba7..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/appending_to_streams_across_restart.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class appending_to_streams_across_restart : SpecificationWithDirectory -{ - private MiniNode _node; - private static readonly TimeSpan ReadinessTimeout = TimeSpan.FromSeconds(60); - - virtual protected IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [TearDown] - public override async Task TearDown() - { - await _node?.Shutdown(); - await base.TearDown(); - } - - [Test] - [Category("Network")] - [Timeout(80000)] - public async Task detect_existing_streams_flush() - { - void CreateNode() - { - _node = new MiniNode( - pathname: PathName, - dbPath: Path.Combine(PathName, "mini-node-db"), - streamExistenceFilterSize: 10_000, - streamExistenceFilterCheckpointIntervalMs: 100, - streamExistenceFilterCheckpointDelayMs: 0); - } - - CreateNode(); - await _node.Start(); - await WaitForNodeReadiness(); - - // GIVEN some streams - var normal = "detect_existing_streams_normal"; - var meta = "detect_existing_streams_meta"; - var committed = "detect_existing_streams_commited_transaction"; - var uncommitted = "detect_existing_streams_uncommited_transaction"; - - EventData[] GenEvents() => Enumerable.Range(0, 10).Select(x => TestEvent.NewTestEvent(Guid.NewGuid())).ToArray(); - var eventsByStream = new Dictionary(){ - { normal, GenEvents() }, - { committed, GenEvents() }, - { uncommitted, GenEvents() }, - }; - - var uncommittedTransId = 0L; - - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - // normal - Assert.AreEqual(9, await store - .Apply(x => x.AppendToStreamAsync(normal, ExpectedVersion.NoStream, eventsByStream[normal])) - .Apply(x => x.NextExpectedVersion)); - - // meta - Assert.AreEqual(0, await store - .Apply(x => x.SetStreamMetadataAsync("meta", ExpectedVersion.NoStream, StreamMetadata.Create(maxCount: 5))) - .Apply(x => x.NextExpectedVersion)); - - if (LogFormatHelper.IsV2) - { - // committed - Assert.AreEqual(9, await new TransactionalWriter(store, committed) - .Apply(x => x.StartTransaction(-1)) - .Apply(x => x.Write(eventsByStream[committed])) - .Apply(x => x.Commit()) - .Apply(x => x.NextExpectedVersion)); - - // uncommitted - uncommittedTransId = await new TransactionalWriter(store, uncommitted) - .Apply(x => x.StartTransaction(-1)) - .Apply(x => x.Write(eventsByStream[committed])) - .Apply(x => x.TransactionId); - } - - // append an event to another stream because the last event is always going to get reinitialised - Assert.AreEqual(0, await store - .Apply(x => x.AppendToStreamAsync("another-stream", ExpectedVersion.NoStream, TestEvent.NewTestEvent(Guid.NewGuid()))) - .Apply(x => x.NextExpectedVersion)); - } - - // WHEN flush and restart - await Task.Delay(500); - await _node.Shutdown(keepDb: true); - CreateNode(); - await _node.Start(); - await WaitForNodeReadiness(); - - // THEN the streams all exist - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - // normal - Assert.AreEqual(10, await store - .Apply(x => x.AppendToStreamAsync(normal, 9, TestEvent.NewTestEvent(Guid.NewGuid()))) - .Apply(x => x.NextExpectedVersion)); - - Assert.AreEqual( - eventsByStream[normal].Length + 1, - await EventsStream.Count(store, normal)); - - // meta - Assert.AreEqual(1, await store - .Apply(x => x.SetStreamMetadataAsync("meta", 0, StreamMetadata.Create(maxCount: 6))) - .Apply(x => x.NextExpectedVersion)); - - Assert.AreEqual(0, await EventsStream.Count(store, meta)); - - if (LogFormatHelper.IsV2) - { - // committed - Assert.AreEqual(10, await store - .Apply(x => x.AppendToStreamAsync(committed, 9, TestEvent.NewTestEvent(Guid.NewGuid()))) - .Apply(x => x.NextExpectedVersion)); - - Assert.AreEqual( - eventsByStream[committed].Length + 1, - await EventsStream.Count(store, committed)); - - // uncommitted - Assert.AreEqual(9, await new TransactionalWriter(store, uncommitted) - .Apply(x => x.ContinueTransaction(uncommittedTransId)) - .Apply(x => x.Commit()) - .Apply(x => x.NextExpectedVersion)); - - Assert.AreEqual( - eventsByStream[uncommitted].Length, - await EventsStream.Count(store, uncommitted)); - } - } - } - - private async Task WaitForNodeReadiness() - { - await _node.WaitForTcpEndPoint().WithTimeout(ReadinessTimeout); - using var connection = await TestConnectionLifecycle.ReconnectUntilReady( - () => BuildConnection(_node), - conn => conn.ReadAllEventsForwardAsync(Position.Start, 1, false, DefaultData.AdminCredentials), - ReadinessTimeout); - } -} - -public static class Extensions -{ - public async static Task Apply(this Task x, Func> f) - { - var r = await x; - return await f(r); - } - - public static U Apply(this T x, Func f) - { - return f(x); - } - - public async static Task Apply(this T x, Func> f) - { - return await f(x); - } - - public async static Task Apply(this Task x, Func f) - { - var r = await x; - return f(r); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/catch_up_subscription_handles_errors.cs b/src/EventStore.Core.Tests/ClientAPI/catch_up_subscription_handles_errors.cs deleted file mode 100644 index 93a44ceabc..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/catch_up_subscription_handles_errors.cs +++ /dev/null @@ -1,753 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.ClientOperations; -using EventStore.ClientAPI.Common.Log; -using EventStore.ClientAPI.Internal; -using EventStore.ClientAPI.SystemData; -using NUnit.Framework; -using ClientMessage = EventStore.ClientAPI.Messages.ClientMessage; -using ResolvedEvent = EventStore.ClientAPI.ResolvedEvent; -using StreamMetadata = EventStore.ClientAPI.StreamMetadata; -using SystemSettings = EventStore.ClientAPI.SystemSettings; - -namespace EventStore.Core.Tests.ClientAPI; - -[TestFixture, Category("ClientAPI"), Category("LongRunning")] -public class catch_up_subscription_handles_errors -{ - private const int TimeoutMs = 2000; - private FakeEventStoreConnection _connection; - private IList _raisedEvents; - private bool _liveProcessingStarted; - private bool _isDropped; - private TaskCompletionSource _dropEvent; - private TaskCompletionSource _raisedEventEvent; - private Exception _dropException; - private SubscriptionDropReason _dropReason; - private EventStoreStreamCatchUpSubscription _subscription; - private static readonly string StreamId = "stream1"; - - [SetUp] - public void SetUp() - { - _connection = new FakeEventStoreConnection(); - _raisedEvents = new List(); - _dropEvent = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - _raisedEventEvent = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - _liveProcessingStarted = false; - _isDropped = false; - _dropReason = SubscriptionDropReason.Unknown; - _dropException = null; - - var settings = new CatchUpSubscriptionSettings(1, 1, false, false, String.Empty); - _subscription = new EventStoreStreamCatchUpSubscription(_connection, new NoopLogger(), StreamId, null, null, - (subscription, ev) => - { - _raisedEvents.Add(ev); - if (_raisedEvents.Count >= 2) - { - _raisedEventEvent.TrySetResult(true); - } - return Task.CompletedTask; - }, - subscription => { _liveProcessingStarted = true; }, - (subscription, reason, ex) => - { - _isDropped = true; - _dropReason = reason; - _dropException = ex; - _dropEvent.TrySetResult(true); - }, - settings); - } - - [Test] - public async Task read_events_til_stops_subscription_when_throws_immediately() - { - var expectedException = new ApplicationException("Test"); - - _connection.HandleReadStreamEventsForwardAsync((stream, start, max) => - { - Assert.That(stream, Is.EqualTo(StreamId)); - Assert.That(start, Is.EqualTo(0)); - Assert.That(max, Is.EqualTo(1)); - throw expectedException; - }); - - await AssertStartFailsAndDropsSubscriptionWithException(expectedException); - } - - private async Task AssertStartFailsAndDropsSubscriptionWithException(ApplicationException expectedException) - { - await AssertEx.ThrowsAsync(() => _subscription.StartAsync()); - Assert.That(_isDropped); - Assert.That(_dropReason, Is.EqualTo(SubscriptionDropReason.CatchUpError)); - Assert.That(_dropException, Is.SameAs(expectedException)); - Assert.That(_liveProcessingStarted, Is.False); - } - - [Test] - public async Task read_events_til_stops_subscription_when_throws_asynchronously() - { - var expectedException = new ApplicationException("Test"); - _connection.HandleReadStreamEventsForwardAsync((stream, start, max) => - { - var taskCompletionSource = - new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - Assert.That(stream, Is.EqualTo(StreamId)); - Assert.That(start, Is.EqualTo(0)); - Assert.That(max, Is.EqualTo(1)); - taskCompletionSource.SetException(expectedException); - return taskCompletionSource.Task; - }); - - await AssertStartFailsAndDropsSubscriptionWithException(expectedException); - } - - [Test] - public async Task read_events_til_stops_subscription_when_second_read_throws_immediately() - { - var expectedException = new ApplicationException("Test"); - - int callCount = 0; - - _connection.HandleReadStreamEventsForwardAsync((stream, start, max) => - { - Assert.That(stream, Is.EqualTo(StreamId)); - Assert.That(max, Is.EqualTo(1)); - - if (callCount++ == 0) - { - Assert.That(start, Is.EqualTo(0)); - var taskCompletionSource = - new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - taskCompletionSource.SetResult(CreateStreamEventsSlice()); - return taskCompletionSource.Task; - } - else - { - Assert.That(start, Is.EqualTo(1)); - throw expectedException; - } - }); - - await AssertStartFailsAndDropsSubscriptionWithException(expectedException); - Assert.That(_raisedEvents.Count, Is.EqualTo(1)); - } - - [Test] - public async Task read_events_til_stops_subscription_when_second_read_throws_asynchronously() - { - var expectedException = new ApplicationException("Test"); - - int callCount = 0; - - _connection.HandleReadStreamEventsForwardAsync((stream, start, max) => - { - Assert.That(stream, Is.EqualTo(StreamId)); - Assert.That(max, Is.EqualTo(1)); - - if (callCount++ == 0) - { - Assert.That(start, Is.EqualTo(0)); - var taskCompletionSource = - new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - taskCompletionSource.SetResult(CreateStreamEventsSlice()); - return taskCompletionSource.Task; - } - else - { - Assert.That(start, Is.EqualTo(1)); - var taskCompletionSource = - new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - taskCompletionSource.SetException(expectedException); - return taskCompletionSource.Task; - } - }); - - await AssertStartFailsAndDropsSubscriptionWithException(expectedException); - Assert.That(_raisedEvents.Count, Is.EqualTo(1)); - } - - [Test] - public async Task start_stops_subscription_if_subscribe_fails_immediately() - { - var expectedException = new ApplicationException("Test"); - - _connection.HandleReadStreamEventsForwardAsync((stream, start, max) => - { - var taskCompletionSource = - new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - taskCompletionSource.SetResult(CreateStreamEventsSlice(isEnd: true)); - return taskCompletionSource.Task; - }); - - _connection.HandleSubscribeToStreamAsync((stream, raise, drop) => - { - Assert.That(stream, Is.EqualTo(StreamId)); - throw expectedException; - }); - - await AssertStartFailsAndDropsSubscriptionWithException(expectedException); - Assert.That(_raisedEvents.Count, Is.EqualTo(1)); - } - - [Test] - public async Task start_stops_subscription_if_subscribe_fails_async() - { - var expectedException = new ApplicationException("Test"); - - _connection.HandleReadStreamEventsForwardAsync((stream, start, max) => - { - var taskCompletionSource = - new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - taskCompletionSource.SetResult(CreateStreamEventsSlice(isEnd: true)); - return taskCompletionSource.Task; - }); - - _connection.HandleSubscribeToStreamAsync((stream, raise, drop) => - { - var taskCompletionSource = - new TaskCompletionSource(TaskCreationOptions - .RunContinuationsAsynchronously); - taskCompletionSource.SetException(expectedException); - return taskCompletionSource.Task; - }); - - await AssertStartFailsAndDropsSubscriptionWithException(expectedException); - Assert.That(_raisedEvents.Count, Is.EqualTo(1)); - } - - [Test] - public async Task start_stops_subscription_if_historical_missed_events_load_fails_immediate() - { - var expectedException = new ApplicationException("Test"); - - int callCount = 0; - _connection.HandleReadStreamEventsForwardAsync((stream, start, max) => - { - if (callCount++ == 0) - { - var taskCompletionSource = - new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - taskCompletionSource.SetResult(CreateStreamEventsSlice(isEnd: true)); - return taskCompletionSource.Task; - } - else - { - Assert.That(start, Is.EqualTo(1)); - throw expectedException; - } - }); - - _connection.HandleSubscribeToStreamAsync((stream, raise, drop) => - { - var taskCompletionSource = - new TaskCompletionSource(TaskCreationOptions - .RunContinuationsAsynchronously); - taskCompletionSource.SetResult(CreateVolatileSubscription(raise, drop, 1)); - return taskCompletionSource.Task; - }); - - await AssertStartFailsAndDropsSubscriptionWithException(expectedException); - Assert.That(_raisedEvents.Count, Is.EqualTo(1)); - } - - - [Test] - public async Task start_stops_subscription_if_historical_missed_events_load_fails_async() - { - var expectedException = new ApplicationException("Test"); - - int callCount = 0; - _connection.HandleReadStreamEventsForwardAsync((stream, start, max) => - { - if (callCount++ == 0) - { - var taskCompletionSource = - new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - taskCompletionSource.SetResult(CreateStreamEventsSlice(isEnd: true)); - return taskCompletionSource.Task; - } - else - { - Assert.That(start, Is.EqualTo(1)); - var taskCompletionSource = - new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - taskCompletionSource.SetException(expectedException); - return taskCompletionSource.Task; - } - }); - - _connection.HandleSubscribeToStreamAsync((stream, raise, drop) => - { - var taskCompletionSource = - new TaskCompletionSource(TaskCreationOptions - .RunContinuationsAsynchronously); - taskCompletionSource.SetResult(CreateVolatileSubscription(raise, drop, 1)); - return taskCompletionSource.Task; - }); - - await AssertStartFailsAndDropsSubscriptionWithException(expectedException); - Assert.That(_raisedEvents.Count, Is.EqualTo(1)); - } - - [Test] - public async Task start_completes_onces_subscription_is_live() - { - var finalEvent = new ManualResetEventSlim(); - int callCount = 0; - _connection.HandleReadStreamEventsForwardAsync((stream, start, max) => Task.Run(() => - { - callCount++; - - if (callCount == 1) - { - return Task.FromResult(CreateStreamEventsSlice(isEnd: true)); - } - else if (callCount == 2) - { - var result = Task.FromResult(CreateStreamEventsSlice(fromEvent: 1, isEnd: true)); - Assert.That(finalEvent.Wait(TimeoutMs)); - return result; - } - else - { - throw new InvalidOperationException("Should not get a third call"); - } - })); - - _connection.HandleSubscribeToStreamAsync((stream, raise, drop) => - Task.FromResult(CreateVolatileSubscription(raise, drop, 1))); - - var task = _subscription.StartAsync(); - - Assert.That(task.Status, Is.Not.EqualTo(TaskStatus.RanToCompletion)); - - finalEvent.Set(); - - await task.WithTimeout(TimeoutMs); - } - - private static VolatileEventStoreSubscription CreateVolatileSubscription( - Func raise, - Action drop, int? lastEventNumber) - { - return new VolatileEventStoreSubscription( - new VolatileSubscriptionOperation(new NoopLogger(), - new TaskCompletionSource(TaskCreationOptions - .RunContinuationsAsynchronously), StreamId, false, null, raise, drop, false, () => null), - StreamId, -1, lastEventNumber); - } - - private static StreamEventsSlice CreateStreamEventsSlice(int fromEvent = 0, int count = 1, bool isEnd = false) - { - var events = Enumerable.Range(0, count) - .Select( - i => - new ClientMessage.ResolvedIndexedEvent( - new ClientMessage.EventRecord(StreamId, i, Guid.NewGuid().ToByteArray(), null, 0, 0, null, - null, null, null), null)) - .ToArray(); - - return new StreamEventsSlice(SliceReadStatus.Success, StreamId, fromEvent, ReadDirection.Forward, events, - fromEvent + count, 100, isEnd); - } -} - -internal class FakeEventStoreConnection : IEventStoreConnection -{ - private Func> _readAllEventsForwardAsync; - private Func> _readStreamEventsForwardAsync; - - private Func, - Action, Task> - _subscribeToStreamAsync; - - private Func, - Action, Task> - _subscribeToAllAsync; - - public void Dispose() - { - throw new NotImplementedException(); - } - - public string ConnectionName { get; } - - public ConnectionSettings Settings - { - get { return null; } - } - - public Task ConnectAsync() - { - throw new NotImplementedException(); - } - - public void Close() - { - throw new NotImplementedException(); - } - - public Task DeleteStreamAsync(string stream, long expectedVersion, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task DeleteStreamAsync(string stream, long expectedVersion, bool hardDelete, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task AppendToStreamAsync(string stream, long expectedVersion, params EventData[] events) - { - throw new NotImplementedException(); - } - - public Task AppendToStreamAsync(string stream, long expectedVersion, - UserCredentials userCredentials, params EventData[] events) - { - throw new NotImplementedException(); - } - - public Task AppendToStreamAsync(string stream, long expectedVersion, IEnumerable events, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task ConditionalAppendToStreamAsync(string stream, long expectedVersion, - IEnumerable events, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task StartTransactionAsync(string stream, long expectedVersion, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public EventStoreTransaction ContinueTransaction(long transactionId, UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task ReadEventAsync(string stream, long eventNumber, bool resolveLinkTos, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public void HandleReadStreamEventsForwardAsync(Func> callback) - { - _readStreamEventsForwardAsync = callback; - } - - public Task ReadStreamEventsForwardAsync(string stream, long start, int count, - bool resolveLinkTos, - UserCredentials userCredentials = null) - { - return _readStreamEventsForwardAsync(stream, start, count); - } - - public Task ReadStreamEventsBackwardAsync(string stream, long start, int count, - bool resolveLinkTos, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public void HandleReadAllEventsForwardAsync( - Func> callback) - { - _readAllEventsForwardAsync = callback; - } - - public Task ReadAllEventsForwardAsync(Position position, int maxCount, bool resolveLinkTos, - UserCredentials userCredentials = null) - { - return _readAllEventsForwardAsync(position, maxCount, resolveLinkTos, userCredentials); - } - - public Task FilteredReadAllEventsForwardAsync(Position position, int maxCount, bool resolveLinkTos, Filter filter, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task FilteredReadAllEventsForwardAsync(Position position, int maxCount, bool resolveLinkTos, Filter filter, - int maxSearchWindow, UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task ReadAllEventsBackwardAsync(Position position, int maxCount, bool resolveLinkTos, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task FilteredReadAllEventsBackwardAsync(Position position, int maxCount, bool resolveLinkTos, Filter filter, - int maxSearchWindow, UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task FilteredReadAllEventsBackwardAsync(Position position, int maxCount, bool resolveLinkTos, Filter filter, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public void HandleSubscribeToStreamAsync( - Func, - Action, Task> - callback) - { - _subscribeToStreamAsync = callback; - } - - public Task SubscribeToStreamAsync(string stream, bool resolveLinkTos, - Func eventAppeared, - Action subscriptionDropped = null, - UserCredentials userCredentials = null) - { - return _subscribeToStreamAsync(stream, eventAppeared, subscriptionDropped); - } - - public EventStoreStreamCatchUpSubscription SubscribeToStreamFrom(string stream, long? lastCheckpoint, - bool resolveLinkTos, - Func eventAppeared, - Action liveProcessingStarted = null, - Action subscriptionDropped = null, - UserCredentials userCredentials = null, int readBatchSize = 500, string subscriptionName = "") - { - throw new NotImplementedException(); - } - - public EventStoreStreamCatchUpSubscription SubscribeToStreamFrom( - string stream, - long? lastCheckpoint, - CatchUpSubscriptionSettings settings, - Func eventAppeared, - Action liveProcessingStarted = null, - Action subscriptionDropped = null, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public void HandleSubscribeToAllAsync( - Func, - Action, Task> - callback) - { - _subscribeToAllAsync = callback; - } - - public Task SubscribeToAllAsync(bool resolveLinkTos, - Func eventAppeared, - Action subscriptionDropped = null, - UserCredentials userCredentials = null) - { - return _subscribeToAllAsync(resolveLinkTos, eventAppeared, subscriptionDropped); - } - - public Task FilteredSubscribeToAllAsync(bool resolveLinkTos, Filter filter, Func eventAppeared, Func checkpointReached, - int checkpointInterval, Action subscriptionDropped = null, UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task FilteredSubscribeToAllAsync(bool resolveLinkTos, Filter filter, Func eventAppeared, - Action subscriptionDropped = null, UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task SubscribeToAllFilteredAsync(bool resolveLinkTos, Filter filter, - Func eventAppeared, - Func checkpointReached = null, - int? checkpointInterval = null, - Action subscriptionDropped = null, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public EventStorePersistentSubscriptionBase ConnectToPersistentSubscription(string stream, string groupName, - Func eventAppeared, - Action subscriptionDropped = null, - UserCredentials userCredentials = null, int bufferSize = 10, - bool autoAck = true) - { - throw new NotImplementedException(); - } - - public Task ConnectToPersistentSubscriptionAsync(string stream, - string groupName, Func eventAppeared, - Action subscriptionDropped = null, - UserCredentials userCredentials = null, int bufferSize = 10, - bool autoAck = true) - { - throw new NotImplementedException(); - } - - public EventStoreAllCatchUpSubscription SubscribeToAllFrom(Position? lastCheckpoint, bool resolveLinkTos, - Func eventAppeared, - Action liveProcessingStarted = null, - Action subscriptionDropped = null, - UserCredentials userCredentials = null, - int readBatchSize = 500, - string subscriptionName = "") - { - throw new NotImplementedException(); - } - - public EventStoreAllCatchUpSubscription SubscribeToAllFrom( - Position? lastCheckpoint, - CatchUpSubscriptionSettings settings, - Func eventAppeared, - Action liveProcessingStarted = null, - Action subscriptionDropped = null, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public EventStoreAllFilteredCatchUpSubscription FilteredSubscribeToAllFrom(Position? lastCheckpoint, Filter filter, - CatchUpSubscriptionFilteredSettings settings, Func eventAppeared, Func checkpointReached, - int checkpointIntervalMultiplier, Action liveProcessingStarted = null, Action subscriptionDropped = null, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public EventStoreAllFilteredCatchUpSubscription FilteredSubscribeToAllFrom(Position? lastCheckpoint, Filter filter, - CatchUpSubscriptionFilteredSettings settings, Func eventAppeared, Action liveProcessingStarted = null, - Action subscriptionDropped = null, UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task UpdatePersistentSubscriptionAsync(string stream, string groupName, - PersistentSubscriptionSettings settings, - UserCredentials credentials) - { - throw new NotImplementedException(); - } - - public Task CreatePersistentSubscriptionAsync(string stream, string groupName, - PersistentSubscriptionSettings settings, - UserCredentials credentials) - { - throw new NotImplementedException(); - } - - public Task DeletePersistentSubscriptionAsync(string stream, string groupName, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task SetStreamMetadataAsync(string stream, long expectedMetastreamVersion, - StreamMetadata metadata, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task SetStreamMetadataAsync(string stream, long expectedMetastreamVersion, byte[] metadata, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task - GetStreamMetadataAsync(string stream, UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task GetStreamMetadataAsRawBytesAsync(string stream, - UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public Task SetSystemSettingsAsync(SystemSettings settings, UserCredentials userCredentials = null) - { - throw new NotImplementedException(); - } - - public event EventHandler Connected; - public event EventHandler Disconnected; - public event EventHandler Reconnecting; - public event EventHandler Closed; - public event EventHandler ErrorOccurred; - public event EventHandler AuthenticationFailed; - - protected virtual void OnErrorOccurred(ClientErrorEventArgs e) - { - var handler = ErrorOccurred; - if (handler != null) - { - handler(this, e); - } - } - - protected virtual void OnAuthenticationFailed(ClientAuthenticationFailedEventArgs e) - { - var handler = AuthenticationFailed; - if (handler != null) - { - handler(this, e); - } - } - - protected virtual void OnClosed(ClientClosedEventArgs e) - { - var handler = Closed; - if (handler != null) - { - handler(this, e); - } - } - - protected virtual void OnReconnecting(ClientReconnectingEventArgs e) - { - var handler = Reconnecting; - if (handler != null) - { - handler(this, e); - } - } - - protected virtual void OnDisconnected(ClientConnectionEventArgs e) - { - var handler = Disconnected; - if (handler != null) - { - handler(this, e); - } - } - - public void OnConnected(ClientConnectionEventArgs e) - { - var handler = Connected; - if (handler != null) - { - handler(this, e); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/catchup_filtered_subscription.cs b/src/EventStore.Core.Tests/ClientAPI/catchup_filtered_subscription.cs deleted file mode 100644 index 0d8df30fc9..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/catchup_filtered_subscription.cs +++ /dev/null @@ -1,358 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.SystemData; -using EventStore.Core.Services; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("LongRunning"), Category("ClientAPI"), NonParallelizable] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class catchup_filtered_subscription : SpecificationWithDirectory -{ - private MiniNode _node; - private IEventStoreConnection _conn; - private List _testEvents; - private List _testEventsAfter; - private const int Timeout = 10000; - private static readonly TimeSpan StartupTimeout = TimeSpan.FromMinutes(10); - private static readonly TimeSpan ConnectionCloseTimeout = TimeSpan.FromSeconds(10); - private const int LongRunningTimeout = 600000; - - [SetUp] - public override async Task SetUp() - { - await base.SetUp(); - _node = new MiniNode(PathName); - await _node.Start(StartupTimeout); - await _node.WaitForTcpEndPoint().WithTimeout(TimeSpan.FromSeconds(60)); - - _conn = await TestConnectionLifecycle.ReconnectUntilReady( - () => BuildConnection(_node), - conn => conn.ReadAllEventsForwardAsync(Position.Start, 1, false, DefaultData.AdminCredentials), - StartupTimeout); - await _conn.SetStreamMetadataAsync(SystemStreams.AllStream, -1, - StreamMetadata.Build().SetReadRole(SystemRoles.All), - new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword)); - - _testEvents = Enumerable - .Range(0, 10) - .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "AEvent")) - .ToList(); - - _testEvents.AddRange( - Enumerable - .Range(0, 10) - .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "BEvent")).ToList()); - - _testEventsAfter = Enumerable - .Range(0, 10) - .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "AEvent")) - .ToList(); - - _testEventsAfter.AddRange( - Enumerable - .Range(0, 10) - .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "BEvent")).ToList()); - - await _conn.AppendToStreamAsync("stream-a", ExpectedVersion.NoStream, _testEvents.EvenEvents()); - await _conn.AppendToStreamAsync("stream-b", ExpectedVersion.NoStream, _testEvents.OddEvents()); - } - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [Test] - public void calls_checkpoint_delegate_during_catchup() - { - var filter = Filter.StreamId.Prefix("stream-a"); - // in v2 there are 20 events, 10 in stream-a and 10 in stream-b. - // in v3 there are additionally two stream records and two event type records - var isV2 = LogFormatHelper.IsV2; - var checkpointReached = new CountdownEvent(isV2 ? 10 : 14); - var eventsSeen = 0; - - var settings = new CatchUpSubscriptionFilteredSettings( - maxLiveQueueSize: 10000, - readBatchSize: 2, - verboseLogging: false, - resolveLinkTos: true, - maxSearchWindow: 2, - subscriptionName: String.Empty - ); - - var subscription = _conn.FilteredSubscribeToAllFrom( - Position.Start, - filter, - settings, - (s, e) => - { - eventsSeen++; - return Task.CompletedTask; - }, - (s, p) => - { - checkpointReached.Signal(); - return Task.CompletedTask; - }, 1); - - try - { - if (!checkpointReached.Wait(Timeout)) - { - Assert.Fail("Checkpoint reached not called enough times within time limit."); - } - - Assert.AreEqual(10, eventsSeen); - } - finally - { - StopSubscription(subscription); - } - } - - [Test] - public void calls_checkpoint_during_live_processing_stage() - { - var filter = Filter.StreamId.Prefix("stream-a"); - var appeared = new CountdownEvent(_testEventsAfter.EvenEvents().Count + 1); // Calls once for switch to live. - var eventsSeen = 0; - var isLive = false; - - var settings = new CatchUpSubscriptionFilteredSettings( - 10000, - 1, - verboseLogging: false, - resolveLinkTos: true, - maxSearchWindow: 1, - subscriptionName: String.Empty - ); - - var subscription = _conn.FilteredSubscribeToAllFrom( - Position.Start, - filter, - settings, - (s, e) => - { - eventsSeen++; - return Task.CompletedTask; - }, - (s, p) => - { - if (isLive) - { - appeared.Signal(); - } - - return Task.CompletedTask; - }, 1, s => - { - isLive = true; - _conn.AppendToStreamAsync("stream-a", ExpectedVersion.Any, _testEventsAfter.EvenEvents()).Wait(); - }); - - try - { - if (!appeared.Wait(Timeout)) - { - Assert.Fail("Checkpoint appeared not called enough times within time limit."); - } - - Assert.AreEqual(20, eventsSeen); - } - finally - { - StopSubscription(subscription); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public void only_return_events_with_a_given_stream_prefix() - { - var filter = Filter.StreamId.Prefix("stream-a"); - var foundEvents = new ConcurrentBag(); - var appeared = new CountdownEvent(20); - var subscription = Subscribe(filter, foundEvents, appeared); - try - { - if (!appeared.Wait(Timeout)) - { - Assert.Fail("Appeared countdown event timed out."); - } - - Assert.True(foundEvents.All(e => e.Event.EventStreamId == "stream-a")); - } - finally - { - StopSubscription(subscription); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public void only_return_events_with_a_given_event_prefix() - { - var filter = Filter.EventType.Prefix("AE"); - var foundEvents = new ConcurrentBag(); - var appeared = new CountdownEvent(20); - var subscription = Subscribe(filter, foundEvents, appeared); - try - { - if (!appeared.Wait(Timeout)) - { - Assert.Fail("Appeared countdown event timed out."); - } - - Assert.True(foundEvents.All(e => e.Event.EventType == "AEvent")); - } - finally - { - StopSubscription(subscription); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public void only_return_events_that_satisfy_a_given_stream_regex() - { - var filter = Filter.StreamId.Regex(new Regex(@"^.*eam-b.*$")); - var foundEvents = new ConcurrentBag(); - var appeared = new CountdownEvent(20); - var subscription = Subscribe(filter, foundEvents, appeared); - try - { - if (!appeared.Wait(Timeout)) - { - Assert.Fail("Appeared countdown event timed out."); - } - - Assert.True(foundEvents.All(e => e.Event.EventStreamId == "stream-b")); - } - finally - { - StopSubscription(subscription); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public void only_return_events_that_satisfy_a_given_event_regex() - { - var filter = Filter.EventType.Regex(new Regex(@"^.*BEv.*$")); - var foundEvents = new ConcurrentBag(); - var appeared = new CountdownEvent(20); - var subscription = Subscribe(filter, foundEvents, appeared); - try - { - if (!appeared.Wait(Timeout)) - { - Assert.Fail("Appeared countdown event timed out."); - } - - Assert.True(foundEvents.All(e => e.Event.EventType == "BEvent")); - } - finally - { - StopSubscription(subscription); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public void only_return_events_that_are_not_system_events() - { - var filter = Filter.ExcludeSystemEvents; - var foundEvents = new ConcurrentBag(); - using var appeared = new ManualResetEventSlim(); - const int requiredEvents = 20; - var foundEventsCount = 0; - var subscription = _conn.FilteredSubscribeToAllFrom( - Position.Start, - filter, - CatchUpSubscriptionFilteredSettings.Default, - (s, e) => - { - foundEvents.Add(e); - if (Interlocked.Increment(ref foundEventsCount) >= requiredEvents) - { - appeared.Set(); - } - - return Task.CompletedTask; - }, - (s, p) => Task.CompletedTask, 5, - s => - { - _conn.AppendToStreamAsync("stream-a", ExpectedVersion.Any, _testEventsAfter.EvenEvents()).Wait(); - _conn.AppendToStreamAsync("stream-b", ExpectedVersion.Any, _testEventsAfter.OddEvents()).Wait(); - }); - try - { - if (!appeared.Wait(Timeout)) - { - Assert.Fail("Appeared countdown event timed out."); - } - - Assert.True(foundEvents.All(e => !e.Event.EventType.StartsWith("$"))); - } - finally - { - StopSubscription(subscription); - } - } - - private EventStoreCatchUpSubscription Subscribe(Filter filter, ConcurrentBag foundEvents, - CountdownEvent appeared) - { - return _conn.FilteredSubscribeToAllFrom( - Position.Start, - filter, - CatchUpSubscriptionFilteredSettings.Default, - (s, e) => - { - foundEvents.Add(e); - appeared.Signal(); - return Task.CompletedTask; - }, - (s, p) => Task.CompletedTask, 5, - s => - { - _conn.AppendToStreamAsync("stream-a", ExpectedVersion.Any, _testEventsAfter.EvenEvents()).Wait(); - _conn.AppendToStreamAsync("stream-b", ExpectedVersion.Any, _testEventsAfter.OddEvents()).Wait(); - }); - } - - [TearDown] - public override async Task TearDown() - { - try - { - await TestConnectionLifecycle.CloseConnectionAndWait(_conn, ConnectionCloseTimeout); - } - catch - { - TestConnectionLifecycle.TryCloseConnection(_conn); - } - - TestConnectionLifecycle.DisposeIfNeeded(_conn); - await _node.Shutdown(); - await base.TearDown(); - } - - private static void StopSubscription(EventStoreCatchUpSubscription subscription) - { - try - { - subscription.Stop(ConnectionCloseTimeout); - } - catch - { - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/catchup_subscription_handles_small_batch_sizes.cs b/src/EventStore.Core.Tests/ClientAPI/catchup_subscription_handles_small_batch_sizes.cs deleted file mode 100644 index f64aebf271..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/catchup_subscription_handles_small_batch_sizes.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.SystemData; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Ignore("Very long running")] -[Category("LongRunning"), Category("ClientAPI")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class catchup_subscription_handles_small_batch_sizes : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - private string _streamName = "TestStream"; - private CatchUpSubscriptionSettings _settings; - private IEventStoreConnection _conn; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - - _conn = BuildConnection(_node); - await _conn.ConnectAsync(); - //Create 80000 events - for (var i = 0; i < 80; i++) - { - await _conn.AppendToStreamAsync(_streamName, ExpectedVersion.Any, CreateThousandEvents()); - } - - _settings = new CatchUpSubscriptionSettings(100, 1, false, true, String.Empty); - } - - private EventData[] CreateThousandEvents() - { - var events = new List(); - for (var i = 0; i < 1000; i++) - { - events.Add(new EventData(Guid.NewGuid(), "testEvent", true, - Encoding.UTF8.GetBytes("{ \"Foo\":\"Bar\" }"), null)); - } - - return events.ToArray(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - _conn.Dispose(); - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [Test] - public void CatchupSubscriptionToAllHandlesManyEventsWithSmallBatchSize() - { - var mre = new ManualResetEvent(false); - _conn.SubscribeToAllFrom(null, _settings, (sub, evnt) => - { - if (evnt.OriginalEventNumber % 1000 == 0) - { - Console.WriteLine("Processed {0} events", evnt.OriginalEventNumber); - } - - return Task.CompletedTask; - }, (sub) => { mre.Set(); }, null, new UserCredentials("admin", "changeit")); - - if (!mre.WaitOne(TimeSpan.FromMinutes(10))) - { - Assert.Fail("Timed out waiting for test to complete"); - } - } - - [Test] - public void CatchupSubscriptionToStreamHandlesManyEventsWithSmallBatchSize() - { - var mre = new ManualResetEvent(false); - _conn.SubscribeToStreamFrom(_streamName, null, _settings, (sub, evnt) => - { - if (evnt.OriginalEventNumber % 1000 == 0) - { - Console.WriteLine("Processed {0} events", evnt.OriginalEventNumber); - } - - return Task.CompletedTask; - }, (sub) => { mre.Set(); }, null, new UserCredentials("admin", "changeit")); - - if (!mre.WaitOne(TimeSpan.FromMinutes(10))) - { - Assert.Fail("Timed out waiting for test to complete"); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/connect.cs b/src/EventStore.Core.Tests/ClientAPI/connect.cs deleted file mode 100644 index 588507fc92..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/connect.cs +++ /dev/null @@ -1,166 +0,0 @@ -using System; -using System.Net; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Internal; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string), TcpType.Normal)] -[TestFixture(typeof(LogFormat.V2), typeof(string), TcpType.Ssl)] -public class Connect : SpecificationWithDirectoryPerTestFixture -{ - private readonly TcpType _tcpType; - - public Connect(TcpType tcpType) - { - _tcpType = tcpType; - } - - //TODO GFY THESE NEED TO BE LOOKED AT IN LINUX - [Test, Category("Network")] - public async Task should_not_throw_exception_when_server_is_down() - { - var ip = IPAddress.Loopback; - int port = PortsHelper.GetAvailablePort(ip); - using var connection = TestConnection.Create(new IPEndPoint(ip, port), _tcpType); - await connection.ConnectAsync(); - } - - //TODO GFY THESE NEED TO BE LOOKED AT IN LINUX - [Test, Category("Network")] - public async Task should_throw_exception_when_trying_to_reopen_closed_connection() - { - ClientApiLoggerBridge.Default.Info("Starting '{0}' test...", - "should_throw_exception_when_trying_to_reopen_closed_connection"); - - var closed = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - var settings = ConnectionSettings.Create() - .EnableVerboseLogging() - .UseCustomLogger(ClientApiLoggerBridge.Default) - .LimitReconnectionsTo(0) - .WithConnectionTimeoutOf(TimeSpan.FromSeconds(10)) - .SetReconnectionDelayTo(TimeSpan.FromMilliseconds(0)) - .FailOnNoServerResponse(); - if (_tcpType == TcpType.Ssl) - { - settings.DisableServerCertificateValidation(); - } - else - { - settings.DisableTls(); - } - - var ip = IPAddress.Loopback; - int port = PortsHelper.GetAvailablePort(ip); - using var connection = EventStoreConnection.Create(settings, new IPEndPoint(ip, port).ToESTcpUri()); - connection.Closed += (s, e) => closed.TrySetResult(true); - - await connection.ConnectAsync(); - - await closed.Task.WithTimeout( - TimeSpan.FromSeconds(120)); // TCP connection timeout might be even 60 seconds - - await AssertEx.ThrowsAsync(() => connection.ConnectAsync().WithTimeout()); - } - - //TODO GFY THIS TEST TIMES OUT IN LINUX. - [Test, Category("Network")] - public async Task should_close_connection_after_configured_amount_of_failed_reconnections() - { - var closed = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - var settings = - ConnectionSettings.Create() - .EnableVerboseLogging() - .UseCustomLogger(ClientApiLoggerBridge.Default) - .LimitReconnectionsTo(1) - .WithConnectionTimeoutOf(TimeSpan.FromSeconds(10)) - .SetReconnectionDelayTo(TimeSpan.FromMilliseconds(0)) - .FailOnNoServerResponse(); - if (_tcpType == TcpType.Ssl) - { - settings.DisableServerCertificateValidation(); - } - else - { - settings.DisableTls(); - } - - var ip = IPAddress.Loopback; - int port = PortsHelper.GetAvailablePort(ip); - using var connection = EventStoreConnection.Create(settings, new IPEndPoint(ip, port).ToESTcpUri()); - connection.Closed += (s, e) => closed.TrySetResult(true); - connection.Connected += (s, e) => - Console.WriteLine("EventStoreConnection '{0}': connected to [{1}]...", - e.Connection.ConnectionName, e.RemoteEndPoint); - connection.Reconnecting += (s, e) => - Console.WriteLine("EventStoreConnection '{0}': reconnecting...", e.Connection.ConnectionName); - connection.Disconnected += (s, e) => - Console.WriteLine("EventStoreConnection '{0}': disconnected from [{1}]...", - e.Connection.ConnectionName, e.RemoteEndPoint); - connection.ErrorOccurred += (s, e) => Console.WriteLine("EventStoreConnection '{0}': error = {1}", - e.Connection.ConnectionName, e.Exception); - - await connection.ConnectAsync(); - - await closed.Task.WithTimeout( - TimeSpan.FromSeconds(120)); // TCP connection timeout might be even 60 seconds - - await AssertEx.ThrowsAsync(() => connection - .AppendToStreamAsync("stream", ExpectedVersion.NoStream, TestEvent.NewTestEvent()) - .WithTimeout()); - } -} - -[TestFixture, Category("ClientAPI"), Category("LongRunning")] -public class not_connected_tests -{ - private readonly TcpType _tcpType = TcpType.Ssl; - - [Test] - public async Task should_timeout_connection_after_configured_amount_time_on_conenct() - { - var closed = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - var settings = - ConnectionSettings.Create() - .EnableVerboseLogging() - .UseCustomLogger(ClientApiLoggerBridge.Default) - .LimitReconnectionsTo(0) - .SetReconnectionDelayTo(TimeSpan.FromMilliseconds(0)) - .FailOnNoServerResponse() - .WithConnectionTimeoutOf(TimeSpan.FromMilliseconds(1000)); - - if (_tcpType == TcpType.Ssl) - { - settings.DisableServerCertificateValidation(); - } - else - { - settings.DisableTls(); - } - - var ip = new IPAddress(new byte[] - {8, 8, 8, 8}); //NOTE: This relies on Google DNS server being configured to swallow nonsense traffic - const int port = 4567; - using (var connection = EventStoreConnection.Create(settings, new IPEndPoint(ip, port).ToESTcpUri())) - { - connection.Closed += (s, e) => closed.TrySetResult(true); - connection.Connected += (s, e) => Console.WriteLine("EventStoreConnection '{0}': connected to [{1}]...", - e.Connection.ConnectionName, e.RemoteEndPoint); - connection.Reconnecting += (s, e) => - Console.WriteLine("EventStoreConnection '{0}': reconnecting...", e.Connection.ConnectionName); - connection.Disconnected += (s, e) => - Console.WriteLine("EventStoreConnection '{0}': disconnected from [{1}]...", - e.Connection.ConnectionName, e.RemoteEndPoint); - connection.ErrorOccurred += (s, e) => Console.WriteLine("EventStoreConnection '{0}': error = {1}", - e.Connection.ConnectionName, e.Exception); - await connection.ConnectAsync(); - - await closed.Task.WithTimeout(TimeSpan.FromSeconds(15)); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/connecting_with_connection_string.cs b/src/EventStore.Core.Tests/ClientAPI/connecting_with_connection_string.cs deleted file mode 100644 index 362032a25d..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/connecting_with_connection_string.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class when_connecting_with_connection_string : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - [Test] - public async Task should_not_throw_when_connect_to_is_set() - { - string connectionString = string.Format("ConnectTo=tcp://{0};", _node.TcpEndPoint); - using (var connection = EventStoreConnection.Create(connectionString)) - { - await connection.ConnectAsync(); - connection.Close(); - } - } - - [Test] - public void should_not_throw_when_only_gossip_seeds_is_set() - { - string connectionString = string.Format("GossipSeeds={0};", _node.HttpEndPoint); - IEventStoreConnection connection = null; - - Assert.DoesNotThrow(() => connection = EventStoreConnection.Create(connectionString)); - Assert.AreEqual(_node.HttpEndPoint, connection.Settings.GossipSeeds.First().EndPoint); - - connection.Dispose(); - } - - [Test] - public void should_throw_when_gossip_seeds_and_connect_to_is_set() - { - string connectionString = string.Format("ConnectTo=tcp://{0};GossipSeeds={1}", _node.TcpEndPoint, - _node.HttpEndPoint); - Assert.Throws(() => EventStoreConnection.Create(connectionString)); - } - - [Test] - public void should_throw_when_neither_gossip_seeds_nor_connect_to_is_set() - { - string connectionString = string.Format("HeartBeatTimeout=2000"); - Assert.Throws(() => EventStoreConnection.Create(connectionString)); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/connection_string.cs b/src/EventStore.Core.Tests/ClientAPI/connection_string.cs deleted file mode 100644 index f4d8749998..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/connection_string.cs +++ /dev/null @@ -1,69 +0,0 @@ -using EventStore.ClientAPI; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[TestFixture, Category("ClientAPI")] -public class connection_string -{ - [Test] - public void can_set_bool_value_with_string() - { - var settings = ConnectionString.GetConnectionSettings("verboselogging=true"); - Assert.AreEqual(true, settings.VerboseLogging); - } - - [Test] - public void can_set_with_spaces() - { - var settings = ConnectionString.GetConnectionSettings("Verbose Logging=true"); - Assert.AreEqual(true, settings.VerboseLogging); - } - - - [Test] - public void can_set_int() - { - var settings = ConnectionString.GetConnectionSettings("maxretries=55"); - Assert.AreEqual(55, settings.MaxRetries); - } - - [Test] - public void can_set_timespan() - { - var settings = ConnectionString.GetConnectionSettings("heartbeattimeout=5555"); - Assert.AreEqual(5555, settings.HeartbeatTimeout.TotalMilliseconds); - } - - [Test] - public void can_set_multiple_values() - { - var settings = ConnectionString.GetConnectionSettings("heartbeattimeout=5555;maxretries=55"); - Assert.AreEqual(5555, settings.HeartbeatTimeout.TotalMilliseconds); - Assert.AreEqual(55, settings.MaxRetries); - } - - [Test] - public void can_set_mixed_case() - { - var settings = ConnectionString.GetConnectionSettings("heArtbeAtTimeout=5555"); - Assert.AreEqual(5555, settings.HeartbeatTimeout.TotalMilliseconds); - } - - [Test] - public void can_set_gossip_seeds() - { - var settings = - ConnectionString.GetConnectionSettings( - "gossipseeds=111.222.222.111:1111,111.222.222.111:1112,111.222.222.111:1113"); - Assert.AreEqual(3, settings.GossipSeeds.Length); - } - - [Test] - public void can_set_default_user_credentials() - { - var settings = ConnectionString.GetConnectionSettings("DefaultUserCredentials=foo:bar"); - Assert.AreEqual("foo", settings.DefaultUserCredentials.Username); - Assert.AreEqual("bar", settings.DefaultUserCredentials.Password); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/deleting_stream.cs b/src/EventStore.Core.Tests/ClientAPI/deleting_stream.cs deleted file mode 100644 index 318c754e50..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/deleting_stream.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Exceptions; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class deleting_stream : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - virtual protected IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [Test] - [Category("Network")] - public async Task which_doesnt_exists_should_success_when_passed_empty_stream_expected_version() - { - const string stream = "which_already_exists_should_success_when_passed_empty_stream_expected_version"; - using (var connection = BuildConnection(_node)) - { - await connection.ConnectAsync(); - await connection.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - } - } - - [Test] - [Category("Network")] - public async Task which_doesnt_exists_should_success_when_passed_any_for_expected_version() - { - const string stream = "which_already_exists_should_success_when_passed_any_for_expected_version"; - using (var connection = BuildConnection(_node)) - { - await connection.ConnectAsync(); - - await connection.DeleteStreamAsync(stream, ExpectedVersion.Any, hardDelete: true); - } - } - - [Test] - [Category("Network")] - public async Task with_invalid_expected_version_should_fail() - { - const string stream = "with_invalid_expected_version_should_fail"; - using (var connection = BuildConnection(_node)) - { - await connection.ConnectAsync(); - - await AssertEx.ThrowsAsync(() => - connection.DeleteStreamAsync(stream, 1, hardDelete: true)); - } - } - - public async Task should_return_log_position_when_writing() - { - const string stream = "delete_should_return_log_position_when_writing"; - using (var connection = BuildConnection(_node)) - { - await connection.ConnectAsync(); - - var result = await connection - .AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()); - var delete = await connection.DeleteStreamAsync(stream, 1, hardDelete: true); - - Assert.IsTrue(0 < result.LogPosition.PreparePosition); - Assert.IsTrue(0 < result.LogPosition.CommitPosition); - } - } - - [Test] - [Category("Network")] - public async Task which_was_already_deleted_should_fail() - { - const string stream = "which_was_allready_deleted_should_fail"; - using (var connection = BuildConnection(_node)) - { - await connection.ConnectAsync(); - - await connection.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - - await AssertEx.ThrowsAsync( - () => connection.DeleteStreamAsync(stream, ExpectedVersion.Any, hardDelete: true)); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/event_store_connection_should.cs b/src/EventStore.Core.Tests/ClientAPI/event_store_connection_should.cs deleted file mode 100644 index 81fefbd37b..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/event_store_connection_should.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string), TcpType.Normal)] -[TestFixture(typeof(LogFormat.V2), typeof(string), TcpType.Ssl)] -public class event_store_connection_should : SpecificationWithDirectoryPerTestFixture -{ - private readonly TcpType _tcpType; - private MiniNode _node; - - public event_store_connection_should(TcpType tcpType) - { - _tcpType = tcpType; - } - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - [Test] - [Category("Network")] - public void not_throw_on_close_if_connect_was_not_called() - { - var connection = TestConnection.To(_node, _tcpType); - Assert.DoesNotThrow(connection.Close); - } - - [Test] - [Category("Network")] - public async Task not_throw_on_close_if_called_multiple_times() - { - var connection = TestConnection.To(_node, _tcpType); - await connection.ConnectAsync(); - connection.Close(); - Assert.DoesNotThrow(connection.Close); - } - - /* - //TODO WEIRD TEST GFY - [Test] - [Category("Network")] - public void throw_on_connect_called_more_than_once() - { - var connection = TestConnection.To(_node, _tcpType); - Assert.DoesNotThrow(() => connection.ConnectAsync().Wait()); - - await AssertEx.ThrowsAsync<>(() => connection.ConnectAsync().Wait(), - Throws.Exception.InstanceOf().With.InnerException.InstanceOf()); - } - - [Test] - [Category("Network")] - public void throw_on_connect_called_after_close() - { - var connection = TestConnection.To(_node, _tcpType); - connection.ConnectAsync().Wait(); - connection.Close(); - - await AssertEx.ThrowsAsync<>(() => connection.ConnectAsync().Wait(), - Throws.Exception.InstanceOf().With.InnerException.InstanceOf()); - } - */ - [Test] - [Category("Network")] - public async Task throw_invalid_operation_on_every_api_call_if_connect_was_not_called() - { - var connection = TestConnection.To(_node, _tcpType); - - const string s = "stream"; - var events = new[] { TestEvent.NewTestEvent() }; - - await AssertEx.ThrowsAsync(() => connection.DeleteStreamAsync(s, 0)); - - await AssertEx.ThrowsAsync(() => connection.AppendToStreamAsync(s, 0, events)); - - await AssertEx.ThrowsAsync( - () => connection.ReadStreamEventsForwardAsync(s, 0, 1, resolveLinkTos: false)); - - await AssertEx.ThrowsAsync( - () => connection.ReadStreamEventsBackwardAsync(s, 0, 1, resolveLinkTos: false)); - - await AssertEx.ThrowsAsync( - () => connection.ReadAllEventsForwardAsync(Position.Start, 1, false)); - - await AssertEx.ThrowsAsync(() => - connection.ReadAllEventsBackwardAsync(Position.End, 1, false)); - - await AssertEx.ThrowsAsync(() => connection.StartTransactionAsync(s, 0)); - - await AssertEx.ThrowsAsync( - () => connection.SubscribeToStreamAsync(s, false, (_, __) => Task.CompletedTask, (_, __, ___) => { })); - - await AssertEx.ThrowsAsync( - () => connection.SubscribeToAllAsync(false, (_, __) => Task.CompletedTask, (_, __, ___) => { })); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/isjson_flag_on_event.cs b/src/EventStore.Core.Tests/ClientAPI/isjson_flag_on_event.cs deleted file mode 100644 index ea916aa847..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/isjson_flag_on_event.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Common.Utils; -using EventStore.Core.Messages; -using EventStore.Core.Messaging; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using EventStore.Core.TransactionLog.LogRecords; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class isjson_flag_on_event : SpecificationWithDirectory -{ - private MiniNode _node; - - [SetUp] - public override async Task SetUp() - { - await base.SetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - } - - [TearDown] - public override async Task TearDown() - { - await _node.Shutdown(); - await base.TearDown(); - } - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.To(node, TcpType.Ssl); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task should_be_preserved_with_all_possible_write_and_read_methods() - { - const string stream = "should_be_preserved_with_all_possible_write_methods"; - using (var connection = BuildConnection(_node)) - { - await connection.ConnectAsync(); - - await connection.AppendToStreamAsync( - stream, - ExpectedVersion.Any, - new EventData(Guid.NewGuid(), "some-type", true, - Helper.UTF8NoBom.GetBytes("{\"some\":\"json\"}"), null), - new EventData(Guid.NewGuid(), "some-type", true, null, - Helper.UTF8NoBom.GetBytes("{\"some\":\"json\"}")), - new EventData(Guid.NewGuid(), "some-type", true, - Helper.UTF8NoBom.GetBytes("{\"some\":\"json\"}"), - Helper.UTF8NoBom.GetBytes("{\"some\":\"json\"}"))); - var expectedEvents = 3; - - if (LogFormatHelper.SupportsExplicitTransactions) - { - using (var transaction = await connection.StartTransactionAsync(stream, ExpectedVersion.Any)) - { - await transaction.WriteAsync( - new EventData(Guid.NewGuid(), "some-type", true, - Helper.UTF8NoBom.GetBytes("{\"some\":\"json\"}"), null), - new EventData(Guid.NewGuid(), "some-type", true, null, - Helper.UTF8NoBom.GetBytes("{\"some\":\"json\"}")), - new EventData(Guid.NewGuid(), "some-type", true, - Helper.UTF8NoBom.GetBytes("{\"some\":\"json\"}"), - Helper.UTF8NoBom.GetBytes("{\"some\":\"json\"}"))); - await transaction.CommitAsync(); - expectedEvents += 3; - } - } - - var done = new ManualResetEventSlim(); - _node.Node.MainQueue.Publish(new ClientMessage.ReadStreamEventsForward( - Guid.NewGuid(), Guid.NewGuid(), new CallbackEnvelope(message => - { - Assert.IsInstanceOf(message); - var msg = (ClientMessage.ReadStreamEventsForwardCompleted)message; - Assert.AreEqual(Data.ReadStreamResult.Success, msg.Result); - Assert.AreEqual(expectedEvents, msg.Events.Count); - Assert.IsTrue(msg.Events.All(x => (x.OriginalEvent.Flags & PrepareFlags.IsJson) != 0)); - - done.Set(); - }), stream, 0, 100, false, false, null, null, replyOnExpired: false)); - Assert.IsTrue(done.Wait(10000), "Read was not completed in time."); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_all_events_backward_filtered_should.cs b/src/EventStore.Core.Tests/ClientAPI/read_all_events_backward_filtered_should.cs deleted file mode 100644 index 3c48c685ce..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_all_events_backward_filtered_should.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Services; -using EventStore.Core.Tests.ClientAPI.Helpers; -using NUnit.Framework; -using ExpectedVersion = EventStore.ClientAPI.ExpectedVersion; -using StreamMetadata = EventStore.ClientAPI.StreamMetadata; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_all_events_backward_filtered_should - : SpecificationWithMiniNode -{ - private List _testEvents; - - protected override async Task When() - { - await _conn.SetStreamMetadataAsync("$all", -1, - StreamMetadata.Build().SetReadRole(SystemRoles.All), - DefaultData.AdminCredentials); - - _testEvents = Enumerable.Range(0, 10).Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "AEvent")) - .ToList(); - _testEvents.AddRange( - Enumerable.Range(0, 10).Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "BEvent")) - .ToList()); - - await _conn.AppendToStreamAsync("stream-a", ExpectedVersion.NoStream, _testEvents.EvenEvents()); - await _conn.AppendToStreamAsync("stream-b", ExpectedVersion.NoStream, _testEvents.OddEvents()); - } - - [Test, Category("LongRunning")] - public async Task only_return_events_with_a_given_stream_prefix() - { - var filter = Filter.StreamId.Prefix("stream-a"); - - var read = await _conn.FilteredReadAllEventsBackwardAsync(Position.End, 4096, false, filter, 4096); - Assert.That(EventDataComparer.Equal( - _testEvents.EvenEvents().ReverseEvents(), - read.Events.Select(x => x.Event).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task only_return_events_with_a_given_event_prefix() - { - var filter = Filter.EventType.Prefix("AE"); - - // Have to order the events as we are writing to two streams and can't guarantee ordering - - var read = await _conn.FilteredReadAllEventsBackwardAsync(Position.End, 4096, false, filter, 4096); - Assert.AreEqual(ReadDirection.Backward, read.ReadDirection); - Assert.That(EventDataComparer.Equal( - _testEvents.Where(e => e.Type == "AEvent").OrderBy(x => x.EventId).ToArray(), - read.Events.Select(x => x.Event).OrderBy(x => x.EventId).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task only_return_events_that_satisfy_a_given_stream_regex() - { - var filter = Filter.StreamId.Regex(new Regex(@"^.*m-b.*$")); - - var read = await _conn.FilteredReadAllEventsBackwardAsync(Position.End, 4096, false, filter, 4096); - Assert.AreEqual(ReadDirection.Backward, read.ReadDirection); - Assert.That(EventDataComparer.Equal( - _testEvents.OddEvents().ReverseEvents(), - read.Events.Select(x => x.Event).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task only_return_events_that_satisfy_a_given_event_regex() - { - var filter = Filter.EventType.Regex(new Regex(@"^.*BEv.*$")); - - // Have to order the events as we are writing to two streams and can't guarantee ordering - var read = await _conn.FilteredReadAllEventsBackwardAsync(Position.End, 4096, false, filter, 4096); - Assert.AreEqual(ReadDirection.Backward, read.ReadDirection); - Assert.That(EventDataComparer.Equal( - _testEvents.Where(e => e.Type == "BEvent").OrderBy(x => x.EventId).ToArray(), - read.Events.Select(x => x.Event).OrderBy(x => x.EventId).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task only_return_events_that_are_not_system_events() - { - var filter = Filter.ExcludeSystemEvents; - - // Have to order the events as we are writing to two streams and can't guarantee ordering - var read = await _conn.FilteredReadAllEventsBackwardAsync(Position.End, 4096, false, filter, 4096); - Assert.AreEqual(ReadDirection.Backward, read.ReadDirection); - Assert.That(!read.Events.Any(e => e.Event.EventType.StartsWith("$"))); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_all_events_backward_should.cs b/src/EventStore.Core.Tests/ClientAPI/read_all_events_backward_should.cs deleted file mode 100644 index 414484c094..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_all_events_backward_should.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Services; -using EventStore.Core.Tests.ClientAPI.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_all_events_backward_should - : SpecificationWithMiniNode -{ - private EventData[] _testEvents; - - protected override async Task When() - { - await _conn.SetStreamMetadataAsync("$all", -1, - StreamMetadata.Build().SetReadRole(SystemRoles.All), - DefaultData.AdminCredentials); - - _testEvents = Enumerable.Range(0, 20).Select(x => TestEvent.NewTestEvent(x.ToString())).ToArray(); - await _conn.AppendToStreamAsync("stream", ExpectedVersion.NoStream, _testEvents); - } - - [Test, Category("LongRunning")] - public async Task return_empty_slice_if_asked_to_read_from_start() - { - var read = await _conn.ReadAllEventsBackwardAsync(Position.Start, 1, false); - Assert.That(read.IsEndOfStream, Is.True); - Assert.That(read.Events.Length, Is.EqualTo(0)); - } - - [Test, Category("LongRunning")] - public async Task return_partial_slice_if_not_enough_events() - { - var read = await _conn.ReadAllEventsBackwardAsync(Position.End, 40, false); - Assert.That(read.Events.Length, Is.LessThan(40)); - Assert.That(EventDataComparer.Equal(_testEvents.Reverse().ToArray(), - read.Events.Take(_testEvents.Length).Select(x => x.Event).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task return_events_in_reversed_order_compared_to_written() - { - var read = await _conn.ReadAllEventsBackwardAsync(Position.End, _testEvents.Length, false); - Assert.That(EventDataComparer.Equal(_testEvents.Reverse().ToArray(), - read.Events.Select(x => x.Event).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task be_able_to_read_all_one_by_one_until_end_of_stream() - { - var all = new List(); - var position = Position.End; - AllEventsSlice slice; - - while (!(slice = await _conn.ReadAllEventsBackwardAsync(position, 1, false)).IsEndOfStream) - { - all.Add(slice.Events.Single().Event); - position = slice.NextPosition; - } - - Assert.That( - EventDataComparer.Equal(_testEvents.Reverse().ToArray(), all.Take(_testEvents.Length).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task be_able_to_read_events_slice_at_time() - { - var all = new List(); - var position = Position.End; - AllEventsSlice slice; - - while (!(slice = await _conn.ReadAllEventsBackwardAsync(position, 5, false)).IsEndOfStream) - { - all.AddRange(slice.Events.Select(x => x.Event)); - position = slice.NextPosition; - } - - Assert.That( - EventDataComparer.Equal(_testEvents.Reverse().ToArray(), all.Take(_testEvents.Length).ToArray())); - } - - [Test] - [Category("Network")] - public async Task throw_when_got_int_max_value_as_maxcount() - { - await AssertEx.ThrowsAsync( - () => _conn.ReadAllEventsBackwardAsync(Position.Start, int.MaxValue, resolveLinkTos: false)); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_all_events_filtered_paging_should.cs b/src/EventStore.Core.Tests/ClientAPI/read_all_events_filtered_paging_should.cs deleted file mode 100644 index f0e56d7c42..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_all_events_filtered_paging_should.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Services; -using EventStore.Core.Tests.ClientAPI.Helpers; -using NUnit.Framework; -using ExpectedVersion = EventStore.ClientAPI.ExpectedVersion; -using ResolvedEvent = EventStore.ClientAPI.ResolvedEvent; -using StreamMetadata = EventStore.ClientAPI.StreamMetadata; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_all_events_filtered_paging_should - : SpecificationWithMiniNode -{ - private List _testEvents = new List(); - - private List _testEventsA; - - private List _testEventsC; - - public read_all_events_filtered_paging_should() : base(chunkSize: 2 * 1024 * 1024) { } - - protected override async Task When() - { - await _conn.SetStreamMetadataAsync("$all", -1, - StreamMetadata.Build().SetReadRole(SystemRoles.All), - DefaultData.AdminCredentials); - - _testEventsA = Enumerable - .Range(0, 10) - .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "AEvent")) - .ToList(); - - var testEventsB = Enumerable - .Range(0, 10000) - .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "BEvent")) - .ToList(); - - _testEventsC = Enumerable - .Range(0, 10) - .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "CEvent")) - .ToList(); - - _testEvents.AddRange(_testEventsA); - _testEvents.AddRange(testEventsB); - _testEvents.AddRange(_testEventsC); - - _conn.AppendToStreamAsync("stream-a", ExpectedVersion.NoStream, _testEvents).Wait(); - } - - [Test, Category("LongRunning")] - public void handle_paging_between_events_forward() - { - var numberOfEmptySlicesRead = 0; - - var filter = Filter.EventType.Prefix("CE"); - var sliceStart = Position.Start; - var read = new List(); - AllEventsSlice slice; - - do - { - slice = _conn.FilteredReadAllEventsForwardAsync(sliceStart, 50, false, filter, maxSearchWindow: 100) - .GetAwaiter() - .GetResult(); - - if (slice.Events.Length == 0) - { - numberOfEmptySlicesRead++; - } - else - { - read.AddRange(slice.Events); - } - - sliceStart = slice.NextPosition; - } while (!slice.IsEndOfStream); - - Assert.That(EventDataComparer.Equal( - _testEventsC.ToArray(), - read.Select(x => x.Event).ToArray())); - - Assert.AreEqual(100, numberOfEmptySlicesRead); - } - - [Test, Category("LongRunning")] - public void handle_paging_between_events_backward() - { - var numberOfEmptySlicesRead = 0; - - var filter = Filter.EventType.Prefix("AE"); - var sliceStart = Position.End; - var read = new List(); - AllEventsSlice slice; - - do - { - slice = _conn.FilteredReadAllEventsBackwardAsync(sliceStart, 50, false, filter, maxSearchWindow: 100) - .GetAwaiter() - .GetResult(); - if (slice.Events.Length == 0) - { - numberOfEmptySlicesRead++; - } - else - { - read.AddRange(slice.Events); - } - - sliceStart = slice.NextPosition; - } while (!slice.IsEndOfStream); - - Assert.That(EventDataComparer.Equal( - _testEventsA.ReverseEvents(), - read.Select(x => x.Event).ToArray())); - - Assert.AreEqual(100, numberOfEmptySlicesRead); - } - - [Test, Category("LongRunning")] - public void handle_paging_between_events_returns_correct_number_of_events_for_max_search_window_forward() - { - var filter = Filter.EventType.Prefix("BE"); - - var slice = _conn.FilteredReadAllEventsForwardAsync(Position.Start, 30, false, filter, maxSearchWindow: 30) - .GetAwaiter() - .GetResult(); - - // Includes system events at start of stream (inc epoch-information) - var expectedCount = 11; - - Assert.AreEqual(expectedCount, slice.Events.Length); - } - - [Test, Category("LongRunning")] - public void handle_paging_between_events_returns_correct_number_of_events_for_max_search_window_backward() - { - var filter = Filter.EventType.Prefix("BE"); - - var slice = _conn.FilteredReadAllEventsBackwardAsync(Position.End, 20, false, filter, maxSearchWindow: 20) - .GetAwaiter() - .GetResult(); - - Assert.AreEqual(10, slice.Events.Length); // Includes system events - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_filtered_should.cs b/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_filtered_should.cs deleted file mode 100644 index 3dd8a928a5..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_filtered_should.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Services; -using EventStore.Core.Tests.ClientAPI.Helpers; -using NUnit.Framework; -using ExpectedVersion = EventStore.ClientAPI.ExpectedVersion; -using StreamMetadata = EventStore.ClientAPI.StreamMetadata; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_all_events_forward_filtered_should - : SpecificationWithMiniNode -{ - private List _testEvents; - - protected override async Task When() - { - await _conn.SetStreamMetadataAsync("$all", -1, - StreamMetadata.Build().SetReadRole(SystemRoles.All), - DefaultData.AdminCredentials); - - _testEvents = Enumerable - .Range(0, 10) - .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "AEvent")) - .ToList(); - - _testEvents.AddRange( - Enumerable - .Range(0, 10) - .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "BEvent")).ToList()); - - await _conn.AppendToStreamAsync("stream-a", ExpectedVersion.NoStream, _testEvents.EvenEvents()); - await _conn.AppendToStreamAsync("stream-b", ExpectedVersion.NoStream, _testEvents.OddEvents()); - } - - [Test, Category("LongRunning")] - public async Task only_return_events_with_a_given_stream_prefix() - { - var filter = Filter.StreamId.Prefix("stream-a"); - - var read = await _conn.FilteredReadAllEventsForwardAsync(Position.Start, 1000, false, filter, 1000); - Assert.That(EventDataComparer.Equal( - _testEvents.EvenEvents().ToArray(), - read.Events.Select(x => x.Event).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task only_return_events_with_a_given_event_prefix() - { - var filter = Filter.EventType.Prefix("AE"); - - // Have to order the events as we are writing to two streams and can't guarantee ordering - var read = await _conn.FilteredReadAllEventsForwardAsync(Position.Start, 1000, false, filter, 1000); - Assert.That(EventDataComparer.Equal( - _testEvents.Where(e => e.Type == "AEvent").OrderBy(x => x.EventId).ToArray(), - read.Events.Select(x => x.Event).OrderBy(x => x.EventId).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task only_return_events_that_satisfy_a_given_stream_regex() - { - var filter = Filter.StreamId.Regex(new Regex(@"^.*eam-b.*$")); - - var read = await _conn.FilteredReadAllEventsForwardAsync(Position.Start, 1000, false, filter, 1000); - Assert.AreEqual(ReadDirection.Forward, read.ReadDirection); - Assert.That(EventDataComparer.Equal( - _testEvents.OddEvents().ToArray(), - read.Events.Select(x => x.Event).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task only_return_events_that_satisfy_a_given_event_regex() - { - var filter = Filter.EventType.Regex(new Regex(@"^.*BEv.*$")); - - // Have to order the events as we are writing to two streams and can't guarantee ordering - var read = await _conn.FilteredReadAllEventsForwardAsync(Position.Start, 1000, false, filter, 1000); - Assert.AreEqual(ReadDirection.Forward, read.ReadDirection); - Assert.That(EventDataComparer.Equal( - _testEvents.Where(e => e.Type == "BEvent").OrderBy(x => x.EventId).ToArray(), - read.Events.Select(x => x.Event).OrderBy(x => x.EventId).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task only_return_events_that_are_not_system_events() - { - var filter = Filter.ExcludeSystemEvents; - - // Have to order the events as we are writing to two streams and can't guarantee ordering - var read = await _conn.FilteredReadAllEventsForwardAsync(Position.Start, 1000, false, filter, 1000); - Assert.AreEqual(ReadDirection.Forward, read.ReadDirection); - Assert.That(!read.Events.Any(e => e.Event.EventType.StartsWith("$"))); - } -} - -internal static class EventDataExtensions -{ - internal static List EvenEvents(this List ed) => ed.Where((c, i) => i % 2 == 0).ToList(); - - internal static List OddEvents(this List ed) => ed.Where((c, i) => i % 2 != 0).ToList(); - - internal static EventData[] ReverseEvents(this List ed) => ed.ToArray().Reverse().ToArray(); -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_should.cs b/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_should.cs deleted file mode 100644 index 8fda5abf07..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_should.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Services; -using EventStore.Core.Tests.ClientAPI.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_all_events_forward_should : SpecificationWithMiniNode -{ - private EventData[] _testEvents; - - protected override async Task When() - { - await _conn.SetStreamMetadataAsync("$all", -1, - StreamMetadata.Build().SetReadRole(SystemRoles.All), - DefaultData.AdminCredentials); - - _testEvents = Enumerable.Range(0, 20).Select(x => TestEvent.NewTestEvent(x.ToString())).ToArray(); - await _conn.AppendToStreamAsync("stream", ExpectedVersion.NoStream, _testEvents); - } - - [Test, Category("LongRunning")] - public async Task return_empty_slice_if_asked_to_read_from_end() - { - var read = await _conn.ReadAllEventsForwardAsync(Position.End, 1, false); - Assert.That(read.IsEndOfStream, Is.True); - Assert.That(read.Events.Length, Is.EqualTo(0)); - } - - [Test, Category("LongRunning")] - public async Task return_events_in_same_order_as_written() - { - var read = await _conn.ReadAllEventsForwardAsync(Position.Start, _testEvents.Length + 20, false); - Assert.That(EventDataComparer.Equal( - _testEvents.ToArray(), - read.Events.Skip(read.Events.Length - _testEvents.Length).Select(x => x.Event).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task be_able_to_read_all_one_by_one_until_end_of_stream() - { - var all = new List(); - var position = Position.Start; - AllEventsSlice slice; - - while (!(slice = await _conn.ReadAllEventsForwardAsync(position, 1, false)).IsEndOfStream) - { - all.Add(slice.Events.Single().Event); - position = slice.NextPosition; - } - - Assert.That(EventDataComparer.Equal(_testEvents, all.Skip(all.Count - _testEvents.Length).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task be_able_to_read_events_slice_at_time() - { - var all = new List(); - var position = Position.Start; - AllEventsSlice slice; - - while (!(slice = await _conn.ReadAllEventsForwardAsync(position, 5, false)).IsEndOfStream) - { - all.AddRange(slice.Events.Select(x => x.Event)); - position = slice.NextPosition; - } - - Assert.That(EventDataComparer.Equal(_testEvents, all.Skip(all.Count - _testEvents.Length).ToArray())); - } - - [Test, Category("LongRunning")] - public async Task return_partial_slice_if_not_enough_events() - { - var read = await _conn.ReadAllEventsForwardAsync(Position.Start, 40, false); - Assert.That(read.Events.Length, Is.LessThan(40)); - Assert.That(EventDataComparer.Equal( - _testEvents, - read.Events.Skip(read.Events.Length - _testEvents.Length).Select(x => x.Event).ToArray())); - } - - [Test] - [Category("Network")] - public async Task throw_when_got_int_max_value_as_maxcount() - { - await AssertEx.ThrowsAsync( - () => _conn.ReadAllEventsForwardAsync(Position.Start, int.MaxValue, resolveLinkTos: false)); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_hard_deleted_stream_should.cs b/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_hard_deleted_stream_should.cs deleted file mode 100644 index c70c149509..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_hard_deleted_stream_should.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.SystemData; -using EventStore.Core.Data; -using EventStore.Core.Services; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; -using ExpectedVersion = EventStore.ClientAPI.ExpectedVersion; -using StreamMetadata = EventStore.ClientAPI.StreamMetadata; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_all_events_forward_with_hard_deleted_stream_should - : SpecificationWithMiniNode -{ - private EventData[] _testEvents; - - protected override async Task When() - { - await _conn.SetStreamMetadataAsync( - "$all", -1, StreamMetadata.Build().SetReadRole(SystemRoles.All), - new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword)); - - _testEvents = Enumerable.Range(0, 20).Select(x => TestEvent.NewTestEvent(x.ToString())).ToArray(); - await _conn.AppendToStreamAsync("stream", ExpectedVersion.NoStream, _testEvents); - await _conn.DeleteStreamAsync("stream", ExpectedVersion.Any, hardDelete: true); - } - - [Test, Category("LongRunning")] - public async Task ensure_deleted_stream() - { - var res = await _conn.ReadStreamEventsForwardAsync("stream", 0, 100, false); - Assert.AreEqual(SliceReadStatus.StreamDeleted, res.Status); - Assert.AreEqual(0, res.Events.Length); - } - - [Test, Category("LongRunning")] - public async Task returns_all_events_including_tombstone() - { - AllEventsSlice read = await _conn.ReadAllEventsForwardAsync(Position.Start, _testEvents.Length + 20, false) -; - Assert.That( - EventDataComparer.Equal( - _testEvents.ToArray(), - read.Events.Skip(read.Events.Length - _testEvents.Length - 1) - .Take(_testEvents.Length) - .Select(x => x.Event) - .ToArray())); - var lastEvent = read.Events.Last().Event; - Assert.AreEqual("stream", lastEvent.EventStreamId); - Assert.AreEqual(SystemEventTypes.StreamDeleted, lastEvent.EventType); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_linkto_passed_max_count.cs b/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_linkto_passed_max_count.cs deleted file mode 100644 index 0869ba4264..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_linkto_passed_max_count.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_all_events_forward_with_linkto_passed_max_count : SpecificationWithLinkToToMaxCountDeletedEvents -{ - private StreamEventsSlice _read; - - protected override async Task When() - { - _read = await _conn.ReadStreamEventsForwardAsync(LinkedStreamName, 0, 1, true); - } - - [Test] - public void one_event_is_read() - { - Assert.AreEqual(1, _read.Events.Length); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_linkto_to_deleted_event.cs b/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_linkto_to_deleted_event.cs deleted file mode 100644 index f98b47457a..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_linkto_to_deleted_event.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Threading.Tasks; -using EventStore.ClientAPI; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_all_events_forward_with_linkto_to_deleted_event : SpecificationWithLinkToToDeletedEvents -{ - private StreamEventsSlice _read; - - protected override async Task When() - { - _read = await _conn.ReadStreamEventsForwardAsync(LinkedStreamName, 0, 1, true, null); - } - - [Test] - public void one_event_is_read() - { - Assert.AreEqual(1, _read.Events.Length); - } - - [Test] - public void the_linked_event_is_not_resolved() - { - Assert.IsNull(_read.Events[0].Event); - } - - [Test] - public void the_link_event_is_included() - { - Assert.IsNotNull(_read.Events[0].OriginalEvent); - } - - [Test] - public void the_event_is_not_resolved() - { - Assert.IsFalse(_read.Events[0].IsResolved); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_soft_deleted_stream_should.cs b/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_soft_deleted_stream_should.cs deleted file mode 100644 index e190d70eef..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_all_events_forward_with_soft_deleted_stream_should.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.SystemData; -using EventStore.Core.Data; -using EventStore.Core.Services; -using EventStore.Core.Tests.ClientAPI.Helpers; -using NUnit.Framework; -using ExpectedVersion = EventStore.ClientAPI.ExpectedVersion; -using StreamMetadata = EventStore.ClientAPI.StreamMetadata; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_all_events_forward_with_soft_deleted_stream_should - : SpecificationWithMiniNode -{ - private EventData[] _testEvents; - - protected override async Task When() - { - await _conn.SetStreamMetadataAsync( - "$all", -1, StreamMetadata.Build().SetReadRole(SystemRoles.All), - new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword)); - - _testEvents = Enumerable.Range(0, 20).Select(x => TestEvent.NewTestEvent(x.ToString())).ToArray(); - await _conn.AppendToStreamAsync("stream", ExpectedVersion.NoStream, _testEvents); - await _conn.DeleteStreamAsync("stream", ExpectedVersion.Any); - } - - [Test, Category("LongRunning")] - public async Task ensure_deleted_stream() - { - var res = await _conn.ReadStreamEventsForwardAsync("stream", 0, 100, false); - Assert.AreEqual(SliceReadStatus.StreamNotFound, res.Status); - Assert.AreEqual(0, res.Events.Length); - } - - [Test, Category("LongRunning")] - public async Task returns_all_events_including_tombstone() - { - AllEventsSlice read = await _conn.ReadAllEventsForwardAsync(Position.Start, _testEvents.Length + 20, false) -; - Assert.That( - EventDataComparer.Equal( - _testEvents.ToArray(), - read.Events.Skip(read.Events.Length - _testEvents.Length - 1) - .Take(_testEvents.Length) - .Select(x => x.Event) - .ToArray())); - var lastEvent = read.Events.Last().Event; - Assert.AreEqual("$$stream", lastEvent.EventStreamId); - Assert.AreEqual(SystemEventTypes.StreamMetadata, lastEvent.EventType); - var metadata = StreamMetadata.FromJsonBytes(lastEvent.Data); - Assert.AreEqual(EventNumber.DeletedStream, metadata.TruncateBefore); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_allevents_backward_with_linkto_deleted_event.cs b/src/EventStore.Core.Tests/ClientAPI/read_allevents_backward_with_linkto_deleted_event.cs deleted file mode 100644 index 055d9f3997..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_allevents_backward_with_linkto_deleted_event.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System.Threading.Tasks; -using EventStore.ClientAPI; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_event_of_linkto_to_deleted_event : SpecificationWithLinkToToDeletedEvents -{ - private EventReadResult _read; - - protected override async Task When() - { - _read = await _conn.ReadEventAsync(LinkedStreamName, 0, true); - } - - [Test] - public void the_linked_event_is_returned() - { - Assert.IsNotNull(_read.Event.Value.Link); - } - - [Test] - public void the_deleted_event_is_not_resolved() - { - Assert.IsNull(_read.Event.Value.Event); - } - - [Test] - public void the_status_is_success() - { - Assert.AreEqual(EventReadStatus.Success, _read.Status); - } -} - -[Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_allevents_backward_with_linkto_deleted_event : SpecificationWithLinkToToDeletedEvents -{ - private StreamEventsSlice _read; - - protected override async Task When() - { - _read = await _conn.ReadStreamEventsBackwardAsync(LinkedStreamName, 0, 1, true, null); - } - - [Test] - public void one_event_is_read() - { - Assert.AreEqual(1, _read.Events.Length); - } - - [Test] - public void the_linked_event_is_not_resolved() - { - Assert.IsNull(_read.Events[0].Event); - } - - [Test] - public void the_link_event_is_included() - { - Assert.IsNotNull(_read.Events[0].OriginalEvent); - } - - [Test] - public void the_event_is_not_resolved() - { - Assert.IsFalse(_read.Events[0].IsResolved); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_event_should.cs b/src/EventStore.Core.Tests/ClientAPI/read_event_should.cs deleted file mode 100644 index 58380d9de1..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_event_should.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_event_should - : SpecificationWithMiniNode -{ - private Guid _eventId0; - private Guid _eventId1; - - protected override async Task When() - { - _eventId0 = Guid.NewGuid(); - _eventId1 = Guid.NewGuid(); - - await _conn.AppendToStreamAsync("test-stream", - -1, - new EventData(_eventId0, "event0", false, new byte[3], new byte[2]), - new EventData(_eventId1, "event1", true, new byte[7], new byte[10])); - await _conn.DeleteStreamAsync("deleted-stream", -1, hardDelete: true); - } - - [Test, Category("Network")] - public async Task throw_if_stream_id_is_null() - { - await AssertEx.ThrowsAsync(() => _conn.ReadEventAsync(null, 0, resolveLinkTos: false)); - } - - [Test, Category("Network")] - public async Task throw_if_stream_id_is_empty() - { - await AssertEx.ThrowsAsync(() => _conn.ReadEventAsync("", 0, resolveLinkTos: false)); - } - - [Test, Category("Network")] - public async Task throw_if_event_number_is_less_than_minus_one() - { - await AssertEx.ThrowsAsync(() => - _conn.ReadEventAsync("stream", -2, resolveLinkTos: false)); - } - - [Test, Category("Network")] - public async Task notify_using_status_code_if_stream_not_found() - { - var res = await _conn.ReadEventAsync("unexisting-stream", 5, false); - - Assert.AreEqual(EventReadStatus.NoStream, res.Status); - Assert.IsNull(res.Event); - Assert.AreEqual("unexisting-stream", res.Stream); - Assert.AreEqual(5, res.EventNumber); - } - - [Test, Category("Network")] - public async Task return_no_stream_if_requested_last_event_in_empty_stream() - { - var res = await _conn.ReadEventAsync("some-really-empty-stream", -1, false); - Assert.AreEqual(EventReadStatus.NoStream, res.Status); - } - - [Test, Category("Network")] - public async Task notify_using_status_code_if_stream_was_deleted() - { - var res = await _conn.ReadEventAsync("deleted-stream", 5, false); - - Assert.AreEqual(EventReadStatus.StreamDeleted, res.Status); - Assert.IsNull(res.Event); - Assert.AreEqual("deleted-stream", res.Stream); - Assert.AreEqual(5, res.EventNumber); - } - - [Test, Category("Network")] - public async Task notify_using_status_code_if_stream_does_not_have_event() - { - var res = await _conn.ReadEventAsync("test-stream", 5, false); - - Assert.AreEqual(EventReadStatus.NotFound, res.Status); - Assert.IsNull(res.Event); - Assert.AreEqual("test-stream", res.Stream); - Assert.AreEqual(5, res.EventNumber); - } - - [Test, Category("Network")] - public async Task return_existing_event() - { - var res = await _conn.ReadEventAsync("test-stream", 0, false); - - Assert.AreEqual(EventReadStatus.Success, res.Status); - Assert.AreEqual(res.Event.Value.OriginalEvent.EventId, _eventId0); - Assert.AreEqual("test-stream", res.Stream); - Assert.AreEqual(0, res.EventNumber); - Assert.AreNotEqual(DateTime.MinValue, res.Event.Value.OriginalEvent.Created); - Assert.AreNotEqual(0, res.Event.Value.OriginalEvent.CreatedEpoch); - } - - [Test, Category("Network")] - public async Task retrieve_the_is_json_flag_properly() - { - var res = await _conn.ReadEventAsync("test-stream", 1, false); - - Assert.AreEqual(EventReadStatus.Success, res.Status); - Assert.AreEqual(res.Event.Value.OriginalEvent.EventId, _eventId1); - Assert.IsTrue(res.Event.Value.OriginalEvent.IsJson); - } - - [Test, Category("Network")] - public async Task return_last_event_in_stream_if_event_number_is_minus_one() - { - var res = await _conn.ReadEventAsync("test-stream", -1, false); - - Assert.AreEqual(EventReadStatus.Success, res.Status); - Assert.AreEqual(res.Event.Value.OriginalEvent.EventId, _eventId1); - Assert.AreEqual("test-stream", res.Stream); - Assert.AreEqual(-1, res.EventNumber); - Assert.AreNotEqual(DateTime.MinValue, res.Event.Value.OriginalEvent.Created); - Assert.AreNotEqual(0, res.Event.Value.OriginalEvent.CreatedEpoch); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_event_stream_backward_should.cs b/src/EventStore.Core.Tests/ClientAPI/read_event_stream_backward_should.cs deleted file mode 100644 index 8886a6f3cf..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_event_stream_backward_should.cs +++ /dev/null @@ -1,243 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_event_stream_backward_should : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - virtual protected IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [Test] - [Category("Network")] - public async Task throw_if_count_le_zero() - { - const string stream = "read_event_stream_backward_should_throw_if_count_le_zero"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - await AssertEx.ThrowsAsync(() => - store.ReadStreamEventsBackwardAsync(stream, 0, 0, resolveLinkTos: false)); - } - } - - [Test] - [Category("Network")] - public async Task throw_if_start_less_than_minus_one() - { - const string stream = "read_event_stream_backward_should_throw_if_start_less_than_minus_one"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - await AssertEx.ThrowsAsync(() => - store.ReadStreamEventsBackwardAsync(stream, -2, 100, resolveLinkTos: false)); - } - } - - - [Test] - [Category("Network")] - public async Task notify_using_status_code_if_stream_not_found() - { - const string stream = "read_event_stream_backward_should_notify_using_status_code_if_stream_not_found"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var read = await store.ReadStreamEventsBackwardAsync(stream, StreamPosition.End, 1, - resolveLinkTos: false); - - Assert.That(read.Status, Is.EqualTo(SliceReadStatus.StreamNotFound)); - } - } - - [Test] - [Category("Network")] - public async Task notify_using_status_code_if_stream_was_deleted() - { - const string stream = "read_event_stream_backward_should_notify_using_status_code_if_stream_was_deleted"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - await store.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - - var read = await store.ReadStreamEventsBackwardAsync(stream, StreamPosition.End, 1, - resolveLinkTos: false); - - Assert.That(read.Status, Is.EqualTo(SliceReadStatus.StreamDeleted)); - } - } - - [Test] - [Category("Network")] - public async Task return_no_events_when_called_on_empty_stream() - { - const string stream = "read_event_stream_backward_should_return_single_event_when_called_on_empty_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var read = await store.ReadStreamEventsBackwardAsync(stream, StreamPosition.End, 1, - resolveLinkTos: false); - - Assert.That(read.Events.Length, Is.EqualTo(0)); - } - } - - [Test] - [Category("Network")] - public async Task return_partial_slice_if_no_enough_events_in_stream() - { - const string stream = - "read_event_stream_backward_should_return_partial_slice_if_no_enough_events_in_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var testEvents = Enumerable.Range(0, 10).Select(x => TestEvent.NewTestEvent((x + 1).ToString())) - .ToArray(); - var write10 = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, testEvents); - - var read = await store.ReadStreamEventsBackwardAsync(stream, 1, 5, resolveLinkTos: false); - - Assert.That(read.Events.Length, Is.EqualTo(2)); - } - } - - [Test] - [Category("Network")] - public async Task return_events_reversed_compared_to_written() - { - const string stream = "read_event_stream_backward_should_return_events_reversed_compared_to_written"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var testEvents = Enumerable.Range(0, 10).Select(x => TestEvent.NewTestEvent((x + 1).ToString())) - .ToArray(); - var write10 = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, testEvents); - - var read = await store.ReadStreamEventsBackwardAsync(stream, StreamPosition.End, testEvents.Length, - resolveLinkTos: false); - - Assert.That(EventDataComparer.Equal(testEvents.Reverse().ToArray(), - read.Events.Select(x => x.Event).ToArray())); - } - } - - [Test] - [Category("Network")] - public async Task be_able_to_read_single_event_from_arbitrary_position() - { - const string stream = - "read_event_stream_backward_should_be_able_to_read_single_event_from_arbitrary_position"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var testEvents = Enumerable.Range(0, 10).Select(x => TestEvent.NewTestEvent(x.ToString())).ToArray(); - var write10 = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, testEvents); - - var read = await store.ReadStreamEventsBackwardAsync(stream, 7, 1, resolveLinkTos: false); - - Assert.That(EventDataComparer.Equal(testEvents[7], read.Events.Single().Event)); - } - } - - [Test] - [Category("Network")] - public async Task be_able_to_read_first_event() - { - const string stream = "read_event_stream_backward_should_be_able_to_read_first_event"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var testEvents = Enumerable.Range(0, 10).Select(x => TestEvent.NewTestEvent((x + 1).ToString())) - .ToArray(); - var write10 = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, testEvents); - - var read = await store.ReadStreamEventsBackwardAsync(stream, StreamPosition.Start, 1, - resolveLinkTos: false); - - Assert.That(read.Events.Length, Is.EqualTo(1)); - } - } - - [Test] - [Category("Network")] - public async Task be_able_to_read_last_event() - { - const string stream = "read_event_stream_backward_should_be_able_to_read_last_event"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var testEvents = Enumerable.Range(0, 10).Select(x => TestEvent.NewTestEvent(x.ToString())).ToArray(); - var write10 = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, testEvents); - - var read = await store.ReadStreamEventsBackwardAsync(stream, StreamPosition.End, 1, - resolveLinkTos: false); - - Assert.That(EventDataComparer.Equal(testEvents.Last(), read.Events.Single().Event)); - } - } - - [Test] - [Category("Network")] - public async Task be_able_to_read_slice_from_arbitrary_position() - { - const string stream = "read_event_stream_backward_should_be_able_to_read_slice_from_arbitrary_position"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var testEvents = Enumerable.Range(0, 10).Select(x => TestEvent.NewTestEvent(x.ToString())).ToArray(); - var write10 = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, testEvents); - - var read = await store.ReadStreamEventsBackwardAsync(stream, 3, 2, resolveLinkTos: false); - - Assert.That(EventDataComparer.Equal(testEvents.Skip(2).Take(2).Reverse().ToArray(), - read.Events.Select(x => x.Event).ToArray())); - } - } - - [Test] - [Category("Network")] - public async Task throw_when_got_int_max_value_as_maxcount() - { - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - await AssertEx.ThrowsAsync(() => - store.ReadStreamEventsBackwardAsync("foo", StreamPosition.Start, int.MaxValue, - resolveLinkTos: false)); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_event_stream_forward_should.cs b/src/EventStore.Core.Tests/ClientAPI/read_event_stream_forward_should.cs deleted file mode 100644 index 45a4fec0b3..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_event_stream_forward_should.cs +++ /dev/null @@ -1,219 +0,0 @@ -using System; -using System.Globalization; -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_event_stream_forward_should : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - virtual protected IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [Test] - [Category("Network")] - public async Task throw_if_count_le_zero() - { - const string stream = "read_event_stream_forward_should_throw_if_count_le_zero"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - await AssertEx.ThrowsAsync(() => - store.ReadStreamEventsForwardAsync(stream, 0, 0, resolveLinkTos: false)); - } - } - - [Test] - [Category("Network")] - public async Task throw_if_start_lt_zero() - { - const string stream = "read_event_stream_forward_should_throw_if_start_lt_zero"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - await AssertEx.ThrowsAsync(() => - store.ReadStreamEventsForwardAsync(stream, -1, 1, resolveLinkTos: false)); - } - } - - [Test] - [Category("Network")] - public async Task notify_using_status_code_if_stream_not_found() - { - const string stream = "read_event_stream_forward_should_notify_using_status_code_if_stream_not_found"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var read = await store.ReadStreamEventsForwardAsync(stream, 0, 1, resolveLinkTos: false); - - Assert.That(read.Status, Is.EqualTo(SliceReadStatus.StreamNotFound)); - } - } - - [Test] - [Category("Network")] - public async Task notify_using_status_code_if_stream_was_deleted() - { - const string stream = "read_event_stream_forward_should_notify_using_status_code_if_stream_was_deleted"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var delete = await store.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - - var read = await store.ReadStreamEventsForwardAsync(stream, 0, 1, resolveLinkTos: false); - - Assert.That(read.Status, Is.EqualTo(SliceReadStatus.StreamDeleted)); - } - } - - [Test] - [Category("Network")] - public async Task return_no_events_when_called_on_empty_stream() - { - const string stream = "read_event_stream_forward_should_return_single_event_when_called_on_empty_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var read = await store.ReadStreamEventsForwardAsync(stream, 0, 1, resolveLinkTos: false); - - Assert.That(read.Events.Length, Is.EqualTo(0)); - } - } - - [Test] - [Category("Network")] - public async Task return_empty_slice_when_called_on_non_existing_range() - { - const string stream = - "read_event_stream_forward_should_return_empty_slice_when_called_on_non_existing_range"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var write10 = await store.AppendToStreamAsync(stream, - ExpectedVersion.NoStream, - Enumerable.Range(0, 10).Select(x => - TestEvent.NewTestEvent((x + 1).ToString(CultureInfo.InvariantCulture)))); - - var read = await store.ReadStreamEventsForwardAsync(stream, 11, 5, resolveLinkTos: false); - - Assert.That(read.Events.Length, Is.EqualTo(0)); - } - } - - [Test] - [Category("Network")] - public async Task return_partial_slice_if_not_enough_events_in_stream() - { - const string stream = "read_event_stream_forward_should_return_partial_slice_if_no_enough_events_in_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var write10 = await store.AppendToStreamAsync(stream, - ExpectedVersion.NoStream, - Enumerable.Range(0, 10).Select(x => - TestEvent.NewTestEvent((x + 1).ToString(CultureInfo.InvariantCulture)))); - - var read = await store.ReadStreamEventsForwardAsync(stream, 9, 5, resolveLinkTos: false); - - Assert.That(read.Events.Length, Is.EqualTo(1)); - } - } - - [Test] - [Category("Network")] - public async Task throw_when_got_int_max_value_as_maxcount() - { - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - await AssertEx.ThrowsAsync(() => - store.ReadStreamEventsForwardAsync("foo", StreamPosition.Start, int.MaxValue, - resolveLinkTos: false)); - } - } - - [Test] - [Category("Network")] - public async Task return_events_in_same_order_as_written() - { - const string stream = "read_event_stream_forward_should_return_events_in_same_order_as_written"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var testEvents = Enumerable.Range(0, 10).Select(x => TestEvent.NewTestEvent(x.ToString())).ToArray(); - var write10 = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, testEvents); - - var read = await store.ReadStreamEventsForwardAsync(stream, StreamPosition.Start, testEvents.Length, - resolveLinkTos: false); - - Assert.That(EventDataComparer.Equal(testEvents, read.Events.Select(x => x.Event).ToArray())); - } - } - - [Test] - [Category("Network")] - public async Task be_able_to_read_single_event_from_arbitrary_position() - { - const string stream = "read_event_stream_forward_should_be_able_to_read_from_arbitrary_position"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var testEvents = Enumerable.Range(0, 10).Select(x => TestEvent.NewTestEvent(x.ToString())).ToArray(); - var write10 = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, testEvents); - - var read = await store.ReadStreamEventsForwardAsync(stream, 5, 1, resolveLinkTos: false); - - Assert.That(EventDataComparer.Equal(testEvents[5], read.Events.Single().Event)); - } - } - - [Test] - [Category("Network")] - public async Task be_able_to_read_slice_from_arbitrary_position() - { - const string stream = "read_event_stream_forward_should_be_able_to_read_slice_from_arbitrary_position"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var testEvents = Enumerable.Range(0, 10).Select(x => TestEvent.NewTestEvent(x.ToString())).ToArray(); - var write10 = await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, testEvents); - - var read = await store.ReadStreamEventsForwardAsync(stream, 5, 2, resolveLinkTos: false); - - Assert.That(EventDataComparer.Equal(testEvents.Skip(5).Take(2).ToArray(), - read.Events.Select(x => x.Event).ToArray())); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_event_with_hash_collision.cs b/src/EventStore.Core.Tests/ClientAPI/read_event_with_hash_collision.cs deleted file mode 100644 index 47046963a9..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_event_with_hash_collision.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Tests; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.Services.Storage.HashCollisions; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_event_with_hash_collision : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.To(node, TcpType.Ssl); - } - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName, - memTableSize: 20, - hashCollisionReadLimit: 1, - indexBitnessVersion: EventStore.Core.Index.PTableVersions.IndexV4, - hash32bit: true, - streamExistenceFilterSize: 0); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - [Test] - public async Task should_return_not_found() - { - const string stream1 = "account--696193173"; - const string stream2 = "LPN-FC002_LPK51001"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - //Write event to stream 1 - Assert.AreEqual(0, - (await store.AppendToStreamAsync(stream1, ExpectedVersion.NoStream, - new EventData(Guid.NewGuid(), "TestEvent", true, null, null))).NextExpectedVersion); - //Write 100 events to stream 2 which will have the same hash as stream 1. - for (int i = 0; i < 100; i++) - { - Assert.AreEqual(i, - (await store.AppendToStreamAsync(stream2, ExpectedVersion.Any, - new EventData(Guid.NewGuid(), "TestEvent", true, null, null))).NextExpectedVersion); - } - } - - var tcpPort = _node.TcpEndPoint.Port; - var httpPort = _node.HttpEndPoint.Port; - await _node.Shutdown(keepDb: true); - - //Restart the node to ensure the read index stream info cache is empty - _node = new MiniNode(PathName, - tcpPort, httpPort, - memTableSize: 20, - hashCollisionReadLimit: 1, - indexBitnessVersion: EventStore.Core.Index.PTableVersions.IndexV4, - hash32bit: true, - streamExistenceFilterSize: 0); - await _node.Start(); - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(EventReadStatus.NoStream, (await store.ReadEventAsync(stream1, 0, true)).Status); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_stream_events_backward_with_hash_collision.cs b/src/EventStore.Core.Tests/ClientAPI/read_stream_events_backward_with_hash_collision.cs deleted file mode 100644 index 93a934927c..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_stream_events_backward_with_hash_collision.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Tests; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.Services.Storage.HashCollisions; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_stream_events_backward_with_hash_collision - : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.To(node, TcpType.Ssl); - } - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName, - memTableSize: 20, - hashCollisionReadLimit: 1, - indexBitnessVersion: EventStore.Core.Index.PTableVersions.IndexV4, - hash32bit: true, - streamExistenceFilterSize: 0); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - [Test] - public async Task should_return_stream_not_found() - { - const string stream1 = "account--696193173"; - const string stream2 = "LPN-FC002_LPK51001"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - //Write event to stream 1 - Assert.AreEqual(0, - (await store.AppendToStreamAsync(stream1, ExpectedVersion.NoStream, - new EventData(Guid.NewGuid(), "TestEvent", true, null, null))).NextExpectedVersion); - //Write 100 events to stream 2 which will have the same hash as stream 1. - for (int i = 0; i < 100; i++) - { - Assert.AreEqual(i, - (await store.AppendToStreamAsync(stream2, ExpectedVersion.Any, - new EventData(Guid.NewGuid(), "TestEvent", true, null, null))).NextExpectedVersion); - } - } - - var tcpPort = _node.TcpEndPoint.Port; - var httpPort = _node.HttpEndPoint.Port; - await _node.Shutdown(keepDb: true); - - //Restart the node to ensure the read index stream info cache is empty - _node = new MiniNode(PathName, - tcpPort, httpPort, - memTableSize: 20, - hashCollisionReadLimit: 1, - indexBitnessVersion: EventStore.Core.Index.PTableVersions.IndexV4, - hash32bit: true, - streamExistenceFilterSize: 0); - await _node.Start(); - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(SliceReadStatus.StreamNotFound, - (await store.ReadStreamEventsBackwardAsync(stream1, 0, 1, true)).Status); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_stream_events_forward_with_hash_collision.cs b/src/EventStore.Core.Tests/ClientAPI/read_stream_events_forward_with_hash_collision.cs deleted file mode 100644 index 57f63a0c93..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_stream_events_forward_with_hash_collision.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Tests; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.Services.Storage.HashCollisions; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_stream_events_forward_with_hash_collision : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.To(node, TcpType.Ssl); - } - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName, - memTableSize: 20, - hashCollisionReadLimit: 1, - indexBitnessVersion: EventStore.Core.Index.PTableVersions.IndexV4, - hash32bit: true, - streamExistenceFilterSize: 0); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - [Test] - public async Task should_return_stream_not_found() - { - const string stream1 = "account--696193173"; - const string stream2 = "LPN-FC002_LPK51001"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - //Write event to stream 1 - Assert.AreEqual(0, - (await store.AppendToStreamAsync(stream1, ExpectedVersion.NoStream, - new EventData(Guid.NewGuid(), "TestEvent", true, null, null))).NextExpectedVersion); - //Write 100 events to stream 2 which will have the same hash as stream 1. - for (int i = 0; i < 100; i++) - { - Assert.AreEqual(i, - (await store.AppendToStreamAsync(stream2, ExpectedVersion.Any, - new EventData(Guid.NewGuid(), "TestEvent", true, null, null))).NextExpectedVersion); - } - } - - var tcpPort = _node.TcpEndPoint.Port; - var httpPort = _node.HttpEndPoint.Port; - await _node.Shutdown(keepDb: true); - - //Restart the node to ensure the read index stream info cache is empty - _node = new MiniNode(PathName, - tcpPort, httpPort, - memTableSize: 20, - hashCollisionReadLimit: 1, - indexBitnessVersion: EventStore.Core.Index.PTableVersions.IndexV4, - hash32bit: true, - streamExistenceFilterSize: 0); - await _node.Start(); - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - Assert.AreEqual(SliceReadStatus.StreamNotFound, - (await store.ReadStreamEventsForwardAsync(stream1, 0, 1, true)).Status); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/read_stream_events_with_unresolved_linkto.cs b/src/EventStore.Core.Tests/ClientAPI/read_stream_events_with_unresolved_linkto.cs deleted file mode 100644 index a2e16fe74f..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/read_stream_events_with_unresolved_linkto.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.SystemData; -using EventStore.Core.Data; -using EventStore.Core.Services; -using EventStore.Core.Tests.ClientAPI.Helpers; -using NUnit.Framework; -using ExpectedVersion = EventStore.ClientAPI.ExpectedVersion; -using StreamMetadata = EventStore.ClientAPI.StreamMetadata; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class read_stream_events_with_unresolved_linkto : SpecificationWithMiniNode -{ - private EventData[] _testEvents; - - protected override async Task When() - { - await _conn.SetStreamMetadataAsync( - "$all", -1, StreamMetadata.Build().SetReadRole(SystemRoles.All), - new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword)); - - _testEvents = Enumerable.Range(0, 20).Select(x => TestEvent.NewTestEvent(x.ToString())).ToArray(); - await _conn.AppendToStreamAsync("stream", ExpectedVersion.NoStream, _testEvents); - await _conn.AppendToStreamAsync( - "links", ExpectedVersion.NoStream, - new EventData( - Guid.NewGuid(), EventStore.ClientAPI.Common.SystemEventTypes.LinkTo, false, - Encoding.UTF8.GetBytes("0@stream"), null)); - await _conn.DeleteStreamAsync("stream", ExpectedVersion.Any); - } - - [Test, Category("LongRunning")] - public async Task ensure_deleted_stream() - { - var res = await _conn.ReadStreamEventsForwardAsync("stream", 0, 100, false); - Assert.AreEqual(SliceReadStatus.StreamNotFound, res.Status); - Assert.AreEqual(0, res.Events.Length); - } - - [Test, Category("LongRunning")] - public async Task returns_unresolved_linkto() - { - var read = await _conn.ReadStreamEventsForwardAsync("links", 0, 1, true); - Assert.AreEqual(1, read.Events.Length); - Assert.IsNull(read.Events[0].Event); - Assert.IsNotNull(read.Events[0].Link); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/soft_delete.cs b/src/EventStore.Core.Tests/ClientAPI/soft_delete.cs deleted file mode 100644 index ac4ecf2629..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/soft_delete.cs +++ /dev/null @@ -1,385 +0,0 @@ -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Exceptions; -using EventStore.ClientAPI.Internal; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class soft_delete : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - private IEventStoreConnection _conn; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - - _conn = BuildConnection(_node); - await _conn.ConnectAsync(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - _conn.Close(); - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return EventStoreConnection.Create( - ConnectionSettings.Create().DisableServerCertificateValidation().Build(), - node.TcpEndPoint.ToESTcpUri()); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task soft_deleted_stream_returns_no_stream_and_no_events_on_read() - { - const string stream = "soft_deleted_stream_returns_no_stream_and_no_events_on_read"; - - Assert.AreEqual(1, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(), - TestEvent.NewTestEvent())).NextExpectedVersion); - await _conn.DeleteStreamAsync(stream, 1); - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.StreamNotFound, res.Status); - Assert.AreEqual(0, res.Events.Length); - Assert.AreEqual(1, res.LastEventNumber); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task soft_deleted_stream_allows_recreation_when_expver_any() - { - const string stream = "soft_deleted_stream_allows_recreation_when_expver_any"; - - Assert.AreEqual(1, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(), - TestEvent.NewTestEvent())).NextExpectedVersion); - await _conn.DeleteStreamAsync(stream, 1); - - var events = new[] { TestEvent.NewTestEvent(), TestEvent.NewTestEvent(), TestEvent.NewTestEvent() }; - Assert.AreEqual(4, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.Any, events)).NextExpectedVersion); - - await Task.Delay(50); //TODO: This is a workaround until github issue #1744 is fixed - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(4, res.LastEventNumber); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(events.Select(x => x.EventId), res.Events.Select(x => x.OriginalEvent.EventId)); - Assert.AreEqual(new[] { 2, 3, 4 }, res.Events.Select(x => x.OriginalEvent.EventNumber)); - - var meta = await _conn.GetStreamMetadataAsync(stream); - Assert.AreEqual(2, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(1, meta.MetastreamVersion); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task soft_deleted_stream_allows_recreation_when_expver_no_stream() - { - const string stream = "soft_deleted_stream_allows_recreation_when_expver_no_stream"; - - Assert.AreEqual(1, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(), - TestEvent.NewTestEvent())).NextExpectedVersion); - await _conn.DeleteStreamAsync(stream, 1); - - var events = new[] { TestEvent.NewTestEvent(), TestEvent.NewTestEvent(), TestEvent.NewTestEvent() }; - Assert.AreEqual(4, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, events)).NextExpectedVersion); - - await Task.Delay(50); //TODO: This is a workaround until github issue #1744 is fixed - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(4, res.LastEventNumber); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(events.Select(x => x.EventId), res.Events.Select(x => x.OriginalEvent.EventId)); - Assert.AreEqual(new[] { 2, 3, 4 }, res.Events.Select(x => x.OriginalEvent.EventNumber)); - - var meta = await _conn.GetStreamMetadataAsync(stream); - Assert.AreEqual(2, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(1, meta.MetastreamVersion); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task soft_deleted_stream_allows_recreation_when_expver_is_exact() - { - const string stream = "soft_deleted_stream_allows_recreation_when_expver_is_exact"; - - Assert.AreEqual(1, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(), - TestEvent.NewTestEvent())).NextExpectedVersion); - await _conn.DeleteStreamAsync(stream, 1); - - var events = new[] { TestEvent.NewTestEvent(), TestEvent.NewTestEvent(), TestEvent.NewTestEvent() }; - Assert.AreEqual(4, (await _conn.AppendToStreamAsync(stream, 1, events)).NextExpectedVersion); - - await Task.Delay(50); //TODO: This is a workaround until github issue #1744 is fixed - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(4, res.LastEventNumber); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(events.Select(x => x.EventId), res.Events.Select(x => x.OriginalEvent.EventId)); - Assert.AreEqual(new[] { 2, 3, 4 }, res.Events.Select(x => x.OriginalEvent.EventNumber)); - - var meta = await _conn.GetStreamMetadataAsync(stream); - Assert.AreEqual(2, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(1, meta.MetastreamVersion); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task soft_deleted_stream_when_recreated_preserves_metadata_except_truncatebefore() - { - const string stream = "soft_deleted_stream_when_recreated_preserves_metadata_except_truncatebefore"; - - Assert.AreEqual(1, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(), - TestEvent.NewTestEvent())).NextExpectedVersion); - - Assert.AreEqual(0, (await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(long.MaxValue) - .SetMaxCount(100) - .SetDeleteRole("some-role") - .SetCustomProperty("key1", true) - .SetCustomProperty("key2", 17) - .SetCustomProperty("key3", "some value"))).NextExpectedVersion); - - var events = new[] { TestEvent.NewTestEvent(), TestEvent.NewTestEvent(), TestEvent.NewTestEvent() }; - Assert.AreEqual(4, (await _conn.AppendToStreamAsync(stream, 1, events)).NextExpectedVersion); - await Task.Delay(50); //TODO: This is a workaround until github issue #1744 is fixed - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(4, res.LastEventNumber); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(events.Select(x => x.EventId), res.Events.Select(x => x.OriginalEvent.EventId)); - Assert.AreEqual(new[] { 2, 3, 4 }, res.Events.Select(x => x.OriginalEvent.EventNumber)); - - var meta = await _conn.GetStreamMetadataAsync(stream); - Assert.AreEqual(1, meta.MetastreamVersion); - Assert.AreEqual(2, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(100, meta.StreamMetadata.MaxCount); - Assert.AreEqual("some-role", meta.StreamMetadata.Acl.DeleteRole); - Assert.AreEqual(true, meta.StreamMetadata.GetValue("key1")); - Assert.AreEqual(17, meta.StreamMetadata.GetValue("key2")); - Assert.AreEqual("some value", meta.StreamMetadata.GetValue("key3")); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task soft_deleted_stream_can_be_hard_deleted() - { - const string stream = "soft_deleted_stream_can_be_deleted"; - - Assert.AreEqual(1, - actual: (await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(), - TestEvent.NewTestEvent())).NextExpectedVersion); - await _conn.DeleteStreamAsync(stream, 1); - await _conn.DeleteStreamAsync(stream, ExpectedVersion.Any, hardDelete: true); - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.StreamDeleted, res.Status); - var meta = await _conn.GetStreamMetadataAsync(stream); - Assert.AreEqual(true, meta.IsStreamDeleted); - - await AssertEx.ThrowsAsync(() => - _conn.AppendToStreamAsync(stream, ExpectedVersion.Any, TestEvent.NewTestEvent())); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task soft_deleted_stream_allows_recreation_only_for_first_write() - { - const string stream = "soft_deleted_stream_allows_recreation_only_for_first_write"; - - Assert.AreEqual(1, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(), - TestEvent.NewTestEvent())).NextExpectedVersion); - await _conn.DeleteStreamAsync(stream, 1); - - var events = new[] { TestEvent.NewTestEvent(), TestEvent.NewTestEvent(), TestEvent.NewTestEvent() }; - Assert.AreEqual(4, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, events)).NextExpectedVersion); - await Task.Delay(50); //TODO: This is a workaround until github issue #1744 is fixed - - await AssertEx.ThrowsAsync(() => - _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent())); - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(4, res.LastEventNumber); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(events.Select(x => x.EventId), res.Events.Select(x => x.OriginalEvent.EventId)); - Assert.AreEqual(new[] { 2, 3, 4 }, res.Events.Select(x => x.OriginalEvent.EventNumber)); - - var meta = await _conn.GetStreamMetadataAsync(stream); - Assert.AreEqual(2, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(1, meta.MetastreamVersion); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task soft_deleted_stream_appends_both_writes_when_expver_any() - { - const string stream = "soft_deleted_stream_appends_both_concurrent_writes_when_expver_any"; - - Assert.AreEqual(1, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(), - TestEvent.NewTestEvent())).NextExpectedVersion); - await _conn.DeleteStreamAsync(stream, 1); - - var events1 = new[] { TestEvent.NewTestEvent(), TestEvent.NewTestEvent(), TestEvent.NewTestEvent() }; - var events2 = new[] { TestEvent.NewTestEvent(), TestEvent.NewTestEvent() }; - Assert.AreEqual(4, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.Any, events1)).NextExpectedVersion); - await Task.Delay(50); //TODO: This is a workaround until github issue #1744 is fixed - - Assert.AreEqual(6, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.Any, events2)).NextExpectedVersion); - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(6, res.LastEventNumber); - Assert.AreEqual(5, res.Events.Length); - Assert.AreEqual(events1.Concat(events2).Select(x => x.EventId), - res.Events.Select(x => x.OriginalEvent.EventId)); - Assert.AreEqual(new[] { 2, 3, 4, 5, 6 }, res.Events.Select(x => x.OriginalEvent.EventNumber)); - - var meta = await _conn.GetStreamMetadataAsync(stream); - Assert.AreEqual(2, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(1, meta.MetastreamVersion); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task - setting_json_metadata_on_empty_soft_deleted_stream_recreates_stream_not_overriding_metadataAsync() - { - const string stream = - "setting_json_metadata_on_empty_soft_deleted_stream_recreates_stream_not_overriding_metadata"; - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.Any, StreamMetadata.Build() - .SetTruncateBefore(long.MaxValue)); - - Assert.AreEqual(1, (await _conn.SetStreamMetadataAsync(stream, 0, - StreamMetadata.Build().SetMaxCount(100) - .SetDeleteRole("some-role") - .SetCustomProperty("key1", true) - .SetCustomProperty("key2", 17) - .SetCustomProperty("key3", "some value"))).NextExpectedVersion); - - await Task.Delay(50); //TODO: This is a workaround until github issue #1744 is fixed - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.StreamNotFound, res.Status); - Assert.AreEqual(-1, res.LastEventNumber); - Assert.AreEqual(0, res.Events.Length); - - var meta = await _conn.GetStreamMetadataAsync(stream); - Assert.AreEqual(2, meta.MetastreamVersion); - Assert.AreEqual(0, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(100, meta.StreamMetadata.MaxCount); - Assert.AreEqual("some-role", meta.StreamMetadata.Acl.DeleteRole); - Assert.AreEqual(true, meta.StreamMetadata.GetValue("key1")); - Assert.AreEqual(17, meta.StreamMetadata.GetValue("key2")); - Assert.AreEqual("some value", meta.StreamMetadata.GetValue("key3")); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task - setting_json_metadata_on_nonempty_soft_deleted_stream_recreates_stream_not_overriding_metadataAsync() - { - const string stream = - "setting_json_metadata_on_nonempty_soft_deleted_stream_recreates_stream_not_overriding_metadata"; - - Assert.AreEqual(1, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(), - TestEvent.NewTestEvent())).NextExpectedVersion); - await _conn.DeleteStreamAsync(stream, 1, hardDelete: false); - - Assert.AreEqual(1, (await _conn.SetStreamMetadataAsync(stream, 0, - StreamMetadata.Build().SetMaxCount(100) - .SetDeleteRole("some-role") - .SetCustomProperty("key1", true) - .SetCustomProperty("key2", 17) - .SetCustomProperty("key3", "some value"))).NextExpectedVersion); - - await Task.Delay(50); //TODO: This is a workaround until github issue #1744 is fixed - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(1, res.LastEventNumber); - Assert.AreEqual(0, res.Events.Length); - - var meta = await _conn.GetStreamMetadataAsync(stream); - Assert.AreEqual(2, meta.MetastreamVersion); - Assert.AreEqual(2, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(100, meta.StreamMetadata.MaxCount); - Assert.AreEqual("some-role", meta.StreamMetadata.Acl.DeleteRole); - Assert.AreEqual(true, meta.StreamMetadata.GetValue("key1")); - Assert.AreEqual(17, meta.StreamMetadata.GetValue("key2")); - Assert.AreEqual("some value", meta.StreamMetadata.GetValue("key3")); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task - setting_nonjson_metadata_on_empty_soft_deleted_stream_recreates_stream_keeping_original_metadataAsync() - { - const string stream = - "setting_nonjson_metadata_on_empty_soft_deleted_stream_recreates_stream_overriding_metadata"; - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.Any, StreamMetadata.Build() - .SetTruncateBefore(long.MaxValue)); - - Assert.AreEqual(1, (await _conn.SetStreamMetadataAsync(stream, 0, new byte[256])).NextExpectedVersion); - - await Task.Delay(50); //TODO: This is a workaround until github issue #1744 is fixed - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.StreamNotFound, res.Status); - Assert.AreEqual(-1, res.LastEventNumber); - Assert.AreEqual(0, res.Events.Length); - - var meta = await _conn.GetStreamMetadataAsRawBytesAsync(stream); - Assert.AreEqual(1, meta.MetastreamVersion); - Assert.AreEqual(new byte[256], meta.StreamMetadata); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task - setting_nonjson_metadata_on_nonempty_soft_deleted_stream_recreates_stream_keeping_original_metadataAsync() - { - const string stream = - "setting_nonjson_metadata_on_nonempty_soft_deleted_stream_recreates_stream_overriding_metadata"; - - Assert.AreEqual(1, - (await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(), - TestEvent.NewTestEvent())).NextExpectedVersion); - await _conn.DeleteStreamAsync(stream, 1, hardDelete: false); - - Assert.AreEqual(1, (await _conn.SetStreamMetadataAsync(stream, 0, new byte[256])).NextExpectedVersion); - await Task.Delay(50); //TODO: This is a workaround until github issue #1744 is fixed - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(1, res.LastEventNumber); - Assert.AreEqual(2, res.Events.Length); - Assert.AreEqual(new[] { 0, 1 }, res.Events.Select(x => x.OriginalEventNumber).ToArray()); - - var meta = await _conn.GetStreamMetadataAsRawBytesAsync(stream); - Assert.AreEqual(1, meta.MetastreamVersion); - Assert.AreEqual(new byte[256], meta.StreamMetadata); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/subscribe_should.cs b/src/EventStore.Core.Tests/ClientAPI/subscribe_should.cs deleted file mode 100644 index 3bda338b71..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/subscribe_should.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class subscribe_should : SpecificationWithDirectoryPerTestFixture -{ - private const int Timeout = 10000; - - private MiniNode _node; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [Test, Category("LongRunning")] - public async Task be_able_to_subscribe_to_non_existing_stream_and_then_catch_new_event() - { - const string stream = - "subscribe_should_be_able_to_subscribe_to_non_existing_stream_and_then_catch_created_event"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var appeared = new CountdownEvent(1); - var dropped = new CountdownEvent(1); - - using (await store.SubscribeToStreamAsync(stream, false, (s, x) => - { - appeared.Signal(); - return; - }, (s, r, e) => dropped.Signal())) - { - await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()); - Assert.IsTrue(appeared.Wait(Timeout), "Appeared countdown event timed out."); - } - } - } - - [Test, Category("LongRunning")] - public async Task allow_multiple_subscriptions_to_same_stream() - { - const string stream = "subscribe_should_allow_multiple_subscriptions_to_same_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var appeared = new CountdownEvent(2); - var dropped = new CountdownEvent(2); - - using (await store.SubscribeToStreamAsync(stream, false, (s, x) => - { - appeared.Signal(); - return; - }, (s, r, e) => dropped.Signal())) - using (await store.SubscribeToStreamAsync(stream, false, (s, x) => - { - appeared.Signal(); - return; - }, (s, r, e) => dropped.Signal())) - { - await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()); - Assert.IsTrue(appeared.Wait(Timeout), "Appeared countdown event timed out."); - } - } - } - - [Test, Category("LongRunning")] - public async Task call_dropped_callback_after_unsubscribe_method_call() - { - const string stream = "subscribe_should_call_dropped_callback_after_unsubscribe_method_call"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var dropped = new CountdownEvent(1); - using (var subscription = await store.SubscribeToStreamAsync(stream, false, (s, x) => Task.CompletedTask, - (s, r, e) => dropped.Signal())) - { - subscription.Unsubscribe(); - } - - Assert.IsTrue(dropped.Wait(Timeout), "Dropped countdown event timed out."); - } - } - - [Test, Category("LongRunning")] - public async Task catch_deleted_events_as_well() - { - const string stream = "subscribe_should_catch_created_and_deleted_events_as_well"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var appeared = new CountdownEvent(1); - var dropped = new CountdownEvent(1); - using (await store.SubscribeToStreamAsync(stream, false, (s, x) => - { - appeared.Signal(); - return; - }, - (s, r, e) => dropped.Signal())) - { - await store.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - Assert.IsTrue(appeared.Wait(Timeout), "Appeared countdown event timed out."); - } - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/subscribe_to_all_catching_up_should.cs b/src/EventStore.Core.Tests/ClientAPI/subscribe_to_all_catching_up_should.cs deleted file mode 100644 index c8ffbb398a..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/subscribe_to_all_catching_up_should.cs +++ /dev/null @@ -1,325 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.SystemData; -using EventStore.Core.Services; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; -using ILogger = Serilog.ILogger; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning"), NonParallelizable] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class subscribe_to_all_catching_up_should : SpecificationWithDirectory -{ - private static readonly ILogger Log = Serilog.Log.ForContext>(); - private static readonly TimeSpan Timeout = TimeSpan.FromSeconds(60); - private const int LongRunningTimeout = 300000; - private static readonly TimeSpan StartupTimeout = TimeSpan.FromMinutes(5); - private static readonly TimeSpan ConnectionCloseTimeout = TimeSpan.FromSeconds(10); - - private MiniNode _node; - private IEventStoreConnection _conn; - - [SetUp] - public override async Task SetUp() - { - await base.SetUp(); - _node = new MiniNode(PathName); - await _node.Start(StartupTimeout); - await _node.WaitForTcpEndPoint().WithTimeout(TimeSpan.FromSeconds(60)); - - _conn = await TestConnectionLifecycle.ReconnectUntilReady( - () => BuildConnection(_node), - conn => conn.ReadAllEventsForwardAsync(Position.Start, 1, false, DefaultData.AdminCredentials), - StartupTimeout); - await _conn.SetStreamMetadataAsync("$all", -1, - StreamMetadata.Build().SetReadRole(SystemRoles.All), - new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword)); - } - - [TearDown] - public override async Task TearDown() - { - try - { - if (_conn != null) - { - await TestConnectionLifecycle.CloseConnectionAndWait(_conn, ConnectionCloseTimeout); - } - } - catch - { - if (_conn != null) - { - TestConnectionLifecycle.TryCloseConnection(_conn); - } - } - finally - { - TestConnectionLifecycle.DisposeIfNeeded(_conn); - } - - await _node.Shutdown(); - await base.TearDown(); - } - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public async Task call_dropped_callback_after_stop_method_call() - { - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var dropped = new CountdownEvent(1); - var subscription = store.SubscribeToAllFrom(null, - CatchUpSubscriptionSettings.Default, - (x, y) => Task.CompletedTask, - _ => Log.Information("Live processing started."), - (x, y, z) => dropped.Signal()); - - Assert.IsFalse(dropped.Wait(0)); - subscription.Stop(Timeout); - Assert.IsTrue(dropped.Wait(Timeout)); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public async Task call_dropped_callback_when_an_error_occurs_while_processing_an_event() - { - const string stream = "call_dropped_callback_when_an_error_occurs_while_processing_an_event"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - await store.AppendToStreamAsync(stream, ExpectedVersion.Any, - new EventData(Guid.NewGuid(), "event", false, new byte[3], null)); - - var dropped = new CountdownEvent(1); - store.SubscribeToAllFrom(null, CatchUpSubscriptionSettings.Default, - (x, y) => { throw new Exception("Error"); }, - _ => Log.Information("Live processing started."), - (x, y, z) => dropped.Signal()); - Assert.IsTrue(dropped.Wait(Timeout)); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public async Task be_able_to_subscribe_to_empty_db() - { - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var appeared = new ManualResetEventSlim(false); - var dropped = new CountdownEvent(1); - - var subscription = store.SubscribeToAllFrom(null, - CatchUpSubscriptionSettings.Default, - (_, x) => - { - if (!SystemStreams.IsSystemStream(x.OriginalEvent.EventStreamId)) - { - appeared.Set(); - } - - return Task.CompletedTask; - }, - _ => Log.Information("Live processing started."), - (_, __, ___) => dropped.Signal()); - - await Task.Delay(100); // give time for first pull phase - await store.SubscribeToAllAsync(false, (s, x) => Task.CompletedTask, (s, r, e) => { }); - await Task.Delay(100); - - Assert.IsFalse(appeared.Wait(0), "Some event appeared."); - Assert.IsFalse(dropped.Wait(0), "Subscription was dropped prematurely."); - subscription.Stop(Timeout); - Assert.IsTrue(dropped.Wait(Timeout)); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public async Task read_all_existing_events_and_keep_listening_to_new_ones() - { - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = new List(); - var appeared = new CountdownEvent(20); - var dropped = new CountdownEvent(1); - - for (int i = 0; i < 10; ++i) - { - await store.AppendToStreamAsync("stream-" + i.ToString(), -1, - new EventData(Guid.NewGuid(), "et-" + i.ToString(), false, new byte[3], null)); - } - - var subscription = store.SubscribeToAllFrom(null, - CatchUpSubscriptionSettings.Default, - (x, y) => - { - if (!SystemStreams.IsSystemStream(y.OriginalEvent.EventStreamId)) - { - events.Add(y); - appeared.Signal(); - } - - return Task.CompletedTask; - }, - _ => Log.Information("Live processing started."), - (x, y, z) => dropped.Signal()); - for (int i = 10; i < 20; ++i) - { - await store.AppendToStreamAsync("stream-" + i.ToString(), -1, - new EventData(Guid.NewGuid(), "et-" + i.ToString(), false, new byte[3], null)); - } - - if (!appeared.Wait(Timeout)) - { - Assert.IsFalse(dropped.Wait(0), "Subscription was dropped prematurely."); - Assert.Fail("Could not wait for all events."); - } - - Assert.AreEqual(20, events.Count); - for (int i = 0; i < 20; ++i) - { - Assert.AreEqual("et-" + i.ToString(), events[i].OriginalEvent.EventType); - } - - Assert.IsFalse(dropped.Wait(0)); - subscription.Stop(Timeout); - Assert.IsTrue(dropped.Wait(Timeout)); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public async Task filter_events_and_keep_listening_to_new_ones() - { - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = new List(); - var appeared = new CountdownEvent(10); - var dropped = new CountdownEvent(1); - - for (int i = 0; i < 10; ++i) - { - await store.AppendToStreamAsync("stream-" + i.ToString(), -1, - new EventData(Guid.NewGuid(), "et-" + i.ToString(), false, new byte[3], null)); - } - - var allSlice = await store.ReadAllEventsForwardAsync(Position.Start, 100, false); - var lastEvent = allSlice.Events.Last(); - - var subscription = store.SubscribeToAllFrom(lastEvent.OriginalPosition, - CatchUpSubscriptionSettings.Default, - (x, y) => - { - if (SystemStreams.IsSystemStream(y.Event.EventStreamId)) - { - return Task.CompletedTask; - } - events.Add(y); - appeared.Signal(); - return Task.CompletedTask; - }, - _ => Log.Information("Live processing started."), - (x, y, z) => - { - Log.Information("Subscription dropped: {0}, {1}.", y, z); - dropped.Signal(); - }); - - for (int i = 10; i < 20; ++i) - { - await store.AppendToStreamAsync("stream-" + i.ToString(), -1, - new EventData(Guid.NewGuid(), "et-" + i.ToString(), false, new byte[3], null)); - } - - Log.Information("Waiting for events..."); - if (!appeared.Wait(Timeout)) - { - Assert.IsFalse(dropped.Wait(0), "Subscription was dropped prematurely."); - Assert.Fail("Could not wait for all events."); - } - - Log.Information("Events appeared..."); - Assert.AreEqual(10, events.Count); - for (int i = 0; i < 10; ++i) - { - Assert.AreEqual("et-" + (10 + i).ToString(), events[i].OriginalEvent.EventType); - } - - Assert.IsFalse(dropped.Wait(0)); - subscription.Stop(Timeout); - Assert.IsTrue(dropped.Wait(Timeout)); - - Assert.AreEqual(events.Last().OriginalPosition, subscription.LastProcessedPosition); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public async Task filter_events_and_work_if_nothing_was_written_after_subscription() - { - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = new List(); - var appeared = new CountdownEvent(1); - var dropped = new CountdownEvent(1); - - for (int i = 0; i < 10; ++i) - { - await store.AppendToStreamAsync("stream-" + i.ToString(), -1, - new EventData(Guid.NewGuid(), "et-" + i.ToString(), false, new byte[3], null)); - } - - var allSlice = await store.ReadAllEventsForwardAsync(Position.Start, 100, false); - var lastEvent = allSlice.Events[allSlice.Events.Length - 2]; - - var subscription = store.SubscribeToAllFrom(lastEvent.OriginalPosition, - CatchUpSubscriptionSettings.Default, - (x, y) => - { - events.Add(y); - appeared.Signal(); - return Task.CompletedTask; - }, - _ => Log.Information("Live processing started."), - (x, y, z) => - { - Log.Information("Subscription dropped: {0}, {1}.", y, z); - dropped.Signal(); - }); - - Log.Information("Waiting for events..."); - if (!appeared.Wait(Timeout)) - { - Assert.IsFalse(dropped.Wait(0), "Subscription was dropped prematurely."); - Assert.Fail("Could not wait for all events."); - } - - Log.Information("Events appeared..."); - Assert.AreEqual(1, events.Count); - Assert.AreEqual("et-9", events[0].OriginalEvent.EventType); - - Assert.IsFalse(dropped.Wait(0)); - subscription.Stop(Timeout); - Assert.IsTrue(dropped.Wait(Timeout)); - - Assert.AreEqual(events.Last().OriginalPosition, subscription.LastProcessedPosition); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/subscribe_to_all_filtered_should.cs b/src/EventStore.Core.Tests/ClientAPI/subscribe_to_all_filtered_should.cs deleted file mode 100644 index 7ebcb15d99..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/subscribe_to_all_filtered_should.cs +++ /dev/null @@ -1,388 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.SystemData; -using EventStore.Core.Services; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning"), NonParallelizable] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class subscribe_to_all_filtered_should : SpecificationWithDirectory -{ - private const int Timeout = 10000; - private const int LongRunningTimeout = 600000; - private static readonly TimeSpan StartupTimeout = TimeSpan.FromMinutes(10); - private static readonly TimeSpan ConnectionCloseTimeout = TimeSpan.FromSeconds(10); - - private MiniNode _node; - private IEventStoreConnection _conn; - private List _testEvents; - private List _fakeSystemEvents; - - [SetUp] - public override async Task SetUp() - { - await base.SetUp(); - _node = new MiniNode(PathName); - await _node.Start(StartupTimeout); - await _node.WaitForTcpEndPoint().WithTimeout(TimeSpan.FromSeconds(60)); - - _conn = await TestConnectionLifecycle.ReconnectUntilReady( - () => BuildConnection(_node), - conn => conn.ReadAllEventsForwardAsync(Position.Start, 1, false, DefaultData.AdminCredentials), - StartupTimeout); - await _conn.SetStreamMetadataAsync("$all", -1, - StreamMetadata.Build().SetReadRole(SystemRoles.All), - new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword)); - - _testEvents = Enumerable - .Range(0, 5) - .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "AEvent")) - .ToList(); - - _testEvents.AddRange( - Enumerable - .Range(0, 5) - .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "BEvent")).ToList()); - - _fakeSystemEvents = Enumerable - .Range(0, 5) - .Select(x => TestEvent.NewTestEvent(x.ToString(), eventName: "$systemEvent")) - .ToList(); - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public async Task only_return_events_with_a_given_stream_prefix() - { - var filter = Filter.StreamId.Prefix("stream-a"); - var foundEvents = new List(); - var store = await CreateStoreConnection(); - try - { - var appeared = CreateAppearedSignal(); - var subscription = await store.FilteredSubscribeToAllAsync(false, filter, (s, e) => - { - foundEvents.Add(e); - if (foundEvents.Count == 5) - { - appeared.TrySetResult(true); - } - return Task.CompletedTask; - }, (s, p) => Task.CompletedTask, 100, CreateDropHandler(appeared)); - try - { - await _conn.AppendToStreamAsync("stream-b", ExpectedVersion.NoStream, _testEvents.EvenEvents()); - await _conn.AppendToStreamAsync("stream-a", ExpectedVersion.NoStream, _testEvents.OddEvents()); - - await appeared.Task.WithTimeout(Timeout); - - Assert.True(foundEvents.All(e => e.Event.EventStreamId == "stream-a")); - } - finally - { - StopSubscription(subscription); - } - } - finally - { - await CloseConnection(store); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public async Task only_return_events_with_a_given_event_prefix() - { - var filter = Filter.EventType.Prefix("AE"); - var foundEvents = new List(); - var store = await CreateStoreConnection(); - try - { - var appeared = CreateAppearedSignal(); - var subscription = await store.FilteredSubscribeToAllAsync(false, filter, (s, e) => - { - if (e.OriginalStreamId == SystemStreams.EventTypesStream) - { - return Task.CompletedTask; - } - - foundEvents.Add(e); - if (foundEvents.Count == 5) - { - appeared.TrySetResult(true); - } - return Task.CompletedTask; - }, (s, p) => Task.CompletedTask, 100, CreateDropHandler(appeared)); - try - { - await _conn.AppendToStreamAsync("stream-b", ExpectedVersion.NoStream, _testEvents.EvenEvents()); - await _conn.AppendToStreamAsync("stream-a", ExpectedVersion.NoStream, _testEvents.OddEvents()); - - await appeared.Task.WithTimeout(Timeout); - - Assert.True(foundEvents.All(e => e.Event.EventType == "AEvent")); - } - finally - { - StopSubscription(subscription); - } - } - finally - { - await CloseConnection(store); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public async Task only_return_events_that_satisfy_a_given_stream_regex() - { - var filter = Filter.StreamId.Regex(new Regex(@"^.*eam-b.*$")); - var foundEvents = new List(); - var store = await CreateStoreConnection(); - try - { - var appeared = CreateAppearedSignal(); - var subscription = await store.FilteredSubscribeToAllAsync(false, filter, (s, e) => - { - foundEvents.Add(e); - if (foundEvents.Count == 5) - { - appeared.TrySetResult(true); - } - return Task.CompletedTask; - }, (s, p) => Task.CompletedTask, 100, CreateDropHandler(appeared)); - try - { - await _conn.AppendToStreamAsync("stream-a", ExpectedVersion.NoStream, _testEvents.EvenEvents()); - await _conn.AppendToStreamAsync("stream-b", ExpectedVersion.NoStream, _testEvents.OddEvents()); - - await appeared.Task.WithTimeout(Timeout); - - Assert.True(foundEvents.All(e => e.Event.EventStreamId == "stream-b")); - } - finally - { - StopSubscription(subscription); - } - } - finally - { - await CloseConnection(store); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public async Task only_return_events_that_satisfy_a_given_event_regex() - { - var filter = Filter.EventType.Regex(new Regex(@"^.*BEv.*$")); - var foundEvents = new ConcurrentBag(); - var store = await CreateStoreConnection(); - try - { - var appeared = CreateAppearedSignal(); - var subscription = await store.FilteredSubscribeToAllAsync(false, filter, (s, e) => - { - foundEvents.Add(e); - if (foundEvents.Count == 5) - { - appeared.TrySetResult(true); - } - return Task.CompletedTask; - }, (s, p) => Task.CompletedTask, 100, CreateDropHandler(appeared)); - try - { - await _conn.AppendToStreamAsync("stream-a", ExpectedVersion.NoStream, _testEvents.EvenEvents()); - await _conn.AppendToStreamAsync("stream-b", ExpectedVersion.NoStream, _testEvents.OddEvents()); - - await appeared.Task.WithTimeout(Timeout); - - Assert.True(foundEvents.All(e => e.Event.EventType == "BEvent")); - } - finally - { - StopSubscription(subscription); - } - } - finally - { - await CloseConnection(store); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public async Task only_return_events_that_are_not_system_events() - { - var filter = Filter.ExcludeSystemEvents; - var foundEvents = new List(); - var store = await CreateStoreConnection(); - try - { - var appeared = CreateAppearedSignal(); - var subscription = await store.FilteredSubscribeToAllAsync(false, filter, (s, e) => - { - foundEvents.Add(e); - if (foundEvents.Count == 5) - { - appeared.TrySetResult(true); - } - return Task.CompletedTask; - }, (s, p) => Task.CompletedTask, 100, CreateDropHandler(appeared)); - try - { - await _conn.AppendToStreamAsync("stream-a", ExpectedVersion.NoStream, _fakeSystemEvents); - await _conn.AppendToStreamAsync("stream-b", ExpectedVersion.NoStream, _testEvents.EvenEvents()); - - await appeared.Task.WithTimeout(Timeout); - - Assert.True(foundEvents.All(e => !e.Event.EventType.StartsWith("$"))); - } - finally - { - StopSubscription(subscription); - } - } - finally - { - await CloseConnection(store); - } - } - - [Test, Category("LongRunning")] - public async Task throw_an_exception_if_interval_is_negative() - { - var filter = Filter.ExcludeSystemEvents; - var store = await CreateStoreConnection(); - try - { - Assert.Throws(() => - { - store.FilteredSubscribeToAllAsync( - false, - filter, - (s, e) => Task.CompletedTask, - (s, p) => Task.CompletedTask, 0).Wait(); - }); - } - finally - { - await CloseConnection(store); - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public async Task calls_checkpoint_reached_according_to_checkpoint_message_count() - { - var filter = Filter.ExcludeSystemEvents; - const int expectedEvents = 10; - const int expectedCheckpoints = 5; - var store = await CreateStoreConnection(); - - void TryComplete(TaskCompletionSource appeared, List eventsSeen, int checkpointsSeen) - { - if (checkpointsSeen >= expectedCheckpoints && eventsSeen.Count >= expectedEvents) - { - appeared.TrySetResult(true); - } - } - - try - { - var appeared = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - var eventsSeen = new List(); - var checkpointsSeen = 0; - - var subscription = await store.FilteredSubscribeToAllAsync(false, - filter, - (s, e) => - { - eventsSeen.Add(e); - TryComplete(appeared, eventsSeen, checkpointsSeen); - return Task.CompletedTask; - }, - (s, p) => - { - checkpointsSeen++; - TryComplete(appeared, eventsSeen, checkpointsSeen); - return Task.CompletedTask; - }, - checkpointInterval: 2, - CreateDropHandler(appeared)); - try - { - await _conn.AppendToStreamAsync("stream-a", ExpectedVersion.NoStream, _testEvents); - - await appeared.Task.WithTimeout(Timeout); - - Assert.AreEqual(expectedCheckpoints * 2 /*considered events*/, eventsSeen.Count); - Assert.True(eventsSeen.All(x => x.Event.EventStreamId == "stream-a")); - } - finally - { - StopSubscription(subscription); - } - } - finally - { - await CloseConnection(store); - } - } - - [TearDown] - public override async Task TearDown() - { - await CloseConnection(_conn); - await _node.Shutdown(); - await base.TearDown(); - } - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - private Task CreateStoreConnection() => - TestConnectionLifecycle.ReconnectUntilReady( - () => BuildConnection(_node), - connection => connection.ReadAllEventsForwardAsync(Position.Start, 1, false, DefaultData.AdminCredentials), - StartupTimeout); - - private static TaskCompletionSource CreateAppearedSignal() => - new(TaskCreationOptions.RunContinuationsAsynchronously); - - private static Action CreateDropHandler( - TaskCompletionSource appeared) => - (_, reason, ex) => appeared.TrySetException(ex ?? new InvalidOperationException($"Subscription dropped: {reason}")); - - private static async Task CloseConnection(IEventStoreConnection connection) - { - try - { - await TestConnectionLifecycle.CloseConnectionAndWait(connection, ConnectionCloseTimeout); - } - catch - { - TestConnectionLifecycle.TryCloseConnection(connection); - } - - TestConnectionLifecycle.DisposeIfNeeded(connection); - } - - private static void StopSubscription(EventStoreSubscription subscription) - { - try - { - subscription.Dispose(); - } - catch - { - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/subscribe_to_all_should.cs b/src/EventStore.Core.Tests/ClientAPI/subscribe_to_all_should.cs deleted file mode 100644 index 811012e89f..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/subscribe_to_all_should.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.SystemData; -using EventStore.Core.Services; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class subscribe_to_all_should : SpecificationWithDirectory -{ - private const int Timeout = 10000; - private const int LongRunningTimeout = 120000; - - private MiniNode _node; - - [SetUp] - public override async Task SetUp() - { - await base.SetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - - using (var connection = BuildConnection(_node)) - { - await connection.ConnectAsync(); - await connection.SetStreamMetadataAsync("$all", -1, - StreamMetadata.Build().SetReadRole(SystemRoles.All), - new UserCredentials(SystemUsers.Admin, SystemUsers.DefaultAdminPassword)); - } - } - - [TearDown] - public override async Task TearDown() - { - await _node.Shutdown(); - await base.TearDown(); - } - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [Test, Category("LongRunning")] - public async Task allow_multiple_subscriptions() - { - const string stream = "subscribe_to_all_should_allow_multiple_subscriptions"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var appeared = new CountdownEvent(2); - var dropped = new CountdownEvent(2); - - using (await store.SubscribeToAllAsync(false, (s, x) => - { - appeared.Signal(); - return; - }, (s, r, e) => dropped.Signal())) - using (await store.SubscribeToAllAsync(false, (s, x) => - { - appeared.Signal(); - return; - }, (s, r, e) => dropped.Signal())) - { - var create = - await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()); - - Assert.IsTrue(appeared.Wait(Timeout), "Appeared countdown event timed out."); - } - } - } - - [Test, Category("LongRunning"), Timeout(LongRunningTimeout)] - public async Task catch_deleted_events_as_well() - { - const string stream = "subscribe_to_all_should_catch_created_and_deleted_events_as_well"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var appeared = new CountdownEvent(1); - var dropped = new CountdownEvent(1); - - var completed = false; - var subscription = await store.SubscribeToAllAsync(false, (s, x) => - { - appeared.Signal(); - return Task.CompletedTask; - }, - (s, r, e) => dropped.Signal()); - - try - { - await store.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - - Assert.IsTrue(appeared.Wait(Timeout), "Appeared countdown event didn't fire in time."); - completed = true; - } - finally - { - subscription.Unsubscribe(); - - if (completed) - { - Assert.IsTrue(dropped.Wait(Timeout), "Dropped countdown event timed out."); - } - else - { - dropped.Wait(Timeout); - } - } - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/subscribe_to_stream_catching_up_should.cs b/src/EventStore.Core.Tests/ClientAPI/subscribe_to_stream_catching_up_should.cs deleted file mode 100644 index 478d459d8b..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/subscribe_to_stream_catching_up_should.cs +++ /dev/null @@ -1,361 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; -using ILogger = Serilog.ILogger; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class subscribe_to_stream_catching_up_should : SpecificationWithDirectoryPerTestFixture -{ - private static readonly ILogger Log = - Serilog.Log.ForContext>(); - - private static readonly TimeSpan Timeout = TimeSpan.FromSeconds(500); - - private MiniNode _node; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - virtual protected IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [Test, Category("LongRunning")] - public async Task be_able_to_subscribe_to_non_existing_stream() - { - const string stream = "be_able_to_subscribe_to_non_existing_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var appeared = new ManualResetEventSlim(false); - var dropped = new CountdownEvent(1); - - var subscription = store.SubscribeToStreamFrom(stream, - null, - CatchUpSubscriptionSettings.Default, - (_, x) => - { - appeared.Set(); - return Task.CompletedTask; - }, - _ => Log.Information("Live processing started."), - (_, __, ___) => dropped.Signal()); - - await Task.Delay(100); // give time for first pull phase - await store.SubscribeToStreamAsync(stream, false, (s, x) => Task.CompletedTask, (s, r, e) => { }); - await Task.Delay(100); - Assert.IsFalse(appeared.Wait(0), "Some event appeared."); - Assert.IsFalse(dropped.Wait(0), "Subscription was dropped prematurely."); - subscription.Stop(Timeout); - Assert.IsTrue(dropped.Wait(Timeout)); - } - } - - [Test, Category("LongRunning")] - public async Task be_able_to_subscribe_to_non_existing_stream_and_then_catch_event() - { - const string stream = "be_able_to_subscribe_to_non_existing_stream_and_then_catch_event"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var appeared = new CountdownEvent(1); - var dropped = new CountdownEvent(1); - - var subscription = store.SubscribeToStreamFrom(stream, - null, - CatchUpSubscriptionSettings.Default, - (_, x) => - { - appeared.Signal(); - return Task.CompletedTask; - }, - _ => Log.Information("Live processing started."), - (_, __, ___) => dropped.Signal()); - - await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()); - - if (!appeared.Wait(Timeout)) - { - Assert.IsFalse(dropped.Wait(0), "Subscription was dropped prematurely."); - Assert.Fail("Appeared countdown event timed out."); - } - - Assert.IsFalse(dropped.Wait(0)); - subscription.Stop(Timeout); - Assert.IsTrue(dropped.Wait(Timeout)); - } - } - - [Test, Category("LongRunning")] - public async Task allow_multiple_subscriptions_to_same_stream() - { - const string stream = "allow_multiple_subscriptions_to_same_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var appeared = new CountdownEvent(2); - var dropped1 = new ManualResetEventSlim(false); - var dropped2 = new ManualResetEventSlim(false); - - var sub1 = store.SubscribeToStreamFrom(stream, - null, - CatchUpSubscriptionSettings.Default, - (_, e) => - { - appeared.Signal(); - return Task.CompletedTask; - }, - _ => Log.Information("Live processing started."), - (x, y, z) => dropped1.Set()); - var sub2 = store.SubscribeToStreamFrom(stream, - null, - CatchUpSubscriptionSettings.Default, - (_, e) => - { - appeared.Signal(); - return Task.CompletedTask; - }, - _ => Log.Information("Live processing started."), - (x, y, z) => dropped2.Set()); - - await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()); - - if (!appeared.Wait(Timeout)) - { - Assert.IsFalse(dropped1.Wait(0), "Subscription1 was dropped prematurely."); - Assert.IsFalse(dropped2.Wait(0), "Subscription2 was dropped prematurely."); - Assert.Fail("Could not wait for all events."); - } - - Assert.IsFalse(dropped1.Wait(0)); - sub1.Stop(Timeout); - Assert.IsTrue(dropped1.Wait(Timeout)); - - Assert.IsFalse(dropped2.Wait(0)); - sub2.Stop(Timeout); - Assert.IsTrue(dropped2.Wait(Timeout)); - } - } - - [Test, Category("LongRunning")] - public async Task call_dropped_callback_after_stop_method_call() - { - const string stream = "call_dropped_callback_after_stop_method_call"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var dropped = new CountdownEvent(1); - var subscription = store.SubscribeToStreamFrom(stream, - null, - CatchUpSubscriptionSettings.Default, - (x, y) => Task.CompletedTask, - _ => Log.Information("Live processing started."), - (x, y, z) => dropped.Signal()); - Assert.IsFalse(dropped.Wait(0)); - subscription.Stop(Timeout); - Assert.IsTrue(dropped.Wait(Timeout)); - } - } - - [Test, Category("LongRunning")] - public async Task call_dropped_callback_when_an_error_occurs_while_processing_an_event() - { - const string stream = "call_dropped_callback_when_an_error_occurs_while_processing_an_event"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - await store.AppendToStreamAsync(stream, ExpectedVersion.Any, - new EventData(Guid.NewGuid(), "event", false, new byte[3], null)); - - var dropped = new CountdownEvent(1); - store.SubscribeToStreamFrom(stream, null, - CatchUpSubscriptionSettings.Default, - (x, y) => { throw new Exception("Error"); }, - _ => Log.Information("Live processing started."), - (x, y, z) => dropped.Signal()); - Assert.IsTrue(dropped.Wait(Timeout)); - } - } - - [Test, Category("LongRunning")] - public async Task read_all_existing_events_and_keep_listening_to_new_ones() - { - const string stream = "read_all_existing_events_and_keep_listening_to_new_ones"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = new List(); - var appeared = new CountdownEvent(20); // events - var dropped = new CountdownEvent(1); - - for (int i = 0; i < 10; ++i) - { - await store.AppendToStreamAsync(stream, i - 1, - new EventData(Guid.NewGuid(), "et-" + i.ToString(), false, new byte[3], null)); - } - - var subscription = store.SubscribeToStreamFrom(stream, - null, - CatchUpSubscriptionSettings.Default, - (x, y) => - { - events.Add(y); - appeared.Signal(); - return Task.CompletedTask; - }, - _ => Log.Information("Live processing started."), - (x, y, z) => dropped.Signal()); - for (int i = 10; i < 20; ++i) - { - await store.AppendToStreamAsync(stream, i - 1, - new EventData(Guid.NewGuid(), "et-" + i.ToString(), false, new byte[3], null)); - } - - if (!appeared.Wait(Timeout)) - { - Assert.IsFalse(dropped.Wait(0), "Subscription was dropped prematurely."); - Assert.Fail("Could not wait for all events."); - } - - Assert.AreEqual(20, events.Count); - for (int i = 0; i < 20; ++i) - { - Assert.AreEqual("et-" + i.ToString(), events[i].OriginalEvent.EventType); - } - - Assert.IsFalse(dropped.Wait(0)); - subscription.Stop(Timeout); - Assert.IsTrue(dropped.Wait(Timeout)); - } - } - - [Test, Category("LongRunning")] - public async Task filter_events_and_keep_listening_to_new_ones() - { - const string stream = "filter_events_and_keep_listening_to_new_ones"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = new List(); - var appeared = new CountdownEvent(20); // skip first 10 events - var dropped = new CountdownEvent(1); - - for (int i = 0; i < 20; ++i) - { - await store.AppendToStreamAsync(stream, i - 1, - new EventData(Guid.NewGuid(), "et-" + i.ToString(), false, new byte[3], null)); - } - - var subscription = store.SubscribeToStreamFrom(stream, - 9, - CatchUpSubscriptionSettings.Default, - (x, y) => - { - events.Add(y); - appeared.Signal(); - return Task.CompletedTask; - }, - _ => Log.Information("Live processing started."), - (x, y, z) => dropped.Signal()); - for (int i = 20; i < 30; ++i) - { - await store.AppendToStreamAsync(stream, i - 1, - new EventData(Guid.NewGuid(), "et-" + i.ToString(), false, new byte[3], null)); - } - - if (!appeared.Wait(Timeout)) - { - Assert.IsFalse(dropped.Wait(0), "Subscription was dropped prematurely."); - Assert.Fail("Could not wait for all events."); - } - - Assert.AreEqual(20, events.Count); - for (int i = 0; i < 20; ++i) - { - Assert.AreEqual("et-" + (i + 10).ToString(), events[i].OriginalEvent.EventType); - } - - Assert.IsFalse(dropped.Wait(0)); - subscription.Stop(Timeout); - Assert.IsTrue(dropped.Wait(Timeout)); - - Assert.AreEqual(events.Last().OriginalEventNumber, subscription.LastProcessedEventNumber); - - subscription.Stop(TimeSpan.FromSeconds(0)); - } - } - - [Test, Category("LongRunning")] - public async Task filter_events_and_work_if_nothing_was_written_after_subscription() - { - const string stream = "filter_events_and_work_if_nothing_was_written_after_subscription"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var events = new List(); - var appeared = new CountdownEvent(10); - var dropped = new CountdownEvent(1); - - for (int i = 0; i < 20; ++i) - { - await store.AppendToStreamAsync(stream, i - 1, - new EventData(Guid.NewGuid(), "et-" + i.ToString(), false, new byte[3], null)); - } - - var subscription = store.SubscribeToStreamFrom(stream, - 9, - CatchUpSubscriptionSettings.Default, - (x, y) => - { - events.Add(y); - appeared.Signal(); - return Task.CompletedTask; - }, - _ => Log.Information("Live processing started."), - (x, y, z) => dropped.Signal()); - if (!appeared.Wait(Timeout)) - { - Assert.IsFalse(dropped.Wait(0), "Subscription was dropped prematurely."); - Assert.Fail("Could not wait for all events."); - } - - Assert.AreEqual(10, events.Count); - for (int i = 0; i < 10; ++i) - { - Assert.AreEqual("et-" + (i + 10).ToString(), events[i].OriginalEvent.EventType); - } - - Assert.IsFalse(dropped.Wait(0)); - subscription.Stop(Timeout); - Assert.IsTrue(dropped.Wait(Timeout)); - - Assert.AreEqual(events.Last().OriginalEventNumber, subscription.LastProcessedEventNumber); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/transaction.cs b/src/EventStore.Core.Tests/ClientAPI/transaction.cs deleted file mode 100644 index c64e37f12f..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/transaction.cs +++ /dev/null @@ -1,282 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Exceptions; -using EventStore.Common.Utils; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class Transaction : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [Test] - [Category("Network")] - public async Task should_start_on_non_existing_stream_with_correct_exp_ver_and_create_stream_on_commit() - { - const string stream = - "should_start_on_non_existing_stream_with_correct_exp_ver_and_create_stream_on_commit"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - using (var transaction = await store.StartTransactionAsync(stream, ExpectedVersion.NoStream)) - { - await transaction.WriteAsync(TestEvent.NewTestEvent()); - Assert.AreEqual(0, (await transaction.CommitAsync()).NextExpectedVersion); - } - } - } - - [Test] - [Category("Network")] - public async Task should_start_on_non_existing_stream_with_exp_ver_any_and_create_stream_on_commit() - { - const string stream = "should_start_on_non_existing_stream_with_exp_ver_any_and_create_stream_on_commit"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - using (var transaction = await store.StartTransactionAsync(stream, ExpectedVersion.Any)) - { - await transaction.WriteAsync(TestEvent.NewTestEvent()); - Assert.AreEqual(0, (await transaction.CommitAsync()).NextExpectedVersion); - } - } - } - - [Test] - [Category("Network")] - public async Task should_fail_to_commit_non_existing_stream_with_wrong_exp_ver() - { - const string stream = "should_fail_to_commit_non_existing_stream_with_wrong_exp_ver"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - using (var transaction = await store.StartTransactionAsync(stream, 1)) - { - await transaction.WriteAsync(TestEvent.NewTestEvent()); - await AssertEx.ThrowsAsync(() => transaction.CommitAsync()); - } - } - } - - [Test] - [Category("Network")] - public async Task should_do_nothing_if_commits_no_events_to_empty_stream() - { - const string stream = "should_do_nothing_if_commits_no_events_to_empty_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - using (var transaction = await store.StartTransactionAsync(stream, ExpectedVersion.NoStream)) - { - Assert.AreEqual(-1, (await transaction.CommitAsync()).NextExpectedVersion); - } - - var result = await store.ReadStreamEventsForwardAsync(stream, 0, 1, resolveLinkTos: false); - Assert.That(result.Events.Length, Is.EqualTo(0)); - } - } - - [Test, Category("Network")] - public async Task should_do_nothing_if_transactionally_writing_no_events_to_empty_stream() - { - const string stream = "should_do_nothing_if_transactionally_writing_no_events_to_empty_stream"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - using (var transaction = await store.StartTransactionAsync(stream, ExpectedVersion.NoStream)) - { - await transaction.WriteAsync(); - Assert.AreEqual(-1, (await transaction.CommitAsync()).NextExpectedVersion); - } - - var result = await store.ReadStreamEventsForwardAsync(stream, 0, 1, resolveLinkTos: false); - Assert.That(result.Events.Length, Is.EqualTo(0)); - } - } - - [Test] - [Category("Network")] - public async Task should_validate_expectations_on_commit() - { - const string stream = "should_validate_expectations_on_commit"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - using (var transaction = await store.StartTransactionAsync(stream, 100500)) - { - await transaction.WriteAsync(TestEvent.NewTestEvent()); - await AssertEx.ThrowsAsync(() => transaction.CommitAsync()); - } - } - } - - [Test] - [Category("Network")] - public async Task should_commit_when_writing_with_exp_ver_any_even_while_somene_is_writing_in_parallel() - { - const string stream = - "should_commit_when_writing_with_exp_ver_any_even_while_somene_is_writing_in_parallel"; - - const int totalTranWrites = 500; - const int totalPlainWrites = 500; - - async Task PlainWrites() - { - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - using (var transaction = await store.StartTransactionAsync(stream, ExpectedVersion.Any)) - { - var writes = new List(); - for (int i = 0; i < totalTranWrites; i++) - { - writes.Add(transaction.WriteAsync(TestEvent.NewTestEvent(i.ToString(), "trans write"))); - } - - await Task.WhenAll(writes); - await transaction.CommitAsync(); - } - } - } - - async Task ParallelWrites() - { - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var writes = new List(); - for (int i = 0; i < totalPlainWrites; i++) - { - writes.Add(store.AppendToStreamAsync(stream, - ExpectedVersion.Any, TestEvent.NewTestEvent(i.ToString(), "plain write"))); - } - - await Task.WhenAll(writes); - } - } - - await Task.WhenAll(ParallelWrites(), PlainWrites()); - - // check all written - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - var slice = await store.ReadStreamEventsForwardAsync(stream, 0, totalTranWrites + totalPlainWrites, - false); - Assert.That(slice.Events.Length, Is.EqualTo(totalTranWrites + totalPlainWrites)); - - Assert.That(slice.Events.Count(ent => Helper.UTF8NoBom.GetString(ent.Event.Metadata) == "trans write"), - Is.EqualTo(totalTranWrites)); - Assert.That(slice.Events.Count(ent => Helper.UTF8NoBom.GetString(ent.Event.Metadata) == "plain write"), - Is.EqualTo(totalPlainWrites)); - } - } - - [Test] - [Category("Network")] - public async Task should_fail_to_commit_if_started_with_correct_ver_but_committing_with_bad() - { - const string stream = "should_fail_to_commit_if_started_with_correct_ver_but_committing_with_bad"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - using (var transaction = await store.StartTransactionAsync(stream, ExpectedVersion.NoStream)) - { - await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()) - ; - await transaction.WriteAsync(TestEvent.NewTestEvent()); - await AssertEx.ThrowsAsync(() => transaction.CommitAsync()); - } - } - } - - [Test, Category("Network")] - public async Task should_not_fail_to_commit_if_started_with_wrong_ver_but_committing_with_correct_ver() - { - const string stream = "should_not_fail_to_commit_if_started_with_wrong_ver_but_committing_with_correct_ver"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - using (var transaction = await store.StartTransactionAsync(stream, 0)) - { - await store.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()) - ; - await transaction.WriteAsync(TestEvent.NewTestEvent()); - var writeResult = await transaction.CommitAsync(); - Assert.AreEqual(1, writeResult.NextExpectedVersion); - } - } - } - - [Test] - [Category("Network")] - public async Task should_fail_to_commit_if_started_with_correct_ver_but_on_commit_stream_was_deleted() - { - const string stream = "should_fail_to_commit_if_started_with_correct_ver_but_on_commit_stream_was_deleted"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - using (var transaction = await store.StartTransactionAsync(stream, ExpectedVersion.NoStream)) - { - await transaction.WriteAsync(TestEvent.NewTestEvent()); - await store.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - await AssertEx.ThrowsAsync(() => transaction.CommitAsync()); - } - } - } - - [Test, Category("LongRunning")] - public async Task idempotency_is_correct_for_explicit_transactions_with_expected_version_any() - { - const string streamId = "idempotency_is_correct_for_explicit_transactions_with_expected_version_any"; - using (var store = BuildConnection(_node)) - { - await store.ConnectAsync(); - - var e = new EventData(Guid.NewGuid(), "SomethingHappened", true, - Helper.UTF8NoBom.GetBytes("{Value:42}"), null); - - var transaction1 = await store.StartTransactionAsync(streamId, ExpectedVersion.Any); - await transaction1.WriteAsync(e); - Assert.AreEqual(0, (await transaction1.CommitAsync()).NextExpectedVersion); - - var transaction2 = await store.StartTransactionAsync(streamId, ExpectedVersion.Any); - await transaction2.WriteAsync(e); - var writeResult = await transaction2.CommitAsync(); - Assert.AreEqual(0, writeResult.NextExpectedVersion); - - var res = await store.ReadStreamEventsForwardAsync(streamId, 0, 100, false); - Assert.AreEqual(1, res.Events.Length); - Assert.AreEqual(e.EventId, res.Events[0].Event.EventId); - } - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/when_committing_empty_transaction.cs b/src/EventStore.Core.Tests/ClientAPI/when_committing_empty_transaction.cs deleted file mode 100644 index 2fa1a065ec..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/when_committing_empty_transaction.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Exceptions; -using EventStore.ClientAPI.SystemData; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class when_committing_empty_transaction : SpecificationWithDirectory -{ - private static readonly TimeSpan StartupTimeout = TimeSpan.FromMinutes(5); - private const int LongRunningTimeout = 120000; - private MiniNode _node; - private IEventStoreConnection _connection; - private EventData _firstEvent; - - [SetUp] - public override async Task SetUp() - { - await base.SetUp(); - _node = new MiniNode(PathName); - await _node.Start(StartupTimeout); - await _node.WaitForTcpEndPoint().WithTimeout(TimeSpan.FromSeconds(60)); - - _firstEvent = TestEvent.NewTestEvent(); - - _connection = await TestConnectionLifecycle.ReconnectUntilReady( - () => BuildConnection(_node), - connection => connection.ReadAllEventsForwardAsync(Position.Start, 1, false, DefaultData.AdminCredentials), - StartupTimeout); - - Assert.AreEqual(2, (await _connection.AppendToStreamAsync("test-stream", - ExpectedVersion.NoStream, - _firstEvent, - TestEvent.NewTestEvent(), - TestEvent.NewTestEvent())).NextExpectedVersion); - - using (var transaction = await _connection.StartTransactionAsync("test-stream", 2)) - { - Assert.AreEqual(2, (await transaction.CommitAsync()).NextExpectedVersion); - } - } - - [TearDown] - public override async Task TearDown() - { - try - { - await TestConnectionLifecycle.CloseConnectionAndWait(_connection, TimeSpan.FromSeconds(10)); - } - catch - { - TestConnectionLifecycle.TryCloseConnection(_connection); - } - - TestConnectionLifecycle.DisposeIfNeeded(_connection); - await _node.Shutdown(); - await base.TearDown(); - } - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [Test, Timeout(LongRunningTimeout)] - public async Task following_append_with_correct_expected_version_are_commited_correctly() - { - Assert.AreEqual(4, - (await _connection.AppendToStreamAsync("test-stream", 2, TestEvent.NewTestEvent(), - TestEvent.NewTestEvent()) - ).NextExpectedVersion); - - var res = await _connection.ReadStreamEventsForwardAsync("test-stream", 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(5, res.Events.Length); - for (int i = 0; i < 5; ++i) - { - Assert.AreEqual(i, res.Events[i].OriginalEventNumber); - } - } - - [Test, Timeout(LongRunningTimeout)] - public async Task following_append_with_expected_version_any_are_commited_correctly() - { - Assert.AreEqual(4, - (await _connection.AppendToStreamAsync("test-stream", ExpectedVersion.Any, TestEvent.NewTestEvent(), - TestEvent.NewTestEvent())).NextExpectedVersion); - - var res = await _connection.ReadStreamEventsForwardAsync("test-stream", 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(5, res.Events.Length); - for (int i = 0; i < 5; ++i) - { - Assert.AreEqual(i, res.Events[i].OriginalEventNumber); - } - } - - [Test, Timeout(LongRunningTimeout)] - public async Task committing_first_event_with_expected_version_no_stream_is_idempotent() - { - Assert.AreEqual(0, - (await _connection.AppendToStreamAsync("test-stream", ExpectedVersion.NoStream, _firstEvent)) - .NextExpectedVersion); - - var res = await _connection.ReadStreamEventsForwardAsync("test-stream", 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - for (int i = 0; i < 3; ++i) - { - Assert.AreEqual(i, res.Events[i].OriginalEventNumber); - } - } - - [Test, Timeout(LongRunningTimeout)] - public async Task trying_to_append_new_events_with_expected_version_no_stream_fails() - { - await AssertEx.ThrowsAsync(() => - _connection.AppendToStreamAsync("test-stream", ExpectedVersion.NoStream, TestEvent.NewTestEvent())); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/when_having_max_count_set_for_stream.cs b/src/EventStore.Core.Tests/ClientAPI/when_having_max_count_set_for_stream.cs deleted file mode 100644 index b037129c28..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/when_having_max_count_set_for_stream.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class when_having_max_count_set_for_stream : SpecificationWithDirectory -{ - private const string Stream = "max-count-test-stream"; - - private MiniNode _node; - private IEventStoreConnection _connection; - private EventData[] _testEvents; - - [SetUp] - public override async Task SetUp() - { - await base.SetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - - _connection = TestConnection.Create(_node.TcpEndPoint); - await _connection.ConnectAsync(); - - await _connection.SetStreamMetadataAsync(Stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetMaxCount(3)); - - _testEvents = Enumerable.Range(0, 5).Select(x => TestEvent.NewTestEvent(data: x.ToString())).ToArray(); - await _connection.AppendToStreamAsync(Stream, ExpectedVersion.NoStream, _testEvents); - } - - [TearDown] - public override async Task TearDown() - { - _connection.Close(); - await _node.Shutdown(); - await base.TearDown(); - } - - [Test] - public async Task read_stream_forward_respects_max_count() - { - var res = await _connection.ReadStreamEventsForwardAsync(Stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - } - - [Test] - public async Task read_stream_backward_respects_max_count() - { - var res = await _connection.ReadStreamEventsBackwardAsync(Stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - } - - [Test] - public async Task after_setting_less_strict_max_count_read_stream_forward_reads_more_events() - { - var res = await _connection.ReadStreamEventsForwardAsync(Stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - - await _connection.SetStreamMetadataAsync(Stream, 0, StreamMetadata.Build().SetMaxCount(4)); - - res = await _connection.ReadStreamEventsForwardAsync(Stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(4, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(1).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - } - - [Test] - public async Task after_setting_more_strict_max_count_read_stream_forward_reads_less_events() - { - var res = await _connection.ReadStreamEventsForwardAsync(Stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - - await _connection.SetStreamMetadataAsync(Stream, 0, StreamMetadata.Build().SetMaxCount(2)); - - res = await _connection.ReadStreamEventsForwardAsync(Stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(2, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(3).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - } - - [Test] - public async Task after_setting_less_strict_max_count_read_stream_backward_reads_more_events() - { - var res = await _connection.ReadStreamEventsBackwardAsync(Stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - - await _connection.SetStreamMetadataAsync(Stream, 0, StreamMetadata.Build().SetMaxCount(4)); - - res = await _connection.ReadStreamEventsBackwardAsync(Stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(4, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(1).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - } - - [Test] - public async Task after_setting_more_strict_max_count_read_stream_backward_reads_less_events() - { - var res = await _connection.ReadStreamEventsBackwardAsync(Stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - - await _connection.SetStreamMetadataAsync(Stream, 0, StreamMetadata.Build().SetMaxCount(2)); - - res = await _connection.ReadStreamEventsBackwardAsync(Stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(2, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(3).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/when_having_truncatebefore_set_for_stream.cs b/src/EventStore.Core.Tests/ClientAPI/when_having_truncatebefore_set_for_stream.cs deleted file mode 100644 index 69868b8ba3..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/when_having_truncatebefore_set_for_stream.cs +++ /dev/null @@ -1,379 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class when_having_truncatebefore_set_for_stream : SpecificationWithMiniNode -{ - private EventData[] _testEvents; - - protected override Task When() - { - _testEvents = Enumerable.Range(0, 5).Select(x => TestEvent.NewTestEvent(data: x.ToString())).ToArray(); - return Task.CompletedTask; - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task read_event_respects_truncatebefore() - { - const string stream = "read_event_respects_truncatebefore"; - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadEventAsync(stream, 1, false); - Assert.AreEqual(EventReadStatus.NotFound, res.Status); - - res = await _conn.ReadEventAsync(stream, 2, false); - Assert.AreEqual(EventReadStatus.Success, res.Status); - Assert.AreEqual(_testEvents[2].EventId, res.Event.Value.OriginalEvent.EventId); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task read_stream_forward_respects_truncatebefore() - { - const string stream = "read_stream_forward_respects_truncatebefore"; - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task read_stream_backward_respects_truncatebefore() - { - const string stream = "read_stream_backward_respects_truncatebefore"; - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadStreamEventsBackwardAsync(stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task after_setting_less_strict_truncatebefore_read_event_reads_more_events() - { - const string stream = "after_setting_less_strict_truncatebefore_read_event_reads_more_events"; - - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadEventAsync(stream, 1, false); - Assert.AreEqual(EventReadStatus.NotFound, res.Status); - - res = await _conn.ReadEventAsync(stream, 2, false); - Assert.AreEqual(EventReadStatus.Success, res.Status); - Assert.AreEqual(_testEvents[2].EventId, res.Event.Value.OriginalEvent.EventId); - - await _conn.SetStreamMetadataAsync(stream, 0, StreamMetadata.Build().SetTruncateBefore(1)); - - res = await _conn.ReadEventAsync(stream, 0, false); - Assert.AreEqual(EventReadStatus.NotFound, res.Status); - - res = await _conn.ReadEventAsync(stream, 1, false); - Assert.AreEqual(EventReadStatus.Success, res.Status); - Assert.AreEqual(_testEvents[1].EventId, res.Event.Value.OriginalEvent.EventId); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task after_setting_more_strict_truncatebefore_read_event_reads_less_events() - { - const string stream = "after_setting_more_strict_truncatebefore_read_event_reads_less_events"; - - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadEventAsync(stream, 1, false); - Assert.AreEqual(EventReadStatus.NotFound, res.Status); - - res = await _conn.ReadEventAsync(stream, 2, false); - Assert.AreEqual(EventReadStatus.Success, res.Status); - Assert.AreEqual(_testEvents[2].EventId, res.Event.Value.OriginalEvent.EventId); - - await _conn.SetStreamMetadataAsync(stream, 0, StreamMetadata.Build().SetTruncateBefore(3)); - - res = await _conn.ReadEventAsync(stream, 2, false); - Assert.AreEqual(EventReadStatus.NotFound, res.Status); - - res = await _conn.ReadEventAsync(stream, 3, false); - Assert.AreEqual(EventReadStatus.Success, res.Status); - Assert.AreEqual(_testEvents[3].EventId, res.Event.Value.OriginalEvent.EventId); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task less_strict_max_count_doesnt_change_anything_for_event_read() - { - const string stream = "less_strict_max_count_doesnt_change_anything_for_event_read"; - - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadEventAsync(stream, 1, false); - Assert.AreEqual(EventReadStatus.NotFound, res.Status); - - res = await _conn.ReadEventAsync(stream, 2, false); - Assert.AreEqual(EventReadStatus.Success, res.Status); - Assert.AreEqual(_testEvents[2].EventId, res.Event.Value.OriginalEvent.EventId); - - await _conn.SetStreamMetadataAsync(stream, 0, StreamMetadata.Build().SetTruncateBefore(2).SetMaxCount(4)); - - res = await _conn.ReadEventAsync(stream, 1, false); - Assert.AreEqual(EventReadStatus.NotFound, res.Status); - - res = await _conn.ReadEventAsync(stream, 2, false); - Assert.AreEqual(EventReadStatus.Success, res.Status); - Assert.AreEqual(_testEvents[2].EventId, res.Event.Value.OriginalEvent.EventId); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task more_strict_max_count_gives_less_events_for_event_read() - { - const string stream = "more_strict_max_count_gives_less_events_for_event_read"; - - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadEventAsync(stream, 1, false); - Assert.AreEqual(EventReadStatus.NotFound, res.Status); - - res = await _conn.ReadEventAsync(stream, 2, false); - Assert.AreEqual(EventReadStatus.Success, res.Status); - Assert.AreEqual(_testEvents[2].EventId, res.Event.Value.OriginalEvent.EventId); - - await _conn.SetStreamMetadataAsync(stream, 0, StreamMetadata.Build().SetTruncateBefore(2).SetMaxCount(2)); - - res = await _conn.ReadEventAsync(stream, 2, false); - Assert.AreEqual(EventReadStatus.NotFound, res.Status); - - res = await _conn.ReadEventAsync(stream, 3, false); - Assert.AreEqual(EventReadStatus.Success, res.Status); - Assert.AreEqual(_testEvents[3].EventId, res.Event.Value.OriginalEvent.EventId); - } - - - [Test, Category("LongRunning"), Category("Network")] - public async Task after_setting_less_strict_truncatebefore_read_stream_forward_reads_more_events() - { - const string stream = "after_setting_less_strict_truncatebefore_read_stream_forward_reads_more_events"; - - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - - await _conn.SetStreamMetadataAsync(stream, 0, StreamMetadata.Build().SetTruncateBefore(1)); - - res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(4, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(1).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task after_setting_more_strict_truncatebefore_read_stream_forward_reads_less_events() - { - const string stream = "after_setting_more_strict_truncatebefore_read_stream_forward_reads_less_events"; - - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - - await _conn.SetStreamMetadataAsync(stream, 0, StreamMetadata.Build().SetTruncateBefore(3)); - - res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(2, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(3).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task less_strict_max_count_doesnt_change_anything_for_stream_forward_read() - { - const string stream = "less_strict_max_count_doesnt_change_anything_for_stream_forward_read"; - - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - - await _conn.SetStreamMetadataAsync(stream, 0, StreamMetadata.Build().SetTruncateBefore(2).SetMaxCount(4)); - - res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task more_strict_max_count_gives_less_events_for_stream_forward_read() - { - const string stream = "more_strict_max_count_gives_less_events_for_stream_forward_read"; - - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - - await _conn.SetStreamMetadataAsync(stream, 0, StreamMetadata.Build().SetTruncateBefore(2).SetMaxCount(2)); - - res = await _conn.ReadStreamEventsForwardAsync(stream, 0, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(2, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(3).Select(x => x.EventId).ToArray(), - res.Events.Select(x => x.Event.EventId).ToArray()); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task after_setting_less_strict_truncatebefore_read_stream_backward_reads_more_events() - { - const string stream = "after_setting_less_strict_truncatebefore_read_stream_backward_reads_more_events"; - - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadStreamEventsBackwardAsync(stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - - await _conn.SetStreamMetadataAsync(stream, 0, StreamMetadata.Build().SetTruncateBefore(1)); - - res = await _conn.ReadStreamEventsBackwardAsync(stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(4, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(1).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task after_setting_more_strict_truncatebefore_read_stream_backward_reads_less_events() - { - const string stream = "after_setting_more_strict_truncatebefore_read_stream_backward_reads_less_events"; - - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadStreamEventsBackwardAsync(stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - - await _conn.SetStreamMetadataAsync(stream, 0, StreamMetadata.Build().SetTruncateBefore(3)); - - res = await _conn.ReadStreamEventsBackwardAsync(stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(2, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(3).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task less_strict_max_count_doesnt_change_anything_for_stream_backward_read() - { - const string stream = "less_strict_max_count_doesnt_change_anything_for_stream_backward_read"; - - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadStreamEventsBackwardAsync(stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - - await _conn.SetStreamMetadataAsync(stream, 0, StreamMetadata.Build().SetTruncateBefore(2).SetMaxCount(4)); - - res = await _conn.ReadStreamEventsBackwardAsync(stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - } - - [Test, Category("LongRunning"), Category("Network")] - public async Task more_strict_max_count_gives_less_events_for_stream_backward_read() - { - const string stream = "more_strict_max_count_gives_less_events_for_stream_backward_read"; - - await _conn.AppendToStreamAsync(stream, ExpectedVersion.NoStream, _testEvents); - - await _conn.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, - StreamMetadata.Build().SetTruncateBefore(2)); - - var res = await _conn.ReadStreamEventsBackwardAsync(stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(3, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(2).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - - await _conn.SetStreamMetadataAsync(stream, 0, StreamMetadata.Build().SetTruncateBefore(2).SetMaxCount(2)); - - res = await _conn.ReadStreamEventsBackwardAsync(stream, -1, 100, false); - Assert.AreEqual(SliceReadStatus.Success, res.Status); - Assert.AreEqual(2, res.Events.Length); - Assert.AreEqual(_testEvents.Skip(3).Select(x => x.EventId).ToArray(), - res.Events.Reverse().Select(x => x.Event.EventId).ToArray()); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/when_working_with_metadata.cs b/src/EventStore.Core.Tests/ClientAPI/when_working_with_metadata.cs deleted file mode 100644 index b876703470..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/when_working_with_metadata.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Exceptions; -using EventStore.Common.Utils; -using EventStore.Core.Data; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using Newtonsoft.Json.Linq; -using NUnit.Framework; -using ExpectedVersion = EventStore.ClientAPI.ExpectedVersion; -using StreamMetadata = EventStore.ClientAPI.StreamMetadata; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class when_working_with_metadata : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - private IEventStoreConnection _connection; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - - _connection = BuildConnection(_node); - await _connection.ConnectAsync(); - } - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - _connection.Close(); - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - [Test] - public async Task when_getting_metadata_for_an_existing_stream_and_no_metadata_exists() - { - const string stream = "when_getting_metadata_for_an_existing_stream_and_no_metadata_exists"; - - await _connection.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()); - - var meta = await _connection.GetStreamMetadataAsRawBytesAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(-1, meta.MetastreamVersion); - Assert.AreEqual(Helper.UTF8NoBom.GetBytes(""), meta.StreamMetadata); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/when_working_with_stream_metadata_as_byte_array.cs b/src/EventStore.Core.Tests/ClientAPI/when_working_with_stream_metadata_as_byte_array.cs deleted file mode 100644 index cb976f3b6f..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/when_working_with_stream_metadata_as_byte_array.cs +++ /dev/null @@ -1,182 +0,0 @@ -using System; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Exceptions; -using EventStore.Core.Data; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; -using ExpectedVersion = EventStore.ClientAPI.ExpectedVersion; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class when_working_with_stream_metadata_as_byte_array : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - private IEventStoreConnection _connection; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - - _connection = BuildConnection(_node); - await _connection.ConnectAsync(); - } - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - _connection.Close(); - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - [Test] - public async Task setting_empty_metadata_works() - { - const string stream = "setting_empty_metadata_works"; - - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, (byte[])null); - - var meta = await _connection.GetStreamMetadataAsRawBytesAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - Assert.AreEqual(new byte[0], meta.StreamMetadata); - } - - [Test] - public async Task setting_metadata_few_times_returns_last_metadata() - { - const string stream = "setting_metadata_few_times_returns_last_metadata"; - - var metadataBytes = Guid.NewGuid().ToByteArray(); - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, metadataBytes); - var meta = await _connection.GetStreamMetadataAsRawBytesAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - Assert.AreEqual(metadataBytes, meta.StreamMetadata); - - metadataBytes = Guid.NewGuid().ToByteArray(); - await _connection.SetStreamMetadataAsync(stream, 0, metadataBytes); - meta = await _connection.GetStreamMetadataAsRawBytesAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(1, meta.MetastreamVersion); - Assert.AreEqual(metadataBytes, meta.StreamMetadata); - } - - [Test] - public async Task trying_to_set_metadata_with_wrong_expected_version_fails() - { - const string stream = "trying_to_set_metadata_with_wrong_expected_version_fails"; - await AssertEx.ThrowsAsync(() => _connection.SetStreamMetadataAsync(stream, 5, new byte[100])); - } - - [Test] - public async Task setting_metadata_with_expected_version_any_works() - { - const string stream = "setting_metadata_with_expected_version_any_works"; - - var metadataBytes = Guid.NewGuid().ToByteArray(); - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.Any, metadataBytes); - var meta = await _connection.GetStreamMetadataAsRawBytesAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - Assert.AreEqual(metadataBytes, meta.StreamMetadata); - - metadataBytes = Guid.NewGuid().ToByteArray(); - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.Any, metadataBytes); - meta = await _connection.GetStreamMetadataAsRawBytesAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(1, meta.MetastreamVersion); - Assert.AreEqual(metadataBytes, meta.StreamMetadata); - } - - [Test] - public async Task setting_metadata_for_not_existing_stream_works() - { - const string stream = "setting_metadata_for_not_existing_stream_works"; - var metadataBytes = Guid.NewGuid().ToByteArray(); - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, metadataBytes); - - var meta = await _connection.GetStreamMetadataAsRawBytesAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - Assert.AreEqual(metadataBytes, meta.StreamMetadata); - } - - [Test] - public async Task setting_metadata_for_existing_stream_works() - { - const string stream = "setting_metadata_for_existing_stream_works"; - - await _connection.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent(), - TestEvent.NewTestEvent()); - - var metadataBytes = Guid.NewGuid().ToByteArray(); - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, metadataBytes); - - var meta = await _connection.GetStreamMetadataAsRawBytesAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - Assert.AreEqual(metadataBytes, meta.StreamMetadata); - } - - [Test] - public async Task setting_metadata_for_deleted_stream_throws_stream_deleted_exception() - { - const string stream = "setting_metadata_for_deleted_stream_throws_stream_deleted_exception"; - - await _connection.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - - var metadataBytes = Guid.NewGuid().ToByteArray(); - await AssertEx.ThrowsAsync( - () => _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, metadataBytes)); - } - - [Test] - public async Task getting_metadata_for_nonexisting_stream_returns_empty_byte_array() - { - const string stream = "getting_metadata_for_nonexisting_stream_returns_empty_byte_array"; - - var meta = await _connection.GetStreamMetadataAsRawBytesAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(-1, meta.MetastreamVersion); - Assert.AreEqual(new byte[0], meta.StreamMetadata); - } - - [Test] - public async Task getting_metadata_for_deleted_stream_returns_empty_byte_array_and_signals_stream_deletion() - { - const string stream = - "getting_metadata_for_deleted_stream_returns_empty_byte_array_and_signals_stream_deletion"; - - var metadataBytes = Guid.NewGuid().ToByteArray(); - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, metadataBytes); - - await _connection.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - - var meta = await _connection.GetStreamMetadataAsRawBytesAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(true, meta.IsStreamDeleted); - Assert.AreEqual(EventNumber.DeletedStream, meta.MetastreamVersion); - Assert.AreEqual(new byte[0], meta.StreamMetadata); - } -} diff --git a/src/EventStore.Core.Tests/ClientAPI/when_working_with_stream_metadata_as_structured_info.cs b/src/EventStore.Core.Tests/ClientAPI/when_working_with_stream_metadata_as_structured_info.cs deleted file mode 100644 index 02f516d4c7..0000000000 --- a/src/EventStore.Core.Tests/ClientAPI/when_working_with_stream_metadata_as_structured_info.cs +++ /dev/null @@ -1,384 +0,0 @@ -using System; -using System.Threading.Tasks; -using EventStore.ClientAPI; -using EventStore.ClientAPI.Exceptions; -using EventStore.Common.Utils; -using EventStore.Core.Data; -using EventStore.Core.Tests.ClientAPI.Helpers; -using EventStore.Core.Tests.Helpers; -using NUnit.Framework; -using ExpectedVersion = EventStore.ClientAPI.ExpectedVersion; -using StreamMetadata = EventStore.ClientAPI.StreamMetadata; - -namespace EventStore.Core.Tests.ClientAPI; - -[Category("ClientAPI"), Category("LongRunning")] -[TestFixture(typeof(LogFormat.V2), typeof(string))] -public class when_working_with_stream_metadata_as_structured_info : SpecificationWithDirectoryPerTestFixture -{ - private MiniNode _node; - private IEventStoreConnection _connection; - - [OneTimeSetUp] - public override async Task TestFixtureSetUp() - { - await base.TestFixtureSetUp(); - _node = new MiniNode(PathName); - await _node.Start(); - - _connection = BuildConnection(_node); - await _connection.ConnectAsync(); - } - - protected virtual IEventStoreConnection BuildConnection(MiniNode node) - { - return TestConnection.Create(node.TcpEndPoint); - } - - [OneTimeTearDown] - public override async Task TestFixtureTearDown() - { - _connection.Close(); - await _node.Shutdown(); - await base.TestFixtureTearDown(); - } - - [Test] - public async Task setting_empty_metadata_works() - { - const string stream = "setting_empty_metadata_works"; - - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, StreamMetadata.Create()); - - var meta = await _connection.GetStreamMetadataAsRawBytesAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - Assert.AreEqual(Helper.UTF8NoBom.GetBytes("{}"), meta.StreamMetadata); - } - - [Test] - public async Task setting_metadata_few_times_returns_last_metadata_info() - { - const string stream = "setting_metadata_few_times_returns_last_metadata_info"; - var metadata = - StreamMetadata.Create(17, TimeSpan.FromSeconds(0xDEADBEEF), 10, TimeSpan.FromSeconds(0xABACABA)); - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, metadata); - - var meta = await _connection.GetStreamMetadataAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - Assert.AreEqual(metadata.MaxCount, meta.StreamMetadata.MaxCount); - Assert.AreEqual(metadata.MaxAge, meta.StreamMetadata.MaxAge); - Assert.AreEqual(metadata.TruncateBefore, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(metadata.CacheControl, meta.StreamMetadata.CacheControl); - - metadata = StreamMetadata.Create(37, TimeSpan.FromSeconds(0xBEEFDEAD), 24, - TimeSpan.FromSeconds(0xDABACABAD)); - await _connection.SetStreamMetadataAsync(stream, 0, metadata); - - meta = await _connection.GetStreamMetadataAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(1, meta.MetastreamVersion); - Assert.AreEqual(metadata.MaxCount, meta.StreamMetadata.MaxCount); - Assert.AreEqual(metadata.MaxAge, meta.StreamMetadata.MaxAge); - Assert.AreEqual(metadata.TruncateBefore, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(metadata.CacheControl, meta.StreamMetadata.CacheControl); - } - - [Test] - public async Task trying_to_set_metadata_with_wrong_expected_version_fails() - { - const string stream = "trying_to_set_metadata_with_wrong_expected_version_fails"; - await AssertEx.ThrowsAsync(() => - _connection.SetStreamMetadataAsync(stream, 2, StreamMetadata.Create())); - } - - [Test] - public async Task setting_metadata_with_expected_version_any_works() - { - const string stream = "setting_metadata_with_expected_version_any_works"; - var metadata = - StreamMetadata.Create(17, TimeSpan.FromSeconds(0xDEADBEEF), 10, TimeSpan.FromSeconds(0xABACABA)); - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.Any, metadata); - - var meta = await _connection.GetStreamMetadataAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - Assert.AreEqual(metadata.MaxCount, meta.StreamMetadata.MaxCount); - Assert.AreEqual(metadata.MaxAge, meta.StreamMetadata.MaxAge); - Assert.AreEqual(metadata.TruncateBefore, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(metadata.CacheControl, meta.StreamMetadata.CacheControl); - - metadata = StreamMetadata.Create(37, TimeSpan.FromSeconds(0xBEEFDEAD), 24, - TimeSpan.FromSeconds(0xDABACABAD)); - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.Any, metadata); - - meta = await _connection.GetStreamMetadataAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(1, meta.MetastreamVersion); - Assert.AreEqual(metadata.MaxCount, meta.StreamMetadata.MaxCount); - Assert.AreEqual(metadata.MaxAge, meta.StreamMetadata.MaxAge); - Assert.AreEqual(metadata.TruncateBefore, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(metadata.CacheControl, meta.StreamMetadata.CacheControl); - } - - [Test] - public async Task setting_metadata_for_not_existing_stream_works() - { - const string stream = "setting_metadata_for_not_existing_stream_works"; - var metadata = - StreamMetadata.Create(17, TimeSpan.FromSeconds(0xDEADBEEF), 10, TimeSpan.FromSeconds(0xABACABA)); - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, metadata); - - var meta = await _connection.GetStreamMetadataAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - Assert.AreEqual(metadata.MaxCount, meta.StreamMetadata.MaxCount); - Assert.AreEqual(metadata.MaxAge, meta.StreamMetadata.MaxAge); - Assert.AreEqual(metadata.TruncateBefore, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(metadata.CacheControl, meta.StreamMetadata.CacheControl); - } - - [Test] - public async Task setting_metadata_for_existing_stream_works() - { - const string stream = "setting_metadata_for_existing_stream_works"; - - await _connection.AppendToStreamAsync(stream, ExpectedVersion.NoStream, TestEvent.NewTestEvent()); - - var metadata = - StreamMetadata.Create(17, TimeSpan.FromSeconds(0xDEADBEEF), 10, TimeSpan.FromSeconds(0xABACABA)); - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, metadata); - - var meta = await _connection.GetStreamMetadataAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - Assert.AreEqual(metadata.MaxCount, meta.StreamMetadata.MaxCount); - Assert.AreEqual(metadata.MaxAge, meta.StreamMetadata.MaxAge); - Assert.AreEqual(metadata.TruncateBefore, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(metadata.CacheControl, meta.StreamMetadata.CacheControl); - } - - [Test] - public async Task getting_metadata_for_nonexisting_stream_returns_empty_stream_metadata() - { - const string stream = "getting_metadata_for_nonexisting_stream_returns_empty_stream_metadata"; - - var meta = await _connection.GetStreamMetadataAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(-1, meta.MetastreamVersion); - Assert.AreEqual(null, meta.StreamMetadata.MaxCount); - Assert.AreEqual(null, meta.StreamMetadata.MaxAge); - Assert.AreEqual(null, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(null, meta.StreamMetadata.CacheControl); - } - - [Test, Ignore("You can't get stream metadata for metastream through ClientAPI")] - public async Task getting_metadata_for_metastream_returns_correct_metadata() - { - const string stream = "$$getting_metadata_for_metastream_returns_correct_metadata"; - - var meta = await _connection.GetStreamMetadataAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(-1, meta.MetastreamVersion); - Assert.AreEqual(1, meta.StreamMetadata.MaxCount); - Assert.AreEqual(null, meta.StreamMetadata.MaxAge); - Assert.AreEqual(null, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(null, meta.StreamMetadata.CacheControl); - } - - [Test] - public async Task getting_metadata_for_deleted_stream_returns_empty_stream_metadata_and_signals_stream_deletion() - { - const string stream = - "getting_metadata_for_deleted_stream_returns_empty_stream_metadata_and_signals_stream_deletion"; - - var metadata = - StreamMetadata.Create(17, TimeSpan.FromSeconds(0xDEADBEEF), 10, TimeSpan.FromSeconds(0xABACABA)); - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, metadata); - - await _connection.DeleteStreamAsync(stream, ExpectedVersion.NoStream, hardDelete: true); - - var meta = await _connection.GetStreamMetadataAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(true, meta.IsStreamDeleted); - Assert.AreEqual(EventNumber.DeletedStream, meta.MetastreamVersion); - Assert.AreEqual(null, meta.StreamMetadata.MaxCount); - Assert.AreEqual(null, meta.StreamMetadata.MaxAge); - Assert.AreEqual(null, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(null, meta.StreamMetadata.CacheControl); - Assert.AreEqual(null, meta.StreamMetadata.Acl); - } - - [Test] - public async Task setting_correctly_formatted_metadata_as_raw_allows_to_read_it_as_structured_metadata() - { - const string stream = - "setting_correctly_formatted_metadata_as_raw_allows_to_read_it_as_structured_metadata"; - - var rawMeta = Helper.UTF8NoBom.GetBytes(@"{ - ""$maxCount"": 17, - ""$maxAge"": 123321, - ""$tb"": 23, - ""$cacheControl"": 7654321, - ""$acl"": { - ""$r"": ""readRole"", - ""$w"": ""writeRole"", - ""$d"": ""deleteRole"", - ""$mw"": ""metaWriteRole"" - }, - ""customString"": ""a string"", - ""customInt"": -179, - ""customDouble"": 1.7, - ""customLong"": 123123123123123123, - ""customBool"": true, - ""customNullable"": null, - ""customRawJson"": { - ""subProperty"": 999 - } - }"); - - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, rawMeta); - - var meta = await _connection.GetStreamMetadataAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - Assert.AreEqual(17, meta.StreamMetadata.MaxCount); - Assert.AreEqual(TimeSpan.FromSeconds(123321), meta.StreamMetadata.MaxAge); - Assert.AreEqual(23, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(TimeSpan.FromSeconds(7654321), meta.StreamMetadata.CacheControl); - - Assert.NotNull(meta.StreamMetadata.Acl); - Assert.AreEqual("readRole", meta.StreamMetadata.Acl.ReadRole); - Assert.AreEqual("writeRole", meta.StreamMetadata.Acl.WriteRole); - Assert.AreEqual("deleteRole", meta.StreamMetadata.Acl.DeleteRole); - // meta role removed to allow reading - // Assert.AreEqual("metaReadRole", meta.StreamMetadata.Acl.MetaReadRole); - Assert.AreEqual("metaWriteRole", meta.StreamMetadata.Acl.MetaWriteRole); - - Assert.AreEqual("a string", meta.StreamMetadata.GetValue("customString")); - Assert.AreEqual(-179, meta.StreamMetadata.GetValue("customInt")); - Assert.AreEqual(1.7, meta.StreamMetadata.GetValue("customDouble")); - Assert.AreEqual(123123123123123123L, meta.StreamMetadata.GetValue("customLong")); - Assert.AreEqual(true, meta.StreamMetadata.GetValue("customBool")); - Assert.AreEqual(null, meta.StreamMetadata.GetValue("customNullable")); - Assert.AreEqual(@"{""subProperty"":999}", meta.StreamMetadata.GetValueAsRawJsonString("customRawJson")); - } - - [Test] - public async Task setting_structured_metadata_with_custom_properties_returns_them_untouched() - { - const string stream = "setting_structured_metadata_with_custom_properties_returns_them_untouched"; - - StreamMetadata metadata = StreamMetadata.Build() - .SetMaxCount(17) - .SetMaxAge(TimeSpan.FromSeconds(123321)) - .SetTruncateBefore(23) - .SetCacheControl(TimeSpan.FromSeconds(7654321)) - .SetReadRole("readRole") - .SetWriteRole("writeRole") - .SetDeleteRole("deleteRole") - //.SetMetadataReadRole("metaReadRole") - .SetMetadataWriteRole("metaWriteRole") - .SetCustomProperty("customString", "a string") - .SetCustomProperty("customInt", -179) - .SetCustomProperty("customDouble", 1.7) - .SetCustomProperty("customLong", 123123123123123123L) - .SetCustomProperty("customBool", true) - .SetCustomProperty("customNullable", new int?()) - .SetCustomPropertyWithValueAsRawJsonString("customRawJson", - @"{ - ""subProperty"": 999 - }"); - - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, metadata); - - var meta = await _connection.GetStreamMetadataAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - Assert.AreEqual(17, meta.StreamMetadata.MaxCount); - Assert.AreEqual(TimeSpan.FromSeconds(123321), meta.StreamMetadata.MaxAge); - Assert.AreEqual(23, meta.StreamMetadata.TruncateBefore); - Assert.AreEqual(TimeSpan.FromSeconds(7654321), meta.StreamMetadata.CacheControl); - - Assert.NotNull(meta.StreamMetadata.Acl); - Assert.AreEqual("readRole", meta.StreamMetadata.Acl.ReadRole); - Assert.AreEqual("writeRole", meta.StreamMetadata.Acl.WriteRole); - Assert.AreEqual("deleteRole", meta.StreamMetadata.Acl.DeleteRole); - //Assert.AreEqual("metaReadRole", meta.StreamMetadata.Acl.MetaReadRole); - Assert.AreEqual("metaWriteRole", meta.StreamMetadata.Acl.MetaWriteRole); - - Assert.AreEqual("a string", meta.StreamMetadata.GetValue("customString")); - Assert.AreEqual(-179, meta.StreamMetadata.GetValue("customInt")); - Assert.AreEqual(1.7, meta.StreamMetadata.GetValue("customDouble")); - Assert.AreEqual(123123123123123123L, meta.StreamMetadata.GetValue("customLong")); - Assert.AreEqual(true, meta.StreamMetadata.GetValue("customBool")); - Assert.AreEqual(null, meta.StreamMetadata.GetValue("customNullable")); - Assert.AreEqual(@"{""subProperty"":999}", meta.StreamMetadata.GetValueAsRawJsonString("customRawJson")); - } - - [Test] - public async Task setting_structured_metadata_with_multiple_roles_can_be_read_back() - { - const string stream = "setting_structured_metadata_with_multiple_roles_can_be_read_back"; - - StreamMetadata metadata = StreamMetadata.Build() - .SetReadRoles(new[] { "r1", "r2", "r3" }) - .SetWriteRoles(new[] { "w1", "w2" }) - .SetDeleteRoles(new[] { "d1", "d2", "d3", "d4" }) - .SetMetadataWriteRoles(new[] { "mw1", "mw2" }); - - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, metadata); - - var meta = await _connection.GetStreamMetadataAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - - Assert.NotNull(meta.StreamMetadata.Acl); - Assert.AreEqual(new[] { "r1", "r2", "r3" }, meta.StreamMetadata.Acl.ReadRoles); - Assert.AreEqual(new[] { "w1", "w2" }, meta.StreamMetadata.Acl.WriteRoles); - Assert.AreEqual(new[] { "d1", "d2", "d3", "d4" }, meta.StreamMetadata.Acl.DeleteRoles); - Assert.AreEqual(new[] { "mw1", "mw2" }, meta.StreamMetadata.Acl.MetaWriteRoles); - } - - [Test] - public async Task setting_correct_metadata_with_multiple_roles_in_acl_allows_to_read_it_as_structured_metadata() - { - const string stream = - "setting_correct_metadata_with_multiple_roles_in_acl_allows_to_read_it_as_structured_metadata"; - - var rawMeta = Helper.UTF8NoBom.GetBytes(@"{ - ""$acl"": { - ""$r"": [""r1"", ""r2"", ""r3""], - ""$w"": [""w1"", ""w2""], - ""$d"": [""d1"", ""d2"", ""d3"", ""d4""], - ""$mw"": [""mw1"", ""mw2""], - } - }"); - - await _connection.SetStreamMetadataAsync(stream, ExpectedVersion.NoStream, rawMeta); - - var meta = await _connection.GetStreamMetadataAsync(stream); - Assert.AreEqual(stream, meta.Stream); - Assert.AreEqual(false, meta.IsStreamDeleted); - Assert.AreEqual(0, meta.MetastreamVersion); - - Assert.NotNull(meta.StreamMetadata.Acl); - Assert.AreEqual(new[] { "r1", "r2", "r3" }, meta.StreamMetadata.Acl.ReadRoles); - Assert.AreEqual(new[] { "w1", "w2" }, meta.StreamMetadata.Acl.WriteRoles); - Assert.AreEqual(new[] { "d1", "d2", "d3", "d4" }, meta.StreamMetadata.Acl.DeleteRoles); - Assert.AreEqual(new[] { "mw1", "mw2" }, meta.StreamMetadata.Acl.MetaWriteRoles); - } -} From 0ebd76e5f44cc39f241964f313d1c6e1ddea295c Mon Sep 17 00:00:00 2001 From: Yordis Prieto Date: Sun, 13 Sep 2026 14:19:38 -0400 Subject: [PATCH 2/2] fix(tests): preserve stream behavior over gRPC Signed-off-by: Yordis Prieto --- .../FilteredReadAllSpecification.cs | 101 +++++++++++ .../Grpc/StreamsTests/append_to_stream.cs | 72 ++++++++ .../Grpc/StreamsTests/isjson_flag_on_event.cs | 92 ++++++++++ ...ead_all_events_backward_filtered_should.cs | 61 +++++++ ...read_all_events_forward_filtered_should.cs | 61 +++++++ ...forward_with_hard_deleted_stream_should.cs | 114 ++++++++++++ ...forward_with_soft_deleted_stream_should.cs | 111 ++++++++++++ .../Grpc/StreamsTests/read_event_should.cs | 169 ++++++++++++++++++ .../Grpc/StreamsTests/subscribe_should.cs | 66 +++++++ .../StreamsTests/subscribe_to_all_should.cs | 99 ++++++++++ 10 files changed, 946 insertions(+) create mode 100644 src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/FilteredReadAllSpecification.cs create mode 100644 src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/append_to_stream.cs create mode 100644 src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/isjson_flag_on_event.cs create mode 100644 src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_backward_filtered_should.cs create mode 100644 src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_forward_filtered_should.cs create mode 100644 src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_forward_with_hard_deleted_stream_should.cs create mode 100644 src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_forward_with_soft_deleted_stream_should.cs create mode 100644 src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_event_should.cs create mode 100644 src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/subscribe_should.cs create mode 100644 src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/subscribe_to_all_should.cs diff --git a/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/FilteredReadAllSpecification.cs b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/FilteredReadAllSpecification.cs new file mode 100644 index 0000000000..8c051c6833 --- /dev/null +++ b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/FilteredReadAllSpecification.cs @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using EventStore.Client.Streams; +using EventStore.Core.Services.Transport.Grpc; +using Google.Protobuf; +using Grpc.Core; +using GrpcMetadata = EventStore.Core.Services.Transport.Grpc.Constants.Metadata; + +namespace EventStore.Core.Tests.Services.Transport.Grpc.StreamsTests; + +public abstract class FilteredReadAllSpecification + : GrpcSpecification +{ + protected const string StreamA = "stream-a"; + protected const string StreamB = "stream-b"; + + protected override async Task Given() + { + await Append(StreamA, Enumerable.Range(0, 10) + .Select(i => CreateEvent(i % 2 == 0 ? "AEvent" : "BEvent"))); + await Append(StreamB, Enumerable.Range(0, 10) + .Select(i => CreateEvent(i % 2 == 0 ? "BEvent" : "AEvent"))); + } + + protected override Task When() => Task.CompletedTask; + + protected async Task Read( + ReadReq.Types.Options.Types.ReadDirection direction, + ReadReq.Types.Options.Types.FilterOptions filter) + { + using var call = StreamsClient.Read(new() + { + Options = new() + { + UuidOption = new() { Structured = new() }, + Count = 1000, + ReadDirection = direction, + ResolveLinks = false, + All = direction == ReadReq.Types.Options.Types.ReadDirection.Forwards + ? new() { Start = new() } + : new() { End = new() }, + Filter = filter + } + }, GetCallOptions(AdminCredentials)); + + return (await call.ResponseStream.ReadAllAsync().ToArrayAsync()) + .Where(x => x.ContentCase == ReadResp.ContentOneofCase.Event) + .Select(x => x.Event) + .ToArray(); + } + + protected static ReadReq.Types.Options.Types.FilterOptions StreamPrefix(string prefix) => new() + { + Count = new(), + CheckpointIntervalMultiplier = 1, + StreamIdentifier = new() { Prefix = { prefix } } + }; + + protected static ReadReq.Types.Options.Types.FilterOptions EventTypePrefix(string prefix) => new() + { + Count = new(), + CheckpointIntervalMultiplier = 1, + EventType = new() { Prefix = { prefix } } + }; + + protected static ReadReq.Types.Options.Types.FilterOptions StreamRegex(string regex) => new() + { + Count = new(), + CheckpointIntervalMultiplier = 1, + StreamIdentifier = new() { Regex = regex } + }; + + protected static ReadReq.Types.Options.Types.FilterOptions EventTypeRegex(string regex) => new() + { + Count = new(), + CheckpointIntervalMultiplier = 1, + EventType = new() { Regex = regex } + }; + + protected static string StreamName(ReadResp.Types.ReadEvent readEvent) => + readEvent.Event.StreamIdentifier.StreamName.ToStringUtf8(); + + protected static string EventType(ReadResp.Types.ReadEvent readEvent) => + readEvent.Event.Metadata[GrpcMetadata.Type]; + + private ValueTask Append( + string streamName, + IEnumerable events) => + AppendToStreamBatch(new BatchAppendReq + { + Options = new() + { + NoStream = new(), + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(streamName) } + }, + CorrelationId = Uuid.NewUuid().ToDto(), + IsFinal = true, + ProposedMessages = { events } + }); +} diff --git a/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/append_to_stream.cs b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/append_to_stream.cs new file mode 100644 index 0000000000..92c6380689 --- /dev/null +++ b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/append_to_stream.cs @@ -0,0 +1,72 @@ +using System.Linq; +using System.Threading.Tasks; +using EventStore.Client.Streams; +using EventStore.Core.Services.Transport.Grpc; +using Google.Protobuf; +using NUnit.Framework; + +namespace EventStore.Core.Tests.Services.Transport.Grpc.StreamsTests; + +[TestFixture(typeof(LogFormat.V2), typeof(string))] +public class append_to_stream : GrpcSpecification +{ + protected override Task Given() => Task.CompletedTask; + + protected override Task When() => Task.CompletedTask; + + [Test] + public async Task can_append_to_stream_with_long_name() + { + var streamName = nameof(can_append_to_stream_with_long_name) + new string('A', 300); + var response = await Append(streamName, CreateEvents(1)); + + Assert.That(response.ResultCase, Is.EqualTo(BatchAppendResp.ResultOneofCase.Success)); + Assert.That(response.Success.CurrentRevision, Is.Zero); + } + + [Test] + public async Task can_append_multiple_events_to_stream_with_long_name_at_once() + { + var streamName = nameof(can_append_multiple_events_to_stream_with_long_name_at_once) + new string('A', 300); + var response = await Append(streamName, CreateEvents(3)); + + Assert.That(response.ResultCase, Is.EqualTo(BatchAppendResp.ResultOneofCase.Success)); + Assert.That(response.Success.CurrentRevision, Is.EqualTo(2)); + } + + [Test] + public async Task can_append_event_with_long_event_type() + { + var response = await Append(nameof(can_append_event_with_long_event_type), + new[] { CreateEvent(new string('A', 300)) }); + + Assert.That(response.ResultCase, Is.EqualTo(BatchAppendResp.ResultOneofCase.Success)); + Assert.That(response.Success.CurrentRevision, Is.Zero); + } + + [Test] + public async Task can_append_multiple_events_with_long_event_type_at_once() + { + var eventType = new string('A', 300); + var response = await Append(nameof(can_append_multiple_events_with_long_event_type_at_once), + Enumerable.Range(0, 3).Select(_ => CreateEvent(eventType))); + + Assert.That(response.ResultCase, Is.EqualTo(BatchAppendResp.ResultOneofCase.Success)); + Assert.That(response.Success.CurrentRevision, Is.EqualTo(2)); + } + + private ValueTask Append( + string streamName, + System.Collections.Generic.IEnumerable events) => + AppendToStreamBatch(new BatchAppendReq + { + Options = new() + { + NoStream = new(), + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(streamName) } + }, + CorrelationId = Uuid.NewUuid().ToDto(), + IsFinal = true, + ProposedMessages = { events } + }); +} diff --git a/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/isjson_flag_on_event.cs b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/isjson_flag_on_event.cs new file mode 100644 index 0000000000..62f61b059c --- /dev/null +++ b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/isjson_flag_on_event.cs @@ -0,0 +1,92 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using EventStore.Client.Streams; +using EventStore.Core.Messages; +using EventStore.Core.Messaging; +using EventStore.Core.Services.Transport.Grpc; +using EventStore.Core.TransactionLog.LogRecords; +using Google.Protobuf; +using NUnit.Framework; +using GrpcMetadata = EventStore.Core.Services.Transport.Grpc.Constants.Metadata; + +namespace EventStore.Core.Tests.Services.Transport.Grpc.StreamsTests; + +[TestFixture(typeof(LogFormat.V2), typeof(string))] +public class isjson_flag_on_event : GrpcSpecification +{ + private const string StreamName = nameof(isjson_flag_on_event); + private bool _allEventsAreJson; + + protected override async Task Given() + { + var json = ByteString.CopyFromUtf8("{\"some\":\"json\"}"); + var response = await AppendToStreamBatch(new BatchAppendReq + { + Options = new() + { + Any = new(), + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(StreamName) } + }, + CorrelationId = Uuid.NewUuid().ToDto(), + IsFinal = true, + ProposedMessages = + { + CreateJsonEvent(json, ByteString.Empty), + CreateJsonEvent(ByteString.Empty, json), + CreateJsonEvent(json, json) + } + }); + + Assert.That(response.ResultCase, Is.EqualTo(BatchAppendResp.ResultOneofCase.Success)); + } + + protected override async Task When() + { + var completion = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + Node.Node.MainQueue.Publish(new ClientMessage.ReadStreamEventsForward( + Guid.NewGuid(), + Guid.NewGuid(), + new CallbackEnvelope(message => + { + if (message is not ClientMessage.ReadStreamEventsForwardCompleted completed) + { + completion.TrySetException(new InvalidOperationException( + $"Unexpected response type {message.GetType().Name}.")); + return; + } + + completion.TrySetResult( + completed.Result == Data.ReadStreamResult.Success && + completed.Events.Count == 3 && + completed.Events.All(x => (x.OriginalEvent.Flags & PrepareFlags.IsJson) != 0)); + }), + StreamName, + 0, + 100, + false, + false, + null, + null, + replyOnExpired: false)); + + _allEventsAreJson = await completion.Task.WithTimeout(TimeSpan.FromSeconds(10)); + } + + [Test] + public void should_be_preserved_with_all_possible_write_and_read_methods() => + Assert.That(_allEventsAreJson, Is.True); + + private static BatchAppendReq.Types.ProposedMessage CreateJsonEvent(ByteString data, ByteString customMetadata) => + new() + { + Id = Uuid.NewUuid().ToDto(), + Metadata = + { + [GrpcMetadata.Type] = "some-type", + [GrpcMetadata.ContentType] = GrpcMetadata.ContentTypes.ApplicationJson + }, + Data = data, + CustomMetadata = customMetadata + }; +} diff --git a/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_backward_filtered_should.cs b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_backward_filtered_should.cs new file mode 100644 index 0000000000..f288829aaa --- /dev/null +++ b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_backward_filtered_should.cs @@ -0,0 +1,61 @@ +using System.Linq; +using System.Threading.Tasks; +using EventStore.Client.Streams; +using NUnit.Framework; + +namespace EventStore.Core.Tests.Services.Transport.Grpc.StreamsTests; + +[TestFixture(typeof(LogFormat.V2), typeof(string))] +public class read_all_events_backward_filtered_should + : FilteredReadAllSpecification +{ + private const ReadReq.Types.Options.Types.ReadDirection Direction = + ReadReq.Types.Options.Types.ReadDirection.Backwards; + + [Test] + public async Task only_return_events_with_a_given_stream_prefix() + { + var events = await Read(Direction, StreamPrefix(StreamA)); + + Assert.That(events, Has.Length.EqualTo(10)); + Assert.That(events.All(x => StreamName(x) == StreamA), Is.True); + Assert.That(events.Select(x => x.Event.StreamRevision), Is.EqualTo(Enumerable.Range(0, 10).Reverse())); + } + + [Test] + public async Task only_return_events_with_a_given_event_prefix() + { + var events = await Read(Direction, EventTypePrefix("AE")); + + Assert.That(events, Has.Length.EqualTo(10)); + Assert.That(events.All(x => EventType(x) == "AEvent"), Is.True); + } + + [Test] + public async Task only_return_events_that_satisfy_a_given_stream_regex() + { + var events = await Read(Direction, StreamRegex("^.*m-b.*$")); + + Assert.That(events, Has.Length.EqualTo(10)); + Assert.That(events.All(x => StreamName(x) == StreamB), Is.True); + Assert.That(events.Select(x => x.Event.StreamRevision), Is.EqualTo(Enumerable.Range(0, 10).Reverse())); + } + + [Test] + public async Task only_return_events_that_satisfy_a_given_event_regex() + { + var events = await Read(Direction, EventTypeRegex("^.*BEv.*$")); + + Assert.That(events, Has.Length.EqualTo(10)); + Assert.That(events.All(x => EventType(x) == "BEvent"), Is.True); + } + + [Test] + public async Task only_return_events_that_are_not_system_events() + { + var events = await Read(Direction, StreamRegex("^[^$].*")); + + Assert.That(events, Is.Not.Empty); + Assert.That(events.All(x => !EventType(x).StartsWith("$")), Is.True); + } +} diff --git a/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_forward_filtered_should.cs b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_forward_filtered_should.cs new file mode 100644 index 0000000000..f4d5efe5b4 --- /dev/null +++ b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_forward_filtered_should.cs @@ -0,0 +1,61 @@ +using System.Linq; +using System.Threading.Tasks; +using EventStore.Client.Streams; +using NUnit.Framework; + +namespace EventStore.Core.Tests.Services.Transport.Grpc.StreamsTests; + +[TestFixture(typeof(LogFormat.V2), typeof(string))] +public class read_all_events_forward_filtered_should + : FilteredReadAllSpecification +{ + private const ReadReq.Types.Options.Types.ReadDirection Direction = + ReadReq.Types.Options.Types.ReadDirection.Forwards; + + [Test] + public async Task only_return_events_with_a_given_stream_prefix() + { + var events = await Read(Direction, StreamPrefix(StreamA)); + + Assert.That(events, Has.Length.EqualTo(10)); + Assert.That(events.All(x => StreamName(x) == StreamA), Is.True); + Assert.That(events.Select(x => x.Event.StreamRevision), Is.EqualTo(Enumerable.Range(0, 10))); + } + + [Test] + public async Task only_return_events_with_a_given_event_prefix() + { + var events = await Read(Direction, EventTypePrefix("AE")); + + Assert.That(events, Has.Length.EqualTo(10)); + Assert.That(events.All(x => EventType(x) == "AEvent"), Is.True); + } + + [Test] + public async Task only_return_events_that_satisfy_a_given_stream_regex() + { + var events = await Read(Direction, StreamRegex("^.*eam-b.*$")); + + Assert.That(events, Has.Length.EqualTo(10)); + Assert.That(events.All(x => StreamName(x) == StreamB), Is.True); + Assert.That(events.Select(x => x.Event.StreamRevision), Is.EqualTo(Enumerable.Range(0, 10))); + } + + [Test] + public async Task only_return_events_that_satisfy_a_given_event_regex() + { + var events = await Read(Direction, EventTypeRegex("^.*BEv.*$")); + + Assert.That(events, Has.Length.EqualTo(10)); + Assert.That(events.All(x => EventType(x) == "BEvent"), Is.True); + } + + [Test] + public async Task only_return_events_that_are_not_system_events() + { + var events = await Read(Direction, StreamRegex("^[^$].*")); + + Assert.That(events, Is.Not.Empty); + Assert.That(events.All(x => !EventType(x).StartsWith("$")), Is.True); + } +} diff --git a/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_forward_with_hard_deleted_stream_should.cs b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_forward_with_hard_deleted_stream_should.cs new file mode 100644 index 0000000000..c476f5ab42 --- /dev/null +++ b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_forward_with_hard_deleted_stream_should.cs @@ -0,0 +1,114 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using EventStore.Client.Streams; +using EventStore.Core.Services; +using EventStore.Core.Services.Transport.Grpc; +using Google.Protobuf; +using Grpc.Core; +using NUnit.Framework; +using GrpcConstants = EventStore.Core.Services.Transport.Grpc.Constants; + +namespace EventStore.Core.Tests.Services.Transport.Grpc.StreamsTests; + +[TestFixture(typeof(LogFormat.V2), typeof(string))] +public class read_all_events_forward_with_hard_deleted_stream_should + : GrpcSpecification +{ + private const string StreamName = nameof(read_all_events_forward_with_hard_deleted_stream_should); + private readonly List _allEvents = new(); + private RpcException _streamReadException; + + protected override async Task Given() + { + var appendResponse = await AppendToStreamBatch(new BatchAppendReq + { + Options = new() + { + NoStream = new(), + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(StreamName) } + }, + CorrelationId = Uuid.NewUuid().ToDto(), + IsFinal = true, + ProposedMessages = { CreateEvents(20) } + }); + Assert.That(appendResponse.ResultCase, Is.EqualTo(BatchAppendResp.ResultOneofCase.Success)); + + await StreamsClient.TombstoneAsync(new() + { + Options = new() + { + Any = new(), + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(StreamName) } + } + }, GetCallOptions(AdminCredentials)); + } + + protected override async Task When() + { + try + { + using var streamCall = StreamsClient.Read(ReadStreamRequest(), GetCallOptions(AdminCredentials)); + await streamCall.ResponseStream.ReadAllAsync().ToArrayAsync(); + } + catch (RpcException ex) + { + _streamReadException = ex; + } + + using var allCall = StreamsClient.Read(ReadAllRequest(), GetCallOptions(AdminCredentials)); + _allEvents.AddRange((await allCall.ResponseStream.ReadAllAsync().ToArrayAsync()) + .Where(x => x.ContentCase == ReadResp.ContentOneofCase.Event) + .Select(x => x.Event)); + } + + [Test] + public void ensure_deleted_stream() + { + Assert.That(_streamReadException, Is.Not.Null); + Assert.That(_streamReadException.StatusCode, Is.EqualTo(StatusCode.FailedPrecondition)); + Assert.That(_streamReadException.Trailers.Select(x => (x.Key, x.Value)), + Does.Contain((GrpcConstants.Exceptions.ExceptionKey, GrpcConstants.Exceptions.StreamDeleted))); + } + + [Test] + public void returns_all_events_including_tombstone() + { + var streamEvents = _allEvents + .Where(x => x.Event.StreamIdentifier.StreamName.ToStringUtf8() == StreamName) + .ToArray(); + + Assert.That(streamEvents, Has.Length.EqualTo(21)); + Assert.That(streamEvents.Take(20).All(x => x.Event.Metadata[GrpcConstants.Metadata.Type] == "-"), Is.True); + Assert.That(streamEvents[^1].Event.Metadata[GrpcConstants.Metadata.Type], + Is.EqualTo(SystemEventTypes.StreamDeleted)); + } + + private static ReadReq ReadStreamRequest() => new() + { + Options = new() + { + UuidOption = new() { Structured = new() }, + NoFilter = new(), + ReadDirection = ReadReq.Types.Options.Types.ReadDirection.Forwards, + Count = 100, + Stream = new() + { + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(StreamName) }, + Start = new() + } + } + }; + + private static ReadReq ReadAllRequest() => new() + { + Options = new() + { + UuidOption = new() { Structured = new() }, + NoFilter = new(), + ReadDirection = ReadReq.Types.Options.Types.ReadDirection.Forwards, + Count = 100, + All = new() { Start = new() } + } + }; +} diff --git a/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_forward_with_soft_deleted_stream_should.cs b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_forward_with_soft_deleted_stream_should.cs new file mode 100644 index 0000000000..9a83152bee --- /dev/null +++ b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_all_events_forward_with_soft_deleted_stream_should.cs @@ -0,0 +1,111 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using EventStore.Client.Streams; +using EventStore.Core.Data; +using EventStore.Core.Services; +using EventStore.Core.Services.Transport.Grpc; +using Google.Protobuf; +using Grpc.Core; +using NUnit.Framework; +using GrpcConstants = EventStore.Core.Services.Transport.Grpc.Constants; + +namespace EventStore.Core.Tests.Services.Transport.Grpc.StreamsTests; + +[TestFixture(typeof(LogFormat.V2), typeof(string))] +public class read_all_events_forward_with_soft_deleted_stream_should + : GrpcSpecification +{ + private const string StreamName = nameof(read_all_events_forward_with_soft_deleted_stream_should); + private readonly List _streamResponses = new(); + private readonly List _allEvents = new(); + + protected override async Task Given() + { + var appendResponse = await AppendToStreamBatch(new BatchAppendReq + { + Options = new() + { + NoStream = new(), + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(StreamName) } + }, + CorrelationId = Uuid.NewUuid().ToDto(), + IsFinal = true, + ProposedMessages = { CreateEvents(20) } + }); + Assert.That(appendResponse.ResultCase, Is.EqualTo(BatchAppendResp.ResultOneofCase.Success)); + + await StreamsClient.DeleteAsync(new() + { + Options = new() + { + Any = new(), + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(StreamName) } + } + }, GetCallOptions(AdminCredentials)); + } + + protected override async Task When() + { + using (var streamCall = StreamsClient.Read(ReadStreamRequest(), GetCallOptions(AdminCredentials))) + { + _streamResponses.AddRange(await streamCall.ResponseStream.ReadAllAsync().ToArrayAsync()); + } + + using var allCall = StreamsClient.Read(ReadAllRequest(), GetCallOptions(AdminCredentials)); + _allEvents.AddRange((await allCall.ResponseStream.ReadAllAsync().ToArrayAsync()) + .Where(x => x.ContentCase == ReadResp.ContentOneofCase.Event) + .Select(x => x.Event)); + } + + [Test] + public void ensure_deleted_stream() + { + Assert.That(_streamResponses.Count(x => x.ContentCase == ReadResp.ContentOneofCase.Event), Is.Zero); + Assert.That(_streamResponses.Single().ContentCase, Is.EqualTo(ReadResp.ContentOneofCase.StreamNotFound)); + } + + [Test] + public void returns_all_events_including_tombstone() + { + var streamEvents = _allEvents + .Where(x => x.Event.StreamIdentifier.StreamName.ToStringUtf8() == StreamName) + .ToArray(); + Assert.That(streamEvents, Has.Length.EqualTo(20)); + Assert.That(streamEvents.All(x => x.Event.Metadata[GrpcConstants.Metadata.Type] == "-"), Is.True); + + var metadataEvent = _allEvents.Single(x => + x.Event.StreamIdentifier.StreamName.ToStringUtf8() == SystemStreams.MetastreamOf(StreamName)); + Assert.That(metadataEvent.Event.Metadata[GrpcConstants.Metadata.Type], Is.EqualTo(SystemEventTypes.StreamMetadata)); + Assert.That(StreamMetadata.FromJsonBytes(metadataEvent.Event.Data.Memory).TruncateBefore, + Is.EqualTo(EventNumber.DeletedStream)); + } + + private static ReadReq ReadStreamRequest() => new() + { + Options = new() + { + UuidOption = new() { Structured = new() }, + NoFilter = new(), + ReadDirection = ReadReq.Types.Options.Types.ReadDirection.Forwards, + Count = 100, + Stream = new() + { + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(StreamName) }, + Start = new() + } + } + }; + + private static ReadReq ReadAllRequest() => new() + { + Options = new() + { + UuidOption = new() { Structured = new() }, + NoFilter = new(), + ReadDirection = ReadReq.Types.Options.Types.ReadDirection.Forwards, + Count = 100, + All = new() { Start = new() } + } + }; +} diff --git a/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_event_should.cs b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_event_should.cs new file mode 100644 index 0000000000..77727d0bf4 --- /dev/null +++ b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/read_event_should.cs @@ -0,0 +1,169 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using EventStore.Client; +using EventStore.Client.Streams; +using EventStore.Core.Services.Transport.Grpc; +using Google.Protobuf; +using Grpc.Core; +using NUnit.Framework; +using GrpcConstants = EventStore.Core.Services.Transport.Grpc.Constants; + +namespace EventStore.Core.Tests.Services.Transport.Grpc.StreamsTests; + +[TestFixture(typeof(LogFormat.V2), typeof(string))] +public class read_event_should : GrpcSpecification +{ + private const string StreamName = "test-stream"; + private const string DeletedStreamName = "deleted-stream"; + private readonly Uuid _eventId0 = Uuid.NewUuid(); + private readonly Uuid _eventId1 = Uuid.NewUuid(); + + protected override async Task Given() + { + await AppendToStreamBatch(new BatchAppendReq + { + Options = new() + { + NoStream = new(), + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(StreamName) } + }, + CorrelationId = Uuid.NewUuid().ToDto(), + IsFinal = true, + ProposedMessages = + { + CreateEvent(_eventId0, "event0", GrpcConstants.Metadata.ContentTypes.ApplicationOctetStream), + CreateEvent(_eventId1, "event1", GrpcConstants.Metadata.ContentTypes.ApplicationJson) + } + }); + + await StreamsClient.TombstoneAsync(new() + { + Options = new() + { + NoStream = new(), + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(DeletedStreamName) } + } + }, GetCallOptions(AdminCredentials)); + } + + protected override Task When() => Task.CompletedTask; + + [Test] + public async Task notify_using_status_code_if_stream_not_found() + { + var responses = await Read("unexisting-stream", revision: 5); + + Assert.That(responses, Has.Length.EqualTo(1)); + Assert.That(responses[0].ContentCase, Is.EqualTo(ReadResp.ContentOneofCase.StreamNotFound)); + Assert.That(responses[0].StreamNotFound.StreamIdentifier.StreamName.ToStringUtf8(), + Is.EqualTo("unexisting-stream")); + } + + [Test] + public async Task return_no_stream_if_requested_last_event_in_empty_stream() + { + var responses = await Read("some-really-empty-stream", fromEnd: true); + + Assert.That(responses, Has.Length.EqualTo(1)); + Assert.That(responses[0].ContentCase, Is.EqualTo(ReadResp.ContentOneofCase.StreamNotFound)); + } + + [Test] + public void notify_using_status_code_if_stream_was_deleted() + { + var exception = Assert.ThrowsAsync(async () => await Read(DeletedStreamName, revision: 5)); + + Assert.That(exception.StatusCode, Is.EqualTo(StatusCode.FailedPrecondition)); + Assert.That(exception.Trailers.Select(x => (x.Key, x.Value)), + Does.Contain((GrpcConstants.Exceptions.ExceptionKey, GrpcConstants.Exceptions.StreamDeleted))); + } + + [Test] + public async Task notify_using_status_code_if_stream_does_not_have_event() + { + var responses = await Read(StreamName, revision: 5); + + Assert.That(responses.Count(x => x.ContentCase == ReadResp.ContentOneofCase.Event), Is.Zero); + } + + [Test] + public async Task return_existing_event() + { + var readEvent = (await Read(StreamName, revision: 0)) + .Single(x => x.ContentCase == ReadResp.ContentOneofCase.Event).Event; + + Assert.That(Uuid.FromDto(readEvent.Event.Id), Is.EqualTo(_eventId0)); + Assert.That(readEvent.Event.StreamIdentifier.StreamName.ToStringUtf8(), Is.EqualTo(StreamName)); + Assert.That(readEvent.Event.StreamRevision, Is.Zero); + Assert.That(readEvent.Event.Metadata[GrpcConstants.Metadata.Created], Is.Not.Empty); + } + + [Test] + public async Task retrieve_the_is_json_flag_properly() + { + var readEvent = (await Read(StreamName, revision: 1)) + .Single(x => x.ContentCase == ReadResp.ContentOneofCase.Event).Event; + + Assert.That(Uuid.FromDto(readEvent.Event.Id), Is.EqualTo(_eventId1)); + Assert.That(readEvent.Event.Metadata[GrpcConstants.Metadata.ContentType], + Is.EqualTo(GrpcConstants.Metadata.ContentTypes.ApplicationJson)); + } + + [Test] + public async Task return_last_event_in_stream_if_event_number_is_minus_one() + { + var readEvent = (await Read(StreamName, fromEnd: true)) + .Single(x => x.ContentCase == ReadResp.ContentOneofCase.Event).Event; + + Assert.That(Uuid.FromDto(readEvent.Event.Id), Is.EqualTo(_eventId1)); + Assert.That(readEvent.Event.StreamIdentifier.StreamName.ToStringUtf8(), Is.EqualTo(StreamName)); + Assert.That(readEvent.Event.StreamRevision, Is.EqualTo(1)); + Assert.That(readEvent.Event.Metadata[GrpcConstants.Metadata.Created], Is.Not.Empty); + } + + private async Task Read(string streamName, ulong revision = 0, bool fromEnd = false) + { + var request = new ReadReq + { + Options = new() + { + UuidOption = new() { Structured = new() }, + NoFilter = new(), + ReadDirection = fromEnd + ? ReadReq.Types.Options.Types.ReadDirection.Backwards + : ReadReq.Types.Options.Types.ReadDirection.Forwards, + Count = 1, + Stream = new() + { + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(streamName) } + } + } + }; + + if (fromEnd) + { + request.Options.Stream.End = new(); + } + else + { + request.Options.Stream.Revision = revision; + } + + using var call = StreamsClient.Read(request, GetCallOptions(AdminCredentials)); + return await call.ResponseStream.ReadAllAsync().ToArrayAsync(); + } + + private static BatchAppendReq.Types.ProposedMessage CreateEvent(Uuid id, string eventType, string contentType) => + new() + { + Id = id.ToDto(), + Metadata = + { + [GrpcConstants.Metadata.Type] = eventType, + [GrpcConstants.Metadata.ContentType] = contentType + }, + Data = ByteString.Empty, + CustomMetadata = ByteString.Empty + }; +} diff --git a/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/subscribe_should.cs b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/subscribe_should.cs new file mode 100644 index 0000000000..6c990134e0 --- /dev/null +++ b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/subscribe_should.cs @@ -0,0 +1,66 @@ +using System.Threading.Tasks; +using EventStore.Client.Streams; +using EventStore.Core.Services; +using EventStore.Core.Services.Transport.Grpc; +using Google.Protobuf; +using Grpc.Core; +using NUnit.Framework; +using GrpcMetadata = EventStore.Core.Services.Transport.Grpc.Constants.Metadata; + +namespace EventStore.Core.Tests.Services.Transport.Grpc.StreamsTests; + +[TestFixture(typeof(LogFormat.V2), typeof(string))] +public class subscribe_should : GrpcSpecification +{ + protected override Task Given() => Task.CompletedTask; + + protected override Task When() => Task.CompletedTask; + + [Test] + public async Task catch_deleted_events_as_well() + { + const string streamName = nameof(catch_deleted_events_as_well); + using var subscription = StreamsClient.Read(new() + { + Options = new() + { + Subscription = new(), + NoFilter = new(), + ReadDirection = ReadReq.Types.Options.Types.ReadDirection.Forwards, + UuidOption = new() { Structured = new() }, + Stream = new() + { + End = new(), + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(streamName) } + } + } + }, GetCallOptions(AdminCredentials)); + + Assert.That(await subscription.ResponseStream.MoveNext(), Is.True); + Assert.That(subscription.ResponseStream.Current.ContentCase, + Is.EqualTo(ReadResp.ContentOneofCase.Confirmation)); + + await StreamsClient.TombstoneAsync(new() + { + Options = new() + { + NoStream = new(), + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(streamName) } + } + }, GetCallOptions(AdminCredentials)); + + ReadResp deleted = null; + while (await subscription.ResponseStream.MoveNext()) + { + if (subscription.ResponseStream.Current.ContentCase == ReadResp.ContentOneofCase.Event) + { + deleted = subscription.ResponseStream.Current; + break; + } + } + + Assert.That(deleted, Is.Not.Null); + Assert.That(deleted.Event.Event.StreamIdentifier.StreamName.ToStringUtf8(), Is.EqualTo(streamName)); + Assert.That(deleted.Event.Event.Metadata[GrpcMetadata.Type], Is.EqualTo(SystemEventTypes.StreamDeleted)); + } +} diff --git a/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/subscribe_to_all_should.cs b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/subscribe_to_all_should.cs new file mode 100644 index 0000000000..90d5b20462 --- /dev/null +++ b/src/EventStore.Core.Tests/Services/Transport/Grpc/StreamsTests/subscribe_to_all_should.cs @@ -0,0 +1,99 @@ +using System.Linq; +using System.Threading.Tasks; +using EventStore.Client.Streams; +using EventStore.Core.Services; +using EventStore.Core.Services.Transport.Grpc; +using Google.Protobuf; +using Grpc.Core; +using NUnit.Framework; +using GrpcMetadata = EventStore.Core.Services.Transport.Grpc.Constants.Metadata; + +namespace EventStore.Core.Tests.Services.Transport.Grpc.StreamsTests; + +[TestFixture(typeof(LogFormat.V2), typeof(string))] +public class subscribe_to_all_should : GrpcSpecification +{ + protected override Task Given() => Task.CompletedTask; + + protected override Task When() => Task.CompletedTask; + + [Test] + public async Task allow_multiple_subscriptions() + { + const string streamName = nameof(allow_multiple_subscriptions); + using var first = StreamsClient.Read(SubscribeRequest(), GetCallOptions(AdminCredentials)); + using var second = StreamsClient.Read(SubscribeRequest(), GetCallOptions(AdminCredentials)); + + Assert.That(await first.ResponseStream.MoveNext(), Is.True); + Assert.That(first.ResponseStream.Current.ContentCase, Is.EqualTo(ReadResp.ContentOneofCase.Confirmation)); + Assert.That(await second.ResponseStream.MoveNext(), Is.True); + Assert.That(second.ResponseStream.Current.ContentCase, Is.EqualTo(ReadResp.ContentOneofCase.Confirmation)); + + await AppendToStreamBatch(new BatchAppendReq + { + Options = new() + { + NoStream = new(), + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(streamName) } + }, + CorrelationId = Uuid.NewUuid().ToDto(), + IsFinal = true, + ProposedMessages = { CreateEvents(1) } + }); + + Assert.That(await ReadNextEvent(first), Is.EqualTo(streamName)); + Assert.That(await ReadNextEvent(second), Is.EqualTo(streamName)); + } + + [Test] + public async Task catch_deleted_events_as_well() + { + const string streamName = nameof(catch_deleted_events_as_well); + using var subscription = StreamsClient.Read(SubscribeRequest(), GetCallOptions(AdminCredentials)); + Assert.That(await subscription.ResponseStream.MoveNext(), Is.True); + Assert.That(subscription.ResponseStream.Current.ContentCase, + Is.EqualTo(ReadResp.ContentOneofCase.Confirmation)); + + await StreamsClient.TombstoneAsync(new() + { + Options = new() + { + NoStream = new(), + StreamIdentifier = new() { StreamName = ByteString.CopyFromUtf8(streamName) } + } + }, GetCallOptions(AdminCredentials)); + + var deleted = await ReadNextEventResponse(subscription); + Assert.That(deleted.Event.StreamIdentifier.StreamName.ToStringUtf8(), Is.EqualTo(streamName)); + Assert.That(deleted.Event.Metadata[GrpcMetadata.Type], Is.EqualTo(SystemEventTypes.StreamDeleted)); + } + + private static ReadReq SubscribeRequest() => new() + { + Options = new() + { + Subscription = new(), + NoFilter = new(), + ReadDirection = ReadReq.Types.Options.Types.ReadDirection.Forwards, + UuidOption = new() { Structured = new() }, + All = new() { End = new() } + } + }; + + private static async Task ReadNextEvent(global::Grpc.Core.AsyncServerStreamingCall subscription) => + (await ReadNextEventResponse(subscription)).Event.StreamIdentifier.StreamName.ToStringUtf8(); + + private static async Task ReadNextEventResponse( + global::Grpc.Core.AsyncServerStreamingCall subscription) + { + while (await subscription.ResponseStream.MoveNext()) + { + if (subscription.ResponseStream.Current.ContentCase == ReadResp.ContentOneofCase.Event) + { + return subscription.ResponseStream.Current.Event; + } + } + + throw new AssertionException("The subscription ended before an event was received."); + } +}