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
33 changes: 33 additions & 0 deletions api/v1alpha1/api_test_helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
Copyright 2026 The Fluid Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
. "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)

func apiGVKFor(object runtime.Object) (schema.GroupVersionKind, error) {
gvks, _, err := UnitTestScheme.ObjectKinds(object)
if err != nil {
return schema.GroupVersionKind{}, err
}

Expect(gvks).NotTo(BeEmpty())
return gvks[0], nil
}
47 changes: 47 additions & 0 deletions api/v1alpha1/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
Copyright 2026 The Fluid Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var _ = Describe("common API helpers", func() {
Describe("MetadataSyncPolicy.AutoSyncEnabled", func() {
It("defaults to true when auto sync is not configured", func() {
policy := &MetadataSyncPolicy{}

Expect(policy.AutoSyncEnabled()).To(BeTrue())
})

It("returns true when auto sync is explicitly enabled", func() {
enabled := true
policy := &MetadataSyncPolicy{AutoSync: &enabled}

Expect(policy.AutoSyncEnabled()).To(BeTrue())
})

It("returns false when auto sync is explicitly disabled", func() {
disabled := false
policy := &MetadataSyncPolicy{AutoSync: &disabled}

Expect(policy.AutoSyncEnabled()).To(BeFalse())
})
})

})
39 changes: 13 additions & 26 deletions api/v1alpha1/container_network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,18 @@ limitations under the License.

package v1alpha1

