Azioni di TestabilitàTestability actions

Per simulare un'infrastruttura non affidabile, Azure Service Fabric offre agli sviluppatori la possibilità di simulare errori e transizioni di stato reali,In order to simulate an unreliable infrastructure, Azure Service Fabric provides you, the developer, with ways to simulate various real-world failures and state transitions. esposti come azioni di testabilità.These are exposed as testability actions. Le azioni sono le API di basso livello che causano una specifica fault injection, una transizione di stato o una convalida.The actions are the low-level APIs that cause a specific fault injection, state transition, or validation. La combinazione di queste azioni consente di scrivere scenari di test completi per i servizi.By combining these actions, you can write comprehensive test scenarios for your services.

Service Fabric fornisce alcuni scenari di test comuni costituiti da queste azioni.Service Fabric provides some common test scenarios composed of these actions. È consigliabile usare questi scenari predefiniti, poiché vengono scelti con attenzione per testare le transizioni di stato e i casi di errore comuni.We highly recommend that you utilize these built-in scenarios, which are carefully chosen to test common state transitions and failure cases. È comunque possibile creare anche scenari di test personalizzati, costituiti dalle stesse azioni, quando si vuole aggiungere la copertura per scenari specifici di un'applicazione o non ancora presenti negli scenari integrati.However, actions can be used to create custom test scenarios when you want to add coverage for scenarios that are not covered by the built-in scenarios yet or that are custom tailored for your application.

Implementazioni in C# delle azioni sono disponibili nell'assembly System.Fabric.dll.C# implementations of the actions are found in the System.Fabric.dll assembly. Il modulo di PowerShell System Fabric si trova nell'assembly Microsoft.ServiceFabric.Powershell.dll.The System Fabric PowerShell module is found in the Microsoft.ServiceFabric.Powershell.dll assembly. Nell'ambito dell'installazione del runtime viene installato il modulo ServiceFabric di PowerShell per garantire una maggiore semplicità d'uso.As part of runtime installation, the ServiceFabric PowerShell module is installed to allow for ease of use.

Azioni di errore normali e anomaleGraceful vs. ungraceful fault actions

Le azioni di Testabilità sono classificate in due bucket principali:Testability actions are classified into two major buckets:

  • Errori anomali: questi errori simulano errori come il riavvio del computer e gli arresti anomali dei processi.Ungraceful faults: These faults simulate failures like machine restarts and process crashes. In caso di errori di questo tipo, il contesto di esecuzione del processo si interrompe in modo brusco.In such cases of failures, the execution context of process stops abruptly. Non è quindi possibile eseguire alcuna pulizia dello stato prima che l'applicazione venga avviata nuovamente.This means no cleanup of the state can run before the application starts up again.
  • Errori normali: questi errori simulano azioni normali come gli spostamenti delle repliche e le eliminazioni attivate dal bilanciamento del carico.Graceful faults: These faults simulate graceful actions like replica moves and drops triggered by load balancing. In questi casi, il servizio riceve una notifica dello stato di chiusura e può eseguire la pulizia dello stato prima di uscire.In such cases, the service gets a notification of the close and can clean up the state before exiting.

Per una convalida migliore in termini di qualità, eseguire il carico di lavoro del servizio e del business, includendo diversi errori normali e anomali.For better quality validation, run the service and business workload while inducing various graceful and ungraceful faults. Gli errori anomali danno luogo a scenari in cui il processo di servizio si chiude improvvisamente nel corso di un flusso di lavoro.Ungraceful faults exercise scenarios where the service process abruptly exits in the middle of some workflow. Ciò consente di verificare il percorso di ripristino una volta che Service Fabric ripristina la replica del servizio.This tests the recovery path once the service replica is restored by Service Fabric. Ciò consentirà di verificare la coerenza dei dati e se lo stato del servizio viene conservato correttamente dopo gli errori.This will help test data consistency and whether the service state is maintained correctly after failures. L'altro set di errori, ovvero gli errori normali, verifica che il servizio risponda correttamente alle repliche spostate da Service Fabric.The other set of failures (the graceful failures) test that the service correctly reacts to replicas being moved around by Service Fabric. Ciò consente di verificare la gestione dell'annullamento nel metodo RunAsync.This tests handling of cancellation in the RunAsync method. Il servizio deve controllare che il token di annullamento sia impostato, salvarne correttamente lo stato e chiudere il metodo RunAsync.The service needs to check for the cancellation token being set, correctly save its state, and exit the RunAsync method.

Elenco delle azioni di TestabilitàTestability actions list

