Skip to content

Commit edc936c

Browse files
Add GitHub action for E2E
Signed-off-by: Carlos Eduardo Arango Gutierrez <[email protected]> mergable commit Signed-off-by: Carlos Eduardo Arango Gutierrez <[email protected]>
1 parent 0c5eacb commit edc936c

File tree

9 files changed

+182
-110
lines changed

9 files changed

+182
-110
lines changed

.github/workflows/ci.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,13 @@ jobs:
3131
secrets: inherit
3232
with:
3333
version: ${{ needs.basic.outputs.version }}
34+
35+
e2e-test:
36+
needs:
37+
- image
38+
- basic
39+
secrets: inherit
40+
uses: ./.github/workflows/e2e.yaml
41+
with:
42+
version: ${{ needs.basic.outputs.version }}
43+
golang_version: ${{ needs.basic.outputs.golang_version }}

.github/workflows/e2e.yaml

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Copyright 2025 NVIDIA CORPORATION
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: End-to-end Tests
16+
17+
on:
18+
workflow_call:
19+
inputs:
20+
version:
21+
required: true
22+
type: string
23+
golang_version:
24+
required: true
25+
type: string
26+
secrets:
27+
AWS_ACCESS_KEY_ID:
28+
required: true
29+
AWS_SECRET_ACCESS_KEY:
30+
required: true
31+
AWS_SSH_KEY:
32+
required: true
33+
SLACK_BOT_TOKEN:
34+
required: true
35+
SLACK_CHANNEL_ID:
36+
required: true
37+
38+
jobs:
39+
e2e-tests:
40+
runs-on: linux-amd64-cpu4
41+
steps:
42+
- name: Check out code
43+
uses: actions/checkout@v4
44+
45+
- name: Install Go
46+
uses: actions/setup-go@v5
47+
with:
48+
go-version: ${{ inputs.golang_version }}
49+
50+
- name: Set up Holodeck
51+
uses: NVIDIA/[email protected]
52+
with:
53+
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }}
54+
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
55+
aws_ssh_key: ${{ secrets.AWS_SSH_KEY }}
56+
holodeck_config: "tests/e2e/infra/holodeck.yaml"
57+
58+
- name: Run e2e tests
59+
env:
60+
KUBECONFIG: ${{ github.workspace }}/kubeconfig
61+
HELM_CHART: ${{ github.workspace }}/deployments/helm/nvidia-dra-driver-gpu
62+
E2E_IMAGE_REPO: ghcr.io/nvidia/k8s-dra-driver-gpu
63+
E2E_IMAGE_TAG: ${{ inputs.version }}-ubi9
64+
E2E_IMAGE_PULL_POLICY: IfNotPresent
65+
LOG_ARTIFACTS_DIR: ${{ github.workspace }}/e2e_logs
66+
run: |
67+
make -f tests/e2e/Makefile test-e2e
68+
69+
- name: Archive test logs
70+
if: ${{ failure() }}
71+
uses: actions/upload-artifact@v4
72+
with:
73+
name: e2e-test-logs
74+
path: ./e2e_logs/
75+
retention-days: 15
76+
77+
- name: Archive Ginkgo logs
78+
uses: actions/upload-artifact@v4
79+
with:
80+
name: ginkgo-logs
81+
path: ginkgo.json
82+
retention-days: 15
83+
84+
- name: Post text to a Slack channel
85+
if: ${{ failure() }}
86+
uses: slackapi/[email protected]
87+
env:
88+
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
89+
SUMMARY_URL: https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}
90+
with:
91+
method: chat.postMessage
92+
token: ${{ secrets.SLACK_BOT_TOKEN }}
93+
payload: |
94+
channel: ${{ secrets.SLACK_CHANNEL_ID }}
95+
text: ":x: On repository ${{ github.repository }} the Workflow *${{ github.workflow }}* has failed.
96+
97+
Details: ${{ env.SUMMARY_URL }}"

.github/workflows/image.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,22 @@ jobs:
2828
steps:
2929
- uses: actions/checkout@v4
3030
name: Check out code
31+
3132
- name: Set up QEMU
3233
uses: docker/setup-qemu-action@v3
3334
with:
3435
image: tonistiigi/binfmt:qemu-v7.0.0-28
36+
3537
- name: Set up Docker Buildx
3638
uses: docker/setup-buildx-action@v3
39+
3740
- name: Login to GitHub Container Registry
3841
uses: docker/login-action@v3
3942
with:
4043
registry: ghcr.io
4144
username: ${{ github.actor }}
4245
password: ${{ secrets.GITHUB_TOKEN }}
46+
4347
- name: Build image
4448
env:
4549
IMAGE_NAME: ghcr.io/nvidia/k8s-dra-driver-gpu

