def test_basic_proto(self): xtarget = XProtoTestHelpers.write_tmp_target("{{ proto }}") xproto = """ message Person { required string name = 1; required int32 id = 2; // Unique ID number for this person. optional string email = 3 [symphony = "da da da dum"]; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } required string number = 1; optional PhoneType type = 2; repeated PhoneNumber phones = 4; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = xtarget output = XOSProcessor.process(args) self.assertIn("PhoneNumber", output)
def test_controller_network_policy(self): xproto = """ policy test_policy < ctx.user.is_admin | (exists Privilege: Privilege.accessor_id = ctx.user.id & Privilege.accessor_type = "User" & Privilege.object_type = "Slice" & Privilege.object_id = obj.owner.id) | (exists Privilege: Privilege.accessor_id = ctx.user.id & Privilege.accessor_type = "User" & Privilege.object_type = "Site" & Privilege.object_id = obj.owner.site.id & Privilege.permission = "role:admin") > """ args = XOSProcessorArgs() args.inputs = xproto args.target = self.target output = XOSProcessor.process(args) exec(output) # This loads the generated function, which should look like this: """ def policy_output_enforcer(obj, ctx): i2 = ctx.user.is_admin i4 = Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(object_type='Slice'), Q(object_id=obj.owner.id))[0] i5 = Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(object_type='Site'), Q(object_id=obj.owner.site.id), Q(permission='role:admin'))[0] i3 = (i4 or i5) i1 = (i2 or i3) return i1 """ # FIXME: Test this policy by executing it self.assertTrue(policy_output_enforcer is not None)
def test_pluralize(self): proto = """ message TestPluralize { // The following field has an explicitly specified plural required int anecdote = 1 [plural = "data"]; // The following fields have automatically computed plurals required int sheep = 2; required int slice = 2; required int network = 2; required int omf_friendly = 2; } """ target = XProtoTestHelpers.write_tmp_target( """ {% for m in proto.messages.0.fields -%} {{ xproto_pluralize(m) }}, {%- endfor %} """ ) args = XOSProcessorArgs() args.inputs = proto args.target = target output = XOSProcessor.process(args) self.assertEqual( "data,sheep,slices,networks,omf_friendlies", output.lstrip().rstrip().rstrip(","), )
def test_slice_name_validation(self): xproto = """ policy test_policy < not obj.id -> {{ obj.name.startswith(obj.site.login_base) }} > """ args = XOSProcessorArgs() args.inputs = xproto args.target = self.target output = XOSProcessor.process(args) obj = FakeObject() obj.isolation = "container" obj.kind = "not a container" exec(output) # This loads the generated function, which should look like this: """ def policy_output_validator(obj, ctx): i3 = obj.id i4 = obj.name.startswith(obj.site.login_base) i2 = ((not i3) or i4) i1 = (not i2) if (not i1): raise ValidationError('Necessary Failure') """ with self.assertRaises(Exception): policy_output_validator(obj, {})
def test_equal(self): xproto = """ policy test_policy < not (ctx.user = obj.user) > """ args = XOSProcessorArgs() args.inputs = xproto args.target = self.target output = XOSProcessor.process(args) exec(output) # This loads the generated function, which should look like this: """ def policy_output_validator(obj, ctx): i2 = (ctx.user == obj.user) i1 = (not i2) if (not i1): raise Exception('Necessary Failure') """ obj = FakeObject() obj.user = 1 ctx = FakeObject() ctx.user = 1 with self.assertRaises(Exception): policy_output_validator(obj, ctx)
def test_instance_container(self): xproto = """ policy test_policy < (obj.isolation = "container" | obj.isolation = "container_vm" ) -> (obj.image.kind = "container") > """ args = XOSProcessorArgs() args.inputs = xproto args.target = self.target output = XOSProcessor.process(args) obj = FakeObject() obj.isolation = "container" obj.kind = "not a container" exec(output) # This loads the generated function, which should look like this: """ def policy_output_validator(obj, ctx): i4 = (obj.isolation == 'container') i5 = (self.isolation == 'container_vm') i2 = (i4 or i5) i3 = (obj.image.kind == 'container') i1 = (i2 or i3) return i1 """ with self.assertRaises(Exception): policy_output_validator(obj, {})
def test_max_length_zero(self): args = XOSProcessorArgs() args.files = ["/tmp/testvalidator.xproto"] open("/tmp/testvalidator.xproto", "w").write(""" option app_label = "test"; message Port (XOSBase){ required string foo = 1 [max_length=0]; } """) args.target = "modeldefs.xtarget" with patch.object(XProtoValidator, "print_errors", autospec=True) as print_errors: print_errors.return_value = None output = XOSProcessor.process(args) self.assertEqual(print_errors.call_count, 1) validator = print_errors.call_args[0][0] self.assertEqual(len(validator.errors), 1) self.assertEqual(validator.errors[0]["severity"], "ERROR") self.assertEqual(validator.errors[0]["message"], "max_length should not be zero")
def test_package_fqn(self): args = XOSProcessorArgs() target = XProtoTestHelpers.write_tmp_target( """ {% for m in proto.messages %} {{ m.name }},{{ m.package }},{{ m.fqn }} {% endfor %} """ ) xproto = """ package xos.core; message Port (PlCoreBase,ParameterMixin) { required manytoone network->Network:links = 1 [db_index = True, null = False, blank = False]; optional manytoone instance->Instance:ports = 2 [db_index = True, null = True, blank = True]; optional string ip = 3 [max_length = 39, content_type = "ip", blank = True, help_text = "Instance ip address", null = True, db_index = False]; optional string port_id = 4 [help_text = "Neutron port id", max_length = 256, null = True, db_index = False, blank = True]; optional string mac = 5 [help_text = "MAC address associated with this port", max_length = 256, null = True, db_index = False, blank = True]; required bool xos_created = 6 [default = False, null = False, db_index = False, blank = True]; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = target output = XOSProcessor.process(args) self.assertIn("Port,xos.core,xos.core.Port", output)
def test_one_to_many_in_modeldef(self): xproto = """ option app_label = "test"; message ServiceDependency { required manytoone provider_service->Service:provided_dependencies = 1; required manytoone subscriber_service->Service:subscribed_dependencies = 2; } message Service { required string name = 1; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = "modeldefs.xtarget" output = XOSProcessor.process(args) # Service deps model self.assertIn( "{model: Service, type: manytoone, on_field: provider_service}", output) self.assertIn( "{model: Service, type: manytoone, on_field: provider_service}", output) # Service model self.assertIn( "{model: ServiceDependency, type: onetomany, on_field: provider_service}", output, ) self.assertIn( "{model: ServiceDependency, type: onetomany, on_field: provider_service}", output, )
def test_one_to_many_in_modeldef(self): xproto = """ option app_label = "test"; message ServiceDependency { required manytoone provider_service->Service:provided_dependencies = 1; required manytoone subscriber_service->Service:subscribed_dependencies = 2; } message Service { required string name = 1; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = "modeldefs.xtarget" output = XOSProcessor.process(args) # Service deps model self.assertIn( "{model: Service, type: manytoone, on_field: provider_service}", output ) self.assertIn( "{model: Service, type: manytoone, on_field: provider_service}", output ) # Service model self.assertIn( "{model: ServiceDependency, type: onetomany, on_field: provider_service}", output, ) self.assertIn( "{model: ServiceDependency, type: onetomany, on_field: provider_service}", output, )
def test_bin(self): xproto = """ policy output < (ctx.is_admin = True | obj.empty = True) | False> """ args = XOSProcessorArgs() args.inputs = xproto args.target = self.target output = XOSProcessor.process(args) exec( output ) # This loads the generated function, which should look like this: """ def policy_output_validator(obj, ctx): i2 = (ctx.is_admin == True) i3 = (obj.empty == True) i1 = (i2 or i3) if (not i1): raise Exception('Necessary Failure') """ obj = FakeObject() obj.empty = False ctx = FakeObject() ctx.is_admin = False with self.assertRaises(Exception): verdict = policy_output_validator(obj, ctx)
def test_singularize(self): proto = """ message TestSingularize { // The following field has an explicitly specified singular required int many = 1 [singular = "one"]; // The following fields have automatically computed singulars required int sheep = 2; required int slices = 2; required int networks = 2; required int omf_friendlies = 2; } """ target = XProtoTestHelpers.write_tmp_target( """ {% for m in proto.messages.0.fields -%} {{ xproto_singularize(m) }}, {%- endfor %} """ ) args = XOSProcessorArgs() args.inputs = proto args.target = target output = XOSProcessor.process(args) self.assertEqual( "one,sheep,slice,network,omf_friendly", output.lstrip().rstrip().rstrip(",") )
def generate(self, client): log.info("[XOS-TOSCA] Generating TOSCA") try: xproto = client.utility.GetXproto(Empty()) args = XOSProcessorArgs( output=TOSCA_DEFS_DIR, inputs=str(xproto.xproto), target=os.path.join(current_dir, "xtarget/tosca.xtarget"), write_to_file="target", ) XOSProcessor.process(args) log.info("[XOS-TOSCA] Recipes generated in %s" % args.output) except Exception: log.exception("[XOS-TOSCA] Failed to generate TOSCA") try: xproto = client.utility.GetXproto(Empty()) args = XOSProcessorArgs( output=TOSCA_KEYS_DIR, inputs=str(xproto.xproto), target=os.path.join(current_dir, "xtarget/tosca_keys.xtarget"), write_to_file="single", dest_file="KEYS.py", ) XOSProcessor.process(args) log.info("[XOS-TOSCA] TOSCA Keys generated in %s" % args.output) except Exception: log.exception("[XOS-TOSCA] Failed to generate TOSCA Keys")
def test_bin(self): xproto = """ policy output < (ctx.is_admin = True | obj.empty = True) | False> """ args = XOSProcessorArgs() args.inputs = xproto args.target = self.target output = XOSProcessor.process(args) exec(output) # This loads the generated function, which should look like this: """ def policy_output_validator(obj, ctx): i2 = (ctx.is_admin == True) i3 = (obj.empty == True) i1 = (i2 or i3) if (not i1): raise Exception('Necessary Failure') """ obj = FakeObject() obj.empty = False ctx = FakeObject() ctx.is_admin = False with self.assertRaises(Exception): verdict = policy_output_validator(obj, ctx)
def generate_core_models(core_dir): core_xproto = os.path.join(core_dir, "core.xproto") args = XOSProcessorArgs( output=core_dir, target="django.xtarget", dest_extension="py", write_to_file="model", files=[core_xproto], ) XOSProcessor.process(args) security_args = XOSProcessorArgs( output=core_dir, target="django-security.xtarget", dest_file="security.py", write_to_file="single", files=[core_xproto], ) XOSProcessor.process(security_args) init_args = XOSProcessorArgs( output=core_dir, target="init.xtarget", dest_file="__init__.py", write_to_file="single", files=[core_xproto], ) XOSProcessor.process(init_args)
def test_user_policy(self): xproto = """ policy test_policy < ctx.user.is_admin | ctx.user.id = obj.id | (exists Privilege: Privilege.accessor_id = ctx.user.id & Privilege.accessor_type = "User" & Privilege.permission = "role:admin" & Privilege.object_type = "Site" & Privilege.object_id = ctx.user.site.id) > """ args = XOSProcessorArgs() args.inputs = xproto args.target = self.target output = XOSProcessor.process(args) exec( output ) # This loads the generated function, which should look like this: """ def policy_output_enforcer(obj, ctx): i2 = ctx.user.is_admin i4 = (ctx.user.id == obj.id) i5 = Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(permission='role:admin'), Q(object_type='Site'), Q(object_id=ctx.user.site.id))[0] i3 = (i4 or i5) i1 = (i2 or i3) return i1 """ # FIXME: Test this policy by executing it self.assertTrue(policy_output_enforcer is not None)
def test_base_class_fields(self): target = XProtoTestHelpers.write_tmp_target( """ {% for m in proto.messages %} {{ m.name }} { {%- for b in m.bases %} {%- if proto.message_table[b.fqn] -%} {%- set model = proto.message_table[b.fqn] %} {% for f in model.fields %} {{ f.type }} {{ f.name }}; {% endfor %} {%- endif -%} {% endfor %} } {% endfor %} """ ) xproto = """ package xos.network; message Port (PlCoreBase,ParameterMixin){ required manytoone network->Network:links = 1 [db_index = True, null = False, blank = False]; optional manytoone instance->Instance:ports = 2 [db_index = True, null = True, blank = True]; optional string ip = 3 [max_length = 39, content_type = "ip", blank = True, help_text = "Instance ip address", null = True, db_index = False]; optional string port_id = 4 [help_text = "Neutron port id", max_length = 256, null = True, db_index = False, blank = True]; optional string mac = 5 [help_text = "MAC address associated with this port", max_length = 256, null = True, db_index = False, blank = True]; required bool xos_created = 6 [default = False, null = False, db_index = False, blank = True]; } package xos.someotherpackage; message Instance (xos.network.Port){ optional string instance_id = 1 [max_length = 200, content_type = "stripped", blank = True, help_text = "Nova instance id", null = True, db_index = False]; optional string instance_uuid = 2 [max_length = 200, content_type = "stripped", blank = True, help_text = "Nova instance uuid", null = True, db_index = False]; required string name = 3 [max_length = 200, content_type = "stripped", blank = False, help_text = "Instance name", null = False, db_index = False]; optional string instance_name = 4 [max_length = 200, content_type = "stripped", blank = True, help_text = "OpenStack generated name", null = True, db_index = False]; optional string ip = 5 [max_length = 39, content_type = "ip", blank = True, help_text = "Instance ip address", null = True, db_index = False]; required manytoone image->Image:instances = 6 [db_index = True, null = False, blank = False]; optional manytoone creator->User:instances = 7 [db_index = True, null = True, blank = True]; required manytoone slice->Slice:instances = 8 [db_index = True, null = False, blank = False]; required manytoone deployment->Deployment:instance_deployment = 9 [db_index = True, null = False, blank = False]; required manytoone node->Node:instances = 10 [db_index = True, null = False, blank = False]; required int32 numberCores = 11 [help_text = "Number of cores for instance", default = 0, null = False, db_index = False, blank = False]; required manytoone flavor->Flavor:instance = 12 [help_text = "Flavor of this instance", default = "get_default_flavor()", null = False, db_index = True, blank = False]; optional string userData = 13 [help_text = "user_data passed to instance during creation", null = True, db_index = False, blank = True]; required string isolation = 14 [default = "vm", choices = "(('vm', 'Virtual Machine'), ('container', 'Container'), ('container_vm', 'Container In VM'))", max_length = 30, blank = False, null = False, db_index = False]; optional string volumes = 15 [help_text = "Comma-separated list of directories to expose to parent context", null = True, db_index = False, blank = True]; optional manytoone parent->Instance:instance = 16 [help_text = "Parent Instance for containers nested inside of VMs", null = True, db_index = True, blank = True]; required manytomany tags->Tag = 17 [db_index = False, null = False, blank = True]; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = target output = XOSProcessor.process(args) self.assertIn("xos_created", output)
def test_xproto_lib(self): target = XProtoTestHelpers.write_tmp_target(""" {{ xproto_first_non_empty([None, None, None, None, None, None, "Eureka"]) }} """) args = XOSProcessorArgs() args.inputs = "" args.target = target output = XOSProcessor.process(args) self.assertIn("Eureka", output)
def test_base_class_fields(self): target = XProtoTestHelpers.write_tmp_target(""" {% for m in proto.messages %} {{ m.name }} { {%- for b in m.bases %} {%- if proto.message_table[b.fqn] -%} {%- set model = proto.message_table[b.fqn] %} {% for f in model.fields %} {{ f.type }} {{ f.name }}; {% endfor %} {%- endif -%} {% endfor %} } {% endfor %} """) xproto = """ package xos.network; message Port (PlCoreBase,ParameterMixin){ required manytoone network->Network:links = 1 [db_index = True, null = False, blank = False]; optional manytoone instance->Instance:ports = 2 [db_index = True, null = True, blank = True]; optional string ip = 3 [max_length = 39, content_type = "ip", blank = True, help_text = "Instance ip address", null = True, db_index = False]; optional string port_id = 4 [help_text = "Neutron port id", max_length = 256, null = True, db_index = False, blank = True]; optional string mac = 5 [help_text = "MAC address associated with this port", max_length = 256, null = True, db_index = False, blank = True]; required bool xos_created = 6 [default = False, null = False, db_index = False, blank = True]; } package xos.someotherpackage; message Instance (xos.network.Port){ optional string instance_id = 1 [max_length = 200, content_type = "stripped", blank = True, help_text = "Nova instance id", null = True, db_index = False]; optional string instance_uuid = 2 [max_length = 200, content_type = "stripped", blank = True, help_text = "Nova instance uuid", null = True, db_index = False]; required string name = 3 [max_length = 200, content_type = "stripped", blank = False, help_text = "Instance name", null = False, db_index = False]; optional string instance_name = 4 [max_length = 200, content_type = "stripped", blank = True, help_text = "OpenStack generated name", null = True, db_index = False]; optional string ip = 5 [max_length = 39, content_type = "ip", blank = True, help_text = "Instance ip address", null = True, db_index = False]; required manytoone image->Image:instances = 6 [db_index = True, null = False, blank = False]; optional manytoone creator->User:instances = 7 [db_index = True, null = True, blank = True]; required manytoone slice->Slice:instances = 8 [db_index = True, null = False, blank = False]; required manytoone deployment->Deployment:instance_deployment = 9 [db_index = True, null = False, blank = False]; required manytoone node->Node:instances = 10 [db_index = True, null = False, blank = False]; required int32 numberCores = 11 [help_text = "Number of cores for instance", default = 0, null = False, db_index = False, blank = False]; required manytoone flavor->Flavor:instance = 12 [help_text = "Flavor of this instance", default = "get_default_flavor()", null = False, db_index = True, blank = False]; optional string userData = 13 [help_text = "user_data passed to instance during creation", null = True, db_index = False, blank = True]; required string isolation = 14 [default = "vm", choices = "(('vm', 'Virtual Machine'), ('container', 'Container'), ('container_vm', 'Container In VM'))", max_length = 30, blank = False, null = False, db_index = False]; optional string volumes = 15 [help_text = "Comma-separated list of directories to expose to parent context", null = True, db_index = False, blank = True]; optional manytoone parent->Instance:instance = 16 [help_text = "Parent Instance for containers nested inside of VMs", null = True, db_index = True, blank = True]; required manytomany tags->Tag = 17 [db_index = False, null = False, blank = True]; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = target output = XOSProcessor.process(args) self.assertIn("xos_created", output)
def test_context(self): target = XProtoTestHelpers.write_tmp_target(""" {{ context.what }} """) args = XOSProcessorArgs() args.inputs = "" args.target = target args.kv = "what:what is what" output = XOSProcessor.process(args) self.assertIn("what is what", output)
def generate_service_models(service_dir, service_dest_dir, service_name): """ Generate the django code starting from xProto for a given service. :param service_dir: string (path to the folder) :param service_name: string (name of the service) :return: void """ sync_dir = os.path.join(service_dir, "xos/synchronizer/models") xprotos = find_xproto_in_folder(sync_dir) decls = find_decls_models(sync_dir) log.debug("Generating models for %s from files %s" % (service_name, ", ".join(xprotos))) out_dir = os.path.join(service_dest_dir, service_name) if not os.path.isdir(out_dir): os.mkdir(out_dir) args = XOSProcessorArgs( output=out_dir, files=xprotos, target="service.xtarget", write_to_file="target", ) XOSProcessor.process(args) security_args = XOSProcessorArgs( output=out_dir, target="django-security.xtarget", dest_file="security.py", write_to_file="single", files=xprotos, ) XOSProcessor.process(security_args) init_py_filename = os.path.join(out_dir, "__init__.py") if not os.path.exists(init_py_filename): open(init_py_filename, "w").write("# created by dynamicbuild") # copy over models.py files from the service if len(decls) > 0: for file in decls: fn = os.path.basename(file) src_fn = file dest_fn = os.path.join(out_dir, fn) log.debug("Copying models.py from %s to %s" % (src_fn, dest_fn)) shutil.copyfile(src_fn, dest_fn) # copy existing migrations from the service, otherwise they won't be incremental src_dir = os.path.join(service_dir, "xos", "synchronizer", "migrations") if os.path.isdir(src_dir): dest_dir = os.path.join(out_dir, "migrations") if os.path.isdir(dest_dir): shutil.rmtree( dest_dir) # empty the folder, we'll copy everything again shutil.copytree(src_dir, dest_dir)
def test_pure_policies(self): xproto = """ policy my_policy < exists x:a=b > """ proto = """ option my_policy = "policy:< exists x:a=b >"; """ target = XProtoTestHelpers.write_tmp_target( """ {{ policies }} """ ) args_xproto = XOSProcessorArgs() args_xproto.inputs = xproto args_xproto.target = target xproto_gen = XOSProcessor.process(args_xproto) args_proto = XOSProcessorArgs() args_proto.inputs = proto args_proto.target = target args_proto.rev = True proto_gen = XOSProcessor.process(args_proto) self.assertEqual(proto_gen, xproto_gen)
def test_slice_policy(self): xproto = """ policy site_policy < ctx.user.is_admin | (ctx.write_access -> exists Privilege: Privilege.object_type = "Site" & Privilege.object_id = obj.id & Privilege.accessor_id = ctx.user.id & Privilege.permission_id = "role:admin") > policy test_policy < ctx.user.is_admin | (*site_policy(site) & ((exists Privilege: Privilege.accessor_id = ctx.user.id & Privilege.accessor_type = "User" & Privilege.object_type = "Slice" & Privilege.object_id = obj.id & (ctx.write_access->Privilege.permission="role:admin")) | (exists Privilege: Privilege.accessor_id = ctx.user.id & Privilege.accessor_type = "User" & Privilege.object_type = "Site" & Privilege.object_id = obj.site.id & Privilege.permission = "role:admin")) )> """ args = XOSProcessorArgs() args.inputs = xproto args.target = self.target output = XOSProcessor.process(args) exec( output ) # This loads the generated function, which should look like this: """ def policy_output_enforcer(obj, ctx): i2 = ctx.user.is_admin i4 = policy_site_policy_enforcer(obj.site, ctx) i10 = ctx.write_access i11 = (not (not Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(object_type='Slice'), Q(object_id=obj.id), Q(permission='role:admin')))) i8 = (i10 and i11) i14 = ctx.write_access i12 = (not i14) i13 = (not (not Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(object_type='Slice'), Q(object_id=obj.id)))) i9 = (i12 and i13) i6 = (i8 or i9) i7 = (not (not Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(object_type='Site'), Q(object_id=obj.site.id), Q(permission='role:admin')))) i5 = (i6 or i7) i3 = (i4 and i5) i1 = (i2 or i3) return i1 """ # FIXME: Test this policy by executing it self.assertTrue(policy_output_enforcer is not None)
def test_xproto_lib(self): target = XProtoTestHelpers.write_tmp_target( """ {{ xproto_first_non_empty([None, None, None, None, None, None, "Eureka"]) }} """ ) args = XOSProcessorArgs() args.inputs = "" args.target = target output = XOSProcessor.process(args) self.assertIn("Eureka", output)
def test_slice_policy(self): xproto = """ policy site_policy < ctx.user.is_admin | (ctx.write_access -> exists Privilege: Privilege.object_type = "Site" & Privilege.object_id = obj.id & Privilege.accessor_id = ctx.user.id & Privilege.permission_id = "role:admin") > policy test_policy < ctx.user.is_admin | (*site_policy(site) & ((exists Privilege: Privilege.accessor_id = ctx.user.id & Privilege.accessor_type = "User" & Privilege.object_type = "Slice" & Privilege.object_id = obj.id & (ctx.write_access->Privilege.permission="role:admin")) | (exists Privilege: Privilege.accessor_id = ctx.user.id & Privilege.accessor_type = "User" & Privilege.object_type = "Site" & Privilege.object_id = obj.site.id & Privilege.permission = "role:admin")) )> """ args = XOSProcessorArgs() args.inputs = xproto args.target = self.target output = XOSProcessor.process(args) exec(output) # This loads the generated function, which should look like this: """ def policy_output_enforcer(obj, ctx): i2 = ctx.user.is_admin i4 = policy_site_policy_enforcer(obj.site, ctx) i10 = ctx.write_access i11 = (not (not Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(object_type='Slice'), Q(object_id=obj.id), Q(permission='role:admin')))) i8 = (i10 and i11) i14 = ctx.write_access i12 = (not i14) i13 = (not (not Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(object_type='Slice'), Q(object_id=obj.id)))) i9 = (i12 and i13) i6 = (i8 or i9) i7 = (not (not Privilege.objects.filter(Q(accessor_id=ctx.user.id), Q(accessor_type='User'), Q(object_type='Site'), Q(object_id=obj.site.id), Q(permission='role:admin')))) i5 = (i6 or i7) i3 = (i4 and i5) i1 = (i2 or i3) return i1 """ # FIXME: Test this policy by executing it self.assertTrue(policy_output_enforcer is not None)
def test_message_base(self): xtarget = XProtoTestHelpers.write_tmp_target("{{ proto.messages.0.bases }}") xproto = """ message base(Base) { } """ args = XOSProcessorArgs() args.inputs = xproto args.target = xtarget output = XOSProcessor.process(args) self.assertIn("Base", output)
def test_context(self): target = XProtoTestHelpers.write_tmp_target( """ {{ context.what }} """ ) args = XOSProcessorArgs() args.inputs = "" args.target = target args.kv = "what:what is what" output = XOSProcessor.process(args) self.assertIn("what is what", output)
def test_constant(self): xproto = """ policy true_policy < True > """ target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.true_policy }}") args = XOSProcessorArgs() args.inputs = xproto args.target = target output = XOSProcessor.process(args).replace("t", "T") self.assertTrue(eval(output))
def test_message_base(self): xtarget = XProtoTestHelpers.write_tmp_target( "{{ proto.messages.0.bases }}") xproto = """ message base(Base) { } """ args = XOSProcessorArgs() args.inputs = xproto args.target = xtarget output = XOSProcessor.process(args) self.assertIn("Base", output)
def test_file_methods(self): target = XProtoTestHelpers.write_tmp_target(""" {%% if file_exists("%s") %%} {{ include_file("%s") }} {%% endif %%} """ % (TEST_FILE, TEST_FILE)) args = XOSProcessorArgs() args.inputs = "" args.target = target args.attic = OUTPUT_DIR output = XOSProcessor.process(args) self.assertIn(TEST_OUTPUT, output)
def test_through_extensions(self): xtarget = XProtoTestHelpers.write_tmp_target( "{{ proto.messages.0.links.0.through }}") xproto = """ message links { required manytomany vrouter_service->VRouterService/ServiceProxy:device_ports = 4 [db_index = True, null = False, blank = False]; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = xtarget output = XOSProcessor.process(args) self.assertIn("ServiceProxy", output)
def test_message_options(self): xtarget = XProtoTestHelpers.write_tmp_target( "{{ proto.messages.0.options.type }}") xproto = """ message link { option type = "e1000"; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = xtarget output = XOSProcessor.process(args) self.assertIn("e1000", output)
def test_link_extensions(self): xtarget = XProtoTestHelpers.write_tmp_target("{{ proto.messages.0.links }}") xproto = """ message links { required manytoone vrouter_service->VRouterService:device_ports = 4 [db_index = True, null = False, blank = False]; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = xtarget output = XOSProcessor.process(args) self.assertIn("VRouterService", output)
def test_not_default_value_in_modeldef(self): xproto = """ option app_label = "test"; message Foo { required string name = 1 [ null = "False", blank="False"]; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = "modeldefs.xtarget" output = XOSProcessor.process(args) self.assertNotIn("default:", output)
def test_policy_missing_function(self): xproto = """ policy slice_policy < exists Privilege: Privilege.object_id = obj.id > policy network_slice_policy < *slice_policyX(slice) > """ target = XProtoTestHelpers.write_tmp_target( "{{ proto.policies.network_slice_policy }} ") args = XOSProcessorArgs() args.inputs = xproto args.target = target with self.assertRaises(Exception): output = XOSProcessor.process(args)
def test_global_options(self): xtarget = XProtoTestHelpers.write_tmp_target("{{ options }}") xproto = """ option kind = "vsg"; option verbose_name = "vSG Service"; """ args = XOSProcessorArgs() args.inputs = xproto args.target = xtarget output = XOSProcessor.process(args) self.assertIn("vsg", output) self.assertIn("vSG Service", output)
def test_constant(self): xproto = """ policy true_policy < True > """ target = XProtoTestHelpers.write_tmp_target( "{{ proto.policies.true_policy }}") args = XOSProcessorArgs() args.inputs = xproto args.target = target output = XOSProcessor.process(args).replace("t", "T") self.assertTrue(eval(output))
def test_message_options(self): xtarget = XProtoTestHelpers.write_tmp_target( "{{ proto.messages.0.options.type }}" ) xproto = """ message link { option type = "e1000"; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = xtarget output = XOSProcessor.process(args) self.assertIn("e1000", output)
def test_policy_missing_function(self): xproto = """ policy slice_policy < exists Privilege: Privilege.object_id = obj.id > policy network_slice_policy < *slice_policyX(slice) > """ target = XProtoTestHelpers.write_tmp_target( "{{ proto.policies.network_slice_policy }} " ) args = XOSProcessorArgs() args.inputs = xproto args.target = target with self.assertRaises(Exception): output = XOSProcessor.process(args)
def test_forall(self): # This one we only parse xproto = """ policy instance < forall Instance: exists Credential: Credential.obj_id = Instance.obj_id > """ target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.instance }}") args = XOSProcessorArgs() args.inputs = xproto args.target = target output = XOSProcessor.process(args) (op, operands), = eval(output).items() self.assertEqual(op, "forall")
def test_call_policy(self): xproto = """ policy sub_policy < ctx.user = obj.user > policy output < *sub_policy(child) > """ args = XOSProcessorArgs(inputs=xproto, target=self.target) output = XOSProcessor.process(args) exec(output, globals( )) # This loads the generated function, which should look like this: """ def policy_sub_policy_validator(obj, ctx): i1 = (ctx.user == obj.user) if (not i1): raise ValidationError('Necessary Failure') def policy_output_validator(obj, ctx): i1 = policy_sub_policy_validator(obj.child, ctx) if (not i1): raise ValidationError('Necessary Failure') """ obj = FakeObject() obj.child = FakeObject() obj.child.user = 1 ctx = FakeObject() ctx.user = 1 with self.assertRaises(Exception): verdict = policy_output_enforcer(obj, ctx)
def test_file_methods(self): target = XProtoTestHelpers.write_tmp_target( """ {%% if file_exists("%s") %%} {{ include_file("%s") }} {%% endif %%} """ % (TEST_FILE, TEST_FILE) ) args = XOSProcessorArgs() args.inputs = "" args.target = target args.attic = OUTPUT_DIR output = XOSProcessor.process(args) self.assertIn(TEST_OUTPUT, output)
def test_optional_relations(self): """ [XOS-GenX] Generate DJANGO models, verify relations """ xproto = """ option app_label = "test"; message ENodeB { } message Handover { } message Foo { optional manytoone enodeb->ENodeB:profiles = 1 [null = True, blank = True]; required manytoone handover->Handover:profiles = 2 [null = False, blank = False]; } """ args = XOSProcessorArgs(inputs=xproto, target="django.xtarget") output = XOSProcessor.process(args) null_true = [s for s in output.splitlines() if "null = True" in s] null_false = [s for s in output.splitlines() if "null = False" in s] blank_true = [s for s in output.splitlines() if "blank = True" in s] blank_false = [s for s in output.splitlines() if "blank = False" in s] self.assertEqual(len(null_true), 1) self.assertEqual(len(null_false), 1) self.assertEqual(len(blank_true), 1) self.assertEqual(len(blank_false), 1)
def test_generator_custom_target_from_file(self): """ [XOS-GenX] Generate output from base.xproto """ args = XOSProcessorArgs(files=[TEST_XPROTO], target=TEST_TARGET) output = XOSProcessor.process(args) self.assertEqual(output, TEST_EXPECTED_OUTPUT)
def test_static_options(self): xproto = """ option app_label = "test"; message Foo { required string name = 1 [ null = "False", blank="False"]; required string isolation = 14 [default = "vm", choices = "(('vm', 'Virtual Machine'), ('container', 'Container'), ('container_vm', 'Container In VM'))", max_length = 30, blank = False, null = False, db_index = False]; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = "modeldefs.xtarget" output = XOSProcessor.process(args) self.assertIn("options:", output) self.assertIn(" {'id': 'container_vm', 'label': 'Container In VM'}", output)
def test_unfiltered(self): """ With no include_* args, should get all models """ args = XOSProcessorArgs(files=[FILTERTEST_XPROTO], target=FILTERTEST_TARGET) output = XOSProcessor.process(args) self.assertEqual(output, "Model1,Model2,Model3,")
def test_annotation(self): xproto = """ policy true_policy < True > message always::true_policy { required int still = 9; } """ target = XProtoTestHelpers.write_tmp_target("{{ proto.messages.0 }}") args = XOSProcessorArgs() args.inputs = xproto args.target = target output = XOSProcessor.process(args) self.assertIn("true_policy", output)
def test_gui_hidden_model_fields(self): xproto = """ option app_label = "test"; message Foo { required string name = 1 [ null = "False", blank="False"]; required string secret = 1 [ null = "False", blank="False", gui_hidden = "True"]; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = "modeldefs.xtarget" output = XOSProcessor.process(args) yaml_ir = yaml.safe_load(output) self.assertEqual(len(yaml_ir["items"]), 1) self.assertIn("name", output) self.assertNotIn("secret", output)
def test_xproto_fields_to_tosca_keys_default(self): """ [XOS-GenX] if no "tosca_key" is specified, and a name attribute is present in the model, use that """ xproto = """ option app_label = "test"; message Foo { required string name = 1 [ null = "False", blank="False"]; } """ args = XOSProcessorArgs() args.inputs = xproto args.target = self.target_tosca_keys output = XOSProcessor.process(args) self.assertIn("name", output)
def test_function_term(self): xproto = """ policy slice_user < slice.user.compute_is_admin() > """ target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.slice_user }}") args = XOSProcessorArgs() args.inputs = xproto args.target = target output = XOSProcessor.process(args) slice = FakeObject() slice.user = FakeObject() slice.user.compute_is_admin = lambda: True expr = eval(output) self.assertTrue(expr)
def test_num_constant(self): xproto = """ policy slice_user < slice.user.age = 57 > """ target = XProtoTestHelpers.write_tmp_target("{{ proto.policies.slice_user }}") args = XOSProcessorArgs() args.inputs = xproto args.target = target output = XOSProcessor.process(args) slice = FakeObject() slice.user = FakeObject() slice.user.is_admin = True expr = eval(output) self.assertTrue(expr)