Перейти к содержимому

Данные в экспериментах ​

Значения проходят через запуск: параметр выбирает цель, поле одного ответа становится заголовком следующего запроса, сгенерированный идентификатор уходит в команде и возвращается в проверке. На этой странице — откуда берутся эти значения и как их использует поле.

ИсточникКак записываетсяГде задаётся
Параметр{{api}} или {{params.api}}панель Параметры, профиль, Запустить с…
Переменная{{token}} или {{vars.token}}узел во время запуска: Извлечь значение, ожидание, отправка, которая ждёт ответ
Секрет{{secret.API_TOKEN}}хранилище учётных данных компьютера или окружение и файлы сервера
Встроенное значение{{run.seed}}, {{now.iso}}, {{counter}}сам запуск
Генератор{{uuid}}, {{random_int(1, 100)}}получается из seed запуска

Параметры ​

Параметр — это именованное текстовое значение, которое может использовать любое поле с шаблонами. Храните цели в параметрах: тогда смена адреса — одна правка, а не по одной на каждый узел.

Добавление параметра ​

  1. Нажмите Параметры ({ }) на панели инструментов редактора.
  2. На вкладке По умолчанию нажмите Добавить параметр.
  3. Заполните поля Имя и Значение, например api и http://127.0.0.1:8080.
  4. В поле узла напишите {{api}}/login.

Каждое изменение в панели — это правка эксперимента: она сохраняется вместе с ним и отменяется клавишами Ctrl+Z как любая другая.

Правила ​

ПравилоПредел
Имяначинается с буквы или _, затем буквы, цифры и _
Зарезервированные именаvars, params, secret, run, node, now, uuid, counter, random_int, random_float, pick
Параметров в эксперименте64
Размер одного значения64 КиБ
Именауникальны; у переменной не может быть имени параметра

Значение — простой текст, и подставляется оно как написано: {{…}} внутри значения не раскрывается. Когда поле запрашивает часть параметра ({{config.ports[0]}}), значение читается как JSON; у значения, которое не JSON, частей нет.

Параметр с недопустимым, зарезервированным или повторяющимся именем не мешает сохранению эксперимента, так что можно продолжать вводить; запуск невозможен, пока имя не исправлено.

Профили ​

Профиль — это именованный набор значений параметров, например Ноутбук, Сцена, Площадка, поэтому смена цели — это выбор, а не правка каждого узла. Профиль меняет одни параметры; остальные остаются со значениями по умолчанию.

Создание профиля ​

  1. Откройте Параметры и нажмите Профиль. Откроется новая вкладка.
  2. Переименуйте профиль в поле Имя профиля.
  3. Для каждого параметра, который меняет профиль, введите его значение. Пустое поле сохраняет значение по умолчанию, оно показано в поле серым; кнопка Вернуть значение по умолчанию (↺) очищает значение.
  4. Нажмите Использовать, чтобы запускать с этим профилем. На вкладке активного профиля стоит ● Используется. Кнопка Использовать на вкладке По умолчанию возвращает значения по умолчанию.

Когда в эксперименте появляются профили, между ними переключает список Профиль на панели инструментов. Активный профиль используют запуски, предпросмотр и Отправить сейчас; он сохраняется в эксперименте, поэтому экспортированный файл открывается с теми же целями. Кнопка Удалить профиль удаляет профиль, открытый на экране.

ПравилоПредел
Профилей в эксперименте32
Имя1–64 символа, уникальное (пробелы по краям не считаются)
Значениятолько существующих параметров; не больше 64

Переименование или удаление параметра сразу меняет его во всех профилях.

Какое значение использует запуск ​

Побеждает более поздний пункт:

  1. значение параметра по умолчанию, на вкладке По умолчанию;
  2. значение активного профиля, если оно в нём задано;
  3. значение, введённое в Запустить с… только для этого запуска, — см. запуск с другими значениями.

В Запустить с… можно задать только те параметры, которые есть в эксперименте. Отчёт о запуске записывает профиль, значения, введённые для запуска, и все использованные значения.

Профили, с которыми запуск не пройдёт ​

