< Summary

Class:Azure.Core.TestFramework.TestEnvironment
Assembly:Azure.Core.TestFramework
File(s):C:\Git\azure-sdk-for-net\sdk\core\Azure.Core.TestFramework\src\TestEnvironment.cs
Covered lines:59
Uncovered lines:25
Coverable lines:84
Total lines:278
Line coverage:70.2% (59 of 84)
Covered branches:24
Total branches:38
Branch coverage:63.1% (24 of 38)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.ctor(...)-56.25%37.5%
.cctor()-85.71%62.5%
get_Mode()-100%100%
get_SubscriptionId()-100%100%
get_ResourceGroup()-100%100%
get_Location()-100%100%
get_AzureEnvironment()-0%100%
get_TenantId()-100%100%
get_ResourceManagerUrl()-0%100%
get_ServiceManagementUrl()-0%100%
get_AuthorityHostUrl()-0%100%
get_StorageEndpointSuffix()-0%100%
get_ClientId()-100%100%
get_ClientSecret()-0%100%
get_Credential()-50%75%
GetRecordedOptionalVariable(...)-100%100%
GetRecordedVariable(...)-100%100%
GetOptionalVariable(...)-100%100%
GetVariable(...)-100%100%
EnsureValue(...)-33.33%50%
SetRecording(...)-100%100%
GetRecordedValue(...)-100%50%
SetRecordedValue(...)-66.67%50%
GetTokenAsync(...)-100%100%
GetToken(...)-100%100%

File(s)

