Repository: googleapis/api-linter
Pull request #404 (2019-12-03 16:16:00)

[fix] Permit `validate_only`.


Patch:
diff --git a/rules/aip0133/request_unknown_fields.go b/rules/aip0133/request_unknown_fields.go
index 22f5b6b..2e52dc5 100644
--- a/rules/aip0133/request_unknown_fields.go
+++ b/rules/aip0133/request_unknown_fields.go
@@ -33,8 +33,9 @@ var unknownFields = &lint.MessageRule{
 
 		// Rule check: Establish that there are no unexpected fields.
 		allowedFields := map[string]*builder.FieldType{
-			"parent":     nil, // AIP-133
-			"request_id": nil, // AIP-155
+			"parent":        nil, // AIP-133
+			"request_id":    nil, // AIP-155
+			"validate_only": nil, // AIP needed
 			fmt.Sprintf("%s_id", strings.ToLower(strcase.SnakeCase(resourceMsgName))): nil,
 		}
 
diff --git a/rules/aip0134/request_unknown_fields.go b/rules/aip0134/request_unknown_fields.go
index 083eeb3..ddf79d2 100644
--- a/rules/aip0134/request_unknown_fields.go
+++ b/rules/aip0134/request_unknown_fields.go
@@ -31,8 +31,9 @@ var unknownFields = &lint.MessageRule{
 		// Rule check: Establish that there are no unexpected fields.
 		allowedFields := stringset.New(
 			fieldNameFromResource(resource), // AIP-134
-			"update_mask",                   // AIP-134
 			"request_id",                    // AIP-155
+			"update_mask",                   // AIP-134
+			"validate_only",                 // AIP needed
 		)
 		for _, field := range m.GetFields() {
 			if !allowedFields.Contains(field.GetName()) {
diff --git a/rules/aip0135/request_unknown_fields.go b/rules/aip0135/request_unknown_fields.go
index 0fb7247..012143b 100644
--- a/rules/aip0135/request_unknown_fields.go
+++ b/rules/aip0135/request_unknown_fields.go
@@ -28,10 +28,11 @@ var unknownFields = &lint.MessageRule{
 	LintMessage: func(m *desc.MessageDescriptor) (problems []lint.Problem) {
 		// Rule check: Establish that there are no unexpected fields.
 		allowedFields := map[string]struct{}{
-			"name":       {}, // AIP-135
-			"force":      {}, // AIP-135
-			"etag":       {}, // AIP-154
-			"request_id": {}, // AIP-155
+			"name":          {}, // AIP-135
+			"force":         {}, // AIP-135
+			"etag":          {}, // AIP-154
+			"request_id":    {}, // AIP-155
+			"validate_only": {}, // AIP needed
 		}
 		for _, field := range m.GetFields() {
 			if _, ok := allowedFields[string(field.GetName())]; !ok {


Test patch:
diff --git a/rules/aip0133/request_unknown_fields_test.go b/rules/aip0133/request_unknown_fields_test.go
index 6041ffa..3bf57aa 100644
--- a/rules/aip0133/request_unknown_fields_test.go
+++ b/rules/aip0133/request_unknown_fields_test.go
@@ -43,6 +43,13 @@ func TestUnknownFields(t *testing.T) {
 			testutils.Problems{},
 			nil,
 		},
+		{
+			"ValidateOnly",
+			"CreateBookRequest",
+			[]field{{"parent", builder.FieldTypeString()}, {"validate_only", builder.FieldTypeBool()}},
+			testutils.Problems{},
+			nil,
+		},
 		{
 			"ResourceRelatedField",
 			"CreateBookRequest",
diff --git a/rules/aip0134/request_unknown_fields_test.go b/rules/aip0134/request_unknown_fields_test.go
index 5db42d2..f961b83 100644
--- a/rules/aip0134/request_unknown_fields_test.go
+++ b/rules/aip0134/request_unknown_fields_test.go
@@ -40,6 +40,8 @@ func TestUnknownFields(t *testing.T) {
 		// Use BigBook instead of Book to test correct casing logic
 		{"UpdateMask", "UpdateBigBookRequest", "update_mask",
 			builder.FieldTypeImportedMessage(fieldMask), testutils.Problems{}},
+		{"ValidateOnly", "UpdateBigBookRequest", "validate_only",
+			builder.FieldTypeBool(), testutils.Problems{}},
 		{"Invalid", "UpdateBigBookRequest", "application_id",
 			builder.FieldTypeString(), testutils.Problems{{Message: "Unexpected field"}}},
 		{"InvalidCasing", "UpdateBigBookRequest", "bigbook",
diff --git a/rules/aip0135/request_unknown_fields_test.go b/rules/aip0135/request_unknown_fields_test.go
index 29597a3..882de71 100644
--- a/rules/aip0135/request_unknown_fields_test.go
+++ b/rules/aip0135/request_unknown_fields_test.go
@@ -33,6 +33,7 @@ func TestUnknownFields(t *testing.T) {
 		{"Force", "DeleteBookRequest", "force", builder.FieldTypeBool(), testutils.Problems{}},
 		{"Etag", "DeleteBookRequest", "etag", builder.FieldTypeString(), testutils.Problems{}},
 		{"RequestId", "DeleteBookRequest", "request_id", builder.FieldTypeString(), testutils.Problems{}},
+		{"ValidateOnly", "DeleteBookRequest", "validate_only", builder.FieldTypeBool(), testutils.Problems{}},
 		{"Invalid", "DeleteBookRequest", "application_id", builder.FieldTypeString(), testutils.Problems{{
 			Message: "Unexpected field",
 		}}},