예제 #1
0
    public async void ExecuteAsync_ReplicaHealthReportDisabled_ReplicasHealthIsNotReported()
    {
        _scenarioOptions = new ServiceFabricDiscoveryOptions {
            ReportReplicasHealth = false
        };
        const string       TestClusterId = "MyService123";
        var                labels        = SFTestHelpers.DummyLabels(TestClusterId);
        ApplicationWrapper application;

        Mock_AppsResponse(
            application = CreateApp_1Service_SingletonPartition_1Replica("MyApp", "MYService", out var service, out var replica, out var partition));
        Mock_ServiceLabels(application, service, labels);

        var(routes, clusters) = await RunScenarioAsync();

        var expectedClusters = new[]
        {
            ClusterWithDestinations(_testServiceName, labels,
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica, partition)),
        };
        var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, labels);

        clusters.Should().BeEquivalentTo(expectedClusters);
        routes.Should().BeEquivalentTo(expectedRoutes);
        AssertServiceHealthReported(service, HealthState.Ok);
        _healthReports.Should().HaveCount(1);
    }
예제 #2
0
    public async void ExecuteAsync_StatefulService_SelectReplicaWork(string selectionMode, ReplicaRole?replicaRole)
    {
        _scenarioOptions = new ServiceFabricDiscoveryOptions {
            ReportReplicasHealth = true
        };
        const string TestClusterId = "MyService123";
        var          labels        = SFTestHelpers.DummyLabels(TestClusterId);

        labels["YARP.Backend.ServiceFabric.StatefulReplicaSelectionMode"] = selectionMode;
        ApplicationWrapper application;

        Mock_AppsResponse(application = CreateApp_1Service_SingletonPartition_1Replica("MyApp", "MYService", out var service, out var replica, out var partition, serviceKind: ServiceKind.Stateful));
        Mock_ServiceLabels(application, service, labels);
        replica.ServiceKind = ServiceKind.Stateful;
        replica.Role        = replicaRole;

        var(_, clusters) = await RunScenarioAsync();

        var expectedClusters = new[]
        {
            ClusterWithDestinations(_testServiceName, labels,
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica, partition)),
        };

        clusters.Should().BeEquivalentTo(expectedClusters);
        _healthReports.Should().HaveCount(2);
    }
예제 #3
0
    public async void ExecuteAsync_ValidListenerNameForStatelessService_Work()
    {
        _scenarioOptions = new ServiceFabricDiscoveryOptions {
            ReportReplicasHealth = true
        };
        const string TestClusterId = "MyService123";
        var          labels        = SFTestHelpers.DummyLabels(TestClusterId);

        labels["YARP.Backend.ServiceFabric.ListenerName"] = "ExampleTeamEndpoint";
        labels["YARP.Backend.HealthCheck.Active.ServiceFabric.ListenerName"] = "ExampleTeamHealthEndpoint";
        ApplicationWrapper application;

        Mock_AppsResponse(
            application        = CreateApp_1Service_SingletonPartition_1Replica("MyApp", "MyService", out var service, out var replica, out var partition, serviceKind: ServiceKind.Stateless));
        replica.ReplicaAddress = MockReplicaAdressWithListenerName("MyApp", "MyService", new string[] { "ExampleTeamEndpoint", "ExampleTeamHealthEndpoint" });
        Mock_ServiceLabels(application, service, labels);

        var(routes, clusters) = await RunScenarioAsync();

        var expectedClusters = new[]
        {
            ClusterWithDestinations(_testServiceName, labels,
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica, partition, "ExampleTeamHealthEndpoint")),
        };
        var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, labels);

        clusters.Should().BeEquivalentTo(expectedClusters);
        routes.Should().BeEquivalentTo(expectedRoutes);
        AssertServiceHealthReported(service, HealthState.Ok);
        AssertStatelessServiceInstanceHealthReported(replica, HealthState.Ok, (description) =>
                                                     description.StartsWith("Successfully built"));
        _healthReports.Should().HaveCount(2);
    }
예제 #4
0
    public async void ExecuteAsync_InvalidRouteOrder_NoRoutesAndBadHealthReported()
    {
        _scenarioOptions = new ServiceFabricDiscoveryOptions {
            ReportReplicasHealth = true
        };
        var labels = new Dictionary <string, string>()
        {
            { "YARP.Enable", "true" },
            { "YARP.Backend.BackendId", "SomeClusterId" },
            { "YARP.Routes.MyRoute.Hosts", "example.com" },
            { "YARP.Routes.MyRoute.Order", "not a number" },
        };
        ApplicationWrapper application;

        Mock_AppsResponse(
            application = CreateApp_1Service_SingletonPartition_1Replica("MyApp", "MyService", out var service, out var replica, out var partition));

        Mock_ServiceLabels(application, service, labels);

        var(routes, clusters) = await RunScenarioAsync();

        var expectedClusters = new[]
        {
            ClusterWithDestinations(_testServiceName, labels,
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica, partition)),
        };
        var expectedRoutes = new List <RouteConfig>();

        clusters.Should().BeEquivalentTo(expectedClusters);
        routes.Should().BeEmpty();
        AssertServiceHealthReported(service, HealthState.Warning, (description) =>
                                    description.Contains("Order")); // Check that the invalid key is mentioned in the description
        _healthReports.Should().HaveCount(2);
    }
