Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions test/e2e/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ import (
"sigs.k8s.io/yaml"
)

// config represents the raw configuration data loaded from YAML files.
// Config represents the raw configuration data loaded from YAML files.
// This struct contains file paths and basic configuration values that are used
// to load and initialize the actual Kubernetes objects for testing.
//
// - Loaded from YAML config files (e.g., config-quick.yaml, config-provisioning.yaml)
// - Loaded from YAML Config files (e.g., Config-quick.yaml, Config-provisioning.yaml)
// - Used by applyConfig() to populate systemTestInput with actual Kubernetes objects
// - Used by systemTestInput for object loading and initialization
type config struct {
type Config struct {
DPUFlavorPath *string `json:"dpuFlavor,omitempty"`
ProvisioningControllerPVCPath *string `json:"provisioningControllerPVC,omitempty"`
BFBPath *string `json:"bfb,omitempty"`
Expand Down Expand Up @@ -73,12 +73,12 @@ type config struct {
AdditionalDPUServiceConfigurationPath *string `json:"additionalDPUServiceConfiguration,omitempty"`
}

func readConfig(path string) (*config, error) {
func ReadConfig(path string) (*Config, error) {
configData, err := os.ReadFile(path)
if err != nil {
return nil, err
}
conf := &config{}
conf := &Config{}
if err = yaml.UnmarshalStrict(configData, conf); err != nil {
return nil, err
}
Expand Down
14 changes: 7 additions & 7 deletions test/e2e/deprecation_warnings.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,19 @@ func (w *warningCollector) get() []string {
// warnings fire when a deprecated field is set on a DPF resource. It uses
// spec.bmcIP on a DPU as one arbitrary example of a deprecated field to
// trigger and assert on the warning.
func ValidateVAPDeprecationWarnings(ctx context.Context, input *systemTestInput) {
func ValidateVAPDeprecationWarnings(ctx context.Context, input *SystemTestInput) {
collector := &warningCollector{}
cfg := rest.CopyConfig(input.restConfig)
cfg := rest.CopyConfig(input.RestConfig)
cfg.WarningHandler = collector

warningClient, err := client.New(cfg, client.Options{Scheme: input.client.Scheme()})
warningClient, err := client.New(cfg, client.Options{Scheme: input.Client.Scheme()})
Expect(err).NotTo(HaveOccurred())

By("Creating a DPU with deprecated spec.bmcIP set")
dpu := &provisioningv1.DPU{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "e2e-vap-warning-",
Namespace: dpfOperatorSystemNamespace,
Namespace: DPFOperatorSystemNamespace,
Labels: CleanupScope.It,
},
Spec: provisioningv1.DPUSpec{
Expand All @@ -90,16 +90,16 @@ func ValidateVAPDeprecationWarnings(ctx context.Context, input *systemTestInput)

By("Creating a DPU without any deprecated fields set")
negativeCollector := &warningCollector{}
negativeCfg := rest.CopyConfig(input.restConfig)
negativeCfg := rest.CopyConfig(input.RestConfig)
negativeCfg.WarningHandler = negativeCollector

negativeClient, err := client.New(negativeCfg, client.Options{Scheme: input.client.Scheme()})
negativeClient, err := client.New(negativeCfg, client.Options{Scheme: input.Client.Scheme()})
Expect(err).NotTo(HaveOccurred())

dpuNoDeprecated := &provisioningv1.DPU{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "e2e-vap-no-warning-",
Namespace: dpfOperatorSystemNamespace,
Namespace: DPFOperatorSystemNamespace,
Labels: CleanupScope.It,
},
Spec: provisioningv1.DPUSpec{
Expand Down
28 changes: 14 additions & 14 deletions test/e2e/doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ General information about the E2E testing framework structure, patterns, and bes

### Infrastructure setup
* `test/e2e/system_setup.go` - DPF system deployment, node setup, cluster provisioning
* `test/e2e/system_test.go` - system-level test configuration (SetInput, SystemSetupBeforeSuite)
* `test/e2e/system_bootstrap.go` - system-level test configuration (`SetInput`, `SystemSetupBeforeSuite`)

### Test suites
* `test/e2e/*_test.go`
Expand Down Expand Up @@ -83,7 +83,7 @@ Configs reference YAML manifests in `test/objects/`

### Related files
* `test/e2e/config.go` - config struct definition
* `test/e2e/system_setup.go` - `systemTestInput` (holds loaded objects), `applyConfig()` (loads manifests)
* `test/e2e/system_setup.go` - `SystemTestInput` (holds loaded objects), `ApplyConfig()` (loads manifests)

### CI workflows
For automated test execution workflows, see:
Expand Down Expand Up @@ -174,7 +174,7 @@ var _ = Describe("DPF <some> tests ...", Labels{Domain.DPFSystem}, func() {

BeforeEach(func() {
// If required: Check if we have DPU nodes
if !input.hasDpuNodes() {
if !input.HasDpuNodes() {
return
}
})
Expand All @@ -184,17 +184,17 @@ var _ = Describe("DPF <some> tests ...", Labels{Domain.DPFSystem}, func() {
// * Only It starts with a minuscule
Context("Validate my fancy feature", Labels{dpfSystemLabel, requiresNodesLabel}, func() {
It("create a pod consuming a DPUServiceNAD with all dependencies and check that it is created successfully", func() {
ValidateMyFeature(ctx, input)
ValidateMyFeature(Ctx, input)
})
})
})
```

```go
// myfeature.go
func ValidateMyFeature(ctx context.Context, input *systemTestInput) {
func ValidateMyFeature(ctx context.Context, input *SystemTestInput) {
// If required: Check if we have DPU nodes
if !input.hasDpuNodes() {
if !input.HasDpuNodes() {
Skip("Skip test as there are not multiple nodes")
}

Expand Down Expand Up @@ -225,29 +225,29 @@ func ValidateMyFeature(ctx context.Context, input *systemTestInput) {
Labels: utils.AfterAllCleanupLabels, // Define appropriate cleanup label
},
}
Expect(input.client.Create(ctx, testNS)).To(Succeed())
Expect(input.Client.Create(ctx, testNS)).To(Succeed())
By("Created test namespace: " + testNS.Name)

//////////////////////////////////////////////
// Image pull secrets

By("Copy image pull secret to namespace " + testNS.Name)
// Re-use generic existing helper functions if possible
CopySecretToNamespace(ctx, input.client, dpfPullSecretName, dpfOperatorSystemNamespace, testNS.Name, utils.AfterEachCleanupLabels)
CopySecretToNamespace(ctx, input.Client, DPFPullSecretName, DPFOperatorSystemNamespace, testNS.Name, utils.AfterEachCleanupLabels)

//////////////////////////////////////////////
// Object creation and validation
By("Create DPUServiceNAD")
// Easy to read as factory method abstracts away construction details and programm flow and business logic is more in focus
// Separation of concerns (object construction separated from creation)
dpuServiceNAD := constructDPUServiceNAD(dpuServiceNADName, testNS.Name, mtu)
Expect(input.client.Create(ctx, dpuServiceNAD)).To(Succeed())
Expect(input.Client.Create(ctx, dpuServiceNAD)).To(Succeed())

// ...

By("Verify DPUServiceNAD is ready")
// Most of our objects have a defined status field structure and can be validated easily using helpers
EventuallyCheckReadyStatusCondition(ctx, input.client, dpuServiceNAD, defaultTimeout)
EventuallyCheckReadyStatusCondition(ctx, input.Client, dpuServiceNAD, defaultTimeout)

By("Verify DPUService pods are created in DPU cluster")
// Check with Eventually for async operations
Expand All @@ -257,8 +257,8 @@ func ValidateMyFeature(ctx context.Context, input *systemTestInput) {
Eventually(func(g Gomega) {
const podServiceLabel string = "svc.dpu.nvidia.com/service"
podList := &corev1.PodList{}
// Use `dpuClusterClient` for DPU cluster operations, `input.client` for host cluster
g.Expect(dpuClusterClient.List(ctx, podList,
// Use `DPUClusterClient` for DPU cluster operations, `input.Client` for host cluster
g.Expect(DPUClusterClient[0].List(ctx, podList,
client.InNamespace(testNS.Name),
client.MatchingLabels{podServiceLabel: serviceName},
)).To(Succeed())
Expand All @@ -270,7 +270,7 @@ func ValidateMyFeature(ctx context.Context, input *systemTestInput) {
// Use when you need to check properties on every pod/object in the list
Eventually(func(g Gomega) {
podList := &corev1.PodList{}
g.Expect(dpuClusterClient.List(ctx, podList, ...)).To(Succeed())
g.Expect(DPUClusterClient[0].List(ctx, podList, ...)).To(Succeed())
g.Expect(podList.Items).ToNot(BeEmpty())
// Loop through and check each pod's status
for _, pod := range podList.Items {
Expand Down Expand Up @@ -325,7 +325,7 @@ func constructDummyDPUServiceObject(serviceName, namespace, interfaceName string
// values:
// global:
// imagePullSecretName: dpf-pull-secret
`{"imagePullSecrets": [{"name": "%s"}]}`, dpfPullSecretName,
`{"imagePullSecrets": [{"name": "%s"}]}`, DPFPullSecretName,
)),
}
}
Expand Down
Loading