public void MapTest()
        {
            var configStore   = new MockConfigStore();
            var configSection = new ConfigSection(TraceType, configStore, SectionName);

            string rootPrefix = "Test.";

            var policy = new RoleInstanceStatusMapHealthPolicy(configSection, rootPrefix);
            var ri     = new RoleInstance("1", RoleInstanceState.Unhealthy, DateTime.UtcNow);

            string key = BaseRoleInstanceHealthPolicy.GetFullKeyName(
                rootPrefix,
                policy.Name,
                RoleInstanceState.Unhealthy);

            var defaultValue = policy.GetConfigValue(key);

            HealthState output = policy.Apply(ri, HealthState.Ok);

            Assert.AreEqual(output.ToString(), defaultValue, "Health state with default mapping");

            const HealthState NewHealth = HealthState.Warning;

            configStore.AddKeyValue(SectionName, key, NewHealth.ToString());

            output = policy.Apply(ri, HealthState.Ok);

            Assert.AreEqual(output, NewHealth, "New health state with updated mapping");
        }
Example #2
0
        private static IConfigSection GetConfigSection()
        {
            var store = new MockConfigStore();

            store.AddKeyValue(ConfigSectionName, WindowsAzureInfrastructureCoordinator.ConfigEnableLearningModeForJobTypeFormatKeyName.ToString(JobType.PlatformUpdateJob), true.ToString());
            store.AddKeyValue(ConfigSectionName, WindowsAzureInfrastructureCoordinator.ConfigEnableLearningModeForJobTypeFormatKeyName.ToString(JobType.DeploymentUpdateJob), true.ToString());

            var cs = new ConfigSection(traceType, store, ConfigSectionName);

            return(cs);
        }
        public void MaxAllowedValueTest()
        {
            var configStore   = new MockConfigStore();
            var configSection = new ConfigSection(TraceType, configStore, SectionName);

            string rootPrefix = "Test.";

            var policy = new RoleInstanceStatusMaxAllowedHealthPolicy(configSection, rootPrefix);
            var ri     = new RoleInstance("1", RoleInstanceState.Unhealthy, DateTime.UtcNow);

            string maxAllowedKeyName = BaseRoleInstanceHealthPolicy.GetFullKeyName(
                rootPrefix,
                policy.Name,
                "HealthState");

            configStore.UpdateKey(SectionName, maxAllowedKeyName, HealthState.Error.ToString());

            var         inputHealthState = HealthState.Unknown;
            HealthState output           = policy.Apply(ri, inputHealthState);


            Assert.AreEqual(output, HealthState.Error, string.Format(CultureInfo.CurrentCulture, "Output health state clipped down from '{0}' to max allowed state '{1}'", inputHealthState, output));

            inputHealthState = HealthState.Warning;
            output           = policy.Apply(ri, inputHealthState);

            Assert.AreEqual(output, inputHealthState, "Output health state not clipped since it is below max allowed state");

            inputHealthState = HealthState.Unknown;
            string oldValue = configStore.GetValue(SectionName, maxAllowedKeyName);

            configStore.UpdateKey(SectionName, maxAllowedKeyName, HealthState.Warning.ToString());
            output = policy.Apply(ri, inputHealthState);

            Assert.AreEqual(output, HealthState.Warning, string.Format(CultureInfo.CurrentCulture, "Output health state clipped down from '{0}' to max allowed state '{1}'", inputHealthState, output));

            // revert to old value
            configStore.UpdateKey(SectionName, maxAllowedKeyName, oldValue);
            output = policy.Apply(ri, inputHealthState);

            Assert.AreEqual(output.ToString(), oldValue, string.Format(CultureInfo.CurrentCulture, "Output health state clipped down from '{0}' to max allowed state '{1}'", inputHealthState, output));
        }
        public IInfrastructureCoordinator Create()
        {
            string configSectionName = typeof(WindowsAzureInfrastructureCoordinatorTest).Name + "ConfigSection";

            const string ConfigJobPollingIntervalInSecondsKeyName = "WindowsAzure.JobPollingIntervalInSeconds";

            var configStore = new MockConfigStore();

            // loop faster in the ProcessManagementNotification loop of WindowsAzureInfrastructureCoordinator
            configStore.AddKeyValue(configSectionName, ConfigJobPollingIntervalInSecondsKeyName, "1");

            foreach (var pair in configSettings)
            {
                configStore.AddKeyValue(configSectionName, pair.Key, pair.Value);
            }

            var partitionId = Guid.NewGuid();
            var jobBlockingPolicyManager = new MockJobBlockingPolicyManager();

            var jobImpactManager = new JobImpactManager(new ConfigSection(traceType, configStore, configSectionName), queryClient);

            var coordinator = new WindowsAzureInfrastructureCoordinator(
                "mytenant",
                managementClient,
                this.agent,
                configStore,
                configSectionName,
                partitionId,
                0,
                new MockHealthClient(),
                jobBlockingPolicyManager,
                jobImpactManager,
                null);

            return(coordinator);
        }
