Skip to content
This repository has been archived by the owner on Jul 30, 2024. It is now read-only.
/ NuGet.Jobs Public archive

Commit

Permalink
Skipping Admin-only tests instead of failing them (#766)
Browse files Browse the repository at this point in the history
* Skipping admin-only tests when run as non-admin gracefully instead of failing them.
* Made non-admin test skip conditional on the presence of `ENABLE_NONADMIN_TEST_SKIP` environment variable so that there would be no way to skip those in CI by accident.
  • Loading branch information
agr authored Jun 15, 2019
1 parent d6276cc commit a48031f
Show file tree
Hide file tree
Showing 14 changed files with 236 additions and 74 deletions.
11 changes: 9 additions & 2 deletions NuGet.Jobs.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.645
# Visual Studio Version 16
VisualStudioVersion = 16.0.28902.138
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NuGet.Jobs.Common", "src\NuGet.Jobs.Common\NuGet.Jobs.Common.csproj", "{4B4B1EFB-8F33-42E6-B79F-54E7F3293D31}"
EndProject
Expand Down Expand Up @@ -149,6 +149,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Monitoring.PackageLag.Tests
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NuGet.Jobs.GitHubIndexer", "src\NuGet.Jobs.GitHubIndexer\NuGet.Jobs.GitHubIndexer.csproj", "{42B1EB66-58F9-4D9A-8E23-FF12CBF5D643}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestUtil", "tests\TestUtil\TestUtil.csproj", "{C3F84BAD-ACFA-4AE3-8286-D12F5A5BBC62}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -393,6 +395,10 @@ Global
{42B1EB66-58F9-4D9A-8E23-FF12CBF5D643}.Debug|Any CPU.Build.0 = Debug|Any CPU
{42B1EB66-58F9-4D9A-8E23-FF12CBF5D643}.Release|Any CPU.ActiveCfg = Release|Any CPU
{42B1EB66-58F9-4D9A-8E23-FF12CBF5D643}.Release|Any CPU.Build.0 = Release|Any CPU
{C3F84BAD-ACFA-4AE3-8286-D12F5A5BBC62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C3F84BAD-ACFA-4AE3-8286-D12F5A5BBC62}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C3F84BAD-ACFA-4AE3-8286-D12F5A5BBC62}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C3F84BAD-ACFA-4AE3-8286-D12F5A5BBC62}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -457,6 +463,7 @@ Global
{19EC1E99-89A8-445A-8C22-C1B0CD8CC777} = {6A776396-02B1-475D-A104-26940ADB04AB}
{D3F1711A-25AC-4EC9-9971-4F838BCD2A07} = {6A776396-02B1-475D-A104-26940ADB04AB}
{42B1EB66-58F9-4D9A-8E23-FF12CBF5D643} = {FA5644B5-4F08-43F6-86B3-039374312A47}
{C3F84BAD-ACFA-4AE3-8286-D12F5A5BBC62} = {6A776396-02B1-475D-A104-26940ADB04AB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {284A7AC3-FB43-4F1F-9C9C-2AF0E1F46C2B}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ private List<string> RecordOperationOrder()
.Returns(Task.CompletedTask)
.Callback(() => operations.Add(nameof(IMessageService<Package>.SendValidationFailedMessageAsync)));
TelemetryServiceMock
.Setup(x => x.TrackTotalValidationDuration(It.IsAny<TimeSpan>(), It.IsAny<bool>()))
.Setup(x => x.TrackTotalValidationDuration(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Guid>(), It.IsAny<TimeSpan>(), It.IsAny<bool>()))
.Callback(() => operations.Add(nameof(ITelemetryService.TrackTotalValidationDuration)));
PackageFileServiceMock
.Setup(x => x.DeletePackageForValidationSetAsync(It.IsAny<PackageValidationSet>()))
Expand Down
23 changes: 23 additions & 0 deletions tests/TestUtil/AdminOnlyFactAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using Xunit;
using Xunit.Sdk;

namespace TestUtil
{
/// <summary>
/// Indicates a test that can be set up to be skipped when run as non-Admin user if environment
/// is set up appropriately. See <see cref="UserHelper.EnableSkipVariableName"/> for more details.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
[XunitTestCaseDiscoverer("Xunit.Sdk.FactDiscoverer", "xunit.execution.{Platform}")]
public class AdminOnlyFactAttribute : FactAttribute
{
public AdminOnlyFactAttribute()
{
UserHelper.SetupFactSkipIfAdmin(this);
}
}
}
23 changes: 23 additions & 0 deletions tests/TestUtil/AdminOnlyTheoryAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using Xunit;
using Xunit.Sdk;

namespace TestUtil
{
/// <summary>
/// Indicates a test set that can be set up to be skipped when run as non-Admin user if environment
/// is set up appropriately. See <see cref="UserHelper.EnableSkipVariableName"/> for more details.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
[XunitTestCaseDiscoverer("Xunit.Sdk.TheoryDiscoverer", "xunit.execution.{Platform}")]
public class AdminOnlyTheoryAttribute : TheoryAttribute
{
public AdminOnlyTheoryAttribute()
{
UserHelper.SetupFactSkipIfAdmin(this);
}
}
}
12 changes: 12 additions & 0 deletions tests/TestUtil/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Reflection;
using System.Runtime.InteropServices;

[assembly: AssemblyTitle("TestUtil")]
[assembly: AssemblyDescription("Shared test code")]
[assembly: AssemblyCompany(".NET Foundation")]
[assembly: AssemblyProduct("TestUtil")]
[assembly: AssemblyCopyright("Copyright © .NET Foundation 2017")]
[assembly: ComVisible(false)]
[assembly: Guid("c3f84bad-acfa-4ae3-8286-d12f5a5bbc62")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
55 changes: 55 additions & 0 deletions tests/TestUtil/TestUtil.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C3F84BAD-ACFA-4AE3-8286-D12F5A5BBC62}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TestUtil</RootNamespace>
<AssemblyName>TestUtil</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AdminOnlyFactAttribute.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="AdminOnlyTheoryAttribute.cs" />
<Compile Include="UserHelper.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="xunit">
<Version>2.3.1</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
37 changes: 37 additions & 0 deletions tests/TestUtil/UserHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Security.Principal;
using Xunit;

namespace TestUtil
{
public static class UserHelper
{
/// <summary>
/// Certain tests fail when run as a non-Administrator user. Adding the environment
/// variable with the name specified below and any value will enable skipping those
/// tests when run as non-Administrator. They will still run if executed as Admin.
/// </summary>
public const string EnableSkipVariableName = "ENABLE_NONADMIN_TEST_SKIP";

/// <summary>
/// Source: https://stackoverflow.com/a/11660205
/// </summary>
public static bool IsAdministrator()
{
var identity = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}

public static void SetupFactSkipIfAdmin(FactAttribute attribute)
{
if (!UserHelper.IsAdministrator() && Environment.GetEnvironmentVariable(EnableSkipVariableName) != null)
{
attribute.Skip = "Test will not run unless executed as Administrator";
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

using System;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Threading.Tasks;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.X509.Extension;
using Test.Utility.Signing;
using TestUtil;
using Xunit;
using BCCertificate = Org.BouncyCastle.X509.X509Certificate;

Expand All @@ -35,8 +35,8 @@ public class CertificateIntegrationTestFixture : IDisposable
public CertificateIntegrationTestFixture()
{
Assert.True(
IsAdministrator(),
"This test must be executing with administrator privileges since it installs a trusted root.");
UserHelper.IsAdministrator(),
$"This test must be executing with administrator privileges since it installs a trusted root. Add {UserHelper.EnableSkipVariableName} environment variable to skip this test.");

_testServer = new Lazy<Task<SigningTestServer>>(SigningTestServer.CreateAsync);
_rootCertificateAuthority = new Lazy<Task<CertificateAuthority>>(CreateDefaultTrustedRootCertificateAuthorityAsync);
Expand Down Expand Up @@ -338,16 +338,6 @@ private async Task<string> GetDefaultTrustedSigningCertificateThumbprintAsync()
return certificate.ComputeSHA256Thumbprint();
}

/// <summary>
/// Source: https://stackoverflow.com/a/11660205
/// </summary>
private static bool IsAdministrator()
{
var identity = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}

public class RevokableCertificate
{
private readonly Action _revokeAction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@
<Project>{91c060da-736f-4da9-a57f-cb3ac0e6cb10}</Project>
<Name>Validation.PackageSigning.Core</Name>
</ProjectReference>
<ProjectReference Include="..\TestUtil\TestUtil.csproj">
<Project>{c3f84bad-acfa-4ae3-8286-d12f5a5bbc62}</Project>
<Name>TestUtil</Name>
</ProjectReference>
<ProjectReference Include="..\Validation.PackageSigning.Helpers\Tests.ContextHelpers.csproj">
<Project>{2c5be067-adfd-49e3-ba9f-13a74436e5db}</Project>
<Name>Tests.ContextHelpers</Name>
Expand Down
Loading

0 comments on commit a48031f

Please sign in to comment.