public void InvalidDateIsIgnored() { var logger = new LoggerStub(); var repo = new CandleHistoryRepositoryStub(); var controller = new CandleGenerationController(repo, logger, "test component", env); DateTime unspecified = new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Unspecified); DateTime local = new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Local); controller.HandleQuote(new Quote() { AssetPair = "btcrub", IsBuy = true, Price = 1, Timestamp = unspecified }).Wait(); controller.HandleQuote(new Quote() { AssetPair = "btcrub", IsBuy = true, Price = 1, Timestamp = local }).Wait(); controller.HandleQuote(new Quote() { AssetPair = "btcrub", IsBuy = true, Price = 1, Timestamp = DateTime.MinValue }).Wait(); controller.HandleQuote(new Quote() { AssetPair = "btcrub", IsBuy = true, Price = 1, Timestamp = DateTime.MaxValue }).Wait(); Assert.Equal(0, repo.Stored.Count); }
public QueueMonitor(ILog logger, CandleGenerationController controller, int warningSize, string componentName) : base(componentName, (int)TimeSpan.FromMinutes(1).TotalMilliseconds, logger) { this.componentName = componentName; this.logger = logger; this.controller = controller; this.warningSize = warningSize; }
public void NullIsIgnored() { var logger = new LoggerStub(); var repo = new CandleHistoryRepositoryStub(); var controller = new CandleGenerationController(repo, logger, "test component", env); controller.HandleQuote(null).Wait(); Assert.Equal(0, repo.Stored.Count); }
public void ConfigureServices(ContainerBuilder builder, ILog log) { var mq = settings.FeedCandlesHistoryWriterBroker.RabbitMq; RabbitMqSubscriberSettings subscriberSettings = new RabbitMqSubscriberSettings() { ConnectionString = $"amqp://{mq.Username}:{mq.Password}@{mq.Host}:{mq.Port}", QueueName = mq.QuoteFeed + ".candleshistorywriter", ExchangeName = mq.QuoteFeed, IsDurable = true }; var dictRepo = new AssetPairsRepository(new AzureTableStorage <AssetPairEntity>( settings.FeedCandlesHistoryWriterBroker.ConnectionStrings.DictsConnectionString, settings.FeedCandlesHistoryWriterBroker.DictionaryTableName, log)); var env = new Environment(dictRepo, log, ApplicationName); var subscriber = new RabbitMqSubscriber <Quote>(subscriberSettings); this.controller = new CandleGenerationController(log, ApplicationName, env); this.monitor = new QueueMonitor(log, this.controller, settings.FeedCandlesHistoryWriterBroker.QueueWarningSize, ApplicationName); this.broker = new Broker(subscriber, log, this.controller, ApplicationName); builder.Register(c => new CandleHistoryRepositoryResolver((asset, tableName) => { string connString; if (!settings.CandleHistoryAssetConnections.TryGetValue(asset, out connString) || string.IsNullOrEmpty(connString)) { throw new AppSettingException(string.Format("Connection string for asset pair '{0}' is not specified.", asset)); } var storage = new AzureTableStorage <CandleTableEntity>(connString, tableName, log); // Preload table info var res = storage.GetDataAsync(asset, "1900-01-01").Result; return(storage); })).As <ICandleHistoryRepository>(); builder.RegisterInstance(subscriber) .As <IStartable>() .As <IStopable>(); builder.RegisterInstance(this.controller) .As <IStartable>() .As <IStopable>(); builder.RegisterInstance(this.monitor) .As <IStartable>() .As <IStopable>(); builder.RegisterInstance(this.broker) .As <IStartable>() .As <IStopable>() .As <IPersistent>(); }
public void NoExceptionExpectedOnMultithread() { var logger = new LoggerStub(); var candlesRepo = new CandleHistoryRepositoryStub(); var env = new EnvironmentStub(new List <AssetPair>() { new AssetPair() { Id = "btcusd", Accuracy = 5 } }); var controller = new CandleGenerationController(candlesRepo, logger, "test component", env); // Cancel after 1 sec CancellationTokenSource tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(2)); CancellationToken token = tokenSource.Token; int consumeCalledTimes = 0; int tickCalledTimes = 0; // Call Consume and Tick methods at the same time repeatedly and check that there was no exception. Task producing = Task.Run(async() => { while (!token.IsCancellationRequested) { await controller.HandleQuote(new Quote() { AssetPair = "btcusd", IsBuy = true, Price = 100, Timestamp = DateTime.UtcNow }); await Task.Delay(50); Interlocked.Increment(ref consumeCalledTimes); } }, token); Task timer = Task.Run(() => { while (!token.IsCancellationRequested) { controller.Tick(); Interlocked.Increment(ref tickCalledTimes); } }, token); Task.WaitAll(producing, timer); Assert.True(consumeCalledTimes > 0); Assert.True(tickCalledTimes > 0); Assert.True(candlesRepo.Stored.Count > 0); }
public void EmptyAssetIsIgnored() { var logger = new LoggerStub(); var repo = new CandleHistoryRepositoryStub(); var controller = new CandleGenerationController(repo, logger, "test component", env); controller.HandleQuote(new Quote() { AssetPair = null, IsBuy = true, Price = 1, Timestamp = Utils.ParseUtc("2017-01-01 10:10:10Z") }).Wait(); controller.HandleQuote(new Quote() { AssetPair = "", IsBuy = true, Price = 1, Timestamp = Utils.ParseUtc("2017-01-01 10:10:10Z") }).Wait(); Assert.Equal(0, repo.Stored.Count); }
public Broker( RabbitMqSubscriber <Quote> subscriber, ILog logger, CandleGenerationController controller, string componentName) : base(componentName, (int)TimeSpan.FromMinutes(1).TotalMilliseconds, logger) { this.componentName = componentName; this.logger = logger; this.controller = controller; this.subscriber = subscriber; // Using default message reader strategy subscriber .SetMessageDeserializer(new MessageDeserializer()) .Subscribe(HandleMessage) .SetLogger(logger); }
private static void ProcessAllQuotes(IEnumerable <Quote> quotes, ICandleHistoryRepository repo, LoggerStub logger) { var env = new EnvironmentStub(new List <AssetPair>() { new AssetPair() { Id = "btcusd", Accuracy = 3 }, //new AssetPair() { Id = "btcrub", Accuracy = 3 } }); var controller = new CandleGenerationController(repo, logger, "test component", env); var tasks = new List <Task>(); foreach (var quote in quotes) { var task = controller.HandleQuote(quote); tasks.Add(task); } Task.WaitAll(tasks.ToArray()); // ... signal controller to process quotes controller.Tick(); int counter = 0; while (counter < 5) { Task.Delay(1000).Wait(); // Wait while produce task is finished. if (controller.QueueLength == 0) { break; } counter++; } Assert.Equal(0, controller.QueueLength); }
public void ControllerHandlesRepositoryExceptions() { const string asset1 = "btcusd"; DateTime dt = new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Utc); var logger = new LoggerStub(); ClearTable(asset1, new string[] { "sec", "minute", "min30", "hour", "day", "week", "month" }); var repo = new CandleHistoryRepositoryResolver((string asset, string tableName) => { return(CreateStorage <CandleTableEntity>(asset, tableName, logger, 2, clear: false)); }); // 2. Process incoming quotes // var env = new EnvironmentStub(new List <AssetPair>() { new AssetPair() { Id = asset1, Accuracy = 3 } }); var controller = new CandleGenerationController(repo, logger, "test component", env); for (int i = 0; i < 5; i++) { var tasks = new List <Task>(); // pass a quote and signal controller to process quotes var q = new Quote() { AssetPair = asset1, IsBuy = true, Price = i + 1, Timestamp = dt.AddMinutes(i) }; var task = controller.HandleQuote(q); tasks.Add(task); Task.WaitAll(tasks.ToArray()); // ... signal controller to process quotes controller.Tick(); int counter = 0; while (counter < 60) { Task.Delay(1000).Wait(); // Wait while produce task is finished. if (controller.QueueLength == 0) { break; } counter++; } } Assert.Equal(0, controller.QueueLength); controller.Stop(); // ... check for errors //Assert.Equal(0, logger.Log.Where(rec => rec.Severity != LoggerStub.Severity.Info).Count()); var logs = logger.Log.Where(rec => rec.Severity != LoggerStub.Severity.Info); // 3. Read candles with repository and check count of generated candles // IEnumerable <IFeedCandle> candles = repo.GetCandlesAsync(asset1, TimeInterval.Minute, PriceType.Bid, dt.AddDays(-1), dt.AddDays(1)).Result; Assert.Equal(5, candles.Count()); candles = repo.GetCandlesAsync(asset1, TimeInterval.Sec, PriceType.Bid, dt.AddDays(-1), dt.AddDays(1)).Result; Assert.Equal(5, candles.Count()); }