137 lines
5.3 KiB
Go
137 lines
5.3 KiB
Go
package apigen
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestGeneratedConfigurationConsumer(t *testing.T) {
|
|
if os.Getenv("GO_OMNI_SCAFFOLD_INTEGRATION") != "1" {
|
|
t.Skip("set GO_OMNI_SCAFFOLD_INTEGRATION=1")
|
|
}
|
|
dir := filepath.Join(t.TempDir(), "app")
|
|
api := filepath.Join(t.TempDir(), "service.api")
|
|
writeFile(t, api, "service configuration {\n@handler ping\nget /ping\n}\n")
|
|
o := Options{API: api, Dir: dir, Module: "example.com/configuration", FrameworkDir: frameworkRoot(t)}
|
|
if err := generateManagedTestProject(t, o); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
main := readFile(t, filepath.Join(dir, "main.go"))
|
|
// The business only changes fields/defaults/validation, not the loading flow.
|
|
writeFile(t, filepath.Join(dir, "internal/config/config.go"), `package config
|
|
import("git.yuntuo.hk/k2safe/go-omni/config";"git.yuntuo.hk/k2safe/go-omni/logx")
|
|
type Config struct { Server config.Config `+"`json:\"server\"`"+`;Limit int `+"`json:\"limit\"`"+` }
|
|
func Default()Config{ c:=config.Default();c.Log.File="./var/log/app.log";c.Log.Rotation=logx.RotationConfig{Enabled:true,MaxSizeMB:10};return Config{Server:c,Limit:10} }
|
|
func(c Config)Validate()error{if err:=c.Server.Validate();err!=nil{return config.AtField("server",err)};if c.Limit<0{return config.Invalid("limit","must not be negative")};return nil}
|
|
`)
|
|
writeFile(t, filepath.Join(dir, "internal/config/loader.go"), `package config
|
|
import omniConfig "git.yuntuo.hk/k2safe/go-omni/config"
|
|
func NewLoader()(*omniConfig.Loader,error){return omniConfig.NewLoader(omniConfig.WithDecoder("custom",omniConfig.JSONDecoder{}))}
|
|
`)
|
|
svc := filepath.Join(dir, "internal/svc/serviceContext.go")
|
|
writeFile(t, svc, strings.Replace(readFile(t, svc), "return nil", "panic(\"dependencies must not initialize on invalid config\")", 1))
|
|
writeFile(t, filepath.Join(dir, "consumer_test.go"), readFile(t, "testdata/configuration/consumer_test.go"))
|
|
runConsumerGo(t, dir, "mod", "tidy")
|
|
runConsumerGo(t, dir, "test", "-race", "-count=1", "./...")
|
|
runConsumerGo(t, dir, "build", ".")
|
|
o.API = filepath.Join(dir, "api/service.api")
|
|
before := snapshot(t, dir)
|
|
for _, mode := range []string{"dry", "generate", "check"} {
|
|
o.DryRun = mode == "dry"
|
|
o.Check = mode == "check"
|
|
if err := generateManagedTestProject(t, o); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if !sameFiles(before, snapshot(t, dir)) {
|
|
t.Fatal("business files overwritten")
|
|
}
|
|
if main != readFile(t, filepath.Join(dir, "main.go")) {
|
|
t.Fatal("main changed")
|
|
}
|
|
load := filepath.Join(dir, "internal/config/loadGen.go")
|
|
original := readFile(t, load)
|
|
writeFile(t, load, original+"\n// drift\n")
|
|
if err := generateManagedTestProject(t, o); err == nil {
|
|
t.Fatal("loadGen drift accepted")
|
|
}
|
|
writeFile(t, load, original)
|
|
if os.Getenv("GO_OMNI_RELEASE_CLI") != "" {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
cmd := exec.CommandContext(ctx, "go", "list", "-m", "-json", frameworkModule)
|
|
cmd.Dir = dir
|
|
cmd.Env = append(os.Environ(), "GOWORK=off")
|
|
data, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
t.Fatal(err, string(data))
|
|
}
|
|
var dependency struct {
|
|
Version, Sum string
|
|
Replace any
|
|
}
|
|
if err = json.Unmarshal(data, &dependency); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if dependency.Version != os.Getenv("GO_OMNI_RELEASE_VERSION") || dependency.Replace != nil || dependency.Sum == "" {
|
|
t.Fatal("not a remote consumer")
|
|
}
|
|
t.Logf("remote framework %s checksum %s; no local replace", dependency.Version, dependency.Sum)
|
|
}
|
|
}
|
|
func TestConfigLoadMigrationGuard(t *testing.T) {
|
|
dir := filepath.Join(t.TempDir(), "app")
|
|
o := Options{Dir: dir, Module: "example.com/upgrade", FrameworkDir: frameworkRoot(t)}
|
|
if _, err := New(o); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
o.API = filepath.Join(dir, "api/service.api")
|
|
matches, err := filepath.Glob(filepath.Join(dir, "api/*.api"))
|
|
if err != nil || len(matches) != 1 {
|
|
t.Fatal(matches, err)
|
|
}
|
|
o.API = matches[0]
|
|
writeFile(t, filepath.Join(dir, "internal/config/legacy.go"), "package config\nfunc Load(path string)(Config,error){return Default(),nil}\n")
|
|
before := snapshot(t, dir)
|
|
for _, mode := range []string{"dry", "generate", "check"} {
|
|
o.DryRun = mode == "dry"
|
|
o.Check = mode == "check"
|
|
_, err := Generate(o)
|
|
if err == nil || !strings.Contains(err.Error(), "CONFIG.md") {
|
|
t.Fatal("missing migration diagnostic", err)
|
|
}
|
|
if !sameFiles(before, snapshot(t, dir)) {
|
|
t.Fatal("migration guard changed files")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRemovedEnvironmentTagsRejectBeforeGeneration(t *testing.T) {
|
|
dir := filepath.Join(t.TempDir(), "app")
|
|
o := Options{Dir: dir, Module: "example.com/migrate", FrameworkDir: frameworkRoot(t)}
|
|
if _, err := New(o); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
o.API = filepath.Join(dir, "api/service.api")
|
|
path := filepath.Join(dir, "internal/config/config.go")
|
|
source := readFile(t, path)
|
|
writeFile(t, path, strings.Replace(source, "json:\"server\"", "json:\"server\" env:\"OLD_SERVER\"", 1))
|
|
before := snapshot(t, dir)
|
|
for _, mode := range []string{"dry", "generate", "check"} {
|
|
o.DryRun = mode == "dry"
|
|
o.Check = mode == "check"
|
|
if _, err := Generate(o); err == nil || !strings.Contains(err.Error(), "env/envDefault") {
|
|
t.Fatal(err)
|
|
}
|
|
if !sameFiles(before, snapshot(t, dir)) {
|
|
t.Fatal("migration rejection wrote files")
|
|
}
|
|
}
|
|
}
|