internal static JobExecutionListResult DeserializeJobExecutionListResult(JsonElement element) { Optional <IReadOnlyList <JobExecutionData> > value = default; Optional <string> nextLink = default; foreach (var property in element.EnumerateObject()) { if (property.NameEquals("value")) { if (property.Value.ValueKind == JsonValueKind.Null) { property.ThrowNonNullablePropertyIsNull(); continue; } List <JobExecutionData> array = new List <JobExecutionData>(); foreach (var item in property.Value.EnumerateArray()) { array.Add(JobExecutionData.DeserializeJobExecutionData(item)); } value = array; continue; } if (property.NameEquals("nextLink")) { nextLink = property.Value.GetString(); continue; } } return(new JobExecutionListResult(Optional.ToList(value), nextLink.Value)); }
ServerJobAgentJobExecution IOperationSource <ServerJobAgentJobExecution> .CreateResult(Response response, CancellationToken cancellationToken) { using var document = JsonDocument.Parse(response.ContentStream); var data = JobExecutionData.DeserializeJobExecutionData(document.RootElement); return(new ServerJobAgentJobExecution(_armClient, data)); }
public void TestObserverJobExecution_When_User_Was_Under_Attack_Gameplay_Returns_Attack() { var villageRepoMock = new Mock <IVillageRepository>(); villageRepoMock.Setup(x => x.GetVillages(FakeDataProvider.TravianUserName)) .Returns(Task.FromResult((IEnumerable <VillageModel>)FakeDataProvider.GetVillagesFromDatabase(true))); _serviceBuilder = _serviceBuilder .WithService(villageRepoMock.Object); var observerJob = new ObserverJob(_serviceBuilder.Build()); var context = new Mock <IJobExecutionContext>(); var jobDetail = new Mock <IJobDetail>(); var data = new JobExecutionData { TravianUser = FakeDataProvider.GetUser(PlayerStatus.UNDER_ATTACK, true) }; jobDetail.Setup(x => x.JobDataMap[AbstractJob.JobExecutionDataKey]).Returns(data); context.Setup(x => x.JobDetail).Returns(jobDetail.Object); Assert.DoesNotThrowAsync(async() => await observerJob.Execute(data)); _logger.Verify(x => x.Log(LogLevel.Error, It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never); _cmdFactoryMock.Verify(x => x.GetQueueableCommand(nameof(PrepareToAttackCommand), It.IsAny <long>()), Times.Once); _travianUserRepoMock.Verify(x => x.ReplacePlayerDataVillages(It.IsAny <TravianUser>()), Times.Once); Assert.AreEqual(2, _reportMsgs.Count); Assert.IsTrue(_reportMsgs[1].Contains($"Village [test_village_under_attack] is under attack.")); Assert.IsTrue(_reportMsgs[1].Contains(FakeDataProvider.NewAttackDateTime.ToDisplayStringApplyTimeZone("UTC+2"))); Assert.AreEqual(1, _updates.Count); Assert.AreEqual(PlayerStatus.UNDER_ATTACK, _updates.First().PlayerData.Status); }
public static JobKey BuildJobKey(JobExecutionData jobData) { var additional = string.Empty; if (string.IsNullOrEmpty(jobData.Cron)) { additional = $":timestamp:{jobData.Start.ToTimeStamp()}"; } return(new JobKey($"{jobData.JobType.Name}:job:for:{jobData.TravianUser.UserName}{additional}", BuildGroupKey(jobData.TravianUser.UserName, jobData.TravianUser.BotUserName))); }
public void Test_Prepare_To_Attack() { var actionProviderMock = new Mock <IActionProvider>(); actionProviderMock.Setup(x => x.GetActionsForPlayer(It.IsNotNull <TravianUser>())) .Returns(Task.FromResult((IEnumerable <GameAction>)Builder <GameAction> .CreateListOfSize(2) .TheFirst(1) .With(x => x.Action = GameActionType.TRAIN_ARMY) .With(x => x.Village = Builder <Village> .CreateNew().With(y => y.Name = "test_village_1").Build()) .TheNext(1) .With(x => x.Action = GameActionType.SEND_RESOURCES) .With(x => x.Village = Builder <Village> .CreateNew().With(y => y.Name = "test_village_2").Build()) .Build())); var gameplayMock = new Mock <IGameplayClient>(); gameplayMock .Setup(x => x.ExecuteActions(It.IsNotNull <TravianUser>(), It.IsNotNull <List <GameAction> >())) .Returns(Task.FromResult(Builder <BaseScenarioResult> .CreateNew().Build())); _serviceBuilder = _serviceBuilder .WithService(actionProviderMock.Object) .WithService(gameplayMock.Object); var job = new PrepareToAttackJob(_serviceBuilder.Build()); //var context = new Mock<IJobExecutionContext>(); //var jobDetail = new Mock<IJobDetail>(); var data = new JobExecutionData { TravianUser = FakeDataProvider.GetUser(PlayerStatus.UNDER_ATTACK, true), JobType = typeof(PrepareToAttackJob) }; //jobDetail.Setup(x => x.JobDataMap[AbstractJob.JobExecutionDataKey]).Returns(data); //context.Setup(x => x.JobDetail).Returns(jobDetail.Object); Assert.DoesNotThrowAsync(async() => await job.Execute(data)); _serviceBuilder.LoggerMock.Verify(x => x.Log( LogLevel.Error, It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never); Assert.AreEqual(2, _serviceBuilder.Messages.Count); Assert.AreEqual($"The village test_village_1 was prepared to attack with following action: [TRAIN_ARMY].", _serviceBuilder.Messages[0]); Assert.AreEqual($"The village test_village_2 was prepared to attack with following action: [SEND_RESOURCES].", _serviceBuilder.Messages[1]); }
public void TestObserverJobExecution_When_It_Was_Quiet_And_Gameplay_Returns_Attack() { var villageRepoMock = new Mock <IVillageRepository>(); villageRepoMock.Setup(x => x.GetVillages(FakeDataProvider.TravianUserName)) .Returns(Task.FromResult((IEnumerable <VillageModel>)FakeDataProvider.GetVillagesFromDatabase(false))); _serviceBuilder = _serviceBuilder .WithService(villageRepoMock.Object); var observerJob = new ObserverJob(_serviceBuilder.Build()); var context = new Mock <IJobExecutionContext>(); var jobDetail = new Mock <IJobDetail>(); var data = new JobExecutionData { TravianUser = FakeDataProvider.GetUser(PlayerStatus.ALL_QUIET, true) }; jobDetail.Setup(x => x.JobDataMap[AbstractJob.JobExecutionDataKey]).Returns(data); context.Setup(x => x.JobDetail).Returns(jobDetail.Object); Assert.DoesNotThrowAsync(async() => await observerJob.Execute(data)); _logger.Verify(x => x.Log(LogLevel.Error, It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never); _cmdFactoryMock.Verify(x => x.GetQueueableCommand(nameof(PrepareToAttackCommand), It.IsAny <long>()), Times.Exactly(2)); _travianUserRepoMock.Verify(x => x.ReplacePlayerDataVillages(It.IsAny <TravianUser>()), Times.Once); Assert.AreEqual(7, _reportMsgs.Count); Assert.IsTrue(_reportMsgs[0].Contains($"Player {FakeDataProvider.TravianUserName} has been scanned")); Assert.IsTrue(_reportMsgs[1].Contains($"Player {FakeDataProvider.TravianUserName} has been scanned")); Assert.IsTrue(_reportMsgs[2].Contains($"Player {FakeDataProvider.TravianUserName} is under attack:")); Assert.IsTrue(_reportMsgs[2].Contains("The village [test_village_under_attack] is under attack")); Assert.IsTrue(_reportMsgs[3].Contains($"Player {FakeDataProvider.TravianUserName} is under attack:")); Assert.IsTrue(_reportMsgs[3].Contains("The village [test_village_under_attack] is under attack")); Assert.AreEqual(_reportMsgs[4], $"New incoming attacks discovered for player [{FakeDataProvider.TravianUserName}]"); Assert.IsTrue(_reportMsgs[5].Contains($"Village [{FakeDataProvider.TestVillageName}] is under attack")); Assert.IsTrue(_reportMsgs[5].Contains($"The attack date time:")); Assert.IsTrue(_reportMsgs[5].Contains($"The intruder:")); Assert.IsTrue(_reportMsgs[6].Contains($"Village [{FakeDataProvider.TestVillageName}] is under attack")); Assert.IsTrue(_reportMsgs[6].Contains($"The attack date time:")); Assert.IsTrue(_reportMsgs[6].Contains($"The intruder:")); Assert.AreEqual(2, _updates.Count); Assert.AreEqual(PlayerStatus.UNDER_ATTACK, _updates.First().PlayerData.Status); }
public async Task Execute(string parameters = "") { var jobData = new JobExecutionData { Cron = Cron, JobType = JobType }; IJobDetail job = JobBuilder.Create(typeof(EmptyJob)) .WithIdentity($"{Name}_{JobType}") .Build(); job.JobDataMap[AbstractJob.JobExecutionDataKey] = jobData; var trigger = TriggerBuilder.Create() .WithIdentity($"{jobData.JobType.Name}:trigger", $"{jobData.JobType.Name}") .WithCronSchedule(jobData.Cron).Build(); await _scheduler.ScheduleJob(job, trigger, new System.Threading.CancellationToken()); }
public void TestObserverJobExecution_When_User_Was_Under_Attack_Gameplay_Returns_All_Quiet() { var villageRepoMock = new Mock <IVillageRepository>(); villageRepoMock.Setup(x => x.GetVillages(FakeDataProvider.TravianUserName)) .Returns(Task.FromResult((IEnumerable <VillageModel>)FakeDataProvider.GetVillagesFromDatabase(false))); var user = FakeDataProvider.GetUser(PlayerStatus.UNDER_ATTACK); var result = Builder <BaseScenarioResult> .CreateNew() .With(x => x.Villages = Builder <Village> .CreateListOfSize(2).All().With(y => y.Attacks = null).Build().ToList()) .Build(); var gameplayMock = new Mock <IGameplayClient>(); gameplayMock.Setup(x => x.RunScan(It.IsAny <TravianUser>(), It.IsAny <bool>())).Returns(Task.FromResult(result)); _serviceBuilder = _serviceBuilder .WithService(villageRepoMock.Object) .WithService(gameplayMock.Object); var observerJob = new ObserverJob(_serviceBuilder.Build()); var context = new Mock <IJobExecutionContext>(); var jobDetail = new Mock <IJobDetail>(); var data = new JobExecutionData { TravianUser = FakeDataProvider.GetUser(PlayerStatus.UNDER_ATTACK, true) }; jobDetail.Setup(x => x.JobDataMap[AbstractJob.JobExecutionDataKey]).Returns(data); context.Setup(x => x.JobDetail).Returns(jobDetail.Object); Assert.DoesNotThrowAsync(async() => await observerJob.Execute(data)); _logger.Verify(x => x.Log(LogLevel.Error, It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never); _travianUserRepoMock.Verify(x => x.ReplacePlayerDataVillages(It.IsAny <TravianUser>()), Times.Once); _travianUserRepoMock.Verify(x => x.ReplacePlayerData(It.IsAny <TravianUser>()), Times.Once); _travianUserRepoMock.Verify(x => x.ReplacePlayerData(It.IsAny <TravianUser>()), Times.Once); Assert.AreEqual(2, _updates.Count); Assert.AreEqual(PlayerStatus.ALL_QUIET, _updates.First().PlayerData.Status); }
public async Task <JobKey> ScheduleCommandAsync(JobExecutionData jobData, CancellationToken cancellationToken) { try { if (string.IsNullOrEmpty(jobData.JobType.Name)) { throw new ArgumentNullException(nameof(jobData.JobType.Name), "The command name must be specified."); } IJobDetail job = JobBuilder.Create(typeof(MasterJob)) .WithIdentity(BuildJobKey(jobData)) .Build(); job.JobDataMap[AbstractJob.JobExecutionDataKey] = jobData; var builder = TriggerBuilder.Create() .WithIdentity($"{jobData.JobType.Name}:trigger:for:{jobData.TravianUser.UserName}:timestamp:{jobData.Start.ToTimeStamp()}", $"{jobData.TravianUser.BotUserName}.group") .WithDescription($"{jobData.JobType}.trigger.With: CRON: {jobData.Cron}, StartDateTime: {jobData.Start.ToFormattedStringWithMills()}") .StartAt(jobData.Start); var trigger = string.IsNullOrEmpty(jobData.Cron) ? builder.Build() : builder.WithCronSchedule(jobData.Cron).Build(); await _scheduler.ScheduleJob(job, trigger, cancellationToken); if (!string.IsNullOrEmpty(jobData.Cron) || jobData.Start < DateTimeOffset.UtcNow && (DateTimeOffset.UtcNow - jobData.Start).TotalMinutes < 5) { await _scheduler.TriggerJob(job.Key); } return(job.Key); } catch (Exception exc) { this._logger.LogError(LoggingEvents.BackgroundJobCreationException, exc, $"Unable to create new Job instance of type [{jobData.JobType}]"); return(null); } }
public void Test_One_Village_With_Building_Being_Built() { var testVillage = PrepareTestOneVillage(); var resultVillage = _serviceProviderBuilder.Mapper.Map <Village>(testVillage); var finishTime = TimeSpan.FromMinutes(30); resultVillage.Dorf1BuildTimeLeft = finishTime; resultVillage.CanBuild = false; resultVillage.Resources = new Resources { Lumber = 100, Clay = 100, Iron = 100, Crop = 100 }; resultVillage.Warehourse = 800; resultVillage.Granary = 800; var infoResult = Builder <BaseScenarioResult> .CreateNew() .With(x => x.Success = true) .With(x => x.Villages = new List <Village> { resultVillage }) .Build(); var gamePlayMock = new Mock <IGameplayClient>(); gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <GameAction> >())) .Returns(Task.FromResult(infoResult)); gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >())) .Returns(Task.FromResult(new BaseScenarioResult())); _serviceProviderBuilder.WithService(gamePlayMock.Object); var cmd = new FakeCommand(); var cmdMock = new Mock <ICommandFactory>(); cmdMock.Setup(x => x.GetQueueableCommand(nameof(BuildCommand), It.IsAny <long>())) .Returns(cmd); _serviceProviderBuilder.WithService(cmdMock.Object); var job = new BuildingPlanExecutionJob(_serviceProviderBuilder.Build()); var data = new JobExecutionData { TravianUser = FakeDataProvider.GetUser(PlayerStatus.ALL_QUIET, true), JobType = typeof(BuildingPlanExecutionJob) }; var now = DateTimeOffset.Now; Assert.DoesNotThrowAsync(async() => await job.Execute(data)); _serviceProviderBuilder.LoggerMock.Verify(x => x.Log( LogLevel.Error, It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never); gamePlayMock.Verify(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <GameAction> >()), Times.Once); gamePlayMock.Verify(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >()), Times.Never); var diff = cmd.Start - now - finishTime; Assert.IsTrue(diff <= TimeSpan.FromSeconds(3)); // will fail while debugging because of date time now Assert.IsTrue(diff >= TimeSpan.FromSeconds(2)); }
private AbstractJob PrepareOneVillageTest(BaseScenarioResult buildScenarioResult, BaseScenarioResult infoScenarioResult) { var testVillage = PrepareTestOneVillage(isBuildingFeatureOn: true); var resultVillage = _serviceProviderBuilder.Mapper.Map <Village>(testVillage); var finishTime = TimeSpan.FromMinutes(30); resultVillage.Dorf1BuildTimeLeft = finishTime; resultVillage.CanBuild = true; resultVillage.Resources = new Resources { Lumber = 100, Clay = 100, Iron = 100, Crop = 100 }; resultVillage.Warehourse = 800; resultVillage.Granary = 800; var infoResult = Builder <BaseScenarioResult> .CreateNew() .With(x => x.Success = true) .With(x => x.Villages = new List <Village> { resultVillage }) .Build(); var actionProviderMock = new Mock <IActionProvider>(); actionProviderMock.Setup(x => x.GetBuildActions(resultVillage, It.IsAny <IEnumerable <BuildingModel> >())) .Returns(Task.FromResult((true, (IEnumerable <BuildAction>) new List <BuildAction> { new BuildAction { Village = resultVillage, BuildingId = "test", BuildingSlot = "test", Level = 1 } }))); _serviceProviderBuilder.WithService(actionProviderMock.Object); var buildActionResult = Builder <BaseScenarioResult> .CreateNew() .With(x => x.Success = true) .With(x => x.Villages = new List <Village> { Builder <Village> .CreateNew() .With(y => y.CanBuild = false) .With(y => y.Dorf1BuildTimeLeft = TimeSpan.FromMinutes(5)) .Build() }) .Build(); var gamePlayMock = new Mock <IGameplayClient>(); gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <GameAction> >())) .Returns(Task.FromResult(infoResult)); gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >())) .Returns(Task.FromResult(buildActionResult)); _serviceProviderBuilder.WithService(gamePlayMock.Object); var cmd = new FakeCommand(); var cmdMock = new Mock <ICommandFactory>(); cmdMock.Setup(x => x.GetQueueableCommand(nameof(BuildCommand), It.IsAny <long>())) .Returns(cmd); _serviceProviderBuilder.WithService(cmdMock.Object); var job = new BuildingPlanExecutionJob(_serviceProviderBuilder.Build()); var data = new JobExecutionData { TravianUser = FakeDataProvider.GetUser(PlayerStatus.ALL_QUIET, true), JobType = typeof(BuildingPlanExecutionJob) }; return(job); }
public async Task Test_Three_Villages_Build_Action_Returns_Error(BuildErrorType errorType) { var testVillage = GetVillage(isBuildingFeatureOn: true); var resultVillage = _serviceProviderBuilder.Mapper.Map <Village>(testVillage); var finishTime = TimeSpan.FromMinutes(30); resultVillage.Dorf1BuildTimeLeft = finishTime; resultVillage.CanBuild = true; resultVillage.Resources = new Resources { Lumber = 100, Clay = 100, Iron = 100, Crop = 100 }; resultVillage.Warehourse = 800; resultVillage.Granary = 800; var testVillage2 = GetVillage(isBuildingFeatureOn: true); var resultVillage2 = _serviceProviderBuilder.Mapper.Map <Village>(testVillage2); var finishTime2 = TimeSpan.FromMinutes(45); resultVillage2.Dorf1BuildTimeLeft = finishTime2; resultVillage2.CanBuild = true; resultVillage2.Resources = new Resources { Lumber = 100, Clay = 100, Iron = 100, Crop = 100 }; resultVillage2.Warehourse = 800; resultVillage2.Granary = 800; var testVillage3 = GetVillage(isBuildingFeatureOn: false); resultVillage2.Resources = new Resources { Lumber = 100, Clay = 100, Iron = 100, Crop = 100 }; resultVillage2.Warehourse = 800; resultVillage2.Granary = 800; var allVillages = new List <VillageModel> { testVillage, testVillage2, testVillage3 }; var villageRepo = new Mock <IVillageRepository>(); villageRepo.Setup(x => x.GetVillages(_serviceProviderBuilder.TravianUser.UserName)) .Returns(Task.FromResult((IEnumerable <VillageModel>)allVillages)); villageRepo.Setup(x => x.GetVillage(It.IsAny <int>(), It.IsAny <int>())) .Returns((int x, int y) => { return(Task.FromResult(allVillages.FirstOrDefault(z => z.CoordinateX == x && z.CoordinateY == y))); }); _serviceProviderBuilder.WithService(villageRepo.Object); var infoResult = Builder <BaseScenarioResult> .CreateNew() .With(x => x.Success = true) .With(x => x.Villages = new List <Village> { resultVillage2 }) .Build(); var actionProviderMock = new Mock <IActionProvider>(); actionProviderMock.Setup(x => x.GetBuildActions(resultVillage, It.IsAny <IEnumerable <BuildingModel> >())) .Returns(Task.FromResult((true, (IEnumerable <BuildAction>) new List <BuildAction> { new BuildAction { Village = resultVillage, BuildingId = "test", BuildingSlot = "test", Level = 1 } }))); actionProviderMock.Setup(x => x.GetBuildActions(resultVillage2, It.IsAny <IEnumerable <BuildingModel> >())) .Returns(Task.FromResult((true, (IEnumerable <BuildAction>) new List <BuildAction> { new BuildAction { Village = resultVillage2, BuildingId = "test", BuildingSlot = "test", Level = 1 } }))); _serviceProviderBuilder.WithService(actionProviderMock.Object); var buildActionResult = Builder <BaseScenarioResult> .CreateNew() .With(x => x.Success = true) .With(x => x.Villages = new List <Village> { Builder <Village> .CreateNew() .With(y => y.CanBuild = false) .With(y => y.Dorf1BuildTimeLeft = TimeSpan.FromMinutes(2)) .With(y => y.CoordinateX = resultVillage.CoordinateX) .With(y => y.CoordinateY = resultVillage.CoordinateY) .With(y => y.Warehourse = 800) .With(y => y.Granary = 800) .With(y => y.Resources = Builder <Resources> .CreateNew().Build()) .With(y => y.ResourcesProduction = Builder <Resources> .CreateNew().Build()) .Build(), Builder <Village> .CreateNew() .With(y => y.CanBuild = false) .With(y => y.Dorf1BuildTimeLeft = TimeSpan.FromMinutes(5)) .With(y => y.CoordinateX = resultVillage2.CoordinateX) .With(y => y.CoordinateY = resultVillage2.CoordinateY) .Build() }) .With(x => x.Errors = new List <ScenarioError> { Builder <BuildScenarioError> .CreateNew() .With(y => y.BuildErrorType = errorType) .With(y => y.Village = resultVillage) .Build() }) .Build(); var gamePlayMock = new Mock <IGameplayClient>(); gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <GameAction> >())) .Returns(Task.FromResult(infoResult)); gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >())) .Returns(Task.FromResult(buildActionResult)); _serviceProviderBuilder.WithService(gamePlayMock.Object); var cmd = new FakeCommand(); var cmdMock = new Mock <ICommandFactory>(); cmdMock.Setup(x => x.GetQueueableCommand(nameof(BuildCommand), It.IsAny <long>())) .Returns(cmd); _serviceProviderBuilder.WithService(cmdMock.Object); var job = new BuildingPlanExecutionJob(_serviceProviderBuilder.Build()); var travianUser = FakeDataProvider.GetUser(PlayerStatus.ALL_QUIET, true); var data = new JobExecutionData { TravianUser = travianUser, JobType = typeof(BuildingPlanExecutionJob) }; var now = DateTimeOffset.Now; Assert.DoesNotThrowAsync(async() => await job.Execute(data)); _serviceProviderBuilder.LoggerMock.Verify(x => x.Log( LogLevel.Error, It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never); gamePlayMock.Verify(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >()), Times.Once); var expected = errorType == BuildErrorType.NoSpaceInQueue ? TimeSpan.FromMinutes(2) : Calculator.CalculateTimeForUnit( resultVillage, _serviceProviderBuilder.Mapper.Map <Village>(testVillage3), await _serviceProviderBuilder.UnitRepository.GetTrader(travianUser.PlayerData.Tribe)); var diff = cmd.Start - now - TimeSpan.FromMinutes(2); Assert.IsTrue(diff <= TimeSpan.FromSeconds(3)); // will fail while debugging because of date time now Assert.IsTrue(diff >= TimeSpan.FromSeconds(2)); buildActionResult = Builder <BaseScenarioResult> .CreateNew() .With(x => x.Success = true) .With(x => x.Villages = new List <Village> { Builder <Village> .CreateNew() .With(y => y.CanBuild = true) .With(y => y.CoordinateX = resultVillage.CoordinateX) .With(y => y.CoordinateY = resultVillage.CoordinateY) .Build(), Builder <Village> .CreateNew() .With(y => y.CanBuild = false) .With(y => y.Dorf1BuildTimeLeft = TimeSpan.FromMinutes(5)) .With(y => y.CoordinateX = resultVillage2.CoordinateX) .With(y => y.CoordinateY = resultVillage2.CoordinateY) .Build() }) .With(x => x.Errors = new List <ScenarioError> { Builder <BuildScenarioError> .CreateNew() .With(y => y.BuildErrorType = errorType) .With(y => y.Village = resultVillage) .Build() }) .Build(); gamePlayMock = new Mock <IGameplayClient>(); gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <GameAction> >())) .Returns(Task.FromResult(infoResult)); gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >())) .Returns(Task.FromResult(buildActionResult)); _serviceProviderBuilder.WithService(gamePlayMock.Object); job = new BuildingPlanExecutionJob(_serviceProviderBuilder.Build()); now = DateTimeOffset.Now; Assert.DoesNotThrowAsync(async() => await job.Execute(data)); _serviceProviderBuilder.LoggerMock.Verify(x => x.Log( LogLevel.Error, It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never); gamePlayMock.Verify(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >()), Times.Once); diff = cmd.Start - now; Assert.IsTrue(diff <= TimeSpan.FromSeconds(3)); // will fail while debugging because of date time now Assert.IsTrue(diff >= TimeSpan.FromSeconds(2)); }
[TestCase(true, BuildErrorType.NoSpaceInQueue)] // test one village with build action returns no space in queue error //[TestCase(true, BuildErrorType.NotEnoughResources)] public void Test_One_Village_Rescheduling_Next_Execution_Time(bool noSpaceInQueueError, BuildErrorType buildErrorType) { var testVillage = PrepareTestOneVillage(isBuildingFeatureOn: true); var resultVillage = _serviceProviderBuilder.Mapper.Map <Village>(testVillage); var finishTime = TimeSpan.FromMinutes(30); resultVillage.Dorf1BuildTimeLeft = finishTime; resultVillage.CanBuild = true; resultVillage.Resources = new Resources { Lumber = 100, Clay = 100, Iron = 100, Crop = 100 }; resultVillage.Warehourse = 800; resultVillage.Granary = 800; var infoResult = Builder <BaseScenarioResult> .CreateNew() .With(x => x.Success = true) .With(x => x.Villages = new List <Village> { resultVillage }) .Build(); var actionProviderMock = new Mock <IActionProvider>(); actionProviderMock.Setup(x => x.GetBuildActions(resultVillage, It.IsAny <IEnumerable <BuildingModel> >())) .Returns(Task.FromResult((true, (IEnumerable <BuildAction>) new List <BuildAction> { new BuildAction { Village = resultVillage, BuildingId = "test", BuildingSlot = "test", Level = 1 } }))); _serviceProviderBuilder.WithService(actionProviderMock.Object); var buildActionResult = Builder <BaseScenarioResult> .CreateNew() .With(x => x.Success = true) .With(x => x.Villages = new List <Village> { Builder <Village> .CreateNew() .With(y => y.CoordinateX = resultVillage.CoordinateX) .With(y => y.CoordinateY = resultVillage.CoordinateY) .With(y => y.CanBuild = false) .With(y => y.Dorf1BuildTimeLeft = TimeSpan.FromMinutes(5)) .Build() }) .With(x => x.Errors = noSpaceInQueueError ? new List <ScenarioError> { Builder <BuildScenarioError> .CreateNew() .With(y => y.BuildErrorType = buildErrorType) .With(y => y.Village = resultVillage) .Build() } : new List <ScenarioError>()) .Build(); var gamePlayMock = new Mock <IGameplayClient>(); gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <GameAction> >())) .Returns(Task.FromResult(infoResult)); gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >())) .Returns(Task.FromResult(buildActionResult)); _serviceProviderBuilder.WithService(gamePlayMock.Object); var cmd = new FakeCommand(); var cmdMock = new Mock <ICommandFactory>(); cmdMock.Setup(x => x.GetQueueableCommand(nameof(BuildCommand), It.IsAny <long>())) .Returns(cmd); _serviceProviderBuilder.WithService(cmdMock.Object); var job = new BuildingPlanExecutionJob(_serviceProviderBuilder.Build()); var data = new JobExecutionData { TravianUser = FakeDataProvider.GetUser(PlayerStatus.ALL_QUIET, true), JobType = typeof(BuildingPlanExecutionJob) }; var now = DateTimeOffset.Now; Assert.DoesNotThrowAsync(async() => await job.Execute(data)); _serviceProviderBuilder.LoggerMock.Verify(x => x.Log( LogLevel.Error, It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never); gamePlayMock.Verify(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >()), Times.Once); var diff = cmd.Start - now - TimeSpan.FromMinutes(5); Assert.IsTrue(diff <= TimeSpan.FromSeconds(3)); // will fail while debugging because of date time now Assert.IsTrue(diff >= TimeSpan.FromSeconds(2)); }
protected sealed override async Task ExecuteCommand(string parameters = "") { var jobData = new JobExecutionData { Cron = Cron, JobType = JobType, Start = Start, TravianUser = _travianUser }; var commandKey = SchedulerService.BuildJobKey(jobData); await CleanContext(commandKey); var isRunning = await _schedulerService.IsJobRunning(commandKey); if (_travianUser.ExecutionContext == null) { _travianUser.ExecutionContext = new ExecutionContextModel { Commands = new List <CommandModel>(), IsUserNotified = false }; } else if (_travianUser.ExecutionContext.Commands == null) { _travianUser.ExecutionContext.Commands = new List <CommandModel>(); } if (_travianUser.PlayerData == null || string.IsNullOrEmpty(_travianUser.PlayerData?.TimeZone) || _travianUser.PlayerData.Tribe == Tribe.NOT_SPECIFIED) { var updateInfoResult = await _gameplayClient.RunUpdateUserInfo(_travianUser); _travianUser.PlayerData = new PlayerDataModel { Status = PlayerStatus.ALL_QUIET, Tribe = (Tribe)updateInfoResult.Player.Tribe, TimeZone = updateInfoResult.Player.TimeZone, // TODO: add alliance UserName = _travianUser.UserName }; } string msg; if (parameters.Contains("stop")) { if (isRunning) { var stopResult = await _schedulerService.InterruptCommandAsync(commandKey); if (stopResult) { var i = _travianUser.ExecutionContext.Commands.FindIndex( x => x.Name == Name && x.KeyGroup == commandKey.Group && x.KeyName == commandKey.Name); if (i > -1) { _travianUser.ExecutionContext.Commands[i].IsRunning = false; await _travianUserRepository.Update(_travianUser); } } msg = stopResult ? $"The {Name} command for player {_travianUser.UserName} has been stopped." : $"Can not stop the {Name} command for player {_travianUser.UserName}."; } else { msg = $"The {Name} command is not running for player {_travianUser.UserName}."; } } else { if (isRunning) { msg = $"The {Name} command is already being executing for player {_travianUser.UserName}."; } else { msg = $"Starting the {Name} command for player {_travianUser.UserName}."; await _schedulerService.ScheduleCommandAsync(jobData, new CancellationToken()); var i = _travianUser.ExecutionContext?.Commands?.FindIndex( x => x.Name == Name && x.KeyGroup == commandKey.Group && x.KeyName == commandKey.Name && x.StartDateTime == Start); if (i.HasValue && i > -1) { _travianUser.ExecutionContext.Commands[i.Value].IsRunning = true; } else { _travianUser.ExecutionContext.Commands.Add(new CommandModel { Name = Name, IsRunning = true, KeyName = commandKey.Name, KeyGroup = commandKey.Group, StartDateTime = Start }); } await _travianUserRepository.Update(_travianUser); } } await _bot.SendTextMessageAsync(_chatId, msg); }