Skip to content

Commit

Permalink
Merge pull request #6283 from smoogipoo/insecure-requests-via-env
Browse files Browse the repository at this point in the history
Allow insecure requests on debug builds via `OSU_INSECURE_REQUESTS` environment variable
  • Loading branch information
peppy committed May 15, 2024
2 parents 812e529 + 694f7f5 commit 3e8a5fc
Show file tree
Hide file tree
Showing 6 changed files with 320 additions and 117 deletions.
55 changes: 53 additions & 2 deletions osu.Framework.Tests/FlakyTestAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,75 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using NUnit.Framework;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Commands;

namespace osu.Framework.Tests
{
/// <summary>
/// An attribute to mark any flaky tests.
/// Will add a retry count unless environment variable `FAIL_FLAKY_TESTS` is set to `1`.
/// </summary>
public class FlakyTestAttribute : RetryAttribute
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public class FlakyTestAttribute : NUnitAttribute, IRepeatTest
{
private readonly int tryCount;

public FlakyTestAttribute()
: this(10)
{
}

public FlakyTestAttribute(int tryCount)
: base(FrameworkEnvironment.FailFlakyTests ? 1 : tryCount)
{
this.tryCount = tryCount;
}

public TestCommand Wrap(TestCommand command) => new FlakyTestCommand(command, tryCount);

// Adapted from https://github.com/nunit/nunit/blob/4eaab2eef3713907ca37bfb2f7f47e3fc2785214/src/NUnitFramework/framework/Attributes/RetryAttribute.cs
// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt
public class FlakyTestCommand : DelegatingTestCommand
{
private readonly int tryCount;

public FlakyTestCommand(TestCommand innerCommand, int tryCount)
: base(innerCommand)
{
this.tryCount = tryCount;
}

public override TestResult Execute(TestExecutionContext context)
{
int count = FrameworkEnvironment.FailFlakyTests ? 1 : tryCount;

while (count-- > 0)
{
try
{
context.CurrentResult = innerCommand.Execute(context);
}
catch (Exception ex)
{
context.CurrentResult ??= context.CurrentTest.MakeTestResult();
context.CurrentResult.RecordException(ex);
}

if (context.CurrentResult.ResultState != ResultState.Failure)
break;

if (count > 0)
{
context.CurrentResult = context.CurrentTest.MakeTestResult();
context.CurrentRepeatCount++;
}
}

return context.CurrentResult;
}
}
}
}
121 changes: 121 additions & 0 deletions osu.Framework.Tests/IO/TestOnlineStore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.IO.Stores;

namespace osu.Framework.Tests.IO
{
[TestFixture]
[Category("httpbin")]
public class TestOnlineStore
{
private const string default_protocol = "http";

private static readonly string host;
private static readonly IEnumerable<string> protocols;

private bool oldAllowInsecureRequests;
private OnlineStore store = null!;

static TestOnlineStore()
{
bool localHttpBin = Environment.GetEnvironmentVariable("OSU_TESTS_LOCAL_HTTPBIN") == "1";

if (localHttpBin)
{
// httpbin very frequently falls over and causes random tests to fail
// Thus github actions builds rely on a local httpbin instance to run the tests

host = "127.0.0.1:8080";
protocols = new[] { default_protocol };
}
else
{
host = "httpbin.org";
protocols = new[] { default_protocol, "https" };
}
}

[OneTimeSetUp]
public void GlobalSetup()
{
oldAllowInsecureRequests = FrameworkEnvironment.AllowInsecureRequests;
FrameworkEnvironment.AllowInsecureRequests = true;
}

[OneTimeTearDown]
public void GlobalTeardown()
{
FrameworkEnvironment.AllowInsecureRequests = oldAllowInsecureRequests;
}

[SetUp]
public void Setup()
{
store = new OnlineStore();
}

[Test, Retry(5)]
public void TestValidUrlReturnsData([ValueSource(nameof(protocols))] string protocol, [Values(true, false)] bool async)
{
byte[]? result = async
? store.GetAsync($"{protocol}://{host}/image/png").GetResultSafely()
: store.Get($"{protocol}://{host}/image/png");

Assert.That(result, Is.Not.Null);
Assert.That(result, Has.Length.GreaterThan(0));
}

[Test]
public void TestMissingSchemeReturnsNull([Values(true, false)] bool async)
{
byte[]? result = async
? store.GetAsync($"{host}/image/png").GetResultSafely()
: store.Get($"{host}/image/png");

Assert.That(result, Is.Null);
}

[Test]
public void TestInvalidUrlReturnsNull()
{
byte[]? result = store.Get("this is not a valid url");
Assert.That(result, Is.Null);
}

[Test]
public void TestNullUrlReturnsNull()
{
// Not sure if this store should accept a null URL, but let's test it anyway.
byte[]? result = store.Get(null);
Assert.That(result, Is.Null);
}

[Test]
public void TestFileUrlFails([Values(true, false)] bool async)
{
// Known, guaranteed file path.
string path = new Uri(RuntimeInfo.EntryAssembly.Location).AbsoluteUri;

Check warning on line 102 in osu.Framework.Tests/IO/TestOnlineStore.cs

View workflow job for this annotation

GitHub Actions / Build only (Android)

'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.

Check warning on line 102 in osu.Framework.Tests/IO/TestOnlineStore.cs

View workflow job for this annotation

GitHub Actions / Build only (Android)

'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.

byte[]? result = async
? store.GetAsync(path).GetResultSafely()
: store.Get(path);

Assert.That(result, Is.Null);
}

[Test]
public void TestBadWebRequest([ValueSource(nameof(protocols))] string protocol, [Values(true, false)] bool async)
{
byte[]? result = async
? store.GetAsync($"{protocol}://{host}/status/500").GetResultSafely()
: store.Get($"{protocol}://{host}/status/500");

Assert.That(result, Is.Null);
}
}
}
Loading

0 comments on commit 3e8a5fc

Please sign in to comment.