Example #5
0
 public void TestInitialize()
 {
     this.configStore = new MockConfigStore();
     this.translator  = new ImpactTranslator(new ConfigSection(TraceType, this.configStore, ConfigSectionName));
 }
        public void InvalidKeysTest()
        {
            var configStore   = new MockConfigStore();
            var configSection = new ConfigSection(TraceType, configStore, SectionName);

            string rootPrefix = "Test.";

            var policy = new RoleInstanceStatusMaxAllowedHealthPolicy(configSection, rootPrefix);
            var ri     = new RoleInstance("1", RoleInstanceState.Unhealthy, DateTime.UtcNow);

            string maxAllowedKeyName = BaseRoleInstanceHealthPolicy.GetFullKeyName(
                rootPrefix,
                policy.Name,
                "HealthState");

            #region typo in key name

            string nonExistentKeyName = BaseRoleInstanceHealthPolicy.GetFullKeyName(
                rootPrefix,
                policy.Name,
                "HealthStatt"); // note the type from "HealthState". user has typed this in his clustermanifest.xml

            // set a default value to config store
            configStore.UpdateKey(SectionName, maxAllowedKeyName, HealthState.Error.ToString());

            // now update config store with an invalid key
            configStore.UpdateKey(SectionName, nonExistentKeyName, HealthState.Unknown.ToString());

            // fetch the correct key
            var maxAllowedHealthState = configStore.GetValue(SectionName, maxAllowedKeyName);

            const HealthState InputHealthState = HealthState.Unknown;
            HealthState       output           = policy.Apply(ri, InputHealthState);

            Assert.AreEqual(
                output,
                HealthState.Error,
                string.Format(CultureInfo.CurrentCulture, "Output health state clipped down from '{0}' to default max allowed state '{1}'", InputHealthState, output));

            // now user realizes that he has made a typo in his clustermanifest.xml
            configStore.UpdateKey(SectionName, maxAllowedKeyName, HealthState.Unknown.ToString());
            output = policy.Apply(ri, InputHealthState);

            Assert.AreEqual(output, HealthState.Unknown, string.Format(CultureInfo.CurrentCulture, "Output health state not clipped down from '{0}' to max allowed state '{1}'", InputHealthState, output));

            #endregion typo in key name

            #region typo in key value

            configStore.ClearKeys(); // revert to defaults
            string defaultMaxHealthState = policy.GetConfigValue(maxAllowedKeyName);

            Assert.AreEqual(defaultMaxHealthState, HealthState.Error.ToString());

            // In this case, we know the default value as 'Error'.
            // Ideally, we need to parse the enum and get the next higher enum to update the key with
            configStore.UpdateKey(SectionName, maxAllowedKeyName, "Wurning");

            output = policy.Apply(ri, InputHealthState);

            // verify that Wurning didn't apply due to the typo. Since input was higher (Unknown) than the default, the output is also Unknown
            // i.e. no clipping applied

            Assert.AreEqual(
                output,
                InputHealthState,
                string.Format(
                    CultureInfo.CurrentCulture,
                    "Output health state not altered from '{0}' to default max allowed state '{1}' as it may not be safe to apply default since input was already higher than default",
                    InputHealthState,
                    defaultMaxHealthState));

            // provide a lower health state. Since there is an error in parsing, a warning should be returned
            output = policy.Apply(ri, HealthState.Ok);

            // verify that input of Ok is converted to Warning so that user observes that something is wrong and fixes his typo

            Assert.AreEqual(
                output,
                HealthState.Warning,
                string.Format(
                    CultureInfo.CurrentCulture,
                    "Output health state altered from '{0}' to '{1}' as there was an error applying policy",
                    HealthState.Ok,
                    output));

            // user realizes typo and fixes it
            configStore.UpdateKey(SectionName, maxAllowedKeyName, HealthState.Warning.ToString());

            output = policy.Apply(ri, InputHealthState);

            // verify that the new max allowed policy is in effect
            Assert.AreEqual(
                output,
                HealthState.Warning,
                string.Format(CultureInfo.CurrentCulture, "Output health state clipped down from '{0}' to max allowed state '{1}'", InputHealthState, output));

            #endregion typo in key value
        }
