Skip to content
Snippets Groups Projects
Commit da98ddfe authored by Michele Chiari's avatar Michele Chiari
Browse files

Initial support for DOML 2.1

parent b8913f20
No related branches found
No related tags found
No related merge requests found
commons:
DOMLElement:
attributes:
name:
type: String
multiplicity: "0..1"
description:
type: String
multiplicity: "0..1"
associations:
annotations:
class: commons_Property
multiplicity: "0..*"
Property:
attributes:
key:
type: String
multiplicity: "0..1"
associations:
reference:
class: commons_DOMLElement
multiplicity: "0..1"
IProperty:
superclass: commons_Property
attributes:
value:
type: Integer
multiplicity: "0..1"
SProperty:
superclass: commons_Property
attributes:
value:
type: String
multiplicity: "0..1"
FProperty:
superclass: commons_Property
attributes:
value:
type: String
multiplicity: "0..1"
BProperty:
superclass: commons_Property
attributes:
value:
type: Boolean
multiplicity: "0..1"
Configuration:
superclass: commons_DOMLElement
associations:
deployments:
class: commons_Deployment
multiplicity: "0..*"
Deployment:
associations:
component:
class: application_ApplicationComponent
multiplicity: "1"
node:
class: infrastructure_InfrastructureElement
multiplicity: "1"
application:
ApplicationLayer:
superclass: commons_DOMLElement
associations:
components:
class: application_ApplicationComponent
multiplicity: "0..*"
ApplicationComponent:
superclass: commons_DOMLElement
SoftwareComponent:
superclass: application_ApplicationComponent
attributes:
isPersistent:
type: Boolean
multiplicity: "1"
default: false
licenseCost:
type: String
multiplicity: "0..1"
configFile:
type: String
multiplicity: "0..1"
associations:
exposedInterfaces:
class: application_SoftwareInterface
mutiplicity: "0..*"
consumedInterfaces:
class: application_SoftwareInterface
mutiplicity: "0..*"
SaaS:
superclass: application_ApplicationComponent
attributes:
licenseCost:
type: String
multiplicity: "0..1"
associations:
exposedInterfaces:
class: application_SoftwareInterface
mutiplicity: "0..*"
SoftwareInterface:
superclass: application_ApplicationComponent
attributes:
endPoint:
type: String
multiplicity: "0..1"
DBMS:
superclass: application_SoftwareComponent
SaaSDBMS:
superclass: application_SaaS
infrastructure:
InfrastructureLayer:
superclass: commons_DOMLElement
associations:
nodes:
class: infrastructure_ComputingNode
multiplicity: "0..*"
generators:
class: infrastructure_ComputingNodeGenerator
multiplicity: "0..*"
storages:
class: infrastructure_Storage
multiplicity: "0..*"
faas:
class: infrastructure_FunctionAsAService
multiplicity: "0..*"
credentials:
class: infrastructure_Credentials
multiplicity: "0..*"
groups:
class: infrastructure_ComputingGroup
multiplicity: "0..*"
securityGroups:
class: infrastructure_SecurityGroup
multiplicity: "0..*"
networks:
class: infrastructure_Network
multiplicity: "0..*"
InfrastructureElement:
superclass: commons_DOMLElement
ComputingNode:
superclass: infrastructure_InfrastructureElement
attributes:
architecture:
type: String
multiplicity: "0..1"
os:
type: String
multiplicity: "0..1"
memory_mb:
type: Integer
multiplicity: "0..1"
memory_kb: # Missing in official Ecore, added by parser
type: Integer
multiplicity: "0..1"
storage:
type: String
multiplicity: "0..1"
cpu_count:
type: Integer
multiplicity: "0..1"
cost:
type: Integer # in cents
multiplicity: "0..1"
associations:
ifaces:
class: infrastructure_NetworkInterface
multiplicity: "0..*"
location:
class: infrastructure_Location
multiplicity: "0..1"
credentials:
class: infrastructure_Credentials
multiplicity: "0..1"
group:
class: infrastructure_ComputingGroup
multiplicity: "0..1"
inverse_of: infrastructure_ComputingGroup::groupedNodes
PhysicalComputingNode:
superclass: infrastructure_ComputingNode
VirtualMachine:
superclass: infrastructure_ComputingNode
attributes:
sizeDescription:
type: String
multiplicity: "0..1"
associations:
generatedFrom:
class: infrastructure_VMImage
multiplicity: "0..1"
Location:
superclass: commons_DOMLElement
attributes:
region:
type: String
multiplicity: "0..1"
zone:
type: String
multiplicity: "0..1"
ContainerConfig:
superclass: commons_DOMLElement
attributes:
container_port:
type: Integer
multiplicity: "0..1"
vm_port:
type: Integer
multiplicity: "0..1"
associations:
host:
class: infrastructure_ComputingNode
multiplicity: "0..1"
iface:
class: infrastructure_NewtorkInterface
multiplicity: "0..1"
Container:
superclass: infrastructure_ComputingNode
associations:
generatedFrom:
class: infrastructure_ContainerImage
multiplicity: "0..1"
configs:
class: infrastructure_ContainerConfig
multiplicity: "0..*"
ComputingNodeGenerator:
superclass: commons_DOMLElement
attributes:
uri:
type: String
multiplicity: "0..1"
kind:
type: GeneratorKind # enum { SCRIPT, IMAGE }
VMImage:
superclass: infrastructure_ComputingNodeGenerator
associations:
generatedVMs:
class: infrastructure_VirtualMachine
multiplicity: "0..*"
inverse_of: infrastructure_VirtualMachine::generatedFrom
ContainerImage:
superclass: infrastructure_ComputingNodeGenerator
associations:
generatedContainers:
class: infrastructure_Container
multiplicity: "0..*"
inverse_of: infrastructure_Container::generatedFrom
AutoScalingGroup:
superclass: infrastructure_ComputingGroup
attributes:
min:
type: Integer
multiplicity: "0..1"
max:
type: Integer
multiplicity: "0..1"
loadBalancer:
type: String
multiplicity: "0..1"
associations:
machineDefinition:
class: infrastructure_VirtualMachine
multiplicity: "1"
securityGroup:
class: infrastructure_SecurityGroup
multiplicity: "0..1"
Storage:
superclass: infrastructure_InfrastructureElement
attributes:
label:
type: String
multiplicity: "0..1"
size_gb:
type: Integer # in GBs
multiplicity: "0..1"
cost:
type: Integer # in cents
multiplicity: "0..1"
associations:
ifaces:
class: infrastructure_NetworkInterface
multiplicity: "0..*"
FunctionAsAService:
superclass: infrastructure_InfrastructureElement
attributes:
cost:
type: Integer # in cents
multiplicity: "0..1"
associations:
ifaces:
class: infrastructure_NetworkInterface
multiplicity: "0..*"
Network:
superclass: commons_DOMLElement
attributes:
protocol:
type: String
multiplicity: "0..1"
addressRange:
type: String
multiplicity: "0..1"
cidr:
type: Integer
multiplicity: "0..1"
associations:
connectedIfaces:
class: infrastructure_NetworkInterface
multiplicity: "0..*"
inverse_of: infrastructure_NetworkInterface::belongsTo
igws:
class: infrastructure_InternetGateway
multiplicity: "0..*"
subnets:
class: infrastructure_Subnet
multiplicity: "0..*"
Subnet:
superclass: infrastructure_Network
associations:
connectedTo:
class: infrastructure_Network
multiplicity: "0..1"
NetworkInterface:
superclass: infrastructure_InfrastructureElement
attributes:
endPoint:
type: Integer
multiplicity: "0..1"
speed:
type: String
multiplicity: "0..1"
associations:
belongsTo:
class: infrastructure_Network
multiplicity: "0..1" # This should be "1", but it would break InternetGateway
associated:
class: infrastructure_SecurityGroup
multiplicity: "0..1" # TODO: try putting this to 1 and see why it fails
InternetGateway:
superclass: infrastructure_NetworkInterface
ComputingGroup:
superclass: commons_DOMLElement
associations:
groupedNodes:
class: infrastructure_ComputingNode
multiplicity: "0..*"
inverse_of: infrastructure_ComputingNode::group
SecurityGroup:
superclass: commons_DOMLElement
associations:
rules:
class: infrastructure_Rule
multiplicity: "0..*"
ifaces:
class: infrastructure_NetworkInterface
multiplicity: "0..*"
inverse_of: infrastructure_NetworkInterface::associated
Rule:
superclass: commons_DOMLElement
attributes:
kind:
type: String
multiplicity: "1"
protocol:
type: String
multiplicity: "1"
fromPort:
type: Integer
multiplicity: "1"
toPort:
type: Integer
multiplicity: "1"
cidr:
type: String
multiplicity: "0..*"
Credentials:
superclass: commons_DOMLElement
KeyPair:
superclass: infrastructure_Credentials
attributes:
user:
type: String
multiplicity: "0..1"
keyfile:
type: String
multiplicity: "0..1"
algorithm:
type: String
multiplicity: "0..1"
bits:
type: Integer
multiplicity: "0..1"
UserPass:
superclass: infrastructure_Credentials
attributes:
username:
type: String
multiplicity: "1"
password:
type: String
multiplicity: "1"
SwarmRole:
superclass: commons_DOMLElement
attributes:
kind:
type: String
multiplicity: "1"
associations:
nodes:
class: infrastructure_ComputingNode
multiplicity: "0..*"
Swarm:
superclass: infrastructure_ComputingGroup
associations:
roles:
class: infrastructure_SwarmRole
multiplicity: "0..*"
ExtInfrastructureElement:
superclass: infrastructure_InfrastructureElement
concrete:
ConcreteInfrastructure:
superclass: commons_DOMLElement
associations:
providers:
class: concrete_RuntimeProvider
multiplicity: "0..*"
ConcreteElement:
superclass: commons_DOMLElement
attributes:
configurationScript:
type: String
multiplicity: "0..1"
RuntimeProvider:
superclass: commons_DOMLElement
associations:
vms:
class: concrete_VirtualMachine
multiplicity: "0..*"
vmImages:
class: concrete_VMImage
multiplicity: "0..*"
containerImages:
class: concrete_ContainerImage
multiplicity: "0..*"
networks:
class: concrete_Network
multiplicity: "0..*"
storages:
class: concrete_Storage
multiplicity: "0..*"
faas:
class: concrete_FunctionAsAService
multiplicity: "0..*"
group:
class: concrete_ComputingGroup
multiplicity: "0..*"
VirtualMachine:
superclass: concrete_ConcreteElement
associations:
maps:
class: infrastructure_VirtualMachine
multiplicity: "0..1"
VMImage:
superclass: concrete_ConcreteElement
associations:
maps:
class: infrastructure_VMImage
multiplicity: "0..1"
ContainerImage:
superclass: concrete_ConcreteElement
associations:
maps:
class: infrastructure_ContainerImage
multiplicity: "0..1"
Network:
superclass: concrete_ConcreteElement
attributes:
address:
type: Integer
multiplicity: "0..1"
associations:
maps:
class: infrastructure_Network
multiplicity: "0..1"
Storage:
superclass: concrete_ConcreteElement
associations:
maps:
class: infrastructure_Storage
multiplicity: "0..1"
FunctionAsAService:
superclass: concrete_ConcreteElement
associations:
maps:
class: infrastructure_FunctionAsAService
multiplicity: "0..1"
ComputingGroup:
superclass: concrete_ConcreteElement
associations:
maps:
class: infrastructure_ComputingGroup
multiplicity: "1"
This diff is collapsed.
from .mc import ModelChecker # noqa: F401
from .mc_result import MCResult, MCResults # noqa: F401
from .intermediate_model.metamodel import DOMLVersion # noqa: F401
from .intermediate_model.metamodel import DOMLVersion, init_metamodels # noqa: F401
from .xmi_parser.doml_model import init_doml_rsets
from .xmi_parser.special_parsers import init_special_parsers
__all__ = ["ModelChecker", "MCResult", "MCResults", "DOMLVersion"]
# Load metamodels
init_metamodels()
# Load ecores
init_doml_rsets()
# Generate SpecialParsers
init_special_parsers()
......@@ -9,7 +9,7 @@ from z3 import (
from .imc import (
SMTEncoding, SMTSorts, Requirement, RequirementStore
)
from .intermediate_model.doml_element import IntermediateModel
from .intermediate_model import IntermediateModel, DOMLVersion
def get_consts(smtsorts: SMTSorts, consts: list[str]) -> list[ExprRef]:
......@@ -32,9 +32,9 @@ def vm_iface(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
def software_package_iface_net(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
asc_consumer, asc_exposer, siface, net, net_iface, cnode, cdeployment, enode, edeployment, vm, dc = get_consts(
asc_consumer, asc_exposer, siface, net, net_iface, cnode, cdeployment, enode, edeployment, vm = get_consts(
smtsorts,
["asc_consumer", "asc_exposer", "siface", "net", "net_iface", "cnode", "cdeployment", "enode", "edeployment", "vm", "dc"]
["asc_consumer", "asc_exposer", "siface", "net", "net_iface", "cnode", "cdeployment", "enode", "edeployment", "vm"]
)
return And(
smtenc.association_rel(asc_consumer, smtenc.associations["application_SoftwareComponent::exposedInterfaces"], siface),
......@@ -91,6 +91,68 @@ def software_package_iface_net(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprR
)
def software_package_iface_net_v2_1(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
asc_consumer, asc_exposer, siface, net, net_iface, cnode, cdeployment, enode, edeployment, vm, cconf = get_consts(
smtsorts,
["asc_consumer", "asc_exposer", "siface", "net", "net_iface", "cnode", "cdeployment", "enode", "edeployment", "vm", "cconf"]
)
return And(
smtenc.association_rel(asc_consumer, smtenc.associations["application_SoftwareComponent::exposedInterfaces"], siface),
smtenc.association_rel(asc_exposer, smtenc.associations["application_SoftwareComponent::consumedInterfaces"], siface),
Not(
Exists(
[cdeployment, cnode, edeployment, enode, net],
And(
smtenc.association_rel(cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer),
smtenc.association_rel(cdeployment, smtenc.associations["commons_Deployment::node"], cnode),
Exists(
[vm, net_iface, cconf],
Or(
And( # asc_consumer is deployed on a component with an interface in network n
smtenc.association_rel(cnode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
),
And( # asc_consumer is deployed on a container hosted in a VM with an interface in network n
smtenc.association_rel(cnode, smtenc.associations["infrastructure_Container::configs"], cconf),
smtenc.association_rel(cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm),
smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
),
And( # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n
smtenc.association_rel(cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
),
)
),
smtenc.association_rel(edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer),
smtenc.association_rel(edeployment, smtenc.associations["commons_Deployment::node"], enode),
Exists(
[vm, net_iface, cconf],
Or(
And( # asc_exposer is deployed on a component with an interface in network n
smtenc.association_rel(enode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
),
And( # asc_exposer is deployed on a container hosted on a VM with an interface in network n
smtenc.association_rel(enode, smtenc.associations["infrastructure_Container::configs"], cconf),
smtenc.association_rel(cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm),
smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
),
And( # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n
smtenc.association_rel(enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
),
)
)
)
)
)
)
def iface_uniq(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
endPointAttr = smtenc.attributes["infrastructure_NetworkInterface::endPoint"]
ni1, ni2 = get_consts(smtsorts, ["ni1", "ni2"])
......@@ -303,15 +365,32 @@ def ed_all_concrete_map_something(solver: Solver, smtsorts: SMTSorts, intermedia
return "A concrete infrastructure element is mapped to no abstract infrastructure element."
CommonRequirements = RequirementStore(
[
Requirement(*rt) for rt in [
RequirementLists = {
DOMLVersion.V1_0: [
(vm_iface, "vm_iface", "All virtual machines must be connected to at least one network interface.", ed_vm_iface),
(software_package_iface_net, "software_package_iface_net", "All software packages can see the interfaces they need through a common network.", ed_software_package_iface_net),
(iface_uniq, "iface_uniq", "There are no duplicated interfaces.", ed_iface_uniq),
(all_SoftwareComponents_deployed, "all_SoftwareComponents_deployed", "All software components have been deployed to some node.", ed_all_SoftwareComponents_deployed),
(all_infrastructure_elements_deployed, "all_infrastructure_elements_deployed", "All abstract infrastructure elements are mapped to an element in the active concretization.", ed_all_infrastructure_elements_deployed),
(all_concrete_map_something, "all_concrete_map_something", "All elements in the active concretization are mapped to some abstract infrastructure element.", ed_all_concrete_map_something)
]
]
)
],
DOMLVersion.V2_0: [
(vm_iface, "vm_iface", "All virtual machines must be connected to at least one network interface.", ed_vm_iface),
(software_package_iface_net, "software_package_iface_net", "All software packages can see the interfaces they need through a common network.", ed_software_package_iface_net),
(iface_uniq, "iface_uniq", "There are no duplicated interfaces.", ed_iface_uniq),
(all_SoftwareComponents_deployed, "all_SoftwareComponents_deployed", "All software components have been deployed to some node.", ed_all_SoftwareComponents_deployed),
(all_infrastructure_elements_deployed, "all_infrastructure_elements_deployed", "All abstract infrastructure elements are mapped to an element in the active concretization.", ed_all_infrastructure_elements_deployed),
(all_concrete_map_something, "all_concrete_map_something", "All elements in the active concretization are mapped to some abstract infrastructure element.", ed_all_concrete_map_something)
],
DOMLVersion.V2_1: [
(vm_iface, "vm_iface", "All virtual machines must be connected to at least one network interface.", ed_vm_iface),
(software_package_iface_net_v2_1, "software_package_iface_net", "All software packages can see the interfaces they need through a common network.", ed_software_package_iface_net),
(iface_uniq, "iface_uniq", "There are no duplicated interfaces.", ed_iface_uniq),
(all_SoftwareComponents_deployed, "all_SoftwareComponents_deployed", "All software components have been deployed to some node.", ed_all_SoftwareComponents_deployed),
(all_infrastructure_elements_deployed, "all_infrastructure_elements_deployed", "All abstract infrastructure elements are mapped to an element in the active concretization.", ed_all_infrastructure_elements_deployed),
(all_concrete_map_something, "all_concrete_map_something", "All elements in the active concretization are mapped to some abstract infrastructure element.", ed_all_concrete_map_something)
],
}
CommonRequirements = {ver: RequirementStore([Requirement(*rt) for rt in reqs]) for ver, reqs in RequirementLists.items()}
from .metamodel import init_metamodels, MetaModel # noqa: F401
from .metamodel import DOMLVersion, MetaModel # noqa: F401
from .doml_element import IntermediateModel, DOMLElement # noqa: F401
# Load metamodels
init_metamodels()
......@@ -13,6 +13,7 @@ from .._utils import merge_dicts
class DOMLVersion(Enum):
V1_0 = "v1.0"
V2_0 = "v2.0"
V2_1 = "v2.1"
Multiplicity = tuple[Literal["0", "1"], Literal["1", "*"]]
......@@ -151,6 +152,7 @@ def parse_inverse_associations(doc: dict) -> list[tuple[str, str]]:
def init_metamodels():
global MetaModels, InverseAssociations
for ver in DOMLVersion:
mmdoc = yaml.load(ilres.read_text(assets, f"doml_meta_{ver.value}.yaml"), yaml.Loader)
MetaModels[ver] = parse_metamodel(mmdoc)
......
......@@ -22,13 +22,13 @@ from .consistency_reqs import (
class ModelChecker:
def __init__(self, xmi_model: bytes, doml_version: Optional[DOMLVersion] = None):
self.intermediate_model, doml_version = parse_doml_model(xmi_model, doml_version)
self.metamodel = MetaModels[doml_version]
self.inv_assoc = InverseAssociations[doml_version]
self.intermediate_model, self.doml_version = parse_doml_model(xmi_model, doml_version)
self.metamodel = MetaModels[self.doml_version]
self.inv_assoc = InverseAssociations[self.doml_version]
def check_common_requirements(self, threads: int = 1, consistency_checks: bool = False, timeout: Optional[int] = None) -> MCResults:
assert self.metamodel and self.inv_assoc
req_store = CommonRequirements
req_store = CommonRequirements[self.doml_version]
if consistency_checks:
req_store = req_store \
+ get_attribute_type_reqs(self.metamodel) \
......
from .doml_model import parse_doml_model, init_doml_rsets # noqa: F401
init_doml_rsets()
from .doml_model import parse_doml_model # noqa: F401
......@@ -2,16 +2,16 @@ from typing import Optional, Tuple
import copy
import importlib.resources as ilres
from lxml import etree
from ipaddress import ip_address, ip_network
from mc_openapi import assets
from mc_openapi.bytes_uri import BytesURI
from pyecore.ecore import EObject
from pyecore.resources import ResourceSet
from ..intermediate_model.doml_element import Attributes, IntermediateModel, reciprocate_inverse_associations
from ..intermediate_model.doml_element import IntermediateModel, reciprocate_inverse_associations
from ..intermediate_model.metamodel import DOMLVersion, MetaModels, InverseAssociations
from .ecore import ELayerParser, SpecialParser
from .ecore import ELayerParser
from .special_parsers import SpecialParsers
doml_rsets = {}
......@@ -62,29 +62,12 @@ def infer_domlx_version(raw_model: bytes) -> DOMLVersion:
def parse_doml_model(raw_model: bytes, doml_version: Optional[DOMLVersion]) -> Tuple[IntermediateModel, DOMLVersion]:
def parse_network_address_range(arange: str) -> Attributes:
ipnet = ip_network(arange)
return {"address_lb": [int(ipnet[0])], "address_ub": [int(ipnet[-1])]}
def parse_iface_address(addrport: str) -> Attributes:
addr, _, port = addrport.rpartition(":")
if addr == "":
addr = port
return {"endPoint": [int(ip_address(addr))]}
if doml_version is None:
doml_version = infer_domlx_version(raw_model)
model = parse_xmi_model(raw_model, doml_version)
mm = MetaModels[doml_version]
sp = SpecialParser(mm, {
("infrastructure_Network", "addressRange"): parse_network_address_range,
("infrastructure_NetworkInterface", "endPoint"): parse_iface_address,
("infrastructure_ComputingNode", "memory_mb"): lambda mem: {"memory_mb": [int(mem)], "memory_kb": [int(mem * 1024)]},
("commons_FProperty", "value"): lambda fval: {"value": [str(fval)]},
})
elp = ELayerParser(mm, sp)
elp = ELayerParser(MetaModels[doml_version], SpecialParsers[doml_version])
if model.application:
elp.parse_elayer(model.application)
if model.infrastructure:
......
from ipaddress import ip_address, ip_network
from .ecore import SpecialParser
from ..intermediate_model.metamodel import DOMLVersion, MetaModels
from ..intermediate_model.doml_element import Attributes
SpecialParsers: dict[DOMLVersion, SpecialParser] = {}
def parse_network_address_range(arange: str) -> Attributes:
ipnet = ip_network(arange)
return {"address_lb": [int(ipnet[0])], "address_ub": [int(ipnet[-1])]}
def parse_iface_address(addrport: str) -> Attributes:
addr, _, port = addrport.rpartition(":")
if addr == "":
addr = port
return {"endPoint": [int(ip_address(addr))]}
def parse_memory_mb(mem: str) -> Attributes:
return {"memory_mb": [int(mem)], "memory_kb": [int(mem * 1024)]}
def parse_fproperty(fval: str) -> Attributes:
return {"value": [str(fval)]}
def parse_cidr(arange: str) -> Attributes:
attrs: Attributes = {"addressRange": [arange]}
if arange[0] == "/":
try:
attrs["cidr"] = [int(arange[1:])]
except (ValueError, IndexError):
pass
return attrs
def init_special_parsers():
global SpecialParsers
assert len(MetaModels) > 0
attribute_parsers = {
DOMLVersion.V1_0: {
("infrastructure_Network", "addressRange"): parse_network_address_range,
("infrastructure_NetworkInterface", "endPoint"): parse_iface_address,
("commons_FProperty", "value"): parse_fproperty,
},
DOMLVersion.V2_0: {
("infrastructure_Network", "addressRange"): parse_network_address_range,
("infrastructure_NetworkInterface", "endPoint"): parse_iface_address,
("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb,
("commons_FProperty", "value"): parse_fproperty,
},
DOMLVersion.V2_1: {
("infrastructure_Network", "addressRange"): parse_cidr,
("infrastructure_NetworkInterface", "endPoint"): parse_iface_address,
("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb,
("commons_FProperty", "value"): parse_fproperty,
},
}
for ver in DOMLVersion:
SpecialParsers[ver] = SpecialParser(MetaModels[ver], attribute_parsers[ver])
from mc_openapi import __version__
from mc_openapi.doml_mc.common_reqs import CommonRequirements
from mc_openapi.doml_mc import DOMLVersion
import requests
......@@ -29,7 +30,7 @@ def test_post_faas_sat():
assert payload["result"] == "unsat"
def test_post_common_reqs():
def test_post_common_reqs_V2_0():
check_strings = [
"is connected to no network interface.",
"but they are deployed to nodes that cannot communicate through a common network.",
......@@ -39,7 +40,7 @@ def test_post_common_reqs():
"is mapped to no abstract infrastructure element."
]
for req, err_desc in zip(CommonRequirements.get_all_requirements(), check_strings):
for req, err_desc in zip(CommonRequirements[DOMLVersion.V2_0].get_all_requirements(), check_strings):
with open(f"tests/doml/nginx-openstack_v2.0_wrong_{req.assert_name}.domlx", "r") as f:
doml = f.read()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment