public void GetBuildProjectBySpecificationId_WhenSpeficationIdIsInValidFormat_ShouldReturnResult()
        {
            // Arrange
            ICalculationsApiClient mockApi = Substitute.For <ICalculationsApiClient>();

            mockApi
            .GetBuildProjectBySpecificationId(Arg.Any <string>())
            .Returns(new ApiResponse <Common.ApiClient.Calcs.Models.BuildProject>(HttpStatusCode.OK, new Common.ApiClient.Calcs.Models.BuildProject()));

            CalculationsRepository calculationsRepository = new CalculationsRepository(mockApi, CreateMapper());

            // Act
            var          configuredTaskAwaiter = calculationsRepository.GetBuildProjectBySpecificationId("Test").ConfigureAwait(false).GetAwaiter();
            BuildProject buildProject          = configuredTaskAwaiter.GetResult();

            // Assert
            buildProject.Should().NotBeNull();
            mockApi.Received(1).GetBuildProjectBySpecificationId(Arg.Any <string>());
        }
        public async Task <IActionResult> ValidateGherkin(ValidateGherkinRequestModel model)
        {
            if (model == null)
            {
                _logger.Error("Null model was provided to ValidateGherkin");
                return(new BadRequestObjectResult("Null or empty specification id provided"));
            }

            if (string.IsNullOrWhiteSpace(model.SpecificationId))
            {
                _logger.Error("No specification id was provided to ValidateGherkin");
                return(new BadRequestObjectResult("Null or empty specification id provided"));
            }

            if (string.IsNullOrWhiteSpace(model.Gherkin))
            {
                _logger.Error("Null or empty gherkin was provided to ValidateGherkin");
                return(new BadRequestObjectResult("Null or empty gherkin name provided"));
            }

            BuildProject buildProject = _mapper.Map <BuildProject>(await _calcsApiClientPolicy.ExecuteAsync(() => _calcsApiClient.GetBuildProjectBySpecificationId(model.SpecificationId)));

            if (buildProject == null || buildProject.Build == null)
            {
                _logger.Error($"Failed to find a valid build project for specification id: {model.SpecificationId}");

                return(new StatusCodeResult((int)HttpStatusCode.PreconditionFailed));
            }

            GherkinParseResult parseResult = await _gherkinParser.Parse(model.SpecificationId, model.Gherkin, buildProject);

            if (parseResult.HasErrors)
            {
                _logger.Information($"Gherkin parser failed validation with ");
            }

            return(new OkObjectResult(parseResult.Errors));
        }
        public async Task <BuildProject> GetBuildProjectBySpecificationId(string specificationId)
        {
            if (string.IsNullOrWhiteSpace(specificationId))
            {
                throw new ArgumentNullException(nameof(specificationId));
            }

            ApiResponse <Common.ApiClient.Calcs.Models.BuildProject> apiResponse = await _apiClient.GetBuildProjectBySpecificationId(specificationId);

            return(_mapper.Map <BuildProject>(apiResponse?.Content));
        }
        public override async Task Process(Message message)
        {
            Stopwatch runTestsStopWatch = Stopwatch.StartNew();

            string specificationId = message.UserProperties["specificationId"].ToString();

            if (string.IsNullOrWhiteSpace(specificationId))
            {
                _logger.Error("Null or empty specification id provided");
                return;
            }

            BuildProject buildProject = _mapper.Map <BuildProject>(await _calcsApiClientPolicy.ExecuteAsync(() => _calcsApiClient.GetBuildProjectBySpecificationId(specificationId)));

            if (buildProject == null)
            {
                _logger.Error("A null build project was provided to UpdateAllocations");

                throw new ArgumentNullException(nameof(buildProject));
            }

            string cacheKey = message.UserProperties["providerResultsCacheKey"].ToString();

            if (string.IsNullOrWhiteSpace(cacheKey))
            {
                _logger.Error("Null or empty cache key provided");
                return;
            }

            Stopwatch providerResultsQueryStopwatch      = Stopwatch.StartNew();
            IEnumerable <ProviderResult> providerResults = await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.GetAsync <List <ProviderResult> >($"{CacheKeys.ProviderResultBatch}{cacheKey}"));

            providerResultsQueryStopwatch.Stop();

            if (providerResults.IsNullOrEmpty())
            {
                _logger.Error($"No provider results found in cache for key: {cacheKey}");
                return;
            }

            await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.RemoveAsync <List <ProviderResult> >($"{CacheKeys.ProviderResultBatch}{cacheKey}"));

            Stopwatch testScenariosStopwatch         = Stopwatch.StartNew();
            IEnumerable <TestScenario> testScenarios = await _scenariosRepositoryPolicy.ExecuteAsync(() => _scenariosRepository.GetTestScenariosBySpecificationId(specificationId));

            testScenariosStopwatch.Stop();

            if (testScenarios.IsNullOrEmpty())
            {
                _logger.Warning($"No test scenarios found for specification id: {specificationId}");
                return;
            }

            Stopwatch specificationLookupStopwatch = Stopwatch.StartNew();
            ApiResponse <SpecModel.SpecificationSummary> specificationApiResponse =
                await _specificationsApiClientPolicy.ExecuteAsync(() => _specificationsApiClient.GetSpecificationSummaryById(specificationId));

            specificationLookupStopwatch.Stop();

            if (!specificationApiResponse.StatusCode.IsSuccess() || specificationApiResponse.Content == null)
            {
                _logger.Error($"No specification found for specification id: {specificationId}");
                return;
            }

            SpecModel.SpecificationSummary specification = specificationApiResponse.Content;

            IEnumerable <string> providerIds = providerResults.Select(m => m.Provider.Id);

            Stopwatch providerSourceDatasetsStopwatch          = Stopwatch.StartNew();
            IEnumerable <ProviderSourceDataset> sourceDatasets = await _providerSourceDatasetsRepositoryPolicy.ExecuteAsync(() =>
                                                                                                                            _providerSourceDatasetsRepository.GetProviderSourceDatasetsByProviderIdsAndSpecificationId(providerIds, specificationId));

            providerSourceDatasetsStopwatch.Stop();

            if (sourceDatasets.IsNullOrEmpty())
            {
                _logger.Error($"No source datasets found for specification id: {specificationId}");
                return;
            }

            byte[] assembly = await _calculationsRepository.GetAssemblyBySpecificationId(specificationId);

            if (assembly.IsNullOrEmpty())
            {
                _logger.Error($"No assemblyfor specification id: {specificationId}");
                return;
            }

            buildProject.Build.Assembly = assembly;

            Stopwatch existingTestResultsStopwatch = Stopwatch.StartNew();
            IEnumerable <TestScenarioResult> testScenarioResults = await _testResultsRepositoryPolicy.ExecuteAsync(() => _testResultsRepository.GetCurrentTestResults(providerIds, specificationId));

            existingTestResultsStopwatch.Stop();

            Stopwatch runTestsStopwatch = Stopwatch.StartNew();
            IEnumerable <TestScenarioResult> results = await _testEngine.RunTests(testScenarios, providerResults, sourceDatasets, testScenarioResults.ToList(), specification, buildProject);

            runTestsStopwatch.Stop();

            Stopwatch saveResultsStopwatch = new Stopwatch();

            if (results.Any())
            {
                saveResultsStopwatch.Start();
                HttpStatusCode status = await _testResultsService.SaveTestProviderResults(results, providerResults);

                saveResultsStopwatch.Stop();

                if (!status.IsSuccess())
                {
                    _logger.Error($"Failed to save test results with status code: {status}");
                }
            }

            runTestsStopWatch.Stop();

            IDictionary <string, double> metrics = new Dictionary <string, double>()
            {
                { "tests-run-totalMs", runTestsStopWatch.ElapsedMilliseconds },
                { "tests-run-testScenarioQueryMs", testScenariosStopwatch.ElapsedMilliseconds },
                { "tests-run-numberOfTestScenarios", testScenarios.Count() },
                { "tests-run-providersResultsQueryMs", providerResultsQueryStopwatch.ElapsedMilliseconds },
                { "tests-run-totalProvidersProcessed", providerIds.Count() },
                { "tests-run-specificationQueryMs", specificationLookupStopwatch.ElapsedMilliseconds },
                { "tests-run-providerSourceDatasetsQueryMs", providerSourceDatasetsStopwatch.ElapsedMilliseconds },
                { "tests-run-existingTestsQueryMs", existingTestResultsStopwatch.ElapsedMilliseconds },
                { "tests-run-existingTestScenarioResultsTotal", testScenarioResults.Count() },
                { "tests-run-runTestsMs", runTestsStopwatch.ElapsedMilliseconds },
            };

            if (results.Any())
            {
                metrics.Add("tests-run-saveTestResultsMs", saveResultsStopwatch.ElapsedMilliseconds);
                metrics.Add("tests-run-numberOfSavedResults", results.Count());
            }

            _telemetry.TrackEvent("RunTests",
                                  new Dictionary <string, string>()
            {
                { "specificationId", specificationId },
                { "buildProjectId", buildProject.Id },
                { "cacheKey", cacheKey },
            },
                                  metrics
                                  );
        }