Esempio n. 1
0
        public async Task UpdateRootLevelMembersWithNullSetsToDefault()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string metricId = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            await using DisposableDetectionConfiguration disposableDetectionConfig = await CreateTempDetectionConfigurationAsync(adminClient, metricId);

            var detectionConfigId = disposableDetectionConfig.Configuration.Id;

            string configName = Recording.GenerateAlphaNumericId("config");

            var configToCreate = new AnomalyAlertConfiguration()
            {
                Name        = configName,
                Description = "description",
                MetricAlertConfigurations =
                {
                    new MetricAlertConfiguration(detectionConfigId, MetricAnomalyAlertScope.CreateScopeForWholeSeries())
                }
            };

            await using var disposableConfig = await DisposableAlertConfiguration.CreateAlertConfigurationAsync(adminClient, configToCreate);

            AnomalyAlertConfiguration configToUpdate = disposableConfig.Configuration;

            configToUpdate.Description = null;

            AnomalyAlertConfiguration updatedConfig = await adminClient.UpdateAlertConfigurationAsync(configToUpdate);

            Assert.That(updatedConfig.Description, Is.Empty);
        }
Esempio n. 2
0
        public async Task CreateAndGetAlertConfigurationWithSeriesGroupScope()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string metricId = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            await using DisposableDetectionConfiguration disposableDetectionConfig = await CreateTempDetectionConfigurationAsync(adminClient, metricId);

            var dimensions = new Dictionary <string, string>()
            {
                { TempDataFeedDimensionNameA, "Delhi" }
            };
            DimensionKey groupKey = new DimensionKey(dimensions);

            var detectionConfigId = disposableDetectionConfig.Configuration.Id;
            var scope             = MetricAnomalyAlertScope.CreateScopeForSeriesGroup(groupKey);
            var metricAlertConfig = new MetricAlertConfiguration(detectionConfigId, scope);

            string configName = Recording.GenerateAlphaNumericId("config");

            var configToCreate = new AnomalyAlertConfiguration()
            {
                Name = configName,
                MetricAlertConfigurations = { metricAlertConfig }
            };

            await using var disposableConfig = await DisposableAlertConfiguration.CreateAlertConfigurationAsync(adminClient, configToCreate);

            AnomalyAlertConfiguration createdConfig = disposableConfig.Configuration;

            Assert.That(createdConfig.Id, Is.Not.Null.And.Not.Empty);
            Assert.That(createdConfig.Name, Is.EqualTo(configName));
            Assert.That(createdConfig.Description, Is.Empty);
            Assert.That(createdConfig.CrossMetricsOperator, Is.Null);
            Assert.That(createdConfig.IdsOfHooksToAlert, Is.Not.Null.And.Empty);
            Assert.That(createdConfig.DimensionsToSplitAlert, Is.Not.Null.And.Empty);
            Assert.That(createdConfig.MetricAlertConfigurations, Is.Not.Null);

            MetricAlertConfiguration createdMetricAlertConfig = createdConfig.MetricAlertConfigurations.Single();

            Assert.That(createdMetricAlertConfig.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(createdMetricAlertConfig.AlertScope, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.SeriesGroup));
            Assert.That(createdMetricAlertConfig.AlertScope.TopNGroupInScope, Is.Null);

            ValidateTempDataFeedDimensionKey(createdMetricAlertConfig.AlertScope.SeriesGroupInScope, "Delhi");

            Assert.That(createdMetricAlertConfig.AlertConditions, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition, Is.Null);
            Assert.That(createdMetricAlertConfig.AlertConditions.SeverityCondition, Is.Null);

            Assert.That(createdMetricAlertConfig.AlertSnoozeCondition, Is.Null);
            Assert.That(createdMetricAlertConfig.UseDetectionResultToFilterAnomalies, Is.False);
        }
