Esempio n. 1
0
        public ActionResult Index()
        {
            var startDate = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1);
            using (var dbContext = new ReportingContext())
            {
                var buildSummary = GetLastBuildSummary(dbContext);
                var viewModel = new HomeViewModel
                {
                    Builds = buildSummary,
                    CoverageStat = new ModuleCoverageForABuild(),
                    Challenges = ComputeChallengesSummary(dbContext, startDate, startDate.AddMonths(1)),
                };

                var mainProjectName = ConfigurationManager.AppSettings["MainProjectName"];
                var lastBuild = !string.IsNullOrEmpty(mainProjectName) ? buildSummary.FirstOrDefault(i => i.ActualBuild.Definition == mainProjectName) : buildSummary.FirstOrDefault();
                if (lastBuild != null)
                {
                    var coverages = lastBuild.ActualBuild.CoverageCollection.OrderBy(i => (i.BlocksCovered * 100) / (i.BlocksNotCovered + i.BlocksCovered)).ToArray();
                    viewModel.CoverageStat.Modules = string.Join(", ", coverages.Select(i => i.Name.Replace(".dll", string.Empty).Replace(".exe", string.Empty)));
                    viewModel.CoverageStat.Coverages = string.Join(", ", coverages.Select(i => (i.BlocksCovered * 100) / (i.BlocksNotCovered + i.BlocksCovered)));
                }

                viewModel.ShootBoxBuilds = GetLastBuilds(dbContext, startDate, startDate.AddMonths(1)).ToArray();
                return View(viewModel);
            }
        }
Esempio n. 2
0
        public ActionResult Challenges()
        {
            var monthChallenges = new List<MonthChallenge>();
            using (var context = new ReportingContext())
            {
                var firstDate = context.Builds.OrderBy(i => i.Date).Select(i => i.Date).FirstOrDefault();
                firstDate = new DateTime(firstDate.Year, firstDate.Month, 1);
                for (var date = firstDate; date < DateTime.UtcNow; date = date.AddMonths(1))
                {
                    var challengeSummary = ComputeChallengesSummary(context, date, date.AddMonths(1));
                    monthChallenges.Add(new MonthChallenge
                    {
                        Date = date,
                        Summary = challengeSummary
                    });
                }
            }

            return View(new ChallengesViewModel { MonthChallenges = monthChallenges.OrderByDescending(i => i.Date).ToArray() });
        }
