diff --git a/Makefile b/Makefile index a1e11e7b..1b64e52a 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ KUBECONFIG = $(shell pwd)/metal/kubeconfig.yaml KUBE_CONFIG_PATH = $(KUBECONFIG) -default: metal bootstrap external wait post-install +default: metal bootstrap external smoke-test post-install configure: ./scripts/configure @@ -20,8 +20,8 @@ bootstrap: external: make -C external -wait: - ./scripts/wait-main-apps +smoke-test: + make -C test filter=Smoke post-install: @./scripts/hacks diff --git a/README.md b/README.md index fcab891e..5cf58ba3 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ More information can be found in [the roadmap](#roadmap) below. - [ ] Monitoring and alerting 🚧 - [ ] Automated offsite backups 🚧 - [ ] Single sign-on 🚧 +- [x] Infrastructure testing Some demo videos and screenshots are shown here. They can't capture all the project's features, but they are sufficient to get a concept of it. diff --git a/scripts/wait-main-apps b/scripts/wait-main-apps deleted file mode 100755 index 52fa4a03..00000000 --- a/scripts/wait-main-apps +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python - -import requests - -from kubernetes import client, config -from rich.console import Console -from time import sleep - -# Essential services -ingresses = [ - { - 'name': 'argocd-server', - 'fullname': 'ArgoCD', - 'namespace': 'argocd' - }, - { - 'name': 'hajimari', - 'fullname': 'Homepage', - 'namespace': 'hajimari' - }, - { - 'name': 'vault', - 'fullname': 'Vault', - 'namespace': 'vault' - }, - { - 'name': 'gitea', - 'fullname': 'Gitea', - 'namespace': 'gitea' - } -] - - -def wait_app(name: str, fullname: str, namespace: str) -> None: - console = Console() - success = False - - with console.status(f"Waiting for {fullname}"): - while not success: - try: - ingress = client.NetworkingV1Api().read_namespaced_ingress( - name, - namespace - ) - url = f"https://{ingress.spec.rules[0].host}" - requests.get(url, verify=False).raise_for_status() - console.log(f"{fullname} is ready, visit {url}") - success = True - except Exception: - sleep(60) - - -def main() -> None: - Console().rule("Waiting for essential applications") - config.load_kube_config(config_file='./metal/kubeconfig.yaml') - requests.urllib3.disable_warnings() - - for ingress in ingresses: - wait_app(ingress['name'], ingress['fullname'], ingress['namespace']) - - print("There's more, but you can start exploring right away!") - - -if __name__ == '__main__': - main() diff --git a/test/Makefile b/test/Makefile index aa165f9b..8ab99f91 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,6 +1,8 @@ .POSIX: +filter=. + default: test test: - gotestsum --format testname -- --timeout 30m + gotestsum --format testname -- -timeout 30m -run "${filter}" diff --git a/test/smoke_test.go b/test/smoke_test.go new file mode 100644 index 00000000..b975f458 --- /dev/null +++ b/test/smoke_test.go @@ -0,0 +1,57 @@ +package test + +import ( + "crypto/tls" + "fmt" + "testing" + "time" + + http_helper "github.com/gruntwork-io/terratest/modules/http-helper" + "github.com/gruntwork-io/terratest/modules/k8s" +) + +func TestSmoke(t *testing.T) { + t.Parallel() + + var mainApps = []struct { + name string + namespace string + }{ + {"argocd-server", "argocd"}, + {"hajimari", "hajimari"}, + {"vault", "vault"}, + {"gitea", "gitea"}, + } + + for _, app := range mainApps { + app := app // https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables + t.Run(app.name, func(t *testing.T) { + t.Parallel() + + options := k8s.NewKubectlOptions("", "", app.namespace) + + // Wait the service to become available to ensure that we can access it + k8s.WaitUntilIngressAvailable(t, options, app.name, 10, 30*time.Second) + + // Now we verify that the service will successfully boot and start serving requests + ingress := k8s.GetIngress(t, options, app.name) + + // Setup a TLS configuration, ignore the certificate because we may not use cert-manager (like the sandbox environment) + tlsConfig := tls.Config{ + InsecureSkipVerify: true, + } + + // Test the endpoint, this will only fail if we timeout waiting for the service to return a 200 response + http_helper.HttpGetWithRetryWithCustomValidation( + t, + fmt.Sprintf("https://%s", ingress.Spec.Rules[0].Host), + &tlsConfig, + 30, + 30*time.Second, + func(statusCode int, body string) bool { + return statusCode == 200 + }, + ) + }) + } +} diff --git a/test/tools_test.go b/test/tools_test.go index 72eec661..cf3ac9e5 100644 --- a/test/tools_test.go +++ b/test/tools_test.go @@ -31,9 +31,9 @@ func TestToolsVersions(t *testing.T) { for _, tool := range tools { params := version_checker.CheckVersionParams{ - BinaryPath: tool.binaryPath, + BinaryPath: tool.binaryPath, VersionConstraint: tool.versionConstraint, - WorkingDir: ".", + WorkingDir: ".", } version_checker.CheckVersion(t, params)