Skip to content

Commit

Permalink
add config validation integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
safeer committed Jul 10, 2024
1 parent 1c8f121 commit 18e9825
Show file tree
Hide file tree
Showing 9 changed files with 270 additions and 1 deletion.
3 changes: 2 additions & 1 deletion backend/controller/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,8 @@ func (s *AdminService) validateAgainstSchema(ctx context.Context, isSecret bool,
r := schema.RefKey{Module: ref.Module.Default(""), Name: ref.Name}.ToRef()
decl, ok := sch.Resolve(r).Get()
if !ok {
return fmt.Errorf("declaration %q not found", ref.Name)
logger.Debugf("skipping validation; declaration %q not found", ref.Name)
return nil
}

var fieldType schema.Type
Expand Down
34 changes: 34 additions & 0 deletions common/projectconfig/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,37 @@ func TestFindConfig(t *testing.T) {
checkConfig("."),
)
}

func TestConfigValidation(t *testing.T) {
in.Run(t, "./validateconfig/ftl-project.toml",
in.CopyModule("validateconfig"),

// Global sets never error.
in.Chdir("validateconfig", in.Exec("ftl", "config", "set", "key", "--inline", "valueTwo")),
in.Chdir("validateconfig", in.Exec("ftl", "config", "set", "key", "--inline", "2")),
in.ExecWithExpectedOutput("\"2\"\n", "ftl", "config", "get", "key"),

// No deploy yet; module sets don't error if decl isn't found.
in.Exec("ftl", "config", "set", "validateconfig.defaultName", "--inline", "somename"),
in.ExecWithExpectedOutput("\"somename\"\n", "ftl", "config", "get", "validateconfig.defaultName"),
in.Exec("ftl", "config", "set", "validateconfig.count", "--inline", "1"),
in.ExecWithExpectedOutput("\"1\"\n", "ftl", "config", "get", "validateconfig.count"),

// This is a mismatched type, but should pass without an active deployment.
in.Exec("ftl", "config", "set", "validateconfig.count", "--inline", "one"),

// Deploy; validation should now be run on config sets.
in.Deploy("validateconfig"),
in.Exec("ftl", "config", "set", "validateconfig.defaultName", "--inline", "somenametwo"),
in.ExecWithExpectedOutput("\"somenametwo\"\n", "ftl", "config", "get", "validateconfig.defaultName"),
in.Exec("ftl", "config", "set", "validateconfig.count", "--inline", "2"),
in.ExecWithExpectedOutput("\"2\"\n", "ftl", "config", "get", "validateconfig.count"),

// With a deploy, set should fail validation on bad data type.
in.ExecWithExpectedError("ftl: error: unknown: JSON validation failed: count has wrong type, expected Int found string",
"ftl", "config", "set", "validateconfig.count", "--inline", "three"),

in.ExecWithExpectedOutput("key = \"2\"\nvalidateconfig.count = \"2\"\nvalidateconfig.defaultName = \"somenametwo\"\n",
"ftl", "config", "list", "--values"),
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name = "testdata"

[global]
[global.configuration]
key = "inline://InZhbHVlIg"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name = "testdata"
2 changes: 2 additions & 0 deletions common/projectconfig/testdata/go/validateconfig/ftl.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module = "validateconfig"
language = "go"
47 changes: 47 additions & 0 deletions common/projectconfig/testdata/go/validateconfig/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module ftl/validateconfig

go 1.22.2

toolchain go1.22.4

require github.com/TBD54566975/ftl v1.1.5

require (
connectrpc.com/connect v1.16.1 // indirect
connectrpc.com/grpcreflect v1.2.0 // indirect
connectrpc.com/otelconnect v0.7.0 // indirect
github.com/alecthomas/atomic v0.1.0-alpha2 // indirect
github.com/alecthomas/concurrency v0.0.2 // indirect
github.com/alecthomas/participle/v2 v2.1.1 // indirect
github.com/alecthomas/types v0.16.0 // indirect
github.com/alessio/shellescape v1.4.2 // indirect
github.com/danieljoos/wincred v1.2.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgx/v5 v5.6.0 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/puzpuzpuz/xsync/v3 v3.2.0 // indirect
github.com/swaggest/jsonschema-go v0.3.72 // indirect
github.com/swaggest/refl v1.3.0 // indirect
github.com/zalando/go-keyring v0.2.5 // indirect
go.opentelemetry.io/otel v1.27.0 // indirect
go.opentelemetry.io/otel/metric v1.27.0 // indirect
go.opentelemetry.io/otel/trace v1.27.0 // indirect
golang.org/x/crypto v0.24.0 // indirect
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
)

replace github.com/TBD54566975/ftl => ../../../../..
144 changes: 144 additions & 0 deletions common/projectconfig/testdata/go/validateconfig/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions common/projectconfig/testdata/go/validateconfig/validateconfig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package validateconfig

import (
"context"
"fmt"

"github.com/TBD54566975/ftl/go-runtime/ftl" // Import the FTL SDK.
)

var defaultName = ftl.Config[string]("default")
var count = ftl.Config[int]("count")

type EchoRequest struct {
Name ftl.Option[string] `json:"name"`
}

type EchoResponse struct {
Message string `json:"message"`
}

//ftl:verb
func Echo(ctx context.Context, req EchoRequest) (EchoResponse, error) {
return EchoResponse{Message: fmt.Sprintf("Hello, %s!", req.Name.Default(defaultName.Get(ctx)))}, nil
}
11 changes: 11 additions & 0 deletions integration/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ func ExecWithExpectedOutput(want string, cmd string, args ...string) Action {
}
}

// ExecWithExpectedError runs a command from the test working directory, and
// expects it to fail with the given error message.
func ExecWithExpectedError(want string, cmd string, args ...string) Action {
return func(t testing.TB, ic TestContext) {
Infof("Executing: %s %s", cmd, shellquote.Join(args...))
output, err := ftlexec.Capture(ic, ic.workDir, cmd, args...)
assert.Error(t, err)
assert.Contains(t, string(output), want)
}
}

// ExecWithOutput runs a command from the test working directory.
// On success capture() is executed with the output
// On error, an error with the output is returned.
Expand Down

0 comments on commit 18e9825

Please sign in to comment.