diff --git a/Makefile b/Makefile index 71dddec..ab5ba53 100644 --- a/Makefile +++ b/Makefile @@ -60,24 +60,32 @@ test: ## Run all the tests $(GINKGO) $(GINKGO_FLAGS) --label-filter=$(label-filter) .PHONY: test-unit -test-unit: ## Run the unit tests (skips the e2e) +test-unit: ## Run the unit tests (skips the e2e and integration tests) $(GINKGO) $(GINKGO_FLAGS) --skip-file=tests/* -.PHONY: test-controller -test-controller: ## Run the controller tests (pkg/controller) - $(GINKGO) $(GINKGO_FLAGS) pkg/controller +.PHONY: test-kubelet +test-kubelet: ## Run the k3k-kubelet controller tests (tests/integration/k3k-kubelet) + $(GINKGO) $(GINKGO_FLAGS) tests/integration/k3k-kubelet -.PHONY: test-kubelet-controller -test-kubelet-controller: ## Run the controller tests (pkg/controller) - $(GINKGO) $(GINKGO_FLAGS) k3k-kubelet/controller +.PHONY: test-policy +test-policy: ## Run the policy controller tests (tests/integration/policy) + $(GINKGO) $(GINKGO_FLAGS) tests/integration/policy + +.PHONY: test-cluster +test-cluster: ## Run the cluster controller tests (tests/integration/cluster) + $(GINKGO) $(GINKGO_FLAGS) tests/integration/cluster + +.PHONY: test-integration +test-integration: ## Run the controller tests that use envtest (tests/integration) + $(GINKGO) $(GINKGO_FLAGS) tests/integration .PHONY: test-e2e test-e2e: ## Run the e2e tests - $(GINKGO) $(GINKGO_FLAGS) --label-filter="$(E2E_LABEL_FILTER)" tests + $(GINKGO) $(GINKGO_FLAGS) --label-filter="$(E2E_LABEL_FILTER)" tests/e2e .PHONY: test-cli test-cli: ## Run the cli tests - $(GINKGO) $(GINKGO_FLAGS) --label-filter=cli --flake-attempts=3 tests + $(GINKGO) $(GINKGO_FLAGS) --flake-attempts=3 tests/cli .PHONY: generate generate: ## Generate the CRDs specs diff --git a/docs/development.md b/docs/development.md index 2e3b39d..caa4d85 100644 --- a/docs/development.md +++ b/docs/development.md @@ -51,9 +51,11 @@ To see all the available Make commands you can run `make help`, i.e: package Package the k3k and k3k-kubelet Docker images push Push the K3k images to the registry test Run all the tests - test-unit Run the unit tests (skips the e2e) - test-controller Run the controller tests (pkg/controller) - test-kubelet-controller Run the controller tests (pkg/controller) + test-unit Run the unit tests (skips the e2e and integration tests) + test-kubelet Run the k3k-kubelet controller tests (tests/integration/k3k-kubelet) + test-policy Run the policy controller tests (tests/integration/policy) + test-cluster Run the cluster controller tests (tests/integration/cluster) + test-integration Run the controller tests (pkg/controller) test-e2e Run the e2e tests test-cli Run the cli tests generate Generate the CRDs specs diff --git a/tests/cli_test.go b/tests/cli/cli_test.go similarity index 99% rename from tests/cli_test.go rename to tests/cli/cli_test.go index 31cd5d0..38fb2d1 100644 --- a/tests/cli_test.go +++ b/tests/cli/cli_test.go @@ -1,4 +1,4 @@ -package k3k_test +package cli_test import ( "bytes" diff --git a/tests/cli/common_test.go b/tests/cli/common_test.go new file mode 100644 index 0000000..5c5301f --- /dev/null +++ b/tests/cli/common_test.go @@ -0,0 +1,55 @@ +package cli_test + +import ( + "context" + "fmt" + "os" + "sync" + + "k8s.io/utils/ptr" + "sigs.k8s.io/controller-runtime/pkg/client" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func NewNamespace() *v1.Namespace { + GinkgoHelper() + + namespace := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{GenerateName: "ns-", Labels: map[string]string{"e2e": "true"}}} + namespace, err := k8s.CoreV1().Namespaces().Create(context.Background(), namespace, metav1.CreateOptions{}) + Expect(err).To(Not(HaveOccurred())) + + return namespace +} + +func DeleteNamespaces(names ...string) { + GinkgoHelper() + + if _, found := os.LookupEnv("KEEP_NAMESPACES"); found { + By(fmt.Sprintf("Keeping namespace %v", names)) + return + } + + wg := sync.WaitGroup{} + wg.Add(len(names)) + + for _, name := range names { + go func() { + defer wg.Done() + defer GinkgoRecover() + + By(fmt.Sprintf("Deleting namespace %s", name)) + + err := k8s.CoreV1().Namespaces().Delete(context.Background(), name, metav1.DeleteOptions{ + GracePeriodSeconds: ptr.To[int64](0), + }) + Expect(client.IgnoreNotFound(err)).To(Not(HaveOccurred())) + }() + } + + wg.Wait() +} diff --git a/tests/cli/k8s_restclientgetter_test.go b/tests/cli/k8s_restclientgetter_test.go new file mode 100644 index 0000000..6506412 --- /dev/null +++ b/tests/cli/k8s_restclientgetter_test.go @@ -0,0 +1,56 @@ +package cli_test + +import ( + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/client-go/discovery" + "k8s.io/client-go/rest" + "k8s.io/client-go/restmapper" + "k8s.io/client-go/tools/clientcmd" + + memory "k8s.io/client-go/discovery/cached" +) + +type RESTClientGetter struct { + clientconfig clientcmd.ClientConfig + restConfig *rest.Config + discoveryClient discovery.CachedDiscoveryInterface +} + +func NewRESTClientGetter(kubeconfig []byte) (*RESTClientGetter, error) { + clientconfig, err := clientcmd.NewClientConfigFromBytes([]byte(kubeconfig)) + if err != nil { + return nil, err + } + + restConfig, err := clientconfig.ClientConfig() + if err != nil { + return nil, err + } + + dc, err := discovery.NewDiscoveryClientForConfig(restConfig) + if err != nil { + return nil, err + } + + return &RESTClientGetter{ + clientconfig: clientconfig, + restConfig: restConfig, + discoveryClient: memory.NewMemCacheClient(dc), + }, nil +} + +func (r *RESTClientGetter) ToRESTConfig() (*rest.Config, error) { + return r.restConfig, nil +} + +func (r *RESTClientGetter) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) { + return r.discoveryClient, nil +} + +func (r *RESTClientGetter) ToRESTMapper() (meta.RESTMapper, error) { + return restmapper.NewDeferredDiscoveryRESTMapper(r.discoveryClient), nil +} + +func (r *RESTClientGetter) ToRawKubeConfigLoader() clientcmd.ClientConfig { + return r.clientconfig +} diff --git a/tests/cli/tests_suite_test.go b/tests/cli/tests_suite_test.go new file mode 100644 index 0000000..3765b00 --- /dev/null +++ b/tests/cli/tests_suite_test.go @@ -0,0 +1,234 @@ +package cli_test + +import ( + "context" + "io" + "maps" + "os" + "path" + "strings" + "testing" + "time" + + "github.com/go-logr/zapr" + "github.com/testcontainers/testcontainers-go" + "github.com/testcontainers/testcontainers-go/modules/k3s" + "go.uber.org/zap" + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/chart/loader" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + + "github.com/rancher/k3k/pkg/apis/k3k.io/v1beta1" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +const ( + k3kNamespace = "k3k-system" + + k3sVersion = "v1.35.2-k3s1" + k3sOldVersion = "v1.35.0-k3s1" +) + +func TestTests(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Tests Suite") +} + +var ( + k3sContainer *k3s.K3sContainer + restcfg *rest.Config + k8s *kubernetes.Clientset + k8sClient client.Client + kubeconfigPath string + helmActionConfig *action.Configuration +) + +var _ = BeforeSuite(func() { + ctx := context.Background() + + _, dockerInstallEnabled := os.LookupEnv("K3K_DOCKER_INSTALL") + + if dockerInstallEnabled { + repo := os.Getenv("REPO") + if repo == "" { + repo = "rancher" + } + + installK3SDocker(ctx, repo+"/k3k", repo+"/k3k-kubelet") + initKubernetesClient() + installK3kChart(repo+"/k3k", repo+"/k3k-kubelet") + } else { + initKubernetesClient() + } +}) + +func initKubernetesClient() { + var ( + err error + kubeconfig []byte + ) + + logger, err := zap.NewDevelopment() + Expect(err).NotTo(HaveOccurred()) + + log.SetLogger(zapr.NewLogger(logger)) + + kubeconfigPath := os.Getenv("KUBECONFIG") + Expect(kubeconfigPath).To(Not(BeEmpty())) + + kubeconfig, err = os.ReadFile(kubeconfigPath) + Expect(err).To(Not(HaveOccurred())) + + restcfg, err = clientcmd.RESTConfigFromKubeConfig(kubeconfig) + Expect(err).To(Not(HaveOccurred())) + + k8s, err = kubernetes.NewForConfig(restcfg) + Expect(err).To(Not(HaveOccurred())) + + scheme := buildScheme() + k8sClient, err = client.New(restcfg, client.Options{Scheme: scheme}) + Expect(err).NotTo(HaveOccurred()) +} + +func buildScheme() *runtime.Scheme { + scheme := runtime.NewScheme() + + err := clientgoscheme.AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + err = v1beta1.AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + return scheme +} + +func installK3SDocker(ctx context.Context, controllerImage, kubeletImage string) { + var ( + err error + kubeconfig []byte + ) + + k3sHostVersion := os.Getenv("K3S_HOST_VERSION") + if k3sHostVersion == "" { + k3sHostVersion = k3sVersion + } + + k3sHostVersion = strings.ReplaceAll(k3sHostVersion, "+", "-") + + k3sContainer, err = k3s.Run(ctx, "rancher/k3s:"+k3sHostVersion) + Expect(err).To(Not(HaveOccurred())) + + containerIP, err := k3sContainer.ContainerIP(ctx) + Expect(err).To(Not(HaveOccurred())) + + GinkgoWriter.Println("K3s containerIP: " + containerIP) + + kubeconfig, err = k3sContainer.GetKubeConfig(context.Background()) + Expect(err).To(Not(HaveOccurred())) + + tmpFile, err := os.CreateTemp("", "kubeconfig-") + Expect(err).To(Not(HaveOccurred())) + + _, err = tmpFile.Write(kubeconfig) + Expect(err).To(Not(HaveOccurred())) + Expect(tmpFile.Close()).To(Succeed()) + kubeconfigPath = tmpFile.Name() + + err = k3sContainer.LoadImages(ctx, controllerImage+":dev", kubeletImage+":dev") + Expect(err).To(Not(HaveOccurred())) + DeferCleanup(os.Remove, kubeconfigPath) + + Expect(os.Setenv("KUBECONFIG", kubeconfigPath)).To(Succeed()) + GinkgoWriter.Printf("KUBECONFIG set to: %s\n", kubeconfigPath) +} + +func installK3kChart(controllerImage, kubeletImage string) { + pwd, err := os.Getwd() + Expect(err).To(Not(HaveOccurred())) + + k3kChart, err := loader.Load(path.Join(pwd, "../../charts/k3k")) + Expect(err).To(Not(HaveOccurred())) + + helmActionConfig = new(action.Configuration) + + kubeconfig, err := os.ReadFile(kubeconfigPath) + Expect(err).To(Not(HaveOccurred())) + + restClientGetter, err := NewRESTClientGetter(kubeconfig) + Expect(err).To(Not(HaveOccurred())) + + err = helmActionConfig.Init(restClientGetter, k3kNamespace, os.Getenv("HELM_DRIVER"), func(format string, v ...any) { + GinkgoWriter.Printf("[Helm] "+format+"\n", v...) + }) + Expect(err).To(Not(HaveOccurred())) + + iCli := action.NewInstall(helmActionConfig) + iCli.ReleaseName = "k3k" + iCli.Namespace = k3kNamespace + iCli.CreateNamespace = true + iCli.Timeout = time.Minute + iCli.Wait = true + + controllerMap, _ := k3kChart.Values["controller"].(map[string]any) + + extraEnvArray, _ := controllerMap["extraEnv"].([]map[string]any) + extraEnvArray = append(extraEnvArray, map[string]any{ + "name": "DEBUG", + "value": "true", + }) + controllerMap["extraEnv"] = extraEnvArray + + imageMap, _ := controllerMap["image"].(map[string]any) + maps.Copy(imageMap, map[string]any{ + "repository": controllerImage, + "tag": "dev", + "pullPolicy": "IfNotPresent", + }) + + agentMap, _ := k3kChart.Values["agent"].(map[string]any) + sharedAgentMap, _ := agentMap["shared"].(map[string]any) + sharedAgentImageMap, _ := sharedAgentMap["image"].(map[string]any) + maps.Copy(sharedAgentImageMap, map[string]any{ + "repository": kubeletImage, + "tag": "dev", + }) + + release, err := iCli.Run(k3kChart, k3kChart.Values) + Expect(err).To(Not(HaveOccurred())) + + GinkgoWriter.Printf("Helm release '%s' installed in '%s' namespace\n", release.Name, release.Namespace) +} + +var _ = AfterSuite(func() { + ctx := context.Background() + + if k3sContainer != nil { + // dump k3s logs + k3sLogs, err := k3sContainer.Logs(ctx) + Expect(err).To(Not(HaveOccurred())) + writeLogs("k3s.log", k3sLogs) + + testcontainers.CleanupContainer(GinkgoTB(), k3sContainer) + } +}) + +func writeLogs(filename string, logs io.ReadCloser) { + logsStr, err := io.ReadAll(logs) + Expect(err).To(Not(HaveOccurred())) + + tempfile := path.Join(os.TempDir(), filename) + err = os.WriteFile(tempfile, []byte(logsStr), 0o644) + Expect(err).To(Not(HaveOccurred())) + + GinkgoWriter.Println("logs written to: " + filename) + + _ = logs.Close() +} diff --git a/tests/cluster_addons_test.go b/tests/e2e/cluster_addons_test.go similarity index 100% rename from tests/cluster_addons_test.go rename to tests/e2e/cluster_addons_test.go diff --git a/tests/cluster_certs_test.go b/tests/e2e/cluster_certs_test.go similarity index 100% rename from tests/cluster_certs_test.go rename to tests/e2e/cluster_certs_test.go diff --git a/tests/cluster_network_test.go b/tests/e2e/cluster_network_test.go similarity index 100% rename from tests/cluster_network_test.go rename to tests/e2e/cluster_network_test.go diff --git a/tests/cluster_persistence_test.go b/tests/e2e/cluster_persistence_test.go similarity index 100% rename from tests/cluster_persistence_test.go rename to tests/e2e/cluster_persistence_test.go diff --git a/tests/cluster_pod_test.go b/tests/e2e/cluster_pod_test.go similarity index 100% rename from tests/cluster_pod_test.go rename to tests/e2e/cluster_pod_test.go diff --git a/tests/cluster_registry_test.go b/tests/e2e/cluster_registry_test.go similarity index 100% rename from tests/cluster_registry_test.go rename to tests/e2e/cluster_registry_test.go diff --git a/tests/cluster_status_test.go b/tests/e2e/cluster_status_test.go similarity index 100% rename from tests/cluster_status_test.go rename to tests/e2e/cluster_status_test.go diff --git a/tests/cluster_sync_test.go b/tests/e2e/cluster_sync_test.go similarity index 100% rename from tests/cluster_sync_test.go rename to tests/e2e/cluster_sync_test.go diff --git a/tests/cluster_update_test.go b/tests/e2e/cluster_update_test.go similarity index 100% rename from tests/cluster_update_test.go rename to tests/e2e/cluster_update_test.go diff --git a/tests/common_test.go b/tests/e2e/common_test.go similarity index 100% rename from tests/common_test.go rename to tests/e2e/common_test.go diff --git a/tests/k8s_restclientgetter_test.go b/tests/e2e/k8s_restclientgetter_test.go similarity index 100% rename from tests/k8s_restclientgetter_test.go rename to tests/e2e/k8s_restclientgetter_test.go diff --git a/tests/testdata/addons/nginx.yaml b/tests/e2e/testdata/addons/nginx.yaml similarity index 100% rename from tests/testdata/addons/nginx.yaml rename to tests/e2e/testdata/addons/nginx.yaml diff --git a/tests/testdata/customcerts/client-ca.crt b/tests/e2e/testdata/customcerts/client-ca.crt similarity index 100% rename from tests/testdata/customcerts/client-ca.crt rename to tests/e2e/testdata/customcerts/client-ca.crt diff --git a/tests/testdata/customcerts/client-ca.key b/tests/e2e/testdata/customcerts/client-ca.key similarity index 100% rename from tests/testdata/customcerts/client-ca.key rename to tests/e2e/testdata/customcerts/client-ca.key diff --git a/tests/testdata/customcerts/client-ca.pem b/tests/e2e/testdata/customcerts/client-ca.pem similarity index 100% rename from tests/testdata/customcerts/client-ca.pem rename to tests/e2e/testdata/customcerts/client-ca.pem diff --git a/tests/testdata/customcerts/etcd/peer-ca.crt b/tests/e2e/testdata/customcerts/etcd/peer-ca.crt similarity index 100% rename from tests/testdata/customcerts/etcd/peer-ca.crt rename to tests/e2e/testdata/customcerts/etcd/peer-ca.crt diff --git a/tests/testdata/customcerts/etcd/peer-ca.key b/tests/e2e/testdata/customcerts/etcd/peer-ca.key similarity index 100% rename from tests/testdata/customcerts/etcd/peer-ca.key rename to tests/e2e/testdata/customcerts/etcd/peer-ca.key diff --git a/tests/testdata/customcerts/etcd/peer-ca.pem b/tests/e2e/testdata/customcerts/etcd/peer-ca.pem similarity index 100% rename from tests/testdata/customcerts/etcd/peer-ca.pem rename to tests/e2e/testdata/customcerts/etcd/peer-ca.pem diff --git a/tests/testdata/customcerts/etcd/server-ca.crt b/tests/e2e/testdata/customcerts/etcd/server-ca.crt similarity index 100% rename from tests/testdata/customcerts/etcd/server-ca.crt rename to tests/e2e/testdata/customcerts/etcd/server-ca.crt diff --git a/tests/testdata/customcerts/etcd/server-ca.key b/tests/e2e/testdata/customcerts/etcd/server-ca.key similarity index 100% rename from tests/testdata/customcerts/etcd/server-ca.key rename to tests/e2e/testdata/customcerts/etcd/server-ca.key diff --git a/tests/testdata/customcerts/etcd/server-ca.pem b/tests/e2e/testdata/customcerts/etcd/server-ca.pem similarity index 100% rename from tests/testdata/customcerts/etcd/server-ca.pem rename to tests/e2e/testdata/customcerts/etcd/server-ca.pem diff --git a/tests/testdata/customcerts/intermediate-ca.crt b/tests/e2e/testdata/customcerts/intermediate-ca.crt similarity index 100% rename from tests/testdata/customcerts/intermediate-ca.crt rename to tests/e2e/testdata/customcerts/intermediate-ca.crt diff --git a/tests/testdata/customcerts/intermediate-ca.key b/tests/e2e/testdata/customcerts/intermediate-ca.key similarity index 100% rename from tests/testdata/customcerts/intermediate-ca.key rename to tests/e2e/testdata/customcerts/intermediate-ca.key diff --git a/tests/testdata/customcerts/intermediate-ca.pem b/tests/e2e/testdata/customcerts/intermediate-ca.pem similarity index 100% rename from tests/testdata/customcerts/intermediate-ca.pem rename to tests/e2e/testdata/customcerts/intermediate-ca.pem diff --git a/tests/testdata/customcerts/request-header-ca.crt b/tests/e2e/testdata/customcerts/request-header-ca.crt similarity index 100% rename from tests/testdata/customcerts/request-header-ca.crt rename to tests/e2e/testdata/customcerts/request-header-ca.crt diff --git a/tests/testdata/customcerts/request-header-ca.key b/tests/e2e/testdata/customcerts/request-header-ca.key similarity index 100% rename from tests/testdata/customcerts/request-header-ca.key rename to tests/e2e/testdata/customcerts/request-header-ca.key diff --git a/tests/testdata/customcerts/request-header-ca.pem b/tests/e2e/testdata/customcerts/request-header-ca.pem similarity index 100% rename from tests/testdata/customcerts/request-header-ca.pem rename to tests/e2e/testdata/customcerts/request-header-ca.pem diff --git a/tests/testdata/customcerts/root-ca.crt b/tests/e2e/testdata/customcerts/root-ca.crt similarity index 100% rename from tests/testdata/customcerts/root-ca.crt rename to tests/e2e/testdata/customcerts/root-ca.crt diff --git a/tests/testdata/customcerts/root-ca.key b/tests/e2e/testdata/customcerts/root-ca.key similarity index 100% rename from tests/testdata/customcerts/root-ca.key rename to tests/e2e/testdata/customcerts/root-ca.key diff --git a/tests/testdata/customcerts/root-ca.pem b/tests/e2e/testdata/customcerts/root-ca.pem similarity index 100% rename from tests/testdata/customcerts/root-ca.pem rename to tests/e2e/testdata/customcerts/root-ca.pem diff --git a/tests/testdata/customcerts/server-ca.crt b/tests/e2e/testdata/customcerts/server-ca.crt similarity index 100% rename from tests/testdata/customcerts/server-ca.crt rename to tests/e2e/testdata/customcerts/server-ca.crt diff --git a/tests/testdata/customcerts/server-ca.key b/tests/e2e/testdata/customcerts/server-ca.key similarity index 100% rename from tests/testdata/customcerts/server-ca.key rename to tests/e2e/testdata/customcerts/server-ca.key diff --git a/tests/testdata/customcerts/server-ca.pem b/tests/e2e/testdata/customcerts/server-ca.pem similarity index 100% rename from tests/testdata/customcerts/server-ca.pem rename to tests/e2e/testdata/customcerts/server-ca.pem diff --git a/tests/testdata/customcerts/service.key b/tests/e2e/testdata/customcerts/service.key similarity index 100% rename from tests/testdata/customcerts/service.key rename to tests/e2e/testdata/customcerts/service.key diff --git a/tests/testdata/registry/certs/ca.crt b/tests/e2e/testdata/registry/certs/ca.crt similarity index 100% rename from tests/testdata/registry/certs/ca.crt rename to tests/e2e/testdata/registry/certs/ca.crt diff --git a/tests/testdata/registry/certs/ca.key b/tests/e2e/testdata/registry/certs/ca.key similarity index 100% rename from tests/testdata/registry/certs/ca.key rename to tests/e2e/testdata/registry/certs/ca.key diff --git a/tests/testdata/registry/certs/registry.crt b/tests/e2e/testdata/registry/certs/registry.crt similarity index 100% rename from tests/testdata/registry/certs/registry.crt rename to tests/e2e/testdata/registry/certs/registry.crt diff --git a/tests/testdata/registry/certs/registry.key b/tests/e2e/testdata/registry/certs/registry.key similarity index 100% rename from tests/testdata/registry/certs/registry.key rename to tests/e2e/testdata/registry/certs/registry.key diff --git a/tests/testdata/registry/config.yml b/tests/e2e/testdata/registry/config.yml similarity index 100% rename from tests/testdata/registry/config.yml rename to tests/e2e/testdata/registry/config.yml diff --git a/tests/testdata/registry/registries.yaml b/tests/e2e/testdata/registry/registries.yaml similarity index 100% rename from tests/testdata/registry/registries.yaml rename to tests/e2e/testdata/registry/registries.yaml diff --git a/tests/testdata/resources/ingress-nginx-v1.14.1.yaml b/tests/e2e/testdata/resources/ingress-nginx-v1.14.1.yaml similarity index 100% rename from tests/testdata/resources/ingress-nginx-v1.14.1.yaml rename to tests/e2e/testdata/resources/ingress-nginx-v1.14.1.yaml diff --git a/tests/tests_suite_test.go b/tests/e2e/tests_suite_test.go similarity index 100% rename from tests/tests_suite_test.go rename to tests/e2e/tests_suite_test.go diff --git a/pkg/controller/cluster/cluster_suite_test.go b/tests/integration/cluster/cluster_suite_test.go similarity index 100% rename from pkg/controller/cluster/cluster_suite_test.go rename to tests/integration/cluster/cluster_suite_test.go diff --git a/pkg/controller/cluster/cluster_test.go b/tests/integration/cluster/cluster_test.go similarity index 100% rename from pkg/controller/cluster/cluster_test.go rename to tests/integration/cluster/cluster_test.go diff --git a/k3k-kubelet/controller/syncer/configmap_test.go b/tests/integration/k3k-kubelet/configmap_test.go similarity index 100% rename from k3k-kubelet/controller/syncer/configmap_test.go rename to tests/integration/k3k-kubelet/configmap_test.go diff --git a/k3k-kubelet/controller/syncer/ingress_test.go b/tests/integration/k3k-kubelet/ingress_test.go similarity index 100% rename from k3k-kubelet/controller/syncer/ingress_test.go rename to tests/integration/k3k-kubelet/ingress_test.go diff --git a/k3k-kubelet/controller/syncer/persistentvolumeclaims_test.go b/tests/integration/k3k-kubelet/persistentvolumeclaims_test.go similarity index 100% rename from k3k-kubelet/controller/syncer/persistentvolumeclaims_test.go rename to tests/integration/k3k-kubelet/persistentvolumeclaims_test.go diff --git a/k3k-kubelet/controller/syncer/priority_class_test.go b/tests/integration/k3k-kubelet/priority_class_test.go similarity index 100% rename from k3k-kubelet/controller/syncer/priority_class_test.go rename to tests/integration/k3k-kubelet/priority_class_test.go diff --git a/k3k-kubelet/controller/syncer/secret_test.go b/tests/integration/k3k-kubelet/secret_test.go similarity index 100% rename from k3k-kubelet/controller/syncer/secret_test.go rename to tests/integration/k3k-kubelet/secret_test.go diff --git a/k3k-kubelet/controller/syncer/service_test.go b/tests/integration/k3k-kubelet/service_test.go similarity index 100% rename from k3k-kubelet/controller/syncer/service_test.go rename to tests/integration/k3k-kubelet/service_test.go diff --git a/k3k-kubelet/controller/syncer/syncer_suite_test.go b/tests/integration/k3k-kubelet/syncer_suite_test.go similarity index 100% rename from k3k-kubelet/controller/syncer/syncer_suite_test.go rename to tests/integration/k3k-kubelet/syncer_suite_test.go diff --git a/pkg/controller/policy/policy_suite_test.go b/tests/integration/policy/policy_suite_test.go similarity index 100% rename from pkg/controller/policy/policy_suite_test.go rename to tests/integration/policy/policy_suite_test.go diff --git a/pkg/controller/policy/policy_test.go b/tests/integration/policy/policy_test.go similarity index 100% rename from pkg/controller/policy/policy_test.go rename to tests/integration/policy/policy_test.go