public void GetConfig_FirstTime_CertificateLoadingThrewException_Throws()
        {
            var builder     = new ConfigurationBuilder();
            var proxyConfig = builder.AddInMemoryCollection(new Dictionary <string, string>
            {
                ["Clusters:cluster1:Destinations:destinationA:Address"] = "https://localhost:10001/destC",
                ["Clusters:cluster1:HttpClient:ClientCertificate:Path"] = "mycert.pfx",
                ["Routes:0:RouteId"]       = "routeA",
                ["Routes:0:ClusterId"]     = "cluster1",
                ["Routes:0:Order"]         = "1",
                ["Routes:0:Match:Hosts:0"] = "host-B",
            }).Build();
            var certLoader = new Mock <ICertificateConfigLoader>(MockBehavior.Strict);

            using var certificate = TestResources.GetTestCertificate();
            certLoader.Setup(l => l.LoadCertificate(It.IsAny <IConfigurationSection>())).Throws(new FileNotFoundException());
            var logger   = new Mock <ILogger <ConfigurationConfigProvider> >();
            var provider = new ConfigurationConfigProvider(logger.Object, proxyConfig, certLoader.Object);

            Assert.ThrowsAny <FileNotFoundException>(() => provider.GetConfig());
        }
        public void GetConfig_ValidConfiguration_AllAbstractionsPropertiesAreSet()
        {
            var builder = new ConfigurationBuilder();

            using var stream = new MemoryStream(Encoding.UTF8.GetBytes(_validJsonConfig));
            var proxyConfig = builder.AddJsonStream(stream).Build();
            var certLoader  = new Mock <ICertificateConfigLoader>(MockBehavior.Strict);

            using var certificate = TestResources.GetTestCertificate();
            certLoader.Setup(l => l.LoadCertificate(It.Is <IConfigurationSection>(o => o["Path"] == "mycert.pfx" && o["Password"] == "myPassword1234"))).Returns(certificate);
            var logger = new Mock <ILogger <ConfigurationConfigProvider> >();

            var provider       = new ConfigurationConfigProvider(logger.Object, proxyConfig, certLoader.Object);
            var abstractConfig = (ConfigurationSnapshot)provider.GetConfig();

            var abstractionsNamespace = typeof(Cluster).Namespace;

            // Removed incompletely filled out instances.
            abstractConfig.Clusters = abstractConfig.Clusters.Where(c => c.Id == "cluster1").ToList();
            abstractConfig.Routes   = abstractConfig.Routes.Where(r => r.RouteId == "routeA").ToList();

            VerifyAllPropertiesAreSet(abstractConfig);

            void VerifyFullyInitialized(object obj, string name)
            {
                switch (obj)
                {
                case null:
                    Assert.True(false, $"Property {name} is not initialized.");
                    break;

                case Enum m:
                    Assert.NotEqual(0, (int)(object)m);
                    break;

                case string str:
                    Assert.NotEmpty(str);
                    break;

                case ValueType v:
                    var equals = Equals(Activator.CreateInstance(v.GetType()), v);
                    Assert.False(equals, $"Property {name} is not initialized.");
                    if (v.GetType().Namespace == abstractionsNamespace)
                    {
                        VerifyAllPropertiesAreSet(v);
                    }
                    break;

                case IDictionary d:
                    Assert.NotEmpty(d);
                    foreach (var value in d.Values)
                    {
                        VerifyFullyInitialized(value, name);
                    }
                    break;

                case IEnumerable e:
                    Assert.NotEmpty(e);
                    foreach (var item in e)
                    {
                        VerifyFullyInitialized(item, name);
                    }

                    var type = e.GetType();
                    if (!type.IsArray && type.Namespace == abstractionsNamespace)
                    {
                        VerifyAllPropertiesAreSet(e);
                    }
                    break;

                case object o:
                    if (o.GetType().Namespace == abstractionsNamespace)
                    {
                        VerifyAllPropertiesAreSet(o);
                    }
                    break;
                }
            }

            void VerifyAllPropertiesAreSet(object obj)
            {
                var properties = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public).Cast <PropertyInfo>();

                foreach (var property in properties)
                {
                    VerifyFullyInitialized(property.GetValue(obj), $"{property.DeclaringType.Name}.{property.Name}");
                }
            }
        }