Quarkus Tip : Tester une fonction Google Cloud

Quarkus Tip : Tester une fonction Google Cloud

J’ai récemment contribué une PR à Quarkus qui contient un framework de test pour les fonctions Google Cloud.

Quarkus supporte la création de fonction Google Cloud de trois manières différentes :

  • En utilisant l’API de Google Cloud.
  • En utilisant une extension HTTP de Quarkus : RESTEasy, Reactive routes, Servlet, Spring Web.
  • En utilisant Funqy, l’API de développement de fonction de Quarkus agnostique du fournisseur cloud.

Mais jusqu’à aujourd’hui, pour tester ces fonctions, il fallait les packager puis les lancer localement via l’invoker de fonction fournit par le SDK de Google. L’invoker de fonction est un JAR à télécharger qui peut ensuite être utilisé pour lancer une fonction. Pas très pratique à utiliser, et surtout, ne permet pas une utilisation pour des tests unitaires automatisés.

Les fonctions utilisant une extension HTTP de Quarkus pouvaient implémenter un test unitaire de manière traditionnel, mais celui-ci n’utilisait pas un environnement de fonction. Il ne reproduisait donc pas une exécution de fonction proche de la réalité.

Avec Quarkus 2.15, un framework de test des fonctions Google Cloud existe qui permet de tester une fonction via des appels HTTP. Ce framework va utiliser l’invoker des fonctions et le démarrer automatiquement au lancement du test. Vous pourrez alors utiliser REST-assured pour réaliser le test de votre fonction comme vous l’auriez fait pour une application Quarkus standard.

Pour utiliser ce framework de test, il faut ajouter la dépendance Maven suivante :

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-test-google-cloud-functions</artifactId>
    <scope>test</scope>
</dependency>

Tester une fonction utilisant l’API de Google Cloud Function

La fonction suivante utilise l’API de Google Cloud Function pour implémenter une fonction HTTP qui répond « Hello World ».

@ApplicationScoped // Needed for Quarkus to locate the function
public class HttpFunctionTest implements HttpFunction { 
    @Inject GreetingService greetingService; 

    @Override
    public void service(HttpRequest httpRequest, HttpResponse httpResponse) throws Exception { 
        Writer writer = httpResponse.getWriter();
        writer.write(greetingService.hello());
    }
}

Le test correspondant sera un test Quarkus standard, annoté via @QuarkusTest, mais qui utilisera l’annotation @WithFunction qui permet de lancer la fonction en utilisant l’invoker des fonctions Google Cloud. L’annotation @WithFunction prend comme attribut le type de fonction à lancer, ici FunctionType.HTTP car c’est une fonction HTTP.

@QuarkusTest 
@WithFunction(FunctionType.HTTP) 
class HttpFunctionTestCase {
    @Test
    public void test() {
        when()
                .get()
                .then()
                .statusCode(200)
                .body(is("Hello World!")); 
    }
}

Le test utilise REST-assured pour envoyer une requête HTTP avec la méthode GET, et asserter que la réponse a un code statut 200 et contient la chaîne de caractère « Hello World ».

On peut écrire le même type de test pour une fonction de type background.

Prenons comme exemple une fonction background se déclenchant depuis un événement Cloud Storage :

@ApplicationScoped  // Needed for Quarkus to locate the function
public class BackgroundFunctionStorageTest implements BackgroundFunction<BackgroundFunctionStorageTest.StorageEvent> { 
    @Override
    public void accept(StorageEvent event, Context context) throws Exception { 
        System.out.println("Receive event: " + event);
    }

    // The Cloud Storage event will be deserialized with this class
    public static class StorageEvent { 
        public String name;
    }
}

Elle peut être testée via le code suivant :

@QuarkusTest
@WithFunction(FunctionType.BACKGROUND) 
class BackgroundFunctionStorageTestCase {
    @Test
    public void test() {
        given()
                .body("{\"data\":{\"name\":\"hello.txt\"}}") 
                .when()
                .post()
                .then()
                .statusCode(200);
    }
}

Ici, le test est de type FunctionType.BACKGROUND, et on envoie l’événement à la fonction via une requête POST dont le corps est un JSON dont l’attribut data contient l’événement déclenchant la fonction.

Les fonctions de type Cloud Events sont aussi supportées.

Plus d’information dans le guide Quarkus Google Cloud Functions.

Tester une fonction utilisant Quarkus Funqy

Il est possible d’écrire une fonction Google Cloud réagissant à un événement Cloud Storage via le framework Funqy.
Funqy offre une API agnostique du fournisseur cloud.
Pour utiliser Funqy, il faut écrire une méthode Java annotée via @Funq, qui prend en paramètre l’événement déclencheur de la fonction.

public class GreetingFunctions {
    @Funq 
    public void helloGCSWorld(StorageEvent storageEvent) {
        String message = service.hello("world");
        System.out.println(storageEvent.name + " - " + message);
    }
}

Pour tester cette fonction, on va utiliser le même code que pour une fonction utilisant l’API de Google Cloud, mais on va configurer le framework de test pour une fonction de type FunctionType.FUNQY_BACKGROUND.

@QuarkusTest 
@WithFunction(FunctionType.FUNQY_BACKGROUND) 
class GreetingFunctionsStorageTest {
    @Test
    public void test() {
        given()
                .body("{\"data\":{\"name\":\"hello.txt\"}}") 
                .when()
                .post()
                .then()
                .statusCode(200);
    }
}

Là encore, les fonctions de type Cloud Events sont aussi supportées.

Plus d’information dans le guide Quarkus Funqy Google Cloud Functions.

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.