Example #7
0
        public async Task BasicTestAsync()
        {
            var configStore   = new MockConfigStore();
            var configSection = new ConfigSection(traceType, configStore, "Test");

            CoordinatorFactoryArgs args = new CoordinatorFactoryArgs()
            {
                Agent         = new MockInfrastructureAgentWrapper(),
                ConfigSection = configSection,
                PartitionId   = Guid.NewGuid(),
                ReplicaId     = 42L,
                ServiceName   = new Uri("fabric:/System/InfrastructureService"),
            };

            configStore.AddKeyValue(args.ConfigSectionName, "DelayLoad.RetryDelayInSeconds", "1");

            bool runAsyncCalled = false;

            MockCoordinator mockCoordinator = new MockCoordinator();

            mockCoordinator.RunAsyncHandler = (e, t) =>
            {
                runAsyncCalled = true;
                return(Task.Delay(Timeout.InfiniteTimeSpan, t));
            };

            const string expectedCommandResult = "Hello";

            mockCoordinator.RunCommandAsyncHandler = (admin, cmd, t, ct) =>
            {
                return(Task.FromResult(expectedCommandResult));
            };

            int failureCount = 2;
            Func <CoordinatorFactoryArgs, IInfrastructureCoordinator> factory = a =>
            {
                if (failureCount-- > 0)
                {
                    throw new Exception("Intentional failure");
                }

                return(mockCoordinator);
            };

            var coordinator = new DelayLoadCoordinator(
                factory: factory,
                factoryArgs: args,
                healthClient: new MockHealthClient(),
                configSection: configSection);

            var cts = new CancellationTokenSource();

            Task runAsyncTask = coordinator.RunAsync(0, cts.Token);

            while (!runAsyncCalled)
            {
                await Task.Delay(100);
            }

            Verify.AreEqual(expectedCommandResult, await coordinator.RunCommandAsync(false, "", TimeSpan.FromSeconds(1), CancellationToken.None));

            cts.Cancel();

            try
            {
                await runAsyncTask;
            }
            catch (TaskCanceledException)
            {
            }
        }