AzioneAction DescrizioneDescription API gestitaManaged API Cmdlet di PowerShellPowerShell cmdlet Errori normali/anomaliGraceful/ungraceful faults
CleanTestStateCleanTestState Rimuove lo stato di tutti i test dal cluster in caso di arresto anomalo del driver di test.Removes all the test state from the cluster in case of a bad shutdown of the test driver. CleanTestStateAsyncCleanTestStateAsync Remove-ServiceFabricTestStateRemove-ServiceFabricTestState Non applicabileNot applicable
InvokeDataLossInvokeDataLoss Provoca la perdita di dati in una partizione del servizio.Induces data loss into a service partition. InvokeDataLossAsyncInvokeDataLossAsync Invoke-ServiceFabricPartitionDataLossInvoke-ServiceFabricPartitionDataLoss NormaleGraceful
InvokeQuorumLossInvokeQuorumLoss Inserisce una partizione del servizio con stato in una perdita di quorum.Puts a given stateful service partition into quorum loss. InvokeQuorumLossAsyncInvokeQuorumLossAsync Invoke-ServiceFabricQuorumLossInvoke-ServiceFabricQuorumLoss NormaleGraceful
Move PrimaryMove Primary Sposta la replica primaria specificata di un servizio con stato nel nodo cluster specificato.Moves the specified primary replica of a stateful service to the specified cluster node. MovePrimaryAsyncMovePrimaryAsync Move-ServiceFabricPrimaryReplicaMove-ServiceFabricPrimaryReplica NormaleGraceful
Move SecondaryMove Secondary Sposta la replica secondaria corrente di un servizio con stato a un nodo di cluster diverso.Moves the current secondary replica of a stateful service to a different cluster node. MoveSecondaryAsyncMoveSecondaryAsync Move-ServiceFabricSecondaryReplicaMove-ServiceFabricSecondaryReplica NormaleGraceful
RemoveReplicaRemoveReplica Simula un errore di replica tramite la rimozione di una replica da un cluster.Simulates a replica failure by removing a replica from a cluster. In tal modo la replica verrà chiusa e passata al ruolo 'None', rimuovendo tutto lo stato dal cluster.This will close the replica and will transition it to role 'None', removing all of its state from the cluster. RemoveReplicaAsyncRemoveReplicaAsync Remove-ServiceFabricReplicaRemove-ServiceFabricReplica NormaleGraceful
RestartDeployedCodePackageRestartDeployedCodePackage Simula un errore di processo del pacchetto di codice mediante il riavvio di un pacchetto di codice distribuito in un nodo in un cluster.Simulates a code package process failure by restarting a code package deployed on a node in a cluster. In questo modo, il processo del pacchetto di codice viene interrotto e verranno riavviate tutte le repliche del servizio utente ospitate nel processo.This aborts the code package process, which will restart all the user service replicas hosted in that process. RestartDeployedCodePackageAsyncRestartDeployedCodePackageAsync Restart-ServiceFabricDeployedCodePackageRestart-ServiceFabricDeployedCodePackage AnomaloUngraceful
RestartNodeRestartNode Simula un errore del nodo cluster Infrastruttura di servizi tramite il riavvio di un nodo.Simulates a Service Fabric cluster node failure by restarting a node. RestartNodeAsyncRestartNodeAsync Restart-ServiceFabricNodeRestart-ServiceFabricNode AnomaloUngraceful
RestartPartitionRestartPartition Simula uno scenario di blackout del data center o del cluster mediante il riavvio di alcune o di tutte le repliche di una partizione.Simulates a datacenter blackout or cluster blackout scenario by restarting some or all replicas of a partition. RestartPartitionAsyncRestartPartitionAsync Restart-ServiceFabricPartitionRestart-ServiceFabricPartition NormaleGraceful
RestartReplicaRestartReplica Simula un errore di replica mediante il riavvio di una replica persistente in un cluster, la chiusura della replica e quindi la riapertura.Simulates a replica failure by restarting a persisted replica in a cluster, closing the replica and then reopening it. RestartReplicaAsyncRestartReplicaAsync Restart-ServiceFabricReplicaRestart-ServiceFabricReplica NormaleGraceful
StartNodeStartNode Avvia un nodo in un cluster già arrestato.Starts a node in a cluster that is already stopped. StartNodeAsyncStartNodeAsync Start-ServiceFabricNodeStart-ServiceFabricNode Non applicabileNot applicable
StopNodeStopNode Simula l’errore in un nodo mediante l’arresto di un nodo in un cluster.Simulates a node failure by stopping a node in a cluster. Il nodo resterà inattivo fino a quando non viene chiamato StartNode.The node will stay down until StartNode is called. StopNodeAsyncStopNodeAsync Stop-ServiceFabricNodeStop-ServiceFabricNode AnomaloUngraceful
ValidateApplicationValidateApplication Convalida la disponibilità e l’integrità di tutti i servizi Infrastruttura di servizi all’interno dell’applicazione, in genere dopo aver causato un errore nel sistema.Validates the availability and health of all Service Fabric services within an application, usually after inducing some fault into the system. ValidateApplicationAsyncValidateApplicationAsync Test-ServiceFabricApplicationTest-ServiceFabricApplication Non applicabileNot applicable
ValidateServiceValidateService Convalida la disponibilità e l’integrità di un servizio Infrastruttura di servizi, in genere dopo aver causato un errore nel sistema.Validates the availability and health of a Service Fabric service, usually after inducing some fault into the system. ValidateServiceAsyncValidateServiceAsync Test-ServiceFabricServiceTest-ServiceFabricService Non applicabileNot applicable