Esempio n. 3
0
        private IEnumerable<ChallengeSummary> ComputeChallengesSummary(ReportingContext dbContext, DateTime startDate, DateTime stopDate)
        {
            var challenges = new List<ChallengeSummary>();
            var committers = dbContext.Builds.Where(i => i.Date >= startDate && i.Date < stopDate).Select(i => i.User).Distinct().ToArray();

            // ReSharper disable once LoopCanBeConvertedToQuery
            foreach (var committer in committers)
            {
                var currentCommitter = committer;
                var challengeEntities = dbContext.Challenges.Where(i => i.User == currentCommitter && i.Build.Date >= startDate && i.Build.Date < stopDate).ToList();
                var points = challengeEntities.Sum(i => i.Points);
                var challengeSummary = new ChallengeSummary
                {
                    Name = committer,
                    Points = Convert.ToInt32(points)
                };
                challenges.Add(challengeSummary);
            }

            return challenges.OrderByDescending(i => i.Points).Take(3);
        }
        private double ComputeRatio(BuildEntity buildEntity, ReportingContext context)
        {
            var currentProject = context.Projects.FirstOrDefault(i => i.Name == buildEntity.Definition);
            if (currentProject == null)
            {
                currentProject = new ProjectEntity { Name = buildEntity.Definition };
                context.Projects.Add(currentProject);
            }
            if (!buildEntity.CoverageCollection.Any())
                return 0;

            var currentProjectBlock = buildEntity.CoverageCollection.Sum(i => i.BlocksCovered + i.BlocksNotCovered);
            currentProject.Blocks = currentProjectBlock;

            if (!context.Projects.Any())
                return 1;

            var maxBlock = context.Projects.Max(i => i.Blocks);
            var maxProject = context.Projects.FirstOrDefault(i => i.Blocks == maxBlock);
            if (maxProject == null || maxBlock == 0)
                return 1; // Ratio = 1 : no project to be compared.

            if (maxProject.Id == currentProject.Id)
                return 1; // current projet is the bigest project.

            return (double)currentProjectBlock / maxBlock;
        }
        public async Task<IHttpActionResult> Post([FromBody] HttpHookBuild build)
        {
            var knowDefinitionsBuilds = ConfigurationManager.AppSettings["ExpectedBuilds"].Split('|').Where(i => !string.IsNullOrEmpty(i)).ToArray();
            if (knowDefinitionsBuilds.Any() && !knowDefinitionsBuilds.Contains(build.resource.definition.name))
                return Ok();

            try
            {
                using (var context = new ReportingContext())
                {
                    var request = build.resource.requests.FirstOrDefault();

                    var buildEntity = new BuildEntity
                    {
                        BuildName = build.resource.buildNumber,
                        Definition = build.resource.definition.name,
                        Date = build.resource.finishTime,
                        Status = build.resource.status,
                        Reason = build.resource.reason,
                        Link = build.message.html,
                        User = request != null ? request.requestedFor.uniqueName : "Unknown user",
                        CoverageCollection = new Collection<CoverageEntity>()
                    };

                    if (buildEntity.User == "Project Collection Service Accounts")
                        buildEntity.User = "******";

                    if (buildEntity.User == ConfigurationManager.AppSettings["VsoUsername"])
                        return Ok();

                    if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["VSO.OrganisationName"]) || string.IsNullOrEmpty(ConfigurationManager.AppSettings["VSO.ProjectName"]))
                        throw new ApplicationException("Please configuration VSO.OrganisationName and VSO.ProjectName first.");

                    var api = new ApiWrapper(ConfigurationManager.AppSettings["VSO.OrganisationName"], ConfigurationManager.AppSettings["VSO.ProjectName"]);
                    var coverage = await api.GetBuildCoverageAsync(build);
                    if (coverage != null)
                    {
                        foreach (var moduleCoverage in coverage)
                        {
                            buildEntity.CoverageCollection.Add(new CoverageEntity
                            {
                                Name = moduleCoverage.Name,
                                ComputedAverage = moduleCoverage.ComputedAverage,
                                BlocksCovered = moduleCoverage.BlocksCovered,
                                BlocksNotCovered = moduleCoverage.BlocksNotCovered,
                                Build = buildEntity
                            });
                        }
                    }

                    double currentRatio = ComputeRatio(buildEntity, context);
                    var challenge = ComputeCoverageChanges(buildEntity, context, currentRatio);
                    if (challenge != null)
                        context.Challenges.Add(challenge);

                    context.Builds.Add(buildEntity);
                    context.SaveChanges();
                }

                return Ok();
            }
            catch (Exception e)
            {
                return BadRequest(e.Message);
            }
        }
        private ChallengeEntity ComputeCoverageChanges(BuildEntity buildEntity, ReportingContext context, double currentRatio)
        {
            if (buildEntity.Status != "succeeded")
                return null;

            var previousBuild = context.Builds
                .OrderByDescending(i => i.Date)
                .FirstOrDefault(i => i.Definition == buildEntity.Definition && i.Status == "succeeded" && i.CoverageCollection.Any());

            if (previousBuild == null)
                return null;

            var challenge = new ChallengeEntity
            {
                User = buildEntity.User,
                Build = buildEntity,
                ModuleCoverages = new List<ModuleChallengeCoverage>()
            };

            var allModules = previousBuild.CoverageCollection.Select(i => i.Name).Union(buildEntity.CoverageCollection.Select(i => i.Name));
            foreach (var moduleName in allModules)
            {
                var currentModuleName = moduleName;

                var previousModule = previousBuild.CoverageCollection.FirstOrDefault(i => i.Name == currentModuleName);
                var currentModule = buildEntity.CoverageCollection.FirstOrDefault(i => i.Name == currentModuleName);

                if (currentModule != null && previousModule != null && (previousModule.BlocksCovered == currentModule.BlocksCovered && previousModule.BlocksNotCovered == currentModule.BlocksNotCovered))
                    continue; // Ignore if no change in the module.
                if (currentModule == null)
                    continue;

                var previousModuleCoverage = ComputeBuildCoverage(previousModule);
                var currentModuleCoverage = ComputeBuildCoverage(currentModule);

                var deltaCoverage = currentModuleCoverage - previousModuleCoverage;
                var allBlocks = currentModule.BlocksCovered + currentModule.BlocksNotCovered;

                challenge.ModuleCoverages.Add(new ModuleChallengeCoverage { Module = currentModuleName, DeltaCoverage = deltaCoverage, Blocks = allBlocks });
            }

            var previousProjectCoverage = ComputeBuildCoverage(previousBuild);
            var currentProjectCoverage = ComputeBuildCoverage(buildEntity);
            challenge.Points = (currentProjectCoverage - previousProjectCoverage) * 100 * currentRatio;
            if (double.IsNaN(challenge.Points))
                challenge.Points = 0;

            return challenge;
        }
