Merge branch 'jmezach-bugfix/fcp-dispose' into develop

This commit is contained in:
TomPallister 2020-01-19 10:48:26 +00:00
commit a2a5ec635a
3 changed files with 527 additions and 506 deletions

View File

@ -1,500 +1,500 @@
#tool "nuget:?package=GitVersion.CommandLine&version=5.0.1" #tool "nuget:?package=GitVersion.CommandLine&version=5.0.1"
#tool "nuget:?package=GitReleaseNotes" #tool "nuget:?package=GitReleaseNotes"
#addin nuget:?package=Cake.Json #addin nuget:?package=Cake.Json
#addin nuget:?package=Newtonsoft.Json #addin nuget:?package=Newtonsoft.Json
#addin nuget:?package=System.Net.Http #addin nuget:?package=System.Net.Http
#tool "nuget:?package=ReportGenerator" #tool "nuget:?package=ReportGenerator"
#tool "nuget:?package=coveralls.net&version=0.7.0" #tool "nuget:?package=coveralls.net&version=0.7.0"
#addin Cake.Coveralls&version=0.10.1 #addin Cake.Coveralls&version=0.10.1
// compile // compile
var compileConfig = Argument("configuration", "Release"); var compileConfig = Argument("configuration", "Release");
var slnFile = "./Ocelot.sln"; var slnFile = "./Ocelot.sln";
// build artifacts // build artifacts
var artifactsDir = Directory("artifacts"); var artifactsDir = Directory("artifacts");
// unit testing // unit testing
var artifactsForUnitTestsDir = artifactsDir + Directory("UnitTests"); var artifactsForUnitTestsDir = artifactsDir + Directory("UnitTests");
var unitTestAssemblies = @"./test/Ocelot.UnitTests/Ocelot.UnitTests.csproj"; var unitTestAssemblies = @"./test/Ocelot.UnitTests/Ocelot.UnitTests.csproj";
var minCodeCoverage = 80d; var minCodeCoverage = 80d;
var coverallsRepoToken = "OCELOT_COVERALLS_TOKEN"; var coverallsRepoToken = "OCELOT_COVERALLS_TOKEN";
var coverallsRepo = "https://coveralls.io/github/ThreeMammals/Ocelot"; var coverallsRepo = "https://coveralls.io/github/ThreeMammals/Ocelot";
// acceptance testing // acceptance testing
var artifactsForAcceptanceTestsDir = artifactsDir + Directory("AcceptanceTests"); var artifactsForAcceptanceTestsDir = artifactsDir + Directory("AcceptanceTests");
var acceptanceTestAssemblies = @"./test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj"; var acceptanceTestAssemblies = @"./test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj";
// integration testing // integration testing
var artifactsForIntegrationTestsDir = artifactsDir + Directory("IntegrationTests"); var artifactsForIntegrationTestsDir = artifactsDir + Directory("IntegrationTests");
var integrationTestAssemblies = @"./test/Ocelot.IntegrationTests/Ocelot.IntegrationTests.csproj"; var integrationTestAssemblies = @"./test/Ocelot.IntegrationTests/Ocelot.IntegrationTests.csproj";
// benchmark testing // benchmark testing
var artifactsForBenchmarkTestsDir = artifactsDir + Directory("BenchmarkTests"); var artifactsForBenchmarkTestsDir = artifactsDir + Directory("BenchmarkTests");
var benchmarkTestAssemblies = @"./test/Ocelot.Benchmarks"; var benchmarkTestAssemblies = @"./test/Ocelot.Benchmarks";
// packaging // packaging
var packagesDir = artifactsDir + Directory("Packages"); var packagesDir = artifactsDir + Directory("Packages");
var releaseNotesFile = packagesDir + File("releasenotes.md"); var releaseNotesFile = packagesDir + File("releasenotes.md");
var artifactsFile = packagesDir + File("artifacts.txt"); var artifactsFile = packagesDir + File("artifacts.txt");
// stable releases // stable releases
var tagsUrl = "https://api.github.com/repos/ThreeMammals/ocelot/releases/tags/"; var tagsUrl = "https://api.github.com/repos/ThreeMammals/ocelot/releases/tags/";
var nugetFeedStableKey = EnvironmentVariable("OCELOT_NUTGET_API_KEY"); var nugetFeedStableKey = EnvironmentVariable("OCELOT_NUTGET_API_KEY");
var nugetFeedStableUploadUrl = "https://www.nuget.org/api/v2/package"; var nugetFeedStableUploadUrl = "https://www.nuget.org/api/v2/package";
var nugetFeedStableSymbolsUploadUrl = "https://www.nuget.org/api/v2/package"; var nugetFeedStableSymbolsUploadUrl = "https://www.nuget.org/api/v2/package";
// internal build variables - don't change these. // internal build variables - don't change these.
string committedVersion = "0.0.0-dev"; string committedVersion = "0.0.0-dev";
GitVersion versioning = null; GitVersion versioning = null;
int releaseId = 0; int releaseId = 0;
string gitHubUsername = "TomPallister"; string gitHubUsername = "TomPallister";
string gitHubPassword = Environment.GetEnvironmentVariable("OCELOT_GITHUB_API_KEY"); string gitHubPassword = Environment.GetEnvironmentVariable("OCELOT_GITHUB_API_KEY");
var target = Argument("target", "Default"); var target = Argument("target", "Default");
Information("target is " + target); Information("target is " + target);
Information("Build configuration is " + compileConfig); Information("Build configuration is " + compileConfig);
Task("Default") Task("Default")
.IsDependentOn("Build"); .IsDependentOn("Build");
Task("Build") Task("Build")
.IsDependentOn("RunTests"); .IsDependentOn("RunTests");
Task("RunTests") Task("RunTests")
.IsDependentOn("RunUnitTests") .IsDependentOn("RunUnitTests")
.IsDependentOn("RunAcceptanceTests") .IsDependentOn("RunAcceptanceTests")
.IsDependentOn("RunIntegrationTests"); .IsDependentOn("RunIntegrationTests");
Task("Release") Task("Release")
.IsDependentOn("Build") .IsDependentOn("Build")
.IsDependentOn("CreateArtifacts") .IsDependentOn("CreateArtifacts")
.IsDependentOn("PublishGitHubRelease") .IsDependentOn("PublishGitHubRelease")
.IsDependentOn("PublishToNuget"); .IsDependentOn("PublishToNuget");
Task("Compile") Task("Compile")
.IsDependentOn("Clean") .IsDependentOn("Clean")
.IsDependentOn("Version") .IsDependentOn("Version")
.Does(() => .Does(() =>
{ {
var settings = new DotNetCoreBuildSettings var settings = new DotNetCoreBuildSettings
{ {
Configuration = compileConfig, Configuration = compileConfig,
}; };
DotNetCoreBuild(slnFile, settings); DotNetCoreBuild(slnFile, settings);
}); });
Task("Clean") Task("Clean")
.Does(() => .Does(() =>
{ {
if (DirectoryExists(artifactsDir)) if (DirectoryExists(artifactsDir))
{ {
DeleteDirectory(artifactsDir, recursive:true); DeleteDirectory(artifactsDir, recursive:true);
} }
CreateDirectory(artifactsDir); CreateDirectory(artifactsDir);
}); });
Task("Version") Task("Version")
.Does(() => .Does(() =>
{ {
versioning = GetNuGetVersionForCommit(); versioning = GetNuGetVersionForCommit();
var nugetVersion = versioning.NuGetVersion; var nugetVersion = versioning.NuGetVersion;
Information("SemVer version number: " + nugetVersion); Information("SemVer version number: " + nugetVersion);
if (IsRunningOnCircleCI()) if (IsRunningOnCircleCI())
{ {
Information("Persisting version number..."); Information("Persisting version number...");
PersistVersion(committedVersion, nugetVersion); PersistVersion(committedVersion, nugetVersion);
} }
else else
{ {
Information("We are not running on build server, so we won't persist the version number."); Information("We are not running on build server, so we won't persist the version number.");
} }
}); });
Task("RunUnitTests") Task("RunUnitTests")
.IsDependentOn("Compile") .IsDependentOn("Compile")
.Does(() => .Does(() =>
{ {
var testSettings = new DotNetCoreTestSettings var testSettings = new DotNetCoreTestSettings
{ {
Configuration = compileConfig, Configuration = compileConfig,
ResultsDirectory = artifactsForUnitTestsDir, ResultsDirectory = artifactsForUnitTestsDir,
ArgumentCustomization = args => args ArgumentCustomization = args => args
// this create the code coverage report // this create the code coverage report
.Append("--settings test/Ocelot.UnitTests/UnitTests.runsettings") .Append("--settings test/Ocelot.UnitTests/UnitTests.runsettings")
}; };
EnsureDirectoryExists(artifactsForUnitTestsDir); EnsureDirectoryExists(artifactsForUnitTestsDir);
DotNetCoreTest(unitTestAssemblies, testSettings); DotNetCoreTest(unitTestAssemblies, testSettings);
var coverageSummaryFile = GetSubDirectories(artifactsForUnitTestsDir).First().CombineWithFilePath(File("coverage.opencover.xml")); var coverageSummaryFile = GetSubDirectories(artifactsForUnitTestsDir).First().CombineWithFilePath(File("coverage.opencover.xml"));
Information(coverageSummaryFile); Information(coverageSummaryFile);
Information(artifactsForUnitTestsDir); Information(artifactsForUnitTestsDir);
// todo bring back report generator to get a friendly report // todo bring back report generator to get a friendly report
// ReportGenerator(coverageSummaryFile, artifactsForUnitTestsDir); // ReportGenerator(coverageSummaryFile, artifactsForUnitTestsDir);
// https://github.com/danielpalme/ReportGenerator // https://github.com/danielpalme/ReportGenerator
if (IsRunningOnCircleCI()) if (IsRunningOnCircleCI())
{ {
var repoToken = EnvironmentVariable(coverallsRepoToken); var repoToken = EnvironmentVariable(coverallsRepoToken);
if (string.IsNullOrEmpty(repoToken)) if (string.IsNullOrEmpty(repoToken))
{ {
throw new Exception(string.Format("Coveralls repo token not found. Set environment variable '{0}'", coverallsRepoToken)); throw new Exception(string.Format("Coveralls repo token not found. Set environment variable '{0}'", coverallsRepoToken));
} }
Information(string.Format("Uploading test coverage to {0}", coverallsRepo)); Information(string.Format("Uploading test coverage to {0}", coverallsRepo));
CoverallsNet(coverageSummaryFile, CoverallsNetReportType.OpenCover, new CoverallsNetSettings() CoverallsNet(coverageSummaryFile, CoverallsNetReportType.OpenCover, new CoverallsNetSettings()
{ {
RepoToken = repoToken RepoToken = repoToken
}); });
} }
else else
{ {
Information("We are not running on the build server so we won't publish the coverage report to coveralls.io"); Information("We are not running on the build server so we won't publish the coverage report to coveralls.io");
} }
var sequenceCoverage = XmlPeek(coverageSummaryFile, "//CoverageSession/Summary/@sequenceCoverage"); var sequenceCoverage = XmlPeek(coverageSummaryFile, "//CoverageSession/Summary/@sequenceCoverage");
var branchCoverage = XmlPeek(coverageSummaryFile, "//CoverageSession/Summary/@branchCoverage"); var branchCoverage = XmlPeek(coverageSummaryFile, "//CoverageSession/Summary/@branchCoverage");
Information("Sequence Coverage: " + sequenceCoverage); Information("Sequence Coverage: " + sequenceCoverage);
if(double.Parse(sequenceCoverage) < minCodeCoverage) if(double.Parse(sequenceCoverage) < minCodeCoverage)
{ {
var whereToCheck = !IsRunningOnCircleCI() ? coverallsRepo : artifactsForUnitTestsDir; var whereToCheck = !IsRunningOnCircleCI() ? coverallsRepo : artifactsForUnitTestsDir;
throw new Exception(string.Format("Code coverage fell below the threshold of {0}%. You can find the code coverage report at {1}", minCodeCoverage, whereToCheck)); throw new Exception(string.Format("Code coverage fell below the threshold of {0}%. You can find the code coverage report at {1}", minCodeCoverage, whereToCheck));
}; };
}); });
Task("RunAcceptanceTests") Task("RunAcceptanceTests")
.IsDependentOn("Compile") .IsDependentOn("Compile")
.Does(() => .Does(() =>
{ {
var settings = new DotNetCoreTestSettings var settings = new DotNetCoreTestSettings
{ {
Configuration = compileConfig, Configuration = compileConfig,
ArgumentCustomization = args => args ArgumentCustomization = args => args
.Append("--no-restore") .Append("--no-restore")
.Append("--no-build") .Append("--no-build")
}; };
EnsureDirectoryExists(artifactsForAcceptanceTestsDir); EnsureDirectoryExists(artifactsForAcceptanceTestsDir);
DotNetCoreTest(acceptanceTestAssemblies, settings); DotNetCoreTest(acceptanceTestAssemblies, settings);
}); });
Task("RunIntegrationTests") Task("RunIntegrationTests")
.IsDependentOn("Compile") .IsDependentOn("Compile")
.Does(() => .Does(() =>
{ {
var settings = new DotNetCoreTestSettings var settings = new DotNetCoreTestSettings
{ {
Configuration = compileConfig, Configuration = compileConfig,
ArgumentCustomization = args => args ArgumentCustomization = args => args
.Append("--no-restore") .Append("--no-restore")
.Append("--no-build") .Append("--no-build")
}; };
EnsureDirectoryExists(artifactsForIntegrationTestsDir); EnsureDirectoryExists(artifactsForIntegrationTestsDir);
DotNetCoreTest(integrationTestAssemblies, settings); DotNetCoreTest(integrationTestAssemblies, settings);
}); });
Task("CreateArtifacts") Task("CreateArtifacts")
.IsDependentOn("Compile") .IsDependentOn("Compile")
.Does(() => .Does(() =>
{ {
EnsureDirectoryExists(packagesDir); EnsureDirectoryExists(packagesDir);
CopyFiles("./src/**/Release/Ocelot.*.nupkg", packagesDir); CopyFiles("./src/**/Release/Ocelot.*.nupkg", packagesDir);
// todo fix this for docker build // todo fix this for docker build
//GenerateReleaseNotes(releaseNotesFile); //GenerateReleaseNotes(releaseNotesFile);
var projectFiles = GetFiles("./src/**/Release/Ocelot.*.nupkg"); var projectFiles = GetFiles("./src/**/Release/Ocelot.*.nupkg");
foreach(var projectFile in projectFiles) foreach(var projectFile in projectFiles)
{ {
System.IO.File.AppendAllLines(artifactsFile, new[]{ System.IO.File.AppendAllLines(artifactsFile, new[]{
projectFile.GetFilename().FullPath, projectFile.GetFilename().FullPath,
// todo fix this for docker build // todo fix this for docker build
//"releaseNotes:releasenotes.md" //"releaseNotes:releasenotes.md"
}); });
} }
var artifacts = System.IO.File var artifacts = System.IO.File
.ReadAllLines(artifactsFile) .ReadAllLines(artifactsFile)
.Distinct(); .Distinct();
foreach(var artifact in artifacts) foreach(var artifact in artifacts)
{ {
var codePackage = packagesDir + File(artifact); var codePackage = packagesDir + File(artifact);
Information("Created package " + codePackage); Information("Created package " + codePackage);
} }
}); });
Task("PublishGitHubRelease") Task("PublishGitHubRelease")
.IsDependentOn("CreateArtifacts") .IsDependentOn("CreateArtifacts")
.Does(() => .Does(() =>
{ {
if (IsRunningOnCircleCI()) if (IsRunningOnCircleCI())
{ {
var path = packagesDir.ToString() + @"/**/*"; var path = packagesDir.ToString() + @"/**/*";
CreateGitHubRelease(); CreateGitHubRelease();
foreach (var file in GetFiles(path)) foreach (var file in GetFiles(path))
{ {
UploadFileToGitHubRelease(file); UploadFileToGitHubRelease(file);
} }
CompleteGitHubRelease(); CompleteGitHubRelease();
} }
}); });
Task("EnsureStableReleaseRequirements") Task("EnsureStableReleaseRequirements")
.Does(() => .Does(() =>
{ {
Information("Check if stable release..."); Information("Check if stable release...");
if (!IsRunningOnCircleCI()) if (!IsRunningOnCircleCI())
{ {
throw new Exception("Stable release should happen via circleci"); throw new Exception("Stable release should happen via circleci");
} }
Information("Release is stable..."); Information("Release is stable...");
}); });
Task("DownloadGitHubReleaseArtifacts") Task("DownloadGitHubReleaseArtifacts")
.Does(() => .Does(() =>
{ {
try try
{ {
EnsureDirectoryExists(packagesDir); EnsureDirectoryExists(packagesDir);
var releaseUrl = tagsUrl + versioning.NuGetVersion; var releaseUrl = tagsUrl + versioning.NuGetVersion;
var assets_url = Newtonsoft.Json.Linq.JObject.Parse(GetResource(releaseUrl)) var assets_url = Newtonsoft.Json.Linq.JObject.Parse(GetResource(releaseUrl))
.Value<string>("assets_url"); .Value<string>("assets_url");
var assets = GetResource(assets_url); var assets = GetResource(assets_url);
foreach(var asset in Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JArray>(assets)) foreach(var asset in Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JArray>(assets))
{ {
var file = packagesDir + File(asset.Value<string>("name")); var file = packagesDir + File(asset.Value<string>("name"));
DownloadFile(asset.Value<string>("browser_download_url"), file); DownloadFile(asset.Value<string>("browser_download_url"), file);
} }
} }
catch(Exception exception) catch(Exception exception)
{ {
Information("There was an exception " + exception); Information("There was an exception " + exception);
throw; throw;
} }
}); });
Task("PublishToNuget") Task("PublishToNuget")
.IsDependentOn("DownloadGitHubReleaseArtifacts") .IsDependentOn("DownloadGitHubReleaseArtifacts")
.Does(() => .Does(() =>
{ {
if (IsRunningOnCircleCI()) if (IsRunningOnCircleCI())
{ {
PublishPackages(packagesDir, artifactsFile, nugetFeedStableKey, nugetFeedStableUploadUrl, nugetFeedStableSymbolsUploadUrl); PublishPackages(packagesDir, artifactsFile, nugetFeedStableKey, nugetFeedStableUploadUrl, nugetFeedStableSymbolsUploadUrl);
} }
}); });
RunTarget(target); RunTarget(target);
/// Gets nuique nuget version for this commit /// Gets nuique nuget version for this commit
private GitVersion GetNuGetVersionForCommit() private GitVersion GetNuGetVersionForCommit()
{ {
GitVersion(new GitVersionSettings{ GitVersion(new GitVersionSettings{
UpdateAssemblyInfo = false, UpdateAssemblyInfo = false,
OutputType = GitVersionOutput.BuildServer OutputType = GitVersionOutput.BuildServer
}); });
return GitVersion(new GitVersionSettings{ OutputType = GitVersionOutput.Json }); return GitVersion(new GitVersionSettings{ OutputType = GitVersionOutput.Json });
} }
/// Updates project version in all of our projects /// Updates project version in all of our projects
private void PersistVersion(string committedVersion, string newVersion) private void PersistVersion(string committedVersion, string newVersion)
{ {
Information(string.Format("We'll search all csproj files for {0} and replace with {1}...", committedVersion, newVersion)); Information(string.Format("We'll search all csproj files for {0} and replace with {1}...", committedVersion, newVersion));
var projectFiles = GetFiles("./**/*.csproj"); var projectFiles = GetFiles("./**/*.csproj");
foreach(var projectFile in projectFiles) foreach(var projectFile in projectFiles)
{ {
var file = projectFile.ToString(); var file = projectFile.ToString();
Information(string.Format("Updating {0}...", file)); Information(string.Format("Updating {0}...", file));
var updatedProjectFile = System.IO.File.ReadAllText(file) var updatedProjectFile = System.IO.File.ReadAllText(file)
.Replace(committedVersion, newVersion); .Replace(committedVersion, newVersion);
System.IO.File.WriteAllText(file, updatedProjectFile); System.IO.File.WriteAllText(file, updatedProjectFile);
} }
} }
/// generates release notes based on issues closed in GitHub since the last release /// generates release notes based on issues closed in GitHub since the last release
private void GenerateReleaseNotes(ConvertableFilePath file) private void GenerateReleaseNotes(ConvertableFilePath file)
{ {
if(!IsRunningOnWindows()) if(!IsRunningOnWindows())
{ {
Warning("We are not running on Windows so we cannot generate release notes."); Warning("We are not running on Windows so we cannot generate release notes.");
return; return;
} }
Information("Generating release notes at " + file); Information("Generating release notes at " + file);
var releaseNotesExitCode = StartProcess( var releaseNotesExitCode = StartProcess(
@"tools/GitReleaseNotes/tools/gitreleasenotes.exe", @"tools/GitReleaseNotes/tools/gitreleasenotes.exe",
new ProcessSettings { Arguments = ". /o " + file }); new ProcessSettings { Arguments = ". /o " + file });
if (string.IsNullOrEmpty(System.IO.File.ReadAllText(file))) if (string.IsNullOrEmpty(System.IO.File.ReadAllText(file)))
{ {
System.IO.File.WriteAllText(file, "No issues closed since last release"); System.IO.File.WriteAllText(file, "No issues closed since last release");
} }
if (releaseNotesExitCode != 0) if (releaseNotesExitCode != 0)
{ {
throw new Exception("Failed to generate release notes"); throw new Exception("Failed to generate release notes");
} }
} }
/// Publishes code and symbols packages to nuget feed, based on contents of artifacts file /// Publishes code and symbols packages to nuget feed, based on contents of artifacts file
private void PublishPackages(ConvertableDirectoryPath packagesDir, ConvertableFilePath artifactsFile, string feedApiKey, string codeFeedUrl, string symbolFeedUrl) private void PublishPackages(ConvertableDirectoryPath packagesDir, ConvertableFilePath artifactsFile, string feedApiKey, string codeFeedUrl, string symbolFeedUrl)
{ {
Information("PublishPackages"); Information("PublishPackages");
var artifacts = System.IO.File var artifacts = System.IO.File
.ReadAllLines(artifactsFile) .ReadAllLines(artifactsFile)
.Distinct(); .Distinct();
foreach(var artifact in artifacts) foreach(var artifact in artifacts)
{ {
var codePackage = packagesDir + File(artifact); var codePackage = packagesDir + File(artifact);
Information("Pushing package " + codePackage); Information("Pushing package " + codePackage);
Information("Calling NuGetPush"); Information("Calling NuGetPush");
NuGetPush( NuGetPush(
codePackage, codePackage,
new NuGetPushSettings { new NuGetPushSettings {
ApiKey = feedApiKey, ApiKey = feedApiKey,
Source = codeFeedUrl Source = codeFeedUrl
}); });
} }
} }
private void CreateGitHubRelease() private void CreateGitHubRelease()
{ {
var json = $"{{ \"tag_name\": \"{versioning.NuGetVersion}\", \"target_commitish\": \"master\", \"name\": \"{versioning.NuGetVersion}\", \"body\": \"todo: notes coming\", \"draft\": true, \"prerelease\": true }}"; var json = $"{{ \"tag_name\": \"{versioning.NuGetVersion}\", \"target_commitish\": \"master\", \"name\": \"{versioning.NuGetVersion}\", \"body\": \"todo: notes coming\", \"draft\": true, \"prerelease\": true }}";
var content = new System.Net.Http.StringContent(json, System.Text.Encoding.UTF8, "application/json"); var content = new System.Net.Http.StringContent(json, System.Text.Encoding.UTF8, "application/json");
using(var client = new System.Net.Http.HttpClient()) using(var client = new System.Net.Http.HttpClient())
{ {
client.DefaultRequestHeaders.Authorization = client.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue( new System.Net.Http.Headers.AuthenticationHeaderValue(
"Basic", Convert.ToBase64String( "Basic", Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes( System.Text.ASCIIEncoding.ASCII.GetBytes(
$"{gitHubUsername}:{gitHubPassword}"))); $"{gitHubUsername}:{gitHubPassword}")));
client.DefaultRequestHeaders.Add("User-Agent", "Ocelot Release"); client.DefaultRequestHeaders.Add("User-Agent", "Ocelot Release");
var result = client.PostAsync("https://api.github.com/repos/ThreeMammals/Ocelot/releases", content).Result; var result = client.PostAsync("https://api.github.com/repos/ThreeMammals/Ocelot/releases", content).Result;
if(result.StatusCode != System.Net.HttpStatusCode.Created) if(result.StatusCode != System.Net.HttpStatusCode.Created)
{ {
throw new Exception("CreateGitHubRelease result.StatusCode = " + result.StatusCode); throw new Exception("CreateGitHubRelease result.StatusCode = " + result.StatusCode);
} }
var returnValue = result.Content.ReadAsStringAsync().Result; var returnValue = result.Content.ReadAsStringAsync().Result;
dynamic test = Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(returnValue); dynamic test = Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(returnValue);
releaseId = test.id; releaseId = test.id;
} }
} }
private void UploadFileToGitHubRelease(FilePath file) private void UploadFileToGitHubRelease(FilePath file)
{ {
var data = System.IO.File.ReadAllBytes(file.FullPath); var data = System.IO.File.ReadAllBytes(file.FullPath);
var content = new System.Net.Http.ByteArrayContent(data); var content = new System.Net.Http.ByteArrayContent(data);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
using(var client = new System.Net.Http.HttpClient()) using(var client = new System.Net.Http.HttpClient())
{ {
client.DefaultRequestHeaders.Authorization = client.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue( new System.Net.Http.Headers.AuthenticationHeaderValue(
"Basic", Convert.ToBase64String( "Basic", Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes( System.Text.ASCIIEncoding.ASCII.GetBytes(
$"{gitHubUsername}:{gitHubPassword}"))); $"{gitHubUsername}:{gitHubPassword}")));
client.DefaultRequestHeaders.Add("User-Agent", "Ocelot Release"); client.DefaultRequestHeaders.Add("User-Agent", "Ocelot Release");
var result = client.PostAsync($"https://uploads.github.com/repos/ThreeMammals/Ocelot/releases/{releaseId}/assets?name={file.GetFilename()}", content).Result; var result = client.PostAsync($"https://uploads.github.com/repos/ThreeMammals/Ocelot/releases/{releaseId}/assets?name={file.GetFilename()}", content).Result;
if(result.StatusCode != System.Net.HttpStatusCode.Created) if(result.StatusCode != System.Net.HttpStatusCode.Created)
{ {
throw new Exception("UploadFileToGitHubRelease result.StatusCode = " + result.StatusCode); throw new Exception("UploadFileToGitHubRelease result.StatusCode = " + result.StatusCode);
} }
} }
} }
private void CompleteGitHubRelease() private void CompleteGitHubRelease()
{ {
var json = $"{{ \"tag_name\": \"{versioning.NuGetVersion}\", \"target_commitish\": \"master\", \"name\": \"{versioning.NuGetVersion}\", \"body\": \"todo: notes coming\", \"draft\": false, \"prerelease\": false }}"; var json = $"{{ \"tag_name\": \"{versioning.NuGetVersion}\", \"target_commitish\": \"master\", \"name\": \"{versioning.NuGetVersion}\", \"body\": \"todo: notes coming\", \"draft\": false, \"prerelease\": false }}";
var request = new System.Net.Http.HttpRequestMessage(new System.Net.Http.HttpMethod("Patch"), $"https://api.github.com/repos/ThreeMammals/Ocelot/releases/{releaseId}"); var request = new System.Net.Http.HttpRequestMessage(new System.Net.Http.HttpMethod("Patch"), $"https://api.github.com/repos/ThreeMammals/Ocelot/releases/{releaseId}");
request.Content = new System.Net.Http.StringContent(json, System.Text.Encoding.UTF8, "application/json"); request.Content = new System.Net.Http.StringContent(json, System.Text.Encoding.UTF8, "application/json");
using(var client = new System.Net.Http.HttpClient()) using(var client = new System.Net.Http.HttpClient())
{ {
client.DefaultRequestHeaders.Authorization = client.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue( new System.Net.Http.Headers.AuthenticationHeaderValue(
"Basic", Convert.ToBase64String( "Basic", Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes( System.Text.ASCIIEncoding.ASCII.GetBytes(
$"{gitHubUsername}:{gitHubPassword}"))); $"{gitHubUsername}:{gitHubPassword}")));
client.DefaultRequestHeaders.Add("User-Agent", "Ocelot Release"); client.DefaultRequestHeaders.Add("User-Agent", "Ocelot Release");
var result = client.SendAsync(request).Result; var result = client.SendAsync(request).Result;
if(result.StatusCode != System.Net.HttpStatusCode.OK) if(result.StatusCode != System.Net.HttpStatusCode.OK)
{ {
throw new Exception("CompleteGitHubRelease result.StatusCode = " + result.StatusCode); throw new Exception("CompleteGitHubRelease result.StatusCode = " + result.StatusCode);
} }
} }
} }
/// gets the resource from the specified url /// gets the resource from the specified url
private string GetResource(string url) private string GetResource(string url)
{ {
try try
{ {
Information("Getting resource from " + url); Information("Getting resource from " + url);
var assetsRequest = System.Net.WebRequest.CreateHttp(url); var assetsRequest = System.Net.WebRequest.CreateHttp(url);
assetsRequest.Method = "GET"; assetsRequest.Method = "GET";
assetsRequest.Accept = "application/vnd.github.v3+json"; assetsRequest.Accept = "application/vnd.github.v3+json";
assetsRequest.UserAgent = "BuildScript"; assetsRequest.UserAgent = "BuildScript";
using (var assetsResponse = assetsRequest.GetResponse()) using (var assetsResponse = assetsRequest.GetResponse())
{ {
var assetsStream = assetsResponse.GetResponseStream(); var assetsStream = assetsResponse.GetResponseStream();
var assetsReader = new StreamReader(assetsStream); var assetsReader = new StreamReader(assetsStream);
var response = assetsReader.ReadToEnd(); var response = assetsReader.ReadToEnd();
Information("Response is " + response); Information("Response is " + response);
return response; return response;
} }
} }
catch(Exception exception) catch(Exception exception)
{ {
Information("There was an exception " + exception); Information("There was an exception " + exception);
throw; throw;
} }
} }
private bool IsRunningOnCircleCI() private bool IsRunningOnCircleCI()
{ {
return !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("CIRCLECI")); return !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("CIRCLECI"));
} }

