added unit tests for GitRepositoryBuildStatus class

pull/5418/head
İsmail ÇAĞDAŞ 5 years ago
parent e2624d4310
commit 588040cfa5

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.Build
{
public class DefaultBuildProjectListSorter : IBuildProjectListSorter, ITransientDependency
{
public List<DotNetProjectInfo> SortByDependencies(
List<DotNetProjectInfo> source,
IEqualityComparer<DotNetProjectInfo> comparer = null)
{
/* See: http://www.codeproject.com/Articles/869059/Topological-sorting-in-Csharp
* http://en.wikipedia.org/wiki/Topological_sorting
*/
var sorted = new List<DotNetProjectInfo>();
var visited = new Dictionary<DotNetProjectInfo, bool>(comparer);
foreach (var item in source)
{
SortByDependenciesVisit(source, item, sorted, visited);
}
return sorted;
}
private void SortByDependenciesVisit(
List<DotNetProjectInfo> source,
DotNetProjectInfo item,
List<DotNetProjectInfo> sorted,
Dictionary<DotNetProjectInfo, bool> visited)
{
bool inProcess;
var alreadyVisited = visited.TryGetValue(item, out inProcess);
if (alreadyVisited)
{
if (inProcess)
{
throw new ArgumentException("Cyclic dependency found! Item: " + item);
}
}
else
{
visited[item] = true;
var dependencies = item.Dependencies;
if (dependencies != null)
{
foreach (var dependency in dependencies)
{
var dependencyItem = source.FirstOrDefault(e => e.CsProjPath == dependency.CsProjPath);
if (dependencyItem != null)
{
SortByDependenciesVisit(source, dependencyItem, sorted, visited);
}
}
}
visited[item] = false;
sorted.Add(item);
}
}
}
}

