Files
fission-console/doc/report-2026-04-19.md
T

5.7 KiB

fission-console v0.6.9 — Отчёт о тестировании

Дата: 2026-04-19
Версия: naeel/fission-console:v0.6.9
Ветка: feat/namespace-isolation


Что реализовано

Managed serverless functions service поверх Fission + Kubernetes. Go-бэкенд (консоль), REST API, k8s dynamic client. Пользователи изолированы по namespace (fission-{SHA256(sub)[:16]}).

Поддерживаемые среды выполнения:

  • Node.js 22 (ESM, module.exports / export default / анонимная функция)
  • Python 3.11 (Flask, def main(): без аргументов)

Auth: JWT или TEST_MODE (X-Test-Sub: user@domain → SHA256 → namespace)


Баги исправлены в этой сессии (v0.6.8 → v0.6.9)

# Баг Симптом Фикс
1 Route collision Два разных пользователя создавали функцию с одинаковым маршрутом Префикс последних 12 символов namespace: /{ns[-12:]}/{fn-name}
2 INVOKE несуществующей → 200 Вызов несуществующей функции возвращал HTTP 200 без ошибки GET из k8s перед invoke, IsNotFound → 404
3 DELETE несуществующей → 200 Удаление несуществующей функции возвращало deleted:true Инвертирован if err == nilif err != nil, 404
4 Orphan package при невалидном TTL parseTTL вызывался после создания пакета — при ошибке оставался мусорный package в k8s parseTTL перемещён до создания k8s-ресурсов

Результаты тестирования

PASS=41  FAIL=0

Покрытие (16 блоков):

Блок Что проверяется
A Регресс v0.6.8: INVOKE/DELETE несуществующей → 404, route isolation
B Валидация входных данных → 400 (missing name/code/language, пробелы)
C Дублирующее создание → конфликт
D UPDATE кода + повторный invoke возвращает новый код
E GET функции (200/404)
F LIST изоляция — пользователь видит только свои функции
G Namespace изоляция DELETE — нельзя удалить чужую функцию
H Python def main(): (без аргументов) → invoke 200
I Node.js: module.exports, export.handler, export default
J TTL: expires_at создаётся / не создаётся / невалидный → 400
K ctx.request.url доступен внутри функции
L Stress: 10 параллельных invoke → 10/10 OK
M LIST пустого namespace → []
N DELETE полная цепочка: Function + Package + HTTPTrigger удаляются
O Запрос без auth-заголовка → 401
P POST /auth: без токена → 400, невалидный токен → 401

Архитектурные решения — вопросы для ревью

1. Namespace on-demand

Namespace создаётся при первом обращении пользователя. Нет отдельного registration flow.
Вопрос: правильно ли это? Нет ли рисков при параллельном первом запросе от одного пользователя (race condition на создание namespace)?

2. Сборка функций

Код пользователя пакуется в zip в памяти и передаётся в Fission Package как literal (base64). При обновлении создаётся новый Package, старый удаляется.
Вопрос: нет версионирования. Стоит ли хранить историю версий?

3. Reaper

Горутина раз в 30 секунд проверяет expires-at аннотацию и удаляет протухшие функции вместе с Package и HTTPTrigger. Работает без персистентного стейта — при рестарте пода начинает заново со следующего цикла.
Вопрос: надёжно ли это? Что если под упал в момент удаления — останется ли мусор?

4. Python env и сигнатура main()

Официальный ghcr.io/fission/python-env вызывает main(*args) через Flask. Реально аргументы не передаются (только через route params). При def main(): работает. При def main(ctx):TypeError: main() missing 1 required positional argument.
Вопрос: патчить env или задокументировать ограничение?

5. Валидация имени функции

Имя с пробелами возвращает 502 (k8s отклоняет по RFC 1123), а не 400 (явная валидация в API).
Вопрос: стоит ли добавить regex-валидацию имени на уровне API до обращения в k8s?


Что ещё не сделано

  • Версионирование функций
  • Явная валидация имени функции (RFC 1123) в API
  • Метрики / биллинг
  • Документация API (OpenAPI spec)
  • Merge в master