public async Task ConnectWorker_FollowsFailureOptionsIfTheWorkerFuncDoesntTakeAction() { await ConnectAsync(); await prod.UseAsync("watched"); await DrainUsedTube(); int receivedJobId = 0; var options = new WorkerOptions { Tubes = { "watched" }, FailureBehavior = WorkerFailureBehavior.Bury }; var worker = BeanstalkConnection.ConnectWorkerAsync(connectionString, options, async(c, job) => { if (receivedJobId == 0) { receivedJobId = job.Id; } await Task.Delay(0); // Don't call any IWorker methods }); using (await worker) { await prod.PutAsync(new byte[] { }, 1, TenSeconds, ZeroSeconds); await Task.Delay(100); } var stat = await prod.JobStatisticsAsync(receivedJobId); Assert.Equal(JobState.Buried, stat.State); }
public ItemSyncJob(IStockItemRepository stockRepository, ICrmRepository crmRepository, IOptions <WorkerOptions> options) { _crmRepository = crmRepository ?? throw new ArgumentNullException(nameof(crmRepository)); _stockRepository = stockRepository ?? throw new ArgumentNullException(nameof(stockRepository)); _options = options?.Value ?? throw new ArgumentNullException(nameof(options)); }
public async Task ConnectWorker_StopsWhenDisposed() { await ConnectAsync(); var tube = "i-am-a-tube"; int counter = 0; var options = new WorkerOptions { Tubes = { tube } }; var worker = BeanstalkConnection.ConnectWorkerAsync(connectionString, options, async(c, job) => { counter++; await c.DeleteAsync(); }); using (await worker) { await prod.UseAsync(tube); await prod.PutAsync(new byte[] { }, 1, TenSeconds, ZeroSeconds); await Task.Delay(200); } Assert.True(counter > 0); var finalValue = counter; await prod.PutAsync(new byte[] { }, 1, TenSeconds, ZeroSeconds); await Task.Delay(200); Assert.Equal(finalValue, counter); }
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseWindowsService() .ConfigureHostConfiguration(BuildConfiguration) .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureContainer <ContainerBuilder>(builder => { builder.RegisterType <SecurityHelper>(); builder.RegisterType <SqlConnectionHelper>().As <ISqlConnectionHelper>(); builder.RegisterType <QueryBuilderService>().As <IQueryBuilderService>(); builder.RegisterType <DapperQueryService>().As <IDapperQueryService>(); builder.RegisterType <RabbitMqListenerService>().As <IRabbitMqListenerService>(); }) .ConfigureServices((hostContext, services) => { IConfiguration configuration = hostContext.Configuration; WorkerOptions workerOptions = configuration.GetSection("WorkerOptions").Get <WorkerOptions>(); services.AddSingleton(workerOptions); services.AddHostedService <Worker>(); services.AddDbContext <QueryBuilderDbContext>(options => options .UseSqlServer(configuration.GetValue <string>("ConnectionString"), providerOptions => providerOptions.CommandTimeout(configuration.GetValue <int>("ConnectionStringTimeOut"))) .UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll)); }) .UseWindowsService() .UseSerilog();
public async Task ConnectWorker_CallsTheWorkerOnTheCurrentSyncContextByDefault() { await ConnectAsync(); const int MESSAGE_COUNT = 10; int wrongContextCount = 0; SynchronizationContext startingContext = SynchronizationContext.Current; var options = new WorkerOptions { }; var countdown = new CountdownEvent(MESSAGE_COUNT); var worker = BeanstalkConnection.ConnectWorkerAsync(connectionString, options, async(c, job) => { countdown.Signal(); if (startingContext != SynchronizationContext.Current) { wrongContextCount++; } await c.DeleteAsync(); }); using (await worker) { foreach (var n in Enumerable.Repeat(0, MESSAGE_COUNT)) { await prod.PutAsync(BitConverter.GetBytes(n), 1, TenSeconds, ZeroSeconds); } var consumedAllMessages = countdown.Wait(TimeSpan.FromSeconds(10)); Assert.True(consumedAllMessages, $"Did not consume all messages, remaining: {countdown.CurrentCount}"); } Assert.Equal(0, wrongContextCount); }
public YahooService(WorkerOptions workerOptions) { _client = new HttpClient(); _client.BaseAddress = new Uri(workerOptions.YahooFinanceApi.ApiUrl); _client.DefaultRequestHeaders.Add("x-rapidapi-key", workerOptions.YahooFinanceApi.ApiKey); _client.DefaultRequestHeaders.Add("x-rapidapi-host", workerOptions.YahooFinanceApi.ApiHost); }
public TcpServer(KeyEventProcessor keyEventProcessor, WorkerOptions options, ILogger <TcpServer> logger) { _keyEventMessageProcessor = keyEventProcessor; _logger = logger; _port = options.Port; _ipTemplate = options.IpTemplate; }
//------------------------------------------------------------------------- /// <summary> /// Executes the conversion of test-files asynchronously. /// </summary> /// <param name="options">The <see cref="WorkerOptions"/> to use for the conversion.</param> /// <returns>A task that completes when the conversion is finished.</returns> /// <exception cref="ArgumentNullException"> /// Thrown when <paramref name="options"/> is <c>null</c>. /// </exception> public async Task RunAsync(WorkerOptions options) { #if NET6_0_OR_GREATER ArgumentNullException.ThrowIfNull(options); #else if (options is null) { throw new ArgumentNullException(nameof(options)); } #endif Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; _globHandler.ExpandWildcards(options); ITestResultXmlConverter converter; if (options.ConvertToJunit) { converter = new Trx2JunitTestResultXmlConverter(); Console.WriteLine($"Converting {options.InputFiles.Count} trx file(s) to JUnit-xml..."); } else { converter = new Junit2TrxTestResultXmlConverter(); Console.WriteLine($"Converting {options.InputFiles.Count} junit file(s) to trx-xml..."); } DateTime start = DateTime.Now; await Task.WhenAll(options.InputFiles.Select(input => this.ConvertAsync(converter, input, options.OutputDirectory))); Console.WriteLine($"done in {(DateTime.Now - start).TotalSeconds} seconds. bye."); }
//------------------------------------------------------------------------- /// <inheritdoc/> public void ExpandWildcards(WorkerOptions options) { #if NET6_0_OR_GREATER ArgumentNullException.ThrowIfNull(options); #else if (options is null) { throw new ArgumentNullException(nameof(options)); } #endif var expandedFiles = new List <string>(); foreach (string inpupt in options.InputFiles) { if (!inpupt.Contains('*')) { expandedFiles.Add(inpupt); continue; } this.Expand(inpupt, expandedFiles); } options.InputFiles = expandedFiles; }
public async Task ServiceBusQueueMessagePumpUsingManagedIdentity_PublishServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Queue); ServiceBusConnectionStringProperties properties = ServiceBusConnectionStringProperties.Parse(connectionString); ServicePrincipal servicePrincipal = config.GetServiceBusServicePrincipal(); string tenantId = config.GetTenantId(); using (TemporaryEnvironmentVariable.Create(EnvironmentVariables.AzureTenantId, tenantId)) using (TemporaryEnvironmentVariable.Create(EnvironmentVariables.AzureServicePrincipalClientId, servicePrincipal.ClientId)) using (TemporaryEnvironmentVariable.Create(EnvironmentVariables.AzureServicePrincipalClientSecret, servicePrincipal.ClientSecret)) { var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusQueueMessagePumpUsingManagedIdentity( queueName: properties.EntityPath, serviceBusNamespace: properties.FullyQualifiedNamespace, clientId: servicePrincipal.ClientId, configureMessagePump: opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <OrdersAzureServiceBusMessageHandler, Order>(); // Act await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Assert await service.SimulateMessageProcessingAsync(connectionString); } } }
public async Task ServiceBusTopicMessagePumpWithNamespaceScopedConnectionString_PublishesServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string topicConnectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Topic); var properties = ServiceBusConnectionStringProperties.Parse(topicConnectionString); string namespaceConnectionString = properties.GetNamespaceConnectionString(); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusTopicMessagePump( topicName: properties.EntityPath, subscriptionName: "Test-Receive-All-Topic-Only", getConnectionStringFromConfigurationFunc: configuration => namespaceConnectionString, configureMessagePump: opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <OrdersAzureServiceBusMessageHandler, Order>(); // Act await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Assert await service.SimulateMessageProcessingAsync(topicConnectionString); } }
public async Task ServiceBusQueueMessagePumpWithContextAndBodyFilteringWithSerializer_RoutesServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Queue); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddServiceBusQueueMessagePump(configuration => connectionString, opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <PassThruOrderMessageHandler, Order>(messageContextFilter: context => false) .WithServiceBusMessageHandler <CustomerMessageHandler, Customer>(messageBodyFilter: message => true) .WithServiceBusMessageHandler <OrderBatchMessageHandler, OrderBatch>( messageContextFilter: context => context != null, messageBodySerializerImplementationFactory: serviceProvider => { var logger = serviceProvider.GetService <ILogger <OrderBatchMessageBodySerializer> >(); return(new OrderBatchMessageBodySerializer(logger)); }, messageBodyFilter: message => message.Orders.Length == 1); // Act await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Assert await service.SimulateMessageProcessingAsync(connectionString); } }
public async Task ServiceBusQueueMessagePumpWithServiceBusDeadLetterOnFallback_PublishServiceBusMessage_MessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); string connectionString = config.GetServiceBusConnectionString(ServiceBusEntityType.Queue); var options = new WorkerOptions(); options.AddServiceBusQueueMessagePump( configuration => connectionString, opt => opt.AutoComplete = false) .WithServiceBusMessageHandler <ShipmentAzureServiceBusMessageHandler, Shipment>((AzureServiceBusMessageContext context) => true) .WithServiceBusFallbackMessageHandler <OrdersAzureServiceBusDeadLetterFallbackMessageHandler>(); Order order = OrderGenerator.Generate(); await using (var worker = await Worker.StartNewAsync(options)) await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Act await service.SendMessageToServiceBusAsync(connectionString, order.AsServiceBusMessage()); // Assert await service.AssertDeadLetterMessageAsync(connectionString); } }
public async Task ConnectWorker_WatchesOnlySpecifiedTubes() { await ConnectAsync(); await prod.UseAsync("watched"); await DrainUsedTube(); int counter = 0; var options = new WorkerOptions { Tubes = { "watched" } }; var worker = BeanstalkConnection.ConnectWorkerAsync(connectionString, options, async(c, job) => { counter++; await c.DeleteAsync(); }); using (await worker) { await prod.PutAsync(new byte[] { }, 1, TenSeconds, ZeroSeconds); await prod.UseAsync("default"); await prod.PutAsync(new byte[] { }, 1, TenSeconds, ZeroSeconds); await Task.Delay(200); } Assert.Equal(1, counter); }
public Worker(ILogger <Worker> logger, WorkerOptions options, ICelebration birthdayService, ICommunication comms) { _logger = logger; _options = options; _birthdayService = birthdayService; this.comms = comms; }
public void Output_arg_given_but_no_value___throws_ArgumentException() { string[] args = { "a.trx", "--output" }; ArgumentException actual = Assert.Throws <ArgumentException>(() => WorkerOptions.Parse(args)); Assert.AreEqual("--output specified, but no value is given. An output-directory needs to specified in this case.", actual.Message); }
private static void AddServiceBusMessagePump(WorkerOptions options, KeyRotationConfig rotationConfig, string jobId) { options.AddServiceBusQueueMessagePump(rotationConfig.KeyVault.SecretName, opt => { opt.JobId = jobId; // Unrealistic big maximum exception count so that we're certain that the message pump gets restarted based on the notification and not the unauthorized exception. opt.MaximumUnauthorizedExceptionsBeforeRestart = 1000; }).WithServiceBusMessageHandler <OrdersAzureServiceBusMessageHandler, Order>(); }
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureServices((hostContext, services) => { IConfiguration configuration = hostContext.Configuration; WorkerOptions options = configuration.GetSection("WCF").Get <WorkerOptions>(); services.AddSingleton(options); services.AddHostedService <Worker>(); });
private static void AddSecretStore(WorkerOptions options, KeyRotationConfig rotationConfig) { options.Configure(host => host.ConfigureSecretStore((configuration, stores) => { stores.AddAzureKeyVaultWithServicePrincipal( rotationConfig.KeyVault.VaultUri, rotationConfig.ServicePrincipal.ClientId, rotationConfig.ServicePrincipal.ClientSecret) .AddConfiguration(configuration); })); }
public void WorkerOptions_without_wildcards___nothing_changed() { string[] inputFiles = { "a.txt", "b.txt" }; var options = new WorkerOptions(inputFiles); GlobHandler sut = this.CreateSut(); sut.ExpandWildcards(options); CollectionAssert.AreEqual(inputFiles, options.InputFiles); }
public Worker(ILogger <Worker> logger, IConfiguration configuration) { var workerOptions = new WorkerOptions(); configuration.Bind("Kafka", workerOptions); _logger = logger; _kafkaOptions = new KafkaOptions(new Uri(workerOptions.BootstrapServers)); _brokerRouter = new BrokerRouter(_kafkaOptions); _consumer = new KafkaNet.Consumer(new ConsumerOptions(workerOptions.Topic, _brokerRouter)); }
public void Convert_to_trx___option_false() { string[] args = { "a.trx", "--junit2trx" }; var actual = WorkerOptions.Parse(args); Assert.Multiple(() => { Assert.IsFalse(actual.ConvertToJunit); CollectionAssert.AreEqual(new string[] { "a.trx" }, actual.InputFiles); }); }
private static void AddEventGridPublisher(WorkerOptions options, TestConfig config) { options.Services.AddTransient(svc => { string eventGridTopic = config.GetTestInfraEventGridTopicUri(); string eventGridKey = config.GetTestInfraEventGridAuthKey(); return(EventGridPublisherBuilder .ForTopic(eventGridTopic) .UsingAuthenticationKey(eventGridKey) .Build()); }); }
public JsonPocoConverterTests() { var options = new WorkerOptions(); options.Serializer = new JsonObjectSerializer(new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }); var wrapper = new OptionsWrapper <WorkerOptions>(options); _jsonPocoConverter = new JsonPocoConverter(wrapper); }
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureServices((hostContext, services) => { IConfiguration configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); WorkerOptions options = configuration.GetSection("WCF").Get <WorkerOptions>(); services.AddSingleton(options); services.AddHostedService <Worker>(); });
public async Task ConnectWorker_FollowsFailureOptionsIfTheDeserializerThrows(WorkerFailureBehavior behavior) { await ConnectAsync(); await prod.UseAsync("watched"); await DrainUsedTube(); // Ensure all messages will fail horribly during deserialization var configuration = ConnectionConfiguration.Parse(connectionString); configuration.JobSerializer = new ThrowingSerializer(); bool gotInsideWorkerFunc = false; var options = new WorkerOptions { Tubes = { "watched" }, FailureBehavior = behavior, FailureReleaseDelay = TenSeconds, }; var worker = BeanstalkConnection.ConnectWorkerAsync <Jobject>(configuration, options, async(c, _) => { gotInsideWorkerFunc = true; await c.DeleteAsync(); }); int jobId; using (await worker) { jobId = await prod.PutAsync(new byte[] { }, 1, TenSeconds, ZeroSeconds); await Task.Delay(200); Assert.False(gotInsideWorkerFunc); var stats = await prod.JobStatisticsAsync(jobId); switch (behavior) { case WorkerFailureBehavior.Delete: Assert.Null(stats); return; case WorkerFailureBehavior.Bury: Assert.Equal(JobState.Buried, stats.State); return; case WorkerFailureBehavior.Release: Assert.Equal(JobState.Delayed, stats.State); return; case WorkerFailureBehavior.NoAction: Assert.Equal(JobState.Reserved, stats.State); return; default: throw new Exception("Untested behavior: " + behavior); } } }
public async Task Multiple_files_given___converted() { string[] expectedFiles = { "nunit.xml", "mstest.xml", "mstest-warning.xml" }; DeleteExpectedFiles(expectedFiles); Worker sut = this.CreateSut(); string[] args = { "nunit.trx", "mstest.trx", "mstest-warning.trx" }; var options = new WorkerOptions(args); await sut.RunAsync(options); CheckExpectedFilesExist(expectedFiles); }
public void Multiple_files_and_output_path_at_start___OK() { string[] args = { "--output", "out", "a.trx", "b.trx" }; var actual = WorkerOptions.Parse(args); Assert.Multiple(() => { string[] expected = { "a.trx", "b.trx" }; CollectionAssert.AreEqual(expected, actual.InputFiles); Assert.AreEqual("out", actual.OutputDirectory); }); }
public void Single_file_given___OK() { string[] args = { "a.trx" }; var actual = WorkerOptions.Parse(args); Assert.Multiple(() => { string[] expected = { "a.trx" }; CollectionAssert.AreEqual(expected, actual.InputFiles); Assert.IsNull(actual.OutputDirectory); }); }
public void Multiple_output_directories___last_one_used() { string[] args = { "a.trx", "--output", "out", "b.trx", "--output", "junit-out" }; var actual = WorkerOptions.Parse(args); Assert.Multiple(() => { string[] expected = { "a.trx", "b.trx" }; CollectionAssert.AreEqual(expected, actual.InputFiles); Assert.AreEqual("junit-out", actual.OutputDirectory); }); }
public async Task ConnectWorker_StopsWhenDisposed() { await ConnectAsync(); var tube = "i-am-a-tube"; int counter = 0; var options = new WorkerOptions { Tubes = { tube } }; var worker = BeanstalkConnection.ConnectWorkerAsync(connectionString, options, async (c, job) => { counter++; await c.DeleteAsync(); }); using (await worker) { await prod.UseAsync(tube); await prod.PutAsync(new byte[] { }, 1, TenSeconds, ZeroSeconds); await Task.Delay(200); } Assert.True(counter > 0); var finalValue = counter; await prod.PutAsync(new byte[] { }, 1, TenSeconds, ZeroSeconds); await Task.Delay(200); Assert.Equal(finalValue, counter); }
public async Task ConnectWorker_WatchesOnlySpecifiedTubes() { await ConnectAsync(); await prod.UseAsync("watched"); await DrainUsedTube(); int counter = 0; var options = new WorkerOptions { Tubes = { "watched" } }; var worker = BeanstalkConnection.ConnectWorkerAsync(connectionString, options, async (c, job) => { counter++; await c.DeleteAsync(); }); using (await worker) { await prod.PutAsync(new byte[] { }, 1, TenSeconds, ZeroSeconds); await prod.UseAsync("default"); await prod.PutAsync(new byte[] { }, 1, TenSeconds, ZeroSeconds); await Task.Delay(200); } Assert.Equal(1, counter); }
public async Task ConnectWorker_CallsTheWorkerOnTheCurrentSyncContextByDefault() { await ConnectAsync(); int counter = 0; int wrongContextCount = 0; SynchronizationContext startingContext = SynchronizationContext.Current; var options = new WorkerOptions { }; var worker = BeanstalkConnection.ConnectWorkerAsync(connectionString, options, async (c, job) => { counter++; if (startingContext != SynchronizationContext.Current) wrongContextCount++; await c.DeleteAsync(); }); using (await worker) { foreach (var _ in Enumerable.Repeat(0, 10)) await prod.PutAsync(new byte[] { }, 1, TenSeconds, ZeroSeconds); await Task.Delay(100); } Assert.NotEqual(0, counter); Assert.Equal(0, wrongContextCount); }
public async Task ConnectWorker_ThrownExceptionFollowsSpecifiedBehavior(WorkerFailureBehavior behavior) { await ConnectAsync(); var tube = "test-failure-behaviors"; await prod.UseAsync(tube); await DrainUsedTube(); var options = new WorkerOptions { Tubes = { tube }, FailureBehavior = behavior, FailurePriority = 1, FailureReleaseDelay = TimeSpan.FromSeconds(10), }; var worker = BeanstalkConnection.ConnectWorkerAsync(connectionString, options, (c, job) => { throw new Exception(); }); JobStatistics stats; using (await worker) { var id = await prod.PutAsync(new byte[] { }, 1, TenSeconds, ZeroSeconds); await Task.Delay(100); stats = await prod.JobStatisticsAsync(id); } switch (behavior) { case WorkerFailureBehavior.Delete: Assert.Null(stats); return; case WorkerFailureBehavior.Bury: Assert.Equal(JobState.Buried, stats.State); return; case WorkerFailureBehavior.Release: Assert.Equal(JobState.Delayed, stats.State); return; case WorkerFailureBehavior.NoAction: Assert.Equal(JobState.Reserved, stats.State); return; default: throw new Exception("Untested behavior"); } }
public async Task ConnectWorker_FollowsFailureOptionsIfTheWorkerFuncDoesntTakeAction() { await ConnectAsync(); await prod.UseAsync("watched"); await DrainUsedTube(); int receivedJobId = 0; var options = new WorkerOptions { Tubes = { "watched" }, FailureBehavior = WorkerFailureBehavior.Bury }; var worker = BeanstalkConnection.ConnectWorkerAsync(connectionString, options, async (c, job) => { if (receivedJobId == 0) receivedJobId = job.Id; await Task.Delay(0); // Don't call any IWorker methods }); using (await worker) { await prod.PutAsync(new byte[] { }, 1, TenSeconds, ZeroSeconds); await Task.Delay(100); } var stat = await prod.JobStatisticsAsync(receivedJobId); Assert.Equal(JobState.Buried, stat.State); }
public async Task ConnectWorker_CreatesTheSpecifiedNumberOfWorkers() { var tube = "5-second-tasks"; await ConnectAsync(); await prod.UseAsync(tube); await Task.WhenAll( prod.PutAsync(new byte[] { }, 1, TenSeconds), prod.PutAsync(new byte[] { }, 1, TenSeconds), prod.PutAsync(new byte[] { }, 1, TenSeconds)); var reserved = new List<Job>(); var options = new WorkerOptions { Tubes = { tube }, NumberOfWorkers = 3 }; var worker = BeanstalkConnection.ConnectWorkerAsync(connectionString, options, async (c, job) => { reserved.Add(job); await Task.Delay(5000); await c.DeleteAsync(); }); var stats = new List<JobStatistics>(); using (await worker) { await Task.Delay(200); foreach (var job in reserved) stats.Add(await prod.JobStatisticsAsync(job.Id)); } Assert.Equal(3, stats.Count); Assert.All(stats, stat => Assert.Equal(JobState.Reserved, stat.State)); }