@ -174,6 +174,15 @@ namespace Volo.Abp.Cli.Build
foreach (var file in allCsProjFiles)
{
if (status == null)
{
changedFiles.Add(
new DotNetProjectInfo(repository.Name, Path.Combine(repository.RootPath, file))
);
continue;
}
if (status.GetSelfOrChild(repository.Name).SucceedProjects.Any(e=> e.CsProjPath == file))
{
continue;

@ -17,7 +17,8 @@ namespace Volo.Abp.Cli.Build
Directory.CreateDirectory(BaseBuildStatusStorePath);
}
var buildStatusFile = Path.Combine(BaseBuildStatusStorePath, repository.GetUniqueName(buildNamePrefix)) + ".json";
var buildStatusFile = Path.Combine(BaseBuildStatusStorePath, repository.GetUniqueName(buildNamePrefix)) +
".json";
if (!File.Exists(buildStatusFile))
{
@ -29,12 +30,9 @@ namespace Volo.Abp.Cli.Build
return JsonConvert.DeserializeObject<GitRepositoryBuildStatus>(buildStatusText);
}
public void Set(string buildNamePrefix, GitRepositoryBuildStatus status)
public void Set(string buildNamePrefix, GitRepository repository, GitRepositoryBuildStatus status)
{
if (!Directory.Exists(BaseBuildStatusStorePath))
{
Directory.CreateDirectory(BaseBuildStatusStorePath);
}
var existingRepositoryStatus = Get(buildNamePrefix, repository);
var buildStatusFile = Path.Combine(BaseBuildStatusStorePath, status.GetUniqueName(buildNamePrefix)) + ".json";
if (File.Exists(buildStatusFile))
@ -42,10 +40,28 @@ namespace Volo.Abp.Cli.Build
FileHelper.DeleteIfExists(buildStatusFile);
}
existingRepositoryStatus.MergeWith(status);
using (var file = File.CreateText(buildStatusFile))
{
new JsonSerializer {Formatting = Formatting.Indented}.Serialize(file, status);
new JsonSerializer {Formatting = Formatting.Indented}.Serialize(file, existingRepositoryStatus);
}
}
// private void UpdateBuildStatus(
// GitRepositoryBuildStatus existingBuildStatus,
// GitRepositoryBuildStatus newBuildStatus)
// {
//
// foreach (var succeedProject in newBuildStatus.SucceedProjects)
// {
// existingBuildStatus.UpdateProjectStatus(succeedProject);
//
// foreach (var dependingRepositoryBuildStatus in newBuildStatus.DependingRepositories)
// {
// UpdateBuildStatus(existingBuildStatus, dependingRepositoryBuildStatus);
// }
// }
// }
}
}
}

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Volo.Abp.Cli.Build
{
@ -58,6 +59,48 @@ namespace Volo.Abp.Cli.Build
return null;
}
public string GetUniqueName(string uniqueName)
{
var name = RepositoryName + "_" + BranchName;
foreach (var dependingRepository in DependingRepositories)
{
AddToUniqueName(dependingRepository, name);
}
return (uniqueName.IsNullOrEmpty() ? "" : uniqueName + "_") + name.ToMd5();
}
public void AddOrUpdateProjectStatus(DotNetProjectBuildStatus status)
{
var existingProjectStatus = SucceedProjects.FirstOrDefault(p => p.CsProjPath == status.CsProjPath);
if (existingProjectStatus != null)
{
existingProjectStatus.CommitId = status.CommitId;
}
else
{
SucceedProjects.Add(status);
}
foreach (var dependingRepository in DependingRepositories)
{
dependingRepository.AddOrUpdateProjectStatus(status);
}
}
public void MergeWith(GitRepositoryBuildStatus newBuildStatus)
{
foreach (var succeedProject in newBuildStatus.SucceedProjects)
{
AddOrUpdateProjectStatus(succeedProject);
foreach (var dependingRepositoryBuildStatus in newBuildStatus.DependingRepositories)
{
MergeWith(dependingRepositoryBuildStatus);
}
}
}
private GitRepositoryBuildStatus GetChildInternal(GitRepositoryBuildStatus repositoryBuildStatus,
string repositoryName)
{
@ -73,18 +116,7 @@ namespace Volo.Abp.Cli.Build
return null;
}
public string GetUniqueName(string uniqueName)
{
var name = RepositoryName + "_" + BranchName;
foreach (var dependingRepository in DependingRepositories)
{
AddToUniqueName(dependingRepository, name);
}
return (uniqueName.IsNullOrEmpty() ? "" : uniqueName + "_") + name.ToMd5();
}
private void AddToUniqueName(GitRepositoryBuildStatus gitRepository, string name)
{
name += "_" + gitRepository.RepositoryName + "_" + gitRepository.BranchName;

@ -0,0 +1,11 @@
using System.Collections.Generic;
namespace Volo.Abp.Cli.Build
{
public interface IBuildProjectListSorter
{
List<DotNetProjectInfo> SortByDependencies(
List<DotNetProjectInfo> source,
IEqualityComparer<DotNetProjectInfo> comparer = null);
}
}

@ -4,6 +4,6 @@
{
GitRepositoryBuildStatus Get(string buildNamePrefix, GitRepository repository);
void Set(string buildNamePrefix, GitRepositoryBuildStatus status);
void Set(string buildNamePrefix, GitRepository repository, GitRepositoryBuildStatus status);
}
}

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
@ -28,6 +26,8 @@ namespace Volo.Abp.Cli.Commands
public IBuildStatusGenerator BuildStatusGenerator { get; set; }
public IBuildProjectListSorter BuildProjectListSorter { get; set; }
public Task ExecuteAsync(CommandLineArgs commandLineArgs)
{
var sw = new Stopwatch();
@ -63,7 +63,7 @@ namespace Volo.Abp.Cli.Commands
DotNetProjectDependencyFiller.Fill(changedProjectFiles);
var sortedProjects = SortByDependencies(
var sortedProjects = BuildProjectListSorter.SortByDependencies(
changedProjectFiles,
new DotNetProjectInfoEqualityComparer()
);
@ -80,68 +80,14 @@ namespace Volo.Abp.Cli.Commands
buildSucceededProjects
);
RepositoryBuildStatusStore.Set(buildName, buildStatus);
RepositoryBuildStatusStore.Set(buildName, buildConfig.GitRepository, buildStatus);
sw.Stop();
Console.WriteLine("Build operation is completed in " + sw.ElapsedMilliseconds + " (ms)");
return Task.CompletedTask;
}
private List<DotNetProjectInfo> SortByDependencies(
List<DotNetProjectInfo> source,
IEqualityComparer<DotNetProjectInfo> comparer = null)
{
/* See: http://www.codeproject.com/Articles/869059/Topological-sorting-in-Csharp
* http://en.wikipedia.org/wiki/Topological_sorting
*/
var sorted = new List<DotNetProjectInfo>();
var visited = new Dictionary<DotNetProjectInfo, bool>(comparer);
foreach (var item in source)
{
SortByDependenciesVisit(source, item, sorted, visited);
}
return sorted;
}
private void SortByDependenciesVisit(
List<DotNetProjectInfo> source,
DotNetProjectInfo item,
List<DotNetProjectInfo> sorted,
Dictionary<DotNetProjectInfo, bool> visited)
{
bool inProcess;
var alreadyVisited = visited.TryGetValue(item, out inProcess);
if (alreadyVisited)
{
if (inProcess)
{
throw new ArgumentException("Cyclic dependency found! Item: " + item);
}
}
else
{
visited[item] = true;
var dependencies = item.Dependencies;
if (dependencies != null)
{
foreach (var dependency in dependencies)
{
var dependencyItem = source.FirstOrDefault(e => e.CsProjPath == dependency.CsProjPath);
SortByDependenciesVisit(source, dependencyItem, sorted, visited);
}
}
visited[item] = false;
sorted.Add(item);
}
}
public string GetUsageInfo()
{
var sb = new StringBuilder();

@ -0,0 +1,86 @@
using System.Collections.Generic;
using System.Linq;
using Shouldly;
using Xunit;
namespace Volo.Abp.Cli.Build
{
public class GitRepositoryBuildStatus_Tests : AbpCliTestBase
{
[Fact]
public void Add_New_Build_Status_Test()
{
var existingBuildStatus = new GitRepositoryBuildStatus("volo", "dev")
{
SucceedProjects = new List<DotNetProjectBuildStatus>
{
new DotNetProjectBuildStatus
{
CsProjPath = "project1.csproj",
CommitId = "1"
}
}
};
var newBuildStatus = new GitRepositoryBuildStatus(
existingBuildStatus.RepositoryName,
existingBuildStatus.BranchName
)
{
SucceedProjects = new List<DotNetProjectBuildStatus>
{
new DotNetProjectBuildStatus
{
CsProjPath = "project2.csproj",
CommitId = "2"
}
}
};
existingBuildStatus.MergeWith(newBuildStatus);
existingBuildStatus.SucceedProjects.Count.ShouldBe(2);
}
[Fact]
public void Update_Existing_Build_Status_Test()
{
var existingBuildStatus = new GitRepositoryBuildStatus("volo", "dev")
{
SucceedProjects = new List<DotNetProjectBuildStatus>
{
new DotNetProjectBuildStatus
{
CsProjPath = "project1.csproj",
CommitId = "1"
}
}
};
var newBuildStatus = new GitRepositoryBuildStatus(
existingBuildStatus.RepositoryName,
existingBuildStatus.BranchName
)
{
SucceedProjects = new List<DotNetProjectBuildStatus>
{
new DotNetProjectBuildStatus
{
CsProjPath = "project1.csproj",
CommitId = "2"
},
new DotNetProjectBuildStatus
{
CsProjPath = "project2.csproj",
CommitId = "2"
}
}
};
existingBuildStatus.MergeWith(newBuildStatus);
existingBuildStatus.SucceedProjects.Count.ShouldBe(2);
existingBuildStatus.GetSelfOrChild("volo").SucceedProjects.First(p => p.CsProjPath == "project1.csproj").CommitId.ShouldBe("2");
existingBuildStatus.GetSelfOrChild("volo").SucceedProjects.First(p => p.CsProjPath == "project2.csproj").CommitId.ShouldBe("2");
}
}
}
Loading…
Cancel
Save