/// <summary> /// Seeds the Event Hub partition with enough events to satisfy the read operations the test scenario /// is expected to perform. /// </summary> /// /// <param name="producer">The producer to use for publishing events; ownership is assumed to be retained by the caller.</param> /// <param name="bodySizeBytes">The size, in bytes, that the body of events used to seed the Event Hub should be.</param> /// <param name="eventCount">The number of events that should be published, distributed among partitions.</param> /// private static async Task SeedEventsToBeReadAsync(EventHubProducerClient producer, int bodySizeBytes, int eventCount) { // Use the same event body for all events being published, to ensure consistency of the data being // read and processed for the test. var eventBody = EventGenerator.CreateRandomBody(bodySizeBytes); var remainingEvents = eventCount; while (remainingEvents > 0) { using var batch = await producer.CreateBatchAsync().ConfigureAwait(false); while ((batch.TryAdd(EventGenerator.CreateEventFromBody(eventBody))) && (remainingEvents > 0)) { --remainingEvents; } // If there were no events in the batch, then a single event was generated that is too large to // ever send. In this context, it will be detected on the first TryAdd call, since events are // sharing a common body. if (batch.Count == 0) { throw new InvalidOperationException("There was an event too large to fit into a batch."); } await producer.SendAsync(batch).ConfigureAwait(false); } }
/// <summary> /// Seeds the Event Hub partition with enough events to satisfy the read operations the test scenario /// is expected to perform. /// </summary> /// /// <param name="producer">The producer to use for publishing events; ownership is assumed to be retained by the caller.</param> /// /// <remarks> /// This method makes heavy use of class state, including the /// test environment and command line options. /// </remarks> /// private async Task SeedEventsToBeReadAsync(EventHubProducerClient producer) { // Calculate the number of events needed to satisfy the number of events per iteration // and then buffer it to allow for the warm-up. var eventCount = Options.BatchSize * Options.Iterations * 3; var eventBody = EventGenerator.CreateRandomBody(Options.BodySize); var batchOptions = new CreateBatchOptions { PartitionId = PartitionId }; foreach (var eventData in EventGenerator.CreateEventsFromBody(eventCount, eventBody)) { using var batch = await producer.CreateBatchAsync(batchOptions).ConfigureAwait(false); // Fill the batch with as many events that will fit. while (batch.TryAdd(EventGenerator.CreateEventFromBody(eventBody))) { } // If there were no events in the batch, then a single event was generated that is too large to // ever send. In this context, it will be detected on the first TryAdd call, since events are // sharing a common body. if (batch.Count == 0) { throw new InvalidOperationException("There was an event too large to fit into a batch."); } await producer.SendAsync(batch).ConfigureAwait(false); } }
/// <summary> /// Performs the tasks needed to initialize and set up the environment for the test scenario. /// When multiple instances are run in parallel, the setup will take place once, prior to the /// execution of the first test instance. /// </summary> /// public async override Task GlobalSetupAsync() { await base.GlobalSetupAsync().ConfigureAwait(false); s_scope = await EventHubScope.CreateAsync(Options.PartitionCount).ConfigureAwait(false); s_producer = new EventHubProducerClient(TestEnvironment.EventHubsConnectionString, s_scope.EventHubName); s_eventBody = EventGenerator.CreateRandomBody(Options.BodySize); }
/// <summary> /// Performs the tasks needed to initialize and set up the environment for the test scenario. /// When multiple instances are run in parallel, the setup will take place once, prior to the /// execution of the first test instance. /// </summary> /// public async override Task GlobalSetupAsync() { await base.GlobalSetupAsync().ConfigureAwait(false); s_scope = await EventHubScope.CreateAsync(4).ConfigureAwait(false); s_client = EventHubClient.CreateFromConnectionString(TestUtility.BuildEventHubsConnectionString(s_scope.EventHubName)); s_eventBody = EventGenerator.CreateRandomBody(Options.Size); // Publish an empty event to force the connection and link to be established. await s_client.SendAsync(new[] { new EventData(Array.Empty <byte>()) }).ConfigureAwait(false); }
/// <summary> /// Performs the tasks needed to initialize and set up the environment for the test scenario. /// When multiple instances are run in parallel, the setup will take place once, prior to the /// execution of the first test instance. /// </summary> /// public async override Task GlobalSetupAsync() { await base.GlobalSetupAsync().ConfigureAwait(false); s_scope = await EventHubScope.CreateAsync(4).ConfigureAwait(false); s_producer = new EventHubProducerClient(TestEnvironment.EventHubsConnectionString, s_scope.EventHubName); s_sendOptions = await CreateSendOptions(s_producer).ConfigureAwait(false); s_eventBody = EventGenerator.CreateRandomBody(Options.Size); // Publish an empty event to force the connection and link to be established. await s_producer.SendAsync(new[] { new EventData(Array.Empty <byte>()) }, s_sendOptions).ConfigureAwait(false); }
/// <summary> /// Performs the tasks needed to initialize and set up the environment for the test scenario. /// When multiple instances are run in parallel, the setup will take place once, prior to the /// execution of the first test instance. /// </summary> /// public async override Task GlobalSetupAsync() { await base.GlobalSetupAsync().ConfigureAwait(false); s_scope = await EventHubScope.CreateAsync(4).ConfigureAwait(false); s_client = EventHubClient.CreateFromConnectionString(TestUtility.BuildEventHubsConnectionString(s_scope.EventHubName)); s_eventBody = EventGenerator.CreateRandomBody(Options.Size); // Publish an empty event to force the connection and link to be established. using var batch = s_client.CreateBatch(); if (!batch.TryAdd(new EventData(Array.Empty <byte>()))) { throw new InvalidOperationException("The empty event could not be added to the batch during global setup."); } await s_client.SendAsync(batch).ConfigureAwait(false); }
/// <summary> /// Performs the tasks needed to initialize and set up the environment for the test scenario. /// When multiple instances are run in parallel, the setup will take place once, prior to the /// execution of the first test instance. /// </summary> /// public async override Task GlobalSetupAsync() { await base.GlobalSetupAsync().ConfigureAwait(false); s_scope = await EventHubScope.CreateAsync(4).ConfigureAwait(false); s_producer = new EventHubProducerClient(TestEnvironment.EventHubsConnectionString, s_scope.EventHubName); s_batchOptions = await CreateBatchOptions(s_producer).ConfigureAwait(false); s_eventBody = EventGenerator.CreateRandomBody(Options.Size); // Publish an empty event to force the connection and link to be established. using var batch = await s_producer.CreateBatchAsync(s_batchOptions).ConfigureAwait(false); if (!batch.TryAdd(new EventData(Array.Empty <byte>()))) { throw new InvalidOperationException("The empty event could not be added to the batch during global setup."); } await s_producer.SendAsync(batch).ConfigureAwait(false); }
/// <summary> /// Enqueues events into the buffer to be published. /// </summary> /// /// <param name="testOptions">The set of options governing test execution.</param> /// private async Task EnqueueEvents(CancellationToken cancellationToken) { var eventBody = EventGenerator.CreateRandomBody(Options.BodySize); try { while (!cancellationToken.IsCancellationRequested) { var enqueueOptions = CreateEnqueueOptions(); // Generate events using the same body. This will result in publishing a set of events // of equal size. The events will only differ by the id property that is assigned to them. if (Options.BatchSize > 1) { await _producer.EnqueueEventsAsync(EventGenerator.CreateEventsFromBody(Options.BatchSize, eventBody), enqueueOptions, cancellationToken).ConfigureAwait(false); } else { await _producer.EnqueueEventAsync(EventGenerator.CreateEventFromBody(eventBody), enqueueOptions, cancellationToken).ConfigureAwait(false); } } } catch (OperationCanceledException) { // Expected } catch (EventHubsException ex) when((cancellationToken.IsCancellationRequested) && (ex.IsTransient)) { // If the enqueue is canceled during a retry loop, the most recent exception is thrown. // If the exception is transient, it should be ignored. } catch (Exception ex) { ErrorRaised(ex); } }