import "testing"
import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestIsHostNetwork(t *testing.T) {
testCases := map[string]struct {
n NetworkMode
want bool
}{
"test host network case 1": {
n: HostNetworkMode,
want: true,
var _ = Describe("IsHostNetwork", func() {
DescribeTable("reports whether the network mode uses the host network",
func(mode NetworkMode, expected bool) {
Expect(IsHostNetwork(mode)).To(Equal(expected))
},
"test host network case 2": {
n: "",
want: true,
},
"test container network case 1": {
n: ContainerNetworkMode,
want: false,
},
}

for k, v := range testCases {
got := IsHostNetwork(v.n)
if v.want != got {
t.Errorf("check %s failure, got:%t,want:%t", k, got, v.want)
}
}
}
Entry("host network mode", HostNetworkMode, true),
Entry("default network mode", DefaultNetworkMode, true),
Entry("container network mode", ContainerNetworkMode, false),
)
})
113 changes: 113 additions & 0 deletions api/v1alpha1/databackup_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
Copyright 2026 The Fluid Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
"github.com/fluid-cloudnative/fluid/pkg/common"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ = Describe("DataBackup types", func() {
Describe("scheme registration", func() {
It("registers DataBackup and DataBackupList with the package group version", func() {
dataBackupGVK, err := apiGVKFor(&DataBackup{})
Expect(err).NotTo(HaveOccurred())
Expect(dataBackupGVK).To(Equal(GroupVersion.WithKind("DataBackup")))

dataBackupListGVK, err := apiGVKFor(&DataBackupList{})
Expect(err).NotTo(HaveOccurred())
Expect(dataBackupListGVK).To(Equal(GroupVersion.WithKind("DataBackupList")))
})
})

Describe("DeepCopyObject", func() {
It("returns a distinct runtime object for DataBackup and DataBackupList", func() {
uid := int64(1000)
gid := int64(1000)
dataBackup := &DataBackup{
TypeMeta: metav1.TypeMeta{APIVersion: GroupVersion.String(), Kind: "DataBackup"},
ObjectMeta: metav1.ObjectMeta{Name: "example", Namespace: "fluid"},
Spec: DataBackupSpec{
Dataset: "imagenet",
BackupPath: "s3://bucket/checkpoints",
RunAs: &User{UID: &uid, GID: &gid},
RunAfter: &OperationRef{ObjectRef: ObjectRef{
Kind: "DataLoad",
Name: "prepare-backup",
}},
},
Status: OperationStatus{Phase: common.PhaseComplete, Duration: "30s"},
}

copiedObject := dataBackup.DeepCopyObject()
copiedDataBackup, ok := copiedObject.(*DataBackup)
Expect(ok).To(BeTrue())
Expect(copiedDataBackup).NotTo(BeIdenticalTo(dataBackup))
Expect(copiedDataBackup.Spec).To(Equal(dataBackup.Spec))
// Verify deep copy of nested pointers.
Expect(copiedDataBackup.Spec.RunAs).NotTo(BeIdenticalTo(dataBackup.Spec.RunAs))
Expect(copiedDataBackup.Spec.RunAfter).NotTo(BeIdenticalTo(dataBackup.Spec.RunAfter))
Expect(copiedDataBackup.Status).To(Equal(dataBackup.Status))
Expect(copiedDataBackup.Spec.RunAs.UID).NotTo(BeIdenticalTo(dataBackup.Spec.RunAs.UID))
Expect(copiedDataBackup.Spec.RunAs.GID).NotTo(BeIdenticalTo(dataBackup.Spec.RunAs.GID))

dataBackupList := &DataBackupList{Items: []DataBackup{*dataBackup}}
copiedListObject := dataBackupList.DeepCopyObject()
copiedList, ok := copiedListObject.(*DataBackupList)
Expect(ok).To(BeTrue())
Expect(copiedList).NotTo(BeIdenticalTo(dataBackupList))
Expect(copiedList.Items).To(HaveLen(1))
Expect(copiedList.Items[0].Spec.BackupPath).To(Equal("s3://bucket/checkpoints"))
})
})

Describe("representative spec and status construction", func() {
It("captures backup target, workflow dependency, and backup location info", func() {
ttlSeconds := int32(120)
dataBackup := DataBackup{
Spec: DataBackupSpec{
Dataset: "imagenet",
BackupPath: "oss://archive/imagenet",
RunAs: &User{UserName: "fluid"},
RunAfter: &OperationRef{ObjectRef: ObjectRef{
Kind: "DataLoad",
Name: "freeze-dataset",
}},
TTLSecondsAfterFinished: &ttlSeconds,
},
Status: OperationStatus{
Phase: common.PhaseComplete,
Duration: "3m",
Infos: map[string]string{
"BackupLocationPath": "/archive/imagenet",
"BackupLocationNodeName": "worker-0",
},
},
}

Expect(dataBackup.Spec.Dataset).To(Equal("imagenet"))
Expect(dataBackup.Spec.RunAfter).NotTo(BeNil())
Expect(dataBackup.Spec.RunAfter.ObjectRef).To(Equal(ObjectRef{Kind: "DataLoad", Name: "freeze-dataset"}))
Expect(dataBackup.Spec.RunAs).NotTo(BeNil())
Expect(dataBackup.Spec.RunAs.UserName).To(Equal("fluid"))
Expect(dataBackup.Status.Phase).To(Equal(common.PhaseComplete))
Expect(dataBackup.Status.Infos).To(HaveKeyWithValue("BackupLocationNodeName", "worker-0"))
})
})
})
112 changes: 112 additions & 0 deletions api/v1alpha1/dataload_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
Copyright 2026 The Fluid Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
"github.com/fluid-cloudnative/fluid/pkg/common"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ = Describe("DataLoad types", func() {
Describe("scheme registration", func() {
It("registers DataLoad and DataLoadList with the package group version", func() {
dataLoadGVK, err := apiGVKFor(&DataLoad{})
Expect(err).NotTo(HaveOccurred())
Expect(dataLoadGVK).To(Equal(GroupVersion.WithKind("DataLoad")))

dataLoadListGVK, err := apiGVKFor(&DataLoadList{})
Expect(err).NotTo(HaveOccurred())
Expect(dataLoadListGVK).To(Equal(GroupVersion.WithKind("DataLoadList")))
})
})

Describe("DeepCopyObject", func() {
It("returns a distinct runtime object for DataLoad and DataLoadList", func() {
dataLoad := &DataLoad{
TypeMeta: metav1.TypeMeta{APIVersion: GroupVersion.String(), Kind: "DataLoad"},
ObjectMeta: metav1.ObjectMeta{Name: "example", Namespace: "fluid"},
Spec: DataLoadSpec{
Dataset: TargetDataset{Name: "dataset", Namespace: "fluid"},
Target: []TargetPath{{Path: "/training", Replicas: 2}},
Options: map[string]string{"threads": "8"},
RunAfter: &OperationRef{ObjectRef: ObjectRef{
Kind: "DataLoad",
Name: "prepare",
}},
Policy: Once,
},
Status: OperationStatus{Phase: common.PhaseComplete, Duration: "1m"},
}

copiedObject := dataLoad.DeepCopyObject()
copiedDataLoad, ok := copiedObject.(*DataLoad)
Expect(ok).To(BeTrue())
Expect(copiedDataLoad).NotTo(BeIdenticalTo(dataLoad))
Expect(copiedDataLoad.Spec).To(Equal(dataLoad.Spec))
// Verify deep copy of nested pointers.
Expect(copiedDataLoad.Spec.RunAfter).NotTo(BeIdenticalTo(dataLoad.Spec.RunAfter))
dataLoad.Spec.RunAfter.Name = "changed-after-copy"
Expect(copiedDataLoad.Spec.RunAfter.ObjectRef).To(Equal(ObjectRef{Kind: "DataLoad", Name: "prepare"}))
Expect(copiedDataLoad.Status).To(Equal(dataLoad.Status))
Comment on lines +57 to +66
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to other DeepCopyObject tests, this should verify that nested pointers (like Spec.RunAfter) are deep-copied to ensure that the copy is independent of the original object.

Suggested change
copiedObject := dataLoad.DeepCopyObject()
copiedDataLoad, ok := copiedObject.(*DataLoad)
Expect(ok).To(BeTrue())
Expect(copiedDataLoad).NotTo(BeIdenticalTo(dataLoad))
Expect(copiedDataLoad.Spec).To(Equal(dataLoad.Spec))
Expect(copiedDataLoad.Status).To(Equal(dataLoad.Status))
copiedObject := dataLoad.DeepCopyObject()
copiedDataLoad, ok := copiedObject.(*DataLoad)
Expect(ok).To(BeTrue())
Expect(copiedDataLoad).NotTo(BeIdenticalTo(dataLoad))
Expect(copiedDataLoad.Spec).To(Equal(dataLoad.Spec))
// Verify deep copy of nested pointers
if dataLoad.Spec.RunAfter != nil {
Expect(copiedDataLoad.Spec.RunAfter).NotTo(BeIdenticalTo(dataLoad.Spec.RunAfter))
}
Expect(copiedDataLoad.Status).To(Equal(dataLoad.Status))


dataLoadList := &DataLoadList{Items: []DataLoad{*dataLoad}}
copiedListObject := dataLoadList.DeepCopyObject()
copiedList, ok := copiedListObject.(*DataLoadList)
Expect(ok).To(BeTrue())
Expect(copiedList).NotTo(BeIdenticalTo(dataLoadList))
Expect(copiedList.Items).To(HaveLen(1))
Expect(copiedList.Items[0].Spec.Dataset).To(Equal(dataLoad.Spec.Dataset))
})
})

Describe("representative spec and status construction", func() {
It("captures the dataset target, workflow dependency, and operation progress", func() {
ttlSeconds := int32(60)
dataLoad := DataLoad{
Spec: DataLoadSpec{
Dataset: TargetDataset{Name: "imagenet", Namespace: "fluid"},
LoadMetadata: true,
Target: []TargetPath{{Path: "/train", Replicas: 2}},
Options: map[string]string{"format": "csv"},
RunAfter: &OperationRef{ObjectRef: ObjectRef{
Kind: "DataLoad",
Name: "prepare",
}},
TTLSecondsAfterFinished: &ttlSeconds,
Policy: Once,
},
Status: OperationStatus{
Phase: common.PhaseComplete,
Duration: "45s",
Infos: map[string]string{
"cached": "true",
},
},
}

Expect(dataLoad.Spec.Dataset.Name).To(Equal("imagenet"))
Expect(dataLoad.Spec.Target).To(ContainElement(TargetPath{Path: "/train", Replicas: 2}))
Expect(dataLoad.Spec.RunAfter).NotTo(BeNil())
Expect(dataLoad.Spec.RunAfter.ObjectRef).To(Equal(ObjectRef{Kind: "DataLoad", Name: "prepare"}))
Expect(*dataLoad.Spec.TTLSecondsAfterFinished).To(Equal(ttlSeconds))
Expect(dataLoad.Status.Phase).To(Equal(common.PhaseComplete))
Expect(dataLoad.Status.Infos).To(HaveKeyWithValue("cached", "true"))
})
})
})
Loading
Loading