Example #8
0
        public async Task ServiceReplicaLifecycleTest()
        {
            var configStore = new MockConfigStore();

            configStore.AddKeyValue("InfrastructureService", "CrashOnRunAsyncUnexpectedCompletion", "false");

            var coordinator = new RunAsyncTestCoordinator();

            var replica = new ServiceReplica(
                new NullInfrastructureAgent(),
                coordinator,
                null,
                false,
                new ConfigSection(new TraceType("ServiceReplicaTest"), configStore, "InfrastructureService"));

            replica.Initialize(new StatefulServiceInitializationParameters()
            {
                PartitionId = Guid.NewGuid(),
                ReplicaId   = Stopwatch.GetTimestamp(),
            });

            await replica.OpenAsync(ReplicaOpenMode.New, new MockStatefulServicePartition(), CancellationToken.None);

            // Good coordinator: runs until cancelled
            coordinator.RunAsyncHandler = async(epoch, token) => { await Task.Delay(Timeout.InfiniteTimeSpan, token); };

            await replica.ChangeRoleAsync(ReplicaRole.Primary, CancellationToken.None);

            await Task.Delay(500);

            await replica.ChangeRoleAsync(ReplicaRole.ActiveSecondary, CancellationToken.None);

            await replica.ChangeRoleAsync(ReplicaRole.Primary, CancellationToken.None);

            await Task.Delay(500);

            await replica.CloseAsync(CancellationToken.None);

            // Bad coordinator: returns immediately
            coordinator.RunAsyncHandler = (epoch, token) => Task.FromResult(0);

            await replica.ChangeRoleAsync(ReplicaRole.Primary, CancellationToken.None);

            await Task.Delay(500);

            await replica.ChangeRoleAsync(ReplicaRole.ActiveSecondary, CancellationToken.None);

            await replica.ChangeRoleAsync(ReplicaRole.Primary, CancellationToken.None);

            await Task.Delay(500);

            await replica.CloseAsync(CancellationToken.None);

            // Bad coordinator: synchronous unhandled exception
            configStore.AddKeyValue("InfrastructureService", "CrashOnRunAsyncUnhandledException", "false");
            coordinator.RunAsyncHandler = null;

            await replica.ChangeRoleAsync(ReplicaRole.Primary, CancellationToken.None);

            await Task.Delay(500);

            await replica.ChangeRoleAsync(ReplicaRole.ActiveSecondary, CancellationToken.None);

            await replica.ChangeRoleAsync(ReplicaRole.Primary, CancellationToken.None);

            await Task.Delay(500);

            await replica.CloseAsync(CancellationToken.None);

            // Bad coordinator: delayed (async) unhandled exception
            coordinator.RunAsyncHandler = async(epoch, token) =>
            {
                await Task.Delay(100, token);

                throw new InvalidOperationException();
            };

            await replica.ChangeRoleAsync(ReplicaRole.Primary, CancellationToken.None);

            await Task.Delay(500);

            await replica.ChangeRoleAsync(ReplicaRole.ActiveSecondary, CancellationToken.None);

            await replica.ChangeRoleAsync(ReplicaRole.Primary, CancellationToken.None);

            await Task.Delay(500);

            await replica.CloseAsync(CancellationToken.None);

            // Old code - Bad coordinator: delayed (async) unhandled exception
            configStore.AddKeyValue("InfrastructureService", "WrapRunAsync", "false");

            await replica.ChangeRoleAsync(ReplicaRole.Primary, CancellationToken.None);

            await Task.Delay(500);

            await replica.ChangeRoleAsync(ReplicaRole.ActiveSecondary, CancellationToken.None);

            await replica.ChangeRoleAsync(ReplicaRole.Primary, CancellationToken.None);

            await Task.Delay(500);

            await replica.CloseAsync(CancellationToken.None);

            // Old code - Good coordinator: runs until cancelled
            coordinator.RunAsyncHandler = async(epoch, token) => { await Task.Delay(Timeout.InfiniteTimeSpan, token); };

            await replica.ChangeRoleAsync(ReplicaRole.Primary, CancellationToken.None);

            await Task.Delay(500);

            await replica.ChangeRoleAsync(ReplicaRole.ActiveSecondary, CancellationToken.None);

            await replica.ChangeRoleAsync(ReplicaRole.Primary, CancellationToken.None);

            await Task.Delay(500);

            await replica.CloseAsync(CancellationToken.None);
        }