예제 #5
0
    public async void ExecuteAsync_OneServiceWithGatewayEnabledAndOneNotEnabled_OnlyTheOneEnabledFound()
    {
        _scenarioOptions = new ServiceFabricDiscoveryOptions {
            ReportReplicasHealth = true
        };
        const string       TestClusterIdApp1Sv1 = "MyService123";
        const string       TestClusterIdApp2Sv2 = "MyService234";
        var                gatewayEnabledLabels = SFTestHelpers.DummyLabels(TestClusterIdApp1Sv1);
        var                gatewayNotEnabledLabels = SFTestHelpers.DummyLabels(TestClusterIdApp2Sv2, false);
        ApplicationWrapper application1, application2;

        Mock_AppsResponse(
            application1 = CreateApp_1Service_SingletonPartition_1Replica("MyApp", "MyService1", out var service1, out var replica1, out var partition1),
            application2 = CreateApp_1Service_SingletonPartition_1Replica("MyApp2", "MyService2", out var service2, out var replica2, out var partition2));

        Mock_ServiceLabels(application1, service1, gatewayEnabledLabels);
        Mock_ServiceLabels(application2, service2, gatewayNotEnabledLabels);

        var(routes, clusters) = await RunScenarioAsync();

        var expectedClusters = new[]
        {
            ClusterWithDestinations(_testServiceName, gatewayEnabledLabels,
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica1, partition1)),
        };
        var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, gatewayEnabledLabels);

        clusters.Should().BeEquivalentTo(expectedClusters);
        routes.Should().BeEquivalentTo(expectedRoutes);
        AssertServiceHealthReported(service1, HealthState.Ok);
        AssertStatelessServiceInstanceHealthReported(replica1, HealthState.Ok);
        _healthReports.Should().HaveCount(2);
    }
예제 #6
0
    public async void ExecuteAsync_SingleServiceWithGatewayEnabledAndActiveHealthCheck()
    {
        _scenarioOptions = new ServiceFabricDiscoveryOptions();
        const string       TestClusterId = "MyService123";
        var                labels        = SFTestHelpers.DummyLabels(TestClusterId, activeHealthChecks: true);
        ApplicationWrapper application;

        Mock_AppsResponse(
            application = CreateApp_1StatelessService_2Partition_2ReplicasEach("MyApp", "MYService", out var service, out var replicas, out var partitions));
        Mock_ServiceLabels(application, service, labels);

        var(routes, clusters) = await RunScenarioAsync();

        var expectedClusters = new[]
        {
            ClusterWithDestinations(_testServiceName, labels,
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[0], partitions[0]),
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[1], partitions[0]),
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[2], partitions[1]),
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[3], partitions[1])),
        };
        var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, labels);

        routes.Should().BeEquivalentTo(expectedRoutes);
        clusters.Should().BeEquivalentTo(expectedClusters);
        AssertServiceHealthReported(service, HealthState.Ok);
        _healthReports.Should().HaveCount(1);
    }
예제 #7
0
    public async void ExecuteAsync_SomeUnhealthyReplicas_OnlyHealthyReplicasAreUsed()
    {
        _scenarioOptions = new ServiceFabricDiscoveryOptions {
            ReportReplicasHealth = true
        };
        const string       TestClusterId = "MyService123";
        var                labels        = SFTestHelpers.DummyLabels(TestClusterId);
        ApplicationWrapper application;

        Mock_AppsResponse(
            application = CreateApp_1StatelessService_2Partition_2ReplicasEach(
                "MyApp",
                "MYService",
                out var service,
                out var replicas,
                out var partitions));
        Mock_ServiceLabels(application, service, labels);

        replicas[0].ReplicaStatus = ServiceReplicaStatus.Ready; // Should be used despite Warning health state
        replicas[0].HealthState   = HealthState.Warning;

        replicas[1].ReplicaStatus = ServiceReplicaStatus.Ready; // Should be used
        replicas[1].HealthState   = HealthState.Ok;

        replicas[2].ReplicaStatus = ServiceReplicaStatus.Ready; // Should be used despite Error health state
        replicas[2].HealthState   = HealthState.Error;

        replicas[3].ReplicaStatus = ServiceReplicaStatus.Down; // Should be skipped because of status
        replicas[3].HealthState   = HealthState.Ok;

        var(routes, clusters) = await RunScenarioAsync();

        var expectedClusters = new[]
        {
            ClusterWithDestinations(_testServiceName, labels,
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[0], partitions[0]),
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[1], partitions[0]),
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[2], partitions[1])),
        };
        var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, labels);

        clusters.Should().BeEquivalentTo(expectedClusters);
        routes.Should().BeEquivalentTo(expectedRoutes);
        AssertServiceHealthReported(service, HealthState.Ok);
        AssertStatelessServiceInstanceHealthReported(replicas[0], HealthState.Ok);
        AssertStatelessServiceInstanceHealthReported(replicas[1], HealthState.Ok);
        AssertStatelessServiceInstanceHealthReported(replicas[2], HealthState.Ok);
        _healthReports.Should().HaveCount(4); // 1 service + 3 replicas = 4 health reports
    }
예제 #8
0
    public async void ExecuteAsync_MultipleServicesWithGatewayEnabled_MultipleClustersFound()
    {
        _scenarioOptions = new ServiceFabricDiscoveryOptions {
            ReportReplicasHealth = true
        };
        const string       TestClusterIdApp1Sv1 = "MyService123";
        const string       TestClusterIdApp1Sv2 = "MyService234";
        const string       TestClusterIdApp2Sv3 = "MyService345";
        var                labels1 = SFTestHelpers.DummyLabels(TestClusterIdApp1Sv1);
        var                labels2 = SFTestHelpers.DummyLabels(TestClusterIdApp1Sv2);
        var                labels3 = SFTestHelpers.DummyLabels(TestClusterIdApp2Sv3);
        ApplicationWrapper application1, application2;

        Mock_AppsResponse(
            application1 = CreateApp_1Service_SingletonPartition_1Replica("MyApp", "MYService", out var service1, out var replica1, out var partition1),
            application2 = CreateApp_2StatelessService_SingletonPartition_1Replica("MyApp2", "MyService2", "MyService3", out var service2, out var service3, out var replica2, out var replica3, out var partition2, out var partition3));

        Mock_ServiceLabels(application1, service1, labels1);
        Mock_ServiceLabels(application2, service2, labels2);
        Mock_ServiceLabels(application2, service3, labels3);

        var(routes, clusters) = await RunScenarioAsync();

        var expectedClusters = new[]
        {
            ClusterWithDestinations(_testServiceName, labels1,
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica1, partition1)),
            ClusterWithDestinations(_testServiceName, labels2,
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica2, partition2)),
            ClusterWithDestinations(_testServiceName, labels3,
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica3, partition3)),
        };
        var expectedRoutes = new List <RouteConfig>();

        expectedRoutes.AddRange(LabelsParser.BuildRoutes(_testServiceName, labels1));
        expectedRoutes.AddRange(LabelsParser.BuildRoutes(_testServiceName, labels2));
        expectedRoutes.AddRange(LabelsParser.BuildRoutes(_testServiceName, labels3));

        clusters.Should().BeEquivalentTo(expectedClusters);
        routes.Should().BeEquivalentTo(expectedRoutes);
        AssertServiceHealthReported(service1, HealthState.Ok);
        AssertServiceHealthReported(service2, HealthState.Ok);
        AssertServiceHealthReported(service3, HealthState.Ok);
        AssertStatelessServiceInstanceHealthReported(replica1, HealthState.Ok);
        AssertStatelessServiceInstanceHealthReported(replica2, HealthState.Ok);
        AssertStatelessServiceInstanceHealthReported(replica3, HealthState.Ok);
        _healthReports.Should().HaveCount(6);
    }
예제 #9
0
    public async void ExecuteAsync_SingleServiceWithGatewayEnabled_OneClusterFound()
    {
        _scenarioOptions = new ServiceFabricDiscoveryOptions {
            ReportReplicasHealth = true
        };
        const string       TestClusterId = "MyService123";
        var                labels = SFTestHelpers.DummyLabels(TestClusterId);
        ApplicationWrapper application, anotherApplication;

        Mock_AppsResponse(
            application        = CreateApp_1StatelessService_2Partition_2ReplicasEach("MyApp", "MYService", out var service, out var replicas, out var partitions),
            anotherApplication = CreateApp_1StatelessService_2Partition_2ReplicasEach("AnotherApp", "AnotherService", out var anotherService, out var otherReplicas, out var otherPartitions));
        Mock_ServiceLabels(application, service, labels);
        Mock_ServiceLabels(anotherApplication, anotherService, new Dictionary <string, string>());

        var(routes, clusters) = await RunScenarioAsync();

        var expectedClusters = new[]
        {
            ClusterWithDestinations(_testServiceName, labels,
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[0], partitions[0]),
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[1], partitions[0]),
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[2], partitions[1]),
                                    SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[3], partitions[1])),
        };
        var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, labels);

        routes.Should().BeEquivalentTo(expectedRoutes);
        clusters.Should().BeEquivalentTo(expectedClusters);
        AssertServiceHealthReported(service, HealthState.Ok);
        foreach (var replica in replicas)
        {
            AssertStatelessServiceInstanceHealthReported(replica, HealthState.Ok);
        }
        _healthReports.Should().HaveCount(5);
    }