Esempio n. 7
0
        private IEnumerable<ShootBoxBuild> GetLastBuilds(ReportingContext dbContext, DateTime startDate, DateTime stopDate)
        {
            return dbContext.Builds.Where(i => i.Date >= startDate && i.Date < stopDate).OrderByDescending(i => i.Date).ToList().Select(i =>
            {
                var challenge = dbContext.Challenges.FirstOrDefault(j => j.Build.Id == i.Id);

                return new ShootBoxBuild
                {
                    BuildName = i.BuildName,
                    BuildDate = string.Format("{0} {1}", i.Date.ToShortDateString(), i.Date.ToShortTimeString()),
                    BuildColor = i.Status == "succeeded" ? "#5cb85c" : "#d9534f",
                    SumPoints = challenge != null ? Convert.ToInt32(challenge.Points) : 0,
                    DetailPoints = challenge != null ? challenge.ModuleCoverages : null,
                    User = i.User,
                };
            });
        }
Esempio n. 8
0
        private AboutViewModel GetCoverageStat(string buildName, int top)
        {
            using (var context = new ReportingContext())
            {
                var allStats = context.Builds
                    .Where(i => i.Definition == buildName && i.CoverageCollection.Any()).ToArray();

                if (top != 0)
                {
                    var count = allStats.Count();
                    if (count > top)
                    {
                        allStats = allStats.Skip(count - top).Take(top).ToArray();
                    }
                }

                var stats = allStats
                    .ToArray();
                var step = (stats.Length / 20);
                var selectedEntries = new List<BuildEntity>();
                for (var i = stats.Min(a => a.Id); i < stats.Max(a => a.Id); i += step)
                {
                    var b = stats.FirstOrDefault(j => j.Id == i);
                    if (b != null)
                        selectedEntries.Add(b);
                }
                if (!selectedEntries.Any())
                {
                    return new AboutViewModel { BuildName = buildName, Message = "No coverage result" };
                }


                if (selectedEntries.Count() == 1)
                {
                    selectedEntries = new List<BuildEntity> { selectedEntries[0], selectedEntries[0] };
                }

                selectedEntries = selectedEntries.OrderBy(i => i.Date).ToList();
                var moduleCoverages = new List<int>();
                foreach (var buildInformation in selectedEntries)
                {
                    if (buildInformation.CoverageCollection.Any())
                    {
                        var allCovered = buildInformation.CoverageCollection.Sum(i => i.BlocksCovered);
                        var allNotCovered = buildInformation.CoverageCollection.Sum(i => i.BlocksNotCovered);
                        moduleCoverages.Add((allCovered * 100) / (allNotCovered + allCovered));
                    }
                    else
                    {
                        moduleCoverages.Add(0);
                    }
                }
                var averageStat = new ModuleCoverageByBuild
                {
                    ModuleName = buildName,
                    Dates = string.Join(", ", selectedEntries.Select(i => string.Format("{0} {1}", i.Date.ToShortDateString(), i.Date.ToShortTimeString()))),
                    Coverages = string.Join(", ", moduleCoverages)
                };

                return new AboutViewModel
                {
                    BuildName = buildName,
                    AverageStatistics = averageStat,
                    BuildNames = ConfigurationManager.AppSettings["ExpectedBuilds"].Split('|').Select(i => new SelectListItem { Text = i }).ToList()
                };
            }
        }
Esempio n. 9
0
        private List<BuildSummary> GetLastBuildSummary(ReportingContext dbContext)
        {
            var builds = new List<BuildSummary>();

            foreach (var buildName in ConfigurationManager.AppSettings["ExpectedBuilds"].Split('|'))
            {
                var orderByDescending = dbContext.Builds.OrderByDescending(i => i.Date);
                var build = orderByDescending.FirstOrDefault(i => i.Definition == buildName);
                if (build == null)
                {
                    builds.Add(new BuildSummary { ActualBuild = new BuildEntity { BuildName = "Not actually a build.", CoverageCollection = new Collection<CoverageEntity>() }, Challenge = new ChallengeEntity() });
                    continue;
                }

                var actualBuild = build;
                foreach (var coverageEntity in actualBuild.CoverageCollection)
                {
                    coverageEntity.ComputedAverage =
                        (coverageEntity.BlocksCovered * 100) / (coverageEntity.BlocksCovered + coverageEntity.BlocksNotCovered);
                }
                actualBuild.CoverageCollection = actualBuild.CoverageCollection.OrderBy(i => i.ComputedAverage).ToArray();

                var actualAverageCoverage = ComputeBuildCoverage(actualBuild.CoverageCollection.ToList());

                var buildSummary = new BuildSummary
                {
                    ActualBuild = actualBuild,
                    ActualAverageCoverage = actualAverageCoverage,
                    Challenge = dbContext.Challenges.FirstOrDefault(i => i.Build.Id == actualBuild.Id),
                    UserGravatar = CalculateMD5Hash(actualBuild.User.ToLower()).ToLower()
                };
                builds.Add(buildSummary);
            }

            return builds;
        }