File: ConditionalTestDetectors.cs
Web Access
Project: src\src\System.Private.ServiceModel\tests\Common\Infrastructure\Infrastructure.Common.csproj (Infrastructure.Common)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System;
using Xunit;
 
namespace Infrastructure.Common
{
    // This class contains helper "detector" methods to detect specific
    // conditions about the environment in which the tests are run.
    // They are used for [ConditionalFact] and [ConditionalTheory]
    // tests.  They are called at most once, and the return value cached.
    internal static class ConditionalTestDetectors
    {
        // Detector used by [ConditionalFact(nameof(Root_Certificate_Installed)].
        // It will attempt to install the root certificate in the root store if
        // is not already present, and then it will check whether the install
        // succeeded.  A 'true' return is a guarantee a root certificate is
        // installed in the root store.
        public static bool IsRootCertificateInstalled()
        {
            try
            {
                ServiceUtilHelper.EnsureRootCertificateInstalled();
                return true;
            }
            catch
            {
                // Errors installing the certificate are captured and will be
                // reported when an attempt is made to use it.  But for the
                // purposes of this detector, a failure only propagates as
                // a 'false' return.
                return false;
            }
        }
 
        // Detector used by [ConditionalFact(nameof(Client_Certificate_Installed)].
        // It will attempt to install the client certificate in the certificate store if
        // is not already present, and then it will check whether the install
        // succeeded.  A 'true' return is a guarantee a client certificate is
        // installed in the certificate store.
        public static bool IsClientCertificateInstalled()
        {
            try { 
                ServiceUtilHelper.EnsureClientCertificateInstalled();
                return true;
            }
            catch
            {
                // Errors installing the certificate are captured and will be
                // reported when an attempt is made to use it.  But for the
                // purposes of this detector, a failure only propagates as
                // a 'false' return.
                return false;
            }
        }
 
        // Detector used by [ConditionalFact(nameof(OSXPeer_Certificate_Installed)].
        // It will attempt to install the server certificate in a local keychain if
        // is not already present, and then it will check whether the install
        // succeeded.  A 'true' return is a guarantee a server certificate is
        // installed in the certificate store.
        public static bool IsOSXKeychainCertificateInstalled()
        {
            try
            {
                ServiceUtilHelper.EnsureOSXKeychainCertificateInstalled();
                return true;
            }
            catch
            {
                // Errors installing the certificate are captured and will be
                // reported when an attempt is made to use it.  But for the
                // purposes of this detector, a failure only propagates as
                // a 'false' return.
                return false;
            }
        }
 
        // Detector used by [ConditionalFact(nameof(Peer_Certificate_Installed)].
        // It will attempt to install the server certificate in the certificate store if
        // is not already present, and then it will check whether the install
        // succeeded.  A 'true' return is a guarantee a server certificate is
        // installed in the certificate store.
        public static bool IsPeerCertificateInstalled()
        {
            try
            {
                ServiceUtilHelper.EnsurePeerCertificateInstalled();
                return true;
            }
            catch
            {
                // Errors installing the certificate are captured and will be
                // reported when an attempt is made to use it.  But for the
                // purposes of this detector, a failure only propagates as
                // a 'false' return.
                return false;
            }
        }
 
        // Returns 'true' if the server is running IIS-hosted
        public static bool IsIISHosted()
        {
            return ServiceUtilHelper.IISHosted;
        }
 
        // Tests whether the client is domain-joined.  This test does not
        // consider whether the server is also domain-joined.
        public static bool IsClientDomainJoined()
        {
            // Currently non-Windows clients always return false until we have
            // a cross-platform way to detect this.
            if (!IsWindows())
            {
                return false;
            }
 
            // To determine whether the client is running on a domain joined machine,
            // we use this heuristic based on well known environment variables.
            string computerName = Environment.GetEnvironmentVariable("COMPUTERNAME");
            string logonServer = Environment.GetEnvironmentVariable("LOGONSERVER");
            string userDomain = Environment.GetEnvironmentVariable("USERDOMAIN");
 
            return !String.Equals(computerName, logonServer, StringComparison.OrdinalIgnoreCase) &&
                   !String.Equals(computerName, userDomain, StringComparison.OrdinalIgnoreCase);
        }
 
