Skip to content

Commit 7e332ed

Browse files
committed
adapt tests and build scripts
Signed-off-by: Johannes Aubart <johannes.aubart@sap.com>
1 parent c7aff0e commit 7e332ed

10 files changed

Lines changed: 503 additions & 116 deletions

File tree

.github/workflows/main-update.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,20 @@ jobs:
173173
username: ${{ github.repository_owner }}
174174
password: ${{ secrets.GITHUB_TOKEN }}
175175

176+
- name: Set helm charts versions to release version and create commit
177+
if: ${{ env.SKIP != 'true' }}
178+
run: |
179+
python3 -u ./hack/set-charts-versions.py
180+
181+
git config user.name "${{ env.AUTHOR_NAME }}"
182+
git config user.email "${{ env.AUTHOR_EMAIL }}"
183+
184+
git add charts/
185+
git commit -m "chore: set helm charts versions to release version [skip ci]"
186+
git push origin main
187+
env:
188+
PYTHONUNBUFFERED: "1"
189+
176190
- name: Build OCM component
177191
if: ${{ env.SKIP != 'true' }}
178192
run: |
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
apiVersion: v2
2-
name: open-telemetry-collector-resource
2+
appVersion: v0.0.12-dev
33
description: A Helm chart for an OpenTelemetryCollector resource.
4+
name: open-telemetry-collector-resource
45
type: application
5-
version: 0.0.1
6-
appVersion: 0.0.1
6+
version: v0.0.12-dev

hack/build-component.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
merge_rgd_files,
2424
build_ocm_vars,
2525
run_command,
26+
set_all_charts_versions,
2627
)
2728

2829

@@ -208,6 +209,9 @@ def main():
208209
# Read version from VERSION file
209210
version = read_version_file(repo_root)
210211

212+
# Set helm chart versions to match component version
213+
set_all_charts_versions(repo_root, version)
214+
211215
# Merge ResourceGraphDefinition files
212216
# This is a workaround until the OCM controllers allow deploying directories
213217
merge_rgd_files(repo_root)

