Testbarhetsåtgärder

För att simulera en otillförlitlig infrastruktur ger Azure Service Fabric dig, utvecklaren, sätt att simulera olika verkliga fel och tillståndsövergångar. Dessa exponeras som testbarhetsåtgärder. Åtgärderna är de lågnivå-API:er som orsakar en specifik felinmatning, tillståndsövergång eller validering. Genom att kombinera dessa åtgärder kan du skriva omfattande testscenarier för dina tjänster.

Service Fabric innehåller några vanliga testscenarier som består av dessa åtgärder. Vi rekommenderar starkt att du använder dessa inbyggda scenarier, som väljs noggrant för att testa vanliga tillståndsövergångar och felfall. Åtgärder kan dock användas för att skapa anpassade testscenarier när du vill lägga till täckning för scenarier som inte omfattas av de inbyggda scenarierna ännu eller som är anpassade för ditt program.

C#-implementeringar av åtgärderna finns i System.Fabric.dll sammansättning. System Fabric PowerShell-modulen finns i den Microsoft.ServiceFabric.Powershell.dll sammansättningen. Som en del av körningsinstallationen installeras ServiceFabric PowerShell-modulen för att underlätta användningen.

Graciösa kontra ospårbara felåtgärder

Testbarhetsåtgärder klassificeras i två större bucketar:

  • Felaktiga fel: Dessa fel simulerar fel som omstarter av datorer och processkrascher. I sådana fall av fel stoppas körningskontexten för processen plötsligt. Det innebär att ingen rensning av tillståndet kan köras innan programmet startas igen.
  • Graciösa fel: Dessa fel simulerar graciösa åtgärder som replikflyttningar och droppar som utlöses av belastningsutjämning. I sådana fall får tjänsten ett meddelande om stängningen och kan rensa tillståndet innan det avslutas.

För bättre kvalitetsverifiering kör du tjänst- och företagsarbetsbelastningen samtidigt som du skapar olika graciösa och ospårbara fel. Scenarier med felaktiga fel där tjänstprocessen plötsligt avslutas mitt i ett arbetsflöde. Detta testar återställningssökvägen när tjänstrepliken har återställts av Service Fabric. Detta hjälper till att testa datakonsekvens och om tjänsttillståndet underhålls korrekt efter fel. Den andra uppsättningen fel (de graciösa felen) testar att tjänsten reagerar korrekt på repliker som flyttas runt av Service Fabric. Detta testar hanteringen av annullering i RunAsync-metoden. Tjänsten måste söka efter den annulleringstoken som anges, spara dess tillstånd korrekt och avsluta Metoden RunAsync.

Lista över testbarhetsåtgärder

Åtgärd beskrivning Hanterat API PowerShell-cmdlet Graciösa/ospårbara fel
CleanTestState Tar bort alla testtillstånd från klustret i händelse av en felaktig avstängning av testdrivrutinen. CleanTestStateAsync Remove-ServiceFabricTestState Inte tillämpligt
InvokeDataLoss Inducerar dataförlust i en tjänstpartition. InvokeDataLossAsync Invoke-ServiceFabricPartitionDataLoss Elegant
InvokeQuorumLoss Placerar en viss tillståndskänslig tjänstpartition i kvorumförlust. InvokeQuorumLossAsync Invoke-ServiceFabricQuorumLoss Elegant
MovePrimary Flyttar den angivna primära repliken av en tillståndskänslig tjänst till den angivna klusternoden. MovePrimaryAsync Move-ServiceFabricPrimaryReplica Elegant
MoveSecondary Flyttar den aktuella sekundära repliken av en tillståndskänslig tjänst till en annan klusternod. MoveSecondaryAsync Move-ServiceFabricSecondaryReplica Elegant
MoveInstance Flyttar den aktuella instansen av en tillståndslös tjänst till en annan klusternod. MoveInstanceAsync Move-ServiceFabricInstance Elegant
RemoveReplica Simulerar ett replikfel genom att ta bort en replik från ett kluster. Då stängs repliken och den övergår till rollen "Ingen", vilket tar bort hela dess tillstånd från klustret. RemoveReplicaAsync Remove-ServiceFabricReplica Elegant
RestartDeployedCodePackage Simulerar ett fel i kodpaketets process genom att starta om ett kodpaket som distribuerats på en nod i ett kluster. Detta avbryter kodpaketprocessen, som startar om alla användartjänstrepliker som finns i den processen. RestartDeployedCodePackageAsync Restart-ServiceFabricDeployedCodePackage Ospårbar
RestartNode Simulerar ett Service Fabric-klusternodfel genom att starta om en nod. RestartNodeAsync Restart-ServiceFabricNode Ospårbar
RestartPartition Simulerar ett blackout- eller klusteravbrottsscenario genom att starta om vissa eller alla repliker av en partition. RestartPartitionAsync Restart-ServiceFabricPartition Elegant
RestartReplica Simulerar ett replikfel genom att starta om en bevarad replik i ett kluster, stänga repliken och sedan öppna den igen. RestartReplicaAsync Restart-ServiceFabricReplica Elegant
Startnod Startar en nod i ett kluster som redan har stoppats. StartNodeAsync Start-ServiceFabricNode Inte tillämpligt
StopNode Simulerar ett nodfel genom att stoppa en nod i ett kluster. Noden förblir nere tills StartNode anropas. StopNodeAsync Stop-ServiceFabricNode Ospårbar
ValidateApplication Verifierar tillgängligheten och hälsotillståndet för alla Service Fabric-tjänster i ett program, vanligtvis efter att ha framkallat ett fel i systemet. ValidateApplicationAsync Test-ServiceFabricApplication Inte tillämpligt
ValidateService Verifierar tillgängligheten och hälsotillståndet för en Service Fabric-tjänst, vanligtvis efter att ha framkallat ett fel i systemet. ValidateServiceAsync Test-ServiceFabricService Inte tillämpligt