Esempio n. 3
0
        public async Task CreateAndGetAlertConfigurationWithTopNScope()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string metricId = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            await using DisposableDetectionConfiguration disposableDetectionConfig = await CreateTempDetectionConfigurationAsync(adminClient, metricId);

            var detectionConfigId = disposableDetectionConfig.Configuration.Id;
            var topNGroup         = new TopNGroupScope(30, 20, 10);
            var scope             = MetricAnomalyAlertScope.GetScopeForTopNGroup(topNGroup);
            var metricAlertConfig = new MetricAnomalyAlertConfiguration(detectionConfigId, scope);

            string configName = Recording.GenerateAlphaNumericId("config");

            var configToCreate = new AnomalyAlertConfiguration()
            {
                Name = configName,
                MetricAlertConfigurations = { metricAlertConfig }
            };

            await using var disposableConfig = await DisposableAlertConfiguration.CreateAlertConfigurationAsync(adminClient, configToCreate);

            AnomalyAlertConfiguration createdConfig = disposableConfig.Configuration;

            Assert.That(createdConfig.Id, Is.Not.Null.And.Not.Empty);
            Assert.That(createdConfig.Name, Is.EqualTo(configName));
            Assert.That(createdConfig.Description, Is.Empty);
            Assert.That(createdConfig.CrossMetricsOperator, Is.Null);
            Assert.That(createdConfig.IdsOfHooksToAlert, Is.Not.Null.And.Empty);
            Assert.That(createdConfig.MetricAlertConfigurations, Is.Not.Null);

            MetricAnomalyAlertConfiguration createdMetricAlertConfig = createdConfig.MetricAlertConfigurations.Single();

            Assert.That(createdMetricAlertConfig.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(createdMetricAlertConfig.AlertScope, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.TopN));
            Assert.That(createdMetricAlertConfig.AlertScope.SeriesGroupInScope, Is.Null);

            Assert.That(createdMetricAlertConfig.AlertScope.TopNGroupInScope, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertScope.TopNGroupInScope.Top, Is.EqualTo(30));
            Assert.That(createdMetricAlertConfig.AlertScope.TopNGroupInScope.Period, Is.EqualTo(20));
            Assert.That(createdMetricAlertConfig.AlertScope.TopNGroupInScope.MinimumTopCount, Is.EqualTo(10));

            Assert.That(createdMetricAlertConfig.AlertConditions, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition, Is.Null);
            Assert.That(createdMetricAlertConfig.AlertConditions.SeverityCondition, Is.Null);

            Assert.That(createdMetricAlertConfig.AlertSnoozeCondition, Is.Null);
            Assert.That(createdMetricAlertConfig.UseDetectionResultToFilterAnomalies, Is.False);
        }
        public async Task CreateAndGetDetectionConfigurationWithHardCondition(bool useTokenCredential)
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient(useTokenCredential);

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string configName  = Recording.GenerateAlphaNumericId("config");
            string metricId    = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];
            var    description = "This configuration was created to test the .NET client.";

            var wholeConditions = new MetricWholeSeriesDetectionCondition()
            {
                HardThresholdCondition = new(AnomalyDetectorDirection.Up, new(1, 2.0))
                {
                    UpperBound = 10.0
                }
            };

            var configToCreate = new AnomalyDetectionConfiguration()
            {
                MetricId = metricId,
                Name     = configName,
                WholeSeriesDetectionConditions = wholeConditions,
                // This is the only test that validates description during creation. Please don't remove it!
                Description = description
            };

            await using var disposableConfig = await DisposableDetectionConfiguration.CreateDetectionConfigurationAsync(adminClient, configToCreate);

            AnomalyDetectionConfiguration createdConfig = disposableConfig.Configuration;

            Assert.That(createdConfig.Id, Is.Not.Null.And.Not.Empty);
            Assert.That(createdConfig.MetricId, Is.EqualTo(metricId));
            Assert.That(createdConfig.Name, Is.EqualTo(configName));
            Assert.That(createdConfig.Description, Is.EqualTo(description));
            Assert.That(createdConfig.SeriesGroupDetectionConditions, Is.Not.Null.And.Empty);
            Assert.That(createdConfig.SeriesDetectionConditions, Is.Not.Null.And.Empty);

            MetricWholeSeriesDetectionCondition createdWholeConditions = createdConfig.WholeSeriesDetectionConditions;

            Assert.That(createdWholeConditions, Is.Not.Null);
            Assert.That(createdWholeConditions.ConditionOperator, Is.Null);
            Assert.That(createdWholeConditions.ChangeThresholdCondition, Is.Null);
            Assert.That(createdWholeConditions.SmartDetectionCondition, Is.Null);

            ValidateHardThresholdCondition(createdWholeConditions.HardThresholdCondition, AnomalyDetectorDirection.Up, 10.0, null, 1, 2.0);
        }
