168 lines
5.2 KiB
Go
168 lines
5.2 KiB
Go
package apigen
|
|
|
|
import (
|
|
"encoding/json"
|
|
"git.yuntuo.hk/k2safe/go-omni/cmd/go-omni/scaffold"
|
|
"go/format"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func oldInfrastructureProject(t *testing.T) string {
|
|
t.Helper()
|
|
dir := filepath.Join(t.TempDir(), "app")
|
|
if _, err := New(Options{Dir: dir, Module: "example.com/upgrade", FrameworkDir: frameworkRoot(t)}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
previous, err := scaffold.LegacyAPIInfrastructure("example.com/upgrade", "none", "none", "stderr", "json")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for name, content := range previous {
|
|
if strings.HasSuffix(name, ".go") {
|
|
content, err = format.Source(content)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
writeFile(t, filepath.Join(dir, name), string(content))
|
|
}
|
|
var m manifest
|
|
if err = json.Unmarshal([]byte(readFile(t, filepath.Join(dir, manifestPath))), &m); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
delete(m.Generated, "internal/svc/runtimeGen.go")
|
|
m.TemplateVersion = ""
|
|
_ = os.Remove(filepath.Join(dir, "internal/svc/runtimeGen.go"))
|
|
raw, _ := json.Marshal(m)
|
|
writeFile(t, filepath.Join(dir, manifestPath), string(raw))
|
|
path := filepath.Join(dir, "go.mod")
|
|
writeFile(t, path, strings.ReplaceAll(readFile(t, path), minimumVersion, "v0.13.0-preview"))
|
|
return dir
|
|
}
|
|
|
|
func TestUpgradeRejectsEscapingEntry(t *testing.T) {
|
|
dir := oldInfrastructureProject(t)
|
|
var m manifest
|
|
if err := json.Unmarshal([]byte(readFile(t, filepath.Join(dir, manifestPath))), &m); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
m.Entry = "../outside.api"
|
|
raw, _ := json.Marshal(m)
|
|
writeFile(t, filepath.Join(dir, manifestPath), string(raw))
|
|
before := snapshot(t, dir)
|
|
if _, err := ApplyUpgrade(dir); err == nil {
|
|
t.Fatal("escaping API entry accepted")
|
|
}
|
|
if !sameFiles(before, snapshot(t, dir)) {
|
|
t.Fatal("invalid upgrade wrote project")
|
|
}
|
|
}
|
|
|
|
func TestUpgradeV014PreservesExtensions(t *testing.T) {
|
|
dir := filepath.Join(t.TempDir(), "service")
|
|
if _, err := New(Options{Dir: dir, Module: "example.com/upgrade", FrameworkDir: frameworkRoot(t)}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var m manifest
|
|
if err := json.Unmarshal([]byte(readFile(t, filepath.Join(dir, manifestPath))), &m); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
m.TemplateVersion = "v0.14.0-preview"
|
|
raw, _ := json.Marshal(m)
|
|
writeFile(t, filepath.Join(dir, manifestPath), string(raw))
|
|
mod := filepath.Join(dir, "go.mod")
|
|
writeFile(t, mod, strings.ReplaceAll(readFile(t, mod), minimumVersion, "v0.14.1-preview"))
|
|
owned := map[string]string{}
|
|
for _, name := range []string{"internal/svc/serviceContext.go", "internal/config/config.go", "etc/config.yaml"} {
|
|
path := filepath.Join(dir, name)
|
|
value := readFile(t, path)
|
|
if strings.HasSuffix(name, ".go") {
|
|
value += "\n// project extension kept\n"
|
|
} else {
|
|
value += "\n# project configuration kept\n"
|
|
}
|
|
writeFile(t, path, value)
|
|
owned[path] = value
|
|
}
|
|
plan, err := PlanUpgrade(dir)
|
|
if err != nil || len(plan.Changes) != 1 || plan.Changes[0].Path != "go.mod" {
|
|
t.Fatal(plan, err)
|
|
}
|
|
if _, err := ApplyUpgrade(dir); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for path, want := range owned {
|
|
if readFile(t, path) != want {
|
|
t.Fatal("developer file modified", path)
|
|
}
|
|
}
|
|
if _, err := Generate(Options{Dir: dir, API: filepath.Join(dir, "api/service.api"), Check: true}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
func TestSafeInfrastructureUpgrade(t *testing.T) {
|
|
dir := oldInfrastructureProject(t)
|
|
before := snapshot(t, dir)
|
|
if _, err := Generate(Options{Dir: dir, API: filepath.Join(dir, "api/service.api")}); err == nil {
|
|
t.Fatal("legacy constructor accepted")
|
|
}
|
|
if !sameFiles(before, snapshot(t, dir)) {
|
|
t.Fatal("failed generate wrote files")
|
|
}
|
|
plan, err := PlanUpgrade(dir)
|
|
if err != nil || len(plan.Changes) == 0 {
|
|
t.Fatal(plan, err)
|
|
}
|
|
for _, c := range plan.Changes {
|
|
if c.Manual {
|
|
t.Fatal(c.Path)
|
|
}
|
|
}
|
|
preview := filepath.Join(t.TempDir(), "preview")
|
|
if _, err = PreviewUpgrade(dir, preview); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !sameFiles(before, snapshot(t, dir)) {
|
|
t.Fatal("preview changed project")
|
|
}
|
|
logic := readFile(t, filepath.Join(dir, "internal/logic/greet/greet.go"))
|
|
if _, err = ApplyUpgrade(dir); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err = os.Stat(filepath.Join(dir, "internal/svc/close.go")); !os.IsNotExist(err) {
|
|
t.Fatal("old lifecycle remains")
|
|
}
|
|
if readFile(t, filepath.Join(dir, "internal/logic/greet/greet.go")) != logic {
|
|
t.Fatal("business changed")
|
|
}
|
|
if _, err = Generate(Options{Dir: dir, API: filepath.Join(dir, "api/service.api"), Check: true}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
plan, err = PlanUpgrade(dir)
|
|
if err != nil || len(plan.Changes) != 0 {
|
|
t.Fatal("upgrade not idempotent", plan, err)
|
|
}
|
|
}
|
|
func TestUpgradePreservesCustomFilesAndRollsBack(t *testing.T) {
|
|
for _, custom := range []bool{true, false} {
|
|
dir := oldInfrastructureProject(t)
|
|
if custom {
|
|
path := filepath.Join(dir, "internal/svc/serviceContext.go")
|
|
writeFile(t, path, readFile(t, path)+"\n// custom dependency\n")
|
|
} else {
|
|
path := filepath.Join(dir, "internal/logic/greet/greet.go")
|
|
writeFile(t, path, "package greet;func(s *Logic)Greet(){}")
|
|
}
|
|
before := snapshot(t, dir)
|
|
if _, err := ApplyUpgrade(dir); err == nil {
|
|
t.Fatal("unsafe upgrade accepted")
|
|
}
|
|
if !sameFiles(before, snapshot(t, dir)) {
|
|
t.Fatal("failed upgrade changed project")
|
|
}
|
|
}
|
|
}
|