Source code for stix2generator.test.test_object_generator_object

import pytest

import stix2generator.exceptions


[docs]def test_object(object_generator): value = object_generator.generate_from_spec({ "type": "object", "properties": { "a": 1, "b": 2 } }) assert isinstance(value, dict) assert "a" in value assert "b" in value assert value == {"a": 1, "b": 2}
[docs]def test_object_optional_props(object_generator, num_trials): for _ in range(num_trials): # test with "optional" value = object_generator.generate_from_spec({ "type": "object", "optional": ["b"], "properties": { "a": 1, "b": 2 } }) assert "a" in value assert all(prop_name in ("a", "b") for prop_name in value) # test with "required" value = object_generator.generate_from_spec({ "type": "object", "required": ["a"], "properties": { "a": 1, "b": 2 } }) assert "a" in value assert all(prop_name in ("a", "b") for prop_name in value)
[docs]def test_object_presence_coconstraint_one_required( object_generator, num_trials ): for _ in range(num_trials): value = object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] }, "one": ["group-a"] }, "required": ["group-a"], "properties": { "a": 1, "b": 2 } }) # exactly one of "a" and "b" must be there assert "a" in value or "b" in value assert not ("a" in value and "b" in value)
[docs]def test_object_presence_coconstraint_one_optional( object_generator, num_trials ): for _ in range(num_trials): value = object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] }, "one": ["group-a"] }, "optional": ["group-a"], "properties": { "a": 1, "b": 2 } }) # only "a", only "b", or no properties at all should be there assert ("a" in value and "b" not in value) or \ ("a" not in value and "b" in value) or \ not value
[docs]def test_object_presence_coconstraint_at_least_one_required( object_generator, num_trials ): for _ in range(num_trials): value = object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] }, "at-least-one": ["group-a"] }, "required": ["group-a"], "properties": { "a": 1, "b": 2 } }) # one or both of "a" and "b" must be there assert "a" in value or "b" in value
[docs]def test_object_presence_coconstraint_at_least_one_optional( object_generator, num_trials ): for _ in range(num_trials): value = object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] }, "at-least-one": ["group-a"] }, "optional": ["group-a"], "properties": { "a": 1, "b": 2 } }) # silly case: both, either, or neither of "a" and "b" can be present, # same as making them all optional. Shouldn't write a spec like this, # it's overly complicated. assert all(prop_name in ("a", "b") for prop_name in value)
[docs]def test_object_presence_coconstraint_all_required( object_generator, num_trials ): for _ in range(num_trials): value = object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] }, "all": ["group-a"] }, "required": ["group-a"], "properties": { "a": 1, "b": 2 } }) # silly case: all properties in group-a are required, same as if they # were all individually declared to be required. Shouldn't write a # spec like this, it's overly complicated. assert "a" in value and "b" in value
[docs]def test_object_presence_coconstraint_all_optional( object_generator, num_trials ): for _ in range(num_trials): value = object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] }, "all": ["group-a"] }, "optional": ["group-a"], "properties": { "a": 1, "b": 2 } }) # both or neither of "a" and "b" must be there. assert ("a" in value and "b" in value) or not value
[docs]def test_object_presence_coconstraint_dependencies_props( object_generator, num_trials ): for _ in range(num_trials): value = object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "dependencies": { "a": ["b", "c"] } }, "optional": ["a", "b", "c"], "properties": { "a": 1, "b": 2, "c": 3 } }) # If "a" is present, "b" and "c" must be present. If "a" is not # present, "b" and "c" may or may not be present (since they're # declared optional). if "a" in value: assert "b" in value and "c" in value else: assert all(prop_name in ("b", "c") for prop_name in value)
[docs]def test_object_presence_coconstraint_dependencies_group_key( object_generator, num_trials ): for _ in range(num_trials): value = object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] }, "one": ["group-a"], "dependencies": { "group-a": ["c"] } }, "optional": ["group-a", "c"], "properties": { "a": 1, "b": 2, "c": 3 } }) # If "a" or "b" are present, then "c" must also be present. If neither # "a" nor "b" are present, "c" may or may not be present (since it's # declared optional). if "a" in value or "b" in value: assert "c" in value else: assert "c" in value or not value
[docs]def test_object_presence_coconstraint_dependencies_group_value( object_generator, num_trials ): for _ in range(num_trials): value = object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] }, "one": ["group-a"], "dependencies": { "c": ["group-a"] } }, "optional": ["group-a", "c"], "properties": { "a": 1, "b": 2, "c": 3 } }) # If "c" is present, then exactly one of "a" or "b" must be present. # If "c" is not present, then exactly one or neither of "a" and "b" # must be present (since group-a is declared optional). if "c" in value: assert "a" in value or "b" in value else: assert "a" in value or "b" in value or not value
[docs]def test_object_presence_coconstraint_dependencies_group_key_and_value( object_generator, num_trials ): for _ in range(num_trials): value = object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"], "group-b": ["c", "d"] }, "one": ["group-a"], "all": ["group-b"], "dependencies": { "group-a": ["group-b"] } }, "optional": ["group-a", "group-b"], "properties": { "a": 1, "b": 2, "c": 3, "d": 4 } }) # If exactly one of "a" or "b" is present, then both of "c" and "d" # must be present. If neither "a" nor "b" is present, then neither or # both of "c" and "d" may be present. if "a" in value or "b" in value: assert "c" in value and "d" in value else: assert ("c" in value and "d" in value) or not value
[docs]def test_object_presence_coconstraint_errors1(object_generator): with pytest.raises(stix2generator.exceptions.PresenceCoconstraintError): object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { # refer to undefined property in group "group-a": ["a", "c"] }, "one": ["group-a"] }, "properties": { "a": 1, "b": 2 } })
[docs]def test_object_presence_coconstraint_errors2(object_generator): with pytest.raises(stix2generator.exceptions.PresenceCoconstraintError): object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] }, # refer to undefined group in co-constraint "one": ["group-b"] }, "properties": { "a": 1, "b": 2 } })
[docs]def test_object_presence_coconstraint_errors3(object_generator): with pytest.raises(stix2generator.exceptions.PresenceCoconstraintError): object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "dependencies": { # refer to undefined property as value "a": ["b", "c"] } }, "properties": { "a": 1, "b": 2 } })
[docs]def test_object_presence_coconstraint_errors4(object_generator): with pytest.raises(stix2generator.exceptions.PresenceCoconstraintError): object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "dependencies": { # refer to undefined property as key "c": ["a", "b"] } }, "properties": { "a": 1, "b": 2 } })
[docs]def test_object_presence_coconstraint_errors5(object_generator): with pytest.raises(stix2generator.exceptions.PresenceCoconstraintError): object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] }, "one": ["group-a"], "dependencies": { # refer to undefined group as value "c": ["group-b"] } }, "properties": { "a": 1, "b": 2, "c": 3 } })
[docs]def test_object_presence_coconstraint_errors6(object_generator): with pytest.raises(stix2generator.exceptions.PresenceCoconstraintError): object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] }, "one": ["group-a"], "dependencies": { # refer to undefined group as key "group-b": ["c"] } }, "properties": { "a": 1, "b": 2, "c": 3 } })
[docs]def test_object_presence_coconstraint_errors7(object_generator): with pytest.raises(stix2generator.exceptions.PresenceCoconstraintError): object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] } # group-a is missing its constraint }, "properties": { "a": 1, "b": 2 } })
[docs]def test_object_presence_coconstraint_errors8(object_generator): with pytest.raises(stix2generator.exceptions.PresenceCoconstraintError): object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"], # groups can't overlap "group-b": ["b", "c"] }, "one": ["group-a", "group-b"] }, "properties": { "a": 1, "b": 2, "c": 3 } })
[docs]def test_object_presence_coconstraint_errors9(object_generator): with pytest.raises(stix2generator.exceptions.PresenceCoconstraintError): object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] }, "one": ["group-a"], "dependencies": { # can't directly refer to grouped properties "a": ["group-a"] } }, "properties": { "a": 1, "b": 2 } })
[docs]def test_object_presence_coconstraint_errors10(object_generator): with pytest.raises(stix2generator.exceptions.ObjectGenerationError): object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { "group-a": ["a", "b"] }, "one": ["group-a"] }, # can't directly refer to grouped properties "required": ["a"], "properties": { "a": 1, "b": 2 } })
[docs]def test_object_presence_coconstraint_errors11(object_generator): with pytest.raises(stix2generator.exceptions.PresenceCoconstraintError): object_generator.generate_from_spec({ "type": "object", "presence-coconstraints": { "property-groups": { # can't name a group the same as a property "a": ["b", "c"] }, "one": ["a"] }, "properties": { "a": 1, "b": 2, "c": 3 } })
[docs]def test_object_value_coconstraint(object_generator): object_generator.generate_from_spec({ "type": "object", # Value co-constraints currently only used in certain semantics; # they will be ignored in this spec. Just check for errors. "value-coconstraints": [ "a < b", "a <= b", "a > b", "a >= b", "a = b", "a != b" ], "properties": { "a": 1, "b": 2 } })
[docs]def test_object_value_coconstraint_bad_operator(object_generator): with pytest.raises(stix2generator.exceptions.ValueCoconstraintError): object_generator.generate_from_spec({ "type": "object", # invalid operator "value-coconstraints": ["a $ b"], "properties": { "a": 1, "b": 2 } })
[docs]def test_object_value_coconstraint_bad_property(object_generator): with pytest.raises(stix2generator.exceptions.ValueCoconstraintError): object_generator.generate_from_spec({ "type": "object", # undefined property name "value-coconstraints": ["a = x"], "properties": { "a": 1, "b": 2 } })
[docs]def test_object_value_coconstraint_self_relation(object_generator): with pytest.raises(stix2generator.exceptions.ValueCoconstraintError): object_generator.generate_from_spec({ "type": "object", # can't relate a prop to itself "value-coconstraints": ["a = a"], "properties": { "a": 1, "b": 2 } })