Köra en testbarhetsåtgärd med PowerShell

Den här självstudien visar hur du kör en testbarhetsåtgärd med hjälp av PowerShell. Du får lära dig hur du kör en testbarhetsåtgärd mot ett lokalt (enstaka) kluster eller ett Azure-kluster. Microsoft.Fabric.Powershell.dll– Service Fabric PowerShell-modulen – installeras automatiskt när du installerar Microsoft Service Fabric MSI. Modulen läses in automatiskt när du öppnar en PowerShell-prompt.

Självstudiesegment:

Köra en åtgärd mot ett one-box-kluster

Om du vill köra en testbarhetsåtgärd mot ett lokalt kluster ansluter du först till klustret och öppnar PowerShell-prompten i administratörsläge. Låt oss titta på åtgärden Restart-ServiceFabricNode .

Restart-ServiceFabricNode -NodeName Node1 -CompletionMode DoNotVerify

Här körs åtgärden Restart-ServiceFabricNode på en nod med namnet "Node1". Slutförandeläget anger att den inte ska verifiera om åtgärden restart-node faktiskt lyckades. Om du anger slutförandeläge som "Verifiera" kommer den att verifiera om omstartsåtgärden lyckades. I stället för att ange noden direkt med dess namn kan du ange den via en partitionsnyckel och typen av replik enligt följande:

Restart-ServiceFabricNode -ReplicaKindPrimary  -PartitionKindNamed -PartitionKey Partition3 -CompletionMode Verify
$connection = "localhost:19000"
$nodeName = "Node1"

Connect-ServiceFabricCluster $connection
Restart-ServiceFabricNode -NodeName $nodeName -CompletionMode DoNotVerify

Restart-ServiceFabricNode ska användas för att starta om en Service Fabric-nod i ett kluster. Detta stoppar Fabric.exe processen, som startar om alla systemtjänst- och användartjänstrepliker som finns på den noden. Genom att använda det här API:et för att testa din tjänst kan du upptäcka buggar längs återställningsvägarna för redundans. Det hjälper till att simulera nodfel i klustret.

Följande skärmbild visar testbarhetskommandot Restart-ServiceFabricNode i praktiken.

Skärmbild av körning av kommandot Restart-ServiceFabricNode i PowerShell.

Utdata från den första Get-ServiceFabricNode (en cmdlet från Service Fabric PowerShell-modulen) visar att det lokala klustret har fem noder: Node.1 till Node.5. När teståtgärden (cmdlet) Restart-ServiceFabricNode har körts på noden med namnet Node.4 ser vi att nodens drifttid har återställts.

Köra en åtgärd mot ett Azure-kluster

Att köra en testbarhetsåtgärd (med hjälp av PowerShell) mot ett Azure-kluster liknar att köra åtgärden mot ett lokalt kluster. Den enda skillnaden är att innan du kan köra åtgärden måste du först ansluta till Azure-klustret i stället för att ansluta till det lokala klustret.

Köra en testbarhetsåtgärd med C#

Om du vill köra en testbarhetsåtgärd med hjälp av C# måste du först ansluta till klustret med hjälp av FabricClient. Hämta sedan de parametrar som behövs för att köra åtgärden. Olika parametrar kan användas för att köra samma åtgärd. Om du tittar på åtgärden RestartServiceFabricNode är ett sätt att köra den genom att använda nodinformationen (nodnamn och nodinstans-ID) i klustret.

RestartNodeAsync(nodeName, nodeInstanceId, completeMode, operationTimeout, CancellationToken.None)

Parameterförklaring:

  • CompleteMode anger att läget inte ska verifiera om omstartsåtgärden lyckades. Om du anger slutförandeläge som "Verifiera" kommer den att verifiera om omstartsåtgärden lyckades.
  • OperationTimeout anger hur lång tid åtgärden ska slutföras innan ett TimeoutException-undantag utlöses.
  • CancellationToken gör att ett väntande samtal kan avbrytas.

I stället för att ange noden direkt med dess namn kan du ange den via en partitionsnyckel och typen av replik.

Mer information finns i PartitionSelector och ReplicaSelector.

// Add a reference to System.Fabric.Testability.dll and System.Fabric.dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Fabric.Testability;
using System.Fabric;
using System.Threading;
using System.Numerics;

