Browse Source

Fixed process_execute as well

Yentl Van Tendeloo 8 years ago
parent
commit
faa57326bd
4 changed files with 92 additions and 264 deletions
  1. 13 2
      bootstrap/core_algorithm.alc
  2. 32 253
      integration/test_mvc.py
  3. 10 4
      integration/utils.py
  4. 37 5
      wrappers/modelverse.py

+ 13 - 2
bootstrap/core_algorithm.alc

@@ -639,6 +639,16 @@ Boolean function enact_action(pm : Element, element : String, prefix : String, u
 		elem_name = read_attribute(pm, elem, "name")
 		dict_add(outputs, type_name, prefix + elem_name)
 
+	if read_type(core, transformation_id) == "ActionLanguage":
+		log(string_join("Enacting ActionLanguage: ", read_attribute(pm, element, "name")))
+		output(string_join("Enacting ActionLanguage: ", read_attribute(pm, element, "name")))
+	elif read_type(core, transformation_id) == "ManualOperation":
+		log(string_join("Enacting ManualOperation: ", read_attribute(pm, element, "name")))
+		output(string_join("Enacting ManualOperation: ", read_attribute(pm, element, "name")))
+	else:
+		log(string_join("Enacting ModelTransformation: ", read_attribute(pm, element, "name")))
+		output(string_join("Enacting ModelTransformation: ", read_attribute(pm, element, "name")))
+		
 	result = execute_operation(transformation_id, inputs, dict_keys(outputs), read_root())
 
 	if (element_eq(result, read_root())):
@@ -665,6 +675,8 @@ Void function enact_PM(pm : Element, prefix : String, user_id : String):
 	Element counters
 	Element join_nodes
 
+	output("Success")
+
 	// Initialize Join counters
 	counters = create_node()
 	join_nodes = allInstances(pm, "Join")
@@ -681,8 +693,6 @@ Void function enact_PM(pm : Element, prefix : String, user_id : String):
 		element = tuple[0]
 		result = tuple[1]
 
-		log("Enacting " + cast_v2s(element))
-
 		// Find the type (to see what to do with it)
 		//   this does not yet yield the type of transformation, if it is an Execution
 		type = read_type(pm, element)
@@ -742,6 +752,7 @@ Void function enact_PM(pm : Element, prefix : String, user_id : String):
 			set_add(worklist, create_tuple(next, result))
 
 	// Reached a finish element, so stop
+	output("Success")
 	return !
 
 String function cmd_help(user_id : String):

+ 32 - 253
integration/test_mvc.py

@@ -23,14 +23,12 @@ expected_model_full_list = set([("SimpleClassDiagrams", "SimpleClassDiagrams", "
                                 ("core", "CoreFormalism", "admin", "admin", "200")])
 
 class TestModelverseCore(unittest.TestCase):
-    @classmethod
-    def setup_class(self):
+    def setUp(self):
         self.proc, self.address = start_mvc()
         init(self.address)
         login("admin", "admin")
 
-    @classmethod
-    def teardown_class(self):
+    def tearDown(self):
         kill(self.proc)
 
     def test_list(self):
@@ -269,255 +267,36 @@ class TestModelverseCore(unittest.TestCase):
                                 '"p3" --> 5'])
 
     def test_process_model_trivial_pn(self):
