/// <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);
            }
        }
Exemple #2
0
        /// <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);
        }
Exemple #4
0
        /// <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);
        }
Exemple #5
0
        /// <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);
        }
Exemple #6
0
        /// <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);
        }
Exemple #7
0
        /// <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);
        }
Exemple #8
0
        /// <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);
            }
        }