        // Tests whether the server is domain-joined.  This test does not consider
        // whether the client is domain-joined.
        public static bool IsServerDomainJoined()
        {
            // Requires solution to https://github.com/dotnet/wcf/issues/1095
            // Till then, heuristic is that running localhost == domain joined
            return IsServerLocalHost();
        }
 
        // Returns 'true' if the client is running on a Windows OS
        public static bool IsWindows()
        {
            return OSID.AnyWindows.MatchesCurrent();
        }
 
        public static bool IsWindowsOrSelfHosted()
        {
            if (IsWindows())
            {
                return true;
            }
            else if (!IsIISHosted())
            {
                return true;
            }
 
            return false;
        }
 
        // Returns 'true' if the server is running as localhost.
        // This test is meant to be used only to detect that our service URI
        // indicates localhost.  It is not intended to be used to detect that
        // the services are running locally but using an explicit host name.
        public static bool IsServerLocalHost()
        {
            string host = TestProperties.GetProperty(TestProperties.ServiceUri_PropertyName);
 
            if (String.IsNullOrWhiteSpace(host))
            {
                return false;
            }
 
            int index = host.IndexOf("localhost", 0, StringComparison.OrdinalIgnoreCase);
            return index == 0;
        }
 
        // Returns 'true' if ambient credentials are available to use
        public static bool AreAmbientCredentialsAvailable()
        {
            // Requires solution to https://github.com/dotnet/wcf/issues/1095
            // Till then, heuristic is that running localhost == ambient credentials available
            return IsServerLocalHost();
        }
 
        // Returns 'true' if explicit credentials are available.
        // Currently, 'true' means the TestProperties for ExplicitUserName
        // and ExplicitPassword are non-blank.
        public static bool AreExplicitCredentialsAvailable()
        {
            return !String.IsNullOrWhiteSpace(GetExplicitUserName()) &&
                   !String.IsNullOrWhiteSpace(GetExplicitPassword());
        }
 
        // Returns 'true' if a domain is available.  TestProperties for
        // NegotiateTestDomain takes precedence, but for Windows it can
        // infer the value.
        public static bool IsDomainAvailable()
        {
            return !String.IsNullOrWhiteSpace(GetDomain());
        }
 
        // Returns 'true if SPN is available
        public static bool IsSPNAvailable()
        {
            // SPN is available only if NegotiateTestSpn has been explicitly set.
            // When https://github.com/dotnet/wcf/issues/1283 is fixed, this should be updated to
            // handle the self-hosted as Local System scenario as well.
            return !String.IsNullOrWhiteSpace(GetSPN());
        }
 
        // Returns 'true if UPN is available
        public static bool IsUPNAvailable()
        {
            // UPN is available only if NegotiateTestSpn has been explicitly set.
            // When https://github.com/dotnet/wcf/issues/1283 is fixed, this should be updated to
            // handle the self-hosted as Local System scenario as well.
            return !String.IsNullOrWhiteSpace(GetUPN());
        }
 
        // Returns the explicit user name if available
        internal static string GetExplicitUserName()
        {
            return TestProperties.GetProperty(TestProperties.ExplicitUserName_PropertyName);
        }
 
        // Returns the explicit password if available
        internal static string GetExplicitPassword()
        {
            return TestProperties.GetProperty(TestProperties.ExplicitPassword_PropertyName);
        }
 
        // Returns the Domain if available.
        // TestProperties takes precedence, but if it has not been specified
        // and this is a Windows client, we infer it.
        public static string GetDomain()
        {
            string result = TestProperties.GetProperty(TestProperties.NegotiateTestDomain_PropertyName);
            if (String.IsNullOrEmpty(result) && IsClientDomainJoined())
            {
                result = Environment.GetEnvironmentVariable("USERDOMAIN");
            }
 
            return result;
        }
 
        // Gets the UPN if available
        internal static string GetUPN()
        {
            return TestProperties.GetProperty(TestProperties.NegotiateTestUpn_PropertyName);
        }
 
        // Gets the SPN if available
        internal static string GetSPN()
        {
            return TestProperties.GetProperty(TestProperties.NegotiateTestSpn_PropertyName);
        }
 
    }
}