Browse Source

Patch folder_create

Yentl Van Tendeloo 7 years ago
parent
commit
a08eab93df
5 changed files with 182 additions and 61 deletions
  1. 2 10
      bootstrap/core_algorithm.alc
  2. 121 4
      unit/test_all.py
  3. 10 9
      wrappers/classes/modelverse.xml
  4. 6 0
      wrappers/modelverse.py
  5. 43 38
      wrappers/modelverse_SCCD.py

+ 2 - 10
bootstrap/core_algorithm.alc

@@ -391,8 +391,6 @@ String function create_folders(user_id : String, folder_name : String):
 				instantiate_link(core, "group", "", new_entry, get_group_id("nobody"))
 				instantiate_link(core, "owner", "", new_entry, user_id)
 			else:
-				log("Not allowed to write!")
-				log("User was: " + cast_string(read_attribute(core, current_user_id, "name")))
 				return read_root()!
 
 		prev = get_entry_id(cummul)
@@ -1671,7 +1669,6 @@ String function cmd_model_modify(model_name : String, metamodel_name : String):
 	String type_id
 
 	model_id = get_entry_id(model_name)
-	log("Model modify " + model_name)
 
 	if (model_id != ""):
 		if (allow_read(current_user_id, model_id)):
@@ -1680,22 +1677,17 @@ String function cmd_model_modify(model_name : String, metamodel_name : String):
 				Element new_model
 				new_model = get_full_model(model_id, get_entry_id(metamodel_name))
 				if (element_eq(new_model, read_root())):
-					log("Conformance hierarchy")
 					return "Conformance hierarchy unknown for: " + model_name!
 				modify(new_model, allow_write(current_user_id, model_id))
 				if (allow_write(current_user_id, model_id)):
 					// Overwrite the modified model
 					model_overwrite(new_model, model_id, get_entry_id(metamodel_name))
-					log("OK")
 				return "Success"!
 			else:
-				log("READ PERM1")
 				return string_join("Read permission denied to: ", full_name(type_id))!
 		else:
-			log("READ PERM2")
 			return "Read permission denied to: " + model_name!
 	else:
-		log("location")
 		return "Location not found: " + model_name!
 
 Void function model_delete(model_id : String):
@@ -2397,7 +2389,7 @@ String function cmd_model_types(model_name : String):
 		types = allOutgoingAssociationInstances(core, model_id, "instanceOf")
 		while (set_len(types) > 0):
 			type_link = set_pop(types)
-			result = result + cast_string(full_name(readAssociationDestination(core, type_link))) + ", " + cast_string(full_name(anAssociationDestination(core, type_link, "typing"))) + ", NONE\n"
+			result = result + cast_string(full_name(readAssociationDestination(core, type_link))) + ", " + cast_string(full_name(anAssociationDestination(core, type_link, "typing"))) + ", None\n"
 
 		return result!
 	else:
@@ -2410,7 +2402,7 @@ String function cmd_folder_create(folder_name : String):
 		else:
 			return "Write permission denied to: " + folder_name!
 	else:
-		return "Folder alreay exists: " + folder_name!
+		return "Folder exists: " + folder_name!
 
 String function cmd_conformance_add(model_name : String, metamodel_name : String):
 	// Create a new instanceOf relation now

+ 121 - 4
unit/test_all.py

@@ -473,6 +473,127 @@ class TestModelverse(unittest.TestCase):
         assert all_instances("users/user/test/b", "B") == set(["b"])
         assert all_instances("users/user/test/b", "C") == set(["c"])
 
