Skip to content

Commit

Permalink
Merge pull request #3868 from JohnyWS/correct-flaky-tests
Browse files Browse the repository at this point in the history
Correct flaky tests in bootstrapper
  • Loading branch information
forki authored Jul 25, 2020
2 parents 2367e2f + db044d9 commit 05603e8
Show file tree
Hide file tree
Showing 13 changed files with 125 additions and 68 deletions.
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

[*.cs]
indent_style = space
indent_size = 4
21 changes: 13 additions & 8 deletions Paket.sln
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27009.1
# Visual Studio Version 16
VisualStudioVersion = 16.0.30204.135
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1}"
EndProject
Expand Down Expand Up @@ -68,13 +68,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "content", "content", "{8E6D
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{ED8079DD-2B06-4030-9F0F-DC548F98E1C4}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Paket.Tests", "tests\Paket.Tests\Paket.Tests.fsproj", "{E789C72A-5CFD-436B-8EF1-61AA2852A89F}"
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Paket.Tests", "tests\Paket.Tests\Paket.Tests.fsproj", "{E789C72A-5CFD-436B-8EF1-61AA2852A89F}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Paket", "src\Paket\Paket.fsproj", "{09B32F18-0C20-4489-8C83-5106D5C04C93}"
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Paket", "src\Paket\Paket.fsproj", "{09B32F18-0C20-4489-8C83-5106D5C04C93}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Paket.Bootstrapper", "src\Paket.Bootstrapper\Paket.Bootstrapper.csproj", "{CE3F8B87-1ABD-462E-A35B-CDCEC695898B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Paket.Bootstrapper", "src\Paket.Bootstrapper\Paket.Bootstrapper.csproj", "{CE3F8B87-1ABD-462E-A35B-CDCEC695898B}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Paket.Core", "src\Paket.Core\Paket.Core.fsproj", "{7BAB0AE2-089F-4761-B138-A717AA2F86C5}"
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Paket.Core", "src\Paket.Core\Paket.Core.fsproj", "{7BAB0AE2-089F-4761-B138-A717AA2F86C5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "commands", "commands", "{4425A246-BD18-4622-86B5-0154F19165E4}"
ProjectSection(SolutionItems) = preProject
Expand All @@ -97,9 +97,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "commands", "commands", "{44
docs\content\commands\why.md = docs\content\commands\why.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Paket.Bootstrapper.Tests", "tests\Paket.Bootstrapper.Tests\Paket.Bootstrapper.Tests.csproj", "{7C622582-E281-4EAB-AADA-B5893BB89B45}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Paket.Bootstrapper.Tests", "tests\Paket.Bootstrapper.Tests\Paket.Bootstrapper.Tests.csproj", "{7C622582-E281-4EAB-AADA-B5893BB89B45}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Paket.IntegrationTests", "integrationtests\Paket.IntegrationTests\Paket.IntegrationTests.fsproj", "{7234B9B4-8CF5-4E68-AA29-050C087B9246}"
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Paket.IntegrationTests", "integrationtests\Paket.IntegrationTests\Paket.IntegrationTests.fsproj", "{7234B9B4-8CF5-4E68-AA29-050C087B9246}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{62D18A14-5240-4CB1-AA8A-762D3EB0E19A}"
ProjectSection(SolutionItems) = preProject
Expand All @@ -108,6 +108,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{62D18A
.paket\paket.targets = .paket\paket.targets
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1C9A57E4-9D94-44D1-A106-FC588B7B72DE}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down
12 changes: 6 additions & 6 deletions src/Paket.Bootstrapper/BootstrapperHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,29 +71,29 @@ internal static string GetTempFile(string name)
return fileName;
}

internal static void PrepareWebClient(WebClient client, string url)
internal static void PrepareWebClient(WebClient client, string url, IEnvProxy envProxy)
{
client.Headers.Add("user-agent", PaketBootstrapperUserAgent);
client.UseDefaultCredentials = true;
client.Proxy = GetDefaultWebProxyFor(url);
client.Proxy = GetDefaultWebProxyFor(url, envProxy);
}

internal static HttpWebRequest PrepareWebRequest(string url)
internal static HttpWebRequest PrepareWebRequest(string url, IEnvProxy envProxy)
{
var request = (HttpWebRequest)HttpWebRequest.Create(url);
request.UserAgent = PaketBootstrapperUserAgent;
request.UseDefaultCredentials = true;
request.Proxy = GetDefaultWebProxyFor(url);
request.Proxy = GetDefaultWebProxyFor(url, envProxy);
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
return request;
}

internal static IWebProxy GetDefaultWebProxyFor(String url)
internal static IWebProxy GetDefaultWebProxyFor(String url, IEnvProxy envProxy)
{
Uri uri = new Uri(url);

IWebProxy result;
if (EnvProxy.TryGetProxyFor(uri, out result) && result.GetProxy(uri) != uri)
if (envProxy.TryGetProxyFor(uri, out result) && result.GetProxy(uri) != uri)
return result;

#if NO_SYSTEMWEBPROXY
Expand Down
18 changes: 18 additions & 0 deletions src/Paket.Bootstrapper/HelperProxies/DefaultProxyProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Paket.Bootstrapper.HelperProxies
{
public class DefaultProxyProvider : IProxyProvider
{
public IFileSystemProxy FileSystemProxy { get; }

public IWebRequestProxy WebRequestProxy { get; }

public IEnvProxy EnvProxy { get; }

public DefaultProxyProvider()
{
FileSystemProxy = new FileSystemProxy();
EnvProxy = new EnvProxy();
WebRequestProxy = new WebRequestProxy(EnvProxy);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
using System.Text.RegularExpressions;
using System.Linq;

namespace Paket.Bootstrapper
namespace Paket.Bootstrapper.HelperProxies
{
internal class EnvProxy
internal class EnvProxy : IEnvProxy
{
private static readonly EnvProxy instance = new EnvProxy();
private readonly Dictionary<string, IWebProxy> proxies = new Dictionary<string, IWebProxy>(StringComparer.OrdinalIgnoreCase);

private static string GetEnvVarValue(string name)
Expand Down Expand Up @@ -58,16 +57,16 @@ private void AddProxy(string scheme, string[] bypassList)
}
}

protected EnvProxy()
public EnvProxy()
{
var bypassList = GetBypassList();
AddProxy("http", bypassList);
AddProxy("https", bypassList);
}

public static bool TryGetProxyFor(Uri uri, out IWebProxy proxy)
public bool TryGetProxyFor(Uri uri, out IWebProxy proxy)
{
return instance.proxies.TryGetValue(uri.Scheme, out proxy);
return proxies.TryGetValue(uri.Scheme, out proxy);
}
}
}
10 changes: 10 additions & 0 deletions src/Paket.Bootstrapper/HelperProxies/IEnvProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using System.Net;

namespace Paket.Bootstrapper.HelperProxies
{
public interface IEnvProxy
{
bool TryGetProxyFor(Uri uri, out IWebProxy proxy);
}
}
9 changes: 9 additions & 0 deletions src/Paket.Bootstrapper/HelperProxies/IProxyProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Paket.Bootstrapper.HelperProxies
{
public interface IProxyProvider
{
IFileSystemProxy FileSystemProxy { get; }
IWebRequestProxy WebRequestProxy { get; }
IEnvProxy EnvProxy { get; }
}
}
11 changes: 7 additions & 4 deletions src/Paket.Bootstrapper/HelperProxies/WebRequestProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,25 @@ namespace Paket.Bootstrapper.HelperProxies
{
public class WebRequestProxy : IWebRequestProxy
{
public WebRequestProxy()
private readonly IEnvProxy envProxy;

public WebRequestProxy(IEnvProxy envProxy)
{
Client = new WebClient();
this.envProxy = envProxy;
}

private WebClient Client { get; set; }

public string DownloadString(string address)
{
BootstrapperHelper.PrepareWebClient(Client, address);
BootstrapperHelper.PrepareWebClient(Client, address, envProxy);
return Client.DownloadString(address);
}

public Stream GetResponseStream(string url)
{
var request = BootstrapperHelper.PrepareWebRequest(url);
var request = BootstrapperHelper.PrepareWebRequest(url, envProxy);

using (var httpResponse = (HttpWebResponse)request.GetResponse())
{
Expand All @@ -30,7 +33,7 @@ public Stream GetResponseStream(string url)

public void DownloadFile(string url, string targetLocation)
{
BootstrapperHelper.PrepareWebClient(Client, url);
BootstrapperHelper.PrepareWebClient(Client, url, envProxy);
Client.DownloadFile(url, targetLocation);
}
}
Expand Down
20 changes: 10 additions & 10 deletions src/Paket.Bootstrapper/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ static void Main(string[] args)
executionWatch.Start();
Console.CancelKeyPress += CancelKeyPressed;

var fileProxy = new FileSystemProxy();
IProxyProvider proxyProvider = new DefaultProxyProvider();

var appSettings = ConfigurationManager.AppSettings;

Expand All @@ -45,14 +45,14 @@ static void Main(string[] args)
}

var optionsBeforeDependenciesFile = ArgumentParser.ParseArgumentsAndConfigurations(args, appSettings,
Environment.GetEnvironmentVariables(), fileProxy, Enumerable.Empty<string>());
Environment.GetEnvironmentVariables(), proxyProvider.FileSystemProxy, Enumerable.Empty<string>());
ConsoleImpl.Verbosity = optionsBeforeDependenciesFile.Verbosity;

var argumentsFromDependenciesFile =
WindowsProcessArguments.Parse(
PaketDependencies.GetBootstrapperArgsForFolder(fileProxy));
PaketDependencies.GetBootstrapperArgsForFolder(proxyProvider.FileSystemProxy));
var options = ArgumentParser.ParseArgumentsAndConfigurations(args, appSettings,
Environment.GetEnvironmentVariables(), fileProxy, argumentsFromDependenciesFile);
Environment.GetEnvironmentVariables(), proxyProvider.FileSystemProxy, argumentsFromDependenciesFile);
if (options.ShowHelp)
{
ConsoleImpl.WriteAlways(BootstrapperHelper.HelpText);
Expand All @@ -68,11 +68,11 @@ static void Main(string[] args)
options.DownloadArguments.IgnoreCache = true;
#endif

var effectiveStrategy = GetEffectiveDownloadStrategy(options.DownloadArguments, options.PreferNuget, options.ForceNuget);
var effectiveStrategy = GetEffectiveDownloadStrategy(options.DownloadArguments, options.PreferNuget, options.ForceNuget, proxyProvider);
ConsoleImpl.WriteTrace("Using strategy: " + effectiveStrategy.Name);
ConsoleImpl.WriteTrace("Using install kind: " + (options.DownloadArguments.AsTool? "tool": "exe"));

StartPaketBootstrapping(effectiveStrategy, options.DownloadArguments, fileProxy, () => OnSuccessfulDownload(options));
StartPaketBootstrapping(effectiveStrategy, options.DownloadArguments, proxyProvider.FileSystemProxy, () => OnSuccessfulDownload(options));
}

private static void OnSuccessfulDownload(BootstrapperOptions options)
Expand Down Expand Up @@ -227,13 +227,13 @@ public static void StartPaketBootstrapping(IDownloadStrategy downloadStrategy, D
}
}

public static DownloadStrategy GetEffectiveDownloadStrategy(DownloadArguments dlArgs, bool preferNuget, bool forceNuget)
public static DownloadStrategy GetEffectiveDownloadStrategy(DownloadArguments dlArgs, bool preferNuget, bool forceNuget, IProxyProvider proxyProvider)
{
var gitHubDownloadStrategy =
dlArgs.AsTool
? new GitHubDownloadToolStrategy(new WebRequestProxy(), new FileSystemProxy()).AsCached(dlArgs.IgnoreCache)
: new GitHubDownloadStrategy(new WebRequestProxy(), new FileSystemProxy()).AsCached(dlArgs.IgnoreCache);
var nugetDownloadStrategy = new NugetDownloadStrategy(new WebRequestProxy(), new FileSystemProxy(), dlArgs.Folder, dlArgs.NugetSource, dlArgs.AsTool).AsCached(dlArgs.IgnoreCache);
? new GitHubDownloadToolStrategy(proxyProvider.WebRequestProxy, proxyProvider.FileSystemProxy).AsCached(dlArgs.IgnoreCache)
: new GitHubDownloadStrategy(proxyProvider.WebRequestProxy, proxyProvider.FileSystemProxy).AsCached(dlArgs.IgnoreCache);
var nugetDownloadStrategy = new NugetDownloadStrategy(proxyProvider.WebRequestProxy, proxyProvider.FileSystemProxy, dlArgs.Folder, dlArgs.NugetSource, dlArgs.AsTool).AsCached(dlArgs.IgnoreCache);

DownloadStrategy effectiveStrategy;
if (forceNuget)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,12 @@
using NUnit.Framework;
using System;
using System.Net;
using System.Reflection;

namespace Paket.Bootstrapper.Tests
namespace Paket.Bootstrapper.Tests.HelperProxies
{
[TestFixture]
class EnvWebProxyShould
{
private sealed class FakeEnvProxy : EnvProxy
{
public FakeEnvProxy()
{
var instanceField = typeof(EnvProxy).GetField("instance", BindingFlags.Static | BindingFlags.NonPublic);
instanceField.SetValue(null, this);
}
new public bool TryGetProxyFor(Uri uri, out IWebProxy proxy)
{
return EnvProxy.TryGetProxyFor(uri, out proxy);
}
}
private sealed class DisposableEnvVar : IDisposable
{
private readonly string name;
Expand All @@ -41,10 +28,10 @@ [Test] public void GetNoProxyIfNoneDefined()
using (new DisposableEnvVar("http_proxy"))
using (new DisposableEnvVar("https_proxy"))
{
var envProxy = new FakeEnvProxy();
var envProxy = TestHelper.NoSingletonProxyProvider.EnvProxy;
IWebProxy proxy;
Assert.IsFalse(envProxy.TryGetProxyFor(new Uri("http://github.com"), out proxy));
Assert.IsFalse(envProxy.TryGetProxyFor(new Uri("https://github.com"), out proxy));
Assert.IsFalse(envProxy.TryGetProxyFor(new Uri("http://github.com"), out _));
Assert.IsFalse(envProxy.TryGetProxyFor(new Uri("https://github.com"), out _));
}
}

Expand All @@ -53,9 +40,8 @@ [Test] public void GetHttpProxyWithNoPortNoCredentials()
using (new DisposableEnvVar("http_proxy", "http://proxy.local"))
using (new DisposableEnvVar("no_proxy"))
{
var envProxy = new FakeEnvProxy();
IWebProxy proxy;
Assert.IsTrue(envProxy.TryGetProxyFor(new Uri("http://github.com"), out proxy));
Assert.IsTrue(TestHelper.NoSingletonProxyProvider.EnvProxy.TryGetProxyFor(new Uri("http://github.com"), out proxy));
var webProxy = proxy as WebProxy;
Assert.IsNotNull(webProxy);
Assert.That(webProxy.Address, Is.EqualTo(new Uri("http://proxy.local")));
Expand All @@ -70,9 +56,8 @@ [Test] public void GetHttpProxyWithPortNoCredentials()
using (new DisposableEnvVar("http_proxy", "http://proxy.local:8080"))
using (new DisposableEnvVar("no_proxy"))
{
var envProxy = new FakeEnvProxy();
IWebProxy proxy;
Assert.IsTrue(envProxy.TryGetProxyFor(new Uri("http://github.com"), out proxy));
Assert.IsTrue(TestHelper.NoSingletonProxyProvider.EnvProxy.TryGetProxyFor(new Uri("http://github.com"), out proxy));
var webProxy = proxy as WebProxy;
Assert.IsNotNull(webProxy);
Assert.That(webProxy.Address, Is.EqualTo(new Uri("http://proxy.local:8080")));
Expand All @@ -88,9 +73,8 @@ [Test] public void GetHttpProxyWithPortAndCredentials()
using (new DisposableEnvVar("http_proxy", string.Format("http://user:{0}@proxy.local:8080", Uri.EscapeDataString(password))))
using (new DisposableEnvVar("no_proxy"))
{
var envProxy = new FakeEnvProxy();
IWebProxy proxy;
Assert.IsTrue(envProxy.TryGetProxyFor(new Uri("http://github.com"), out proxy));
Assert.IsTrue(TestHelper.NoSingletonProxyProvider.EnvProxy.TryGetProxyFor(new Uri("http://github.com"), out proxy));
var webProxy = proxy as WebProxy;
Assert.IsNotNull(webProxy);
Assert.That(webProxy.Address, Is.EqualTo(new Uri("http://proxy.local:8080")));
Expand All @@ -109,9 +93,8 @@ [Test] public void GetHttpsProxyWithPortAndCredentials()
using (new DisposableEnvVar("https_proxy", string.Format("https://user:{0}@proxy.local:8080", Uri.EscapeDataString(password))))
using (new DisposableEnvVar("no_proxy"))
{
var envProxy = new FakeEnvProxy();
IWebProxy proxy;
Assert.IsTrue(envProxy.TryGetProxyFor(new Uri("https://github.com"), out proxy));
Assert.IsTrue(TestHelper.NoSingletonProxyProvider.EnvProxy.TryGetProxyFor(new Uri("https://github.com"), out proxy));
var webProxy = proxy as WebProxy;
Assert.IsNotNull(webProxy);
Assert.That(webProxy.Address, Is.EqualTo(new Uri("http://proxy.local:8080")));
Expand All @@ -129,9 +112,8 @@ [Test] public void GetHttpProxyWithBypassList()
using (new DisposableEnvVar("http_proxy", string.Format("http://proxy.local:8080")))
using (new DisposableEnvVar("no_proxy", ".local,127.0.0.1"))
{
var envProxy = new FakeEnvProxy();
IWebProxy proxy;
Assert.IsTrue(envProxy.TryGetProxyFor(new Uri("http://github.com"), out proxy));
Assert.IsTrue(TestHelper.NoSingletonProxyProvider.EnvProxy.TryGetProxyFor(new Uri("http://github.com"), out proxy));
var webProxy = proxy as WebProxy;
Assert.IsNotNull(webProxy);
Assert.That(webProxy.Address, Is.EqualTo(new Uri("http://proxy.local:8080")));
Expand Down
13 changes: 13 additions & 0 deletions tests/Paket.Bootstrapper.Tests/NoSingletonProxyProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Paket.Bootstrapper.HelperProxies;

namespace Paket.Bootstrapper.Tests
{
internal class NoSingletonProxyProvider : IProxyProvider
{
public IFileSystemProxy FileSystemProxy => new FileSystemProxy();

public IWebRequestProxy WebRequestProxy => new WebRequestProxy(EnvProxy);

public IEnvProxy EnvProxy => new EnvProxy();
}
}
Loading

0 comments on commit 05603e8

Please sign in to comment.