diff --git a/internal/integration/mtest/mongotest.go b/internal/integration/mtest/mongotest.go index ce9823b89a..dd7d06b047 100644 --- a/internal/integration/mtest/mongotest.go +++ b/internal/integration/mtest/mongotest.go @@ -816,18 +816,23 @@ func verifyRunOnBlockConstraint(rob RunOnBlock) error { return err } - if rob.CSFLE != nil { - if *rob.CSFLE && !IsCSFLEEnabled() { - return fmt.Errorf("runOnBlock requires CSFLE to be enabled. Build with the cse tag to enable") - } else if !*rob.CSFLE && IsCSFLEEnabled() { - return fmt.Errorf("runOnBlock requires CSFLE to be disabled. Build without the cse tag to disable") - } - if *rob.CSFLE { - if err := verifyVersionConstraints("4.2", ""); err != nil { - return err - } + // TODO(GODRIVER-3486): Once auto encryption is supported by the unified test + // format,this check should be removed. + if rob.CSFLEEnabled() && rob.CSFLE.Options != nil { + return fmt.Errorf("Auto encryption required (GODRIVER-3486)") + } + + if rob.CSFLEEnabled() && !IsCSFLEEnabled() { + return fmt.Errorf("runOnBlock requires CSFLE to be enabled. Build with the cse tag to enable") + } else if !rob.CSFLEEnabled() && IsCSFLEEnabled() { + return fmt.Errorf("runOnBlock requires CSFLE to be disabled. Build without the cse tag to disable") + } + if rob.CSFLEEnabled() { + if err := verifyVersionConstraints("4.2", ""); err != nil { + return err } } + return nil } diff --git a/internal/integration/mtest/options.go b/internal/integration/mtest/options.go index b2a6cb6d2d..3ef86d1b30 100644 --- a/internal/integration/mtest/options.go +++ b/internal/integration/mtest/options.go @@ -49,6 +49,45 @@ var ( falseBool = false ) +// CSFLEOptions holds configuration for Client-Side Field Level Encryption +// (CSFLE). +type CSFLEOptions struct{} + +// CSFLE models the runOnRequirements.csfle field in Unified Test Format tests. +// +// The csfle field accepts either: +// - a boolean: true enables CSFLE with no options; false disables CSFLE +// (Options is nil). +// - an object: Options is populated from the document and Boolean is set to +// false. +type CSFLE struct { + Boolean bool + Options *CSFLEOptions +} + +// UnmarshalBSON implements custom BSON unmarshalling for CSFLE, accepting +// either a boolean or an embedded document. If a document is provided, Options +// is set and Boolean is false. If a boolean is provided, Boolean is set and +// Options is nil. +func (csfle *CSFLE) UnmarshalBSON(data []byte) error { + embRawValue := bson.RawValue{Type: bson.TypeEmbeddedDocument, Value: data} + if err := embRawValue.Unmarshal(&csfle.Options); err == nil { + csfle.Boolean = false + + return nil + } + + rawValue := bson.RawValue{Type: bson.TypeBoolean, Value: data} + if b, ok := rawValue.BooleanOK(); ok { + csfle.Boolean = b + csfle.Options = nil + + return nil + } + + return fmt.Errorf("error unmarshalling CSFLE: %s", data) +} + // RunOnBlock describes a constraint for a test. type RunOnBlock struct { MinServerVersion string `bson:"minServerVersion"` @@ -58,7 +97,11 @@ type RunOnBlock struct { ServerParameters map[string]bson.RawValue `bson:"serverParameters"` Auth *bool `bson:"auth"` AuthEnabled *bool `bson:"authEnabled"` - CSFLE *bool `bson:"csfle"` + CSFLE *CSFLE `bson:"csfleConfiguration"` +} + +func (r *RunOnBlock) CSFLEEnabled() bool { + return r.CSFLE != nil && (r.CSFLE.Boolean || r.CSFLE.Options != nil) } // UnmarshalBSON implements custom BSON unmarshalling behavior for RunOnBlock because some test formats use the @@ -73,7 +116,7 @@ func (r *RunOnBlock) UnmarshalBSON(data []byte) error { ServerParameters map[string]bson.RawValue `bson:"serverParameters"` Auth *bool `bson:"auth"` AuthEnabled *bool `bson:"authEnabled"` - CSFLE *bool `bson:"csfle"` + CSFLE *CSFLE `bson:"csfle"` Extra map[string]any `bson:",inline"` } if err := bson.Unmarshal(data, &temp); err != nil { diff --git a/testdata/specifications b/testdata/specifications index 5ef7b1bc0a..49ade88e52 160000 --- a/testdata/specifications +++ b/testdata/specifications @@ -1 +1 @@ -Subproject commit 5ef7b1bc0acb1d18f7dce8df74b7cdac40f4cf33 +Subproject commit 49ade88e52ddfa6cee7fa0de286e5f8b0d62dcd0