Saltar al contenido

Referencia de nodos ​

Cada tipo de nodo que puede contener un experimento, en los grupos del menú de añadir: acciones, esperas, emulación, fallos, datos, comprobaciones y flujo. Cómo añadirlos y conectarlos está en El editor; signallab nodes imprime el mismo catálogo como JSON, para scripts y asistentes (La línea de comandos).

Cómo leer esta página ​

Cada nodo tiene una tabla de sus campos:

  • Campo es el nombre en el panel de propiedades; En el archivo es la clave en el JSON del experimento.
  • Predeterminado es lo que recibe un nodo cuando lo añades en el editor. Donde un archivo puede omitir una clave, el valor que toma entonces se indica como si falta; las demás claves son obligatorias en un archivo.
  • Plantillas: sí — el campo admite {{templates}}: parámetros, variables definidas antes, secretos y generadores, resueltos al ejecutarse el paso (Datos y plantillas). Solo parámetros — se abre antes del primer paso, cuando solo se conocen los parámetros. No — el valor se toma tal como se escribe.

Los tiempos están en milisegundos. Los límites se comprueban antes de que empiece una ejecución; un campo fuera de rango impide que el experimento se ejecute y se muestra en el nodo.

Un nodo en un archivo ​

En un archivo de experimento, un nodo es un objeto con un id (único en el experimento), su type, su lugar en el lienzo (x, y, cero o más), sus campos y los ajustes que usa (retry, repeat, load, omitidos cuando están desactivados). Un cable es una arista desde la salida de un nodo (port, next si falta) hasta otro nodo:

json
{
  "nodes": [
    { "id": "start", "type": "start", "x": 40, "y": 80 },
    { "id": "ping", "type": "udp", "x": 270, "y": 80, "target": "127.0.0.1:9000", "text": "PING",
      "retry": { "attempts": 3, "delay_ms": 500, "backoff": "fixed" } },
    { "id": "end", "type": "end", "x": 500, "y": 80 }
  ],
  "edges": [
    { "from": "start", "to": "ping", "port": "next" },
    { "from": "ping", "to": "end", "port": "next" }
  ]
}

Los ejemplos de abajo muestran un nodo cada uno, tal como lo contiene un archivo.

Ajustes compartidos por muchos nodos ​

Se activan en la parte inferior de las propiedades de un nodo. Qué nodo admite cuál se indica bajo cada nodo.

AjusteLo admiteQué hace
ReintentarNodos que envían o escuchan: Solicitud HTTP, Mensaje TCP, Mensaje OSC, Datagrama UDP, Publicación MQTT, Conectar WebSocket, Enviar por WebSocket, y todas las esperasVuelve a intentarlo cuando falla el paso
RepetirNodos que envían: Solicitud HTTP, Mensaje TCP, Mensaje OSC, Datagrama UDP, Publicación MQTT, Enviar por WebSocketEnvía una y otra vez, un número de veces o durante un tiempo
CargaSolicitud HTTPEnvía la solicitud según un perfil de carga, medido y juzgado por umbrales
Esperar una respuestaMensaje OSC, Datagrama UDPEnvía y espera la respuesta en el mismo paso

Reintentar ​

reintentar si falla: cuando falla el paso — sin conexión, un tiempo de espera agotado, una espera sin nada que coincida — hace una pausa y se ejecuta de nuevo. Cada intento fallido es una fila en la línea de tiempo; el paso falla cuando falla el último intento. Una plantilla que no se puede resolver no se reintenta. Detener también termina una pausa.

CampoEn el archivoQuéPredeterminado y límites
Intentosretry.attemptsIntentos en total, el primero incluido3; 2–10 en el editor (un archivo también puede decir 1)
Pausa, msretry.delay_msLa pausa antes del segundo intento500; 0–60 000
Pausasretry.backoffiguales (fixed): la misma pausa cada vez; que se duplican (exponential): el doble de larga tras cada fallofixed (también si falta)

Ninguna pausa dura más de 60 segundos, por mucho que se duplique. Una espera cuya salida Tiempo agotado tiene un cable no falla por un tiempo de espera agotado — sale por esa salida — así que entonces no se reintenta.

Repetir ​

repetir el envío: el nodo envía una y otra vez — un latido, un sondeo, un flujo constante — sin un bucle en el grafo. Cada envío lee sus plantillas de nuevo ({{counter}} es su número, {{now}} su hora), y Reintentar, cuando está activado, se aplica a cada envío. El paso se supera cuando lo hizo cada envío; un envío que falla definitivamente falla el paso. La línea de tiempo informa del progreso como máximo una vez por segundo.

CampoEn el archivoQuéPredeterminado y límites
Repetirrepeat.untilun número de veces (count) o durante un tiempo (duration)count (también si falta)
Vecesrepeat.countEnvíos en total, el primero incluido10 (también si falta); 2–10 000
Durante, msrepeat.duration_msCuánto tiempo seguir enviando, desde el primer envío10 000 (también si falta); 1–300 000
Cada, msrepeat.interval_msLa pausa entre dos envíos1 000; 10–60 000; obligatorio en un archivo
Jitter, msrepeat.jitter_msCada pausa hasta este tiempo más larga, extraída de la semilla de la ejecución0 (también si falta); 0–60 000

Las repeticiones deben caber en los 300 segundos de una ejecución, y durante un tiempo debe necesitar menos de 10 000 envíos (su tiempo dividido entre el intervalo).

Carga ​

