mirror of https://github.com/knative/func.git
203 lines
6.2 KiB
Go
203 lines
6.2 KiB
Go
//go:build !integration
|
|
// +build !integration
|
|
|
|
package functions
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/coreos/go-semver/semver"
|
|
)
|
|
|
|
// TestMigrated ensures that the .Migrated() method returns whether or not the
|
|
// migrations were applied based on its self-reported .SpecVersion member.
|
|
func TestMigrated(t *testing.T) {
|
|
vNext := semver.New(LastSpecVersion())
|
|
vNext.BumpMajor()
|
|
|
|
tests := []struct {
|
|
name string
|
|
f Function
|
|
migrated bool
|
|
}{{
|
|
name: "no migration stamp",
|
|
f: Function{},
|
|
migrated: false, // function with no specVersion stamp should be not migrated.
|
|
}, {
|
|
name: "explicit small specVersion",
|
|
f: Function{SpecVersion: "0.0.1"},
|
|
migrated: false,
|
|
}, {
|
|
name: "latest specVersion",
|
|
f: Function{SpecVersion: LastSpecVersion()},
|
|
migrated: true,
|
|
}, {
|
|
name: "future specVersion",
|
|
f: Function{SpecVersion: vNext.String()},
|
|
migrated: true,
|
|
}}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
if test.f.Migrated() != test.migrated {
|
|
t.Errorf("Expected %q.Migrated() to be %t when latest is %q",
|
|
test.f.SpecVersion, test.migrated, LastSpecVersion())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestMigrate ensures that functions have migrations apply the specVersion
|
|
// stamp on instantiation indicating migrations have been applied.
|
|
func TestMigrate(t *testing.T) {
|
|
// Load an old function, as it an earlier version it has registered migrations
|
|
// that will need to be applied.
|
|
root := "testdata/migrations/v0.19.0"
|
|
|
|
// Instantiate the function with the antiquated structure, which should cause
|
|
// migrations to be applied in order, and result in a function whose version
|
|
// compatibility is equivalent to the latest registered migration.
|
|
f, err := NewFunction(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if f.SpecVersion != LastSpecVersion() {
|
|
t.Fatalf("Function was not migrated to %v on instantiation: specVersion is %v",
|
|
LastSpecVersion(), f.SpecVersion)
|
|
}
|
|
}
|
|
|
|
// TestMigrateToCreationStamp ensures that the creation timestamp migration
|
|
// introduced for functions 0.19.0 and earlier is applied.
|
|
func TestMigrateToCreationStamp(t *testing.T) {
|
|
// Load a function of version 0.19.0, which should have the migration applied
|
|
root := "testdata/migrations/v0.19.0"
|
|
|
|
now := time.Now()
|
|
f, err := NewFunction(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if f.Created.Before(now) {
|
|
t.Fatalf("migration not applied: expected timestamp to be now, got %v.", f.Created)
|
|
}
|
|
}
|
|
|
|
// TestMigrateToBuilderImages ensures that the migration which migrates
|
|
// from "builder" and "builders" to "builderImages" is applied. This results
|
|
// in the attributes being removed and no errors on load of the function with
|
|
// old schema.
|
|
func TestMigrateToBuilderImagesDefault(t *testing.T) {
|
|
// Load a function created prior to the adoption of the builder images map
|
|
// (was created with 'builder' and 'builders' which does not support different
|
|
// builder implementations.
|
|
root := "testdata/migrations/v0.23.0"
|
|
|
|
// Without the migration, instantiating the older function would error
|
|
// because its strict unmarshalling would fail parsing the unexpected
|
|
// 'builder' and 'builders' members.
|
|
_, err := NewFunction(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// TestMigrateToBuilderImagesCustom ensures that the migration to builderImages
|
|
// correctly carries forward a customized value for 'builder'.
|
|
func TestMigrateToBuilderImagesCustom(t *testing.T) {
|
|
// An early version of a function which includes a customized value for
|
|
// the 'builder'. This should be correctly carried forward to
|
|
// the namespaced 'builderImages' map as image for the "pack" builder.
|
|
root := "testdata/migrations/v0.23.0-customized"
|
|
expected := "example.com/user/custom-builder" // set in testdata func.yaml
|
|
|
|
f, err := NewFunction(root)
|
|
if err != nil {
|
|
t.Fatal(f)
|
|
}
|
|
i, ok := f.Build.BuilderImages["pack"]
|
|
if !ok {
|
|
t.Fatal("migrated function does not include the pack builder images")
|
|
}
|
|
if i != expected {
|
|
t.Fatalf("migrated function expected builder image '%v', got '%v'", expected, i)
|
|
}
|
|
|
|
}
|
|
|
|
// TestMigrateToSpecVersion ensures that a func.yaml file with a "version" field
|
|
// is migrated to use the field name "specVersion"
|
|
func TestMigrateToSpecVersion(t *testing.T) {
|
|
root := "testdata/migrations/v0.25.0"
|
|
f, err := NewFunction(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if f.SpecVersion != LastSpecVersion() {
|
|
t.Fatal("migrated function does not include the Migration field")
|
|
}
|
|
}
|
|
|
|
// TestMigrateToSpecs ensures that the migration to the sub-specs format from
|
|
// the previous Function structure works
|
|
func TestMigrateToSpecs(t *testing.T) {
|
|
|
|
root := "testdata/migrations/v0.34.0"
|
|
expectedGit := Git{URL: "http://test-url", Revision: "test revision", ContextDir: "/test/context/dir"}
|
|
expectedNamespace := "test-namespace"
|
|
var expectedEnvs []Env
|
|
var expectedVolumes []Volume
|
|
|
|
f, err := NewFunction(root)
|
|
if err != nil {
|
|
t.Error(err)
|
|
t.Fatal(f)
|
|
}
|
|
|
|
if f.Build.Git != expectedGit {
|
|
t.Fatalf("migrated Function expected Git '%v', got '%v'", expectedGit, f.Build.Git)
|
|
}
|
|
|
|
if f.Deploy.Namespace != expectedNamespace {
|
|
t.Fatalf("migrated Function expected Namespace '%v', got '%v'", expectedNamespace, f.Deploy.Namespace)
|
|
}
|
|
|
|
if len(f.Run.Envs) != len(expectedEnvs) {
|
|
t.Fatalf("migrated Function expected Run Envs '%v', got '%v'", len(expectedEnvs), len(f.Run.Envs))
|
|
}
|
|
|
|
if len(f.Run.Volumes) != len(expectedVolumes) {
|
|
t.Fatalf("migrated Function expected Run Volumes '%v', got '%v'", len(expectedEnvs), len(f.Run.Envs))
|
|
}
|
|
|
|
}
|
|
|
|
// TestMigrateFromInvokeStructure tests that migration from f.Invocation.Format to
|
|
// f.Invoke works
|
|
func TestMigrateFromInvokeStructure(t *testing.T) {
|
|
root0 := "testdata/migrations/v0.35.0"
|
|
expectedInvoke := "" // empty because http is default and not written in yaml file
|
|
|
|
f0, err := NewFunction(root0)
|
|
if err != nil {
|
|
t.Error(err)
|
|
t.Fatal(f0)
|
|
}
|
|
if f0.Invoke != expectedInvoke {
|
|
t.Fatalf("migrated Function expected Invoke '%v', got '%v'", expectedInvoke, f0.Invoke)
|
|
}
|
|
|
|
root1 := "testdata/migrations/v0.35.0-nondefault"
|
|
expectedInvoke = "cloudevent"
|
|
f1, err := NewFunction(root1)
|
|
if err != nil {
|
|
t.Error(err)
|
|
t.Fatal(f1)
|
|
}
|
|
if f1.Invoke != expectedInvoke {
|
|
t.Fatalf("migrated Function expected Invoke '%v', got '%v'", expectedInvoke, f0.Invoke)
|
|
}
|
|
}
|