Esecuzione di un'azione di testabilità con PowerShellRunning a testability action using PowerShell

Questa esercitazione illustra come eseguire un'azione di testabilità con PowerShell.This tutorial shows you how to run a testability action by using PowerShell. Si apprenderà come eseguire un'azione di testabilità in un cluster locale (di una casella) o in un cluster di Azure.You will learn how to run a testability action against a local (one-box) cluster or an Azure cluster. Microsoft.Fabric.Powershell.dll, il modulo di PowerShell Service Fabric, viene installato automaticamente quando si installa MSI di Microsoft Service FabricMicrosoft.Fabric.Powershell.dll--the Service Fabric PowerShell module--is installed automatically when you install the Microsoft Service Fabric MSI. e caricato automaticamente quando si apre un prompt di PowerShell.The module is loaded automatically when you open a PowerShell prompt.

Sezioni dell'esercitazione:Tutorial segments:

Eseguire un'azione su un cluster di una casellaRun an action against a one-box cluster

Per eseguire un'azione di testabilità su un cluster locale, è necessario in primo luogo connettersi al cluster e aprire il prompt di PowerShell in modalità amministratore.To run a testability action against a local cluster, first connect to the cluster and open the PowerShell prompt in administrator mode. Esaminiamo l’azione Restart-ServiceFabricNode .Let us look at the Restart-ServiceFabricNode action.

Restart-ServiceFabricNode -NodeName Node1 -CompletionMode DoNotVerify

Qui l'azione Restart-ServiceFabricNode è in esecuzione in un nodo denominato "Node1".Here the action Restart-ServiceFabricNode is being run on a node named "Node1". e la modalità di completamento specifica che l'esito positivo dell'azione di riavvio del nodo non verrà verificato.The completion mode specifies that it should not verify whether the restart-node action actually succeeded. Per verificare l'esito positivo dell'azione di riavvio, è necessario specificare la modalità di completamento come "Verify".Specifying the completion mode as "Verify" will cause it to verify whether the restart action actually succeeded. Anziché specificare direttamente il nodo mediante il nome, è possibile specificarlo tramite una chiave di partizione e il tipo di replica, come indicato di seguito:Instead of directly specifying the node by its name, you can specify it via a partition key and the kind of replica, as follows:

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

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

Restart-ServiceFabricNode deve essere utilizzata per riavviare un nodo Infrastruttura di servizi in un cluster.Restart-ServiceFabricNode should be used to restart a Service Fabric node in a cluster. In questo modo, il processo Fabric.exe verrà interrotto e tutte le repliche del servizio di sistema e del servizio utente ospitate in quel nodo verranno riavviate.This will stop the Fabric.exe process, which will restart all of the system service and user service replicas hosted on that node. L’uso di questa API per il test del servizio consente di rilevare bug lungo i percorsi di ripristino del failover.Using this API to test your service helps uncover bugs along the failover recovery paths. Consente di simulare gli errori dei nodi nel cluster.It helps simulate node failures in the cluster.

La schermata seguente mostra il comando di testabilità Restart-ServiceFabricNode in azione.The following screenshot shows the Restart-ServiceFabricNode testability command in action.

L'output del primo Get ServiceFabricNode (un cmdlet dal modulo PowerShell di ServiceFabric) mostra che il cluster locale ha cinque nodi: da Node.1 a Node.5.The output of the first Get-ServiceFabricNode (a cmdlet from the Service Fabric PowerShell module) shows that the local cluster has five nodes: Node.1 to Node.5. Dopo l'esecuzione dell'azione di testabilità (cmdlet) Restart-ServiceFabricNode sul nodo, denominato Node.4, noteremo che il tempo di attività del nodo è stato reimpostato.After the testability action (cmdlet) Restart-ServiceFabricNode is executed on the node, named Node.4, we see that the node's uptime has been reset.

Eseguire un'azione su un cluster di AzureRun an action against an Azure cluster

L'esecuzione di un'azione di testabilità (con PowerShell) su un cluster di Azure è simile all'esecuzione della stessa azione su un cluster locale.Running a testability action (by using PowerShell) against an Azure cluster is similar to running the action against a local cluster. L'unica differenza è che, prima di poter eseguire l'azione, invece di connettersi al cluster locale, è necessario connettersi al cluster di Azure.The only difference is that before you can run the action, instead of connecting to the local cluster, you need to connect to the Azure cluster first.

Esecuzione di un'azione di testabilità con C#Running a testability action using C#

Per eseguire un'azione di testabilità con C#, è necessario prima connettersi al cluster tramite FabricClient.To run a testability action by using C#, first you need to connect to the cluster by using FabricClient. Ottenere quindi i parametri necessari per eseguire l'azione.Then obtain the parameters needed to run the action. Per eseguire la stessa azione possono essere utilizzati parametri diversi.Different parameters can be used to run the same action. In merito all'azione RestartServiceFabricNode, per eseguirla è possibile usare le informazioni sul nodo (nodo del nome e ID dell'istanza del nodo) disponibili nel cluster.Looking at the RestartServiceFabricNode action, one way to run it is by using the node information (node name and node instance ID) in the cluster.

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

Spiegazione di alcuni parametri:Parameter explanation:

  • CompleteMode specifica che l'esito positivo dell'azione di riavvio non verrà verificato.CompleteMode specifies that the mode should not verify whether the restart action actually succeeded. Per verificare l'esito positivo dell'azione di riavvio, è necessario specificare la modalità di completamento come "Verify".Specifying the completion mode as "Verify" will cause it to verify whether the restart action actually succeeded.
  • OperationTimeout : imposta la quantità di tempo disponibile per completare l'operazione prima che venga generata un'eccezione TimeoutException.OperationTimeout sets the amount of time for the operation to finish before a TimeoutException exception is thrown.
  • CancellationToken : consente di annullare una chiamata in sospeso.CancellationToken enables a pending call to be canceled.

Anziché specificare direttamente il nodo mediante il nome, è possibile specificarlo tramite una chiave di partizione e il tipo di replica:Instead of directly specifying the node by its name, you can specify it via a partition key and the kind of replica.

Per altre informazioni vedere PartitionSelector e ReplicaSelector.For further information, see PartitionSelector and 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 e ReplicaSelectorPartitionSelector and ReplicaSelector

PartitionSelectorPartitionSelector

PartitionSelector è un helper esposto in fase di testabilità che consente di selezionare una partizione specifica in cui eseguire le azioni di testabilità.PartitionSelector is a helper exposed in testability and is used to select a specific partition on which to perform any of the testability actions. Può essere utilizzato per selezionare una partizione specifica se l'ID partizione è noto in anticipo.It can be used to select a specific partition if the partition ID is known beforehand. In alternativa, è possibile fornire la chiave di partizione; l'operazione risolverà internamente l'ID partizione.Or, you can provide the partition key and the operation will resolve the partition ID internally. È inoltre possibile selezionare una partizione casuale.You also have the option of selecting a random partition.

Per usare questo helper, creare l'oggetto PartitionSelector e selezionare la partizione ricorrendo a uno dei metodi Select.To use this helper, create the PartitionSelector object and select the partition by using one of the Select methods. Passare quindi l'oggetto PartitionSelector all'API che lo richiede.Then pass in the PartitionSelector object to the API that requires it. Se non è selezionata alcuna opzione, per impostazione predefinita viene selezionata una partizione casuale.If no option is selected, it defaults to a random 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);

ReplicaSelectorReplicaSelector

ReplicaSelector è un helper esposto in fase di testabilità che consente di selezionare una replica in cui eseguire le azioni di testabilità.ReplicaSelector is a helper exposed in testability and is used to help select a replica on which to perform any of the testability actions. Può essere usato per selezionare una replica specifica se l'ID di replica è noto in anticipo.It can be used to select a specific replica if the replica ID is known beforehand. È possibile selezionare anche una replica primaria o una replica secondaria casuale.In addition, you have the option of selecting a primary replica or a random secondary. ReplicaSelector deriva da PartitionSelector ed è quindi necessario selezionare sia la replica sia la partizione in cui si vuole eseguire l'operazione di testabilità.ReplicaSelector derives from PartitionSelector, so you need to select both the replica and the partition on which you wish to perform the testability operation.

Per usare l'helper, creare un oggetto ReplicaSelector e impostare il modo in cui si vuole selezionare la replica e la partizione.To use this helper, create a ReplicaSelector object and set the way you want to select the replica and the partition. Quindi è possibile passarlo nell'API che lo richiede.You can then pass it into the API that requires it. Se non è selezionata alcuna opzione, per impostazione predefinita vengono selezionate una replica casuale e una partizione casuale.If no option is selected, it defaults to a random replica and random 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);

Passaggi successiviNext steps