enviar bajo carga, solo en un Solicitud HTTP: la solicitud se envía según un perfil — una tasa constante, una rampa, escalones, un pico o llegadas aleatorias — con hasta 512 en vuelo a la vez (32 por defecto), y se mide: latencias, errores, la tasa alcanzada. Los umbrales deciden si el paso se supera. La carga sustituye a Repetir y Reintentar (una solicitud fallida se cuenta, no se reintenta) y no deja respuesta para las comprobaciones posteriores. Sus campos y resultados están en Pruebas de carga.

Esperar una respuesta ​

esperar una respuesta, en un Mensaje OSC o un Datagrama UDP: el mensaje se envía desde el puerto en el que se espera la respuesta, así que se oye a un dispositivo que responde al remitente, y el paso solo se supera cuando llega una respuesta que coincide a tiempo. Sin respuesta, el paso falla — Reintentar envía de nuevo. La respuesta se guarda en una variable, como la de una espera.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Respuesta en (IP:puerto)reply.bindIP:port desde el que enviar y en el que escuchar; el puerto 0 toma cualquier puerto libre0.0.0.0:0No
Patrón de dirección de respuesta (OSC)reply.addressEl patrón de dirección de la respuesta, como en Esperar OSC/*Sí
Reglas de argumentos (OSC)reply.argsReglas de argumentos, como en Esperar OSCninguna; como máximo 16Valores: sí
Carga útil de respuesta (UDP)reply.modeany, contains, regex o hex — consulta Coincidencia de cargas útilesany (también si falta)No
Patrón (UDP)reply.patternLo que la respuesta debe contener o con lo que debe coincidirvacío; obligatorio salvo anySí
Tiempo de espera, msreply.timeout_msCuánto esperar2 000 (también si falta); 1–120 000No
Variable de respuestareply.variableLa variable en la que se guarda la respuestareply (también si falta)No

El puerto de la respuesta se abre antes del primer paso, como el de una espera.

Acciones ​

Nodos que envían. Una espera tras una acción cuenta los mensajes desde el momento en que empezó la acción.

Solicitud HTTP ​

Envía una solicitud HTTP y guarda la respuesta para las comprobaciones, las ramas y los nodos Extraer valor posteriores.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Métodorequest.methodGET, HEAD, POST, PUT, PATCH, DELETE u OPTIONS (un archivo puede nombrar cualquier método)GETNo
URLrequest.urlUna URL http:// o https://http://127.0.0.1:8080/Sí
Tiempo de espera (ms)request.timeout_msPara todo el intercambio4 000 (10 000 si falta); 1–120 000No
Encabezados de la solicitudrequest.headers[[name, value], …]; se omite una fila con un nombre vacíoningunaSí, nombres y valores
Cuerporequest.bodyTexto, o null para ningunonullSí
Autenticaciónrequest.authNinguna, Basic, Token Bearer o Digest, con Nombre de usuario y Contraseña, o TokenningunoSí
  • Cualquier respuesta supera el paso, 404 y 500 incluidos: comprueba el estado con Estado HTTP o ramifícalo con Rama por estado. Una solicitud que no obtiene respuesta — rechazada, un tiempo de espera agotado, un nombre que no se resuelve, un certificado que no es de confianza — falla el paso.
  • Se siguen las redirecciones, como máximo diez. Los certificados https:// se verifican.
  • El cuerpo de la respuesta se conserva hasta 256 KiB para las comprobaciones; un cuerpo mayor se corta ahí (las comprobaciones lo indican cuando lo que buscan puede estar más allá del corte).
  • Digest responde al desafío 401 del servidor y envía la solicitud de nuevo. Las credenciales solo entran en la solicitud: los pasos, los informes y el Inspector nunca muestran el encabezado Authorization. Escribe una contraseña como {{secret.NAME}}.
  • Mientras el experimento conserva las cookies (activado por defecto, en Parámetros), lo que los servidores establecen se devuelve con las solicitudes posteriores de la ejecución a ellos.

Salidas: Salida. Ajustes: Reintentar, Repetir, Carga.

json
{ "id": "cue", "type": "http", "x": 270, "y": 80,
  "request": { "method": "POST", "url": "{{api}}/cue", "headers": [["Content-Type", "application/json"]],
               "body": "{\"cue\": 1}", "timeout_ms": 5000,
               "auth": { "scheme": "bearer", "token": "{{secret.API_TOKEN}}" } } }

Véase también HTTP.

Mensaje TCP ​

Se conecta a un host por TCP, escribe la carga útil, espera hasta 250 ms los primeros bytes de una respuesta (lee como máximo 1 024 bytes, una vez) y cierra la conexión. El tamaño de la respuesta se informa, no se comprueba.

En el Inspector el paso son dos tramas tcp con el origen experiment: la carga útil escrita y, cuando llegó una, la respuesta leída. Los secretos en uso se enmascaran en ambas, como en cualquier trama.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
HosthostUn nombre de host o una dirección IP127.0.0.1Sí
Puertoport9000; 1–65 535No
Tiempo de espera (ms)timeout_msPara conectarse, escribir y la respuesta en conjunto4 000 (también si falta); 1–120 000No
Carga útilpayloadEl texto escrito una vez conectado, como UTF-8helloSí

El paso falla cuando se rechaza la conexión, no se resuelve el nombre o se agota el tiempo. Salidas: Salida. Ajustes: Reintentar, Repetir. Enviar ahora se conecta y escribe la carga útil una vez, y el resultado del nodo indica cuántos bytes se enviaron y volvieron.

json
{ "id": "go", "type": "tcp", "x": 270, "y": 80, "host": "127.0.0.1", "port": 5000, "payload": "GO\r\n", "timeout_ms": 2000 }

Mensaje OSC ​

Envía un mensaje OSC 1.0 por UDP.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Host:puerto de destinotargetIP:port o host:port; un nombre de host se resuelve cuando el paso envía, y se toma su dirección IPv4 cuando la tiene127.0.0.1:9000Sí
Dirección OSCaddressEmpieza por //testSí
Argumentosargs[{ "type", "value" }, …] — int, float, str, long, double, bool, blob (bytes), nil (sin valor)ningunaValores de texto (str): sí
esperar una respuestareplyOpcional: enviar y esperar la respuesta — consulta Esperar una respuestaDesactivado

Salidas: Salida; cuando se espera una respuesta, solo se sigue cuando llegó la respuesta. Ajustes: Reintentar, Repetir, una respuesta. ⚡ Pasar por una degradación en sus propiedades pone un Degradación delante.

json
{ "id": "fader", "type": "osc", "x": 270, "y": 80, "target": "{{device}}", "address": "/fader/1",
  "args": [{ "type": "float", "value": 0.75 }] }

Véase también OSC.

Datagrama UDP ​

Envía una carga útil de texto como un datagrama UDP a uno o varios destinos.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Host:puerto de destinotargetIP:port o host:port; varios separados por comas, puntos y comas o saltos de línea reciben cada uno el datagrama. Un nombre de host se resuelve cuando el paso envía, y se toma su dirección IPv4 cuando la tiene127.0.0.1:9000Sí
Carga útiltextLa carga útil, como UTF-8hello; como máximo 65 507 bytesSí
esperar una respuestareplyOpcional: enviar y esperar la respuesta — consulta Esperar una respuestaDesactivado

El paso falla si no se puede alcanzar algún destino. Salidas: Salida. Ajustes: Reintentar, Repetir, una respuesta.

json
{ "id": "ping", "type": "udp", "x": 270, "y": 80, "target": "{{device}}", "text": "PING {{run.id}}",
  "reply": { "bind": "0.0.0.0:0", "mode": "contains", "pattern": "PONG", "timeout_ms": 1000, "variable": "pong" } }

Publicación MQTT ​

Se conecta a un bróker MQTT, publica un mensaje y se desconecta. La conexión es MQTT 3.1.1 sobre TCP sin cifrar, con una sesión limpia y sin nombre de usuario ni contraseña. La conexión, la publicación y el acuse del bróker deben ocurrir en 15 segundos.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Host del brókerhostEl nombre o la dirección del bróker127.0.0.1Sí
Puertoport1883; 1–65 535No
TematopicSin comodines (+, #)lab/testSí
Carga útilpayloadEl mensaje, como textohelloSí
QoSqos0, 1 o 20No
Retener mensajeretaintrue: el bróker lo conserva como el valor del temafalseNo

Las seis claves son obligatorias en un archivo. El paso falla cuando no se puede alcanzar el bróker o rechaza la conexión o el mensaje. Salidas: Salida. Ajustes: Reintentar, Repetir.

json
{ "id": "light", "type": "mqtt", "x": 270, "y": 80, "host": "{{broker}}", "port": 1883,
  "topic": "lab/light/1/set", "payload": "on", "qos": 1, "retain": false }

Véase también MQTT.

Conexión WebSocket ​

Abre un WebSocket para el resto de la ejecución, o hasta un Cerrar WebSocket. Lo que llega a partir de entonces se guarda para los pasos Esperar WebSocket sobre él. La URL y los encabezados se resuelven cuando se ejecuta el paso, así que un token extraído antes puede estar en ellos. Si se ejecuta de nuevo — en un Bucle — cierra primero su conexión anterior y abre una nueva. Cuando termina la ejecución, de cualquier forma, sus conexiones se cierran con una trama de cierre.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
URLurlUna URL ws:// o wss://ws://127.0.0.1:9001/Sí
Encabezados de la solicitudheaders[[name, value], …] enviados con la solicitud de mejoraningunoSí, nombres y valores
SubprotocolosprotocolsSubprotocolos que ofrecer, por orden de preferencia; el servidor elige unoningunoNo
Tiempo de espera (ms)timeout_msPara conectarse y la mejora5 000 (10 000 si falta); 1–120 000No

wss:// confía en los mismos certificados que https://. El paso falla cuando falla la conexión o la mejora; el estado del servidor está en el motivo. Salidas: Salida. Ajustes: Reintentar (no Repetir).

json
{ "id": "socket", "type": "ws_connect", "x": 270, "y": 80, "url": "ws://127.0.0.1:9001/chat",
  "headers": [["Authorization", "Bearer {{token}}"]], "protocols": ["chat.v1"], "timeout_ms": 5000 }

Véase también WebSocket.

Envío WebSocket ​

Envía un mensaje por la conexión que abrió un Conectar WebSocket.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
ConexiónconnectionEl id de un nodo Conectar WebSocket de este experimentoel primeroNo
FormatobinaryTexto (false), o Binario (hex) (true): la carga útil son bytes escritos en hex, de ad be effalse (también si falta)No
Carga útiltextEl mensajehello; como máximo 16 MiBSí

La conexión debe preceder al envío en su ruta; un envío cuya conexión no está abierta falla. Las respuestas cuentan desde el momento en que se escribe el mensaje. Salidas: Salida. Ajustes: Reintentar, Repetir.

json
{ "id": "hello", "type": "ws_send", "x": 500, "y": 80, "connection": "socket",
  "text": "{\"type\":\"ping\",\"id\":\"{{uuid}}\"}", "binary": false }

Cierre WebSocket ​

Cierra una conexión con un saludo de cierre. La línea de tiempo dice quién la cerró: este paso, el servidor antes (con su código), o una conexión que se había roto.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
ConexiónconnectionEl id de un nodo Conectar WebSocketel primeroNo
Código de cierrecode1000 (normal), o 3000–4999 para uno propio de la aplicación1000 (también si falta)No
MotivoreasonSe envía con el códigovacío; como máximo 123 bytes, tras las plantillasSí

Salidas: Salida. Sin ajustes.

json
{ "id": "bye", "type": "ws_close", "x": 960, "y": 80, "connection": "socket", "code": 1000, "reason": "done" }

Marca de registro ​

Escribe una línea en la línea de tiempo y el informe — un punto de control, o los valores a los que llegó una ejecución.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
MensajemessageEl textoCheck point; como máximo 10 000 caracteresSí

Salidas: Salida. Sin ajustes.

json
{ "id": "ready", "type": "log", "x": 500, "y": 80, "message": "device {{device}} ready" }

Esperas ​

El grupo Observar: nodos que esperan que llegue algo. Comparten estas reglas:

  • Escuchan desde el principio de la ejecución. El puerto o la suscripción al bróker de una espera se abre antes del primer paso, así que no se pierde un dispositivo que responde más rápido de lo que empieza el siguiente paso. Dos esperas en la misma dirección comparten un socket.
  • Cuentan desde la última acción de su rama. Un mensaje que llegó antes de la última solicitud de la rama no es una respuesta a ella; antes de cualquier acción, cuenta todo desde que empezó la ejecución.
  • Se toma el primer mensaje que coincide. Un mensaje que tomó una espera no lo ve otra.
  • Coincide o Tiempo agotado. Cuando coincide, el mensaje se guarda en la variable de la espera y el flujo sigue por Coincide. Cuando se agota el tiempo, sigue por Tiempo agotado si esa salida tiene un cable; si no, el paso falla, indicando cuántos otros mensajes llegaron.
  • Cada socket conserva los 1 024 mensajes más recientes (y 64 MiB); los más antiguos se descartan, y un tiempo de espera agotado dice cuántos eran.
  • Escuchar ahora escucha con ese único paso, a partir de ahora.

Salidas: Coincide (obligatoria), Tiempo agotado (opcional). Ajustes: Reintentar.

Coincidencia de cargas útiles ​

Esperar UDP, Esperar MQTT, Esperar WebSocket y una respuesta UDP eligen cómo debe ser la carga útil:

OpciónEn el archivoCoincide cuando la carga útil
Cualquier datagramaanyes cualquier cosa
Contiene el textocontainsleída como texto UTF-8, contiene el patrón (distingue mayúsculas y minúsculas)
Coincide con la regexregexleída como texto UTF-8, coincide con la expresión regular
Contiene los bytes (hex)hexcontiene los bytes, escritos como pares hex: de ad be ef, deadbeef, 0xde,0xad, DE:AD

El mensaje que coincidió se guarda como un objeto. Los pasos posteriores leen sus campos como {{reply.text}} (con el nombre de la variable en lugar de reply):

CampoQué
textLa carga útil como texto
hex, bytesLa carga útil en hex (sus primeros 1 024 bytes), y su tamaño en bytes
matchLo que coincidió: el texto, el primer grupo de la expresión regular (o toda la coincidencia), o los bytes
fromEl IP:port del remitente
msMilisegundos desde la última acción de la rama (o el inicio de la ejecución) hasta el mensaje
topicEsperar MQTT: el tema en el que se publicó
json, kindEsperar WebSocket: el mensaje analizado como JSON (null cuando no lo es), y text o binary

Esperar OSC ​

Espera un mensaje OSC cuya dirección coincide con un patrón y cuyos argumentos cumplen todas las reglas. En un bundle, se toma el primer mensaje que coincide.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Escuchar en (IP:puerto)bindIP:port en el que escuchar; 0.0.0.0 para todas las tarjetas de red127.0.0.1:9001No
Patrón de direcciónaddress* cualquier carácter, ? uno, [0-9] un conjunto ([!0-9] fuera de él), {ping,pong} cualquiera de los dos; los comodines se quedan dentro de un segmento //pong; como máximo 512 caracteresSí
Reglas de argumentosargs[{ "index", "op", "value" }, …]: el argumento index comparado con value por op (Comparaciones); deben cumplirse todasninguna; como máximo 16, índice 0–63Valores: sí
Tiempo de espera, mstimeout_ms2 000 (también si falta); 1–120 000No
Variable de respuestavariableDónde se guarda el mensajereply (también si falta)No

Un argumento se compara como texto: los números tal como se escriben, las cadenas sin comillas, true/false, un blob en hex. Una regla sobre un argumento que el mensaje no tiene no se cumple. El mensaje guardado tiene address, args ({{reply.args[0]}}), from y ms.

json
{ "id": "status", "type": "wait_osc", "x": 500, "y": 80, "bind": "0.0.0.0:9001", "address": "/status",
  "args": [{ "index": 0, "op": "eq", "value": "ready" }], "timeout_ms": 5000, "variable": "reply" }

Esperar UDP ​

Espera un datagrama UDP cuya carga útil coincide.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Escuchar en (IP:puerto)bindIP:port en el que escuchar127.0.0.1:9001No
Carga útilmodeConsulta Coincidencia de cargas útilescontains (any si falta)No
PatrónpatternLo que la carga útil debe contener o con lo que debe coincidirpong; obligatorio salvo anySí
Tiempo de espera, mstimeout_ms2 000 (también si falta); 1–120 000No
Variable de respuestavariablereply (también si falta)No
json
{ "id": "ready", "type": "wait_udp", "x": 500, "y": 80, "bind": "0.0.0.0:9002", "mode": "contains",
  "pattern": "READY", "timeout_ms": 5000, "variable": "reply" }

Esperar MQTT ​

Espera un mensaje publicado en un tema de un bróker, cuya carga útil coincide. La ejecución se conecta y se suscribe antes de su primer paso. Los mensajes retenidos que el bróker reproduce al suscribirse se ignoran: solo cuenta lo que se publica después de que empezó la ejecución.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Host del brókerhostEl bróker127.0.0.1Solo parámetros
Puertoport1883; 1–65 535No
Filtro de temastopicUn filtro: + es un nivel cualquiera, # todo lo que hay debajo (solo al final)lab/#Solo parámetros
Carga útilmodeConsulta Coincidencia de cargas útilesany (también si falta)No
Patrónpatternvacío; obligatorio salvo anySí
Tiempo de espera, mstimeout_ms2 000 (también si falta); 1–120 000No
Variable de respuestavariablereply (también si falta)No
json
{ "id": "state", "type": "wait_mqtt", "x": 500, "y": 80, "host": "{{broker}}", "port": 1883,
  "topic": "lab/+/state", "mode": "contains", "pattern": "on", "timeout_ms": 5000, "variable": "reply" }

Esperar una solicitud HTTP ​

Espera una solicitud HTTP — un webhook, una retrollamada — al Emulador de la ejecución en esa dirección o, cuando la ejecución no tiene ahí ningún emulador HTTP, a un escucha propio de la ejecución que responde a cada solicitud con 204. La solicitud debe coincidir con el método, la ruta de acceso y todas las condiciones.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Escuchar en (IP:puerto)bindIP:port127.0.0.1:18080 — donde escucha un Emulador nuevoNo
MétodomethodUn método, o Cualquiera (ANY); GET también acepta HEADANY (también si falta)No
Ruta de accesopath/hooks/:name nombra un segmento ({{request.params.name}}); un /* final toma el resto/* (también si falta); como máximo 512 caracteresSí
Condicioneswhen[{ "on", "name", "op", "value" }, …] sobre un header, un parámetro query, el body o una ruta json; debe cumplirse cada unoninguna; como máximo 16Sí, nombres y valores
Tiempo de espera, mstimeout_ms5 000 (2 000 si falta); 1–120 000No
Variable de respuestavariablerequest (también si falta)No

La solicitud guardada tiene method, path, query, headers, body, json, params, from y ms: {{request.json.event}}, {{request.headers.x-key}}.

json
{ "id": "hook", "type": "wait_http", "x": 500, "y": 80, "bind": "127.0.0.1:18081", "method": "POST",
  "path": "/hooks/:name", "when": [{ "on": "json", "name": "$.event", "op": "eq", "value": "deploy" }],
  "timeout_ms": 5000, "variable": "request" }

Esperar WebSocket ​

Espera un mensaje en la conexión que abrió un Conectar WebSocket, cuya carga útil coincide. Cuentan los mensajes desde la última acción de la rama — la propia conexión, un envío o cualquier otra solicitud.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
ConexiónconnectionEl id de un nodo Conectar WebSocketel primeroNo
Carga útilmodeConsulta Coincidencia de cargas útilesany (también si falta)No
Patrónpatternvacío; obligatorio salvo anySí
Tiempo de espera, mstimeout_ms2 000 (también si falta); 1–120 000No
Variable de respuestavariablereply (también si falta)No

Un mensaje JSON se puede leer campo por campo: {{reply.json.type}}. La conexión debe preceder a la espera en su ruta.

json
{ "id": "pong", "type": "wait_ws", "x": 730, "y": 80, "connection": "socket", "mode": "contains",
  "pattern": "pong", "timeout_ms": 3000, "variable": "reply" }

Emulación ​

Emulador ​

Hace el papel de una dependencia — una API HTTP, un dispositivo OSC, UDP o TCP, un bróker MQTT — durante toda la ejecución. Se abre antes del primer paso y responde hasta que termina la ejecución; en el flujo, el paso se supera de inmediato. Lo que recibió se cuenta, regla por regla, en el informe de la ejecución.

CampoEn el archivoQuéPredeterminado
Editar…emulatorEl emulador: name, bind (IP:port), protocol (http, osc, udp, tcp, mqtt), sus rutas o reglas, y una outage opcionalUna API HTTP llamada API en 127.0.0.1:18080 que responde a /health

Las propiedades muestran lo que hace en una línea. Editar… abre sus reglas, el mismo editor que la pantalla Emuladores; A la biblioteca guarda una copia en la biblioteca de emuladores, y De la biblioteca sustituye este por una copia de ella. Las reglas — rutas, respuestas, fallos, caídas — se describen allí.

  • Un emulador HTTP es también lo que lee una Esperar solicitud HTTP en su dirección; un emulador OSC o UDP comparte su puerto con las esperas de la ejecución allí.
  • Dos emuladores de un mismo transporte no pueden compartir un puerto en una ejecución.
  • Emulador caído/activo lo baja y lo vuelve a subir.

Salidas: Salida. Sin ajustes.

json
{ "id": "api", "type": "emulator", "x": 270, "y": 80,
  "emulator": { "name": "Orders API", "bind": "127.0.0.1:18080", "protocol": "http",
    "routes": [{ "method": "GET", "path": "/orders/:id", "order": "sequence",
                 "responses": [{ "status": 503 }, { "status": 200, "body": "{\"id\":\"{{request.params.id}}\"}" }] }] } }

Fallos ​

Nodos que rompen cosas a voluntad. Una rama de nodos Pausa y estos junto al tráfico se lee como una programación; Fallos programados muestra cómo.

Degradación ​

Un relé de degradación durante toda la ejecución: el sistema bajo prueba envía a (o se conecta a) Escuchar en en lugar del destino real; el relé reenvía a Reenviar a, y las respuestas vuelven por el mismo camino, degradadas por el perfil. Se abre antes del primer paso y se cierra cuando termina la ejecución, de cualquier forma, así que nada queda degradado; en el flujo, el paso se supera de inmediato. Cada decisión se extrae de la semilla de la ejecución: la misma semilla y el mismo tráfico corren la misma suerte.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Escuchar enlistenIP:port al que envía el sistema bajo prueba127.0.0.1:9010Solo parámetros
Reenviar atargetIP:port del destino real, o host:port — un nombre de host se resuelve cuando empieza la ejecución, y un nombre que no se encuentra detiene la ejecución en este nodo127.0.0.1:9000Solo parámetros
ProtocoloprotocolUDP (udp): cada datagrama corre su propia suerte; TCP (tcp): cada conexión se une a una propia hacia el destino, y ambos flujos se degradanUDP (udp si falta)No
Preajuste y los valores bajo élprofileLo que el relé hace al tráfico — consulta El perfilLAN (sin degradación si falta)No

La dirección de escucha de un relé no puede ser otro socket de la ejecución, y los relés no pueden reenviarse entre sí en círculo. Un destino dado por nombre se sigue una vez resuelto, así que un círculo a través de un nombre detiene la ejecución al empezar. El informe cuenta cada fase de un relé por separado.

Salidas: Salida. Sin ajustes.

json
{ "id": "relay", "type": "impairment", "x": 270, "y": 80, "listen": "127.0.0.1:9010", "target": "{{device}}",
  "profile": { "name": "lan", "latency_ms": 1, "jitter_ms": 1 } }

El perfil ​

Un chip de preajuste — LAN, Wi-Fi saturada, 4G, Satélite, Intermitente, Sin conexión — rellena todos los valores; cambia cualquiera de ellos después. Un relé solo lee los valores de su protocolo; en un archivo puede omitirse cualquier clave (cero, desactivado).

CampoEn el archivoQuéLímitesProtocolo
—nameUna etiqueta para la línea de tiempo y el informe: la clave de un preajuste (lan, wifi, 4g, satellite, intermittent, offline) o la tuyacomo máximo 60 caracteresambos
Sin conexión — no pasa nadaofflineNo pasa nadatrue / falseambos
Latencialatency_msRetardo añadido a cada paquete, o trozo de un flujo0–60 000 (el deslizador llega a 1 000)ambos
Jitterjitter_msUn retardo extra aleatorio de hasta este tiempo; un flujo TCP se mantiene en orden0–60 000 (el deslizador llega a 500)ambos
Ancho de banda, kbit/srate_kbpsUn límite de ancho de banda, 0 para ninguno. UDP: pasado un segundo de cola, los datagramas se descartan como limitados; TCP: se frena al emisor, no se descarta nada0, o 8–10 000 000ambos
Pérdida de paqueteslossLa probabilidad de que se descarte un datagrama0–1 (el deslizador muestra %)UDP
Pérdida en ráfagas, Longitud de ráfaga, datagramasburst_start, burst_lengthLa probabilidad de que empiece una ráfaga de pérdidas, y cuántos datagramas dura de media0–1; 1–1 000 cuando las ráfagas están activadasUDP
DuplicaciónduplicateLa probabilidad de que un datagrama se envíe dos veces0–1UDP
CorrupcióncorruptLa probabilidad de que se invierta un bit de un datagrama0–1UDP
ReordenaciónreorderLa probabilidad de que un datagrama se retenga, para que los posteriores lo adelanten0–1UDP
Restablecer conexiónresetLa probabilidad de que un trozo de un flujo reinicie su conexión en su lugar — ambos extremos reciben un reinicio0–1TCP
SemiabiertastallLa probabilidad de que un trozo deje su conexión a medias: no pasa nada más en ningún sentido, y no se avisa a ninguno de los dos extremos0–1TCP

Más sobre relés, preajustes y lo que modelan en la página Degradación.

Cambiar degradación ​

Cambia uno de los nodos Degradación de la ejecución a otro perfil a partir de este paso, sin soltar su puerto. La fase hasta ahora se cierra y se cuenta en el informe.

CampoEn el archivoQuéPredeterminadoPlantillas
DegradaciónrelayEl id de un nodo Degradación de este experimentoel primeroNo
Preajuste y los valores bajo élprofileAquello con lo que degrada a partir de ahora — consulta El perfil; el relé lee los valores de su propio protocoloSin conexión (sin degradación si falta)No

El paso falla si el relé no está en marcha — porque no logró reenviar, por ejemplo. Salidas: Salida. Sin ajustes.

json
{ "id": "cut", "type": "impairment_change", "x": 730, "y": 200, "relay": "relay",
  "profile": { "name": "offline", "offline": true } }

Bajar/subir emulador ​

Baja uno de los emuladores de la ejecución, o lo vuelve a subir. Mientras está caído, un emulador HTTP responde como dice Durante la caída; un dispositivo TCP y un bróker MQTT cortan sus conexiones y rechazan las nuevas; los dispositivos OSC y UDP no responden nada. Al subir de nuevo, el emulador sigue su propia programación de caídas, si la tiene.

CampoEn el archivoQuéPredeterminado
EmuladoremulatorEl id de un nodo Emulador de este experimentoel primero
EstadodownCaído (true) o Activo (false)caído (false si falta)
Durante la caídafaultSolo HTTP: 503 No disponible (unavailable), Cerrar la conexión (reset: la conexión se cierra sin respuesta) o Sin respuesta (timeout: la solicitud se retiene hasta que el cliente se rinde, 120 s como máximo)unavailable (también si falta)

Salidas: Salida. Sin ajustes. Nada es una plantilla.

json
{ "id": "down", "type": "emulator_state", "x": 500, "y": 200, "emulator": "api", "down": true, "fault": "unavailable" }

Datos ​

Extraer un valor ​

Guarda una parte de la última respuesta HTTP de su ruta como una variable, para campos posteriores ({{token}}), comprobaciones y ramas. Una solicitud HTTP debe precederlo en todas las rutas. Hacer clic en un valor de una respuesta de Enviar ahora añade uno por ti.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
VariablevariableEl nombre: letras, dígitos y _, sin empezar por un dígito, ni una palabra reservada, ni el nombre de un parámetrotokenNo
Tomar defromCampo JSON (json), Encabezado (header), Código de estado (status), Cuerpo completo (body) o Expresión regular (regex)jsonNo
Ruta JSON, Nombre del encabezado o Patrón (grupo 1 si existe)exprUna ruta JSON ($.data.token, $.items[0], $["first name"]), el nombre de un encabezado (en cualquier caso), o una expresión regular — su primer grupo, o toda la coincidencia$.token; no se usa para el estado y el cuerpoNo

El paso falla cuando no hay nada que tomar: el cuerpo no es JSON, falta la ruta o el encabezado, la expresión no coincide o — para un campo JSON o todo el cuerpo — el cuerpo era más largo que los 256 KiB conservados. Un estado se guarda como número; el resto, como texto, o como el valor JSON encontrado. Salidas: Salida. Sin ajustes.

json
{ "id": "token", "type": "extract", "x": 500, "y": 80, "variable": "token", "from": "json", "expr": "$.data.token" }

Más sobre variables en Datos y plantillas.

Comprobaciones ​

Una comprobación se supera, o falla la ejecución. Las cuatro comprobaciones de respuesta leen la última respuesta HTTP de su ruta, así que una solicitud HTTP — no una bajo carga — debe precederlas en todas las rutas.

Estado HTTP ​

Se supera cuando el estado de la última respuesta es exactamente el indicado.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Estado esperadostatus200; 100–599No

Salidas: Salida. Sin ajustes.

json
{ "id": "ok", "type": "assert_status", "x": 500, "y": 80, "status": 200 }

Texto de la respuesta ​

Se supera cuando el cuerpo de la última respuesta contiene el texto, exactamente (incluidas las mayúsculas y minúsculas). Solo se conservan los primeros 256 KiB de un cuerpo: un texto que no se encuentra en un cuerpo que se cortó falla con ese motivo.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Contiene el textocontainsok; obligatorioSí

Salidas: Salida. Sin ajustes.

json
{ "id": "ready", "type": "assert_body", "x": 500, "y": 80, "contains": "ready" }

Encabezado de la respuesta ​

Se supera cuando la última respuesta tiene el encabezado y su valor contiene el texto. El nombre del encabezado coincide en cualquier caso; el valor, exactamente.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Nombre del encabezadonamecontent-type; obligatorioSí
Contiene el textocontainsLo que debe contener su valor; vacío: el encabezado solo tiene que estarapplication/jsonSí

Salidas: Salida. Sin ajustes.

json
{ "id": "json", "type": "assert_header", "x": 500, "y": 80, "name": "Content-Type", "contains": "json" }

Tiempo de respuesta ​

Se supera cuando la última respuesta tardó como máximo este tiempo, desde el envío de la solicitud hasta el final de su cuerpo.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Tiempo máximo, msmax_ms1 000; 1–120 000No

Salidas: Salida. Sin ajustes.

json
{ "id": "fast", "type": "assert_latency", "x": 500, "y": 80, "max_ms": 250 }

Comprobar un valor ​

Compara un valor — normalmente una variable, escrita como plantilla — con uno esperado, y se supera cuando se cumple la comparación.

CampoEn el archivoQuéPredeterminadoPlantillas
ValorvalueLo que se compara: {{token}}, {{reply.args[0]}}{{token}}Sí
CondiciónopConsulta Comparacionesno está vacíoNo
EsperadoexpectedNo lo usan está vacío ni no está vacíovacío (también si falta)Sí

Salidas: Salida. Sin ajustes.

json
{ "id": "state", "type": "assert_value", "x": 730, "y": 80, "value": "{{state}}", "op": "eq", "expected": "ready" }

Comparaciones ​

Comprobar valor, Rama por valor, la condición de salida de un Bucle, las reglas de argumentos de OSC y las condiciones HTTP comparan del mismo modo:

OpciónEn el archivoSe cumple cuando el valor
es igual aeqes igual al esperado — como números cuando ambos son números (200 = 200.0), si no como texto exacto
no es igual aneno es igual a él, por la misma regla
menor que, como máximo, mayor que, como mínimolt, le, gt, gees menor, como máximo, mayor, como mínimo — ambos deben ser números: si no, una comprobación, una rama o un Bucle falla el paso, y una regla de argumentos o una condición HTTP no se cumple
contienecontainscontiene el texto esperado
coincide con la regexmatchescoincide con la expresión regular esperada
está vacío, no está vacíoempty, not_emptyestá vacío (los espacios cuentan como vacío) / no lo está

Flujo ​

Nodos que deciden adónde va la ejecución. Más sobre ramas, uniones y bucles en Flujo.

Inicio ​

Donde empieza la ejecución; cada experimento tiene exactamente uno. No tiene entrada ni campos. La primera fila de la línea de tiempo da la semilla de la ejecución.

Salidas: Salida, obligatoria. Varios cables desde él inician ramas paralelas a la vez.

json
{ "id": "start", "type": "start", "x": 40, "y": 80 }

Fin ​

Donde se completa la ejecución; cada experimento tiene exactamente uno, y no tiene salidas. Varias ramas pueden conducir a él: la ejecución se supera una vez, después de que termine la última rama, y solo si ninguna falló. Una ejecución que nunca llega a Fin falla.

json
{ "id": "end", "type": "end", "x": 960, "y": 80 }

Retardo ​

Espera un tiempo fijo antes del siguiente paso.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Pausa (ms)ms300; 0–60 000No

Salidas: Salida. Sin ajustes. Para esperas más largas, pon varios en fila o en un Bucle.

json
{ "id": "pause", "type": "delay", "x": 500, "y": 80, "ms": 500 }

Rama por estado ​

Elige Sí cuando la última respuesta HTTP tiene este estado, si no No. Una solicitud HTTP debe precederla en todas las rutas.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Estado esperadostatus200; 100–599No

Salidas: Sí y No, ambas obligatorias. Sin ajustes.

json
{ "id": "branch", "type": "branch_status", "x": 500, "y": 80, "status": 200 }

Rama por valor ​

Elige Sí cuando se cumple una comparación, si no No. Sus campos y sus comparaciones son los de Comprobar valor; una comparación que no se puede hacer (lt sobre texto) falla el paso.

CampoEn el archivoQuéPredeterminadoPlantillas
ValorvalueLo que se compara{{token}}Sí
Condiciónopes igual aNo
Esperadoexpectedvacío (también si falta)Sí

Salidas: Sí y No, ambas obligatorias. Sin ajustes.

json
{ "id": "ok", "type": "branch_value", "x": 730, "y": 80, "value": "{{reply.args[0]}}", "op": "eq", "expected": "ok" }

Rama paralela ​

Ejecuta lo que sigue a Rama 1 y Rama 2 al mismo tiempo, cada rama con su propia copia de las variables. Cada salida puede tener más cables para más ramas. Sin campos.

Salidas: Rama 1 y Rama 2, ambas obligatorias.

json
{ "id": "split", "type": "fork", "x": 270, "y": 80 }

Unir ramas ​

Espera hasta que se haya alcanzado cada cable que entra en él, luego continúa una vez, con las variables de las ramas fusionadas — cuando dos ramas establecen la misma variable, gana la cuyo cable aparece más tarde en el archivo — y la última respuesta HTTP de la última de ellas que tuvo una. Sin campos.

Solo se encuentran aquí las ramas que se ejecutan todas: un Unir ramas detrás de un Rama por estado, cuyos Sí y No nunca ocurren ambos, nunca continúa; cuando ninguna otra ruta llega a Fin, la ejecución falla en este nodo, indicando cuántas ramas seguía esperando.

Salidas: Salida, obligatoria.

Cualquier otro nodo con varios cables que entran en él se ejecuta una vez por cada llegada.

json
{ "id": "joined", "type": "join", "x": 730, "y": 80 }

Bucle ​

Ejecuta los pasos de Cuerpo — que vuelven a él — una y otra vez: como máximo un número de veces y, cuando tiene una condición de salida, hasta que se cumple.

CampoEn el archivoQuéPredeterminado y límitesPlantillas
Iteraciones como máximomaxIteraciones como máximo5; 1–1 000No
detener antes siuntilCondición de salida opcional { "value", "op", "expected" }, como en Comprobar valordesactivadaValor y esperado: sí
  • El cuerpo siempre se ejecuta al menos una vez. La condición de salida se lee después de cada iteración, así que el cuerpo puede establecer lo que prueba.
  • Hecho sigue cuando se cumple la condición — o, sin condición, tras la última iteración.
  • Límite sigue cuando se agotaron las iteraciones antes de que se cumpliera la condición. Sin un cable en ella, eso falla el paso.
  • Dentro del cuerpo, {{counter}} es el número de la iteración.
  • Un cuerpo se ejecuta como una sola rama: cada salida dentro de él tiene un cable; no contiene Inicio, Fin, Rama paralela, Unir ramas ni otro Bucle; se entra en él solo por Cuerpo; y cada cable dentro de él conduce hacia adelante en el cuerpo o de vuelta al bucle.

Salidas: Cuerpo y Hecho (obligatorias), Límite (opcional). Sin ajustes.

json
{ "id": "poll", "type": "loop", "x": 270, "y": 80, "max": 10,
  "until": { "value": "{{status.args[0]}}", "op": "eq", "expected": "ready" } }