Esempio n. 5
0
        protected async Task <DisposableDataFeed> CreateTempDataFeedAsync(MetricsAdvisorAdministrationClient adminClient)
        {
            var dataFeed = new DataFeed()
            {
                Name        = Recording.GenerateAlphaNumericId("dataFeed"),
                DataSource  = new SqlServerDataFeedSource("connString", "query"),
                Granularity = new DataFeedGranularity(DataFeedGranularityType.Daily),
                Schema      = new DataFeedSchema()
                {
                    MetricColumns    = { new DataFeedMetric(TempDataFeedMetricName) },
                    DimensionColumns = { new DataFeedDimension(TempDataFeedDimensionNameA), new DataFeedDimension(TempDataFeedDimensionNameB) }
                },
                IngestionSettings = new DataFeedIngestionSettings(SamplingStartTime)
            };

            return(await DisposableDataFeed.CreateDataFeedAsync(adminClient, dataFeed));
        }
        public async Task UpdateDetectionConfigurationWithMinimumSetup(bool useTokenCredential)
        {
            // Set required parameters of the configuration to be created.

            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string configName = Recording.GenerateAlphaNumericId("config");
            string metricId   = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            var wholeConditions = new MetricWholeSeriesDetectionCondition()
            {
                ConditionOperator      = DetectionConditionOperator.Or,
                HardThresholdCondition = new(AnomalyDetectorDirection.Down, new(1, 2.0))
                {
                    LowerBound = 10.0
                },
        public async Task CreateAndGetDetectionConfigurationWithChangeAndSmartConditions()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string configName = Recording.GenerateAlphaNumericId("config");
            string metricId   = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            var wholeConditions = new MetricWholeSeriesDetectionCondition()
            {
                ConditionOperator        = DetectionConditionOperator.And,
                ChangeThresholdCondition = new(90.0, 5, true, AnomalyDetectorDirection.Both, new(1, 2.0)),
                SmartDetectionCondition  = new(23.0, AnomalyDetectorDirection.Down, new(3, 4.0))
            };

            var configToCreate = new AnomalyDetectionConfiguration()
            {
                MetricId = metricId,
                Name     = configName,
                WholeSeriesDetectionConditions = wholeConditions
            };

            await using var disposableConfig = await DisposableDetectionConfiguration.CreateDetectionConfigurationAsync(adminClient, configToCreate);

            AnomalyDetectionConfiguration createdConfig = disposableConfig.Configuration;

            Assert.That(createdConfig.Id, Is.Not.Null.And.Not.Empty);
            Assert.That(createdConfig.MetricId, Is.EqualTo(metricId));
            Assert.That(createdConfig.Name, Is.EqualTo(configName));
            Assert.That(createdConfig.Description, Is.Empty);
            Assert.That(createdConfig.SeriesGroupDetectionConditions, Is.Not.Null.And.Empty);
            Assert.That(createdConfig.SeriesDetectionConditions, Is.Not.Null.And.Empty);

            MetricWholeSeriesDetectionCondition createdWholeConditions = createdConfig.WholeSeriesDetectionConditions;

            Assert.That(createdWholeConditions, Is.Not.Null);
            Assert.That(createdWholeConditions.ConditionOperator, Is.EqualTo(DetectionConditionOperator.And));
            Assert.That(createdWholeConditions.HardThresholdCondition, Is.Null);

            ValidateChangeThresholdCondition(createdWholeConditions.ChangeThresholdCondition, 90.0, 5, true, AnomalyDetectorDirection.Both, 1, 2.0);
            ValidateSmartDetectionCondition(createdWholeConditions.SmartDetectionCondition, 23.0, AnomalyDetectorDirection.Down, 3, 4.0);
        }
Esempio n. 8
0
        public async Task DeleteAlertConfiguration(bool useTokenCredential)
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient(useTokenCredential);

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string metricId = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            await using DisposableDetectionConfiguration disposableDetectionConfig = await CreateTempDetectionConfigurationAsync(adminClient, metricId);

            string configName        = Recording.GenerateAlphaNumericId("config");
            var    detectionConfigId = disposableDetectionConfig.Configuration.Id;
            var    scope             = MetricAnomalyAlertScope.GetScopeForWholeSeries();
            var    configToCreate    = new AnomalyAlertConfiguration()
            {
                Name = configName,
                MetricAlertConfigurations = { new(detectionConfigId, scope) }
            };

            string configId = null;

            try
            {
                AnomalyAlertConfiguration createdConfig = await adminClient.CreateAlertConfigurationAsync(configToCreate);

                configId = createdConfig.Id;

                Assert.That(configId, Is.Not.Null.And.Not.Empty);
            }
            finally
            {
                if (configId != null)
                {
                    await adminClient.DeleteAlertConfigurationAsync(configId);

                    var errorCause = "Not Found";
                    Assert.That(async() => await adminClient.GetAlertConfigurationAsync(configId), Throws.InstanceOf <RequestFailedException>().With.Message.Contains(errorCause));
                }
            }
        }
        public async Task CreateAndGetDetectionConfigurationWithSeriesConditions()
        {
            // Set required parameters of the configuration to be created.

            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string configName = Recording.GenerateAlphaNumericId("config");
            string metricId   = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            var wholeConditions = new MetricWholeSeriesDetectionCondition()
            {
                HardThresholdCondition = new(AnomalyDetectorDirection.Both, new(1, 2.0))
                {
                    UpperBound = 20.0,
                    LowerBound = 10.0
                }
            };

            var configToCreate = new AnomalyDetectionConfiguration()
            {
                MetricId = metricId,
                Name     = configName,
                WholeSeriesDetectionConditions = wholeConditions
            };

            // Set the series conditions and create the configuration.

            var dimensions = new Dictionary <string, string>()
            {
                { TempDataFeedDimensionNameA, "Delhi" }, { TempDataFeedDimensionNameB, "Handmade" }
            };
            var seriesConditions0 = new MetricSingleSeriesDetectionCondition(new DimensionKey(dimensions))
            {
                SmartDetectionCondition = new(30.0, AnomalyDetectorDirection.Both, new(3, 4.0))
            };

            dimensions = new Dictionary <string, string>()
            {
                { TempDataFeedDimensionNameA, "Kolkata" }, { TempDataFeedDimensionNameB, "Grocery & Gourmet Food" }
            };
            var seriesConditions1 = new MetricSingleSeriesDetectionCondition(new DimensionKey(dimensions))
            {
                ChangeThresholdCondition = new(40.0, 12, false, AnomalyDetectorDirection.Up, new(5, 6.0))
            };

            configToCreate.SeriesDetectionConditions.Add(seriesConditions0);
            configToCreate.SeriesDetectionConditions.Add(seriesConditions1);

            await using var disposableConfig = await DisposableDetectionConfiguration.CreateDetectionConfigurationAsync(adminClient, configToCreate);

            // Get the created configuration and validate top-level members.

            AnomalyDetectionConfiguration createdConfig = disposableConfig.Configuration;

            Assert.That(createdConfig.Id, Is.Not.Null.And.Not.Empty);
            Assert.That(createdConfig.MetricId, Is.EqualTo(metricId));
            Assert.That(createdConfig.Name, Is.EqualTo(configName));
            Assert.That(createdConfig.Description, Is.Empty);
            Assert.That(createdConfig.SeriesGroupDetectionConditions, Is.Not.Null.And.Empty);

            // Validate whole series detection conditions.

            MetricWholeSeriesDetectionCondition createdWholeConditions = createdConfig.WholeSeriesDetectionConditions;

            Assert.That(createdWholeConditions, Is.Not.Null);
            Assert.That(createdWholeConditions.ConditionOperator, Is.Null);
            Assert.That(createdWholeConditions.ChangeThresholdCondition, Is.Null);
            Assert.That(createdWholeConditions.SmartDetectionCondition, Is.Null);

            ValidateHardThresholdCondition(createdWholeConditions.HardThresholdCondition, AnomalyDetectorDirection.Both, 20.0, 10.0, 1, 2.0);

            // Start series conditions validation.

            Assert.That(createdConfig.SeriesDetectionConditions, Is.Not.Null);
            Assert.That(createdConfig.SeriesDetectionConditions.Count, Is.EqualTo(2));

            // Validate first series conditions.

            var createdSeriesConditions0 = createdConfig.SeriesDetectionConditions[0];

            Assert.That(createdSeriesConditions0, Is.Not.Null);

            ValidateTempDataFeedDimensionKey(createdSeriesConditions0.SeriesKey, "Delhi", "Handmade");

            Assert.That(createdSeriesConditions0.ConditionOperator, Is.Null);
            Assert.That(createdSeriesConditions0.HardThresholdCondition, Is.Null);
            Assert.That(createdSeriesConditions0.ChangeThresholdCondition, Is.Null);

            ValidateSmartDetectionCondition(createdSeriesConditions0.SmartDetectionCondition, 30.0, AnomalyDetectorDirection.Both, 3, 4.0);

            // Validate last series conditions.

            var createdSeriesConditions1 = createdConfig.SeriesDetectionConditions[1];

            Assert.That(createdSeriesConditions1, Is.Not.Null);

            ValidateTempDataFeedDimensionKey(createdSeriesConditions1.SeriesKey, "Kolkata", "Grocery & Gourmet Food");

            Assert.That(createdSeriesConditions1.ConditionOperator, Is.Null);
            Assert.That(createdSeriesConditions1.HardThresholdCondition, Is.Null);
            Assert.That(createdSeriesConditions1.SmartDetectionCondition, Is.Null);

            ValidateChangeThresholdCondition(createdSeriesConditions1.ChangeThresholdCondition, 40.0, 12, false, AnomalyDetectorDirection.Up, 5, 6.0);
        }
Esempio n. 10
0
        public async Task UpdateAlertConfigurationWithEveryMember()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string metricId = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            await using DisposableDetectionConfiguration disposableDetectionConfig = await CreateTempDetectionConfigurationAsync(adminClient, metricId);

            // Configure the Metric Anomaly Alert Configurations to be used.

            string hookName     = Recording.GenerateAlphaNumericId("hook");
            var    hookToCreate = new EmailNotificationHook(hookName)
            {
                EmailsToAlert = { "*****@*****.**" }
            };

            await using var disposableHook = await DisposableNotificationHook.CreateHookAsync(adminClient, hookToCreate);

            var detectionConfigId  = disposableDetectionConfig.Configuration.Id;
            var scope              = MetricAnomalyAlertScope.GetScopeForWholeSeries();
            var metricAlertConfig0 = new MetricAnomalyAlertConfiguration(detectionConfigId, scope)
            {
                AlertSnoozeCondition = new MetricAnomalyAlertSnoozeCondition(12, SnoozeScope.Series, true),
                AlertConditions      = new MetricAnomalyAlertConditions()
                {
                    MetricBoundaryCondition = new MetricBoundaryCondition(BoundaryDirection.Both)
                    {
                        UpperBound                    = 20.0,
                        LowerBound                    = 10.0,
                        CompanionMetricId             = metricId,
                        ShouldAlertIfDataPointMissing = true
                    },
                    SeverityCondition = new SeverityCondition(AnomalySeverity.Low, AnomalySeverity.Medium)
                }
            };
            var metricAlertConfig1 = new MetricAnomalyAlertConfiguration(detectionConfigId, scope)
            {
                UseDetectionResultToFilterAnomalies = true
            };

            // Create the Anomaly Alert Configuration.

            string configName  = Recording.GenerateAlphaNumericId("config");
            var    description = "This hook was created to test the .NET client.";
            var    hookIds     = new List <string>()
            {
                disposableHook.Hook.Id
            };
            var metricAlertConfigs = new List <MetricAnomalyAlertConfiguration>()
            {
                metricAlertConfig0, metricAlertConfig1
            };

            var configToCreate = new AnomalyAlertConfiguration()
            {
                Name = configName,
                IdsOfHooksToAlert         = { disposableHook.Hook.Id },
                MetricAlertConfigurations = { metricAlertConfig0, metricAlertConfig1 },
                CrossMetricsOperator      = MetricAnomalyAlertConfigurationsOperator.Xor
            };

            await using var disposableConfig = await DisposableAlertConfiguration.CreateAlertConfigurationAsync(adminClient, configToCreate);

            // Update the created configuration.

            AnomalyAlertConfiguration configToUpdate = disposableConfig.Configuration;

            configToUpdate.Description = description;
            configToUpdate.IdsOfHooksToAlert.Clear();
            configToUpdate.CrossMetricsOperator = MetricAnomalyAlertConfigurationsOperator.And;
            configToUpdate.MetricAlertConfigurations.RemoveAt(1);

            var newScope             = MetricAnomalyAlertScope.GetScopeForTopNGroup(new TopNGroupScope(50, 40, 30));
            var newMetricAlertConfig = new MetricAnomalyAlertConfiguration(detectionConfigId, newScope)
            {
                AlertSnoozeCondition = new MetricAnomalyAlertSnoozeCondition(4, SnoozeScope.Metric, true),
                UseDetectionResultToFilterAnomalies = true
            };

            configToUpdate.MetricAlertConfigurations.Add(newMetricAlertConfig);

            MetricAnomalyAlertConfiguration metricAlertConfigToUpdate = configToUpdate.MetricAlertConfigurations[0];

            metricAlertConfigToUpdate.AlertConditions.MetricBoundaryCondition.UpperBound                    = 15.0;
            metricAlertConfigToUpdate.AlertConditions.MetricBoundaryCondition.LowerBound                    = 5.0;
            metricAlertConfigToUpdate.AlertConditions.MetricBoundaryCondition.CompanionMetricId             = null;
            metricAlertConfigToUpdate.AlertConditions.MetricBoundaryCondition.ShouldAlertIfDataPointMissing = false;

            metricAlertConfigToUpdate.AlertConditions.SeverityCondition = new SeverityCondition(AnomalySeverity.Medium, AnomalySeverity.High);

            metricAlertConfigToUpdate.AlertSnoozeCondition = null;

            AnomalyAlertConfiguration updatedConfig = await adminClient.UpdateAlertConfigurationAsync(configToUpdate);

            // Validate top-level members.

            Assert.That(updatedConfig.Id, Is.EqualTo(configToUpdate.Id));
            Assert.That(updatedConfig.Name, Is.EqualTo(configName));
            Assert.That(updatedConfig.Description, Is.EqualTo(description));
            Assert.That(updatedConfig.CrossMetricsOperator, Is.EqualTo(MetricAnomalyAlertConfigurationsOperator.And));
            Assert.That(updatedConfig.IdsOfHooksToAlert, Is.Not.Null.And.Empty);
            Assert.That(updatedConfig.MetricAlertConfigurations, Is.Not.Null);

            // Validate the first Metric Anomaly Alert Configuration.

            MetricAnomalyAlertConfiguration updatedMetricAlertConfig0 = updatedConfig.MetricAlertConfigurations[0];

            Assert.That(updatedMetricAlertConfig0.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(updatedMetricAlertConfig0.AlertScope, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.WholeSeries));
            Assert.That(updatedMetricAlertConfig0.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(updatedMetricAlertConfig0.AlertScope.TopNGroupInScope, Is.Null);

            Assert.That(updatedMetricAlertConfig0.AlertConditions, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.Direction, Is.EqualTo(BoundaryDirection.Both));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.UpperBound, Is.EqualTo(15.0));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.LowerBound, Is.EqualTo(5.0));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.CompanionMetricId, Is.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.ShouldAlertIfDataPointMissing, Is.False);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.SeverityCondition, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.SeverityCondition.MinimumAlertSeverity, Is.EqualTo(AnomalySeverity.Medium));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.SeverityCondition.MaximumAlertSeverity, Is.EqualTo(AnomalySeverity.High));

            Assert.That(updatedMetricAlertConfig0.AlertSnoozeCondition, Is.Null);
            Assert.That(updatedMetricAlertConfig0.UseDetectionResultToFilterAnomalies, Is.False);

            // Validate the second Metric Anomaly Alert Configuration.

            MetricAnomalyAlertConfiguration updatedMetricAlertConfig1 = updatedConfig.MetricAlertConfigurations[1];

            Assert.That(updatedMetricAlertConfig1.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(updatedMetricAlertConfig1.AlertScope, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig1.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.TopN));
            Assert.That(updatedMetricAlertConfig1.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(updatedMetricAlertConfig1.AlertScope.TopNGroupInScope, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig1.AlertScope.TopNGroupInScope.Top, Is.EqualTo(50));
            Assert.That(updatedMetricAlertConfig1.AlertScope.TopNGroupInScope.Period, Is.EqualTo(40));
            Assert.That(updatedMetricAlertConfig1.AlertScope.TopNGroupInScope.MinimumTopCount, Is.EqualTo(30));

            Assert.That(updatedMetricAlertConfig1.AlertConditions, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig1.AlertConditions.MetricBoundaryCondition, Is.Null);
            Assert.That(updatedMetricAlertConfig1.AlertConditions.SeverityCondition, Is.Null);

            Assert.That(updatedMetricAlertConfig1.AlertSnoozeCondition, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig1.AlertSnoozeCondition.AutoSnooze, Is.EqualTo(4));
            Assert.That(updatedMetricAlertConfig1.AlertSnoozeCondition.SnoozeScope, Is.EqualTo(SnoozeScope.Metric));
            Assert.That(updatedMetricAlertConfig1.AlertSnoozeCondition.IsOnlyForSuccessive, Is.True);

            Assert.That(updatedMetricAlertConfig1.UseDetectionResultToFilterAnomalies, Is.True);
        }
