Files
deploy/test/e2e/managed_by_url_test.go
zeekayandHanzo Dev 1ab6e799c1 cd: the module is github.com/hanzoai/cd, where it is actually hosted
go.mod still declared `module github.com/hanzoai/deploy` after the repo was
renamed. A Go module path is not cosmetic — it is the resolvable location. So
`go get github.com/hanzoai/cd` could not work, and anything importing this
module had to spell a name that no longer exists at that address. The build log
of v3.6.0 is where it surfaced: the compiler was still emitting
github.com/hanzoai/deploy/cmd/cd/commands.

3541 import paths across 690 .go, 19 .proto, 4 .yaml, 3 .sh, 2 .mod, Procfile
and Makefile. Plus the 62 ghcr.io/hanzoai/deploy image references, moved to
ghcr.io/hanzoai/cd to match hanzo.yml's build target — a distinct string from
the module path, replaced separately so neither could clobber the other.

go mod tidy clean, CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ./... clean.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 21:16:24 -07:00

208 lines
7.4 KiB
Go

package e2e
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/hanzoai/cd/pkg/apiclient/application"
"github.com/hanzoai/cd/pkg/apiclient/settings"
. "github.com/hanzoai/cd/pkg/apis/application/v1alpha1"
"github.com/hanzoai/cd/test/e2e/fixture"
. "github.com/hanzoai/cd/test/e2e/fixture/app"
)
const managedByURLTestPath = "guestbook"
// TestManagedByURLWithAnnotation tests that applications with managed-by-url annotation
// include the managed-by-url in their deep links
func TestManagedByURLWithAnnotation(t *testing.T) {
managedByURL := "https://cd-instance-b.example.com"
ctx := Given(t)
ctx.
Project("default").
Path(managedByURLTestPath).
When().
CreateApp().
And(func() {
// Add managed-by-url annotation to the application with retry logic
for i := range 3 {
appObj, err := fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.ArgoCDNamespace).Get(t.Context(), ctx.GetName(), metav1.GetOptions{})
require.NoError(t, err)
if appObj.Annotations == nil {
appObj.Annotations = make(map[string]string)
}
appObj.Annotations[AnnotationKeyManagedByURL] = managedByURL
_, err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.ArgoCDNamespace).Update(t.Context(), appObj, metav1.UpdateOptions{})
if err == nil {
break
}
if i == 2 {
require.NoError(t, err)
}
time.Sleep(100 * time.Millisecond)
}
}).
And(func() {
// Configure deep links that use the managed-by-url template variable
deepLinksConfig := `- url: "{{.managedByURL}}/applications/{{.app.metadata.name}}"
title: "Managed By Instance"
description: "Open in managing ArgoCD instance"`
// Update the cd-cm configmap to include our test deep links and URL
configMap, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.ArgoCDNamespace).Get(t.Context(), "cd-cm", metav1.GetOptions{})
require.NoError(t, err)
if configMap.Data == nil {
configMap.Data = make(map[string]string)
}
configMap.Data["application.links"] = deepLinksConfig
configMap.Data["url"] = "https://cd-test.example.com"
_, err = fixture.KubeClientset.CoreV1().ConfigMaps(fixture.ArgoCDNamespace).Update(t.Context(), configMap, metav1.UpdateOptions{})
require.NoError(t, err)
// Wait a moment for the config to be picked up
time.Sleep(2 * time.Second)
}).
Then().
And(func(app *Application) {
// Test that the managed-by-url annotation is preserved
assert.Equal(t, managedByURL, app.Annotations[AnnotationKeyManagedByURL])
// Test that the application links include the managed-by-url in the deep links
conn, appClient, err := fixture.ArgoCDClientset.NewApplicationClient()
require.NoError(t, err)
defer conn.Close()
links, err := appClient.ListLinks(t.Context(), &application.ListAppLinksRequest{
Name: new(app.Name),
})
require.NoError(t, err)
// Verify that deep links are generated with the managed-by-url
assert.NotNil(t, links)
assert.Len(t, links.Items, 1, "Should have 1 deep link configured")
// Check that the link uses the managed-by-url
expectedLink := managedByURL + "/applications/" + app.Name
found := false
for _, link := range links.Items {
if link.Url != nil && *link.Url == expectedLink {
found = true
assert.Equal(t, "Managed By Instance", *link.Title)
assert.Equal(t, "Open in managing ArgoCD instance", *link.Description)
break
}
}
assert.True(t, found, "Deep link should use managed-by-url: %s", expectedLink)
}).
And(func(_ *Application) {
// Clean up: remove the test deep links configuration
configMap, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.ArgoCDNamespace).Get(t.Context(), "cd-cm", metav1.GetOptions{})
if err == nil && configMap.Data != nil {
delete(configMap.Data, "application.links")
delete(configMap.Data, "url")
_, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.ArgoCDNamespace).Update(t.Context(), configMap, metav1.UpdateOptions{})
if err != nil {
t.Logf("Failed to clean up configmap: %v", err)
}
}
})
}
// TestManagedByURLFallbackToCurrentInstance tests that when no managed-by-url is set,
// the current instance URL is used as fallback
func TestManagedByURLFallbackToCurrentInstance(t *testing.T) {
Given(t).
Project("default").
Path(managedByURLTestPath).
When().
CreateApp().
And(func() {
// Configure deep links that use the managed-by-url template variable
deepLinksConfig := `- url: "{{.managedByURL}}/applications/{{.app.metadata.name}}"
title: "Managed By Instance"
description: "Open in managing ArgoCD instance"`
// Update the cd-cm configmap to include our test deep links and URL
configMap, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.ArgoCDNamespace).Get(t.Context(), "cd-cm", metav1.GetOptions{})
require.NoError(t, err)
if configMap.Data == nil {
configMap.Data = make(map[string]string)
}
configMap.Data["application.links"] = deepLinksConfig
configMap.Data["url"] = "https://cd-test.example.com"
_, err = fixture.KubeClientset.CoreV1().ConfigMaps(fixture.ArgoCDNamespace).Update(t.Context(), configMap, metav1.UpdateOptions{})
require.NoError(t, err)
// Wait a moment for the config to be picked up
time.Sleep(2 * time.Second)
}).
Then().
And(func(app *Application) {
// Test that the application links use the current instance URL as fallback
conn, appClient, err := fixture.ArgoCDClientset.NewApplicationClient()
require.NoError(t, err)
defer conn.Close()
links, err := appClient.ListLinks(t.Context(), &application.ListAppLinksRequest{
Name: new(app.Name),
})
require.NoError(t, err)
// Verify that deep links are generated with the current instance URL as fallback
assert.NotNil(t, links)
assert.Len(t, links.Items, 1, "Should have 1 deep link configured")
// Get the current ArgoCD server URL from settings
conn2, settingsClient, err := fixture.ArgoCDClientset.NewSettingsClient()
require.NoError(t, err)
defer conn2.Close()
settings, err := settingsClient.Get(t.Context(), &settings.SettingsQuery{})
require.NoError(t, err)
// Check that the link uses the current instance URL as fallback
expectedLink := settings.URL + "/applications/" + app.Name
found := false
for _, link := range links.Items {
if link.Url != nil && *link.Url == expectedLink {
found = true
assert.Equal(t, "Managed By Instance", *link.Title)
assert.Equal(t, "Open in managing ArgoCD instance", *link.Description)
break
}
}
if !found {
t.Log("Returned links:")
for _, link := range links.Items {
if link.Url != nil {
t.Logf("- %s", *link.Url)
}
}
}
assert.True(t, found, "Deep link should use current instance URL as fallback: %s", expectedLink)
}).
And(func(_ *Application) {
// Clean up: remove the test deep links configuration
configMap, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.ArgoCDNamespace).Get(t.Context(), "cd-cm", metav1.GetOptions{})
if err == nil && configMap.Data != nil {
delete(configMap.Data, "application.links")
delete(configMap.Data, "url")
_, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.ArgoCDNamespace).Update(t.Context(), configMap, metav1.UpdateOptions{})
if err != nil {
t.Logf("Failed to clean up configmap: %v", err)
}
}
})
}