Skip to content

Commit

Permalink
fixes #1606
Browse files Browse the repository at this point in the history
migrating integration tests to their logical packages
  • Loading branch information
jonathanj-square committed Jun 4, 2024
1 parent fba50cf commit d7075cd
Show file tree
Hide file tree
Showing 99 changed files with 700 additions and 315 deletions.
23 changes: 23 additions & 0 deletions backend/controller/cronjobs/cronjobs_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ package cronjobs

import (
"context"
"os"
"path/filepath"
"testing"
"time"

db "github.com/TBD54566975/ftl/backend/controller/dal"
"github.com/TBD54566975/ftl/backend/controller/sql/sqltest"
in "github.com/TBD54566975/ftl/integration"
"github.com/TBD54566975/ftl/internal/log"
"github.com/alecthomas/assert/v2"
"github.com/benbjohnson/clock"
Expand All @@ -35,3 +38,23 @@ func TestServiceWithRealDal(t *testing.T) {

testServiceWithDal(ctx, t, dal, clk)
}

func TestCron(t *testing.T) {
dir := t.TempDir()
// Due to some MacOS magic, /tmp differs between this test code and the
// executing module, so we need to pass the file path as an environment
// variable.
tmpFile := filepath.Join(dir, "cron.txt")
t.Setenv("DEST_FILE", tmpFile)

t.Cleanup(func() { _ = os.Remove(tmpFile) })

in.Run(t, "",
in.CopyModule("cron"),
in.Deploy("cron"),
func(t testing.TB, ic in.TestContext) {
_, err := os.Stat(tmpFile)
assert.NoError(t, err)
},
)
}
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ require (
google.golang.org/protobuf v1.34.1 // indirect
)

replace github.com/TBD54566975/ftl => ../../../..
replace github.com/TBD54566975/ftl => ./../../../../../..
File renamed without changes.
117 changes: 117 additions & 0 deletions backend/controller/dal/fsm_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
//go:build integration

package dal_test

import (
"fmt"
"path/filepath"
"testing"
"time"

in "github.com/TBD54566975/ftl/integration"
"github.com/alecthomas/assert/v2"
)

func TestFSM(t *testing.T) {
logFilePath := filepath.Join(t.TempDir(), "fsm.log")
t.Setenv("FSM_LOG_FILE", logFilePath)
fsmInState := func(instance, status, state string) in.Action {
return in.QueryRow("ftl", fmt.Sprintf(`
SELECT status, current_state
FROM fsm_instances
WHERE fsm = 'fsm.fsm' AND key = '%s'
`, instance), status, state)
}
in.Run(t, "",
in.CopyModule("fsm"),
in.Deploy("fsm"),

in.Call("fsm", "sendOne", in.Obj{"instance": "1"}, nil),
in.Call("fsm", "sendOne", in.Obj{"instance": "2"}, nil),
in.FileContains(logFilePath, "start 1"),
in.FileContains(logFilePath, "start 2"),
fsmInState("1", "running", "fsm.start"),
fsmInState("2", "running", "fsm.start"),

in.Call("fsm", "sendOne", in.Obj{"instance": "1"}, nil),
in.FileContains(logFilePath, "middle 1"),
fsmInState("1", "running", "fsm.middle"),

in.Call("fsm", "sendOne", in.Obj{"instance": "1"}, nil),
in.FileContains(logFilePath, "end 1"),
fsmInState("1", "completed", "fsm.end"),

in.Fail(in.Call("fsm", "sendOne", in.Obj{"instance": "1"}, nil),
"FSM instance 1 is already in state fsm.end"),

// Invalid state transition
in.Fail(in.Call("fsm", "sendTwo", in.Obj{"instance": "2"}, nil),
"invalid state transition"),

in.Call("fsm", "sendOne", in.Obj{"instance": "2"}, nil),
in.FileContains(logFilePath, "middle 2"),
fsmInState("2", "running", "fsm.middle"),

// Invalid state transition
in.Fail(in.Call("fsm", "sendTwo", in.Obj{"instance": "2"}, nil),
"invalid state transition"),
)
}

func TestFSMRetry(t *testing.T) {
checkRetries := func(origin, verb string, delays []time.Duration) in.Action {
return func(t testing.TB, ic in.TestContext) {
results := []any{}
for i := 0; i < len(delays); i++ {
values := in.GetRow(t, ic, "ftl", fmt.Sprintf("SELECT scheduled_at FROM async_calls WHERE origin = '%s' AND verb = '%s' AND state = 'error' ORDER BY created_at LIMIT 1 OFFSET %d", origin, verb, i), 1)
results = append(results, values[0])
}
times := []time.Time{}
for i, r := range results {
ts, ok := r.(time.Time)
assert.True(t, ok, "unexpected time value: %v", r)
times = append(times, ts)
if i > 0 {
delay := times[i].Sub(times[i-1])
targetDelay := delays[i-1]
assert.True(t, delay >= targetDelay && delay < time.Second+targetDelay, "unexpected time diff for %s retry %d: %v (expected %v - %v)", origin, i, delay, targetDelay, time.Second+targetDelay)
}
}
}
}

in.Run(t, "",
in.CopyModule("fsmretry"),
in.Build("fsmretry"),
in.Deploy("fsmretry"),
// start 2 FSM instances
in.Call("fsmretry", "start", in.Obj{"id": "1"}, func(t testing.TB, response in.Obj) {}),
in.Call("fsmretry", "start", in.Obj{"id": "2"}, func(t testing.TB, response in.Obj) {}),

in.Sleep(2*time.Second),

// transition the FSM, should fail each time.
in.Call("fsmretry", "startTransitionToTwo", in.Obj{"id": "1"}, func(t testing.TB, response in.Obj) {}),
in.Call("fsmretry", "startTransitionToThree", in.Obj{"id": "2"}, func(t testing.TB, response in.Obj) {}),

in.Sleep(8*time.Second), //6s is longest run of retries

// both FSMs instances should have failed
in.QueryRow("ftl", "SELECT COUNT(*) FROM fsm_instances WHERE status = 'failed'", int64(2)),

in.QueryRow("ftl", fmt.Sprintf("SELECT COUNT(*) FROM async_calls WHERE origin = '%s' AND verb = '%s'", "fsm:fsmretry.fsm:1", "fsmretry.state2"), int64(4)),
checkRetries("fsm:fsmretry.fsm:1", "fsmretry.state2", []time.Duration{time.Second, time.Second, time.Second}),
in.QueryRow("ftl", fmt.Sprintf("SELECT COUNT(*) FROM async_calls WHERE origin = '%s' AND verb = '%s'", "fsm:fsmretry.fsm:2", "fsmretry.state3"), int64(4)),
checkRetries("fsm:fsmretry.fsm:2", "fsmretry.state3", []time.Duration{time.Second, 2 * time.Second, 3 * time.Second}),
)
}

func TestFSMGoTests(t *testing.T) {
logFilePath := filepath.Join(t.TempDir(), "fsm.log")
t.Setenv("FSM_LOG_FILE", logFilePath)
in.Run(t, "",
in.CopyModule("fsm"),
in.Build("fsm"),
in.ExecModuleTest("fsm"),
)
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@ require (
google.golang.org/protobuf v1.34.1 // indirect
)

replace github.com/TBD54566975/ftl => ../../../..
replace github.com/TBD54566975/ftl => ./../../../../../..
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ require (
google.golang.org/protobuf v1.34.1 // indirect
)

replace github.com/TBD54566975/ftl => ../../../..
replace github.com/TBD54566975/ftl => ./../../../../../..
File renamed without changes.
2 changes: 1 addition & 1 deletion backend/controller/ingress/testdata/go/httpingress/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ require (
google.golang.org/protobuf v1.34.1 // indirect
)

replace github.com/TBD54566975/ftl => ../../../..
replace github.com/TBD54566975/ftl => ./../../../../../..
59 changes: 59 additions & 0 deletions backend/controller/leases/lease_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//go:build integration

package leases_test

import (
"fmt"
"strings"
"testing"
"time"

"connectrpc.com/connect"
"github.com/alecthomas/assert/v2"
"golang.org/x/sync/errgroup"

ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1"
schemapb "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/schema"
in "github.com/TBD54566975/ftl/integration"
)

func TestLease(t *testing.T) {
in.Run(t, "",
in.CopyModule("leases"),
in.Build("leases"),
// checks if leases work in a unit test environment
in.ExecModuleTest("leases"),
in.Deploy("leases"),
// checks if it leases work with a real controller
func(t testing.TB, ic in.TestContext) {
// Start a lease.
wg := errgroup.Group{}
wg.Go(func() error {
in.Infof("Acquiring lease")
resp, err := ic.Verbs.Call(ic, connect.NewRequest(&ftlv1.CallRequest{
Verb: &schemapb.Ref{Module: "leases", Name: "acquire"},
Body: []byte("{}"),
}))
if respErr := resp.Msg.GetError(); respErr != nil {
return fmt.Errorf("received error on first call: %v", respErr)
}
return err
})

time.Sleep(time.Second)

in.Infof("Trying to acquire lease again")
// Trying to obtain the lease again should fail.
resp, err := ic.Verbs.Call(ic, connect.NewRequest(&ftlv1.CallRequest{
Verb: &schemapb.Ref{Module: "leases", Name: "acquire"},
Body: []byte("{}"),
}))
assert.NoError(t, err)
if resp.Msg.GetError() == nil || !strings.Contains(resp.Msg.GetError().Message, "could not acquire lease") {
t.Fatalf("expected error but got: %#v", resp.Msg.GetError())
}
err = wg.Wait()
assert.NoError(t, err)
},
)
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module ftl/leases

go 1.22.2

replace github.com/TBD54566975/ftl => ../../../..
replace github.com/TBD54566975/ftl => ./../../../../../..

require (
github.com/TBD54566975/ftl v0.0.0-00010101000000-000000000000
Expand Down
File renamed without changes.
File renamed without changes.
25 changes: 25 additions & 0 deletions backend/controller/sql/database_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//go:build integration

package sql_test

import (
"testing"

in "github.com/TBD54566975/ftl/integration"
)

func TestDatabase(t *testing.T) {
in.Run(t, "database/ftl-project.toml",
// deploy real module against "testdb"
in.CopyModule("database"),
in.CreateDBAction("database", "testdb", false),
in.Deploy("database"),
in.Call("database", "insert", in.Obj{"data": "hello"}, nil),
in.QueryRow("testdb", "SELECT data FROM requests", "hello"),

// run tests which should only affect "testdb_test"
in.CreateDBAction("database", "testdb", true),
in.ExecModuleTest("database"),
in.QueryRow("testdb", "SELECT data FROM requests", "hello"),
)
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@ require (
google.golang.org/protobuf v1.34.1 // indirect
)

replace github.com/TBD54566975/ftl => ../../../..
replace github.com/TBD54566975/ftl => ./../../../../../..
File renamed without changes.
4 changes: 4 additions & 0 deletions buildengine/testdata/projects/alpha/go.sum

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

4 changes: 4 additions & 0 deletions buildengine/testdata/projects/another/go.sum

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

4 changes: 4 additions & 0 deletions buildengine/testdata/projects/other/go.sum

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

6 changes: 6 additions & 0 deletions ftl-project.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
module-dirs = ["examples/go"]
external-dirs = []
ftl-min-version = ""

[global]
[global.configuration]
key = "inline://InZhbHVlIg"

[modules]
[modules.echo]
[modules.echo.configuration]
default = "inline://ImFub255bW91cyI"

[executables]
ftl = ""

[commands]
startup = ["echo 'FTL startup command ⚡️'"]
35 changes: 35 additions & 0 deletions go-runtime/compile/compile_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//go:build integration

package compile_test

import (
"testing"

in "github.com/TBD54566975/ftl/integration"
)

func TestNonExportedDecls(t *testing.T) {
in.Run(t, "",
in.CopyModule("time"),
in.Deploy("time"),
in.CopyModule("echo"),
in.Deploy("echo"),
in.CopyModule("notexportedverb"),
in.ExpectError(
in.ExecWithOutput("ftl", "deploy", "notexportedverb"),
"call first argument must be a function but is an unresolved reference to echo.Echo, does it need to be exported?"),
)
}

func TestUndefinedExportedDecls(t *testing.T) {
in.Run(t, "",
in.CopyModule("time"),
in.Deploy("time"),
in.CopyModule("echo"),
in.Deploy("echo"),
in.CopyModule("undefinedverb"),
in.ExpectError(
in.ExecWithOutput("ftl", "deploy", "undefinedverb"),
"call first argument must be a function but is an unresolved reference to echo.Undefined"),
)
}
Loading

0 comments on commit d7075cd

Please sign in to comment.