Esempio n. 11
0
        public async Task UpdateAlertConfigurationWithMinimumSetup(bool useTokenCrendential)
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient(useTokenCrendential);

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string metricId = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            await using DisposableDetectionConfiguration disposableDetectionConfig = await CreateTempDetectionConfigurationAsync(adminClient, metricId);

            // Configure the Metric Anomaly Alert Configurations to be used.

            string hookName     = Recording.GenerateAlphaNumericId("hook");
            var    hookToCreate = new EmailNotificationHook(hookName)
            {
                EmailsToAlert = { "*****@*****.**" }
            };

            await using var disposableHook = await DisposableNotificationHook.CreateHookAsync(adminClient, hookToCreate);

            var detectionConfigId  = disposableDetectionConfig.Configuration.Id;
            var scope              = MetricAnomalyAlertScope.GetScopeForWholeSeries();
            var metricAlertConfig0 = new MetricAnomalyAlertConfiguration(detectionConfigId, scope)
            {
                AlertSnoozeCondition = new MetricAnomalyAlertSnoozeCondition(12, SnoozeScope.Series, true),
                AlertConditions      = new MetricAnomalyAlertConditions()
                {
                    MetricBoundaryCondition = new MetricBoundaryCondition(BoundaryDirection.Both)
                    {
                        UpperBound                    = 20.0,
                        LowerBound                    = 10.0,
                        CompanionMetricId             = metricId,
                        ShouldAlertIfDataPointMissing = true
                    },
                    SeverityCondition = new SeverityCondition(AnomalySeverity.Low, AnomalySeverity.Medium)
                }
            };
            var metricAlertConfig1 = new MetricAnomalyAlertConfiguration(detectionConfigId, scope)
            {
                UseDetectionResultToFilterAnomalies = true
            };

            // Create the Anomaly Alert Configuration.

            string configName = Recording.GenerateAlphaNumericId("config");
            var    hookIds    = new List <string>()
            {
                disposableHook.Hook.Id
            };

            var configToCreate = new AnomalyAlertConfiguration()
            {
                Name = configName,
                IdsOfHooksToAlert         = { disposableHook.Hook.Id },
                MetricAlertConfigurations = { metricAlertConfig0, metricAlertConfig1 },
                CrossMetricsOperator      = MetricAnomalyAlertConfigurationsOperator.Xor
            };

            await using var disposableConfig = await DisposableAlertConfiguration.CreateAlertConfigurationAsync(adminClient, configToCreate);

            // Update the created configuration.

            AnomalyAlertConfiguration configToUpdate = disposableConfig.Configuration;

            configToUpdate.CrossMetricsOperator = MetricAnomalyAlertConfigurationsOperator.Or;

            AnomalyAlertConfiguration updatedConfig = await adminClient.UpdateAlertConfigurationAsync(configToUpdate);

            // Validate top-level members.

            Assert.That(updatedConfig.Id, Is.EqualTo(configToUpdate.Id));
            Assert.That(updatedConfig.Name, Is.EqualTo(configName));
            Assert.That(updatedConfig.Description, Is.Empty);
            Assert.That(updatedConfig.CrossMetricsOperator, Is.EqualTo(MetricAnomalyAlertConfigurationsOperator.Or));
            Assert.That(updatedConfig.IdsOfHooksToAlert, Is.EqualTo(hookIds));
            Assert.That(updatedConfig.MetricAlertConfigurations, Is.Not.Null);
            Assert.That(updatedConfig.MetricAlertConfigurations.Count, Is.EqualTo(2));

            // Validate the first Metric Anomaly Alert Configuration.

            MetricAnomalyAlertConfiguration updatedMetricAlertConfig0 = updatedConfig.MetricAlertConfigurations[0];

            Assert.That(updatedMetricAlertConfig0.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(updatedMetricAlertConfig0.AlertScope, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.WholeSeries));
            Assert.That(updatedMetricAlertConfig0.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(updatedMetricAlertConfig0.AlertScope.TopNGroupInScope, Is.Null);

            Assert.That(updatedMetricAlertConfig0.AlertConditions, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.Direction, Is.EqualTo(BoundaryDirection.Both));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.UpperBound, Is.EqualTo(20.0));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.LowerBound, Is.EqualTo(10.0));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.CompanionMetricId, Is.EqualTo(metricId));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.ShouldAlertIfDataPointMissing, Is.True);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.SeverityCondition, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.SeverityCondition.MinimumAlertSeverity, Is.EqualTo(AnomalySeverity.Low));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.SeverityCondition.MaximumAlertSeverity, Is.EqualTo(AnomalySeverity.Medium));

            Assert.That(updatedMetricAlertConfig0.AlertSnoozeCondition, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertSnoozeCondition.AutoSnooze, Is.EqualTo(12));
            Assert.That(updatedMetricAlertConfig0.AlertSnoozeCondition.SnoozeScope, Is.EqualTo(SnoozeScope.Series));
            Assert.That(updatedMetricAlertConfig0.AlertSnoozeCondition.IsOnlyForSuccessive, Is.True);

            Assert.That(updatedMetricAlertConfig0.UseDetectionResultToFilterAnomalies, Is.False);

            // Validate the second Metric Anomaly Alert Configuration.

            MetricAnomalyAlertConfiguration updatedMetricAlertConfig1 = updatedConfig.MetricAlertConfigurations[1];

            Assert.That(updatedMetricAlertConfig1.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(updatedMetricAlertConfig1.AlertScope, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig1.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.WholeSeries));
            Assert.That(updatedMetricAlertConfig1.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(updatedMetricAlertConfig1.AlertScope.TopNGroupInScope, Is.Null);

            Assert.That(updatedMetricAlertConfig1.AlertConditions, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig1.AlertConditions.MetricBoundaryCondition, Is.Null);
            Assert.That(updatedMetricAlertConfig1.AlertConditions.SeverityCondition, Is.Null);
            Assert.That(updatedMetricAlertConfig1.AlertSnoozeCondition, Is.Null);
            Assert.That(updatedMetricAlertConfig1.UseDetectionResultToFilterAnomalies, Is.True);
        }