+        try:
+            all_instances("administration/core", "Class")
+            self.fail()
+        except ReadPermissionDenied:
+            pass
+
+    def test_op_admin_promote_demote(self):
+        # Verify that user doesn't have admin permissions
+        try:
+            element_list("administration/core")
+            self.fail()
+        except ReadPermissionDenied:
+            pass
+
+        # Cannot do admin_promote ourselves
+        try:
+            admin_promote("user")
+        except AdminPermissionDenied:
+            pass
+
+        # Cannot do admin_demote ourselves
+        try:
+            admin_demote("user")
+        except AdminPermissionDenied:
+            pass
+
+        # Switch to admin for now
+        user_logout()
+        login("admin", "admin")
+        admin_promote("user")
+        user_logout()
+        login("user", "user")
+
+        # Verify that we can do admin operations
+        assert len(element_list("administration/core")) > 0
+
+        # And check that we can promote/demote other users
+        admin_promote("HUTN")
+        admin_demote("HUTN")
+
+        # Can also demote ourselves again
+        admin_demote("user")
+
+        # Verify that user doesn't have admin permissions
+        try:
+            element_list("administration/core")
+            self.fail()
+        except ReadPermissionDenied:
+            pass
+
+    def test_op_model_types(self):
+        model_add("users/user/test/a", "formalisms/SimpleClassDiagrams")
+
+        # Read model types of simple model
+        lst = model_types("users/user/test/a")
+        assert len(lst) == 1
+        entry = lst.pop()
+        assert entry[0] == "formalisms/SimpleClassDiagrams"
+        assert entry[1].startswith("type mappings/")
+        assert entry[2] == None
+
+        # Create bottom and query afterwards
+        alter_context("users/user/test/a", "formalisms/Bottom")
+        element_list_nice("users/user/test/a")
+        alter_context("users/user/test/a", "formalisms/SimpleClassDiagrams")
+
+        lst = model_types("users/user/test/a")
+        assert len(lst) == 2
+        got = set()
+        while lst:
+            entry = lst.pop()
+            assert entry[0] in ["formalisms/SimpleClassDiagrams", "formalisms/Bottom"]
+            assert entry[0] not in got
+            got.add(entry[0])
+            assert entry[1].startswith("type mappings/")
+            assert entry[2] == None
+
+        # No type mapping for type mappings
+        assert model_types(entry[1]) == set([("formalisms/TypeMapping", None, None)])
+
+        # But there will be as soon as we open it
+        element_list_nice(entry[1])
+        lst = model_types(entry[1])
+        assert len(lst) == 1
+        entry = lst.pop()
+        assert entry[0] == "formalisms/TypeMapping"
+        assert entry[1].startswith("type mappings/")
+        assert entry[2] == None
+
+    def test_op_folder_create(self):
+        # Create a folder
+        assert folder_create("users/user/test/folder_a") == None
+        assert model_list_full("users/user/test/") == set([("folder_a/", "user", "nobody", "200")])
+
+        # Create folder with trailing slash
+        assert folder_create("users/user/test/folder_b/") == None
+        assert model_list_full("users/user/test/") == set([("folder_a/", "user", "nobody", "200"), ("folder_b/", "user", "nobody", "200")])
+        assert model_list_full("users/user/test/folder_b") == set()
+
+        # Create multiple folders
+        assert folder_create("users/user/test/folder_a/folder_b/folder_c/folder_d") == None
+        assert model_list_full("users/user/test/") == set([("folder_a/", "user", "nobody", "200"), ("folder_b/", "user", "nobody", "200")])
+        assert model_list_full("users/user/test/folder_a") == set([("folder_b/", "user", "nobody", "200")])
+        assert model_list_full("users/user/test/folder_a/folder_b") == set([("folder_c/", "user", "nobody", "200")])
+        assert model_list_full("users/user/test/folder_a/folder_b/folder_c") == set([("folder_d/", "user", "nobody", "200")])
+
+        # Create folder in non-writable location
+        try:
+            folder_create("a")
+            self.fail()
+        except WritePermissionDenied:
+            pass
+        assert "a" not in model_list("") 
+
+        # Create folder that already exists
+        try:
+            folder_create("users/user/test/folder_a")
+            self.fail()
+        except FolderExists:
+            pass
+
     """
     def test_op_model_render(self):
     def test_op_transformation_between(self):
@@ -484,7 +605,6 @@ class TestModelverse(unittest.TestCase):
     def test_op_transformation_execute_MANUAL(self):
     def test_op_transformation_signature(self):
     def test_op_process_signature(self):
-    def test_op_permission_modify(self):
     def test_op_permission_group(self):
     def test_op_permission_owner(self):
     def test_op_group_create(self):
@@ -494,12 +614,9 @@ class TestModelverse(unittest.TestCase):
     def test_op_group_join(self):
     def test_op_group_kick(self):
     def test_op_group_list(self):
-    def test_op_admin_promote(self):
-    def test_op_admin_demote(self):
     def test_op_conformance_delete(self):
     def test_op_conformance_add(self):
     def test_op_folder_create(self):
-    def test_op_model_types(self):
     def test_op_alter_context(self):
     def test_op_element_list(self):
     def test_op_element_list_nice(self):

+ 10 - 9
wrappers/classes/modelverse.xml

@@ -852,7 +852,7 @@
                     <state id="admin_promote">
                         <onentry>
                             <raise event="request">
-                                <parameter expr="['admin_promote', self.parameters[0], self.parameters[1]]"/>
+                                <parameter expr="['admin_promote', self.parameters[0]]"/>
                             </raise>
                         </onentry>
 
@@ -866,7 +866,7 @@
                     <state id="admin_demote">
                         <onentry>
                             <raise event="request">
-                                <parameter expr="['admin_demote', self.parameters[0], self.parameters[1]]"/>
+                                <parameter expr="['admin_demote', self.parameters[0]]"/>
                             </raise>
                         </onentry>
 
@@ -928,7 +928,7 @@
 
                         <transition cond="self.expect_response_partial('Success: ')" target="../../wait_for_action/history">
                             <raise event="result">
-                                <parameter expr="set([tuple(i.split(', ')) for i in self.split_response(self.responses.pop(0))])"/>
+                                <parameter expr="set([tuple([j if j != 'None' else None for j in i.split(', ')]) for i in self.split_response(self.responses.pop(0))])"/>
                             </raise>
                         </transition>
                     </state>
@@ -1363,6 +1363,13 @@
                         </raise>
                     </transition>
 
+                    <transition cond="self.expect_response_partial('Folder exists: ', pop=False)" target="../wait_for_action/history">
+                        <raise event="exception">
+                            <parameter expr="'FolderExists'"/>
+                            <parameter expr="self.split_response(self.responses.pop(0))[0]"/>
+                        </raise>
+                    </transition>
+
                     <transition cond="self.expect_response_partial('Attribute exists: ', pop=False)" target="../wait_for_action/history">
                         <raise event="exception">
                             <parameter expr="'AttributeExists'"/>
@@ -1552,12 +1559,6 @@
                     </state>
 
                     <state id="megamodelling">
-                        <onentry>
-                            <script>
-                                print("Entered megamodelling with operation: " + str(self.actions))
-                            </script>
-                        </onentry>
-
                         <transition cond="self.expect_action('model_list')" target="../../operations/model_list">
                             <script>
                                 self.load_action()

+ 6 - 0
wrappers/modelverse.py

@@ -48,9 +48,15 @@ class ExistsError(ModelverseException):
 class AttributeExists(ExistsError):
     pass
 
+class ElementExists(ExistsError):
+    pass
+
 class ModelExists(ExistsError):
     pass
 
+class FolderExists(ExistsError):
+    pass
+
 class PermissionDenied(ModelverseException):
     pass
 

+ 43 - 38
wrappers/modelverse_SCCD.py

@@ -1,8 +1,6 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-Date:   Mon Jun 11 09:54:06 2018
-
 Model author: Yentl Van Tendeloo
 Model name:   MvK Server
 Model description:
@@ -509,7 +507,6 @@ class Modelverse(RuntimeClassBase):
         
         # state /initialized/behaviour/wait_for_action/megamodelling
         self.states["/initialized/behaviour/wait_for_action/megamodelling"] = State(105, "/initialized/behaviour/wait_for_action/megamodelling", self)
-        self.states["/initialized/behaviour/wait_for_action/megamodelling"].setEnter(self._initialized_behaviour_wait_for_action_megamodelling_enter)
         
         # state /initialized/behaviour/wait_for_action/service
         self.states["/initialized/behaviour/wait_for_action/service"] = State(106, "/initialized/behaviour/wait_for_action/service", self)
@@ -1780,6 +1777,11 @@ class Modelverse(RuntimeClassBase):
         _initialized_behaviour_operations_17.setTrigger(None)
         _initialized_behaviour_operations_17.setGuard(self._initialized_behaviour_operations_17_guard)
         self.states["/initialized/behaviour/operations"].addTransition(_initialized_behaviour_operations_17)
+        _initialized_behaviour_operations_18 = Transition(self, self.states["/initialized/behaviour/operations"], [self.states["/initialized/behaviour/wait_for_action/history"]])
+        _initialized_behaviour_operations_18.setAction(self._initialized_behaviour_operations_18_exec)
+        _initialized_behaviour_operations_18.setTrigger(None)
+        _initialized_behaviour_operations_18.setGuard(self._initialized_behaviour_operations_18_guard)
+        self.states["/initialized/behaviour/operations"].addTransition(_initialized_behaviour_operations_18)
         
         # transition /initialized/behaviour/wait_for_action
         _initialized_behaviour_wait_for_action_0 = Transition(self, self.states["/initialized/behaviour/wait_for_action"], [self.states["/initialized/behaviour/wait_for_action/history"]])
@@ -2054,10 +2056,10 @@ class Modelverse(RuntimeClassBase):
         self.raiseInternalEvent(Event("request", None, [['group_list', self.parameters[0], self.parameters[1]]]))
     
     def _initialized_behaviour_operations_admin_promote_enter(self):
-        self.raiseInternalEvent(Event("request", None, [['admin_promote', self.parameters[0], self.parameters[1]]]))
+        self.raiseInternalEvent(Event("request", None, [['admin_promote', self.parameters[0]]]))
     
     def _initialized_behaviour_operations_admin_demote_enter(self):
-        self.raiseInternalEvent(Event("request", None, [['admin_demote', self.parameters[0], self.parameters[1]]]))
+        self.raiseInternalEvent(Event("request", None, [['admin_demote', self.parameters[0]]]))
     
     def _initialized_behaviour_operations_conformance_delete_enter(self):
         self.raiseInternalEvent(Event("request", None, [['remove_conformance', self.parameters[0], self.parameters[1]]]))
@@ -2144,9 +2146,6 @@ class Modelverse(RuntimeClassBase):
     def _initialized_behaviour_operations_service_stop_enter(self):
         self.raiseInternalEvent(Event("request", None, [['service_stop']]))
     
-    def _initialized_behaviour_wait_for_action_megamodelling_enter(self):
-        print("Entered megamodelling with operation: " + str(self.actions))
-    
     def _initialized_behaviour_going_manual_init_enter(self):
         self.current_model = self.actions[0]["parameters"][0]
     
@@ -2182,95 +2181,101 @@ class Modelverse(RuntimeClassBase):
         return self.expect_response_partial('Model exists: ', pop=False)
     
     def _initialized_behaviour_operations_3_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['AttributeExists', self.split_response(self.responses.pop(0))[0]]))
+        self.raiseInternalEvent(Event("exception", None, ['FolderExists', self.split_response(self.responses.pop(0))[0]]))
     
     def _initialized_behaviour_operations_3_guard(self, parameters):
-        return self.expect_response_partial('Attribute exists: ', pop=False)
+        return self.expect_response_partial('Folder exists: ', pop=False)
     
     def _initialized_behaviour_operations_4_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['UnknownM3', self.split_response(self.responses.pop(0))[0]]))
+        self.raiseInternalEvent(Event("exception", None, ['AttributeExists', self.split_response(self.responses.pop(0))[0]]))
     
     def _initialized_behaviour_operations_4_guard(self, parameters):
-        return self.expect_response_partial('Type cannot be typed as formalisms/SimpleClassDiagrams: ', pop=False)
+        return self.expect_response_partial('Attribute exists: ', pop=False)
     
     def _initialized_behaviour_operations_5_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['ElementExists', self.split_response(self.responses.pop(0))[0]]))
+        self.raiseInternalEvent(Event("exception", None, ['UnknownM3', self.split_response(self.responses.pop(0))[0]]))
     
     def _initialized_behaviour_operations_5_guard(self, parameters):
-        return self.expect_response_partial('Element exists: ', pop=False)
+        return self.expect_response_partial('Type cannot be typed as formalisms/SimpleClassDiagrams: ', pop=False)
     
     def _initialized_behaviour_operations_6_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['ReadPermissionDenied', self.split_response(self.responses.pop(0))[0]]))
+        self.raiseInternalEvent(Event("exception", None, ['ElementExists', self.split_response(self.responses.pop(0))[0]]))
     
     def _initialized_behaviour_operations_6_guard(self, parameters):
-        return self.expect_response_partial('Read permission denied to: ', pop=False)
+        return self.expect_response_partial('Element exists: ', pop=False)
     
     def _initialized_behaviour_operations_7_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['WritePermissionDenied', self.split_response(self.responses.pop(0))[0]]))
+        self.raiseInternalEvent(Event("exception", None, ['ReadPermissionDenied', self.split_response(self.responses.pop(0))[0]]))
     
     def _initialized_behaviour_operations_7_guard(self, parameters):
-        return self.expect_response_partial('Write permission denied to: ', pop=False)
+        return self.expect_response_partial('Read permission denied to: ', pop=False)
     
     def _initialized_behaviour_operations_8_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['WritePermissionDenied', self.current_model]))
+        self.raiseInternalEvent(Event("exception", None, ['WritePermissionDenied', self.split_response(self.responses.pop(0))[0]]))
     
     def _initialized_behaviour_operations_8_guard(self, parameters):
-        return self.expect_response('Write permission denied', pop=True)
+        return self.expect_response_partial('Write permission denied to: ', pop=False)
     
     def _initialized_behaviour_operations_9_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['ExecutePermissionDenied', self.split_response(self.responses.pop(0))[0]]))
+        self.raiseInternalEvent(Event("exception", None, ['WritePermissionDenied', self.current_model]))
     
     def _initialized_behaviour_operations_9_guard(self, parameters):
-        return self.expect_response_partial('Execute permission denied to: ', pop=False)
+        return self.expect_response('Write permission denied', pop=True)
     
     def _initialized_behaviour_operations_10_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['GroupPermissionDenied', self.split_response(self.responses.pop(0))[0]]))
+        self.raiseInternalEvent(Event("exception", None, ['ExecutePermissionDenied', self.split_response(self.responses.pop(0))[0]]))
     
     def _initialized_behaviour_operations_10_guard(self, parameters):
-        return self.expect_response_partial('Group permission denied to: ', pop=False)
+        return self.expect_response_partial('Execute permission denied to: ', pop=False)
     
     def _initialized_behaviour_operations_11_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['UserPermissionDenied', self.split_response(self.responses.pop(0))[0]]))
+        self.raiseInternalEvent(Event("exception", None, ['GroupPermissionDenied', self.split_response(self.responses.pop(0))[0]]))
     
     def _initialized_behaviour_operations_11_guard(self, parameters):
-        return self.expect_response_partial('User permission denied to: ', pop=False)
+        return self.expect_response_partial('Group permission denied to: ', pop=False)
     
     def _initialized_behaviour_operations_12_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['AdminPermissionDenied', 'Admin permissions are required for this operation!']))
+        self.raiseInternalEvent(Event("exception", None, ['UserPermissionDenied', self.split_response(self.responses.pop(0))[0]]))
     
     def _initialized_behaviour_operations_12_guard(self, parameters):
-        return self.expect_response_partial('Admin permission denied', pop=True)
+        return self.expect_response_partial('User permission denied to: ', pop=False)
     
     def _initialized_behaviour_operations_13_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['InterfaceMismatch', self.split_response(self.responses.pop(0))[0]]))
+        self.raiseInternalEvent(Event("exception", None, ['AdminPermissionDenied', 'Admin permissions are required for this operation!']))
     
     def _initialized_behaviour_operations_13_guard(self, parameters):
-        return self.expect_response_partial('Incorrect format: ', pop=False)
+        return self.expect_response_partial('Admin permission denied', pop=True)
     
     def _initialized_behaviour_operations_14_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['UnknownElement', self.split_response(self.responses.pop(0))[0]]))
+        self.raiseInternalEvent(Event("exception", None, ['InterfaceMismatch', self.split_response(self.responses.pop(0))[0]]))
     
     def _initialized_behaviour_operations_14_guard(self, parameters):
-        return self.expect_response_partial('Element not found: ', pop=False)
+        return self.expect_response_partial('Incorrect format: ', pop=False)
     
     def _initialized_behaviour_operations_15_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['UnknownLocation', self.split_response(self.responses.pop(0))[0]]))
+        self.raiseInternalEvent(Event("exception", None, ['UnknownElement', self.split_response(self.responses.pop(0))[0]]))
     
     def _initialized_behaviour_operations_15_guard(self, parameters):
-        return self.expect_response_partial('Location not found: ', pop=False)
+        return self.expect_response_partial('Element not found: ', pop=False)
     
     def _initialized_behaviour_operations_16_exec(self, parameters):
-        self.raiseInternalEvent(Event("exception", None, ['UnknownMetamodellingHierarchy', 'Metamodelling hierarchy could not be resolved or automatically inferred: there is no typing relation between your specified model and metamodel (%s)' % self.responses.pop(0)]))
+        self.raiseInternalEvent(Event("exception", None, ['UnknownLocation', self.split_response(self.responses.pop(0))[0]]))
     
     def _initialized_behaviour_operations_16_guard(self, parameters):
-        return self.expect_response_partial('Conformance hierarchy unknown for: ', pop=False)
+        return self.expect_response_partial('Location not found: ', pop=False)
     
     def _initialized_behaviour_operations_17_exec(self, parameters):
+        self.raiseInternalEvent(Event("exception", None, ['UnknownMetamodellingHierarchy', 'Metamodelling hierarchy could not be resolved or automatically inferred: there is no typing relation between your specified model and metamodel (%s)' % self.responses.pop(0)]))
+    
+    def _initialized_behaviour_operations_17_guard(self, parameters):
+        return self.expect_response_partial('Conformance hierarchy unknown for: ', pop=False)
+    
+    def _initialized_behaviour_operations_18_exec(self, parameters):
         print("Unknown Error: " + self.responses[0])
         pass
         self.raiseInternalEvent(Event("exception", None, ['UnknownError', 'Error: %s' % self.responses.pop(0)]))
     
-    def _initialized_behaviour_operations_17_guard(self, parameters):
+    def _initialized_behaviour_operations_18_guard(self, parameters):
         return self.expect_response_partial('', pop=False)
     
     def _initialized_behaviour_wait_for_action_0_exec(self, parameters):
@@ -2864,7 +2869,7 @@ class Modelverse(RuntimeClassBase):
         return self.expect_response('Success')
     
     def _initialized_behaviour_operations_model_types_0_exec(self, parameters):
-        self.raiseInternalEvent(Event("result", None, [set([tuple(i.split(', ')) for i in self.split_response(self.responses.pop(0))])]))
+        self.raiseInternalEvent(Event("result", None, [set([tuple([j if j != 'None' else None for j in i.split(', ')]) for i in self.split_response(self.responses.pop(0))])]))
     
     def _initialized_behaviour_operations_model_types_0_guard(self, parameters):
         return self.expect_response_partial('Success: ')