Testare la modalità Datastore utilizzando l'emulatore Firestore

L'interfaccia a riga di comando Google Cloud fornisce un emulatore in memoria locale per Firestore che puoi utilizzare per testare l'applicazione Firestore in modalità Datastore. Puoi utilizzare l'emulatore con tutte le librerie client in modalità Datastore. Dovresti utilizzare l'emulatore solo per i test locali.

Utilizza gcloud emulators firestore con --database-mode=datastore-mode per testare il comportamento di Firestore in modalità Datastore.

Non utilizzare l'emulatore per i deployment di produzione. Poiché l'emulatore archivia i dati solo in memoria, non li conserva tra le esecuzioni.

Installare l'emulatore

Per installare l'emulatore Firestore, installa e aggiorna la gcloud CLI:

  1. Installa l'interfaccia a riga di comando gcloud.

  2. Aggiorna l'installazione della gcloud CLI per ottenere le funzionalità più recenti:

    gcloud components update
    

Eseguire l'emulatore

  1. Esegui il comando seguente per avviare l'emulatore:

    gcloud emulators firestore start --database-mode=datastore-mode
    

    L'emulatore stampa l'host e il numero di porta su cui è in esecuzione.

    Per impostazione predefinita, l'emulatore tenta di utilizzare 127.0.0.1:8080. Per associare l' emulatore a un host e una porta specifici, utilizza il flag facoltativo --host-port, sostituendo HOST e PORT:

    gcloud emulators firestore start --database-mode=datastore-mode --host-port=HOST:PORT
    
  2. Utilizza la scorciatoia da tastiera Control + C per arrestare l'emulatore.

Connettersi all'emulatore

Per connettere una libreria client e un'app all'emulatore, imposta la variabile di ambiente DATASTORE_EMULATOR_HOST. Quando questa variabile di ambiente è impostata, le librerie client si connettono automaticamente all'emulatore.

export DATASTORE_EMULATOR_HOST="HOST:PORT"

Importare entità nell'emulatore

La funzionalità di importazione dell'emulatore ti consente di caricare le entità da un insieme di file di esportazione di entità nell'emulatore. I file di esportazione di entità possono provenire da un'esportazione del database in modalità Datastore o da un'istanza dell'emulatore.

Puoi importare le entità nell'emulatore in due modi. Il primo consiste nell'aggiungere il flag import-data al comando di avvio dell'emulatore. Il secondo metodo consiste nell'inviare una richiesta di importazione POST all'emulatore. Puoi utilizzare curl o uno strumento simile. Fai riferimento agli esempi seguenti.

Protocollo

curl -X POST http://localhost:8080/emulator/v1/projects/PROJECT_ID:import \
-H 'Content-Type: application/json' \
-d '{"database":"DATABASE", "export_directory":"EXPORT_DIRECTORY"}'
Modifica localhost:8080 se l'emulatore utilizza una porta diversa.

Flag dell'interfaccia a riga di comando

gcloud emulators firestore start --database-mode=datastore-mode --import-data=EXPORT_DIRECTORY

dove:

  • [PROJECT_ID] è l'ID del tuo progetto.
  • [DATABASE] è il percorso del database. Ad esempio, un progetto con il database predefinito avrà il seguente aspetto:

    {"database":"projects/myProject/databases/"}

  • [EXPORT_DIRECTORY] è il percorso del file overall_export_metadata dei file di esportazione di entità. Ad esempio:

    {"export_directory":"/home/user/myexports/2024-03-26T19:39:33_443/2024-03-26T19:39:33_443.overall_export_metadata"}

Esportare entità nell'emulatore

La funzionalità di esportazione dell'emulatore ti consente di salvare le entità nell'emulatore in un insieme di file di esportazione di entità. Puoi quindi utilizzare un'operazione di importazione per caricare le entità nei file di esportazione di entità nel database in modalità Datastore o in un'istanza dell'emulatore.

Puoi esportare le entità dall'emulatore in due modi. Il primo consiste nell'aggiungere il flag export-on-exit al comando di avvio dell'emulatore. Il secondo metodo consiste nell'inviare una richiesta di esportazione POST all'emulatore. Puoi utilizzare curl o uno strumento simile. Fai riferimento agli esempi seguenti.

Protocollo

curl -X POST http://localhost:8080/emulator/v1/projects/PROJECT_ID:export \
-H 'Content-Type: application/json' \
-d '{"database":"DATABASE_PATH", "export_directory":"EXPORT_DIRECTORY"}'
Modifica localhost:8080 se l'emulatore utilizza una porta diversa.

Flag dell'interfaccia a riga di comando

gcloud emulators firestore start --database-mode=datastore-mode --export-on-exit=EXPORT_DIRECTORY

dove:

  • [PROJECT_ID] è l'ID del tuo progetto.
  • [DATABASE_PATH] è il percorso del database. Ad esempio, un progetto con il database predefinito avrà il seguente aspetto:

    {"database":"projects/myProject/databases/"}

  • [EXPORT_DIRECTORY] specifica la directory in cui l'emulatore salva i file di esportazione di entità. Questa directory non deve contenere già un insieme di file di esportazione di entità. Ad esempio:

    {"export_directory":"/home/user/myexports/2024-03-26/"}

Persistere i dati nell'emulatore

Per impostazione predefinita, l'emulatore Firestore non salva i dati su disco. Per salvare i dati dell'emulatore, esegui il comando seguente per utilizzare i flag di importazione ed esportazione per caricare e salvare i dati tra le istanze dell'emulatore:

gcloud emulators firestore start --database-mode=datastore-mode --import-data=EXPORT_DIRECTORY --export-on-exit=EXPORT_DIRECTORY

Reimpostare i dati dell'emulatore

L'emulatore Firestore include un endpoint REST per reimpostare tutti i dati nell'emulatore. Puoi utilizzare questo endpoint per cancellare i dati tra i test senza arrestare l'emulatore.

Per reimpostare tutti i dati nell'emulatore, esegui un'operazione HTTP POST contro l'endpoint seguente, sostituendo HOST e PORT con l' host e la porta selezionati e sostituendo PROJECT_ID con il tuo ID progetto:

http://HOST:PORT/reset

Modifica l'host e la porta se l'emulatore non utilizza 127.0.0.1:8080. Il codice deve attendere la conferma REST che la reimpostazione è stata completata o non è riuscita.

Puoi eseguire questa operazione dalla shell utilizzando curl:

$ curl -X POST "http://HOST:PORT/reset"

Differenze tra l'emulatore e la produzione

L'emulatore tenta di replicare fedelmente il comportamento del servizio di produzione con alcune limitazioni importanti.

Concorrenza e coerenza

L'emulatore supporta solo la concorrenza pessimistica e l'elevata coerenza. L'emulatore non supporta le impostazioni di concorrenza ottimistica e coerenza finale.

Transazioni

L'emulatore non tenta di imitare il comportamento delle transazioni osservato in produzione. Utilizza un semplice approccio di blocco e non tenta di rispecchiare le varie modalità di concorrenza offerte nell'ambiente di produzione.

Quando testi funzionalità che comportano più scritture simultanee in un documento, l'emulatore potrebbe impiegare molto tempo per completare le richieste di scrittura. L'emulatore potrebbe impiegare fino a 30 secondi per rilasciare i blocchi. Se devi modificare gli intervalli di timeout dei test, fallo.

L'emulatore non tenta inoltre di imitare tutti i limiti di produzione, come i timeout e i limiti di dimensioni, che coinvolgono le transazioni. Se testi funzionalità che dipendono da questi limiti di produzione, ti consigliamo di utilizzare un ambiente di produzione anziché un emulatore.

Indici

Per impostazione predefinita, l'emulatore non tiene traccia degli indici composti ed esegue invece qualsiasi query valida.

Per verificare se i requisiti degli indici composti sono soddisfatti, avvia l'emulatore con i flag --require-indexes e --index-file. Quando avvii l'emulatore con questi flag, questo verifica e rifiuta le query che richiedono un indice composto non definito nel file di indice specificato.

gcloud emulators firestore start --database-mode=datastore-mode --require-indexes --index-file=./index.yaml

Per ulteriori informazioni sul formato index-file, consulta Configurazione degli indici Datastore con index.yaml.

Limiti

L'emulatore non applica tutti i limiti applicati in produzione. Ad esempio, l'emulatore potrebbe consentire transazioni che verrebbero rifiutate come troppo grandi dal servizio di produzione. Assicurati di conoscere i limiti documentati e di progettare l'app in modo da evitarli in modo proattivo.

Passaggi successivi