hack/common.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,3 +271,32 @@ def run_command(
271271
if e.stderr:
272272
print(f"stderr: {e.stderr}", file=sys.stderr, flush=True)
273273
raise
274+
275+
def set_chart_version(chart_path: str, version: str) -> None:
276+
"""
277+
Sets the 'version' and 'appVersion' fields in a Helm Chart.yaml file.
278+
Either the path to the Chart.yaml file directly or the directory containing it can be provided.
279+
"""
280+
if not chart_path.endswith("Chart.yaml"):
281+
chart_path = os.path.join(chart_path, "Chart.yaml")
282+
283+
with open(chart_path, "r") as f:
284+
chart = yaml.safe_load(f)
285+
286+
chart["version"] = version
287+
chart["appVersion"] = version
288+
289+
with open(chart_path, "w") as f:
290+
yaml.dump(chart, f, default_flow_style=False)
291+
292+
def set_all_charts_versions(repo_root: Path, version: str) -> None:
293+
"""
294+
Sets 'version' and 'appVersion' for all charts in the charts directory to match the given version.
295+
"""
296+
charts_dir = os.path.join(repo_root, "charts")
297+
for name in os.listdir(charts_dir):
298+
chart_path = os.path.join(charts_dir, name, "Chart.yaml")
299+
if os.path.isfile(chart_path):
300+
print(f"Setting version for '{name}' chart to {version} ...", flush=True)
301+
set_chart_version(chart_path, version)
302+

hack/set-charts-versions.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env python3
2+
3+
from common import (
4+
detect_repo_root,
5+
read_version_file,
6+
set_all_charts_versions,
7+
)
8+
9+
if __name__ == "__main__":
10+
# Detect repository root
11+
_, repo_root = detect_repo_root()
12+
13+
# Read version from VERSION file
14+
version = read_version_file(repo_root)
15+
16+
# Set helm chart versions to match component version
17+
set_all_charts_versions(repo_root, version)

test/e2e/coredns.go

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package e2e
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"regexp"
7+
"strings"
8+
"testing"
9+
"time"
10+
11+
corev1 "k8s.io/api/core/v1"
12+
"k8s.io/apimachinery/pkg/runtime/schema"
13+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
14+
15+
"github.com/openmcp-project/controller-utils/pkg/clusters"
16+
"sigs.k8s.io/controller-runtime/pkg/client"
17+
"sigs.k8s.io/e2e-framework/klient/wait"
18+
"sigs.k8s.io/e2e-framework/pkg/envconf"
19+
)
20+
21+
// This regex matches a block from the coredns Corefile that looks like this:
22+
//
23+
// kubernetes cluster.local in-addr.arpa ip6.arpa {
24+
// pods insecure
25+
// fallthrough in-addr.arpa ip6.arpa
26+
// ttl 30
27+
// }
28+
//
29+
// Actually matched are only 'kubernetes cluster.local', followed by a '{' (with optional stuff in between), followed by multiple lines of content, followed by a line with only '}' (with optional whitespace).
30+
// The capturing groups are:
31+
// - whole: the entire matched block
32+
// - space1: the whitespace before the "kubernetes" line
33+
// - space2: the whitespace before the "pods" line
34+
const corednsRegexString = `(?<whole>(?<space1>[^\S\n]*)kubernetes cluster\.local[^\{]*\{(?:\n(?<space2>\s*)\S[^\n]*)(?:\n\s*\S[^\n]*)*?\n\s*\})`
35+
36+
var corednsRegex = regexp.MustCompile(corednsRegexString)
37+
38+
// getHostname retrieves the first hostname defined in the HTTPRoute with the given name and namespace.
39+
func getHostname(ctx context.Context, t *testing.T, config *envconf.Config, name, namespace string) string {
40+
t.Helper()
41+
42+
httpRoute := &gatewayv1.HTTPRoute{}
43+
httpRoute.SetGroupVersionKind(schema.GroupVersionKind{
44+
Group: "gateway.networking.k8s.io",
45+
Version: "v1",
46+
Kind: "HTTPRoute",
47+
})
48+
httpRoute.SetName(name)
49+
httpRoute.SetNamespace(namespace)
50+
if err := config.Client().Resources().Get(ctx, name, namespace, httpRoute); err != nil {
51+
t.Fatalf("failed to get HTTPRoute '%s/%s': %v", namespace, name, err)
52+
}
53+
if len(httpRoute.Spec.Hostnames) == 0 {
54+
t.Fatalf("HTTPRoute '%s/%s' does not have any hostnames defined", namespace, name)
55+
}
56+
return string(httpRoute.Spec.Hostnames[0])
57+
}
58+
59+
// getGatewayIP retrieves the first IP address of the Gateway with the given name and namespace.
60+
func getGatewayIP(ctx context.Context, t *testing.T, config *envconf.Config, name, namespace string) string {
61+
t.Helper()
62+
63+
gateway := &gatewayv1.Gateway{}
64+
gateway.SetGroupVersionKind(schema.GroupVersionKind{
65+
Group: "gateway.networking.k8s.io",
66+
Version: "v1",
67+
Kind: "Gateway",
68+
})
69+
gateway.SetName(name)
70+
gateway.SetNamespace(namespace)
71+
if err := config.Client().Resources().Get(ctx, name, namespace, gateway); err != nil {
72+
t.Fatalf("failed to get Gateway '%s/%s': %v", namespace, name, err)
73+
}
74+
for _, addr := range gateway.Status.Addresses {
75+
if addr.Type != nil && *addr.Type == gatewayv1.IPAddressType {
76+
return addr.Value
77+
}
78+
}
79+
t.Fatalf("Gateway '%s/%s' does not have any IP addresses exposed", namespace, name)
80+
return ""
81+
}
82+
83+
// injectGatewayRoute modifies the coredns configmap to add a hosts entry for the given hostname and gateway IP, then restarts the coredns pods to apply the change.
84+
func injectGatewayRoute(ctx context.Context, t *testing.T, hostname string, gatewayIP string, access *clusters.Cluster) {
85+
t.Helper()
86+
87+
// fetch the coredns configmap
88+
cm := &corev1.ConfigMap{}
89+
cm.Name = "coredns"
90+
cm.Namespace = "kube-system"
91+
if err := access.Client().Get(ctx, client.ObjectKeyFromObject(cm), cm); err != nil {
92+
t.Fatalf("failed to get coredns configmap: %v", err)
93+
}
94+
coreData, exists := cm.Data["Corefile"]
95+
if !exists {
96+
t.Fatalf("coredns configmap does not contain Corefile")
97+
}
98+
99+
match := corednsRegex.FindStringSubmatch(coreData)
100+
if match == nil {
101+
t.Fatalf("failed to find kubernetes block in coredns Corefile using regex: %s", corednsRegexString)
102+
}
103+
fullMatch := match[corednsRegex.SubexpIndex("whole")]
104+
outerIndent := match[corednsRegex.SubexpIndex("space1")]
105+
innerIndent := match[corednsRegex.SubexpIndex("space2")]
106+
107+
replacement := fmt.Sprintf("%s\n%shosts {\n%s%s %s\n%sfallthrough\n%s}", fullMatch, outerIndent, innerIndent, gatewayIP, hostname, innerIndent, outerIndent)
108+
coreData = strings.Replace(coreData, fullMatch, replacement, 1)
109+
cm.Data["Corefile"] = coreData
110+
if err := access.Client().Update(ctx, cm); err != nil {
111+
t.Fatalf("failed to update coredns configmap: %v", err)
112+
}
113+
114+
// kill the coredns pods to force them to reload the configmap
115+
if err := access.Client().DeleteAllOf(ctx, &corev1.Pod{}, client.InNamespace("kube-system"), client.MatchingLabels{"k8s-app": "kube-dns"}); err != nil {
116+
t.Fatalf("failed to delete coredns pods: %v", err)
117+
}
118+
119+
// wait for the coredns pods to be ready again
120+
if err := wait.For(func(ctx context.Context) (done bool, err error) {
121+
podList := &corev1.PodList{}
122+
if err := access.Client().List(ctx, podList, client.InNamespace("kube-system"), client.MatchingLabels{"k8s-app": "kube-dns"}); err != nil {
123+
return false, fmt.Errorf("failed to list coredns pods: %v", err)
124+
}
125+
for _, pod := range podList.Items {
126+
if pod.Status.Phase != corev1.PodRunning {
127+
return false, nil
128+
}
129+
for _, cond := range pod.Status.Conditions {
130+
if cond.Type == corev1.PodReady && cond.Status != corev1.ConditionTrue {
131+
return false, nil
132+
}
133+
}
134+
}
135+
return true, nil
136+
}, wait.WithTimeout(2*time.Minute)); err != nil {
137+
t.Fatalf("coredns pods did not become ready after configmap update: %v", err)
138+
}
139+
}

test/e2e/go.mod

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/openmcp-project/observability-stack
22

3-
go 1.26.1
3+
go 1.26.2
44

55
require (
66
github.com/kubernetes-sigs/kro v0.9.2
@@ -17,6 +17,16 @@ require (
1717
sigs.k8s.io/yaml v1.6.0
1818
)
1919

20+
require (
21+
github.com/fsnotify/fsnotify v1.10.1 // indirect
22+
github.com/go-logr/zapr v1.3.0 // indirect
23+
github.com/openmcp-project/openmcp-operator/lib v0.20.0 // indirect
24+
go.uber.org/multierr v1.11.0 // indirect
25+
go.uber.org/zap v1.28.0 // indirect
26+
golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a // indirect
27+
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
28+
)
29+
2030
require (
2131
al.essio.dev/pkg/shellescape v1.5.1 // indirect
2232
dario.cat/mergo v1.0.1 // indirect
@@ -46,32 +56,32 @@ require (
4656
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
4757
github.com/fatih/color v1.18.0 // indirect
4858
github.com/fluxcd/flux2/v2 v2.8.3 // indirect
49-
github.com/fluxcd/helm-controller/api v1.5.3 // indirect
59+
github.com/fluxcd/helm-controller/api v1.5.4 // indirect
5060
github.com/fluxcd/kustomize-controller/api v1.8.2 // indirect
5161
github.com/fluxcd/pkg/apis/acl v0.9.0 // indirect
52-
github.com/fluxcd/pkg/apis/kustomize v1.15.1 // indirect
62+
github.com/fluxcd/pkg/apis/kustomize v1.18.0 // indirect
5363
github.com/fluxcd/pkg/apis/meta v1.25.1 // indirect
5464
github.com/fluxcd/pkg/kustomize v1.27.1 // indirect
5565
github.com/fluxcd/pkg/tar v0.17.0 // indirect
56-
github.com/fluxcd/source-controller/api v1.8.1 // indirect
57-
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
66+
github.com/fluxcd/source-controller/api v1.8.3 // indirect
67+
github.com/fxamacker/cbor/v2 v2.9.2 // indirect
5868
github.com/go-errors/errors v1.5.1 // indirect
5969
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
6070
github.com/go-logr/logr v1.4.3 // indirect
61-
github.com/go-openapi/jsonpointer v0.22.5 // indirect
71+
github.com/go-openapi/jsonpointer v0.23.1 // indirect
6272
github.com/go-openapi/jsonreference v0.21.5 // indirect
63-
github.com/go-openapi/swag v0.25.5 // indirect
64-
github.com/go-openapi/swag/cmdutils v0.25.5 // indirect
65-
github.com/go-openapi/swag/conv v0.25.5 // indirect
66-
github.com/go-openapi/swag/fileutils v0.25.5 // indirect
67-
github.com/go-openapi/swag/jsonname v0.25.5 // indirect
68-
github.com/go-openapi/swag/jsonutils v0.25.5 // indirect
69-
github.com/go-openapi/swag/loading v0.25.5 // indirect
70-
github.com/go-openapi/swag/mangling v0.25.5 // indirect
71-
github.com/go-openapi/swag/netutils v0.25.5 // indirect
72-
github.com/go-openapi/swag/stringutils v0.25.5 // indirect
73-
github.com/go-openapi/swag/typeutils v0.25.5 // indirect
74-
github.com/go-openapi/swag/yamlutils v0.25.5 // indirect
73+
github.com/go-openapi/swag v0.26.0 // indirect
74+
github.com/go-openapi/swag/cmdutils v0.26.0 // indirect
75+
github.com/go-openapi/swag/conv v0.26.0 // indirect
76+
github.com/go-openapi/swag/fileutils v0.26.0 // indirect
77+
github.com/go-openapi/swag/jsonname v0.26.0 // indirect
78+
github.com/go-openapi/swag/jsonutils v0.26.0 // indirect
79+
github.com/go-openapi/swag/loading v0.26.0 // indirect
80+
github.com/go-openapi/swag/mangling v0.26.0 // indirect
81+
github.com/go-openapi/swag/netutils v0.26.0 // indirect
82+
github.com/go-openapi/swag/stringutils v0.26.0 // indirect
83+
github.com/go-openapi/swag/typeutils v0.26.0 // indirect
84+
github.com/go-openapi/swag/yamlutils v0.26.0 // indirect
7585
github.com/gobwas/glob v0.2.3 // indirect
7686
github.com/google/btree v1.1.3 // indirect
7787
github.com/google/gnostic-models v0.7.1 // indirect
@@ -104,7 +114,9 @@ require (
104114
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
105115
github.com/opencontainers/go-digest v1.0.0 // indirect
106116
github.com/opencontainers/image-spec v1.1.1 // indirect
107-
github.com/openmcp-project/openmcp-operator/api v0.18.1 // indirect
117+
github.com/openmcp-project/controller-utils v0.29.0
118+
github.com/openmcp-project/opencontrolplane-runtime v0.2.1
119+
github.com/openmcp-project/openmcp-operator/api v0.20.0
108120
github.com/pelletier/go-toml v1.9.5 // indirect
109121
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
110122
github.com/pkg/errors v0.9.1 // indirect
@@ -127,36 +139,37 @@ require (
127139
go.opentelemetry.io/otel/trace v1.43.0 // indirect
128140
go.yaml.in/yaml/v2 v2.4.4 // indirect
129141
go.yaml.in/yaml/v3 v3.0.4 // indirect
130-
golang.org/x/crypto v0.49.0 // indirect
131-
golang.org/x/net v0.52.0 // indirect
142+
golang.org/x/crypto v0.51.0 // indirect
143+
golang.org/x/net v0.54.0 // indirect
132144
golang.org/x/oauth2 v0.36.0 // indirect
133145
golang.org/x/sync v0.20.0 // indirect
134-
golang.org/x/sys v0.42.0 // indirect
135-
golang.org/x/term v0.41.0 // indirect
136-
golang.org/x/text v0.35.0 // indirect
146+
golang.org/x/sys v0.44.0 // indirect
147+
golang.org/x/term v0.43.0 // indirect
148+
golang.org/x/text v0.37.0 // indirect
137149
golang.org/x/time v0.15.0 // indirect
138150
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d // indirect
139151
google.golang.org/grpc v1.80.0 // indirect
140152
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
141153
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
142154
gopkg.in/inf.v0 v0.9.1 // indirect
143155
gopkg.in/yaml.v3 v3.0.1 // indirect
144-
k8s.io/apiextensions-apiserver v0.36.0 // indirect
145-
k8s.io/apiserver v0.36.0 // indirect
156+
k8s.io/apiextensions-apiserver v0.36.1 // indirect
157+
k8s.io/apiserver v0.36.1 // indirect
146158
k8s.io/cli-runtime v0.36.0 // indirect
147-
k8s.io/component-base v0.36.0 // indirect
148-
k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect
159+
k8s.io/component-base v0.36.1 // indirect
160+
k8s.io/kube-openapi v0.0.0-20260512234627-ef417d054102 // indirect
149161
k8s.io/kubectl v0.36.0 // indirect
150162
k8s.io/streaming v0.36.1 // indirect
151-
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect
163+
k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 // indirect
152164
ocm.software/open-component-model/bindings/go/descriptor/v2 v2.0.1-alpha9 // indirect
153165
ocm.software/open-component-model/bindings/go/runtime v0.0.7 // indirect
154166
oras.land/oras-go/v2 v2.6.0 // indirect
155-
sigs.k8s.io/controller-runtime v0.23.3 // indirect
167+
sigs.k8s.io/controller-runtime v0.24.1
168+
sigs.k8s.io/gateway-api v1.5.1
156169
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
157170
sigs.k8s.io/kind v0.31.0 // indirect
158171
sigs.k8s.io/kustomize/api v0.21.1 // indirect
159172
sigs.k8s.io/kustomize/kyaml v0.21.1 // indirect
160173
sigs.k8s.io/randfill v1.0.0 // indirect
161-
sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect
174+
sigs.k8s.io/structured-merge-diff/v6 v6.4.0 // indirect
162175
)

0 commit comments

Comments
 (0)