2022-08-13 03:01:29 +02:00

154 lines
4.9 KiB
Go

// Copyright (c) 2020 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License-AGPL.txt in the project root for license information.
package manager
import (
"context"
"testing"
"time"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
"github.com/gitpod-io/gitpod/common-go/util"
csapi "github.com/gitpod-io/gitpod/content-service/api"
"github.com/gitpod-io/gitpod/content-service/pkg/layer"
"github.com/gitpod-io/gitpod/content-service/pkg/storage"
"github.com/gitpod-io/gitpod/ws-manager/api"
config "github.com/gitpod-io/gitpod/ws-manager/api/config"
)
// This file contains test infrastructure for this package. No function in here is meant for consumption outside of tests.
//
// Why is this even here and not in some other package like internal/testing?
// Because we need to modify package internal state
//
func forTestingOnlyManagerConfig() config.Configuration {
return config.Configuration{
Namespace: "default",
SeccompProfile: "workspace-default",
HeartbeatInterval: util.Duration(30 * time.Second),
WorkspaceHostPath: "/tmp/workspaces",
GitpodHostURL: "gitpod.io",
WorkspaceURLTemplate: "{{ .ID }}-{{ .Prefix }}-{{ .Host }}",
WorkspacePortURLTemplate: "{{ .WorkspacePort }}-{{ .ID }}-{{ .Prefix }}-{{ .Host }}",
RegistryFacadeHost: "registry-facade:8080",
WorkspaceClasses: map[string]*config.WorkspaceClass{
config.DefaultWorkspaceClass: {
Container: config.ContainerConfiguration{
Limits: &config.ResourceLimitConfiguration{
CPU: &config.CpuResourceLimit{
MinLimit: "300m",
BurstLimit: "900m",
},
Memory: "1000M",
},
Requests: &config.ResourceRequestConfiguration{
CPU: "899m",
EphemeralStorage: "5Gi",
Memory: "999M",
},
},
},
},
Timeouts: config.WorkspaceTimeoutConfiguration{
AfterClose: util.Duration(1 * time.Minute),
Initialization: util.Duration(30 * time.Minute),
TotalStartup: util.Duration(45 * time.Minute),
RegularWorkspace: util.Duration(60 * time.Minute),
MaxLifetime: util.Duration(36 * time.Hour),
HeadlessWorkspace: util.Duration(90 * time.Minute),
Stopping: util.Duration(60 * time.Minute),
ContentFinalization: util.Duration(55 * time.Minute),
Interrupted: util.Duration(5 * time.Minute),
},
}
}
// forTestingOnlyGetManager creates a workspace manager instance for testing purposes
func forTestingOnlyGetManager(t *testing.T, objects ...client.Object) *Manager {
config := forTestingOnlyManagerConfig()
testEnv := &envtest.Environment{}
cfg, err := testEnv.Start()
if err != nil {
t.Errorf("cannot create test environment: %v", err)
return nil
}
t.Cleanup(func() {
err = testEnv.Stop()
if err != nil {
t.Logf("unexpected error stopping test cluster: %v", err)
}
})
clientset, err := kubernetes.NewForConfig(cfg)
if err != nil {
t.Errorf("cannot create test environment: %v", err)
return nil
}
ctrlClient, err := client.New(cfg, client.Options{Scheme: scheme})
if err != nil {
t.Errorf("cannot create test environment: %v", err)
return nil
}
err = wait.PollImmediate(5*time.Second, 1*time.Minute, func() (bool, error) {
err := ctrlClient.Get(context.Background(), types.NamespacedName{Name: "default"}, &corev1.Namespace{})
if err != nil {
return false, nil
}
return true, nil
})
if err != nil {
t.Errorf("cannot create test environment: %v", err)
return nil
}
for _, obj := range objects {
err := ctrlClient.Create(context.Background(), obj)
if err != nil {
t.Errorf("cannot create test environment objects: %v", err)
return nil
}
}
m, err := New(config, ctrlClient, clientset, &layer.Provider{Storage: &storage.PresignedNoopStorage{}})
if err != nil {
t.Fatalf("cannot create manager: %s", err.Error())
}
// we don't have propr DNS resolution and network access - and we cannot mock it
m.Config.InitProbe.Disabled = true
return m
}
// forTestingOnlyCreateStartWorkspaceContext creates a bare miminum startWorkspaceContext
// which can be used to create a mock workspace pod.
func forTestingOnlyCreateStartWorkspaceContext(manager *Manager, id string, tpe api.WorkspaceType) (*startWorkspaceContext, error) {
return manager.newStartWorkspaceContext(context.Background(), &api.StartWorkspaceRequest{
Id: id,
ServicePrefix: "servicePrefix",
Type: tpe,
Metadata: &api.WorkspaceMetadata{
Owner: "foobar",
MetaId: "foobar",
},
Spec: &api.StartWorkspaceSpec{
WorkspaceImage: "foobar",
IdeImage: &api.IDEImage{WebRef: "someide:version.0"},
Ports: []*api.PortSpec{},
Initializer: &csapi.WorkspaceInitializer{},
},
})
}