From 3f3bfe05ec4c16b34845acc90ad40883a5aad9c7 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 8 Jun 2018 12:31:39 -0700 Subject: [PATCH] Add a test condition for skipping tests when the default keychain is missing for macOS --- .../DataProtectionProviderTests.cs | 28 +++++++++--- .../X509StoreIsAvailableAttribute.cs | 43 +++++++++++++++++++ 2 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 test/Microsoft.AspNetCore.DataProtection.Extensions.Test/X509StoreIsAvailableAttribute.cs diff --git a/test/Microsoft.AspNetCore.DataProtection.Extensions.Test/DataProtectionProviderTests.cs b/test/Microsoft.AspNetCore.DataProtection.Extensions.Test/DataProtectionProviderTests.cs index 40e470ea58..d20332c1e2 100644 --- a/test/Microsoft.AspNetCore.DataProtection.Extensions.Test/DataProtectionProviderTests.cs +++ b/test/Microsoft.AspNetCore.DataProtection.Extensions.Test/DataProtectionProviderTests.cs @@ -115,7 +115,8 @@ namespace Microsoft.AspNetCore.DataProtection }); } - [Fact] + [ConditionalFact] + [X509StoreIsAvailable(StoreName.My, StoreLocation.CurrentUser)] public void System_UsesProvidedDirectoryAndCertificate() { var filePath = Path.Combine(GetTestFilesPath(), "TestCert.pfx"); @@ -162,12 +163,7 @@ namespace Microsoft.AspNetCore.DataProtection var filePath = Path.Combine(GetTestFilesPath(), "TestCert2.pfx"); var certificate = new X509Certificate2(filePath, "password"); - using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) - { - store.Open(OpenFlags.ReadOnly); - // ensure this cert is not in the x509 store - Assert.Empty(store.Certificates.Find(X509FindType.FindByThumbprint, certificate.Thumbprint, false)); - } + AssetStoreDoesNotContain(certificate); WithUniqueTempDirectory(directory => { @@ -189,6 +185,24 @@ namespace Microsoft.AspNetCore.DataProtection }); } + private static void AssetStoreDoesNotContain(X509Certificate2 certificate) + { + using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) + { + try + { + store.Open(OpenFlags.ReadOnly); + } + catch + { + return; + } + + // ensure this cert is not in the x509 store + Assert.Empty(store.Certificates.Find(X509FindType.FindByThumbprint, certificate.Thumbprint, false)); + } + } + [Fact] public void System_CanUnprotectWithCert() { diff --git a/test/Microsoft.AspNetCore.DataProtection.Extensions.Test/X509StoreIsAvailableAttribute.cs b/test/Microsoft.AspNetCore.DataProtection.Extensions.Test/X509StoreIsAvailableAttribute.cs new file mode 100644 index 0000000000..2181b4c24f --- /dev/null +++ b/test/Microsoft.AspNetCore.DataProtection.Extensions.Test/X509StoreIsAvailableAttribute.cs @@ -0,0 +1,43 @@ +// 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.Cryptography.X509Certificates; +using Microsoft.AspNetCore.Testing.xunit; + +namespace Microsoft.AspNetCore.DataProtection +{ + [AttributeUsage(AttributeTargets.Method)] + public class X509StoreIsAvailableAttribute : Attribute, ITestCondition + { + public X509StoreIsAvailableAttribute(StoreName name, StoreLocation location) + { + Name = name; + Location = location; + } + + public bool IsMet + { + get + { + try + { + using (var store = new X509Store(Name, Location)) + { + store.Open(OpenFlags.ReadWrite); + return true; + } + } + catch + { + return false; + } + } + } + + public string SkipReason => $"Skipping because the X509Store({Name}/{Location}) is not available on this machine."; + + public StoreName Name { get; } + public StoreLocation Location { get; } + } +}