C:\Git\azure-sdk-for-net\sdk\core\Azure.Core.TestFramework\src\TestEnvironment.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Security.Cryptography;
 7using System.IO;
 8using System.Reflection;
 9using System.Text.Json;
 10using System.Threading;
 11using System.Threading.Tasks;
 12using Azure.Identity;
 13
 14namespace Azure.Core.TestFramework
 15{
 16    /// <summary>
 17    ///   Represents the ambient environment in which the test suite is
 18    ///   being run.
 19    /// </summary>
 20    public abstract class TestEnvironment
 21    {
 22        private static readonly string RepositoryRoot;
 23        private readonly string _prefix;
 24
 25        private TokenCredential _credential;
 26        private TestRecording _recording;
 27
 68228        private readonly Dictionary<string, string> _environmentFile = new Dictionary<string, string>(StringComparer.Ord
 29
 68230        protected TestEnvironment(string serviceName)
 31        {
 68232            _prefix = serviceName.ToUpperInvariant() + "_";
 68233            if (RepositoryRoot == null)
 34            {
 035                throw new InvalidOperationException("Unexpected error, repository root not found");
 36            }
 37
 68238            var sdkDirectory = Path.Combine(RepositoryRoot, "sdk", serviceName);
 68239            if (!Directory.Exists(sdkDirectory))
 40            {
 041                throw new InvalidOperationException($"SDK directory {sdkDirectory} not found");
 42            }
 43
 68244            var testEnvironmentFile = Path.Combine(RepositoryRoot, "sdk", serviceName, "test-resources.json.env");
 68245            if (File.Exists(testEnvironmentFile))
 46            {
 047                var json = JsonDocument.Parse(
 048                    ProtectedData.Unprotect(File.ReadAllBytes(testEnvironmentFile), null, DataProtectionScope.CurrentUse
 049                );
 50
 051                foreach (var property in json.RootElement.EnumerateObject())
 52                {
 053                    _environmentFile[property.Name] = property.Value.GetString();
 54                }
 55            }
 68256        }
 57
 58        static TestEnvironment()
 59        {
 60            // Traverse parent directories until we find an "artifacts" directory
 61            // parent of that would become a repo root for test environment resolution purposes
 5762            var directoryInfo = new DirectoryInfo(Assembly.GetExecutingAssembly().Location);
 63
 34264            while (directoryInfo.Name != "artifacts")
 65            {
 28566                if (directoryInfo.Parent == null)
 67                {
 068                    return;
 69                }
 70
 28571                directoryInfo = directoryInfo.Parent;
 72            }
 73
 5774            RepositoryRoot = directoryInfo?.Parent?.FullName;
 5775        }
 76
 1274377        internal RecordedTestMode? Mode { get; set; }
 78
 79        /// <summary>
 80        ///   The name of the Azure subscription containing the resource group to be used for Live tests. Recorded.
 81        /// </summary>
 424082        public string SubscriptionId => GetRecordedVariable("SUBSCRIPTION_ID");
 83
 84        /// <summary>
 85        ///   The name of the Azure resource group to be used for Live tests. Recorded.
 86        /// </summary>
 1287        public string ResourceGroup => GetRecordedVariable("RESOURCE_GROUP");
 88
 89        /// <summary>
 90        ///   The location of the Azure resource group to be used for Live tests (e.g. westus2). Recorded.
 91        /// </summary>
 6492        public string Location => GetRecordedVariable("LOCATION");
 93
 94        /// <summary>
 95        ///   The environment of the Azure resource group to be used for Live tests (e.g. AzureCloud). Recorded.
 96        /// </summary>
 097        public string AzureEnvironment => GetRecordedVariable("ENVIRONMENT");
 98
 99        /// <summary>
 100        ///   The name of the Azure Active Directory tenant that holds the service principal to use during Live tests. R
 101        /// </summary>
 24102        public string TenantId => GetRecordedVariable("TENANT_ID");
 103
 104        /// <summary>
 105        ///   The URL of the Azure Resource Manager to be used for management plane operations. Recorded.
 106        /// </summary>
 0107        public string ResourceManagerUrl => GetRecordedOptionalVariable("RESOURCE_MANAGER_URL");
 108
 109        /// <summary>
 110        ///   The URL of the Azure Service Management endpoint to be used for management plane authentication. Recorded.
 111        /// </summary>
 0112        public string ServiceManagementUrl => GetRecordedOptionalVariable("SERVICE_MANAGEMENT_URL");
 113
 114        /// <summary>
 115        ///   The URL of the Azure Authority host to be used for authentication. Recorded.
 116        /// </summary>
 0117        public string AuthorityHostUrl => GetRecordedOptionalVariable("AZURE_AUTHORITY_HOST");
 118
 119        /// <summary>
 120        ///   The suffix for Azure Storage accounts for the active cloud environment, such as "core.windows.net".  Recor
 121        /// </summary>
 0122        public string StorageEndpointSuffix => GetRecordedOptionalVariable("STORAGE_ENDPOINT_SUFFIX");
 123
 124        /// <summary>
 125        ///   The client id of the Azure Active Directory service principal to use during Live tests. Recorded.
 126        /// </summary>
 8127        public string ClientId => GetRecordedVariable("CLIENT_ID");
 128
 129        /// <summary>
 130        ///   The client secret of the Azure Active Directory service principal to use during Live tests. Not recorded.
 131        /// </summary>
 0132        public string ClientSecret => GetVariable("CLIENT_SECRET");
 133
 134        public TokenCredential Credential
 135        {
 136            get
 137            {
 4836138                if (_credential != null)
 139                {
 2938140                    return _credential;
 141                }
 142
 1898143                if (Mode == RecordedTestMode.Playback)
 144                {
 1898145                    _credential = new TestCredential();
 146                }
 147                else
 148                {
 0149                    _credential = new ClientSecretCredential(
 0150                        GetVariable("TENANT_ID"),
 0151                        GetVariable("CLIENT_ID"),
 0152                        GetVariable("CLIENT_SECRET")
 0153                    );
 154                }
 155
 1898156                return _credential;
 157            }
 158        }
 159
 160        /// <summary>
 161        /// Returns and records an environment variable value when running live or recorded value during playback.
 162        /// </summary>
 163        protected string GetRecordedOptionalVariable(string name)
 164        {
 10161165            if (Mode == RecordedTestMode.Playback)
 166            {
 10147167                return GetRecordedValue(name);
 168            }
 169
 14170            string value = GetOptionalVariable(name);
 171
 14172            SetRecordedValue(name, value);
 173
 2174            return value;
 175        }
 176
 177        /// <summary>
 178        /// Returns and records an environment variable value when running live or recorded value during playback.
 179        /// Throws when variable is not found.
 180        /// </summary>
 181        protected string GetRecordedVariable(string name)
 182        {
 9945183            var value = GetRecordedOptionalVariable(name);
 9929184            EnsureValue(name, value);
 9929185            return value;
 186        }
 187
 188        /// <summary>
 189        /// Returns an environment variable value or null when variable is not found.
 190        /// </summary>
 191        protected string GetOptionalVariable(string name)
 192        {
 252193            var prefixedName = _prefix + name;
 194
 195            // Environment variables override the environment file
 252196            var value = Environment.GetEnvironmentVariable(prefixedName) ??
 252197                        Environment.GetEnvironmentVariable(name);
 198
 252199            if (value == null)
 200            {
 220201                _environmentFile.TryGetValue(prefixedName, out value);
 202            }
 203
 252204            if (value == null)
 205            {
 220206                _environmentFile.TryGetValue(name, out value);
 207            }
 208
 252209            return value;
 210        }
 211
 212        /// <summary>
 213        /// Returns an environment variable value.
 214        /// Throws when variable is not found.
 215        /// </summary>
 216        protected string GetVariable(string name)
 217        {
 18218            var value = GetOptionalVariable(name);
 18219            EnsureValue(name, value);
 18220            return value;
 221        }
 222
 223        private void EnsureValue(string name, string value)
 224        {
 9947225            if (value == null)
 226            {
 0227                var prefixedName = _prefix + name;
 0228                throw new InvalidOperationException(
 0229                    $"Unable to find environment variable {prefixedName} or {name} required by test." + Environment.NewL
 0230                    "Make sure the test environment was initialized using eng/common/TestResources/New-TestResources.ps1
 231            }
 9947232        }
 233
 234        public void SetRecording(TestRecording recording)
 235        {
 3692236            _credential = null;
 3692237            _recording = recording;
 3692238        }
 239
 240        private string GetRecordedValue(string name)
 241        {
 10147242            if (_recording == null)
 243            {
 4244                throw new InvalidOperationException("Recorded value should not be retrieved outside the test method invo
 245            }
 246
 10143247            return _recording.GetVariable(name, null);
 248        }
 249
 250        private void SetRecordedValue(string name, string value)
 251        {
 14252            if (!Mode.HasValue)
 253            {
 2254                return;
 255            }
 256
 12257            if (_recording == null)
 258            {
 12259                throw new InvalidOperationException("Recorded value should not be set outside the test method invocation
 260            }
 261
 0262            _recording?.SetVariable(name, value);
 0263        }
 264
 265        private class TestCredential : TokenCredential
 266        {
 267            public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken c
 268            {
 1724269                return new ValueTask<AccessToken>(GetToken(requestContext, cancellationToken));
 270            }
 271
 272            public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken
 273            {
 3452274                return new AccessToken("TEST TOKEN " + string.Join(" ", requestContext.Scopes), DateTimeOffset.MaxValue)
 275            }
 276        }
 277    }
 278}