Path: blob/main/test/tests/components/image-builder/builder_test.go
2499 views
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package imagebuilder56import (7"context"8"errors"9"io"10"testing"11"time"1213"golang.org/x/sync/errgroup"14"golang.org/x/xerrors"15"google.golang.org/grpc/codes"16"google.golang.org/grpc/status"17"sigs.k8s.io/e2e-framework/pkg/envconf"18"sigs.k8s.io/e2e-framework/pkg/features"1920csapi "github.com/gitpod-io/gitpod/content-service/api"21imgapi "github.com/gitpod-io/gitpod/image-builder/api"22"github.com/gitpod-io/gitpod/test/pkg/integration"23)2425func TestBaseImageBuild(t *testing.T) {26f := features.New("database").27WithLabel("component", "image-builder").28Assess("it should build a base image", func(testCtx context.Context, t *testing.T, cfg *envconf.Config) context.Context {29t.Parallel()3031ctx, cancel := context.WithTimeout(testCtx, 5*time.Minute)32defer cancel()3334api := integration.NewComponentAPI(ctx, cfg.Namespace(), kubeconfig, cfg.Client())35t.Cleanup(func() {36api.Done(t)37})3839client, err := api.ImageBuilder()40if err != nil {41t.Fatal("cannot start build", err)42}4344bld, err := client.Build(ctx, &imgapi.BuildRequest{45ForceRebuild: true,46TriggeredBy: "integration-test",47Source: &imgapi.BuildSource{48From: &imgapi.BuildSource_File{49File: &imgapi.BuildSourceDockerfile{50DockerfileVersion: "some-version",51DockerfilePath: "test/tests/components/image-builder/test.Dockerfile",52ContextPath: ".",53Source: &csapi.WorkspaceInitializer{54Spec: &csapi.WorkspaceInitializer_Git{55Git: &csapi.GitInitializer{56RemoteUri: "https://github.com/gitpod-io/gitpod.git",57TargetMode: csapi.CloneTargetMode_REMOTE_BRANCH,58CloneTaget: "main",59Config: &csapi.GitConfig{60Authentication: csapi.GitAuthMethod_NO_AUTH,61},62},63},64},65},66},67},68})69if err != nil {70t.Fatal("cannot start build", err)71}7273var ref string74for {75msg, err := bld.Recv()76if errors.Is(err, io.EOF) {77break78}7980if err != nil {81if st, ok := status.FromError(err); ok && st.Code() == codes.Unavailable {82continue83}84t.Fatal(err)85}8687ref = msg.Ref88if msg.Status == imgapi.BuildStatus_done_success {89break90} else if msg.Status == imgapi.BuildStatus_done_failure {91t.Fatalf("image build failed: %s", msg.Message)92} else {93t.Logf("build output: %s, %s", msg.Message, msg.Info)94}95}96if ref == "" {97t.Fatal("ref was empty")98}99100return testCtx101}).102Feature()103104testEnv.Test(t, f)105}106107func TestParallelBaseImageBuild(t *testing.T) {108f := features.New("image-builder").109WithLabel("component", "image-builder").110Assess("it should allow parallel build of images", func(testCtx context.Context, t *testing.T, cfg *envconf.Config) context.Context {111t.Parallel()112113ctx, cancel := context.WithTimeout(testCtx, 5*time.Minute)114defer cancel()115116api := integration.NewComponentAPI(ctx, cfg.Namespace(), kubeconfig, cfg.Client())117t.Cleanup(func() {118api.Done(t)119})120121client, err := api.ImageBuilder()122if err != nil {123t.Fatalf("cannot start build: %q", err)124}125126req := &imgapi.BuildRequest{127ForceRebuild: true,128TriggeredBy: "integration-test",129Source: &imgapi.BuildSource{130From: &imgapi.BuildSource_File{131File: &imgapi.BuildSourceDockerfile{132DockerfileVersion: "some-version",133DockerfilePath: "test/tests/components/image-builder/test.Dockerfile",134ContextPath: ".",135Source: &csapi.WorkspaceInitializer{136Spec: &csapi.WorkspaceInitializer_Git{137Git: &csapi.GitInitializer{138RemoteUri: "https://github.com/gitpod-io/gitpod.git",139TargetMode: csapi.CloneTargetMode_REMOTE_BRANCH,140CloneTaget: "main",141Config: &csapi.GitConfig{142Authentication: csapi.GitAuthMethod_NO_AUTH,143},144},145},146},147},148},149},150}151152bld0, err := client.Build(ctx, req)153if err != nil {154t.Fatalf("cannot start build: %v", err)155}156bld1, err := client.Build(ctx, req)157if err != nil {158t.Fatalf("cannot start build: %v", err)159}160161watchBuild := func(cl imgapi.ImageBuilder_BuildClient) error {162for {163msg, err := cl.Recv()164if errors.Is(err, io.EOF) {165break166}167168if err != nil {169return xerrors.Errorf("image builder error: %v", err)170}171if err := ctx.Err(); err != nil {172return xerrors.Errorf("context error: %v", err)173}174175if msg.Status == imgapi.BuildStatus_done_success {176break177} else if msg.Status == imgapi.BuildStatus_done_failure {178return xerrors.Errorf("image build failed: %s", msg.Message)179} else {180t.Logf("build output: %s", msg.Message)181}182}183184return nil185}186187var eg errgroup.Group188eg.Go(func() error { return watchBuild(bld0) })189eg.Go(func() error { return watchBuild(bld1) })190191/*192blds, err := client.ListBuilds(ctx, &imgapi.ListBuildsRequest{})193if err != nil {194t.Fatalf("cannot list builds: %v", err)195}196197// TODO(cw): make this assertion resiliant against other on-going builds198if l := len(blds.Builds); l != 1 {199t.Errorf("image builder is running not just one build, but %d", l)200}201*/202err = eg.Wait()203if err != nil {204t.Fatal(err)205}206207return testCtx208}).209Feature()210211testEnv.Test(t, f)212}213214215