При каждой проверке эксперимента проверяются и остальные профили, и значения по умолчанию. Если с каким-то из них запуск завершился бы ошибкой — например, из-за URL, который не начинается с http:// или https://, — он помечается ⚠ на вкладках и в списке на панели инструментов, а его подсказка объясняет почему. Запускам с используемым профилем это не мешает.

Шаблоны ​

Текст внутри {{ }} — выражение; всё остальное в поле сохраняется ровно как написано.

text
{{api}}/users/{{user.id}}?trace={{uuid}}
Bearer {{secret.API_TOKEN}}
  • Пробелы внутри скобок не важны: {{ token }} — это {{token}}.
  • \{{ записывает буквальные {{.
  • Одиночные }} — обычный текст.
  • Значение подставляется как есть, без кавычек. В теле JSON кавычки пишите сами: "id": "{{uuid}}".

Имена ​

ВыражениеЗначение
{{name}}переменная name, если она задана на этом пути, иначе параметр name
{{vars.name}}только переменная
{{params.name}}только параметр
{{secret.NAME}}сохранённый секрет NAME — см. секреты
{{name.field}}поле значения JSON
{{name[0]}}элемент массива JSON
{{name["a b"]}}, {{name['a b']}}поле, в имени которого есть другие символы

Имя поля после . может содержать буквы, цифры, _ и -. Шаги соединяются в цепочку: {{reply.args[0]}}, {{order.items[2].sku}}.

Как записываются значения ​

ЗначениеКак записывается
текстсам текст
числократчайшая запись: 42, 0.5
true, falsetrue, false
nullnull
объект, массивкомпактный JSON: ["x","y"]

Встроенные значения ​

ВыражениеЗначение
{{run.id}}номер задачи запуска; 0 в предпросмотре и в Отправить сейчас
{{run.seed}}seed этого запуска
{{node.id}}идентификатор выполняемого узла
{{now}}текущее время, миллисекунды Unix
{{now.iso}}текущее время в UTC, ISO 8601 с миллисекундами: 2026-09-30T12:34:56.789Z
{{counter}}сколько раз этот узел выполнялся в этом запуске, считая текущий, начиная с 1

{{counter}} считает для каждого узла отдельно: в теле цикла это номер итерации, в узле, который отправляет серией, — номер отправки. У run, node и now есть только перечисленные поля; всё остальное — ошибка.

Генераторы ​

ВыражениеЗначение
{{uuid}} или {{uuid()}}UUID версии 4
{{random_int(min, max)}}целое число от min до max, обе границы включены; аргументы — целые числа, min ≤ max
{{random_float(min, max)}}число от min (включительно) до max (не включительно), с 3 знаками после запятой; min < max
{{random_float(min, max, digits)}}то же с digits знаками после запятой, 0–9
{{pick(a, b, c)}}один из аргументов, их должно быть не меньше одного

Аргументы разделяются запятыми. Аргумент в кавычках ("dark blue" или 'a, b') может содержать что угодно, кроме собственной кавычки; аргумент без кавычек — буквы, цифры и _ - . : / +. Пустой аргумент — ошибка.

Каждый генератор берёт значения из seed запуска. Значения одного выполнения узла зависят только от seed, идентификатора узла и того, сколько раз узел уже выполнялся, поэтому параллельные ветки никогда не меняют значения друг друга, а запуск с тем же seed снова создаёт те же значения. Внутри одного узла значения выбираются в порядке его полей. {{now}} и {{run.id}} не воспроизводятся. См. seed.

Подсказки при вводе ​

Если ввести {{ в поле с шаблонами или нажать Ctrl+Space, откроется список из четырёх групп: Параметры с их значениями, Переменные, заданные до этого узла, с указанием узла, который их задаёт (в том числе поля ответа, например reply.args[0]), Секреты и Генераторы. ↑ и ↓ выбирают, Enter или Tab вставляет, Esc закрывает список, оставляя поле.

Неизвестные имена — это ошибки ​

Имя без значения никогда не превращается в пустую строку. Перед запуском каждое имя, которое использует поле, должно быть параметром, допустимым именем секрета или переменной, заданной на каждом пути, который ведёт к узлу. Редактор указывает на узел и поле:

ПроблемаДо запускаВо время запуска
Имя, которое никто не задаётname.unknown—
Переменная, заданная только на некоторых путяхname.not_on_every_path—
{{params.x}} без параметра xparam.unknown—
Поле, которого у значения нет—template.no_field
Незакрытая {{, пустая {{}}, неверный аргументtemplate.*, с позицией—

Тексты этих кодов приведены на странице Сообщения об ошибках.

Какие поля принимают шаблоны ​

УзелПоля с шаблонами
HTTP-запросURL, имена и значения заголовков, тело, имя пользователя и пароль Basic и Digest, токен Bearer
OSC-сообщениецель, адрес, текстовые аргументы; с ответом: его шаблон адреса и значения правил
UDP-датаграммацель, содержимое; с ответом: его шаблон
TCP-сообщениехост, содержимое
Публикация MQTTхост брокера, топик, содержимое
Лог / Отметкасообщение
Текст ответаожидаемый текст
Заголовок ответаимя заголовка, ожидаемый текст
Проверка значения, Ветвление по значению, условие выхода узла Циклзначение, ожидаемое значение
Ждать OSCшаблон адреса, значения правил
Ждать UDP, Ожидание WebSocketшаблон
Ждать MQTTброкер и топик (только параметры), шаблон
Ждать HTTP-запросшаблон пути, условия
Сетевые помехиадрес прослушивания и цель (только параметры)
Подключение WebSocketURL, имена и значения заголовков
Отправка WebSocketсодержимое
Закрытие WebSocketпричина

Числа — порты, таймауты, задержки, статусы, типизированные числа OSC — и адреса прослушивания у ожиданий задаются буквально. Узел Эмулятор составляет свои ответы из того, что пришло ({{request.…}}), и параметров; см. сбои.

Только параметры. Некоторые поля открываются до первого шага, когда ни одной переменной ещё нет: брокер и топик узла Ждать MQTT, адрес прослушивания и цель узла Сетевые помехи. Они принимают текст и параметры, ничего больше (node.params_only).

Проверяются как литералы. Поле, в котором только параметры, раскрывается до запуска и проверяется как текст, который отправит запуск: URL должен быть http:// или https://, цель OSC — IP:port или host:port, имя заголовка — допустимым. Поле с переменными или генераторами проверяется при выполнении.

Предпросмотр ​

Когда у выбранного узла есть шаблон, его свойства показывают, что он сделает с известными сейчас значениями: Будет отправлено для отправки, Будет ожидаться для ожидания, Будет сравниваться для сравнения. Предпросмотр вычисляет движок, тем же кодом, что и запуск, поэтому предпросмотр никогда не расходится с запуском.

  • Параметры берутся из активного профиля.
  • Переменные берутся из того, что редактор увидел в этой сессии: шаги последнего запуска и Отправить сейчас.
  • Сохранённый секрет показывается как ••••.
  • Имя, у которого пока нет значения, остаётся как написано, и предпросмотр перечисляет такие имена. Секрет, который не сохранён, перечисляется отдельно.
  • Генераторы используют закреплённый seed эксперимента, а если он не закреплён, то 0, как при первом выполнении узла. Когда seed закреплён, предпросмотр показывает сгенерированные значения, которые узел отправит при своём первом выполнении в запуске.

Извлечение значений ​

Извлечь значение читает одно значение из последнего HTTP-ответа на своём пути и записывает его в переменную.

ПолеЧто
Переменнаяпеременная, в которую пишется значение; действуют правила именования параметров
Откуда взятьоткуда берётся значение (ниже)
JSON-путь, Имя заголовка или Регулярное выражение (группа 1, если есть)что читать, в зависимости от источника
Откуда взятьЧитаетЗначение
Поле JSONтело как JSON, по путизначение JSON: текст, число, объект, массив
Заголовокпервый заголовок с таким именем, в любом регистретекст
Код статусакод статусачисло
Всё теловсё телотекст
Регулярное выражениепервое совпадение в телегруппа захвата 1, если она есть в выражении, иначе всё совпадение

Пути JSON. $.token, $.items[0].id, $["a b"], $['a b']['c-d']; начальное $. можно опустить (token, items[0].id), а один $ означает всё тело.

Регулярные выражения используют синтаксис движка regex языка Rust, в котором нет look-around и обратных ссылок. Совпадение ищется в любом месте тела; если это важно, привяжите выражение через ^ и $.

Шаг завершается ошибкой, называя то, чего не хватает, если:

  • перед ним на этом пути не выполнялся ни один HTTP-запрос (check.no_response; редактор и так отклоняет граф, где его быть не может, — graph.needs_http);
  • тело — не JSON или в нём нет этого пути;
  • заголовка нет или выражение не совпало;
  • тело больше 256 КиБ, которые хранит ответ, — для пути JSON или всего тела, а также для выражения, которое ничего не нашло в сохранённой части (extract.truncated).

Лента запуска показывает записанное значение: token = abc123.

Извлечение щелчком

Отправить сейчас у узла HTTP-запрос показывает его JSON-ответ. Щёлкните значение в нём: после запроса добавится узел Извлечь значение с заполненным путём и именем, взятым из ключа, а значение сразу станет известно предпросмотру.

Переменные ​

Переменная хранит значение JSON. Её записывают эти узлы:

УзелЗаписываетНа выходе
Извлечь значениеизвлечённое значениеего выход
Ждать OSC, Ждать UDP, Ждать MQTT, Ждать HTTP-запрос, Ожидание WebSocketто, что пришло; имя по умолчанию reply (request для HTTP)только Получено
OSC-сообщение, UDP-датаграмма с ждать ответответ, имя по умолчанию replyего выход

То, что записывает ожидание, — объект; следующие поля читают его части:

ОжиданиеПоля
OSCaddress, args, from, ms
UDPtext, hex, bytes, from, ms и match, если задан шаблон
MQTTtopic и поля UDP
WebSocketполя UDP и json, если сообщение — JSON
HTTP-запросmethod, path, query, headers, body, json, params, from, ms

ms — время от последнего действия ветки до прихода. Точное содержимое описано в справочнике узлов.

Где известна переменная ​

Переменная существует от выхода, который её записывает, и дальше — на путях, проходящих через этот выход:

  • После слияния альтернативных путей — когда Да и Нет ветвления встречаются снова — известно только то, что задал каждый путь.
  • После Слияние потоков известно то, что задала любая ветка, входящая в него: все они выполнились.
  • После выхода Готово или Лимит узла Цикл и в его условии выхода известно то, что задаёт каждая итерация тела.
  • Переменная ожидания неизвестна после его выхода Таймаут.

Каждая параллельная ветка работает со своей копией переменных. Слияние объединяет копии в порядке входящих связей, и если имя задали обе, побеждает более поздняя связь, так что результат никогда не зависит от того, какая ветка закончила первой. См. как идёт запуск.

Сравнение значений ​

Проверка значения завершает запуск ошибкой, если сравнение не выполняется; Ветвление по значению выходит через Да или Нет; Цикл использует то же сравнение как условие выхода. У каждого есть поля Значение, Условие и Ожидается; значение и ожидаемое значение — шаблоны:

ЗначениеУсловиеОжидается
{{status}}меньше300
{{reply.args[0]}}равно{{nonce}}
УсловиеВыполняется, когда
равно, не равнооба значения равны (не равны) — как числа, если оба являются числами (200 равно 200.0), иначе как точный текст, с учётом регистра
меньше, не больше, больше, не меньшекак числа; сторона, не являющаяся числом, завершает шаг ошибкой (compare.not_numbers) вместо тихого нет
содержитзначение содержит ожидаемый текст, с учётом регистра
соответствует regexрегулярное выражение в ожидаемом значении совпадает где-либо в значении
пусто, не пустозначение пусто или не пусто после обрезки пробелов; ожидаемое значение не используется

Число — это текст, который после обрезки пробелов читается как число: 42, -1.5, 1e3. Лента запуска показывает сравнение в том виде, в каком оно выполнено, — 401 = 200, — каждая сторона обрезана до 120 символов.

Секреты ​

Токен или пароль вводится в поле как {{secret.NAME}}. Файл эксперимента хранит только имя; значение остаётся там, где хранится, и никогда не попадает в интерфейс.

Где живут секреты ​

Где работает Signal LabХранилищеИз интерфейса
Десктопное приложение в WindowsДиспетчер учётных данных Windows, служба SignalLab, по записи на каждое имязадать, заменить, удалить
Десктопное приложение в Linuxнет: запуск, которому нужен секрет, завершается ошибкой secret.unsupported—
Серверпеременная окружения SIGNALLAB_SECRET_<NAME>, иначе файл <NAME> в его папке секретов, /run/secrets/signallab, если не задано иноетолько чтение
signallab в командной строкекак у сервера или Диспетчер учётных данных Windows с --secrets system—

У заголовка раздела Секреты есть подсказка, которая говорит, какой из этих вариантов действует там, где вы находитесь: хранилище Windows, окружение и файлы сервера или — в десктопном приложении в Linux — что хранилища нет. Там secret.unsupported сообщает, что секреты хранятся в Диспетчере учётных данных Windows, которого в этой системе нет.

Секрет принадлежит компьютеру или серверу, а не одному эксперименту: два эксперимента, которые используют {{secret.API_TOKEN}}, используют одно и то же значение.

На сервере переменная окружения важнее файла. Завершающий перевод строки в файле не входит в значение, а пустой файл считается отсутствием секрета. Папка сервера задаётся параметром --secrets-dir или переменной SIGNALLAB_SECRETS_DIR; см. сервер. О командной строке — в разделе signallab run.

ПравилоПредел
Имяначинается с буквы или _, затем буквы, цифры и _; не больше 128 символов
Значениене пустое, не больше 16 КиБ

Как задать секрет ​

В Windows:

  1. Откройте Параметры. В разделе Секреты перечислены все секреты, которые используют поля эксперимента, у каждого указано сохранён или не задан на этом компьютере.
  2. Нажмите Задать… рядом с именем или Секрет для имени, которое пока не использует ни одно поле.
  3. Введите значение — поле показывает точки — и нажмите Сохранить или Enter. Поле очищается; прочитать значение обратно невозможно.

Кнопка Заменить… сохраняет новое значение, а Удалить удаляет его из хранилища учётных данных. Имя, сохранённое в этой сессии, предлагается и в списке подсказок при вводе.

В браузере, подключённом к серверу, раздел говорит только задан на сервере или не задан на сервере: задайте значение там, где работает сервер, одним из двух способов:

bash
# в окружении сервера
SIGNALLAB_SECRET_API_TOKEN='…'
# или файлом в его папке секретов
printf '%s' '…' > /run/secrets/signallab/API_TOKEN

Файл читается при каждом старте запуска, поэтому изменённый файл действует со следующего запуска; после изменения переменной окружения сервер нужно перезапустить.

Перед запуском ​

Каждый секрет, который используют поля запуска, должен быть сохранён. Недостающий секрет останавливает запуск ещё до какого-либо трафика, на первом узле и поле, которые его используют (secret.missing). Отправить сейчас делает ту же проверку для своего узла.

Маскирование ​

Пока запуск или Отправить сейчас используют секреты, каждое вхождение их значений заменяется на •••• во всём, что покидает движок:

  • тексты шагов, ошибки и переменные, записанные шагом;
  • отчёт о запуске;
  • результат Отправить сейчас, включая показанный им HTTP-ответ;
  • кадры Инспектор, захваченные, пока длится запуск, — в hex-дампе каждый байт значения превращается в *, так что смещения остаются верными.

Аутентификация Basic отправляет name:password в base64; если секрет есть в любой из частей, этот текст base64 тоже маскируется. Сам трафик несёт настоящее значение. Предпросмотр показывает сохранённый секрет как ••••. Ответы узла Эмулятор секреты использовать не могут.

Команды ​

Предпросмотр — это experiment_resolve; секреты перечисляются, задаются и удаляются командами secret_status, secret_set и secret_delete. Ни одна команда не возвращает значение секрета.