Mountebank – Respuestas inject

0
227

Aquí tienes la serie completa de tutoriales sobre Mountebank:

Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 15′ (2,3 Ghz Intel Core i7, 16GB DDR4).
  • Sistema Operativo: Mac OS Catalina 10.15.5
  • Entorno de desarrollo: JDK 11, IntelliJ, Docker, Postman

 

Introducción

En este artículo vamos a ver el uso del último tipo de respuesta que nos provee Mountebank, las respuestas de tipo inject, con este tipo de respuesta Mountebank nos permite extender sus funcionalidades por defecto, espero que os guste y/o sirva de ayuda en vuestros tests.

Este artículo está dividido en 5 partes:

  • Respuestas de tipo inject
  • Añadir estado
  • Seguridad
  • Cómo depurar en Mountebank
  • Conclusiones

 

Respuestas de tipo inject

De vez en cuando podemos encontrarnos con servicios que utilizan algo distinto a JSON o XML, por ejemplo CSV. CSV sigue siendo un formato relativamente popular en ciertos tipos de integraciones de servicios, especialmente en aquellos que implican la transmisión de información de tipo bulkstyle, como por ejemplo el servicio meteorológico del sitio weather.com.

rológico del sitio weather.com.
Day,Description,High,Low,Precip,Wind,Humidity
4­Jun,PM Thunderstorms,83,71,50%,E 5 mph,65%
5­Jun,PM Thunderstorms,82,69,60%,NNE 8mph,73%
6­Jun,Sunny,90,67,10%,NNE 11mph,55%
7­Jun,Mostly Sunny,86,65,10%,NE 7 mph,53%
8­Jun,Partly Cloudy,84,68,10%,ESE 4 mph,53%
9­Jun,Partly Cloudy,88,68,0%,SSE 11mph,56%
10­Jun,Partly Cloudy,89,70,10%,S 15 mph,57%
11­Jun,Sunny,90,73,10%,S 16 mph,61%
12­Jun,Partly Cloudy,91,74,10%,S 13 mph,63%
13­Jun,Partly Cloudy,90,74,10%,S 17 mph,64%

Si tuvieses un caso de prueba que nos diera los días con un porcentaje de humedad superior al 60%, tendríamos un problema por que Mountebank no soporta CSV de forma nativa, y por lo tanto no tiene un predicado que busque niveles de humedad superiores al 60%, estamos fuera de sus capacidades incorporadas.

Para todos estos casos donde pensamos que Mountebank no nos puede ayudar vamos a crear nuestros propios predicados usando JavaScript y el predicado de inyección, pero primero tenemos que iniciar mountebank con el indicador de línea de comandos –allowInjection:

mb --­­allowInjection

Todos los predicados que hemos visto hasta ahora funcionan en un solo campo de la petición.  No es así con inject, que nos da control total al pasar todo el objeto de solicitud a una función JavaScript que escribimos. Esa función JavaScript devuelve true si el predicado coincide con la petición y false de otra manera, como se muestra a continuación:

function (request) {
    if (...) {
        return true;
    }
    else {
        return false;
    }
}

Enchufar la función en la matriz de predicados de un stub implica que se use JSONescaping, que reemplaza las nuevas líneas con ‘n’, y escapa de las comillas dobles:

{
    "predicates": [{
        "inject": "function (request) {n if (...) {n return true;n }n else {n return false;n }n}"
    }],
    "responses": [{
        "is": { ... }
    }]
}

También podemos crear nuestra propia respuesta en mountebank. En su forma más simple, la función de inyección de respuesta refleja la de los predicados, aceptando toda la petición como parámetro. Es responsable de devolver un objeto de respuesta que mountebank fusionará con la respuesta predeterminada. Piensa en ello como si estuvieras creando una respuesta de tipo is usando una función JavaScript, de la siguiente manera.

{
    "responses": [{
        "inject": "function (request) { return { statusCode: 400 }; }"
    }]
}

Una función de inyección predicada sólo requiere un parámetro (“config”) que tiene los siguientes campos:

  • request, el objeto de petición específico del protocolo
  • state, un objeto inicialmente vacío al que se le puede agregar estado; será pasado en las llamadas subsecuentes para el mismo impostor.
  • logger, se usa para escribir información de depuración en los registros de mountebank

La función de inyección de respuesta incluye esos campos y añade uno más al parámetro (“config”):

  • callback, una función de devolución de llamada para soportar operaciones asíncronas