Makefile

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ CMDS := $(patsubst ./cmd/%/,%,$(sort $(dir $(wildcard ./cmd/*/))))
3131
CMD_TARGETS := $(patsubst %,cmd-%, $(CMDS))
3232

3333
CHECK_TARGETS := golangci-lint check-generate
34-
MAKE_TARGETS := binaries build build-image check fmt lint-internal test examples cmds coverage generate vendor check-modules $(CHECK_TARGETS) ginkgo
34+
MAKE_TARGETS := binaries build build-image check fmt lint-internal test examples cmds coverage generate vendor check-modules $(CHECK_TARGETS)
3535

3636
TARGETS := $(MAKE_TARGETS) $(CMD_TARGETS)
3737

@@ -47,8 +47,6 @@ CLI_VERSION = $(VERSION)
4747
endif
4848
CLI_VERSION_PACKAGE = $(MODULE)/internal/info
4949

50-
GINKGO_ARGS ?=
51-
5250
binaries: cmds
5351
ifneq ($(PREFIX),)
5452
cmd-%: COMMAND_BUILD_OPTIONS = -o $(PREFIX)/$(*)
@@ -93,13 +91,6 @@ vendor:
9391
check-modules: vendor
9492
git diff --quiet HEAD -- go.mod go.sum vendor
9593

96-
ginkgo: $(CURDIR)/bin/ginkgo
97-
mkdir -p $(CURDIR)/bin
98-
GOBIN=$(CURDIR)/bin go install github.com/onsi/ginkgo/v2/ginkgo@latest
99-
100-
e2e-test: ginkgo
101-
./bin/ginkgo $(GINKGO_ARGS) -v --json-report ginkgo.json ./tests/e2e/...
102-
10394
COVERAGE_FILE := coverage.out
10495
test: build cmds
10596
go test -race -cover -v -coverprofile=$(COVERAGE_FILE) $(MODULE)/...

hack/e2e-test.sh

Lines changed: 0 additions & 43 deletions
This file was deleted.

tests/e2e/Makefile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
.PHONY: test-e2e ginkgo
15+
16+
GINKGO_ARGS ?=
17+
LOG_ARTIFACTS_DIR ?= $(CURDIR)/e2e_logs
18+
19+
ginkgo:
20+
mkdir -p $(CURDIR)/bin
21+
GOBIN=$(CURDIR)/bin go install github.com/onsi/ginkgo/v2/ginkgo@latest
22+
23+
test-e2e: ginkgo
24+
$(CURDIR)/bin/ginkgo $(GINKGO_ARGS) -v --json-report $(CURDIR)/ginkgo.json ./tests/e2e/...

tests/e2e/cleanup_test.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ func cleanupCRDs() {
5454
crds := []string{
5555
"computedomains.resource.nvidia.com",
5656
}
57-
if EnableGFD {
58-
crds = append(crds, "nodefeatures.nfd.k8s-sigs.io", "nodefeaturerules.nfd.k8s-sigs.io")
59-
}
6057

6158
for _, crd := range crds {
6259
err := extClient.ApiextensionsV1().CustomResourceDefinitions().Delete(ctx, crd, metav1.DeleteOptions{})
@@ -252,13 +249,10 @@ func cleanupNodeLabels() error {
252249
changed = true
253250
}
254251

255-
// Conditionally remove additional labels if EnableGFD is true.
256-
if EnableGFD {
257-
for key := range node.Labels {
258-
if strings.HasPrefix(key, "feature.node.kubernetes.io/") || strings.HasPrefix(key, "nvidia.com/") {
259-
delete(node.Labels, key)
260-
changed = true
261-
}
252+
for key := range node.Labels {
253+
if strings.HasPrefix(key, "nvidia.com/") {
254+
delete(node.Labels, key)
255+
changed = true
262256
}
263257
}
264258

tests/e2e/e2e_test.go

Lines changed: 27 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package e2e
1919

2020
import (
2121
"context"
22+
"encoding/json"
2223
"fmt"
2324
"log"
2425
"os"
@@ -30,7 +31,6 @@ import (
3031

3132
v1beta1 "github.com/NVIDIA/k8s-dra-driver-gpu/pkg/nvidia.com/clientset/versioned"
3233
"github.com/NVIDIA/k8s-test-infra/pkg/diagnostics"
33-
"helm.sh/helm/v3/pkg/repo"
3434

3535
. "github.com/onsi/ginkgo/v2"
3636
. "github.com/onsi/gomega"
@@ -41,6 +41,7 @@ import (
4141
extclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
4242
apierrors "k8s.io/apimachinery/pkg/api/errors"
4343
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
44+
"k8s.io/apimachinery/pkg/types"
4445
"k8s.io/apimachinery/pkg/util/rand"
4546
"k8s.io/apimachinery/pkg/util/wait"
4647
clientset "k8s.io/client-go/kubernetes"
@@ -76,7 +77,6 @@ var (
7677
resourceClient *v1beta1.Clientset
7778

7879
testNamespace *corev1.Namespace // Every test has at least one namespace unless creation is skipped
79-
EnableGFD bool
8080

8181
// Helm
8282
helmClient helm.Client
@@ -134,8 +134,8 @@ var _ = BeforeSuite(func() {
134134
helmReleaseName = "nvidia-dra-driver-gpu-e2e-test" + rand.String(5)
135135
getHelmClient()
136136

137-
// Deploy GFD + NFD
138-
deployDependencies(ctx)
137+
// Label the nodes with nvidia.com/gpu.present=true
138+
setNodeLabels(ctx)
139139

140140
// Set Helm values options
141141
setHelmValuesOptions()
@@ -214,7 +214,7 @@ func getTestEnv() {
214214
HelmChart = os.Getenv("HELM_CHART")
215215
Expect(HelmChart).NotTo(BeEmpty(), "HELM_CHART must be set")
216216

217-
LogArtifactDir = os.Getenv("LOG_ARTIFACT_DIR")
217+
LogArtifactDir = os.Getenv("LOG_ARTIFACTS_DIR")
218218

219219
ImageRepo = os.Getenv("E2E_IMAGE_REPO")
220220
Expect(ImageRepo).NotTo(BeEmpty(), "IMAGE_REPO must be set")
@@ -223,13 +223,9 @@ func getTestEnv() {
223223
Expect(ImageTag).NotTo(BeEmpty(), "IMAGE_TAG must be set")
224224

225225
ImagePullPolicy = os.Getenv("E2E_IMAGE_PULL_POLICY")
226-
Expect(ImagePullPolicy).NotTo(BeEmpty(), "IMAGE_PULL_POLICY must be set")
227-
228-
EnableGFD = getBoolEnvVar("ENABLE_GFD", true)
229-
Expect(EnableGFD).NotTo(BeNil(), "ENABLE_GFD must be set")
226+
Expect(ImagePullPolicy).NotTo(BeEmpty(), "E2E_IMAGE_PULL_POLICY must be set")
230227

231228
HostManagedDrivers = getBoolEnvVar("E2E_HOST_MANAGED_DRIVERS", true)
232-
Expect(HostManagedDrivers).NotTo(BeNil(), "E2E_HOST_MANAGED_DRIVERS must be set")
233229

234230
CollectLogsFrom = os.Getenv("COLLECT_LOGS_FROM")
235231

@@ -306,42 +302,32 @@ func CreateTestingNS(baseName string, c clientset.Interface, labels map[string]s
306302
return got, nil
307303
}
308304

309-
// deployDependencies installs all the dependent helm charts
310-
func deployDependencies(ctx context.Context) {
311-
// Install dependencies if not told to skip
312-
if EnableGFD {
313-
// Add or Update Helm repo
314-
helmRepo := repo.Entry{
315-
Name: "gfd",
316-
URL: "https://nvidia.github.io/k8s-device-plugin",
317-
}
318-
err := helmClient.AddOrUpdateChartRepo(helmRepo)
319-
Expect(err).NotTo(HaveOccurred())
320-
321-
err = helmClient.UpdateChartRepos()
322-
Expect(err).NotTo(HaveOccurred())
305+
// setNodeLabels sets the node labels for the test
306+
func setNodeLabels(ctx context.Context) error {
307+
nodes, err := clientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
308+
if err != nil {
309+
log.Fatalf("list nodes: %v", err)
310+
}
323311

324-
values := helmValues.Options{
325-
Values: []string{
326-
"gfd.enabled=true",
327-
"nfd.enabled=true",
328-
"devicePlugin.enabled=false",
312+
// static patch payload (JSON MergePatch)
313+
patch, _ := json.Marshal(map[string]any{
314+
"metadata": map[string]any{
315+
"labels": map[string]string{
316+
"nvidia.com/gpu.present": "true",
329317
},
330-
}
318+
},
319+
})
331320

332-
chartSpec := &helm.ChartSpec{
333-
ReleaseName: "gfd",
334-
ChartName: "gfd/nvidia-device-plugin",
335-
Namespace: testNamespace.Name,
336-
CreateNamespace: false,
337-
ValuesOptions: values,
338-
Wait: true,
339-
Timeout: 5 * time.Minute,
340-
CleanupOnFail: true,
321+
for _, n := range nodes.Items {
322+
_, err := clientSet.CoreV1().
323+
Nodes().
324+
Patch(ctx, n.Name, types.MergePatchType, patch, metav1.PatchOptions{})
325+
if err != nil {
326+
return fmt.Errorf("failed to patch node %s: %v", n.Name, err)
341327
}
342-
_, err = helmClient.InstallOrUpgradeChart(ctx, chartSpec, nil)
343-
Expect(err).NotTo(HaveOccurred())
344328
}
329+
330+
return nil
345331
}
346332

347333
// setHelmValuesOptions sets the Helm values options

0 commit comments

Comments
 (0)