Merge "[jsonschema] Require specifying additionalProperties explicitly"

This commit is contained in:
Zuul 2018-02-02 19:11:12 +00:00 committed by Gerrit Code Review
commit 2480e5da0e
13 changed files with 63 additions and 27 deletions

View File

@ -79,7 +79,8 @@ class CeilometerSampleGenerator(context.Context):
"created_at": {
"type": "string"
}
}
},
"additionalProperties": False
}
},
"batch_size": {

View File

@ -73,12 +73,15 @@ class HeatDataplane(context.Context):
},
"files": {
"type": "object",
"additionalProperties": True
},
"parameters": {
"type": "object",
"additionalProperties": True
},
"context_parameters": {
"type": "object",
"additionalProperties": True
},
},
"additionalProperties": False

View File

@ -39,7 +39,8 @@ class EC2ServerGenerator(context.Context):
"name": {
"type": "string"
}
}
},
"additionalProperties": False
},
"flavor": {
"type": "object",
@ -47,7 +48,8 @@ class EC2ServerGenerator(context.Context):
"name": {
"type": "string"
}
}
},
"additionalProperties": False
},
"servers_per_tenant": {
"type": "integer",

View File

@ -70,12 +70,13 @@ class ShareNetworks(context.Context):
"properties": {
"use_share_networks": {
"type": "boolean",
"description": "specifies whether manila should use share "
"description": "Specifies whether manila should use share "
"networks for share creation or not."},
"share_networks": {
"type": "object",
"description": SHARE_NETWORKS_ARG_DESCR
"description": SHARE_NETWORKS_ARG_DESCR,
"additionalProperties": True
},
},
"additionalProperties": False

View File

@ -48,7 +48,8 @@ class MonascaMetricGenerator(context.Context):
"url": {
"type": "string"
}
}
},
"additionalProperties": False
},
"metrics_per_tenant": {
"type": "integer",
@ -65,7 +66,8 @@ class MonascaMetricGenerator(context.Context):
"value_meta_value": {
"type": "string"
}
}
},
"additionalProperties": False
}
}
},

View File

@ -48,7 +48,8 @@ class Router(context.Context):
"properties": {
"network_id": {"type": "string"},
"enable_snat": {"type": "boolean"}
}
},
"additionalProperties": False
},
"network_id": {
"description": "Network ID",
@ -62,7 +63,8 @@ class Router(context.Context):
"properties": {
"ip_address": {"type": "string"},
"subnet_id": {"type": "string"}
}
},
"additionalProperties": False,
}
},
"distributed": {

View File

@ -32,7 +32,8 @@ class Lbaas(context.Context):
"$schema": consts.JSON_SCHEMA,
"properties": {
"pool": {
"type": "object"
"type": "object",
"additionalProperties": True
},
"lbaas_version": {
"type": "integer",

View File

@ -38,14 +38,16 @@ class ServerGenerator(context.Context):
"type": "object",
"properties": {
"name": {"type": "string"}
}
},
"additionalProperties": False
},
"flavor": {
"description": "Name of flavor to boot server(s) with.",
"type": "object",
"properties": {
"name": {"type": "string"}
}
},
"additionalProperties": False
},
"servers_per_tenant": {
"description": "Number of servers to boot in each Tenant.",
@ -60,11 +62,18 @@ class ServerGenerator(context.Context):
"type": "array",
"description": "List of networks to attach to server.",
"items": {"oneOf": [
{"type": "object",
"properties": {"net-id": {"type": "string"}},
"description": "Network ID in a format like OpenStack API"
" expects to see."},
{"type": "string", "description": "Network ID."}]},
{
"type": "object",
"properties": {"net-id": {"type": "string"}},
"description": "Network ID in a format like OpenStack "
"API expects to see.",
"additionalProperties": False
},
{
"type": "string",
"description": "Network ID."
}
]},
"minItems": 1
}
},

View File

@ -77,10 +77,12 @@ class SaharaCluster(context.Context):
}
},
"node_configs": {
"type": "object"
"type": "object",
"additionalProperties": True
},
"cluster_configs": {
"type": "object"
"type": "object",
"additionalProperties": True
},
"enable_anti_affinity": {
"type": "boolean"

View File

@ -34,6 +34,7 @@ class ProfilesGenerator(context.Context):
},
"properties": {
"type": "object",
"additionalProperties": True,
}
},
"additionalProperties": False,

View File

@ -55,7 +55,8 @@ class BaseCustomImageGenerator(context.Context):
"name": {
"type": "string"
}
}
},
"additionalProperties": False
},
"flavor": {
"type": "object",
@ -63,7 +64,8 @@ class BaseCustomImageGenerator(context.Context):
"name": {
"type": "string"
}
}
},
"additionalProperties": False
},
"username": {
"type": "string"

View File

@ -49,7 +49,8 @@ class AuditTemplateGenerator(context.Context):
"name": {
"type": "string"
}
}
},
"additionalProperties": False
},
"strategy": {
"type": "object",
@ -57,9 +58,11 @@ class AuditTemplateGenerator(context.Context):
"name": {
"type": "string"
}
}
},
"additionalProperties": False
},
},
"additionalProperties": False,
},
}
},

View File

@ -13,6 +13,7 @@
# under the License.
import copy
import json
from rally.common.plugin import plugin
from rally import plugins
@ -35,9 +36,10 @@ class ConfigSchemasTestCase(test.TestCase):
def fail(self, p, schema, msg):
super(ConfigSchemasTestCase, self).fail(
"Config schema of plugin '%s' (%s) is invalid. %s "
"(Schema: %s)" % (p.get_name(),
"Schema: \n%s" % (p.get_name(),
"%s.%s" % (p.__module__, p.__name__),
msg, schema))
msg,
json.dumps(schema, indent=3)))
def _check_anyOf_or_oneOf(self, p, schema, definitions):
if "anyOf" in schema or "oneOf" in schema:
@ -61,6 +63,11 @@ class ConfigSchemasTestCase(test.TestCase):
if unexpected_keys:
self.fail(p, schema, ("Found unexpected key(s) for object type: "
"%s." % ", ".join(unexpected_keys)))
if "additionalProperties" not in schema:
self.fail(p, schema,
"'additionalProperties' is required field for objects. "
"Specify `'additionalProperties': True` explicitly to "
"accept not validated properties.")
if "patternProperties" in schema:
if "properties" in schema:
@ -147,7 +154,7 @@ class ConfigSchemasTestCase(test.TestCase):
pass
elif schema == {}:
# NOTE(andreykurilin): an empty dict means that the user can
# transmit whatever he want in whatever he want format. It is
# transmit whatever he wants in whatever he wants format. It is
# not the case which we want to support.
self.fail(p, schema, "Empty schema is not allowed.")
elif "$ref" in schema:
@ -161,7 +168,7 @@ class ConfigSchemasTestCase(test.TestCase):
@plugins.ensure_plugins_are_loaded
def test_schema_is_valid(self):
for p in plugin.Plugin.get_all():
if not hasattr(p, "CONFIG_SCHEMA"):
if not hasattr(p, "CONFIG_SCHEMA") or "tests.unit" in p.__module__:
continue
# allow only top level definitions
definitions = p.CONFIG_SCHEMA.get("definitions", {})