feat: add 15 auto-test functions + destroy-test + versioning rules
Batch 1: ok, echo, error, cpu, slow Batch 2: jsonout, recurse, bigdata, math, timestamp Batch 3: multiline, encoding, nested, memory, chain Tests: create, update (code_hash), idempotency, destroy, re-create All 15 functions verified via curl with JWT auth
This commit is contained in:
@@ -64,6 +64,25 @@ ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=
|
||||
|
||||
Коммитить и пушить после каждого завершённого этапа.
|
||||
|
||||
### Версионирование тегами
|
||||
|
||||
После каждого коммита с изменениями — поднимать версию тега:
|
||||
|
||||
```bash
|
||||
# Посмотреть текущий тег
|
||||
git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0"
|
||||
|
||||
# Поднять patch-версию (v0.1.0 → v0.1.1, v0.1.1 → v0.1.2 и т.д.)
|
||||
git tag vX.Y.Z && git push origin vX.Y.Z
|
||||
```
|
||||
|
||||
**Правила:**
|
||||
- Patch (Z) — любое изменение: правка кода, новая функция, фикс
|
||||
- Minor (Y) — новая фича/компонент (новый ресурс провайдера, новый модуль консоли)
|
||||
- Major (X) — breaking change
|
||||
- Тег ставить ПОСЛЕ успешного коммита и пуша
|
||||
- Формат: `vMAJOR.MINOR.PATCH` (например `v0.2.3`)
|
||||
|
||||
---
|
||||
|
||||
## Как создать и задеплоить новую Fission-функцию через Terraform
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
def main():
|
||||
lines = []
|
||||
for i in range(500):
|
||||
lines.append(f"line-{i}: {'x' * 80}")
|
||||
return "\n".join(lines)
|
||||
@@ -0,0 +1,9 @@
|
||||
import hashlib
|
||||
import json
|
||||
|
||||
def main():
|
||||
data = {"step": 1, "value": "start"}
|
||||
for i in range(2, 6):
|
||||
h = hashlib.sha256(json.dumps(data).encode()).hexdigest()[:8]
|
||||
data = {"step": i, "prev_hash": h, "value": f"chain-{i}"}
|
||||
return json.dumps(data)
|
||||
@@ -0,0 +1,5 @@
|
||||
def main():
|
||||
s = 0
|
||||
for i in range(1, 100000):
|
||||
s += (i * i) % 97
|
||||
return f"cpu-load:{s}"
|
||||
@@ -0,0 +1,5 @@
|
||||
def main():
|
||||
s = 0
|
||||
for i in range(1, 100000):
|
||||
s += (i * i) % 97
|
||||
return f"cpu-load:{s}"
|
||||
@@ -0,0 +1,4 @@
|
||||
def main():
|
||||
import os
|
||||
msg = os.environ.get("FISSION_INPUT", "echo-default")
|
||||
return f"echo:{msg}"
|
||||
@@ -0,0 +1,5 @@
|
||||
import os
|
||||
|
||||
def main():
|
||||
msg = os.environ.get("FISSION_INPUT", "echo-default")
|
||||
return f"echo:{msg}"
|
||||
@@ -0,0 +1,5 @@
|
||||
def main():
|
||||
emoji = "\U0001f680\U0001f525\u2764\ufe0f"
|
||||
cyrillic = "\u041f\u0440\u0438\u0432\u0435\u0442 \u043c\u0438\u0440!"
|
||||
chinese = "\u4f60\u597d\u4e16\u754c"
|
||||
return f"emoji:{emoji} cyr:{cyrillic} zh:{chinese}"
|
||||
@@ -0,0 +1,2 @@
|
||||
def main():
|
||||
raise Exception("auto-error-test")
|
||||
@@ -0,0 +1,2 @@
|
||||
def main():
|
||||
raise Exception("auto-error-test")
|
||||
@@ -0,0 +1,9 @@
|
||||
import json
|
||||
|
||||
def main():
|
||||
data = {
|
||||
"status": "ok",
|
||||
"items": [{"id": i, "value": i * i} for i in range(10)],
|
||||
"count": 10
|
||||
}
|
||||
return json.dumps(data)
|
||||
@@ -0,0 +1,12 @@
|
||||
import math
|
||||
|
||||
def main():
|
||||
results = {
|
||||
"pi": round(math.pi, 10),
|
||||
"e": round(math.e, 10),
|
||||
"sqrt2": round(math.sqrt(2), 10),
|
||||
"factorial20": math.factorial(20),
|
||||
"log1000": round(math.log(1000), 10),
|
||||
}
|
||||
parts = [f"{k}={v}" for k, v in results.items()]
|
||||
return "; ".join(parts)
|
||||
@@ -0,0 +1,6 @@
|
||||
import sys
|
||||
|
||||
def main():
|
||||
big_list = list(range(500000))
|
||||
size_mb = sys.getsizeof(big_list) / (1024 * 1024)
|
||||
return f"memory-alloc:{size_mb:.2f}MB len={len(big_list)}"
|
||||
@@ -0,0 +1,5 @@
|
||||
def main():
|
||||
return """line1
|
||||
line2
|
||||
line3
|
||||
Конец (кириллица)"""
|
||||
@@ -0,0 +1,9 @@
|
||||
def main():
|
||||
try:
|
||||
a = 1 / 0
|
||||
except ZeroDivisionError:
|
||||
try:
|
||||
raise ValueError("nested after div-by-zero")
|
||||
except ValueError as e:
|
||||
return f"caught-nested:{e}"
|
||||
return "unreachable"
|
||||
@@ -0,0 +1,2 @@
|
||||
def main():
|
||||
return "ok-auto-func"
|
||||
@@ -0,0 +1,2 @@
|
||||
def main():
|
||||
return "ok-auto-func-UPDATED-v2"
|
||||
@@ -0,0 +1,8 @@
|
||||
def fib(n):
|
||||
if n <= 1:
|
||||
return n
|
||||
return fib(n - 1) + fib(n - 2)
|
||||
|
||||
def main():
|
||||
result = fib(30)
|
||||
return f"fib(30)={result}"
|
||||
@@ -0,0 +1,4 @@
|
||||
import time
|
||||
def main():
|
||||
time.sleep(2)
|
||||
return "slow-done"
|
||||
@@ -0,0 +1,5 @@
|
||||
import time
|
||||
|
||||
def main():
|
||||
time.sleep(2)
|
||||
return "slow-done"
|
||||
@@ -0,0 +1,5 @@
|
||||
import datetime
|
||||
|
||||
def main():
|
||||
now = datetime.datetime.utcnow().isoformat()
|
||||
return f"timestamp:{now}Z"
|
||||
@@ -0,0 +1,309 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
fission = {
|
||||
source = "nail/fission"
|
||||
version = "~> 0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "fission" {
|
||||
kubeconfig_path = "/home/naeel/.kube/config"
|
||||
namespace = "default"
|
||||
}
|
||||
|
||||
resource "fission_environment" "python" {
|
||||
name = "tf-auto-env"
|
||||
image = "ghcr.io/fission/python-env"
|
||||
version = 3
|
||||
}
|
||||
|
||||
# ok function
|
||||
resource "fission_package" "ok" {
|
||||
name = "tf-auto-ok-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/ok"
|
||||
code_hash = "v2"
|
||||
}
|
||||
resource "fission_function" "ok" {
|
||||
name = "tf-auto-ok-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.ok.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "ok" {
|
||||
name = "tf-auto-ok-route"
|
||||
function = fission_function.ok.name
|
||||
url = "/auto/ok"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# echo function
|
||||
resource "fission_package" "echo" {
|
||||
name = "tf-auto-echo-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/echo"
|
||||
}
|
||||
resource "fission_function" "echo" {
|
||||
name = "tf-auto-echo-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.echo.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "echo" {
|
||||
name = "tf-auto-echo-route"
|
||||
function = fission_function.echo.name
|
||||
url = "/auto/echo"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# error function
|
||||
resource "fission_package" "error" {
|
||||
name = "tf-auto-error-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/error"
|
||||
}
|
||||
resource "fission_function" "error" {
|
||||
name = "tf-auto-error-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.error.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "error" {
|
||||
name = "tf-auto-error-route"
|
||||
function = fission_function.error.name
|
||||
url = "/auto/error"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# cpu function
|
||||
resource "fission_package" "cpu" {
|
||||
name = "tf-auto-cpu-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/cpu"
|
||||
}
|
||||
resource "fission_function" "cpu" {
|
||||
name = "tf-auto-cpu-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.cpu.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "cpu" {
|
||||
name = "tf-auto-cpu-route"
|
||||
function = fission_function.cpu.name
|
||||
url = "/auto/cpu"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# slow function
|
||||
resource "fission_package" "slow" {
|
||||
name = "tf-auto-slow-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/slow"
|
||||
}
|
||||
resource "fission_function" "slow" {
|
||||
name = "tf-auto-slow-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.slow.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "slow" {
|
||||
name = "tf-auto-slow-route"
|
||||
function = fission_function.slow.name
|
||||
url = "/auto/slow"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# --- BATCH 2 ---
|
||||
|
||||
# jsonout: возвращает сложный JSON
|
||||
resource "fission_package" "jsonout" {
|
||||
name = "tf-auto-jsonout-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/jsonout"
|
||||
}
|
||||
resource "fission_function" "jsonout" {
|
||||
name = "tf-auto-jsonout-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.jsonout.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "jsonout" {
|
||||
name = "tf-auto-jsonout-route"
|
||||
function = fission_function.jsonout.name
|
||||
url = "/auto/jsonout"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# recurse: рекурсивный Фибоначчи (нагрузка на стек)
|
||||
resource "fission_package" "recurse" {
|
||||
name = "tf-auto-recurse-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/recurse"
|
||||
}
|
||||
resource "fission_function" "recurse" {
|
||||
name = "tf-auto-recurse-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.recurse.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "recurse" {
|
||||
name = "tf-auto-recurse-route"
|
||||
function = fission_function.recurse.name
|
||||
url = "/auto/recurse"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# bigdata: большой ответ (~45KB текста)
|
||||
resource "fission_package" "bigdata" {
|
||||
name = "tf-auto-bigdata-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/bigdata"
|
||||
}
|
||||
resource "fission_function" "bigdata" {
|
||||
name = "tf-auto-bigdata-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.bigdata.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "bigdata" {
|
||||
name = "tf-auto-bigdata-route"
|
||||
function = fission_function.bigdata.name
|
||||
url = "/auto/bigdata"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# math: математические вычисления
|
||||
resource "fission_package" "math" {
|
||||
name = "tf-auto-math-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/math"
|
||||
}
|
||||
resource "fission_function" "math" {
|
||||
name = "tf-auto-math-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.math.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "math" {
|
||||
name = "tf-auto-math-route"
|
||||
function = fission_function.math.name
|
||||
url = "/auto/math"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# timestamp: текущее время UTC
|
||||
resource "fission_package" "timestamp" {
|
||||
name = "tf-auto-timestamp-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/timestamp"
|
||||
}
|
||||
resource "fission_function" "timestamp" {
|
||||
name = "tf-auto-timestamp-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.timestamp.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "timestamp" {
|
||||
name = "tf-auto-timestamp-route"
|
||||
function = fission_function.timestamp.name
|
||||
url = "/auto/timestamp"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# --- BATCH 3 ---
|
||||
|
||||
# multiline: многострочный вывод с кириллицей
|
||||
resource "fission_package" "multiline" {
|
||||
name = "tf-auto-multiline-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/multiline"
|
||||
}
|
||||
resource "fission_function" "multiline" {
|
||||
name = "tf-auto-multiline-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.multiline.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "multiline" {
|
||||
name = "tf-auto-multiline-route"
|
||||
function = fission_function.multiline.name
|
||||
url = "/auto/multiline"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# encoding: unicode/emoji/кириллица/китайский
|
||||
resource "fission_package" "encoding" {
|
||||
name = "tf-auto-encoding-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/encoding"
|
||||
}
|
||||
resource "fission_function" "encoding" {
|
||||
name = "tf-auto-encoding-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.encoding.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "encoding" {
|
||||
name = "tf-auto-encoding-route"
|
||||
function = fission_function.encoding.name
|
||||
url = "/auto/encoding"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# nested: вложенные try/except
|
||||
resource "fission_package" "nested" {
|
||||
name = "tf-auto-nested-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/nested"
|
||||
}
|
||||
resource "fission_function" "nested" {
|
||||
name = "tf-auto-nested-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.nested.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "nested" {
|
||||
name = "tf-auto-nested-route"
|
||||
function = fission_function.nested.name
|
||||
url = "/auto/nested"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# memory: аллокация памяти (500k элементов)
|
||||
resource "fission_package" "memory" {
|
||||
name = "tf-auto-memory-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/memory"
|
||||
}
|
||||
resource "fission_function" "memory" {
|
||||
name = "tf-auto-memory-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.memory.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "memory" {
|
||||
name = "tf-auto-memory-route"
|
||||
function = fission_function.memory.name
|
||||
url = "/auto/memory"
|
||||
methods = ["GET"]
|
||||
}
|
||||
|
||||
# chain: хеш-цепочка (имитация блокчейна)
|
||||
resource "fission_package" "chain" {
|
||||
name = "tf-auto-chain-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code/chain"
|
||||
}
|
||||
resource "fission_function" "chain" {
|
||||
name = "tf-auto-chain-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.chain.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
resource "fission_http_trigger" "chain" {
|
||||
name = "tf-auto-chain-route"
|
||||
function = fission_function.chain.name
|
||||
url = "/auto/chain"
|
||||
methods = ["GET"]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
def main():
|
||||
return "destroy-test-alive"
|
||||
@@ -0,0 +1,39 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
fission = {
|
||||
source = "nail/fission"
|
||||
version = "~> 0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "fission" {
|
||||
kubeconfig_path = "/home/naeel/.kube/config"
|
||||
namespace = "default"
|
||||
}
|
||||
|
||||
resource "fission_environment" "python" {
|
||||
name = "tf-destroy-test-env"
|
||||
image = "ghcr.io/fission/python-env"
|
||||
version = 3
|
||||
}
|
||||
|
||||
resource "fission_package" "pkg" {
|
||||
name = "tf-destroy-test-pkg"
|
||||
environment = fission_environment.python.name
|
||||
source_dir = "${path.module}/code"
|
||||
}
|
||||
|
||||
resource "fission_function" "fn" {
|
||||
name = "tf-destroy-test-fn"
|
||||
environment = fission_environment.python.name
|
||||
package_name = fission_package.pkg.name
|
||||
entrypoint = "main.main"
|
||||
}
|
||||
|
||||
resource "fission_http_trigger" "route" {
|
||||
name = "tf-destroy-test-route"
|
||||
function = fission_function.fn.name
|
||||
url = "/destroy-test"
|
||||
methods = ["GET"]
|
||||
}
|
||||
Reference in New Issue
Block a user