public InstanceDiscoveryManager(
            IHttpManager httpManager,
            ITelemetryManager telemetryManager,
            bool /* for test */ shouldClearCaches,
            IKnownMetadataProvider knownMetadataProvider     = null,
            IStaticMetadataProvider staticMetadataProvider   = null,
            INetworkMetadataProvider networkMetadataProvider = null)
        {
            _httpManager      = httpManager ?? throw new ArgumentNullException(nameof(httpManager));
            _telemetryManager = telemetryManager ?? throw new ArgumentNullException(nameof(telemetryManager));

            _knownMetadataProvider   = knownMetadataProvider ?? new KnownMetadataProvider();
            _staticMetadataProvider  = staticMetadataProvider ?? new StaticMetadataProvider();
            _networkMetadataProvider = networkMetadataProvider ?? new NetworkMetadataProvider(_httpManager, _telemetryManager);

            if (shouldClearCaches)
            {
                _staticMetadataProvider.Clear();
            }
        }
        public async Task NetworkProviderIsCalledLastAsync()
        {
            // Arrange
            _staticMetadataProvider = new StaticMetadataProvider();

            _discoveryManager = new InstanceDiscoveryManager(
                _harness.HttpManager,
                _harness.ServiceBundle.TelemetryManager,
                false,
                _knownMetadataProvider,
                _staticMetadataProvider,
                _networkMetadataProvider);

            var otherEnvs = new[] { "env1", "env2" };
            InstanceDiscoveryResponse discoveryResponse = new InstanceDiscoveryResponse
            {
                Metadata = new[] { _expectedResult }
            };
            var authorityUri = new Uri(Authority);

            // No response from the static and known provider
            _knownMetadataProvider
            .GetMetadata("some_env.com", otherEnvs)
            .Returns((InstanceDiscoveryMetadataEntry)null);
            _networkMetadataProvider
            .FetchAllDiscoveryMetadataAsync(authorityUri, _testRequestContext)
            .Returns(discoveryResponse);

            // Act
            InstanceDiscoveryMetadataEntry actualResult = await _discoveryManager.GetMetadataEntryTryAvoidNetworkAsync(
                "https://some_env.com/tid",
                otherEnvs,
                _testRequestContext)
                                                          .ConfigureAwait(false);

            // Assert
            Assert.AreSame(_expectedResult, actualResult, "The known metadata provider should be queried second");
            _knownMetadataProvider.Received(1).GetMetadata("some_env.com", otherEnvs);
            _ = _networkMetadataProvider.Received(1).FetchAllDiscoveryMetadataAsync(authorityUri, _testRequestContext);
        }
        public override void TestInitialize()
        {
            base.TestInitialize();

            _networkMetadataProvider = Substitute.For <INetworkMetadataProvider>();
            _knownMetadataProvider   = Substitute.For <IKnownMetadataProvider>();
            _staticMetadataProvider  = Substitute.For <IStaticMetadataProvider>();
            _expectedResult          = new InstanceDiscoveryMetadataEntry()
            {
                Aliases          = new[] { "some_env.com", "some_env2.com" },
                PreferredCache   = "env",
                PreferredNetwork = "env"
            };

            _harness            = base.CreateTestHarness();
            _testRequestContext = new RequestContext(_harness.ServiceBundle, Guid.NewGuid());
            _discoveryManager   = new InstanceDiscoveryManager(
                _harness.HttpManager,
                _harness.ServiceBundle.TelemetryManager,
                false,
                _knownMetadataProvider,
                _staticMetadataProvider,
                _networkMetadataProvider);
        }