//go:build integration // +build integration package docker_test import ( "bytes" "context" "errors" "io" "strings" "testing" "time" cloudevents "github.com/cloudevents/sdk-go/v2" "github.com/cloudevents/sdk-go/v2/protocol/http" "github.com/docker/docker/api/types/image" dockerClient "github.com/docker/docker/client" "knative.dev/func/pkg/docker" fn "knative.dev/func/pkg/functions" . "knative.dev/func/pkg/testing" ) const displayEventImg = "gcr.io/knative-releases/knative.dev/eventing/cmd/event_display@sha256:610234e4319b767b187398085971d881956da660a4e0fab65a763e0f81881d82" func TestRun(t *testing.T) { root, cleanup := Mktemp(t) defer cleanup() ctx, cancel := context.WithTimeout(context.Background(), time.Minute*10) t.Cleanup(cancel) image := displayEventImg prePullTestImages(t, image) // No need to check for port 8080 since the runner should automatically // choose an open port, with 8080 only being the preferred first choice. // Initialize a new function (creates all artifacts on disk necessary // to perform actions such as running) f := fn.Function{Runtime: "go", Root: root, Image: image} client := fn.New() f, err := client.Init(f) if err != nil { t.Fatal(err) } f, err = client.Build(ctx, f) if err != nil { t.Fatal(err) } // Run the function using a docker runner var out, errOut bytes.Buffer runner := docker.NewRunner(true, &out, &errOut) j, err := runner.Run(ctx, f, fn.DefaultStartTimeout) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = j.Stop() }) time.Sleep(time.Second * 5) var ( id = "runner-test-id" src = "runner-test-src" typ = "runner-test-type" ) event := cloudevents.NewEvent() event.SetID(id) event.SetSource(src) event.SetType(typ) c, err := cloudevents.NewClientHTTP(cloudevents.WithTarget("http://localhost:" + j.Port)) if err != nil { t.Fatal(err) } var httpErr *http.Result res := c.Send(ctx, event) if ok := errors.As(res, &httpErr); ok { if httpErr.StatusCode < 200 || httpErr.StatusCode > 299 { t.Fatal("non 2XX code") } } else { t.Error("expected http.Result type") } time.Sleep(time.Second * 5) t.Log("out: ", out.String()) t.Log("errOut: ", errOut.String()) outStr := out.String() if !(strings.Contains(outStr, id) && strings.Contains(outStr, src) && strings.Contains(outStr, typ)) { t.Error("output doesn't contain invocation info") } } func prePullTestImages(t *testing.T, img string) { t.Helper() c, _, err := docker.NewClient(dockerClient.DefaultDockerHost) if err != nil { t.Fatal(err) } resp, err := c.ImagePull(context.Background(), img, image.PullOptions{}) if err != nil { t.Fatal(err) } _, _ = io.Copy(io.Discard, resp) }