class Test
{
    public static int Main(string[] args)
    {
        string clusterConnection = "localhost:19000";
        Uri serviceName = new Uri("fabric:/samples/PersistentToDoListApp/PersistentToDoListService");
        string nodeName = "N0040";
        BigInteger nodeInstanceId = 130743013389060139;

        Console.WriteLine("Starting RestartNode test");
        try
        {
            //Restart the node by using ReplicaSelector
            RestartNodeAsync(clusterConnection, serviceName).Wait();

            //Another way to restart node is by using nodeName and nodeInstanceId
            RestartNodeAsync(clusterConnection, nodeName, nodeInstanceId).Wait();
        }
        catch (AggregateException exAgg)
        {
            Console.WriteLine("RestartNode did not complete: ");
            foreach (Exception ex in exAgg.InnerExceptions)
            {
                if (ex is FabricException)
                {
                    Console.WriteLine("HResult: {0} Message: {1}", ex.HResult, ex.Message);
                }
            }
            return -1;
        }

        Console.WriteLine("RestartNode completed.");
        return 0;
    }

    static async Task RestartNodeAsync(string clusterConnection, Uri serviceName)
    {
        PartitionSelector randomPartitionSelector = PartitionSelector.RandomOf(serviceName);
        ReplicaSelector primaryofReplicaSelector = ReplicaSelector.PrimaryOf(randomPartitionSelector);

        // Create FabricClient with connection and security information here
        FabricClient fabricclient = new FabricClient(clusterConnection);
        await fabricclient.FaultManager.RestartNodeAsync(primaryofReplicaSelector, CompletionMode.Verify);
    }

    static async Task RestartNodeAsync(string clusterConnection, string nodeName, BigInteger nodeInstanceId)
    {
        // Create FabricClient with connection and security information here
        FabricClient fabricclient = new FabricClient(clusterConnection);
        await fabricclient.FaultManager.RestartNodeAsync(nodeName, nodeInstanceId, CompletionMode.Verify);
    }
}

PartitionSelector och ReplicaSelector

PartitionSelector

PartitionSelector är en hjälpare som exponeras i testbarhet och används för att välja en specifik partition där någon av testbarhetsåtgärderna ska utföras. Den kan användas för att välja en specifik partition om partitions-ID:t är känt i förväg. Eller så kan du ange partitionsnyckeln så löser åtgärden partitions-ID:t internt. Du kan också välja en slumpmässig partition.

Om du vill använda den här hjälpen skapar du PartitionSelector-objektet och väljer partitionen med någon av metoderna Välj* . Skicka sedan in PartitionSelector-objektet till det API som kräver det. Om inget alternativ har valts är det som standard en slumpmässig partition.

Uri serviceName = new Uri("fabric:/samples/InMemoryToDoListApp/InMemoryToDoListService");
Guid partitionIdGuid = new Guid("8fb7ebcc-56ee-4862-9cc0-7c6421e68829");
string partitionName = "Partition1";
Int64 partitionKeyUniformInt64 = 1;

// Select a random partition
PartitionSelector randomPartitionSelector = PartitionSelector.RandomOf(serviceName);

// Select a partition based on ID
PartitionSelector partitionSelectorById = PartitionSelector.PartitionIdOf(serviceName, partitionIdGuid);

// Select a partition based on name
PartitionSelector namedPartitionSelector = PartitionSelector.PartitionKeyOf(serviceName, partitionName);

// Select a partition based on partition key
PartitionSelector uniformIntPartitionSelector = PartitionSelector.PartitionKeyOf(serviceName, partitionKeyUniformInt64);

ReplicaSelector

ReplicaSelector är en hjälpare som exponeras i testbarhet och används för att välja en replik där någon av testbarhetsåtgärderna ska utföras. Den kan användas för att välja en specifik replik om replik-ID:t är känt i förväg. Dessutom kan du välja en primär replik eller en slumpmässig sekundär replik. ReplicaSelector härleds från PartitionSelector, så du måste välja både repliken och partitionen som du vill utföra testbarhetsåtgärden på.

Om du vill använda den här hjälpen skapar du ett ReplicaSelector-objekt och anger hur du vill välja repliken och partitionen. Du kan sedan skicka det till api:et som kräver det. Om inget alternativ har valts är den som standard en slumpmässig replik och slumpmässig partition.

Guid partitionIdGuid = new Guid("8fb7ebcc-56ee-4862-9cc0-7c6421e68829");
PartitionSelector partitionSelector = PartitionSelector.PartitionIdOf(serviceName, partitionIdGuid);
long replicaId = 130559876481875498;

// Select a random replica
ReplicaSelector randomReplicaSelector = ReplicaSelector.RandomOf(partitionSelector);

// Select the primary replica
ReplicaSelector primaryReplicaSelector = ReplicaSelector.PrimaryOf(partitionSelector);

// Select the replica by ID
ReplicaSelector replicaByIdSelector = ReplicaSelector.ReplicaIdOf(partitionSelector, replicaId);

// Select a random secondary replica
ReplicaSelector secondaryReplicaSelector = ReplicaSelector.RandomSecondaryOf(partitionSelector);

Nästa steg