Esempio n. 12
0
        public async Task CreateAndGetAlertConfigurationWithMultipleMetricConfigurations()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string metricId = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            await using DisposableDetectionConfiguration disposableDetectionConfig = await CreateTempDetectionConfigurationAsync(adminClient, metricId);

            // Configure the Metric Anomaly Alert Configurations to be used.

            var detectionConfigId  = disposableDetectionConfig.Configuration.Id;
            var scope              = MetricAnomalyAlertScope.GetScopeForWholeSeries();
            var metricAlertConfig0 = new MetricAnomalyAlertConfiguration(detectionConfigId, scope)
            {
                AlertConditions = new MetricAnomalyAlertConditions()
                {
                    MetricBoundaryCondition = new MetricBoundaryCondition(BoundaryDirection.Up)
                    {
                        UpperBound = 20.0
                    }
                },
                UseDetectionResultToFilterAnomalies = true
            };
            var metricAlertConfig1 = new MetricAnomalyAlertConfiguration(detectionConfigId, scope)
            {
                AlertConditions = new MetricAnomalyAlertConditions()
                {
                    MetricBoundaryCondition = new MetricBoundaryCondition(BoundaryDirection.Down)
                    {
                        LowerBound = 10.0
                    }
                }
            };

            // Create the Anomaly Alert Configuration.

            string configName = Recording.GenerateAlphaNumericId("config");

            var configToCreate = new AnomalyAlertConfiguration()
            {
                Name = configName,
                MetricAlertConfigurations = { metricAlertConfig0, metricAlertConfig1 },
                CrossMetricsOperator      = MetricAnomalyAlertConfigurationsOperator.Xor
            };

            await using var disposableConfig = await DisposableAlertConfiguration.CreateAlertConfigurationAsync(adminClient, configToCreate);

            // Get the created configuration and validate top-level members.

            AnomalyAlertConfiguration createdConfig = disposableConfig.Configuration;

            Assert.That(createdConfig.Id, Is.Not.Null.And.Not.Empty);
            Assert.That(createdConfig.Name, Is.EqualTo(configName));
            Assert.That(createdConfig.Description, Is.Empty);
            Assert.That(createdConfig.CrossMetricsOperator, Is.EqualTo(MetricAnomalyAlertConfigurationsOperator.Xor));
            Assert.That(createdConfig.IdsOfHooksToAlert, Is.Not.Null.And.Empty);
            Assert.That(createdConfig.MetricAlertConfigurations, Is.Not.Null);
            Assert.That(createdConfig.MetricAlertConfigurations.Count, Is.EqualTo(2));

            // Validate the first Metric Anomaly Alert Configuration.

            MetricAnomalyAlertConfiguration createdMetricAlertConfig0 = createdConfig.MetricAlertConfigurations[0];

            Assert.That(createdMetricAlertConfig0.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(createdMetricAlertConfig0.AlertScope, Is.Not.Null);
            Assert.That(createdMetricAlertConfig0.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.WholeSeries));
            Assert.That(createdMetricAlertConfig0.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(createdMetricAlertConfig0.AlertScope.TopNGroupInScope, Is.Null);

            Assert.That(createdMetricAlertConfig0.AlertConditions, Is.Not.Null);
            Assert.That(createdMetricAlertConfig0.AlertConditions.MetricBoundaryCondition, Is.Not.Null);
            Assert.That(createdMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.Direction, Is.EqualTo(BoundaryDirection.Up));
            Assert.That(createdMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.UpperBound, Is.EqualTo(20.0));
            Assert.That(createdMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.LowerBound, Is.Null);
            Assert.That(createdMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.CompanionMetricId, Is.Null);
            Assert.That(createdMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.ShouldAlertIfDataPointMissing, Is.False);
            Assert.That(createdMetricAlertConfig0.AlertConditions.SeverityCondition, Is.Null);

            Assert.That(createdMetricAlertConfig0.AlertSnoozeCondition, Is.Null);
            Assert.That(createdMetricAlertConfig0.UseDetectionResultToFilterAnomalies, Is.True);

            // Validate the second Metric Anomaly Alert Configuration.

            MetricAnomalyAlertConfiguration createdMetricAlertConfig1 = createdConfig.MetricAlertConfigurations[1];

            Assert.That(createdMetricAlertConfig1.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(createdMetricAlertConfig1.AlertScope, Is.Not.Null);
            Assert.That(createdMetricAlertConfig1.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.WholeSeries));
            Assert.That(createdMetricAlertConfig1.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(createdMetricAlertConfig1.AlertScope.TopNGroupInScope, Is.Null);

            Assert.That(createdMetricAlertConfig1.AlertConditions, Is.Not.Null);
            Assert.That(createdMetricAlertConfig1.AlertConditions.MetricBoundaryCondition, Is.Not.Null);
            Assert.That(createdMetricAlertConfig1.AlertConditions.MetricBoundaryCondition.Direction, Is.EqualTo(BoundaryDirection.Down));
            Assert.That(createdMetricAlertConfig1.AlertConditions.MetricBoundaryCondition.UpperBound, Is.Null);
            Assert.That(createdMetricAlertConfig1.AlertConditions.MetricBoundaryCondition.LowerBound, Is.EqualTo(10.0));
            Assert.That(createdMetricAlertConfig1.AlertConditions.MetricBoundaryCondition.CompanionMetricId, Is.Null);
            Assert.That(createdMetricAlertConfig1.AlertConditions.MetricBoundaryCondition.ShouldAlertIfDataPointMissing, Is.False);
            Assert.That(createdMetricAlertConfig1.AlertConditions.SeverityCondition, Is.Null);

            Assert.That(createdMetricAlertConfig1.AlertSnoozeCondition, Is.Null);
            Assert.That(createdMetricAlertConfig1.UseDetectionResultToFilterAnomalies, Is.False);
        }
Esempio n. 13
0
        public async Task CreateAndGetAlertConfigurationWithOptionalSingleMetricConfigurationMembers()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string metricId = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            await using DisposableDetectionConfiguration disposableDetectionConfig = await CreateTempDetectionConfigurationAsync(adminClient, metricId);

            string hookName0 = Recording.GenerateAlphaNumericId("hook");
            string hookName1 = Recording.GenerateAlphaNumericId("hook");

            var hookToCreate0 = new EmailNotificationHook(hookName0);
            var hookToCreate1 = new EmailNotificationHook(hookName1);

            hookToCreate0.EmailsToAlert.Add("*****@*****.**");
            hookToCreate1.EmailsToAlert.Add("*****@*****.**");

            await using var disposableHook0 = await DisposableNotificationHook.CreateHookAsync(adminClient, hookToCreate0);

            await using var disposableHook1 = await DisposableNotificationHook.CreateHookAsync(adminClient, hookToCreate1);

            var detectionConfigId = disposableDetectionConfig.Configuration.Id;
            var scope             = MetricAnomalyAlertScope.GetScopeForWholeSeries();
            var metricAlertConfig = new MetricAnomalyAlertConfiguration(detectionConfigId, scope)
            {
                AlertSnoozeCondition = new MetricAnomalyAlertSnoozeCondition(12, SnoozeScope.Series, true),
                AlertConditions      = new MetricAnomalyAlertConditions()
                {
                    MetricBoundaryCondition = new MetricBoundaryCondition(BoundaryDirection.Both)
                    {
                        UpperBound                    = 20.0,
                        LowerBound                    = 10.0,
                        CompanionMetricId             = metricId,
                        ShouldAlertIfDataPointMissing = true
                    },
                    SeverityCondition = new SeverityCondition(AnomalySeverity.Low, AnomalySeverity.Medium)
                }
            };

            string configName  = Recording.GenerateAlphaNumericId("config");
            var    description = "This hook was created to test the .NET client.";

            var configToCreate = new AnomalyAlertConfiguration()
            {
                Name = configName,
                IdsOfHooksToAlert         = { disposableHook0.Hook.Id, disposableHook1.Hook.Id },
                MetricAlertConfigurations = { metricAlertConfig },
                Description = description
            };

            await using var disposableConfig = await DisposableAlertConfiguration.CreateAlertConfigurationAsync(adminClient, configToCreate);

            AnomalyAlertConfiguration createdConfig = disposableConfig.Configuration;

            Assert.That(createdConfig.Id, Is.Not.Null.And.Not.Empty);
            Assert.That(createdConfig.Name, Is.EqualTo(configName));
            Assert.That(createdConfig.Description, Is.EqualTo(description));
            Assert.That(createdConfig.CrossMetricsOperator, Is.Null);
            Assert.That(createdConfig.IdsOfHooksToAlert.Count, Is.EqualTo(2));
            Assert.That(createdConfig.IdsOfHooksToAlert.Contains(disposableHook0.Hook.Id));
            Assert.That(createdConfig.IdsOfHooksToAlert.Contains(disposableHook1.Hook.Id));
            Assert.That(createdConfig.MetricAlertConfigurations, Is.Not.Null);

            MetricAnomalyAlertConfiguration createdMetricAlertConfig = createdConfig.MetricAlertConfigurations.Single();

            Assert.That(createdMetricAlertConfig.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(createdMetricAlertConfig.AlertScope, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.WholeSeries));
            Assert.That(createdMetricAlertConfig.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(createdMetricAlertConfig.AlertScope.TopNGroupInScope, Is.Null);

            Assert.That(createdMetricAlertConfig.AlertConditions, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition.Direction, Is.EqualTo(BoundaryDirection.Both));
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition.UpperBound, Is.EqualTo(20.0));
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition.LowerBound, Is.EqualTo(10.0));
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition.CompanionMetricId, Is.EqualTo(metricId));
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition.ShouldAlertIfDataPointMissing, Is.True);
            Assert.That(createdMetricAlertConfig.AlertConditions.SeverityCondition, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertConditions.SeverityCondition.MinimumAlertSeverity, Is.EqualTo(AnomalySeverity.Low));
            Assert.That(createdMetricAlertConfig.AlertConditions.SeverityCondition.MaximumAlertSeverity, Is.EqualTo(AnomalySeverity.Medium));

            Assert.That(createdMetricAlertConfig.AlertSnoozeCondition, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertSnoozeCondition.AutoSnooze, Is.EqualTo(12));
            Assert.That(createdMetricAlertConfig.AlertSnoozeCondition.SnoozeScope, Is.EqualTo(SnoozeScope.Series));
            Assert.That(createdMetricAlertConfig.AlertSnoozeCondition.IsOnlyForSuccessive, Is.True);

            Assert.That(createdMetricAlertConfig.UseDetectionResultToFilterAnomalies, Is.False);
        }