diff --git a/e2e/basic/basic_test.go b/e2e/basic/basic_test.go index 07dcd05..616a472 100644 --- a/e2e/basic/basic_test.go +++ b/e2e/basic/basic_test.go @@ -3,51 +3,25 @@ package basic import ( "context" "strings" - - "github.com/stretchr/testify/assert" -) - -const ( - testImage = "alpine:latest" ) -func (ts *TestSuite) TestBasic() { - ts.T().Parallel() - // Setup - +func (s *Suite) TestBasic() { + const namePrefix = "basic" ctx := context.Background() - target, err := ts.Knuu.NewInstance("alpine") - ts.Require().NoError(err) + target, err := s.Knuu.NewInstance(namePrefix + "-target") + s.Require().NoError(err) - ts.Require().NoError(target.Build().SetImage(ctx, testImage)) - ts.Require().NoError(target.Build().SetStartCommand("sleep", "infinity")) - ts.Require().NoError(target.Build().Commit(ctx)) - - ts.T().Cleanup(func() { - if err := target.Execution().Destroy(ctx); err != nil { - ts.T().Logf("error destroying instance: %v", err) - } - }) - - // Test Logic - ts.Require().NoError(target.Execution().Start(ctx)) + s.Require().NoError(target.Build().SetImage(ctx, alpineImage)) + s.Require().NoError(target.Build().SetStartCommand("sleep", "infinity")) + s.Require().NoError(target.Build().Commit(ctx)) + s.Require().NoError(target.Execution().Start(ctx)) // Perform the test - tt := []struct { - name string - }{ - {name: "Hello World"}, - } - - for _, tc := range tt { - tc := tc - ts.Run(tc.name, func() { - output, err := target.Execution().ExecuteCommand(ctx, "echo", tc.name) - ts.Require().NoError(err) + expectedOutput := "Hello World" + output, err := target.Execution().ExecuteCommand(ctx, "echo", expectedOutput) + s.Require().NoError(err) - output = strings.TrimSpace(output) - assert.Contains(ts.T(), output, tc.name) - }) - } + output = strings.TrimSpace(output) + s.Assert().Equal(expectedOutput, output) } diff --git a/e2e/basic/main_test.go b/e2e/basic/main_test.go deleted file mode 100644 index e09a0f5..0000000 --- a/e2e/basic/main_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package basic - -import ( - "os" - "testing" - - "github.com/sirupsen/logrus" - - "github.com/celestiaorg/knuu/pkg/knuu" -) - -func TestMain(m *testing.M) { - err := knuu.Initialize() - if err != nil { - logrus.Fatalf("error initializing knuu: %v", err) - } - logrus.Infof("Scope: %s", knuu.Scope()) - exitVal := m.Run() - os.Exit(exitVal) -} diff --git a/e2e/basic/observability_test.go b/e2e/basic/observability_test.go index b817ab2..aecf028 100644 --- a/e2e/basic/observability_test.go +++ b/e2e/basic/observability_test.go @@ -3,15 +3,10 @@ package basic import ( "context" "fmt" - "io/ioutil" + "io" "net/http" - "os" - "testing" "time" - "github.com/stretchr/testify/require" - - "github.com/celestiaorg/knuu/pkg/knuu" "github.com/celestiaorg/knuu/pkg/sidecars/observability" ) @@ -21,26 +16,30 @@ const ( prometheusConfig = "/etc/prometheus/prometheus.yml" prometheusArgs = "--config.file=/etc/prometheus/prometheus.yml" - targetImage = "curlimages/curl:latest" - otlpPort = observability.DefaultOtelOtlpPort + curlImage = "curlimages/curl:latest" + otlpPort = observability.DefaultOtelOtlpPort ) // TestObservabilityCollector is a test function that verifies the functionality of the otel collector setup -func TestObservabilityCollector(t *testing.T) { - t.Parallel() +func (s *Suite) TestObservabilityCollector() { + const ( + namePrefix = "observability" + targetStartCommand = "while true; do curl -X POST http://localhost:8888/v1/traces; sleep 5; done" + ) + ctx := context.Background() // Setup Prometheus - prometheus, err := knuu.NewInstance("prometheus") - require.NoError(t, err) + prometheus, err := s.Knuu.NewInstance(namePrefix + "-prometheus") + s.Require().NoError(err) - require.NoError(t, prometheus.SetImage(prometheusImage)) - require.NoError(t, prometheus.AddPortTCP(prometheusPort)) + s.Require().NoError(prometheus.Build().SetImage(ctx, prometheusImage)) + s.Require().NoError(prometheus.Network().AddPortTCP(prometheusPort)) // enable proxy for this port - err, prometheusEndpoint := prometheus.AddHost(prometheusPort) - require.NoError(t, err) + prometheusEndpoint, err := prometheus.Network().AddHost(ctx, prometheusPort) + s.Require().NoError(err) - require.NoError(t, prometheus.Commit()) + s.Require().NoError(prometheus.Build().Commit(ctx)) // Add Prometheus config file prometheusConfigContent := fmt.Sprintf(` @@ -51,51 +50,34 @@ scrape_configs: static_configs: - targets: ['otel-collector:%d'] `, otlpPort) - require.NoError(t, prometheus.AddFileBytes([]byte(prometheusConfigContent), prometheusConfig, "0:0")) + s.Require().NoError(prometheus.Storage().AddFileBytes([]byte(prometheusConfigContent), prometheusConfig, "0:0")) - require.NoError(t, prometheus.SetArgs(prometheusArgs)) - require.NoError(t, prometheus.Start()) + s.Require().NoError(prometheus.Build().SetArgs(prometheusArgs)) + s.Require().NoError(prometheus.Execution().Start(ctx)) // Setup observabilitySidecar collector observabilitySidecar := observability.New() - require.NoError(t, observabilitySidecar.SetOtelEndpoint(4318)) - - err = observabilitySidecar.SetPrometheusEndpoint(otlpPort, fmt.Sprintf("knuu-%s", knuu.Scope()), "10s") - require.NoError(t, err) - - require.NoError(t, observabilitySidecar.SetJaegerEndpoint(14250, 6831, 14268)) - - require.NoError(t, observabilitySidecar.SetOtlpExporter("prometheus:9090", "", "")) + s.Require().NoError(observabilitySidecar.SetOtelEndpoint(4318)) + s.Require().NoError(observabilitySidecar.SetPrometheusEndpoint(otlpPort, fmt.Sprintf("knuu-%s", s.Knuu.Scope), "10s")) + s.Require().NoError(observabilitySidecar.SetJaegerEndpoint(14250, 6831, 14268)) + s.Require().NoError(observabilitySidecar.SetOtlpExporter("prometheus:9090", "", "")) // Create and start a target pod and configure it to use the obsySidecar to push metrics - target, err := knuu.NewInstance("target") - require.NoError(t, err, "Error creating target instance") - - err = target.SetImage(targetImage) - require.NoError(t, err, "Error setting target image") - - err = target.SetStartCommand("sh", "-c", "while true; do curl -X POST http://localhost:8888/v1/traces; sleep 5; done") - require.NoError(t, err, "Error setting target command") - - require.NoError(t, target.AddSidecar(context.Background(), observabilitySidecar)) + target, err := s.Knuu.NewInstance(namePrefix + "target") + s.Require().NoError(err) - require.NoError(t, target.Commit(), "Error committing target instance") + s.Require().NoError(target.Build().SetImage(ctx, curlImage)) - require.NoError(t, target.Start(), "Error starting target instance") + err = target.Build().SetStartCommand("sh", "-c", targetStartCommand) + s.Require().NoError(err) - t.Cleanup(func() { - if os.Getenv("KNUU_SKIP_CLEANUP") == "true" { - t.Log("Skipping cleanup") - return - } - err := knuu.BatchDestroy(prometheus, target) - if err != nil { - t.Log("Error destroying instances: ", err) - } - }) + s.Require().NoError(target.Sidecars().Add(ctx, observabilitySidecar)) + s.Require().NoError(target.Build().Commit(ctx)) + s.Require().NoError(target.Execution().Start(ctx)) // Wait for the target pod to push data to the otel collector + s.T().Log("Waiting one minute for the target pod to push data to the otel collector") time.Sleep(1 * time.Minute) // Verify that data has been pushed to Prometheus @@ -105,16 +87,16 @@ scrape_configs: defer cancel() req, err := http.NewRequestWithContext(ctx, "GET", prometheusURL, nil) - require.NoError(t, err) + s.Require().NoError(err) resp, err := http.DefaultClient.Do(req) - require.NoError(t, err) - require.Equal(t, 200, resp.StatusCode, "Prometheus API is not accessible") + s.Require().NoError(err) + s.Require().Equal(http.StatusOK, resp.StatusCode, "Prometheus API is not accessible") defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - require.NoError(t, err) - require.Contains(t, string(body), "otel-collector", "otel-collector data source not found in Prometheus") + body, err := io.ReadAll(resp.Body) + s.Require().NoError(err) + s.Require().Contains(string(body), "otel-collector", "otel-collector data source not found in Prometheus") - t.Log("otel-collector data source is available in Prometheus") + s.T().Log("otel-collector data source is available in Prometheus") } diff --git a/e2e/basic/probe_test.go b/e2e/basic/probe_test.go index 0de49b4..12573ac 100644 --- a/e2e/basic/probe_test.go +++ b/e2e/basic/probe_test.go @@ -2,103 +2,46 @@ package basic import ( "context" - "testing" + "strings" - "github.com/stretchr/testify/assert" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" - - "github.com/celestiaorg/knuu/e2e" - "github.com/celestiaorg/knuu/pkg/knuu" ) -func TestProbe(t *testing.T) { - t.Parallel() - // Setup +func (s *Suite) TestProbe() { + const namePrefix = "probe" + ctx := context.Background() // Ideally this has to be defined in the test suit setup - exe := e2e.Executor{ - Kn: knuu.GetKnuuObj(), - } + executor, err := s.Executor.NewInstance(ctx, namePrefix+"-executor") + s.Require().NoError(err) - ctx := context.Background() - executor, err := exe.NewInstance(ctx, "prob-executor") - if err != nil { - t.Fatalf("Error creating executor: %v", err) - } + web := s.createNginxInstanceWithVolume(ctx, namePrefix+"-web") + + err = web.Storage().AddFile(resourcesHTML+"/index.html", nginxHTMLPath+"/index.html", "0:0") + s.Require().NoError(err) - web, err := knuu.NewInstance("web") - if err != nil { - t.Fatalf("Error creating instance '%v':", err) - } - err = web.SetImage("docker.io/nginx:latest") - if err != nil { - t.Fatalf("Error setting image '%v':", err) - } - web.AddPortTCP(80) - err = web.AddExecuteCommand("mkdir", "-p", "/usr/share/nginx/html") - if err != nil { - t.Fatalf("Error executing command '%v':", err) - } - err = web.AddVolumeWithOwner("/usr/share/nginx/html", "1Gi", 0) - if err != nil { - t.Fatalf("Error adding volume: %v", err) - } - err = web.AddFile("../system/resources/html/index.html", "/usr/share/nginx/html/index.html", "0:0") - if err != nil { - t.Fatalf("Error adding file '%v':", err) - } livenessProbe := v1.Probe{ ProbeHandler: v1.ProbeHandler{ HTTPGet: &v1.HTTPGetAction{ Path: "/", - Port: intstr.IntOrString{Type: intstr.Int, IntVal: 80}, + Port: intstr.IntOrString{Type: intstr.Int, IntVal: nginxPort}, }, }, InitialDelaySeconds: 10, } - err = web.SetLivenessProbe(&livenessProbe) - if err != nil { - t.Fatalf("Error setting readiness probe '%v':", err) - } - err = web.Commit() - if err != nil { - t.Fatalf("Error committing instance: %v", err) - } - - t.Cleanup(func() { - // after refactor, we can use instance.BatchDestroy for simplicity - err := executor.Execution().Destroy(ctx) - if err != nil { - t.Logf("Error destroying instance: %v", err) - } - - err = web.Destroy() - if err != nil { - t.Logf("Error destroying instance: %v", err) - } - }) + s.Require().NoError(web.Monitoring().SetLivenessProbe(&livenessProbe)) + s.Require().NoError(web.Build().Commit(ctx)) // Test logic + webIP, err := web.Network().GetIP(ctx) + s.Require().NoError(err) - webIP, err := web.GetIP() - if err != nil { - t.Fatalf("Error getting IP '%v':", err) - } + s.Require().NoError(web.Execution().Start(ctx)) - err = web.Start() - if err != nil { - t.Fatalf("Error starting instance: %v", err) - } - err = web.WaitInstanceIsRunning() - if err != nil { - t.Fatalf("Error waiting for instance to be running: %v", err) - } - - wget, err := executor.Execution().ExecuteCommand(ctx, "wget", "-q", "-O", "-", webIP) - if err != nil { - t.Fatalf("Error executing command '%v':", err) - } + wgetOutput, err := executor.Execution().ExecuteCommand(ctx, "wget", "-q", "-O", "-", webIP) + s.Require().NoError(err) - assert.Contains(t, wget, "Hello World!") + wgetOutput = strings.TrimSpace(wgetOutput) + s.Assert().Contains(wgetOutput, "Hello World!") } diff --git a/e2e/basic/rbac_test.go b/e2e/basic/rbac_test.go index 9086194..1548640 100644 --- a/e2e/basic/rbac_test.go +++ b/e2e/basic/rbac_test.go @@ -1,67 +1,43 @@ package basic import ( - "testing" + "context" + "strings" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" v1 "k8s.io/api/rbac/v1" +) - "github.com/celestiaorg/knuu/pkg/knuu" +const ( + kubectlImage = "docker.io/bitnami/kubectl:latest" ) -func TestRBAC(t *testing.T) { - t.Parallel() - // Setup +func (s *Suite) TestRBAC() { + const namePrefix = "rbac" + ctx := context.Background() + + target, err := s.Knuu.NewInstance(namePrefix + "-target") + s.Require().NoError(err) + s.Require().NoError(target.Build().SetImage(ctx, kubectlImage)) + s.Require().NoError(target.Build().SetStartCommand("sleep", "infinity")) + s.Require().NoError(target.Build().Commit(ctx)) - instance, err := knuu.NewInstance("kubectl") - if err != nil { - t.Fatalf("Error creating instance '%v':", err) - } - err = instance.SetImage("docker.io/bitnami/kubectl:latest") - if err != nil { - t.Fatalf("Error setting image: %v", err) - } - err = instance.SetStartCommand("sleep", "infinity") - if err != nil { - t.Fatalf("Error setting command: %v", err) - } - err = instance.Commit() - if err != nil { - t.Fatalf("Error committing instance: %v", err) - } policyRule := v1.PolicyRule{ Verbs: []string{"get", "list", "watch"}, APIGroups: []string{""}, Resources: []string{"pods"}, } - err = instance.AddPolicyRule(policyRule) - if err != nil { - t.Fatalf("Error adding policy rule: %v", err) - } - - t.Cleanup(func() { - require.NoError(t, knuu.BatchDestroy(instance)) - }) + s.Require().NoError(target.Security().AddPolicyRule(policyRule)) // Test logic - err = instance.Start() - if err != nil { - t.Fatalf("Error starting instance: %v", err) - } - err = instance.WaitInstanceIsRunning() - if err != nil { - t.Fatalf("Error waiting for instance to be running: %v", err) - } - _, err = instance.ExecuteCommand("kubectl", "get", "pods") - if err != nil { - t.Fatalf("Error executing command '%v':", err) - } - exitCode, err := instance.ExecuteCommand("echo", "$?") - if err != nil { - t.Fatalf("Error executing command '%v':", err) - } + s.Require().NoError(target.Execution().Start(ctx)) + + _, err = target.Execution().ExecuteCommand(ctx, "kubectl", "get", "pods") + s.Require().NoError(err) + + exitCode, err := target.Execution().ExecuteCommand(ctx, "echo", "$?") + s.Require().NoError(err) - assert.Equal(t, "0\n", exitCode) + exitCode = strings.TrimSpace(exitCode) + s.Assert().Equal("0", exitCode) } diff --git a/e2e/basic/reverse_proxy_test.go b/e2e/basic/reverse_proxy_test.go index 088aca6..369045f 100644 --- a/e2e/basic/reverse_proxy_test.go +++ b/e2e/basic/reverse_proxy_test.go @@ -2,92 +2,54 @@ package basic import ( "context" + "errors" "io" "net/http" - "os" "strings" - "testing" "time" - "github.com/celestiaorg/knuu/pkg/knuu" "github.com/celestiaorg/knuu/pkg/sidecars/netshaper" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // TestReverseProxy is a test function that verifies the functionality of a reverse proxy setup. // It mainly tests the ability to reach to a service running in a sidecar like netshaper (BitTwister). // It calls an endpoint of the service and checks if the response is as expected. -func TestReverseProxy(t *testing.T) { - t.Parallel() - // Setup - - main, err := knuu.NewInstance("main") - require.NoError(t, err, "Error creating instance") +func (s *Suite) TestReverseProxy() { + const namePrefix = "reverse-proxy" + ctx := context.Background() - err = main.SetImage("alpine:latest") - require.NoError(t, err, "Error setting image") + main, err := s.Knuu.NewInstance(namePrefix + "-main") + s.Require().NoError(err) - err = main.SetStartCommand("sleep", "infinite") - require.NoError(t, err, "Error executing command") - - require.NoError(t, main.Commit(), "Error committing instance") + s.Require().NoError(main.Build().SetImage(ctx, alpineImage)) + s.Require().NoError(main.Build().SetStartCommand("sleep", "infinite")) + s.Require().NoError(main.Build().Commit(ctx)) btSidecar := netshaper.New() - require.NoError(t, main.AddSidecar(context.Background(), btSidecar)) - - t.Cleanup(func() { - if os.Getenv("KNUU_SKIP_CLEANUP") == "true" { - t.Log("Skipping cleanup") - return - } - - require.NoError(t, main.Destroy(), "Error destroying instance") - }) + s.Require().NoError(main.Sidecars().Add(ctx, btSidecar)) - require.NoError(t, main.Start(), "Error starting main instance") - - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) - defer cancel() + s.Require().NoError(main.Execution().Start(ctx)) - require.NoError(t, btSidecar.WaitForStart(ctx), "Error waiting for BitTwister to start") - - // test if BitTwister running in a sidecar is accessible - err = btSidecar.SetBandwidthLimit(1000) - assert.NoError(t, err, "Error setting bandwidth limit") + s.Require().NoError(btSidecar.WaitForStart(ctx)) // Check if the BitTwister service is set out, err := btSidecar.AllServicesStatus() - assert.NoError(t, err, "Error getting all services status") - assert.GreaterOrEqual(t, len(out), 1, "No services found") - assert.NotEmpty(t, out[0].Name, "Service name is empty") -} - -func TestAddHostWithReadyCheck(t *testing.T) { - t.Parallel() - - target, err := knuu.NewInstance("target") - require.NoError(t, err, "Error creating instance 'target'") + s.Require().NoError(err) - err = target.SetImage("nginx:latest") - require.NoError(t, err, "error setting image") + s.Assert().GreaterOrEqual(len(out), 1) + s.Assert().NotEmpty(out[0].Name) - require.NoError(t, target.Commit(), "error committing instance") + // assert that the BitTwister running in a sidecar is accessible + s.Assert().NoError(btSidecar.SetBandwidthLimit(4_000_000)) +} - t.Cleanup(func() { - if os.Getenv("KNUU_SKIP_CLEANUP") == "true" { - t.Log("Skipping cleanup") - return - } - if err := target.Destroy(); err != nil { - t.Logf("error destroying instance: %v", err) - } - }) +func (s *Suite) TestAddHostWithReadyCheck() { + const namePrefix = "add-host-with-ready-check" + ctx := context.Background() - const port = 80 - require.NoError(t, target.AddPortTCP(port), "error adding port") - require.NoError(t, target.Start(), "error starting instance") + target := s.createNginxInstance(ctx, namePrefix+"-target") + s.Require().NoError(target.Build().Commit(ctx)) + s.Require().NoError(target.Execution().Start(ctx)) ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel() @@ -96,6 +58,9 @@ func TestAddHostWithReadyCheck(t *testing.T) { checkFunc := func(host string) (bool, error) { resp, err := http.Get(host) if err != nil { + if errors.Is(err, io.EOF) { + return false, nil + } return false, err } defer resp.Body.Close() @@ -110,12 +75,12 @@ func TestAddHostWithReadyCheck(t *testing.T) { return strings.Contains(string(bodyBytes), "Welcome to nginx!"), nil } - host, err := target.Network().AddHostWithReadyCheck(ctx, port, checkFunc) - require.NoError(t, err, "error adding host with ready check") - assert.NotEmpty(t, host, "host should not be empty") + host, err := target.Network().AddHostWithReadyCheck(ctx, nginxPort, checkFunc) + s.Require().NoError(err, "error adding host with ready check") + s.Assert().NotEmpty(host, "host should not be empty") // Additional verification that the host is accessible ok, err := checkFunc(host) - require.NoError(t, err, "error checking host") - assert.True(t, ok, "Host should be ready and serving content: expected true, got false") + s.Require().NoError(err, "error checking host") + s.Assert().True(ok, "Host should be ready and serving content: expected true, got false") } diff --git a/e2e/basic/suite_setup_test.go b/e2e/basic/suite_setup_test.go index 39ac31f..4fb8832 100644 --- a/e2e/basic/suite_setup_test.go +++ b/e2e/basic/suite_setup_test.go @@ -2,41 +2,121 @@ package basic import ( "context" + "sync" + "sync/atomic" "testing" + "time" "github.com/sirupsen/logrus" "github.com/stretchr/testify/suite" + "k8s.io/apimachinery/pkg/api/resource" + "github.com/celestiaorg/knuu/e2e" + "github.com/celestiaorg/knuu/pkg/instance" + "github.com/celestiaorg/knuu/pkg/k8s" "github.com/celestiaorg/knuu/pkg/knuu" + "github.com/celestiaorg/knuu/pkg/minio" ) -type TestSuite struct { +const ( + testTimeout = time.Minute * 15 // the same time that is used in the ci/cd pipeline + + nginxImage = "docker.io/nginx:latest" + nginxVolumeOwner = 0 + nginxPort = 80 + nginxHTMLPath = "/usr/share/nginx/html" + nginxCommand = "nginx -g daemon off" + + resourcesHTML = "../system/resources/html" + + alpineImage = "alpine:latest" +) + +type Suite struct { suite.Suite - Knuu *knuu.Knuu + Knuu *knuu.Knuu + Executor e2e.Executor + + cleanupMu sync.Mutex + totalTests atomic.Int32 + finishedTests int32 +} + +var ( + nginxVolume = resource.MustParse("1Gi") +) + +func TestRunSuite(t *testing.T) { + suite.Run(t, new(Suite)) } -func (s *TestSuite) SetupSuite() { +func (s *Suite) SetupSuite() { var ( - err error - ctx = context.Background() + ctx = context.Background() + logger = logrus.New() ) + + k8sClient, err := k8s.NewClient(ctx, knuu.DefaultScope(), logger) + s.Require().NoError(err) + + minioClient, err := minio.New(ctx, k8sClient, logger) + s.Require().NoError(err) + s.Knuu, err = knuu.New(ctx, knuu.Options{ - Scope: "e2e-basic", + ProxyEnabled: true, + K8sClient: k8sClient, + MinioClient: minioClient, + Timeout: testTimeout, }) s.Require().NoError(err) + + s.T().Logf("Scope: %s", s.Knuu.Scope) s.Knuu.HandleStopSignal(ctx) + + s.Executor.Kn = s.Knuu } -func (s *TestSuite) TearDownSuite() { - s.T().Cleanup(func() { - logrus.Info("Tearing down test suite...") - err := s.Knuu.CleanUp(context.Background()) - if err != nil { - s.T().Logf("Error cleaning up test suite: %v", err) - } - }) +// SetupTest is a test setup function that is called before each test is run. +func (s *Suite) SetupTest() { + s.totalTests.Add(1) + s.T().Parallel() } -func TestRunSuite(t *testing.T) { - suite.Run(t, new(TestSuite)) +// TearDownTest is a test teardown function that is called after each test is run. +func (s *Suite) TearDownTest() { + s.cleanupMu.Lock() + defer s.cleanupMu.Unlock() + s.finishedTests++ + + // if I am the last test to finish, I need to clean up the suite + if s.finishedTests == s.totalTests.Load() { + s.cleanupSuite() + } +} + +func (s *Suite) cleanupSuite() { + s.T().Logf("Cleaning up knuu...") + if err := s.Knuu.CleanUp(context.Background()); err != nil { + s.T().Logf("Error cleaning up test suite: %v", err) + } + s.T().Logf("Knuu is cleaned up") +} + +func (s *Suite) createNginxInstance(ctx context.Context, name string) *instance.Instance { + ins, err := s.Knuu.NewInstance(name) + s.Require().NoError(err) + + s.Require().NoError(ins.Build().SetImage(ctx, nginxImage)) + s.Require().NoError(ins.Network().AddPortTCP(nginxPort)) + return ins +} + +func (s *Suite) createNginxInstanceWithVolume(ctx context.Context, name string) *instance.Instance { + ins := s.createNginxInstance(ctx, name) + + err := ins.Build().ExecuteCommand("mkdir", "-p", nginxHTMLPath) + s.Require().NoError(err) + + s.Require().NoError(ins.Storage().AddVolumeWithOwner(nginxHTMLPath, nginxVolume, nginxVolumeOwner)) + return ins } diff --git a/pkg/knuu/instance_old.go b/pkg/knuu/instance_old.go deleted file mode 100644 index 055f5b3..0000000 --- a/pkg/knuu/instance_old.go +++ /dev/null @@ -1,343 +0,0 @@ -/* -* This file is deprecated. -* Please use the new package knuu instead. -* This file keeps the old functionality of knuu for backward compatibility. -* A global variable is defined, tmpKnuu, which is used to hold the knuu instance. - */ - -package knuu - -import ( - "context" - "errors" - "io" - - v1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/apimachinery/pkg/runtime/schema" - - "github.com/celestiaorg/knuu/pkg/builder" - "github.com/celestiaorg/knuu/pkg/instance" -) - -type Instance struct { - instance.Instance -} - -type Executor struct { - *Instance -} - -type InstanceState instance.InstanceState - -const ( - None InstanceState = iota - Preparing - Committed - Started - Stopped - Destroyed -) - -// Deprecated: Use the new package knuu instead. -func NewInstance(name string) (*Instance, error) { - if tmpKnuu == nil { - return nil, errors.New("tmpKnuu is not initialized") - } - - i, err := tmpKnuu.NewInstance(name) - if err != nil { - return nil, err - } - return &Instance{*i}, nil -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) SetImage(image string) error { - if tmpKnuu == nil { - return errors.New("tmpKnuu is not initialized") - } - ctx, cancel := context.WithTimeout(context.Background(), tmpKnuu.timeout) - defer cancel() - return i.Instance.Build().SetImage(ctx, image) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) SetGitRepo(ctx context.Context, gitContext builder.GitContext) error { - return i.Instance.Build().SetGitRepo(ctx, gitContext) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) SetImageInstant(image string) error { - return i.Instance.Execution().UpgradeImage(context.Background(), image) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) SetStartCommand(command ...string) error { - return i.Instance.Build().SetStartCommand(command...) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) SetArgs(args ...string) error { - return i.Instance.Build().SetArgs(args...) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) AddPortTCP(port int) error { - return i.Instance.Network().AddPortTCP(port) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) PortForwardTCP(port int) (int, error) { - return i.Instance.Network().PortForwardTCP(context.Background(), port) -} - -// AddPortUDP adds a UDP port to the instance -// Deprecated: Use the new package knuu instead. -func (i *Instance) AddPortUDP(port int) error { - return i.Instance.Network().AddPortUDP(port) -} - -// Deprecated: Use the new package knuu instead. -// ExecuteCommand executes a command in the instance -func (i *Instance) ExecuteCommand(command ...string) (string, error) { - return i.Instance.Execution().ExecuteCommand(context.Background(), command...) -} - -// Deprecated: Use the new package knuu instead. -// This function adds a command to the instance while it is in the building phase -func (i *Instance) AddExecuteCommand(command ...string) error { - return i.Instance.Build().ExecuteCommand(command...) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) ExecuteCommandWithContext(ctx context.Context, command ...string) (string, error) { - return i.Instance.Execution().ExecuteCommand(ctx, command...) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) AddFile(srcPath, dstPath string, chown string) error { - return i.Instance.Storage().AddFile(srcPath, dstPath, chown) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) AddFolder(srcPath, dstPath string, chown string) error { - return i.Instance.Storage().AddFolder(srcPath, dstPath, chown) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) AddFileBytes(bytes []byte, dest string, chown string) error { - return i.Instance.Storage().AddFileBytes(bytes, dest, chown) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) SetUser(user string) error { - return i.Instance.Build().SetUser(user) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) Commit() error { - return i.Instance.Build().Commit(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) AddVolume(path, size string) error { - return i.Instance.Storage().AddVolume(path, resource.MustParse(size)) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) AddVolumeWithOwner(path, size string, owner int64) error { - return i.Instance.Storage().AddVolumeWithOwner(path, resource.MustParse(size), owner) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) SetMemory(request, limit string) error { - return i.Instance.Resources().SetMemory(resource.MustParse(request), resource.MustParse(limit)) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) SetCPU(request string) error { - return i.Instance.Resources().SetCPU(resource.MustParse(request)) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) SetEnvironmentVariable(key, value string) error { - return i.Instance.Build().SetEnvironmentVariable(key, value) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) GetIP() (string, error) { - return i.Instance.Network().GetIP(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) GetFileBytes(file string) ([]byte, error) { - return i.Instance.Storage().GetFileBytes(context.Background(), file) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) ReadFileFromRunningInstance(ctx context.Context, filePath string) (io.ReadCloser, error) { - return i.Instance.Storage().ReadFileFromRunningInstance(ctx, filePath) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) AddPolicyRule(rule rbacv1.PolicyRule) error { - return i.Instance.Security().AddPolicyRule(rule) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) SetLivenessProbe(livenessProbe *v1.Probe) error { - return i.Instance.Monitoring().SetLivenessProbe(livenessProbe) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) SetReadinessProbe(readinessProbe *v1.Probe) error { - return i.Instance.Monitoring().SetReadinessProbe(readinessProbe) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) SetStartupProbe(startupProbe *v1.Probe) error { - return i.Instance.Monitoring().SetStartupProbe(startupProbe) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) AddSidecar(ctx context.Context, sc instance.SidecarManager) error { - return i.Instance.Sidecars().Add(ctx, sc) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) SetPrivileged(privileged bool) error { - return i.Instance.Security().SetPrivileged(privileged) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) AddKubernetesCapability(capability string) error { - return i.Instance.Security().AddKubernetesCapability(capability) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) AddKubernetesCapabilities(capabilities []string) error { - return i.Instance.Security().AddKubernetesCapabilities(capabilities) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) StartAsync() error { - return i.Instance.Execution().StartAsync(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) StartWithoutWait() error { - return i.Instance.Execution().StartAsync(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) Start() error { - return i.Instance.Execution().Start(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) IsRunning() (bool, error) { - return i.Instance.Execution().IsRunning(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) WaitInstanceIsRunning() error { - return i.Instance.Execution().WaitInstanceIsRunning(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) DisableNetwork() error { - return i.Instance.Network().Disable(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) EnableNetwork() error { - return i.Instance.Network().Enable(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) NetworkIsDisabled() (bool, error) { - return i.Instance.Network().IsDisabled(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) WaitInstanceIsStopped() error { - return i.Instance.Execution().WaitInstanceIsStopped(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) Stop() error { - return i.Instance.Execution().Stop(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) Clone() (*Instance, error) { - newInst, err := i.Instance.Clone() - if err != nil { - return nil, err - } - return &Instance{Instance: *newInst}, nil -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) CloneWithName(name string) (*Instance, error) { - newInst, err := i.Instance.CloneWithName(name) - if err != nil { - return nil, err - } - return &Instance{*newInst}, nil -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) CreateCustomResource(gvr *schema.GroupVersionResource, obj *map[string]interface{}) error { - return i.Instance.Resources().CreateCustomResource(context.Background(), gvr, obj) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) CustomResourceDefinitionExists(gvr *schema.GroupVersionResource) (bool, error) { - return i.Instance.Resources().CustomResourceDefinitionExists(context.Background(), gvr) -} - -// Deprecated: Use the new package knuu instead. -func NewExecutor() (*Executor, error) { - return nil, ErrDeprecated -} - -// Deprecated: Use the new package knuu instead. -func (e *Executor) Destroy() error { - return e.Instance.Destroy() -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) Destroy() error { - return i.Instance.Execution().Destroy(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func BatchDestroy(instances ...*Instance) error { - ins := make([]*instance.Instance, len(instances)) - for i, instance := range instances { - ins[i] = &instance.Instance - } - return instance.BatchDestroy(context.Background(), ins...) -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) Labels() map[string]string { - return i.Instance.Execution().Labels() -} - -// Deprecated: Use the new package knuu instead. -func (i *Instance) IsInState(states ...InstanceState) bool { - statesNew := make([]instance.InstanceState, len(states)) - for i, state := range states { - statesNew[i] = instance.InstanceState(state) - } - return i.Instance.IsInState(statesNew...) -} - -func (i *Instance) AddHost(port int) (err error, host string) { - host, err = i.Instance.Network().AddHost(context.Background(), port) - return err, host -} diff --git a/pkg/knuu/knuu_old.go b/pkg/knuu/knuu_old.go deleted file mode 100644 index db8eca3..0000000 --- a/pkg/knuu/knuu_old.go +++ /dev/null @@ -1,166 +0,0 @@ -/* -* This file is deprecated. -* Please use the new package knuu instead. -* This file keeps the old functionality of knuu for backward compatibility. -* A global variable is defined, tmpKnuu, which is used to hold the knuu instance. - */ -package knuu - -import ( - "context" - "errors" - "fmt" - "io" - "os" - "time" - - "github.com/sirupsen/logrus" - - "github.com/celestiaorg/knuu/pkg/builder" - "github.com/celestiaorg/knuu/pkg/builder/docker" - "github.com/celestiaorg/knuu/pkg/builder/kaniko" - "github.com/celestiaorg/knuu/pkg/k8s" - "github.com/celestiaorg/knuu/pkg/log" - "github.com/celestiaorg/knuu/pkg/minio" -) - -const minioBucketName = "knuu" - -// This is a temporary variable to hold the knuu instance until we refactor knuu pkg -// TODO: remove this temporary variable -var tmpKnuu *Knuu - -// Deprecated: Use the new package knuu instead. -// Initialize initializes knuu with a unique scope -func Initialize() error { - t := time.Now() - scope := fmt.Sprintf("%s-%03d", t.Format("20060102-150405"), t.Nanosecond()/1e6) - return InitializeWithScope(scope) -} - -// Deprecated: Use the new package knuu instead. -func Scope() string { - if tmpKnuu == nil { - return "" - } - return tmpKnuu.Scope -} - -// Deprecated: Use the new package knuu instead. -// InitializeWithScope initializes knuu with a given scope -func InitializeWithScope(testScope string) error { - // Override scope if KNUU_NAMESPACE is set - namespaceEnv := os.Getenv("KNUU_NAMESPACE") - if namespaceEnv != "" { - testScope = namespaceEnv - logrus.Warnf("KNUU_NAMESPACE is deprecated. Scope overridden to: %s", testScope) - } - - logrus.Infof("Initializing knuu with scope: %s", testScope) - - // read timeout from env - var ( - timeoutString = os.Getenv("KNUU_TIMEOUT") - timeout = 60 * time.Minute - ) - if timeoutString != "" { - parsedTimeout, err := time.ParseDuration(timeoutString) - if err != nil { - return ErrCannotParseTimeout.Wrap(err) - } - timeout = parsedTimeout - } - - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) - defer cancel() - - logger := log.DefaultLogger() - k8sClient, err := k8s.NewClient(ctx, testScope, logger) - if err != nil { - return ErrCannotInitializeKnuu.Wrap(err) - } - - minioClient, err := minio.New(ctx, k8sClient, logger) - if err != nil { - return ErrCannotInitializeKnuu.Wrap(err) - } - - tmpKnuu, err = New(ctx, Options{ - K8sClient: k8sClient, - Scope: testScope, - Timeout: timeout, - ProxyEnabled: true, - MinioClient: minioClient, - Logger: logger, - }) - if err != nil { - return ErrCannotInitializeKnuu.Wrap(err) - } - - builderType := os.Getenv("KNUU_BUILDER") - switch builderType { - case "kubernetes": - tmpKnuu.ImageBuilder = &kaniko.Kaniko{ - SystemDependencies: tmpKnuu.SystemDependencies, - } - case "docker", "": - tmpKnuu.ImageBuilder = &docker.Docker{ - K8sClientset: tmpKnuu.K8sClient.Clientset(), - K8sNamespace: tmpKnuu.K8sClient.Namespace(), - } - default: - return ErrInvalidKnuuBuilder.WithParams(builderType) - } - - // TODO: this must be moved to somewhere more meaningful - tmpKnuu.HandleStopSignal(context.Background()) - return nil -} - -// Deprecated: Identifier is deprecated, use Scope() instead. -func Identifier() string { - logrus.Warn("Identifier() is deprecated, use Scope() instead.") - return Scope() -} - -// Deprecated: InitializeWithIdentifier is deprecated, use InitializeWithScope(scope string) instead. -func InitializeWithIdentifier(uniqueIdentifier string) error { - logrus.Warn("InitializeWithIdentifier is deprecated, use InitializeWithScope(scope string) instead.") - return InitializeWithScope(uniqueIdentifier) -} - -// Deprecated: Use the new package knuu instead. -func ImageBuilder() builder.Builder { - if tmpKnuu == nil { - return nil - } - return tmpKnuu.ImageBuilder -} - -// Deprecated: Use the new package knuu instead. -// IsInitialized returns true if knuu is initialized, and false otherwise -func IsInitialized() bool { - return tmpKnuu != nil -} - -// Deprecated: Use the new package knuu instead. -func CleanUp() error { - if tmpKnuu == nil { - return errors.New("tmpKnuu is not initialized") - } - return tmpKnuu.CleanUp(context.Background()) -} - -// Deprecated: Use the new package knuu instead. -func PushFileToMinio(ctx context.Context, contentName string, reader io.Reader) error { - return tmpKnuu.MinioClient.Push(ctx, reader, contentName, minioBucketName) -} - -// Deprecated: Use the new package knuu instead. -func GetMinioURL(ctx context.Context, contentName string) (string, error) { - return tmpKnuu.MinioClient.GetURL(ctx, contentName, minioBucketName) -} - -func GetKnuuObj() *Knuu { - return tmpKnuu -} diff --git a/pkg/knuu/preloader_old.go b/pkg/knuu/preloader_old.go deleted file mode 100644 index 953325a..0000000 --- a/pkg/knuu/preloader_old.go +++ /dev/null @@ -1,42 +0,0 @@ -/* -* This file is deprecated. -* Please use the new package knuu instead. -* This file keeps the old functionality of knuu for backward compatibility. -* A global variable is defined, tmpKnuu, which is used to hold the knuu instance. - */ - -package knuu - -import ( - "context" - - "github.com/celestiaorg/knuu/pkg/preloader" -) - -type Preloader struct { - preloader.Preloader -} - -// Deprecated: Use the new package knuu instead. -func NewPreloader() (*Preloader, error) { - p, err := tmpKnuu.NewPreloader() - if err != nil { - return nil, err - } - return &Preloader{Preloader: *p}, nil -} - -// Deprecated: Use the new package knuu instead. -func (p *Preloader) AddImage(image string) error { - return p.Preloader.AddImage(context.Background(), image) -} - -// Deprecated: Use the new package knuu instead. -func (p *Preloader) RemoveImage(image string) error { - return p.Preloader.RemoveImage(context.Background(), image) -} - -// Deprecated: Use the new package knuu instead. -func (p *Preloader) EmptyImages() error { - return p.Preloader.EmptyImages(context.Background()) -}