-
Notifications
You must be signed in to change notification settings - Fork 357
test: Port tests to XKS #1268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
test: Port tests to XKS #1268
Changes from all commits
db7c3b2
b356499
ec8e3f1
27d113e
17f6bc7
8000c73
fc42e83
75fc84e
d882362
0871361
3e83c7d
835929d
26d6d71
7a84c66
ec6b12f
614e7bc
6c516cb
8cbb00a
fba7758
1d7b019
b6a4f8e
f143bb0
5df9508
6a996ab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| apiVersion: argoproj.io/v1alpha1 | ||
| apiVersion: argoproj.io/v1beta1 | ||
| kind: ArgoCD | ||
| metadata: | ||
| name: argocd | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,10 @@ | ||
| package argocd | ||
|
|
||
| import ( | ||
| "bufio" | ||
| "context" | ||
| "fmt" | ||
| "io" | ||
| "os/exec" | ||
| "strings" | ||
| "time" | ||
|
|
@@ -46,6 +48,20 @@ func Update(obj *argov1beta1api.ArgoCD, modify func(*argov1beta1api.ArgoCD)) { | |
| time.Sleep(7 * time.Second) | ||
| } | ||
|
|
||
| // CreateNewArgoCDInstance creates a new ArgoCD instance with an empty (zero) spec in the | ||
| // given namespace and returns it. Callers should wait for availability via BeAvailable. | ||
| func CreateNewArgoCDInstance(name, namespace string) *argov1beta1api.ArgoCD { | ||
| k8sClient, _ := utils.GetE2ETestKubeClient() | ||
|
|
||
| argoCD := &argov1beta1api.ArgoCD{ | ||
| ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: namespace}, | ||
| Spec: argov1beta1api.ArgoCDSpec{}, | ||
| } | ||
| Expect(k8sClient.Create(context.Background(), argoCD)).To(Succeed()) | ||
|
|
||
| return argoCD | ||
| } | ||
|
|
||
| func GetOpenShiftGitOpsNSArgoCD() (*argov1beta1api.ArgoCD, error) { | ||
|
|
||
| k8sClient, _ := utils.GetE2ETestKubeClient() | ||
|
|
@@ -303,7 +319,96 @@ func LogInToDefaultArgoCDInstance() error { | |
|
|
||
| } | ||
|
|
||
| // NOTE: this should only be called from sequential tests. If you call it from a parallel test, there is a risk that another test will login to a different Argo CD instance. | ||
| // port-forward instead of an OpenShift Route, so it works on xks clusters. | ||
| // instanceName is the ArgoCD CR name (e.g. "openshift-gitops"); namespace is its namespace. | ||
| // The returned cancel func stops the port-forward; call it (or defer it) after all argocd | ||
| // CLI calls in the test are done, since the CLI stores localhost:18080 as the server address. | ||
| func LogInToArgoCDInstanceWithoutRoute(instanceName, namespace string) (func(), error) { | ||
| k8sClient, _, err := utils.GetE2ETestKubeClientWithError() | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| secretName := instanceName + "-cluster" | ||
| secret := &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: secretName, Namespace: namespace}} | ||
| if err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(secret), secret); err != nil { | ||
| return nil, fmt.Errorf("unable to locate %q Secret", secretName) | ||
| } | ||
|
|
||
| const localPort = "18080" | ||
| cancel := portForwardArgoCD(namespace, "svc/"+instanceName+"-server", localPort+":80") | ||
|
|
||
| output, err := RunArgoCDCLI("login", "localhost:"+localPort, "--username", "admin", | ||
| "--password", string(secret.Data["admin.password"]), "--insecure") | ||
| if err != nil { | ||
| cancel() | ||
| return nil, err | ||
| } | ||
|
|
||
| if !strings.Contains(output, "'admin:login' logged in successfully") { | ||
| cancel() | ||
| return nil, fmt.Errorf("unable to log in to ArgoCD instance %q in namespace %q", instanceName, namespace) | ||
| } | ||
|
|
||
| return cancel, nil | ||
| } | ||
|
|
||
| // portForwardArgoCD starts kubectl port-forward and returns a cancel func. | ||
| // Blocks until the tunnel is ready (or Fail()s after 60s). | ||
| func portForwardArgoCD(namespace, subject, port string) func() { | ||
| // Kill any stale process on the local port left by a previous crashed run. | ||
| localPort := strings.SplitN(port, ":", 2)[0] | ||
| // #nosec G204 | ||
| _ = exec.Command("sh", "-c", "lsof -ti :"+localPort+" | xargs kill -9 2>/dev/null; fuser -k "+localPort+"/tcp 2>/dev/null; true").Run() | ||
|
|
||
| cmd := exec.Command("kubectl", "port-forward", "-n", namespace, subject, port) // #nosec G204 | ||
|
|
||
| stdout, err := cmd.StdoutPipe() | ||
| Expect(err).ToNot(HaveOccurred()) | ||
| stderr, err := cmd.StderrPipe() | ||
| Expect(err).ToNot(HaveOccurred()) | ||
|
|
||
| ready := make(chan struct{}) | ||
|
|
||
| stream := func(r io.Reader, signal func()) { | ||
| defer GinkgoRecover() | ||
| sc := bufio.NewScanner(r) | ||
| for sc.Scan() { | ||
| line := sc.Text() | ||
| GinkgoWriter.Println("port-forward:", line) | ||
| if signal != nil && strings.HasPrefix(line, "Forwarding from") { | ||
| signal() | ||
| signal = nil | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Expect(cmd.Start()).To(Succeed()) | ||
| go stream(stdout, func() { close(ready) }) | ||
| go stream(stderr, nil) | ||
| go func() { | ||
| defer GinkgoRecover() | ||
| if waitErr := cmd.Wait(); waitErr != nil && | ||
| !strings.Contains(waitErr.Error(), "killed") && | ||
| !strings.Contains(waitErr.Error(), "signal: killed") { | ||
| GinkgoWriter.Println("port-forward exited:", waitErr) | ||
| } | ||
| }() | ||
|
|
||
| select { | ||
| case <-ready: | ||
| case <-time.After(60 * time.Second): | ||
| Fail("timed out waiting for port-forward to be ready") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -eu
file="test/openshift/e2e/ginkgo/fixture/argocd/fixture.go"
printf '%s\n' '--- target function and nearby definitions ---'
cat -n "$file" | sed -n '330,430p'
printf '%s\n' '--- references to portForwardArgoCD and LogInToArgoCDInstanceWithoutRoute ---'
rg -n -C 3 'portForwardArgoCD|LogInToArgoCDInstanceWithoutRoute' test/openshift/e2e/ginkgoRepository: redhat-developer/gitops-operator Length of output: 8669 🏁 Script executed: cat -n test/openshift/e2e/ginkgo/fixture/argocd/fixture.go | sed -n '360,420p'
rg -n -C 4 'portForwardArgoCD|LogInToArgoCDInstanceWithoutRoute' test/openshift/e2e/ginkgoRepository: redhat-developer/gitops-operator Length of output: 8242 Terminate The timeout branch in Proposed fix case <-time.After(60 * time.Second):
+ if cmd.Process != nil {
+ _ = cmd.Process.Kill()
+ }
Fail("timed out waiting for port-forward to be ready")🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| return func() { | ||
| if cmd.Process != nil { | ||
| _ = cmd.Process.Kill() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // LogInToArgoCDInstanceWithoutRoute logs in to an ArgoCD instance via kubectl | ||
| func RunArgoCDCLI(args ...string) (string, error) { | ||
|
|
||
| cmdArgs := append([]string{"argocd"}, args...) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.