Envtest based integration tests for Fission (#2858)

* skeleton for envtest fission
* Refactor code and add CLI test
* hack
* Update server test
* remove skip-ci for lint tests
* Pass client go storagesvc
* Add clientGen interface across code
* Fix storagesvc test
* Fix cmd client
* add retry in server test
* Fix concurrenct access to pool deployment
* Remove old executor test
* get rid of ginkgo/gomega
* disable flaky test
* flaky test
* revert ci change
* handle err from ParseBool

---------

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>
Co-authored-by: Pranoy Kundu <pranoy1998k@gmail.com>
This commit is contained in:
Sanket Sudake
2023-10-26 12:09:11 +05:30
committed by GitHub
co-authored by Pranoy Kundu
parent 15e16fcc82
commit 8a17d391c5
44 changed files with 534 additions and 524 deletions
+59
View File
@@ -0,0 +1,59 @@
package cli_test
import (
"context"
"testing"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fission/fission/test/e2e/framework"
"github.com/fission/fission/test/e2e/framework/cli"
"github.com/fission/fission/test/e2e/framework/services"
)
func TestFissionCLI(t *testing.T) {
f := framework.NewFramework()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
err := f.Start(ctx)
require.NoError(t, err)
err = services.StartServices(ctx, f)
require.NoError(t, err)
fissionClient, err := f.ClientGen().GetFissionClient()
require.NoError(t, err)
t.Run("environment", func(t *testing.T) {
t.Run("create", func(t *testing.T) {
_, err := cli.ExecCommand(f, ctx, "env", "create", "--name", "test-env", "--image", "fission/python-env")
require.NoError(t, err)
env, err := fissionClient.CoreV1().Environments(metav1.NamespaceDefault).Get(ctx, "test-env", metav1.GetOptions{})
require.NoError(t, err)
require.NotNil(t, env)
require.Equal(t, "test-env", env.Name)
require.Equal(t, "fission/python-env", env.Spec.Runtime.Image)
})
t.Run("update", func(t *testing.T) {
_, err := cli.ExecCommand(f, ctx, "env", "update", "--name", "test-env", "--image", "fission/python-env:v2")
require.NoError(t, err)
env, err := fissionClient.CoreV1().Environments(metav1.NamespaceDefault).Get(ctx, "test-env", metav1.GetOptions{})
require.NoError(t, err)
require.NotNil(t, env)
require.Equal(t, "test-env", env.Name)
require.Equal(t, "fission/python-env:v2", env.Spec.Runtime.Image)
})
t.Run("delete", func(t *testing.T) {
_, err := cli.ExecCommand(f, ctx, "env", "delete", "--name", "test-env")
require.NoError(t, err)
_, err = fissionClient.CoreV1().Environments(metav1.NamespaceDefault).Get(ctx, "test-env", metav1.GetOptions{})
require.Error(t, err)
})
})
}
+27
View File
@@ -0,0 +1,27 @@
package cli
import (
"bytes"
"context"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fission/fission/cmd/fission-cli/app"
"github.com/fission/fission/pkg/fission-cli/cmd"
"github.com/fission/fission/test/e2e/framework"
)
func ExecCommand(f *framework.Framework, ctx context.Context, args ...string) (string, error) {
cmd := app.App(cmd.ClientOptions{
RestConfig: f.RestConfig(),
Namespace: metav1.NamespaceDefault,
})
cmd.SilenceErrors = true // use our own error message printer
cmd.SetArgs(args)
buf := new(bytes.Buffer)
cmd.SetOut(buf)
cmd.SetErr(buf)
err := cmd.ExecuteContext(ctx)
return buf.String(), err
}
+86
View File
@@ -0,0 +1,86 @@
package framework
import (
"context"
"fmt"
"os"
"path/filepath"
"time"
"go.uber.org/zap"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/envtest"
"github.com/fission/fission/pkg/crd"
"github.com/fission/fission/pkg/utils"
"github.com/fission/fission/pkg/utils/loggerfactory"
)
const (
EXECUTOR_URL = "http://executor.fission"
STORAGESVC_URL = "http://storagesvc.fission"
)
type ServiceInfo struct {
Port int
}
type Framework struct {
env *envtest.Environment
config *rest.Config
logger *zap.Logger
ServiceInfo map[string]ServiceInfo
}
func NewFramework() *Framework {
return &Framework{
logger: loggerfactory.GetLogger(),
env: &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("../../..", "crds", "v1")},
ErrorIfCRDPathMissing: true,
CRDInstallOptions: envtest.CRDInstallOptions{
MaxTime: 60 * time.Second,
},
BinaryAssetsDirectory: os.Getenv("KUBEBUILDER_ASSETS"),
},
ServiceInfo: make(map[string]ServiceInfo),
}
}
func (f *Framework) Start(ctx context.Context) error {
var err error
f.config, err = f.env.Start()
if err != nil {
return fmt.Errorf("error starting test env: %v", err)
}
return nil
}
func (f *Framework) ToggleMetricAddr() error {
port, err := utils.FindFreePort()
if err != nil {
return fmt.Errorf("error finding unused port: %v", err)
}
os.Setenv("METRICS_ADDR", fmt.Sprint(port))
return nil
}
func (f *Framework) RestConfig() *rest.Config {
return f.config
}
func (f *Framework) Logger() *zap.Logger {
return f.logger
}
func (f *Framework) ClientGen() *crd.ClientGenerator {
return crd.NewClientGeneratorWithRestConfig(f.config)
}
func (f *Framework) Stop() error {
err := f.env.Stop()
if err != nil {
return fmt.Errorf("error stopping test env: %v", err)
}
return nil
}
+92
View File
@@ -0,0 +1,92 @@
package services
import (
"context"
"fmt"
"os"
"github.com/fission/fission/pkg/buildermgr"
"github.com/fission/fission/pkg/executor"
"github.com/fission/fission/pkg/router"
"github.com/fission/fission/pkg/storagesvc"
"github.com/fission/fission/pkg/utils"
"github.com/fission/fission/test/e2e/framework"
)
func StartServices(ctx context.Context, f *framework.Framework) error {
executorPort, err := utils.FindFreePort()
if err != nil {
return fmt.Errorf("error finding unused port: %v", err)
}
err = f.ToggleMetricAddr()
if err != nil {
return fmt.Errorf("error toggling metric address: %v", err)
}
err = executor.StartExecutor(ctx, f.ClientGen(), f.Logger(), executorPort)
if err != nil {
return fmt.Errorf("error starting executor: %v", err)
}
f.ServiceInfo["executor"] = framework.ServiceInfo{
Port: executorPort,
}
os.Setenv("PRUNE_ENABLED", "true")
os.Setenv("PRUNE_INTERVAL", "60")
storageDir, err := os.MkdirTemp("/tmp", "storagesvc")
if err != nil {
return fmt.Errorf("error creating temp directory: %v", err)
}
storageSvcPort, err := utils.FindFreePort()
if err != nil {
return fmt.Errorf("error finding unused port: %v", err)
}
err = f.ToggleMetricAddr()
if err != nil {
return fmt.Errorf("error toggling metric address: %v", err)
}
err = storagesvc.Start(ctx, f.ClientGen(), f.Logger(), storagesvc.NewLocalStorage(storageDir), storageSvcPort)
if err != nil {
return fmt.Errorf("error starting storage service: %v", err)
}
f.ServiceInfo["storagesvc"] = framework.ServiceInfo{
Port: storageSvcPort,
}
err = f.ToggleMetricAddr()
if err != nil {
return fmt.Errorf("error toggling metric address: %v", err)
}
err = buildermgr.Start(ctx, f.ClientGen(), f.Logger(), fmt.Sprintf("http://localhost:%d", storageSvcPort))
if err != nil {
return fmt.Errorf("error starting builder manager: %v", err)
}
f.ServiceInfo["buildermgr"] = framework.ServiceInfo{}
os.Setenv("ROUTER_ROUND_TRIP_TIMEOUT", "50ms")
os.Setenv("ROUTER_ROUNDTRIP_TIMEOUT_EXPONENT", "2")
os.Setenv("ROUTER_ROUND_TRIP_KEEP_ALIVE_TIME", "30s")
os.Setenv("ROUTER_ROUND_TRIP_DISABLE_KEEP_ALIVE", "true")
os.Setenv("ROUTER_ROUND_TRIP_MAX_RETRIES", "10")
os.Setenv("ROUTER_SVC_ADDRESS_MAX_RETRIES", "5")
os.Setenv("ROUTER_SVC_ADDRESS_UPDATE_TIMEOUT", "30s")
os.Setenv("ROUTER_UNTAP_SERVICE_TIMEOUT", "3600s")
os.Setenv("USE_ENCODED_PATH", "false")
os.Setenv("DISPLAY_ACCESS_LOG", "false")
os.Setenv("DEBUG_ENV", "false")
routerPort, err := utils.FindFreePort()
if err != nil {
return fmt.Errorf("error finding unused port: %v", err)
}
err = f.ToggleMetricAddr()
if err != nil {
return fmt.Errorf("error toggling metric address: %v", err)
}
err = router.Start(ctx, f.ClientGen(), f.Logger(), routerPort, fmt.Sprintf("http://localhost:%d", executorPort))
if err != nil {
return fmt.Errorf("error starting router: %v", err)
}
f.ServiceInfo["router"] = framework.ServiceInfo{
Port: routerPort,
}
return nil
}