View File

@ -105,7 +105,8 @@ namespace Ocelot.Configuration.Repository
public void Dispose() public void Dispose()
{ {
_timer.Dispose(); _timer?.Dispose();
_timer = null;
} }
} }
} }

View File

@ -41,14 +41,14 @@ namespace Ocelot.UnitTests.Configuration
_internalConfigCreator = new Mock<IInternalConfigurationCreator>(); _internalConfigCreator = new Mock<IInternalConfigurationCreator>();
_internalConfigCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).ReturnsAsync(new OkResponse<IInternalConfiguration>(_internalConfig)); _internalConfigCreator.Setup(x => x.Create(It.IsAny<FileConfiguration>())).ReturnsAsync(new OkResponse<IInternalConfiguration>(_internalConfig));
_poller = new FileConfigurationPoller(_factory.Object, _repo.Object, _config.Object, _internalConfigRepo.Object, _internalConfigCreator.Object); _poller = new FileConfigurationPoller(_factory.Object, _repo.Object, _config.Object, _internalConfigRepo.Object, _internalConfigCreator.Object);
_poller.StartAsync(new CancellationToken());
} }
[Fact] [Fact]
public void should_start() public void should_start()
{ {
this.Given(x => ThenTheSetterIsCalled(_fileConfig, 1)) this.Given(x => GivenPollerHasStarted())
.BDDfy(); .Given(x => ThenTheSetterIsCalled(_fileConfig, 1))
.BDDfy();
} }
[Fact] [Fact]
@ -71,7 +71,8 @@ namespace Ocelot.UnitTests.Configuration
} }
}; };
this.Given(x => WhenTheConfigIsChanged(newConfig, 0)) this.Given(x => GivenPollerHasStarted())
.Given(x => WhenTheConfigIsChanged(newConfig, 0))
.Then(x => ThenTheSetterIsCalledAtLeast(newConfig, 1)) .Then(x => ThenTheSetterIsCalledAtLeast(newConfig, 1))
.BDDfy(); .BDDfy();
} }
@ -96,7 +97,8 @@ namespace Ocelot.UnitTests.Configuration
} }
}; };
this.Given(x => WhenTheConfigIsChanged(newConfig, 10)) this.Given(x => GivenPollerHasStarted())
.Given(x => WhenTheConfigIsChanged(newConfig, 10))
.Then(x => ThenTheSetterIsCalled(newConfig, 1)) .Then(x => ThenTheSetterIsCalled(newConfig, 1))
.BDDfy(); .BDDfy();
} }
@ -121,11 +123,24 @@ namespace Ocelot.UnitTests.Configuration
} }
}; };
this.Given(x => WhenProviderErrors()) this.Given(x => GivenPollerHasStarted())
.Given(x => WhenProviderErrors())
.Then(x => ThenTheSetterIsCalled(newConfig, 0)) .Then(x => ThenTheSetterIsCalled(newConfig, 0))
.BDDfy(); .BDDfy();
} }
[Fact]
public void should_dispose_cleanly_without_starting()
{
this.When(x => WhenPollerIsDisposed())
.BDDfy();
}
private void GivenPollerHasStarted()
{
_poller.StartAsync(CancellationToken.None);
}
private void WhenProviderErrors() private void WhenProviderErrors()
{ {
_repo _repo
@ -141,6 +156,11 @@ namespace Ocelot.UnitTests.Configuration
.ReturnsAsync(new OkResponse<FileConfiguration>(newConfig)); .ReturnsAsync(new OkResponse<FileConfiguration>(newConfig));
} }
private void WhenPollerIsDisposed()
{
_poller.Dispose();
}
private void ThenTheSetterIsCalled(FileConfiguration fileConfig, int times) private void ThenTheSetterIsCalled(FileConfiguration fileConfig, int times)
{ {
var result = WaitFor(4000).Until(() => var result = WaitFor(4000).Until(() =>