-        self.assertTrue(run_file(all_files,
-            [ "admin", "admin", "admin", 
-                "model_add",
-                    "SimpleClassDiagrams",
-                    "PetriNet",
-                    ] + get_model_constructor(open("integration/code/pn_design.mvc", "r").read()) + [
-                "model_add",
-                    "SimpleClassDiagrams",
-                    "ReachabilityGraph",
-                    ] + get_model_constructor(open("integration/code/reachability_graph.mvc", "r").read()) + [
-                "model_list",
-                "transformation_add_MT_language",
-                "PetriNet",
-                "",
-                "PetriNet_RAM",
-                "transformation_add_MT_language",
-                "ReachabilityGraph",
-                "",
-                "ReachabilityGraph_RAM",
-                "transformation_add_MT",
-                    "PetriNet_RAM",
-                    "",
-                    "PetriNet",
-                    "",
-                    "initialize_PN",
-                    ] + get_model_constructor(open("integration/code/initialize_PN.mvc", "r").read()) + [
-                "transformation_add_MANUAL",
-                    "PetriNet",
-                    "",
-                    "PetriNet",
-                    "",
-                    "refine_PN",
-                "transformation_add_AL",
-                    "PetriNet",
-                    "",
-                    "ReachabilityGraph",
-                    "",
-                    "reachability",
-                    ] + get_constructor(open("integration/code/reachability.alc", "r").read()) + [
-                "transformation_add_MT",
-                    "ReachabilityGraph_RAM",
-                    "ReachabilityGraph",
-                    "",
-                    "",
-                    "reachability_print",
-                    ] + get_model_constructor(open("integration/code/reachabilitygraph_print.mvc", "r").read()) + [
-                "model_add",
-                    "ProcessModel",
-                    "pn_reachability",
-                    ] + get_model_constructor(open("integration/code/pm_pn_reachability.mvc", "r").read()) + [
-                "model_list",
-                "process_execute",
-                "pn_reachability",
-                "my_",
-                    "instantiate",
-                        "PetriNet/Place",
-                        "p1",
-                    "attr_add",
-                        "p1",
-                        "name",
-                        "p1",
-                    "attr_add",
-                        "p1",
-                        "tokens",
-                        1,
-                    "instantiate",
-                        "PetriNet/Transition",
-                        "t1",
-                    "attr_add",
-                        "t1",
-                        "name",
-                        "t1",
-                    "instantiate",
-                        "PetriNet/P2T",
-                        "p2t",
-                        "p1",
-                        "t1",
-                    "attr_add",
-                        "p2t",
-                        "weight",
-                        1,
-                    "exit",
-                "model_list",
-            ],
-            [   # bootup phase
-                "Desired username for admin user?",
-                "Desired password for admin user?",
-                "Please repeat the password",
-                "Passwords match!",
-                "Welcome to the Model Management Interface v2.0!",
-                "Use the 'help' command for a list of possible commands",
-                "Ready for command...",
-                # model_add
-                "Creating new model!",
-                "Model type?",
-                "Model name?",
-                "Waiting for model constructors...",
-                "Model upload success!",
-                "Ready for command...",
-                # model_add
-                "Creating new model!",
-                "Model type?",
-                "Model name?",
-                "Waiting for model constructors...",
-                "Model upload success!",
-                "Ready for command...",
-                # model_list
-                set(model_list) |
-                set([
-                     "  PetriNet : SimpleClassDiagrams",
-                     "  ReachabilityGraph : SimpleClassDiagrams",]),
-                "Ready for command...",
-                # transformation_add_MT_language
-                "Formalisms to include (terminate with empty string)?",
-                "Name of the RAMified transformation metamodel?",
-                "Ready for command...",
-                # transformation_add_MT_language
-                "Formalisms to include (terminate with empty string)?",
-                "Name of the RAMified transformation metamodel?",
-                "Ready for command...",
-                # transformation_add_MT
-                "RAMified metamodel to use?",
-                "Supported metamodels:",
-                set(["  PetriNet",]),
-                "Which metamodels do you want to use as source for the operation (empty string to finish)?",
-                "Which metamodels do you want to use as target for the operation (empty string to finish)?",
-                "Name of new operation?",
-                "Waiting for model constructors...",
-                "Ready for command...",
-                # transformation_add_MANUAL
-                "Which metamodels do you want to use as source for the operation (empty string to finish)?",
-                "Which metamodels do you want to use as target for the operation (empty string to finish)?",
-                "Name of operation model?",
-                "Ready for command...",
-                # transformation_add_AL
-                "Which metamodels do you want to use as source for the operation (empty string to finish)?",
-                "Which metamodels do you want to use as target for the operation (empty string to finish)?",
-                "Name of operation model?",
-                "Waiting for model constructors...",
-                "Ready for command...",
-                # transformation_add_MT
-                "RAMified metamodel to use?",
-                "Supported metamodels:",
-                set(["  ReachabilityGraph",]),
-                "Which metamodels do you want to use as source for the operation (empty string to finish)?",
-                "Which metamodels do you want to use as target for the operation (empty string to finish)?",
-                "Name of new operation?",
-                "Waiting for model constructors...",
-                "Ready for command...",
-                # model_add
-                "Creating new model!",
-                "Model type?",
-                "Model name?",
-                "Waiting for model constructors...",
-                "Model upload success!",
-                "Ready for command...",
-                # model_list
-                set(model_list) |
-                set([
-                     "  PetriNet : SimpleClassDiagrams",
-                     "  ReachabilityGraph : SimpleClassDiagrams",
-                     "  initialize_PN : PetriNet_RAM",
-                     "  refine_PN : ManualOperation",
-                     "  reachability : ActionLanguage",
-                     "  reachability_print : ReachabilityGraph_RAM",
-                     "  pn_reachability : ProcessModel",
-                     "  PetriNet_RAM : SimpleClassDiagrams",
-                     "  ReachabilityGraph_RAM : SimpleClassDiagrams",
-                     "  __merged_PetriNet_RAM : SimpleClassDiagrams",
-                     "  __merged_ReachabilityGraph_RAM : SimpleClassDiagrams",
-                     "  __merged_refine_PN : SimpleClassDiagrams",
-                     "  __merged_reachability : SimpleClassDiagrams",
-                     ]),
-                "Ready for command...",
-                # process_execute
-                "Which process model do you want to execute?",
-                "Model prefix to use?",
-                    "Please perform manual operation \"refine_PN\"",
-                    "Model loaded, ready for commands!",
-                    "Mode: r/w",
-                    "Use 'help' command for a list of possible commands",
-                    "Please give your command.",
-                    # instantiate p1
-                        "Type to instantiate?",
-                        "Name of new element?",
-                        "Instantiation successful!",
-                        None,
-                        "Please give your command.",
-                        "Which element do you want to assign an attribute to?",
-                        "Which attribute do you wish to assign?",
-                        "Value of attribute?",
-                        "Added attribute!",
-                        "Please give your command.",
-                        "Which element do you want to assign an attribute to?",
-                        "Which attribute do you wish to assign?",
-                        "Value of attribute?",
-                        "Added attribute!",
-                        "Please give your command.",
-                    # instantiate t1
-                        "Type to instantiate?",
-                        "Name of new element?",
-                        "Instantiation successful!",
-                        None,
-                        "Please give your command.",
-                        "Which element do you want to assign an attribute to?",
-                        "Which attribute do you wish to assign?",
-                        "Value of attribute?",
-                        "Added attribute!",
-                        "Please give your command.",
-                    # instantiate p2t
-                        "Type to instantiate?",
-                        "Name of new element?",
-                        "Source name?",
-                        "Destination name?",
-                        "Instantiation successful!",
-                        None,
-                        "Please give your command.",
-                        "Which element do you want to assign an attribute to?",
-                        "Which attribute do you wish to assign?",
-                        "Value of attribute?",
-                        "Added attribute!",
-                        "Please give your command.",
-                set(['"0": {"p1": 1, }',
-                     '"1": {"p1": 0, }',
-                    ]),
-                set(['"0" --["t1"]--> "1"',
-                    ]),
-                "Ready for command...",
-                # model_list
-                set(model_list) |
-                set([
-                     "  PetriNet : SimpleClassDiagrams",
-                     "  ReachabilityGraph : SimpleClassDiagrams",
-                     "  initialize_PN : PetriNet_RAM",
-                     "  refine_PN : ManualOperation",
-                     "  reachability : ActionLanguage",
-                     "  reachability_print : ReachabilityGraph_RAM",
-                     "  pn_reachability : ProcessModel",
-                     "  PetriNet_RAM : SimpleClassDiagrams",
-                     "  ReachabilityGraph_RAM : SimpleClassDiagrams",
-                     "  my_pn : PetriNet",
-                     "  my_reachability : ReachabilityGraph",
-                     "  __merged_PetriNet_RAM : SimpleClassDiagrams",
-                     "  __merged_ReachabilityGraph_RAM : SimpleClassDiagrams",
-                     "  __merged_refine_PN : SimpleClassDiagrams",
-                     "  __merged_reachability : SimpleClassDiagrams",
-                     ]),
-                "Ready for command...",
-            ]))
+        model_add("PetriNet", "SimpleClassDiagrams", open("integration/code/pn_design.mvc", "r").read())
+        model_add("ReachabilityGraph", "SimpleClassDiagrams", open("integration/code/reachability_graph.mvc", "r").read())
+        model_add("pn_reachability", "ProcessModel", open("integration/code/pm_pn_reachability.mvc", "r").read())
+        transformation_add_MT_language(["PetriNet"], "PetriNet_RAM")
+        transformation_add_MT_language(["ReachabilityGraph"], "ReachabilityGraph_RAM")
+        transformation_add_MT("PetriNet_RAM", [], ["PetriNet"], "initialize_PN", open("integration/code/initialize_PN.mvc", "r").read())
+        transformation_add_MANUAL(["PetriNet"], ["PetriNet"], "refine_PN")
+        transformation_add_AL(["PetriNet"], ["ReachabilityGraph"], "reachability", open("integration/code/reachability.alc", "r").read())
+        transformation_add_MT("ReachabilityGraph_RAM", ["ReachabilityGraph"], [], "reachability_print", open("integration/code/reachabilitygraph_print.mvc", 'r').read())
+
+        def callback_refine_PN():
+            p1 = instantiate(None, "PetriNet/Place")
+            attr_assign(None, p1, "name", "p1")
+            attr_assign(None, p1, "tokens", 1)
+
+            t1 = instantiate(None, "PetriNet/Transition")
+            attr_assign(None, t1, "name", "t1")
+
+            p2t = instantiate(None, "PetriNet/P2T", (p1, t1))
+            attr_assign(None, p2t, "weight", 1)
+
+        log = set([])
+        def callback_print(value):
+            log.add(value)
+
+        process_execute("pn_reachability", "my_", {"refine_PN": callback_refine_PN, "reachability_print": callback_print})
+
+        assert log == set(['"0": {"p1": 1, }',
+                           '"1": {"p1": 0, }',
+                           '"0" --["t1"]--> "1"'])
 
     def test_render(self):
         model_add("CausalBlockDiagrams", "SimpleClassDiagrams", open("integration/code/cbd_design.mvc", 'r').read())