Una cosa importante y de la que no podemos perder el foco es que la virtualización de servicios es una estrategia de prueba que nos da determinismo al probar un servicio que tiene dependencias de tiempo de ejecución. No es una forma de reimplementar dependencias de tiempo de ejecución en una plataforma diferente. Aunque mountebank proporciona funcionalidad avanzada para hacer que tus stubs sean más inteligentes cuando necesites que lo sean, lo mejor es no necesitar que sean tan inteligentes. Cuanto más tontos puedan ser sus servicios virtuales, más mantenible será tu arquitectura de pruebas.

 

Añadir estado

Mountebank pasa un parámetro de estado a tus funciones de inyección que puedes usar para recordar información a través de múltiples solicitudes. Inicialmente es un objeto vacío, pero puedes añadirle la información que quieras cada vez que se ejecute la función de inyección.

Vamos a verlo con un ejemplo, empezaremos añadiendo el parámetro a la función e inicializándolo con las variables que desea recordar, en posteriores llamadas utilizaremos el parámetro.

function (request, state) {
    function csvToObjects (csvData) {...}
    // Initialize state arrays
    if (!state.humidities) {
        state.days = [];
        state.humidities = [];
    }
    var rows = csvToObjects(request.body);
    rows.forEach(function (row) {
    if (state.days.indexOf(row.Day) < 0) {   
        state.days.push(row.Day);
        state.humidities.push(row.Humidity.replace('%', ''));
    }
    });
    ...
}

 

Seguridad

La inyección de JavaScript está desactivada de forma predeterminada cuando se inicia mountebank, y por una buena razón. Con la inyección habilitada, mountebank se convierte en un potencial motor de ejecución remota accesible a cualquiera en la red. La inyección es una característica enormemente útil, pero hay que utilizarla teniendo en cuenta las implicaciones de seguridad. 

La primera precaución es no ejecutar mb en su cuenta de usuario. Comenzar mountebank con un usuario sin privilegios, idealmente uno sin credenciales de dominio de red. La siguiente capa de seguridad es restringir qué máquinas pueden acceder a la web de mountebank. Para esto tenemos varias opciones la más sencilla es utilizar el indicador –localOnly, que restringe el acceso a los procesos que se ejecutan en la misma máquina. Esta opción es perfecta cuando tus pruebas se ejecutan en la misma máquina que mountebank, y debería ser la opción por defecto la mayor parte del tiempo. Cuando se requiere pruebas remotas (durante pruebas de carga extensivas, por ejemplo), también podemos restringir qué máquinas pueden acceder al servidor web de mountebank con la bandera –ipWhitelist, que captura un conjunto limitado de direcciones IP. En el siguiente ejemplo vamos a ver como configurar unas únicas direcciones IP remotas que permiten el acceso a mountebank son 10.22.57.137 y 10.22.57.138:

mb --­­allowInjection --­­ipWhitelist "10.22.57.137|10.22.57.138"

 

Cómo depurar en Mountebank

Escribir funciones de inyección tiene la misma complejidad que escribir cualquier código, excepto que es mucho más difícil depurarlas a través de un IDE porque se ejecutan en un proceso remoto aunque siempre podremos utilizar la depuración de impresión. 

Como ya hemos visto mountebank pasa otro parámetro tanto a la inyección predicada como a la de respuesta para hacer la salida un poco más fácil de detectar en los logs, el logger, veamos un ejemplo sencillo de depuración por impresión:

function (request, state, logger) {
    var rows = csvToObjects(request.body), humidities = rows.map(function (row) {
        return parseInt(row.Humidity.replace('%', ''));
    });
    logger.warn(JSON.stringify(humidities));
    return {};
}

 

Conclusiones

En este artículo hemos repasado qué son y cómo podemos utilizar los tipos de respuesta inject que proporciona Mountebank para crear nuestros propios predicados con una función JavaScript que acepta el objeto de petición y devuelve un booleano que representa si el predicado coincide o no, también cómo crear nuestras propias respuestas con una función JavaScript que acepta el objeto de solicitud y devuelve un objeto que representa la respuesta. Hemos repasado los principales problemas de seguridad que se pueden dar sino somos cautelosos, también hemos visto cómo manejar el estado en nuestras funciones javascript y por último cómo depurar dichas funciones.

Puedes descargar el proyecto completo aquí.

 

Referencias

http://www.mbtest.org/

https://github.com/bbyars/mountebank

https://github.com/bbyars/mountebank-in-action

https://hub.docker.com/r/bbyars/mountebank

http://www.mbtest.org/docs/api/injection

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad