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
14 changes: 14 additions & 0 deletions pkg/validate/application/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

e2econfig "github.com/ramendr/ramen/e2e/config"
"github.com/ramendr/ramen/e2e/types"
"sigs.k8s.io/yaml"

basecmd "github.com/ramendr/ramenctl/pkg/command"
"github.com/ramendr/ramenctl/pkg/config"
Expand Down Expand Up @@ -163,6 +164,19 @@ func totalDuration(steps []*report.Step) float64 {
return total
}

func loadApplicationStatus(t *testing.T, name string) *report.ApplicationStatus {
t.Helper()
data, err := os.ReadFile(filepath.Join("testdata", name))
if err != nil {
t.Fatalf("ReadFile(%q) error: %v", name, err)
}
s := &report.ApplicationStatus{}
if err := yaml.Unmarshal(data, s); err != nil {
t.Fatalf("Unmarshal() error: %v", err)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
t.Fatalf("Unmarshal() error: %v", err)
t.Fatalf("Unmarshal(%q) error: %v", name, err)

}
return s
}

func dumpCommandLog(t *testing.T, cmd *Command) {
log, err := os.ReadFile(cmd.LogFile())
if err != nil {
Expand Down
237 changes: 2 additions & 235 deletions pkg/validate/application/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ package application
import (
"context"
"testing"
stdtime "time"

ramenapi "github.com/ramendr/ramen/api/v1alpha1"
corev1 "k8s.io/api/core/v1"

"github.com/ramendr/ramenctl/pkg/helpers"
"github.com/ramendr/ramenctl/pkg/report"
Expand All @@ -20,12 +16,6 @@ import (

const applicationTestdata = "../../testdata/appset-deploy-rbd"

// Must match the cluster-time and lastGroupSyncTime in testdata.
var (
testClusterTime = stdtime.Date(2025, 7, 29, 17, 24, 30, 0, stdtime.UTC)
testLastGroupSyncTime = stdtime.Date(2025, 7, 29, 17, 23, 0, 0, stdtime.UTC)
)

var (
testApplication = &report.Application{
Name: drpcName,
Expand Down Expand Up @@ -126,231 +116,8 @@ func TestValidateApplicationPassed(t *testing.T) {
}
checkItems(t, validate.Report.Steps[1], items)

expectedStatus := &report.ApplicationStatus{
Hub: report.ApplicationStatusHub{
DRPC: report.DRPCSummary{
Name: drpcName,
Namespace: drpcNamespace,
ClusterTime: &testClusterTime,
Deleted: report.ValidatedBool{
Validated: report.Validated{
State: report.OK,
},
},
Action: report.ValidatedString{
Validated: report.Validated{
State: report.OK,
},
},
DRPolicy: "dr-policy-1m",
SchedulingInterval: report.ValidatedDuration{
Validated: report.Validated{
State: report.OK,
},
Value: stdtime.Minute,
},
LastGroupSyncTime: report.ValidatedTime{
Validated: report.Validated{
State: report.OK,
},
Value: &testLastGroupSyncTime,
},
Phase: report.ValidatedString{
Validated: report.Validated{
State: report.OK,
},
Value: string(ramenapi.Deployed),
},
Progression: report.ValidatedString{
Validated: report.Validated{
State: report.OK,
},
Value: string(ramenapi.ProgressionCompleted),
},
Conditions: []report.ValidatedCondition{
{
Validated: report.Validated{
State: report.OK,
},
Type: "Available",
},
{
Validated: report.Validated{
State: report.OK,
},
Type: "PeerReady",
},
{
Validated: report.Validated{
State: report.OK,
},
Type: "Protected",
},
},
},
},
PrimaryCluster: report.ApplicationStatusCluster{
Name: "dr1",
VRG: report.VRGSummary{
Name: drpcName,
Namespace: applicationNamespace,
ClusterTime: &testClusterTime,
Deleted: report.ValidatedBool{
Validated: report.Validated{
State: report.OK,
},
},
SchedulingInterval: report.ValidatedDuration{
Validated: report.Validated{
State: report.OK,
},
Value: stdtime.Minute,
},
LastGroupSyncTime: report.ValidatedTime{
Validated: report.Validated{
State: report.OK,
},
Value: &testLastGroupSyncTime,
},
State: report.ValidatedString{
Validated: report.Validated{
State: report.OK,
},
Value: string(ramenapi.PrimaryState),
},
Conditions: []report.ValidatedCondition{
{
Validated: report.Validated{
State: report.OK,
},
Type: "DataReady",
},
{
Validated: report.Validated{
State: report.OK,
},
Type: "ClusterDataReady",
},
{
Validated: report.Validated{
State: report.OK,
},
Type: "ClusterDataProtected",
},
{
Validated: report.Validated{
State: report.OK,
},
Type: "KubeObjectsReady",
},
{
Validated: report.Validated{
State: report.OK,
},
Type: "NoClusterDataConflict",
},
},
ProtectedPVCs: []report.ProtectedPVCSummary{
{
Name: "busybox-pvc",
Namespace: "e2e-appset-deploy-rbd",
Deleted: report.ValidatedBool{
Validated: report.Validated{
State: report.OK,
},
},
Replication: report.Volrep,
Phase: report.ValidatedString{
Validated: report.Validated{
State: report.OK,
},
Value: string(corev1.ClaimBound),
},
Conditions: []report.ValidatedCondition{
{
Validated: report.Validated{
State: report.OK,
},
Type: "DataReady",
},
{
Validated: report.Validated{
State: report.OK,
},
Type: "ClusterDataProtected",
},
},
},
},
// TODO: https://github.com/RamenDR/ramenctl/issues/330
},
},
SecondaryCluster: report.ApplicationStatusCluster{
Name: "dr2",
VRG: report.VRGSummary{
Name: drpcName,
Namespace: applicationNamespace,
ClusterTime: &testClusterTime,
Deleted: report.ValidatedBool{
Validated: report.Validated{
State: report.OK,
},
},
SchedulingInterval: report.ValidatedDuration{
Validated: report.Validated{
State: report.OK,
},
Value: stdtime.Minute,
},
LastGroupSyncTime: report.ValidatedTime{
Validated: report.Validated{
State: report.OK,
},
},
State: report.ValidatedString{
Validated: report.Validated{
State: report.OK,
},
Value: string(ramenapi.SecondaryState),
},
Conditions: []report.ValidatedCondition{
{
Validated: report.Validated{
State: report.OK,
},
Type: "NoClusterDataConflict",
},
},
},
},
S3: report.ApplicationS3Status{
Profiles: report.ValidatedApplicationS3ProfileStatusList{
Validated: report.Validated{
State: report.OK,
},
Value: []report.ApplicationS3ProfileStatus{
{
Name: "minio-on-dr1",
Gathered: report.ValidatedBool{
Validated: report.Validated{
State: report.OK,
},
Value: true,
},
},
{
Name: "minio-on-dr2",
Gathered: report.ValidatedBool{
Validated: report.Validated{
State: report.OK,
},
Value: true,
},
},
},
},
},
}
expectedStatus := loadApplicationStatus(t, "appset-deploy-rbd.yaml")

checkApplicationStatus(t, validate.Report, expectedStatus)

checkSummary(t, validate.Report, report.Summary{summary.OK: 30})
Expand Down
112 changes: 112 additions & 0 deletions pkg/validate/application/testdata/appset-deploy-rbd.yaml

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let name this after the application tested - appset-deploy-rbd - like the testdata directory. In the future we will have more testdata and golden files.

Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Golden file for the expected report.ApplicationStatus produced by
# TestValidateApplicationPassed in command_test.go.
#
# Generated from the report.ApplicationStatus struct that was previously
# hardcoded in the test, by temporarily marshaling it to yaml and writing

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No need to detail how it used to work ("previously hardcoded in the test")

# it to this path. See the commit message for the exact steps used.
#
# If the test fixtures under pkg/testdata/appset-deploy-rbd/ change,
# this file must be regenerated to match.
Comment on lines +1 to +9

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The useful parts are only:

  • which test uses the file
  • which pkg/testdata/... tree it tracks
  • regenerate when that tree changes


hub:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Add a comment to the file explaining how it is generated and when we need to update it.

drpc:
action:
state: ok ✅
clusterTime: "2025-07-29T17:24:30Z"
conditions:
- state: ok ✅
type: Available
- state: ok ✅
type: PeerReady
- state: ok ✅
type: Protected
deleted:
state: ok ✅
drPolicy: dr-policy-1m
lastGroupSyncTime:
state: ok ✅
value: "2025-07-29T17:23:00Z"
name: appset-deploy-rbd
namespace: argocd
phase:
state: ok ✅
value: Deployed
progression:
state: ok ✅
value: Completed
schedulingInterval:
state: ok ✅
value: 1m0s
primaryCluster:
name: dr1
vrg:
clusterTime: "2025-07-29T17:24:30Z"
conditions:
- state: ok ✅
type: DataReady
- state: ok ✅
type: ClusterDataReady
- state: ok ✅
type: ClusterDataProtected
- state: ok ✅
type: KubeObjectsReady
- state: ok ✅
type: NoClusterDataConflict
deleted:
state: ok ✅
lastGroupSyncTime:
state: ok ✅
value: "2025-07-29T17:23:00Z"
name: appset-deploy-rbd
namespace: e2e-appset-deploy-rbd
protectedPVCs:
- conditions:
- state: ok ✅
type: DataReady
- state: ok ✅
type: ClusterDataProtected
deleted:
state: ok ✅
name: busybox-pvc
namespace: e2e-appset-deploy-rbd
phase:
state: ok ✅
value: Bound
replication: volrep
schedulingInterval:
state: ok ✅
value: 1m0s
state:
state: ok ✅
value: Primary
s3:
profiles:
state: ok ✅
value:
- gathered:
state: ok ✅
value: true
name: minio-on-dr1
- gathered:
state: ok ✅
value: true
name: minio-on-dr2
secondaryCluster:
name: dr2
vrg:
clusterTime: "2025-07-29T17:24:30Z"
conditions:
- state: ok ✅
type: NoClusterDataConflict
deleted:
state: ok ✅
lastGroupSyncTime:
state: ok ✅
name: appset-deploy-rbd
namespace: e2e-appset-deploy-rbd
schedulingInterval:
state: ok ✅
value: 1m0s
state:
state: ok ✅
value: Secondary
Loading