Commit df2bc8bc authored by Xavier Thompson's avatar Xavier Thompson

test/recipe: Add slapconfiguration:jsonschema tests

parent 5cdbaf6f
# coding: utf-8 # coding: utf-8
import copy
import json import json
import mock import mock
import os import os
import shutil
import unittest import unittest
import tempfile import tempfile
from collections import defaultdict from collections import defaultdict
...@@ -32,17 +34,16 @@ class SlapConfigurationTest(unittest.TestCase): ...@@ -32,17 +34,16 @@ class SlapConfigurationTest(unittest.TestCase):
"directory": self.instance_root "directory": self.instance_root
} }
} }
self.software_root = tempfile.mkdtemp()
def tearDown(self): def tearDown(self):
os.unlink(self.resource_file) os.unlink(self.resource_file)
os.rmdir(self.instance_root) os.rmdir(self.instance_root)
shutil.rmtree(self.software_root)
@mock.patch("slapos.slap.slap") @mock.patch("slapos.slap.slap")
def test_correct_naming(self, MockClient): def test_correct_naming(self, _):
"""Test correct naming of variables from resource file.""" """Test correct naming of variables from resource file."""
MockClient.initializeConnection.return_value = None
MockClient.getInstanceParameterDict.return_value = dict()
options = defaultdict(str) options = defaultdict(str)
recipe = slapconfiguration.Recipe(self.buildout, "slapconfiguration", options) recipe = slapconfiguration.Recipe(self.buildout, "slapconfiguration", options)
...@@ -52,3 +53,297 @@ class SlapConfigurationTest(unittest.TestCase): ...@@ -52,3 +53,297 @@ class SlapConfigurationTest(unittest.TestCase):
self.assertEqual(options['address-list'], [10, 20], self.assertEqual(options['address-list'], [10, 20],
"All underscores should be replaced with -") "All underscores should be replaced with -")
def writeJsonSchema(self, serialisation='json-in-xml'):
self.software_json_file = os.path.join(self.software_root, 'software.cfg.json')
software_schema = {
"name": "Test",
"serialisation": serialisation,
"software-type": {
"default": {
"title": "Default",
"software-type": "default",
"request": "instance-default-input.json",
"index": 0,
},
"default/*": {
"title": "Default",
"shared": True,
"software-type": "default",
"request": "shared-default-input.json",
"index": 0,
},
}
}
with open(self.software_json_file, 'w') as f:
json.dump(software_schema, f)
self.instance_json_file = os.path.join(self.software_root, 'instance-default-input.json')
properties = {
"letter": {
"type": "string",
"enum": ["a", "b", "c"],
"default": "a"
},
"number": {
"type": "integer",
},
}
default_dict = {}
without_default = []
for key, obj in properties.items():
default = obj.get('default')
if default is None:
without_default.append(key)
else:
default_dict[key] = default
self.default_dict = default_dict
instance_schema = {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$defs": {
"instance-parameters": {
"type": "object",
"properties": properties,
"required": without_default,
},
},
"unevaluatedProperties": False,
"allOf": [{"$ref": "#/$defs/instance-parameters" },]
}
with open(self.instance_json_file, 'w') as f:
json.dump(instance_schema, f)
self.shared_json_file = os.path.join(self.software_root, 'shared-default-input.json')
shared_schema = {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"oneOf": [
{
"$ref": "shared-1-default-input.json"
},
{
"$ref": "shared-2-default-input.json"
},
]
}
with open(self.shared_json_file, 'w') as f:
json.dump(shared_schema, f)
self.shared_1_json_file = os.path.join(self.software_root, 'shared-1-default-input.json')
shared_1_schema = {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"properties": {
"kind": {
"const": 1,
},
"thing": {
"type": "string",
"default": "hello",
},
},
"required": ["kind"],
}
with open(self.shared_1_json_file, 'w') as f:
json.dump(shared_1_schema, f)
self.shared_2_json_file = os.path.join(self.software_root, 'shared-2-default-input.json')
shared_2_schema = {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"properties": {
"kind": {
"const": 2,
},
"thing": {
"type": "integer",
"default": 42,
},
"required": ["kind"],
}
}
with open(self.shared_2_json_file, 'w') as f:
json.dump(shared_2_schema, f)
def patchSlap(self, parameters, serialise, shared=None, software_type='default'):
shared = copy.deepcopy(shared) if shared else []
d = {'_': json.dumps(parameters)} if serialise else copy.deepcopy(parameters)
for i, s in enumerate(shared):
s['slave_reference'] = 'SHARED%s' % i
slap = mock.MagicMock()
slap_object = slap.return_value
slap_object.initializeConnection.return_value = None
computer_partition = slap_object.registerComputerPartition.return_value
computer_partition.getInstanceParameterDict.return_value = d
d['ip_list'] = []
d['slap_software_type'] = software_type
d['slave_instance_list'] = shared
return mock.patch("slapos.slap.slap", slap)
def runJsonSchemaRecipe(self, options=()):
options = defaultdict(str, options)
options['jsonschema'] = self.software_json_file
slapconfiguration.JsonSchema(self.buildout, "slapconfiguration", options)
return options
def receiveParameters(self, options=()):
options = self.runJsonSchemaRecipe(options)
return options['configuration']
def receiveSharedParameters(self, options=()):
options = self.runJsonSchemaRecipe(options)
self.assertNotIn('slave-instance-list', options)
valid = options['valid-shared-instance-list']
invalid = options['invalid-shared-instance-list']
valid = {d['reference']: d['parameters'] for d in valid}
invalid = {d['reference']: d['parameters'] for d in invalid}
return valid, invalid
def checkParametersWithDefaults(self, received_parameters, sent_parameters):
expected_dict = dict(self.default_dict)
expected_dict.update(sent_parameters)
self.assertEqual(received_parameters, expected_dict)
def test_jsonschema_json_in_xml_valid_xml_input_defaults(self):
self.writeJsonSchema()
parameters = {"number": 1}
with self.patchSlap(parameters, False):
received = self.receiveParameters()
self.checkParametersWithDefaults(received, parameters)
def test_jsonschema_json_in_xml_valid_json_input_defaults(self):
self.writeJsonSchema()
parameters = {"number": 1}
with self.patchSlap(parameters, True):
received = self.receiveParameters()
self.checkParametersWithDefaults(received, parameters)
def test_jsonschema_json_in_xml_valid_xml_input_full(self):
self.writeJsonSchema()
parameters = {"letter": "b", "number": 1}
with self.patchSlap(parameters, False):
received = self.receiveParameters()
self.checkParametersWithDefaults(received, parameters)
def test_jsonschema_json_in_xml_valid_json_input_full(self):
self.writeJsonSchema()
parameters = {"letter": "b", "number": 1}
with self.patchSlap(parameters, True):
received = self.receiveParameters()
self.checkParametersWithDefaults(received, parameters)
def test_jsonschema_json_in_xml_wrong_type_xml_input(self):
self.writeJsonSchema()
parameters = {"number": "1"}
with self.patchSlap(parameters, False):
self.assertRaises(
slapconfiguration.UserError,
self.receiveParameters,
)
def test_jsonschema_json_in_xml_wrong_type_json_input(self):
self.writeJsonSchema()
parameters = {"number": "1"}
with self.patchSlap(parameters, True):
self.assertRaises(
slapconfiguration.UserError,
self.receiveParameters,
)
def test_jsonschema_json_in_xml_incomplete_xml_input(self):
self.writeJsonSchema()
parameters = {}
with self.patchSlap(parameters, False):
self.assertRaises(
slapconfiguration.UserError,
self.receiveParameters,
)
def test_jsonschema_json_in_xml_incomplete_json_input(self):
self.writeJsonSchema()
parameters = {}
with self.patchSlap(parameters, True):
self.assertRaises(
slapconfiguration.UserError,
self.receiveParameters,
)
def test_jsonschema_shared_1_valid_defaults(self):
self.writeJsonSchema()
parameters = {"number": 1}
shared = [{"kind": 1}]
with self.patchSlap(parameters, True, shared):
valid, invalid = self.receiveParameters(shared=True)
self.assertEqual(invalid, {})
self.assertEqual(list(valid.values()), [{"kind": 1, "thing": "hello"}])
def test_jsonschema_shared_2_valid_defaults(self):
self.writeJsonSchema()
parameters = {"number": 1}
shared = [{"kind": 2}]
with self.patchSlap(parameters, True, shared):
valid, invalid = self.receiveSharedParameters()
self.assertEqual(invalid, {})
self.assertEqual(list(valid.values()), [{"kind": 2, "thing": 42}])
def test_jsonschema_shared_1_invalid_defaults(self):
self.writeJsonSchema(valid_defaults=False)
parameters = {"number": 1, "letter": "a"}
shared = [{"kind": 1}]
with self.patchSlap(parameters, True, shared):
valid, invalid = self.receiveSharedParameters()
self.assertEqual(valid, {})
self.assertEqual(list(invalid.values()), [{"kind": 1, "thing": 1}])
def test_jsonschema_shared_2_invalid_defaults(self):
self.writeJsonSchema(valid_defaults=False)
parameters = {"number": 1, "letter": "a"}
shared = [{"kind": 2}]
with self.patchSlap(parameters, True, shared):
valid, invalid = self.receiveSharedParameters()
self.assertEqual(valid, {})
invalid_values = list(invalid.values())
self.assertEqual(invalid_values, [{"kind": 2, "thing": "forty-two"}])
def test_jsonschema_shared_1_and_2_valid_defaults(self):
self.writeJsonSchema()
parameters = {"number": 1}
shared = [{"kind": 1}, {"kind": 2}]
with self.patchSlap(parameters, True, shared):
valid, invalid = self.receiveSharedParameters()
self.assertEqual(invalid, {})
expected = [{"kind": 1, "thing": "hello"}, {"kind": 2, "thing": 42}]
self.assertEqual(list(valid.values()), expected)
def test_jsonschema_shared_invalid_kind(self):
self.writeJsonSchema()
parameters = {"number": 1}
shared = [{"kind": 3}]
with self.patchSlap(parameters, True, shared):
valid, invalid = self.receiveSharedParameters()
self.assertEqual(valid, {})
self.assertEqual(list(invalid.values()), [{"kind": 3}])
def test_jsonschema_shared_1_invalid_thing(self):
self.writeJsonSchema()
parameters = {"number": 1}
shared = [{"kind": 1, "thing": {}}]
with self.patchSlap(parameters, True, shared):
valid, invalid = self.receiveSharedParameters()
self.assertEqual(valid, {})
self.assertEqual(list(invalid.values()), [{"kind": 1, "thing": {}}])
def test_jsonschema_shared_2_invalid_thing(self):
self.writeJsonSchema()
parameters = {"number": 1}
shared = [{"kind": 2, "thing": {}}]
with self.patchSlap(parameters, True, shared):
valid, invalid = self.receiveSharedParameters()
self.assertEqual(valid, {})
self.assertEqual(list(invalid.values()), [{"kind": 2, "thing": {}}])
def test_jsonschema_shared_valid_and_invalid(self):
self.writeJsonSchema()
parameters = {"number": 1}
shared = [{"kind": 1}, {"kind": 2, "thing": "hello"}]
with self.patchSlap(parameters, True, shared):
valid, invalid = self.receiveParameters(shared=True)
self.assertEqual(list(valid.values()), [{"kind": 1, "thing": "hello"}])
self.assertEqual(list(invalid.values()), [{"kind": 2, "thing": "hello"}])
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment