test: add live acceptance CRUD test and document test flow

This commit is contained in:
Naeel
2026-04-14 23:02:20 +03:00
parent 81852c28b1
commit b1b990ada3
4 changed files with 205 additions and 0 deletions
+7
View File
@@ -52,6 +52,13 @@ cd terraform/provider
go test ./...
```
Acceptance-тест (реальный кластер, опционально):
```bash
cd terraform/provider
ACCEPTANCE_TEST=1 KUBECONFIG=/home/naeel/.kube/config go test ./internal/client -run TestAcceptanceFissionCRUD -v
```
Импорт существующего ресурса (пример):
```bash
+11
View File
@@ -128,3 +128,14 @@
### Следующий шаг
- Добавить acceptance-тесты с опциональным запуском по env-флагу.
### Обновление этапа (acceptance тест)
- Добавлен acceptance-тест `terraform/provider/internal/client/client_acceptance_test.go`.
- Тест выполняет живой CRUD в кластере для цепочки:
- Environment -> Package -> Function -> HTTPTrigger
- Запуск теста:
- `ACCEPTANCE_TEST=1 KUBECONFIG=/home/naeel/.kube/config go test ./internal/client -run TestAcceptanceFissionCRUD -v`
- Результат: PASS.
### Следующий шаг
- Расширить acceptance-тест проверкой реального HTTP-вызова функции через ingress.
+16
View File
@@ -156,3 +156,19 @@
- Повторный `terraform apply` успешен.
- Финальная проверка endpoint:
- `GET /tf-hello` -> `hello from fission via terraform`.
---
Агент: GitHub Copilot
Модель: GPT-5.3-Codex
## План (до действий, этап 9)
1. Добавить acceptance-тест для реального CRUD через `internal/client`.
2. Прогнать unit + acceptance тесты.
3. Зафиксировать результат в документации.
## Результат (после действий, этап 9)
- Добавлен `internal/client/client_acceptance_test.go`.
- Unit-тесты: PASS.
- Acceptance-тест `TestAcceptanceFissionCRUD`: PASS.
- Тест создает и удаляет Environment/Package/Function/HTTPTrigger в реальном кластере.
@@ -0,0 +1,171 @@
package client
import (
"context"
"encoding/base64"
"fmt"
"os"
"testing"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// TestAcceptanceFissionCRUD выполняет интеграционный CRUD тест в реальном кластере.
func TestAcceptanceFissionCRUD(t *testing.T) {
if os.Getenv("ACCEPTANCE_TEST") != "1" {
t.Skip("set ACCEPTANCE_TEST=1 to run acceptance tests")
}
kubeconfigPath := os.Getenv("KUBECONFIG")
if kubeconfigPath == "" {
kubeconfigPath = "/home/naeel/.kube/config"
}
namespace := os.Getenv("FISSION_NAMESPACE")
if namespace == "" {
namespace = "default"
}
c, err := New(kubeconfigPath, os.Getenv("KUBE_CONTEXT"), namespace)
if err != nil {
t.Fatalf("create client: %v", err)
}
ctx := context.Background()
suffix := time.Now().UnixNano()
envName := fmt.Sprintf("acc-env-%d", suffix)
pkgName := fmt.Sprintf("acc-pkg-%d", suffix)
fnName := fmt.Sprintf("acc-fn-%d", suffix)
triggerName := fmt.Sprintf("acc-tr-%d", suffix)
urlPath := fmt.Sprintf("/acc-%d", suffix)
envObj := &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "fission.io/v1",
"kind": "Environment",
"metadata": map[string]interface{}{
"name": envName,
"namespace": namespace,
},
"spec": map[string]interface{}{
"version": 3,
"runtime": map[string]interface{}{
"image": "ghcr.io/fission/python-env",
},
"poolsize": 1,
},
}}
if _, err = c.CreateEnvironment(ctx, envObj); err != nil {
t.Fatalf("create environment: %v", err)
}
defer func() { _ = c.DeleteEnvironment(ctx, namespace, envName) }()
if _, err = c.GetEnvironment(ctx, namespace, envName); err != nil {
t.Fatalf("get environment: %v", err)
}
literal := base64.StdEncoding.EncodeToString([]byte("def main():\n return 'ok from acceptance'\n"))
pkgObj := &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "fission.io/v1",
"kind": "Package",
"metadata": map[string]interface{}{
"name": pkgName,
"namespace": namespace,
},
"spec": map[string]interface{}{
"deployment": map[string]interface{}{
"type": "literal",
"literal": literal,
},
"environment": map[string]interface{}{
"name": envName,
"namespace": namespace,
},
"source": map[string]interface{}{},
},
}}
if _, err = c.CreatePackage(ctx, pkgObj); err != nil {
t.Fatalf("create package: %v", err)
}
defer func() { _ = c.DeletePackage(ctx, namespace, pkgName) }()
if _, err = c.GetPackage(ctx, namespace, pkgName); err != nil {
t.Fatalf("get package: %v", err)
}
fnObj := &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "fission.io/v1",
"kind": "Function",
"metadata": map[string]interface{}{
"name": fnName,
"namespace": namespace,
},
"spec": map[string]interface{}{
"environment": map[string]interface{}{
"name": envName,
"namespace": namespace,
},
"InvokeStrategy": map[string]interface{}{
"ExecutionStrategy": map[string]interface{}{
"ExecutorType": "poolmgr",
},
"StrategyType": "execution",
},
"package": map[string]interface{}{
"packageref": map[string]interface{}{
"name": pkgName,
"namespace": namespace,
},
"functionName": "main.main",
},
},
}}
if _, err = c.CreateFunction(ctx, fnObj); err != nil {
t.Fatalf("create function: %v", err)
}
defer func() { _ = c.DeleteFunction(ctx, namespace, fnName) }()
if _, err = c.GetFunction(ctx, namespace, fnName); err != nil {
t.Fatalf("get function: %v", err)
}
trObj := &unstructured.Unstructured{Object: map[string]interface{}{
"apiVersion": "fission.io/v1",
"kind": "HTTPTrigger",
"metadata": map[string]interface{}{
"name": triggerName,
"namespace": namespace,
},
"spec": map[string]interface{}{
"relativeurl": urlPath,
"methods": []interface{}{"GET"},
"functionref": map[string]interface{}{
"type": "name",
"name": fnName,
},
"createingress": false,
},
}}
if _, err = c.CreateHTTPTrigger(ctx, trObj); err != nil {
t.Fatalf("create http trigger: %v", err)
}
defer func() { _ = c.DeleteHTTPTrigger(ctx, namespace, triggerName) }()
if _, err = c.GetHTTPTrigger(ctx, namespace, triggerName); err != nil {
t.Fatalf("get http trigger: %v", err)
}
gvr := schema.GroupVersionResource{Group: "fission.io", Version: "v1", Resource: "httptriggers"}
if err = c.DynClient.Resource(gvr).Namespace(namespace).Delete(ctx, triggerName, metav1.DeleteOptions{}); err != nil {
t.Fatalf("delete trigger via dynamic client: %v", err)
}
if err = c.DeleteHTTPTrigger(ctx, namespace, triggerName); err == nil {
t.Fatalf("expected not found error after trigger deletion")
}
}