+ 10 - 4
integration/utils.py

@@ -18,6 +18,8 @@ from hutn_compiler.compiler import main as do_compile
 taskname = "test_task"
 INIT_TIMEOUT = 30
 
+
+
 try:
     import pytest
     slow = pytest.mark.skipif(
@@ -51,14 +53,18 @@ def execute(scriptname, parameters=[], wait=False):
     else:
         return subprocess.Popen(command, shell=False, stdout=subprocess.PIPE)
 
+def child_kill(pid):
+    subprocess.call(["pkill", "-P", "%i" % pid])
+    while subprocess.call(["pgrep", "-P", "%i" % pid], stdout=open(os.devnull, 'w')) != 1:
+        time.sleep(0.1)
+
 def kill(process):
     if os.name == "nt":
         subprocess.call(["taskkill", "/F", "/T", "/PID", "%i" % process.pid])
     elif os.name == "posix":
-        # Kill parents
-        subprocess.call(["pkill", "-9", "-P", "%i" % process.pid])
-        # Kill self
-        subprocess.call(["kill", "-9", "%i" % process.pid])
+        child_kill(process.pid)
+        process.poll()
+        child_kill(os.getpid())
 
 def flush_data(address, data):
     if data:

+ 37 - 5
wrappers/modelverse.py

@@ -63,7 +63,7 @@ class InterfaceMismatch(ModelverseException):
     pass
 
 # Helper functions and configuration: do not use yourself!
-taskname = random.random()
+taskname = None
 address = None
 last_output = None
 mode = MODE_UNCONNECTED
@@ -164,11 +164,11 @@ def init(address_param="http://127.0.0.1:8001", timeout=20.0):
     # raises UnknownError
     # raises InvalidMode
     global mode
-    if mode != MODE_UNCONNECTED:
-        raise InvalidMode()
     global address
+    global taskname
     address = address_param
     start_time = time.time()
+    taskname = random.random()
     while 1:
         try:
             _input_raw('"%s"' % taskname, "task_manager")
@@ -528,7 +528,9 @@ def transformation_execute_MT(operation_name, input_models_dict, output_models_d
 
     # We are now executing, so everything we get is part of the dialog, except if it is the string for transformation termination
     while _output() not in ["Success", "Failure"]:
+        mode = MODE_DIALOG
         reply = callback(_last_output())
+        mode = MODE_MODELLING
         if reply is not None:
             _input(reply)
 
@@ -572,9 +574,39 @@ def transformation_RAMify(metamodel_name, RAMified_metamodel_name):
     _input(["transformation_RAMify", metamodel_name, RAMified_metamodel_name])
     _handle_output("Success")
 
-def process_execute():
+def process_execute(process_name, prefix, callbacks):
     """Execute a process model."""
-    raise NotImplementedError()
+    global mode
+    if mode != MODE_MODELLING:
+        raise InvalidMode()
+
+    _input(["process_execute", process_name, prefix])
+    _handle_output("Success")
+
+    while _output() != "Success":
+        output = _last_output()
+        if output.startswith("Enacting "):
+            # Next activity!
+            t = output.split(" ", 1)[1].split(":", 1)[0]
+            name = output.split(": ", 1)[1]
+            if name in callbacks:
+                callback = callbacks[name]
+                if t == "ModelTransformation" or t == "ActionLanguage":
+                    while not (_output().startswith("Enacting ") or _last_output() == "Success"):
+                        mode = MODE_DIALOG
+                        reply = callback(_last_output())
+                        mode = MODE_MODELLING
+                        if reply is not None:
+                            _input(reply)
+                elif t == "ManualOperation":
+                    _output()
+                    _output()
+                    _output()
+                    _output()
+                    mode = MODE_MANUAL
+                    callback()
+                    _input("exit")
+                    mode = MODE_MODELLING
 
 def permission_modify():
     """Modify permissions of a model."""