Path: blob/main/test/tests/components/ws-manager/content_test.go
2500 views
// Copyright (c) 2020 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 wsmanager56import (7"context"8"fmt"9"path/filepath"10"testing"11"time"1213"sigs.k8s.io/e2e-framework/pkg/envconf"14"sigs.k8s.io/e2e-framework/pkg/features"1516csapi "github.com/gitpod-io/gitpod/content-service/api"17agent "github.com/gitpod-io/gitpod/test/pkg/agent/workspace/api"18"github.com/gitpod-io/gitpod/test/pkg/integration"19wsmanapi "github.com/gitpod-io/gitpod/ws-manager/api"20)2122// TestBackup tests a basic start/modify/restart cycle23func TestBackup(t *testing.T) {24f := features.New("backup").25WithLabel("component", "ws-manager").26Assess("it should start a workspace, create a file and successfully create a backup", func(testCtx context.Context, t *testing.T, cfg *envconf.Config) context.Context {27tests := []struct {28Name string29ContextURL string30WorkspaceRoot string31CheckoutLocation string32FF []wsmanapi.WorkspaceFeatureFlag33}{34{35Name: "classic",36ContextURL: "https://github.com/gitpod-io/empty",37WorkspaceRoot: "/workspace/empty",38CheckoutLocation: "empty",39},40}41for _, test := range tests {42test := test43t.Run(test.Name, func(t *testing.T) {44t.Parallel()4546ctx, cancel := context.WithTimeout(testCtx, time.Duration(10*len(tests))*time.Minute)47defer cancel()4849api := integration.NewComponentAPI(ctx, cfg.Namespace(), kubeconfig, cfg.Client())50t.Cleanup(func() {51api.Done(t)52})5354// TODO: change to use server API to launch the workspace, so we could run the integration test as the user code flow55// which is client -> server -> ws-manager rather than client -> ws-manager directly56ws1, stopWs1, err := integration.LaunchWorkspaceDirectly(t, ctx, api, integration.WithRequestModifier(func(w *wsmanapi.StartWorkspaceRequest) error {57w.Spec.FeatureFlags = test.FF58w.Spec.Initializer = &csapi.WorkspaceInitializer{59Spec: &csapi.WorkspaceInitializer_Git{60Git: &csapi.GitInitializer{61RemoteUri: test.ContextURL,62CheckoutLocation: test.CheckoutLocation,63Config: &csapi.GitConfig{},64},65},66}67w.Spec.WorkspaceLocation = test.CheckoutLocation68return nil69}))70if err != nil {71t.Fatal(err)72}73t.Cleanup(func() {74if err != nil {75sctx, scancel := context.WithTimeout(context.Background(), 5*time.Minute)76defer scancel()7778sapi := integration.NewComponentAPI(sctx, cfg.Namespace(), kubeconfig, cfg.Client())79defer sapi.Done(t)8081_, err = stopWs1(true, sapi)82if err != nil {83t.Fatal(err)84}85}86})8788rsa, closer, err := integration.Instrument(integration.ComponentWorkspace, "workspace", cfg.Namespace(), kubeconfig, cfg.Client(),89integration.WithInstanceID(ws1.Req.Id),90integration.WithContainer("workspace"),91integration.WithWorkspacekitLift(true),92)93if err != nil {94t.Fatal(err)95}96integration.DeferCloser(t, closer)9798var resp agent.WriteFileResponse99err = rsa.Call("WorkspaceAgent.WriteFile", &agent.WriteFileRequest{100Path: fmt.Sprintf("%s/foobar.txt", test.WorkspaceRoot),101Content: []byte("hello world"),102Mode: 0644,103}, &resp)104rsa.Close()105if err != nil {106if _, serr := stopWs1(true, api); serr != nil {107t.Errorf("cannot stop workspace: %q", serr)108}109t.Fatal(err)110}111112_, err = stopWs1(true, api)113if err != nil {114t.Fatal(err)115}116117ws2, stopWs2, err := integration.LaunchWorkspaceDirectly(t, ctx, api,118integration.WithRequestModifier(func(w *wsmanapi.StartWorkspaceRequest) error {119w.ServicePrefix = ws1.Req.ServicePrefix120w.Metadata.MetaId = ws1.Req.Metadata.MetaId121w.Metadata.Owner = ws1.Req.Metadata.Owner122w.Spec.FeatureFlags = ws1.Req.Spec.FeatureFlags123w.Spec.Initializer = ws1.Req.Spec.Initializer124w.Spec.WorkspaceLocation = ws1.Req.Spec.WorkspaceLocation125126return nil127}),128)129if err != nil {130t.Fatal(err)131}132t.Cleanup(func() {133sctx, scancel := context.WithTimeout(context.Background(), 10*time.Minute)134defer scancel()135136sapi := integration.NewComponentAPI(sctx, cfg.Namespace(), kubeconfig, cfg.Client())137defer sapi.Done(t)138139_, err = stopWs2(true, sapi)140if err != nil {141t.Errorf("cannot stop workspace: %q", err)142}143})144145rsa, closer, err = integration.Instrument(integration.ComponentWorkspace, "workspace", cfg.Namespace(), kubeconfig, cfg.Client(),146integration.WithInstanceID(ws2.Req.Id),147)148if err != nil {149t.Fatal(err)150}151integration.DeferCloser(t, closer)152153var ls agent.ListDirResponse154err = rsa.Call("WorkspaceAgent.ListDir", &agent.ListDirRequest{155Dir: test.WorkspaceRoot,156}, &ls)157if err != nil {158t.Fatal(err)159}160rsa.Close()161162var found bool163for _, f := range ls.Files {164if filepath.Base(f) == "foobar.txt" {165t.Log("found the target file")166found = true167break168}169}170if !found {171t.Fatal("did not find foobar.txt from previous workspace instance")172}173})174}175return testCtx176}).177Feature()178179testEnv.Test(t, f)180181}182183// TestMissingBackup ensures workspaces fail if they should have a backup but don't have one184func TestMissingBackup(t *testing.T) {185f := features.New("CreateWorkspace").186WithLabel("component", "ws-manager").187Assess("it ensures workspace fail if they should have a backup but don't have one", func(testCtx context.Context, t *testing.T, cfg *envconf.Config) context.Context {188ctx, cancel := context.WithTimeout(testCtx, 5*time.Minute)189defer cancel()190191api := integration.NewComponentAPI(ctx, cfg.Namespace(), kubeconfig, cfg.Client())192t.Cleanup(func() {193api.Done(t)194})195196ws, stopWs, err := integration.LaunchWorkspaceDirectly(t, ctx, api)197if err != nil {198t.Fatal(err)199}200201_, err = stopWs(true, api)202if err != nil {203t.Fatal(err)204}205206contentSvc, err := api.ContentService()207if err != nil {208t.Fatal(err)209}210211_, err = contentSvc.DeleteWorkspace(ctx, &csapi.DeleteWorkspaceRequest{212OwnerId: ws.Req.Metadata.Owner,213WorkspaceId: ws.Req.Metadata.MetaId,214})215if err != nil {216t.Fatal(err)217}218219tests := []struct {220Name string221FF []wsmanapi.WorkspaceFeatureFlag222}{223{Name: "classic"},224}225for _, test := range tests {226test := test227t.Run(test.Name+"_backup_init", func(t *testing.T) {228t.Parallel()229230ctx, cancel := context.WithTimeout(context.Background(), time.Duration(5*len(tests))*time.Minute)231defer cancel()232233testws, stopWs2, err := integration.LaunchWorkspaceDirectly(t, ctx, api, integration.WithRequestModifier(func(w *wsmanapi.StartWorkspaceRequest) error {234w.ServicePrefix = ws.Req.ServicePrefix235w.Metadata.MetaId = ws.Req.Metadata.MetaId236w.Metadata.Owner = ws.Req.Metadata.Owner237w.Spec.Initializer = &csapi.WorkspaceInitializer{238Spec: &csapi.WorkspaceInitializer_Backup{239Backup: &csapi.FromBackupInitializer{},240},241}242w.Spec.FeatureFlags = test.FF243return nil244}), integration.WithWaitWorkspaceForOpts(integration.WorkspaceCanFail, integration.WaitForStopped))245if err != nil {246t.Fatal(err)247}248249t.Cleanup(func() {250sctx, scancel := context.WithTimeout(context.Background(), 5*time.Minute)251defer scancel()252253sapi := integration.NewComponentAPI(sctx, cfg.Namespace(), kubeconfig, cfg.Client())254defer sapi.Done(t)255256_, err := stopWs2(true, sapi)257if err != nil {258t.Fatal(err)259}260})261262if testws.LastStatus == nil {263t.Fatal("did not receive a last status")264return265}266if testws.LastStatus.Conditions.Failed == "" {267t.Errorf("restarted workspace did not fail despite missing backup, %v", testws)268}269270})271}272return testCtx273}).274Feature()275276testEnv.Test(t, f)277}278279280