bug 864 fix operation (created/edited) published to kafka
[osm/NBI.git] / osm_nbi / tests / test.py
index 2d7eff3..3033a34 100755 (executable)
@@ -26,6 +26,8 @@ from time import sleep
 from random import randint
 import os
 from sys import stderr
+from uuid import uuid4
+import re
 
 __author__ = "Alfonso Tierno, alfonso.tiernosepulveda@telefonica.com"
 __date__ = "$2018-03-01$"
@@ -81,6 +83,8 @@ headers_text = {"Accept": "text/plain,application/yaml"}
 r_header_zip = {"Content-type": "application/zip"}
 headers_zip = {"Accept": "application/zip,application/yaml"}
 headers_zip_yaml = {"Accept": "application/yaml", "Content-type": "application/zip"}
+headers_zip_json = {"Accept": "application/json", "Content-type": "application/zip"}
+headers_txt_json = {"Accept": "application/json", "Content-type": "text/plain"}
 r_headers_yaml_location_vnfd = {"Location": "/vnfpkgm/v1/vnf_packages_content/", "Content-Type": "application/yaml"}
 r_headers_yaml_location_nsd = {"Location": "/nsd/v1/ns_descriptors_content/", "Content-Type": "application/yaml"}
 r_headers_yaml_location_nst = {"Location": "/nst/v1/netslice_templates_content", "Content-Type": "application/yaml"}
@@ -346,7 +350,7 @@ class TestRest:
             vim_data = "{schema_version: '1.0', name: fakeVim, vim_type: openstack, vim_url: 'http://10.11.12.13/fake'"\
                        ", vim_tenant_name: 'vimtenant', vim_user: vimuser, vim_password: vimpassword}"
         self.test("Create VIM", "POST", "/admin/v1/vim_accounts", headers_yaml, vim_data,
-                  (201), {"Location": "/admin/v1/vim_accounts/", "Content-Type": "application/yaml"}, "yaml")
+                  (201, 202), {"Location": "/admin/v1/vim_accounts/", "Content-Type": "application/yaml"}, "yaml")
         return self.last_id
 
     def print_results(self):
@@ -454,102 +458,225 @@ class TestUsersProjects:
     @staticmethod
     def run(engine, test_osm, manual_check, test_params=None):
         engine.set_test_name("UserProject")
-        engine.get_autorization()
-        engine.test("Create project non admin", "POST", "/admin/v1/projects", headers_json, {"name": "P1"},
-                    (201, 204), {"Location": "/admin/v1/projects/", "Content-Type": "application/json"}, "json")
-        engine.test("Create project admin", "POST", "/admin/v1/projects", headers_json,
-                    {"name": "Padmin", "admin": True}, (201, 204),
-                    {"Location": "/admin/v1/projects/", "Content-Type": "application/json"}, "json")
-        engine.test("Create project bad format", "POST", "/admin/v1/projects", headers_json, {"name": 1}, (400, 422),
-                    r_header_json, "json")
-        engine.test("Create user with bad project", "POST", "/admin/v1/users", headers_json,
-                    {"username": "U1", "projects": ["P1", "P2", "Padmin"], "password": "pw1"}, 409,
-                    r_header_json, "json")
-        engine.test("Create user with bad project and force", "POST", "/admin/v1/users?FORCE=True", headers_json,
-                    {"username": "U1", "projects": ["P1", "P2", "Padmin"], "password": "pw1"}, 201,
-                    {"Location": "/admin/v1/users/", "Content-Type": "application/json"}, "json")
-        engine.test("Create user 2", "POST", "/admin/v1/users", headers_json,
-                    {"username": "U2", "projects": ["P1"], "password": "pw2"}, 201,
-                    {"Location": "/admin/v1/users/", "Content-Type": "application/json"}, "json")
-        engine.test("Edit user U1, delete  P2 project", "PATCH", "/admin/v1/users/U1", headers_json,
-                    {"projects": {"$'P2'": None}}, 204, None, None)
-        res = engine.test("Check user U1, contains the right projects", "GET", "/admin/v1/users/U1",
-                          headers_json, None, 200, None, json)
-        if res:
-            u1 = res.json()
-            # print(u1)
-            expected_projects = ["P1", "Padmin"]
-            if u1["projects"] != expected_projects:
-                logger.error("User content projects '{}' different than expected '{}'. Edition has not done"
-                             " properly".format(u1["projects"], expected_projects))
-                engine.failed_tests += 1
-
-        engine.test("Edit user U1, set Padmin as default project", "PUT", "/admin/v1/users/U1", headers_json,
-                    {"projects": {"$'Padmin'": None, "$+[0]": "Padmin"}}, 204, None, None)
-        res = engine.test("Check user U1, contains the right projects", "GET", "/admin/v1/users/U1",
-                          headers_json, None, 200, None, json)
-        if res:
-            u1 = res.json()
-            # print(u1)
-            expected_projects = ["Padmin", "P1"]
-            if u1["projects"] != expected_projects:
-                logger.error("User content projects '{}' different than expected '{}'. Edition has not done"
-                             " properly".format(u1["projects"], expected_projects))
-                engine.failed_tests += 1
+        # backend = test_params.get("backend") if test_params else None   # UNUSED
 
-        engine.test("Edit user U1, change password", "PATCH", "/admin/v1/users/U1", headers_json,
-                    {"password": "pw1_new"}, 204, None, None)
+        # Initialisation
+        p1 = p2 = p3 = None
+        padmin = pbad = None
+        u1 = u2 = u3 = u4 = None
 
-        engine.test("Change to project P1 non existing", "POST", "/admin/v1/tokens/", headers_json,
-                    {"project_id": "P1"}, 401, r_header_json, "json")
+        engine.get_autorization()
 
-        res = engine.test("Change to user U1 project P1", "POST", "/admin/v1/tokens", headers_json,
-                          {"username": "U1", "password": "pw1_new", "project_id": "P1"}, (200, 201),
-                          r_header_json, "json")
+        res = engine.test("Create project non admin 1", "POST", "/admin/v1/projects", headers_json, {"name": "P1"},
+                          (201, 204), {"Location": "/admin/v1/projects/", "Content-Type": "application/json"}, "json")
+        p1 = engine.last_id if res else None
+
+        res = engine.test("Create project admin", "POST", "/admin/v1/projects", headers_json,
+                          {"name": "Padmin", "admin": True}, (201, 204),
+                          {"Location": "/admin/v1/projects/", "Content-Type": "application/json"}, "json")
+        padmin = engine.last_id if res else None
+
+        res = engine.test("Create project bad format", "POST", "/admin/v1/projects", headers_json, {"name": 1},
+                          (400, 422), r_header_json, "json")
+        pbad = engine.last_id if res else None
+
+        res = engine.test("Get project admin role", "GET", "/admin/v1/roles?name=project_admin", headers_json, {},
+                          (200), {"Content-Type": "application/json"}, "json")
+        rpa = res.json()[0]["_id"] if res else None
+        res = engine.test("Get project user role", "GET", "/admin/v1/roles?name=project_user", headers_json, {},
+                          (200), {"Content-Type": "application/json"}, "json")
+        rpu = res.json()[0]["_id"] if res else None
+        res = engine.test("Get system admin role", "GET", "/admin/v1/roles?name=system_admin", headers_json, {},
+                          (200), {"Content-Type": "application/json"}, "json")
+        rsa = res.json()[0]["_id"] if res else None
+
+        data = {"username": "U1", "password": "pw1"}
+        p2 = uuid4().hex
+        data["project_role_mappings"] = [
+            {"project": p1, "role": rpa},
+            {"project": p2, "role": rpa},
+            {"project": padmin, "role": rpu}
+        ]
+        rc = 201
+        xhd = {"Location": "/admin/v1/users/", "Content-Type": "application/json"}
+        res = engine.test("Create user with bad project and force", "POST", "/admin/v1/users?FORCE=True", headers_json,
+                          data, rc, xhd, "json")
         if res:
-            response = res.json()
-            engine.set_header({"Authorization": "Bearer {}".format(response["id"])})
-
-        engine.test("Edit user projects non admin", "PUT", "/admin/v1/users/U1", headers_json,
-                    {"projects": {"$'P1'": None}}, 401, r_header_json, "json")
-        engine.test("Add new project non admin", "POST", "/admin/v1/projects", headers_json,
-                    {"name": "P2"}, 401, r_header_json, "json")
-        engine.test("Add new user non admin", "POST", "/admin/v1/users", headers_json,
-                    {"username": "U3", "projects": ["P1"], "password": "pw3"}, 401,
-                    r_header_json, "json")
+            u1 = engine.last_id
+        else:
+            # User is created sometimes even though an exception is raised
+            res = engine.test("Get user U1", "GET", "/admin/v1/users?username=U1", headers_json, {},
+                              (200), {"Content-Type": "application/json"}, "json")
+            u1 = res.json()[0]["_id"] if res else None
+
+        data = {"username": "U2", "password": "pw2"}
+        data["project_role_mappings"] = [{"project": p1, "role": rpa}, {"project": padmin, "role": rsa}]
+        res = engine.test("Create user 2", "POST", "/admin/v1/users", headers_json,
+                          data, 201, {"Location": "/admin/v1/users/", "Content-Type": "application/json"}, "json")
+        u2 = engine.last_id if res else None
+
+        if u1:
+            ftt = "project_role_mappings"
+            xpr = [{"project": p1, "role": rpa}, {"project": padmin, "role": rpu}]
+            data = {ftt: xpr}
+            engine.test("Edit user U1, delete  P2 project", "PATCH", "/admin/v1/users/"+u1, headers_json,
+                        data, 204, None, None)
+            res = engine.test("Check user U1, contains the right projects", "GET", "/admin/v1/users/"+u1,
+                              headers_json, None, 200, None, json)
+            if res:
+                rj = res.json()
+                xpr[0]["project_name"] = "P1"
+                xpr[0]["role_name"] = "project_admin"
+                xpr[1]["project_name"] = "Padmin"
+                xpr[1]["role_name"] = "project_user"
+                ok = True
+                for pr in rj[ftt]:
+                    if pr not in xpr:
+                        ok = False
+                for pr in xpr:
+                    if pr not in rj[ftt]:
+                        ok = False
+                if not ok:
+                    logger.error("User {} '{}' are different than expected '{}'. Edition was not done properly"
+                                 .format(ftt, rj[ftt], xpr))
+                    engine.failed_tests += 1
 
-        res = engine.test("Change to user U1 project Padmin", "POST", "/admin/v1/tokens", headers_json,
-                          {"project_id": "Padmin"}, (200, 201), r_header_json, "json")
-        if res:
-            response = res.json()
-            engine.set_header({"Authorization": "Bearer {}".format(response["id"])})
+        p2 = None   # To prevent deletion attempts
+
+        # Add a test of 'default project' for Keystone?
+
+        if u2:
+            engine.test("Edit user U2, change password", "PUT", "/admin/v1/users/"+u2, headers_json,
+                        {"password": "pw2_new"}, 204, None, None)
+
+        if p1:
+            engine.test("Change to project P1 non existing", "POST", "/admin/v1/tokens/", headers_json,
+                        {"project_id": p1}, 401, r_header_json, "json")
+
+        if u2 and p1:
+            res = engine.test("Change to user U2 project P1", "POST", "/admin/v1/tokens", headers_json,
+                              {"username": "U2", "password": "pw2_new", "project_id": "P1"}, (200, 201),
+                              r_header_json, "json")
+            if res:
+                rj = res.json()
+                engine.set_header({"Authorization": "Bearer {}".format(rj["id"])})
+
+                engine.test("Edit user projects non admin", "PUT", "/admin/v1/users/U1", headers_json,
+                            {"remove_project_role_mappings": [{"project": "P1", "role": None}]},
+                            401, r_header_json, "json")
+
+                res = engine.test("Add new project non admin", "POST", "/admin/v1/projects", headers_json,
+                                  {"name": "P2"}, 401, r_header_json, "json")
+                if res is None or res.status_code == 201:
+                    # The project has been created even though it shouldn't
+                    res = engine.test("Get project P2", "GET", "/admin/v1/projects/P2", headers_json, None,
+                                      200, r_header_json, "json")
+                    p2 = res.json()["_id"] if res else None
+
+                if p1:
+                    data = {"username": "U3", "password": "pw3"}
+                    data["project_role_mappings"] = [{"project": p1, "role": rpu}]
+                    res = engine.test("Add new user non admin", "POST", "/admin/v1/users", headers_json,
+                                      data, 401, r_header_json, "json")
+                    if res is None or res.status_code == 201:
+                        # The user has been created even though it shouldn't
+                        res = engine.test("Get user U3", "GET", "/admin/v1/users/U3", headers_json, None,
+                                          200, r_header_json, "json")
+                        u3 = res.json()["_id"] if res else None
+                else:
+                    u3 = None
+
+                if padmin:
+                    res = engine.test("Change to user U2 project Padmin", "POST", "/admin/v1/tokens", headers_json,
+                                      {"project_id": "Padmin"},   # Caused a Keystone authentication error
+                                      # {"username": "U2", "password": "pw2_new", "project_id": "Padmin"},
+                                      (200, 201), r_header_json, "json")
+                    if res:
+                        rj = res.json()
+                        engine.set_header({"Authorization": "Bearer {}".format(rj["id"])})
+
+                        res = engine.test("Add new project admin", "POST", "/admin/v1/projects", headers_json,
+                                          {"name": "P3"}, (201, 204),
+                                          {"Location": "/admin/v1/projects/", "Content-Type": "application/json"},
+                                          "json")
+                        p3 = engine.last_id if res else None
+
+                        if p1:
+                            data = {"username": "U4", "password": "pw4"}
+                            data["project_role_mappings"] = [{"project": p1, "role": rpa}]
+                            res = engine.test("Add new user admin", "POST", "/admin/v1/users", headers_json,
+                                              data, (201, 204),
+                                              {"Location": "/admin/v1/users/", "Content-Type": "application/json"},
+                                              "json")
+                            u4 = engine.last_id if res else None
+                        else:
+                            u4 = None
+
+                        if u4 and p3:
+                            data = {"project_role_mappings": [{"project": p3, "role": rpa}]}
+                            engine.test("Edit user projects admin", "PUT", "/admin/v1/users/U4", headers_json,
+                                        data, 204, None, None)
+                            # Project is deleted even though it shouldn't - PROVISIONAL?
+                            res = engine.test("Delete project P3 conflict", "DELETE", "/admin/v1/projects/"+p3,
+                                              headers_json, None, 409, None, None)
+                            if res and res.status_code in (200, 204):
+                                p3 = None
+                            if p3:
+                                res = engine.test("Delete project P3 forcing", "DELETE",
+                                                  "/admin/v1/projects/"+p3+"?FORCE=True", headers_json, None, 204,
+                                                  None, None)
+                                if res and res.status_code in (200, 204):
+                                    p3 = None
+
+                        if u2:
+                            res = engine.test("Delete user U2. Conflict deleting own user", "DELETE",
+                                              "/admin/v1/users/"+u2, headers_json, None, 409, r_header_json, "json")
+                            if res is None or res.status_code in (200, 204):
+                                u2 = None
+                        if u4:
+                            res = engine.test("Delete user U4", "DELETE", "/admin/v1/users/"+u4, headers_json, None,
+                                              204, None, None)
+                            if res and res.status_code in (200, 204):
+                                u4 = None
+                        if p3:
+                            res = engine.test("Delete project P3", "DELETE", "/admin/v1/projects/"+p3, headers_json,
+                                              None, 204, None, None)
+                            if res and res.status_code in (200, 204):
+                                p3 = None
+
+                if u3:
+                    res = engine.test("Delete user U3", "DELETE", "/admin/v1/users/"+u3, headers_json, None,
+                                      204, None, None)
+                    if res:
+                        u3 = None
 
-        engine.test("Add new project admin", "POST", "/admin/v1/projects", headers_json, {"name": "P2"},
-                    (201, 204), {"Location": "/admin/v1/projects/", "Content-Type": "application/json"}, "json")
-        engine.test("Add new user U3 admin", "POST", "/admin/v1/users",
-                    headers_json, {"username": "U3", "projects": ["P2"], "password": "pw3"}, (201, 204),
-                    {"Location": "/admin/v1/users/", "Content-Type": "application/json"}, "json")
-        engine.test("Edit user projects admin", "PUT", "/admin/v1/users/U3", headers_json,
-                    {"projects": ["P2"]}, 204, None, None)
-
-        engine.test("Delete project P2 conflict", "DELETE", "/admin/v1/projects/P2", headers_json, None, 409,
-                    r_header_json, "json")
-        engine.test("Delete project P2 forcing", "DELETE", "/admin/v1/projects/P2?FORCE=True", headers_json,
-                    None, 204, None, None)
-
-        engine.test("Delete user U1. Conflict deleting own user", "DELETE", "/admin/v1/users/U1", headers_json,
-                    None, 409, r_header_json, "json")
-        engine.test("Delete user U2", "DELETE", "/admin/v1/users/U2", headers_json, None, 204, None, None)
-        engine.test("Delete user U3", "DELETE", "/admin/v1/users/U3", headers_json, None, 204, None, None)
         # change to admin
         engine.remove_authorization()   # To force get authorization
         engine.get_autorization()
-        engine.test("Delete user U1 by Name", "DELETE", "/admin/v1/users/U1", headers_json, None, 204, None, None)
-        engine.test("Delete project P1 by Name", "DELETE", "/admin/v1/projects/P1", headers_json, None, 204, None, None)
-        engine.test("Delete project Padmin by Name", "DELETE", "/admin/v1/projects/Padmin", headers_json, None, 204,
-                    None, None)
+        if u1:
+            engine.test("Delete user U1", "DELETE", "/admin/v1/users/"+u1, headers_json, None, 204, None, None)
+        if u2:
+            engine.test("Delete user U2", "DELETE", "/admin/v1/users/"+u2, headers_json, None, 204, None, None)
+        if u3:
+            engine.test("Delete user U3", "DELETE", "/admin/v1/users/"+u3, headers_json, None, 204, None, None)
+        if u4:
+            engine.test("Delete user U4", "DELETE", "/admin/v1/users/"+u4, headers_json, None, 204, None, None)
+        if p1:
+            engine.test("Delete project P1", "DELETE", "/admin/v1/projects/"+p1, headers_json, None, 204, None, None)
+        if p2:
+            engine.test("Delete project P2", "DELETE", "/admin/v1/projects/"+p2, headers_json, None, 204, None, None)
+        if p3:
+            engine.test("Delete project P3", "DELETE", "/admin/v1/projects/"+p3, headers_json, None, 204, None, None)
+        if padmin:
+            engine.test("Delete project Padmin", "DELETE", "/admin/v1/projects/"+padmin, headers_json, None, 204,
+                        None, None)
+        if pbad:
+            engine.test("Delete bad project", "DELETE", "/admin/v1/projects/"+pbad, headers_json, None, 204,
+                        None, None)
 
         # BEGIN New Tests - Addressing Projects/Users by Name/ID
+        pid1 = pid2 = None
+        uid1 = uid2 = None
         res = engine.test("Create new project P1", "POST", "/admin/v1/projects", headers_json, {"name": "P1"},
                           201, {"Location": "/admin/v1/projects/", "Content-Type": "application/json"}, "json")
         if res:
@@ -560,39 +687,90 @@ class TestUsersProjects:
         if res:
             pid2 = res.json()["id"]
             # print("# pid =", pid2)
-        res = engine.test("Create new user U1", "POST", "/admin/v1/users", headers_json,
-                          {"username": "U1", "projects": ["P1"], "password": "pw1"}, 201,
+        data = {"username": "U1", "password": "pw1"}
+        data["project_role_mappings"] = [{"project": pid1, "role": rpu}]
+        res = engine.test("Create new user U1", "POST", "/admin/v1/users", headers_json, data, 201,
                           {"Location": "/admin/v1/users/", "Content-Type": "application/json"}, "json")
         if res:
             uid1 = res.json()["id"]
             # print("# uid =", uid1)
-        res = engine.test("Create new user U2", "POST", "/admin/v1/users", headers_json,
-                          {"username": "U2", "projects": ["P2"], "password": "pw2"}, 201,
+        data = {"username": "U2", "password": "pw2"}
+        data["project_role_mappings"] = [{"project": pid2, "role": rpu}]
+        res = engine.test("Create new user U2", "POST", "/admin/v1/users", headers_json, data, 201,
                           {"Location": "/admin/v1/users/", "Content-Type": "application/json"}, "json")
         if res:
             uid2 = res.json()["id"]
             # print("# uid =", uid2)
-        engine.test("Get Project P1 by Name", "GET", "/admin/v1/projects/P1", headers_json, None, 200, None, "json")
-        engine.test("Get Project P1 by ID", "GET", "/admin/v1/projects/"+pid1, headers_json, None, 200, None, "json")
-        engine.test("Get User U1 by Name", "GET", "/admin/v1/users/U1", headers_json, None, 200, None, "json")
-        engine.test("Get User U1 by ID", "GET", "/admin/v1/users/"+uid1, headers_json, None, 200, None, "json")
-        engine.test("Rename Project P1 by Name", "PUT", "/admin/v1/projects/P1", headers_json,
-                    {"name": "P3"}, 204, None, None)
-        engine.test("Rename Project P2 by ID", "PUT", "/admin/v1/projects/"+pid2, headers_json,
-                    {"name": "P4"}, 204, None, None)
-        engine.test("Rename User U1 by Name", "PUT", "/admin/v1/users/U1", headers_json,
-                    {"username": "U3"}, 204, None, None)
-        engine.test("Rename User U2 by ID", "PUT", "/admin/v1/users/"+uid2, headers_json,
-                    {"username": "U4"}, 204, None, None)
-        engine.test("Get Project P1 by new Name", "GET", "/admin/v1/projects/P3", headers_json, None, 200, None, "json")
-        engine.test("Get User U1 by new Name", "GET", "/admin/v1/users/U3", headers_json, None, 200, None, "json")
-        engine.test("Delete User U1 by Name", "DELETE", "/admin/v1/users/U3", headers_json, None, 204, None, None)
-        engine.test("Delete User U2 by ID", "DELETE", "/admin/v1/users/"+uid2, headers_json, None, 204, None, None)
-        engine.test("Delete Project P1 by Name", "DELETE", "/admin/v1/projects/P3", headers_json, None, 204, None,
-                    None)
-        engine.test("Delete Project P2 by ID", "DELETE", "/admin/v1/projects/"+pid2, headers_json, None, 204, None,
-                    None)
+        if pid1:
+            engine.test("Get Project P1 by Name", "GET", "/admin/v1/projects/P1", headers_json, None,
+                        200, None, "json")
+            engine.test("Get Project P1 by ID", "GET", "/admin/v1/projects/"+pid1, headers_json, None,
+                        200, None, "json")
+        if uid1:
+            engine.test("Get User U1 by Name", "GET", "/admin/v1/users/U1", headers_json, None, 200, None, "json")
+            engine.test("Get User U1 by ID", "GET", "/admin/v1/users/"+uid1, headers_json, None, 200, None, "json")
+        if pid1:
+            res = engine.test("Rename Project P1 by Name", "PUT", "/admin/v1/projects/P1", headers_json,
+                              {"name": "P3"}, 204, None, None)
+            if res:
+                engine.test("Get Project P1 by new Name", "GET", "/admin/v1/projects/P3", headers_json, None,
+                            200, None, "json")
+        if pid2:
+            res = engine.test("Rename Project P2 by ID", "PUT", "/admin/v1/projects/"+pid2, headers_json,
+                              {"name": "P4"}, 204, None, None)
+            if res:
+                engine.test("Get Project P2 by new Name", "GET", "/admin/v1/projects/P4", headers_json, None,
+                            200, None, "json")
+
+        if uid1:
+            res = engine.test("Rename User U1 by Name", "PUT", "/admin/v1/users/U1", headers_json,
+                              {"username": "U3"}, 204, None, None)
+            if res:
+                engine.test("Get User U1 by new Name", "GET", "/admin/v1/users/U3", headers_json, None,
+                            200, None, "json")
+
+        if uid2:
+            res = engine.test("Rename User U2 by ID", "PUT", "/admin/v1/users/"+uid2, headers_json,
+                              {"username": "U4"}, 204, None, None)
+            if res:
+                engine.test("Get User U2 by new Name", "GET", "/admin/v1/users/U4", headers_json, None,
+                            200, None, "json")
+        if uid1:
+            res = engine.test("Delete User U1 by Name", "DELETE", "/admin/v1/users/U3", headers_json, None,
+                              204, None, None)
+            if res:
+                uid1 = None
+
+        if uid2:
+            res = engine.test("Delete User U2 by ID", "DELETE", "/admin/v1/users/"+uid2, headers_json, None,
+                              204, None, None)
+            if res:
+                uid2 = None
+
+        if pid1:
+            res = engine.test("Delete Project P1 by Name", "DELETE", "/admin/v1/projects/P3", headers_json, None,
+                              204, None, None)
+            if res:
+                pid1 = None
+
+        if pid2:
+            res = engine.test("Delete Project P2 by ID", "DELETE", "/admin/v1/projects/"+pid2, headers_json, None,
+                              204, None, None)
+            if res:
+                pid2 = None
+
         # END New Tests - Addressing Projects/Users by Name
+
+        # CLEANUP
+        if pid1:
+            engine.test("Delete Project P1", "DELETE", "/admin/v1/projects/"+pid1, headers_json, None, 204, None, None)
+        if pid2:
+            engine.test("Delete Project P2", "DELETE", "/admin/v1/projects/"+pid2, headers_json, None, 204, None, None)
+        if uid1:
+            engine.test("Delete User U1", "DELETE", "/admin/v1/users/"+uid1, headers_json, None, 204, None, None)
+        if uid2:
+            engine.test("Delete User U2", "DELETE", "/admin/v1/users/"+uid2, headers_json, None, 204, None, None)
+
         engine.remove_authorization()   # To finish
 
 
@@ -604,6 +782,13 @@ class TestProjectsDescriptors:
         vnfd_ids = []
         engine.set_test_name("ProjectDescriptors")
         engine.get_autorization()
+
+        project_admin_id = None
+        res = engine.test("Get my project Padmin", "GET", "/admin/v1/projects/{}".format(engine.project), headers_json,
+                          None, 200, r_header_json, "json")
+        if res:
+            response = res.json()
+            project_admin_id = response["_id"]
         engine.test("Create project Padmin", "POST", "/admin/v1/projects", headers_json,
                     {"name": "Padmin", "admin": True}, (201, 204),
                     {"Location": "/admin/v1/projects/", "Content-Type": "application/json"}, "json")
@@ -613,8 +798,11 @@ class TestProjectsDescriptors:
                     (201, 204), {"Location": "/admin/v1/projects/", "Content-Type": "application/json"}, "json")
 
         engine.test("Create user U1", "POST", "/admin/v1/users", headers_json,
-                    {"username": "U1", "projects": ["Padmin", "P2", "P3"], "password": "pw1"}, 201,
-                    {"Location": "/admin/v1/users/", "Content-Type": "application/json"}, "json")
+                    {"username": "U1", "password": "pw1",
+                     "project_role_mappings": [{"project": "Padmin", "role": "system_admin"},
+                                               {"project": "P2", "role": "project_admin"},
+                                               {"project": "P3", "role": "project_admin"}],
+                     }, 201, {"Location": "/admin/v1/users/", "Content-Type": "application/json"}, "json")
 
         engine.test("Onboard VNFD id1", "POST", "/vnfpkgm/v1/vnf_packages_content?id=id1", headers_yaml,
                     TestDescriptors.vnfd_empty, 201, r_headers_yaml_location_vnfd, "yaml")
@@ -658,12 +846,14 @@ class TestProjectsDescriptors:
             engine.failed_tests += 1
 
         # list vnfds belonging to project "admin"
-        res = engine.test("List VNFD of admin project", "GET", "/vnfpkgm/v1/vnf_packages?ADMIN=admin",
+        res = engine.test("List VNFD of admin project", "GET",
+                          "/vnfpkgm/v1/vnf_packages?ADMIN={}".format(project_admin_id),
                           headers_json, None, 200, r_header_json, "json")
-        response = res.json()
-        if len(response) != 3:
-            logger.error("Only 3 vnfds should be present for project Padmin. {} listed".format(len(response)))
-            engine.failed_tests += 1
+        if res:
+            response = res.json()
+            if len(response) != 3:
+                logger.error("Only 3 vnfds should be present for project Padmin. {} listed".format(len(response)))
+                engine.failed_tests += 1
 
         # Get Public vnfds
         engine.test("Get VNFD public descriptors", "GET", "/vnfpkgm/v1/vnf_packages/{}".format(vnfd_ids[1]),
@@ -769,7 +959,7 @@ class TestFakeVim:
 
         engine.set_test_name("FakeVim")
         engine.get_autorization()
-        engine.test("Create VIM", "POST", "/admin/v1/vim_accounts", headers_json, self.vim, (201, 204),
+        engine.test("Create VIM", "POST", "/admin/v1/vim_accounts", headers_json, self.vim, (201, 202),
                     {"Location": "/admin/v1/vim_accounts/", "Content-Type": "application/json"}, "json")
         vim_id = engine.last_id
         engine.test("Create VIM without name, bad schema", "POST", "/admin/v1/vim_accounts", headers_json,
@@ -814,28 +1004,28 @@ class TestVIMSDN(TestFakeVim):
         engine.set_test_name("VimSdn")
         engine.get_autorization()
         # Added SDN
-        engine.test("Create SDN", "POST", "/admin/v1/sdns", headers_json, self.sdn, (201, 204),
+        engine.test("Create SDN", "POST", "/admin/v1/sdns", headers_json, self.sdn, (201, 202),
                     {"Location": "/admin/v1/sdns/", "Content-Type": "application/json"}, "json")
         sdnc_id = engine.last_id
         # sleep(5)
         # Edit SDN
         engine.test("Edit SDN", "PATCH", "/admin/v1/sdns/{}".format(sdnc_id), headers_json, {"name": "new_sdn_name"},
-                    204, None, None)
+                    (202, 204), None, None)
         # sleep(5)
         # VIM with SDN
         self.vim["config"]["sdn-controller"] = sdnc_id
         self.vim["config"]["sdn-port-mapping"] = self.port_mapping
-        engine.test("Create VIM", "POST", "/admin/v1/vim_accounts", headers_json, self.vim, (200, 204, 201),
+        engine.test("Create VIM", "POST", "/admin/v1/vim_accounts", headers_json, self.vim, (200, 202, 201),
                     {"Location": "/admin/v1/vim_accounts/", "Content-Type": "application/json"}, "json"),
 
         vim_id = engine.last_id
         self.port_mapping[0]["compute_node"] = "compute node XX"
         engine.test("Edit VIM change port-mapping", "PUT", "/admin/v1/vim_accounts/{}".format(vim_id), headers_json,
-                    {"config": {"sdn-port-mapping": self.port_mapping}}, 204, None, None)
+                    {"config": {"sdn-port-mapping": self.port_mapping}}, (202, 204), None, None)
         engine.test("Edit VIM remove port-mapping", "PUT", "/admin/v1/vim_accounts/{}".format(vim_id), headers_json,
-                    {"config": {"sdn-port-mapping": None}}, 204, None, None)
+                    {"config": {"sdn-port-mapping": None}}, (202, 204), None, None)
 
-        engine.test("Create WIM", "POST", "/admin/v1/wim_accounts", headers_json, self.wim, (200, 204, 201),
+        engine.test("Create WIM", "POST", "/admin/v1/wim_accounts", headers_json, self.wim, (200, 202, 201),
                     {"Location": "/admin/v1/wim_accounts/", "Content-Type": "application/json"}, "json"),
         wim_id = engine.last_id
 
@@ -991,14 +1181,14 @@ class TestDeploy:
         ns_data_text = yaml.safe_dump(ns_data, default_flow_style=True, width=256)
         # create NS Two steps
         r = engine.test("Create NS step 1", "POST", "/nslcm/v1/ns_instances",
-                        headers_yaml, ns_data_text, 201,
+                        headers_yaml, ns_data_text, (201, 202),
                         {"Location": "nslcm/v1/ns_instances/", "Content-Type": "application/yaml"}, "yaml")
         if not r:
             return
         self.ns_id = engine.last_id
         engine.test("Instantiate NS step 2", "POST",
                     "/nslcm/v1/ns_instances/{}/instantiate".format(self.ns_id), headers_yaml, ns_data_text,
-                    201, r_headers_yaml_location_nslcmop, "yaml")
+                    (201, 202), r_headers_yaml_location_nslcmop, "yaml")
         nslcmop_id = engine.last_id
 
         if test_osm:
@@ -1010,7 +1200,7 @@ class TestDeploy:
         # remove deployment
         if test_osm:
             engine.test("Terminate NS", "POST", "/nslcm/v1/ns_instances/{}/terminate".format(self.ns_id), headers_yaml,
-                        None, 201, r_headers_yaml_location_nslcmop, "yaml")
+                        None, (201, 202), r_headers_yaml_location_nslcmop, "yaml")
             nslcmop2_id = engine.last_id
             # Wait until status is Ok
             engine.wait_operation_ready("ns", nslcmop2_id, timeout_deploy)
@@ -1152,7 +1342,7 @@ class TestDeploy:
             ns_data.update(self.ns_params)
         if test_params and test_params.get("ns-config"):
             if isinstance(test_params["ns-config"], str):
-                ns_data.update(yaml.load(test_params["ns-config"]))
+                ns_data.update(yaml.load(test_params["ns-config"]), Loader=yaml.Loader)
             else:
                 ns_data.update(test_params["ns-config"])
         self.instantiate(engine, ns_data)
@@ -1275,7 +1465,7 @@ class TestDeployHackfestCirrosScaling(TestDeploy):
         for i in range(0, 2):
             engine.test("Execute scale action over NS", "POST",
                         "/nslcm/v1/ns_instances/{}/scale".format(self.ns_id), headers_yaml, payload,
-                        201, r_headers_yaml_location_nslcmop, "yaml")
+                        (201, 202), r_headers_yaml_location_nslcmop, "yaml")
             nslcmop2_scale_out = engine.last_id
             engine.wait_operation_ready("ns", nslcmop2_scale_out, timeout_deploy)
             if manual_check:
@@ -1288,7 +1478,7 @@ class TestDeployHackfestCirrosScaling(TestDeploy):
         for i in range(0, 2):
             engine.test("Execute scale IN action over NS", "POST",
                         "/nslcm/v1/ns_instances/{}/scale".format(self.ns_id), headers_yaml, payload,
-                        201, r_headers_yaml_location_nslcmop, "yaml")
+                        (201, 202), r_headers_yaml_location_nslcmop, "yaml")
             nslcmop2_scale_in = engine.last_id
             engine.wait_operation_ready("ns", nslcmop2_scale_in, timeout_deploy)
             if manual_check:
@@ -1298,7 +1488,7 @@ class TestDeployHackfestCirrosScaling(TestDeploy):
         # perform scale in that must fail as reached limit
         engine.test("Execute scale IN out of limit action over NS", "POST",
                     "/nslcm/v1/ns_instances/{}/scale".format(self.ns_id), headers_yaml, payload,
-                    201, r_headers_yaml_location_nslcmop, "yaml")
+                    (201, 202), r_headers_yaml_location_nslcmop, "yaml")
         nslcmop2_scale_in = engine.last_id
         engine.wait_operation_ready("ns", nslcmop2_scale_in, timeout_deploy, expected_fail=True)
 
@@ -1478,7 +1668,7 @@ class TestDeployHackfest3Charmed(TestDeploy):
         payload = '{member_vnf_index: "2", primitive: touch, primitive_params: { filename: /home/ubuntu/OSMTESTNBI }}'
         engine.test("Exec service primitive over NS", "POST",
                     "/nslcm/v1/ns_instances/{}/action".format(self.ns_id), headers_yaml, payload,
-                    201, r_headers_yaml_location_nslcmop, "yaml")
+                    (201, 202), r_headers_yaml_location_nslcmop, "yaml")
         nslcmop2_action = engine.last_id
         # Wait until status is Ok
         engine.wait_operation_ready("ns", nslcmop2_action, timeout_deploy)
@@ -1497,7 +1687,7 @@ class TestDeployHackfest3Charmed(TestDeploy):
         #           '{scaling-group-descriptor: scale_dataVM, member-vnf-index: "1"}}}'
         # engine.test("Execute scale action over NS", "POST",
         #             "/nslcm/v1/ns_instances/{}/scale".format(self.ns_id), headers_yaml, payload,
-        #             201, r_headers_yaml_location_nslcmop, "yaml")
+        #             (201, 202), r_headers_yaml_location_nslcmop, "yaml")
         # nslcmop2_scale_out = engine.last_id
         # engine.wait_operation_ready("ns", nslcmop2_scale_out, timeout_deploy)
         # if manual_check:
@@ -1509,7 +1699,7 @@ class TestDeployHackfest3Charmed(TestDeploy):
         #           '{scaling-group-descriptor: scale_dataVM, member-vnf-index: "1"}}}'
         # engine.test("Execute scale action over NS", "POST",
         #             "/nslcm/v1/ns_instances/{}/scale".format(self.ns_id), headers_yaml, payload,
-        #             201, r_headers_yaml_location_nslcmop, "yaml")
+        #             (201, 202), r_headers_yaml_location_nslcmop, "yaml")
         # nslcmop2_scale_in = engine.last_id
         # engine.wait_operation_ready("ns", nslcmop2_scale_in, timeout_deploy)
         # if manual_check:
@@ -1643,7 +1833,8 @@ class TestDeployHackfest3Charmed3(TestDeployHackfest3Charmed):
                             parameter:
                                 "$[0]":
                                     default-value: "<touch_filename2>"
-                """)
+                """,
+                Loader=yaml.Loader)
         }
         self.ns_params = {
             "additionalParamsForVnf": [
@@ -1664,7 +1855,7 @@ class TestDeployHackfest3Charmed3(TestDeployHackfest3Charmed):
                   '{scaling-group-descriptor: scale_dataVM, member-vnf-index: "1"}}}'
         engine.test("Execute scale action over NS", "POST",
                     "/nslcm/v1/ns_instances/{}/scale".format(self.ns_id), headers_yaml, payload,
-                    201, r_headers_yaml_location_nslcmop, "yaml")
+                    (201, 202), r_headers_yaml_location_nslcmop, "yaml")
         nslcmop2_scale_out = engine.last_id
         engine.wait_operation_ready("ns", nslcmop2_scale_out, timeout_deploy)
         if manual_check:
@@ -1679,7 +1870,7 @@ class TestDeployHackfest3Charmed3(TestDeployHackfest3Charmed):
                   '{scaling-group-descriptor: scale_dataVM, member-vnf-index: "1"}}}'
         engine.test("Execute scale action over NS", "POST",
                     "/nslcm/v1/ns_instances/{}/scale".format(self.ns_id), headers_yaml, payload,
-                    201, r_headers_yaml_location_nslcmop, "yaml")
+                    (201, 202), r_headers_yaml_location_nslcmop, "yaml")
         nslcmop2_scale_in = engine.last_id
         engine.wait_operation_ready("ns", nslcmop2_scale_in, timeout_deploy)
         if manual_check:
@@ -1945,7 +2136,7 @@ class TestDeployHnfd(TestDeployHackfest3Charmed):
                    "vimAccountId": self.vim_id}
         if test_params and test_params.get("ns-config"):
             if isinstance(test_params["ns-config"], str):
-                ns_data.update(yaml.load(test_params["ns-config"]))
+                ns_data.update(yaml.load(test_params["ns-config"]), Loader=yaml.Loader)
             else:
                 ns_data.update(test_params["ns-config"])
 
@@ -2238,7 +2429,7 @@ class TestNetSliceInstances:
     def create_slice(self, engine, nsi_data, name):
         ns_data_text = yaml.safe_dump(nsi_data, default_flow_style=True, width=256)
         r = engine.test(name, "POST", "/nsilcm/v1/netslice_instances",
-                        headers_yaml, ns_data_text, 201,
+                        headers_yaml, ns_data_text, (201, 202),
                         {"Location": "nsilcm/v1/netslice_instances/", "Content-Type": "application/yaml"}, "yaml")
         return r
 
@@ -2246,11 +2437,11 @@ class TestNetSliceInstances:
         ns_data_text = yaml.safe_dump(nsi_data, default_flow_style=True, width=256)
         engine.test(name, "POST",
                     "/nsilcm/v1/netslice_instances/{}/instantiate".format(nsi_id), headers_yaml, ns_data_text,
-                    201, r_headers_yaml_location_nsilcmop, "yaml")
+                    (201, 202), r_headers_yaml_location_nsilcmop, "yaml")
 
     def terminate_slice(self, engine, nsi_id, name):
         engine.test(name, "POST", "/nsilcm/v1/netslice_instances/{}/terminate".format(nsi_id),
-                    headers_yaml, None, 201, r_headers_yaml_location_nsilcmop, "yaml")
+                    headers_yaml, None, (201, 202), r_headers_yaml_location_nsilcmop, "yaml")
 
     def delete_slice(self, engine, nsi_id, name):
         engine.test(name, "DELETE", "/nsilcm/v1/netslice_instances/{}".format(nsi_id), headers_yaml, None,
@@ -2396,6 +2587,533 @@ class TestNetSliceInstances:
                        headers_yaml, None, 204, None, 0)
 
 
+class TestAuthentication:
+    description = "Test Authentication"
+
+    @staticmethod
+    def run(engine, test_osm, manual_check, test_params=None):
+        engine.set_test_name("Authentication")
+        # backend = test_params.get("backend") if test_params else None   # UNUSED
+
+        admin_project_id = test_project_id = None
+        project_admin_role_id = project_user_role_id = None
+        test_user_id = empty_user_id = None
+        default_role_id = empty_role_id = token_role_id = None
+
+        engine.get_autorization()
+
+        # GET
+        engine.test("Get tokens", "GET", "/admin/v1/tokens", headers_json, {},
+                    (200), {"Content-Type": "application/json"}, "json")
+        engine.test("Get projects", "GET", "/admin/v1/projects", headers_json, {},
+                    (200), {"Content-Type": "application/json"}, "json")
+        engine.test("Get users", "GET", "/admin/v1/users", headers_json, {},
+                    (200), {"Content-Type": "application/json"}, "json")
+        engine.test("Get roles", "GET", "/admin/v1/roles", headers_json, {},
+                    (200), {"Content-Type": "application/json"}, "json")
+        res = engine.test("Get admin project", "GET", "/admin/v1/projects?name=admin", headers_json, {},
+                          (200), {"Content-Type": "application/json"}, "json")
+        admin_project_id = res.json()[0]["_id"] if res else None
+        res = engine.test("Get project admin role", "GET", "/admin/v1/roles?name=project_admin", headers_json, {},
+                          (200), {"Content-Type": "application/json"}, "json")
+        project_admin_role_id = res.json()[0]["_id"] if res else None
+        res = engine.test("Get project user role", "GET", "/admin/v1/roles?name=project_user", headers_json, {},
+                          (200), {"Content-Type": "application/json"}, "json")
+        project_user_role_id = res.json()[0]["_id"] if res else None
+
+        # POST
+        res = engine.test("Create test project", "POST", "/admin/v1/projects", headers_json, {"name": "test"},
+                          (201), {"Location": "/admin/v1/projects/", "Content-Type": "application/json"}, "json")
+        test_project_id = engine.last_id if res else None
+        res = engine.test("Create role without permissions", "POST", "/admin/v1/roles", headers_json, {"name": "empty"},
+                          (201), {"Content-Type": "application/json"}, "json")
+        empty_role_id = engine.last_id if res else None
+        res = engine.test("Create role with default permissions", "POST", "/admin/v1/roles", headers_json,
+                          {"name": "default", "permissions": {"default": True}},
+                          (201), {"Location": "/admin/v1/roles/", "Content-Type": "application/json"}, "json")
+        default_role_id = engine.last_id if res else None
+        res = engine.test("Create role with token permissions", "POST", "/admin/v1/roles", headers_json,
+                          {"name": "tokens", "permissions": {"tokens": True}},   # is default required ?
+                          (201), {"Location": "/admin/v1/roles/", "Content-Type": "application/json"}, "json")
+        token_role_id = engine.last_id if res else None
+        pr = "project-role mappings"
+        res = engine.test("Create user without "+pr, "POST", "/admin/v1/users", headers_json,
+                          {"username": "empty", "password": "empty"},
+                          201, {"Content-Type": "application/json"}, "json")
+        empty_user_id = engine.last_id if res else None
+        if admin_project_id and test_project_id and project_admin_role_id and project_user_role_id:
+            data = {"username": "test", "password": "test"}
+            data["project_role_mappings"] = [
+                {"project": test_project_id, "role": project_admin_role_id},
+                {"project": admin_project_id, "role": project_user_role_id}
+            ]
+            res = engine.test("Create user with "+pr, "POST", "/admin/v1/users", headers_json, data,
+                              (201), {"Content-Type": "application/json"}, "json")
+            test_user_id = engine.last_id if res else None
+
+        # PUT
+        if test_user_id:
+            engine.test("Modify test user's password", "PUT", "/admin/v1/users/"+test_user_id, headers_json,
+                        {"password": "password"},
+                        (204), {}, 0)
+        if empty_user_id and admin_project_id and test_project_id and project_admin_role_id and project_user_role_id:
+            data = {"project_role_mappings": [
+                {"project": test_project_id, "role": project_admin_role_id},
+                {"project": admin_project_id, "role": project_user_role_id}
+            ]}
+            engine.test("Modify empty user's "+pr, "PUT", "/admin/v1/users/"+empty_user_id,
+                        headers_json,
+                        data,
+                        (204), {}, 0)
+
+        # DELETE
+        if empty_user_id:
+            engine.test("Delete empty user", "DELETE", "/admin/v1/users/"+empty_user_id, headers_json, {},
+                        (204), {}, 0)
+        if test_user_id:
+            engine.test("Delete test user", "DELETE", "/admin/v1/users/"+test_user_id, headers_json, {},
+                        (204), {}, 0)
+        if empty_role_id:
+            engine.test("Delete empty role", "DELETE", "/admin/v1/roles/"+empty_role_id, headers_json, {},
+                        (204), {}, 0)
+        if default_role_id:
+            engine.test("Delete default role", "DELETE", "/admin/v1/roles/"+default_role_id, headers_json, {},
+                        (204), {}, 0)
+        if token_role_id:
+            engine.test("Delete token role", "DELETE", "/admin/v1/roles/"+token_role_id, headers_json, {},
+                        (204), {}, 0)
+        if test_project_id:
+            engine.test("Delete test project", "DELETE", "/admin/v1/projects/"+test_project_id, headers_json, {},
+                        (204), {}, 0)
+
+        # END Tests
+
+        engine.remove_authorization()   # To finish
+
+
+class TestNbiQuotas():
+    description = "Test NBI Quotas"
+
+    @staticmethod
+    def run(engine, test_osm, manual_check, test_params=None):
+        engine.set_test_name("NBI-Quotas_")
+        # backend = test_params.get("backend") if test_params else None   # UNUSED
+
+        test_username = "test-nbi-quotas"
+        test_password = "test-nbi-quotas"
+        test_project = "test-nbi-quotas"
+
+        test_vim = "test-nbi-quotas"
+        test_wim = "test-nbi-quotas"
+        test_sdn = "test-nbi-quotas"
+
+        test_user_id = None
+        test_project_id = None
+
+        test_vim_ids = []
+        test_wim_ids = []
+        test_sdn_ids = []
+        test_vnfd_ids = []
+        test_nsd_ids = []
+        test_nst_ids = []
+        test_pdu_ids = []
+        test_nsr_ids = []
+        test_nsi_ids = []
+
+        # Save admin access data
+        admin_username = engine.user
+        admin_password = engine.password
+        admin_project = engine.project
+
+        # Get admin access
+        engine.get_autorization()
+        admin_token = engine.last_id
+
+        # Check that test project,user do not exist
+        res1 = engine.test("Check that test project doesn't exist", "GET", "/admin/v1/projects/"+test_project,
+                           headers_json, {}, (404), {}, True)
+        res2 = engine.test("Check that test user doesn't exist", "GET", "/admin/v1/users/"+test_username,
+                           headers_json, {}, (404), {}, True)
+        if None in [res1, res2]:
+            engine.remove_authorization()
+            logger.error("Test project and/or user already exist")
+            return
+
+        # Create test project&user
+        res = engine.test("Create test project", "POST", "/admin/v1/projects", headers_json,
+                          {"name": test_username,
+                           "quotas": {
+                               "vnfds": 2,
+                               "nsds": 2,
+                               "nsts": 1,
+                               "pdus": 1,
+                               "nsrs": 2,
+                               "nsis": 1,
+                               "vim_accounts": 1,
+                               "wim_accounts": 1,
+                               "sdns": 1,
+                           }
+                           },
+                          (201), r_header_json, "json")
+        test_project_id = engine.last_id if res else None
+        res = engine.test("Create test user", "POST", "/admin/v1/users", headers_json,
+                          {"username": test_username, "password": test_password,
+                           "project_role_mappings": [{"project": test_project, "role": "project_admin"}]},
+                          (201), r_header_json, "json")
+        test_user_id = engine.last_id if res else None
+
+        if test_project_id and test_user_id:
+
+            # Get user access
+            engine.token = None
+            engine.user = test_username
+            engine.password = test_password
+            engine.project = test_project
+            engine.get_autorization()
+            user_token = engine.last_id
+
+            # Create test VIM
+            res = engine.test("Create test VIM", "POST", "/admin/v1/vim_accounts", headers_json,
+                              {"name": test_vim,
+                               "vim_type": "openvim",
+                               "vim_user": test_username,
+                               "vim_password": test_password,
+                               "vim_tenant_name": test_project,
+                               "vim_url": "https://0.0.0.0:0/v0.0",
+                               },
+                              (202), r_header_json, "json")
+            test_vim_ids += [engine.last_id if res else None]
+
+            res = engine.test("Try to create second test VIM", "POST", "/admin/v1/vim_accounts", headers_json,
+                              {"name": test_vim + "_2",
+                               "vim_type": "openvim",
+                               "vim_user": test_username,
+                               "vim_password": test_password,
+                               "vim_tenant_name": test_project,
+                               "vim_url": "https://0.0.0.0:0/v0.0",
+                               },
+                              (422), r_header_json, "json")
+            test_vim_ids += [engine.last_id if res is None else None]
+
+            res = engine.test("Try to create second test VIM with FORCE",
+                              "POST", "/admin/v1/vim_accounts?FORCE", headers_json,
+                              {"name": test_vim + "_3",
+                               "vim_type": "openvim",
+                               "vim_user": test_username,
+                               "vim_password": test_password,
+                               "vim_tenant_name": test_project,
+                               "vim_url": "https://0.0.0.0:0/v0.0",
+                               },
+                              (202), r_header_json, "json")
+            test_vim_ids += [engine.last_id if res else None]
+
+            if test_vim_ids[0]:
+
+                # Download descriptor files (if required)
+                test_dir = "/tmp/"+test_username+"/"
+                test_url = "https://osm-download.etsi.org/ftp/osm-6.0-six/7th-hackfest/packages/"
+                vnfd_filenames = ["slice_hackfest_vnfd.tar.gz", "slice_hackfest_middle_vnfd.tar.gz"]
+                nsd_filenames = ["slice_hackfest_nsd.tar.gz", "slice_hackfest_middle_nsd.tar.gz"]
+                nst_filenames = ["slice_hackfest_nstd.yaml"]
+                pdu_filenames = ["PDU_router.yaml"]
+                desc_filenames = vnfd_filenames + nsd_filenames + nst_filenames + pdu_filenames
+                if not os.path.exists(test_dir):
+                    os.makedirs(test_dir)
+                for filename in desc_filenames:
+                    if not os.path.exists(test_dir+filename):
+                        res = requests.get(test_url+filename)
+                        if res.status_code < 300:
+                            with open(test_dir+filename, "wb") as file:
+                                file.write(res.content)
+
+                if all([os.path.exists(test_dir+p) for p in desc_filenames]):
+
+                    # Test VNFD Quotas
+                    res = engine.test("Create test VNFD #1", "POST", "/vnfpkgm/v1/vnf_packages_content",
+                                      headers_zip_json, "@b"+test_dir+vnfd_filenames[0],
+                                      (201), r_header_json, "json")
+                    test_vnfd_ids += [engine.last_id if res else None]
+                    res = engine.test("Create test VNFD #2", "POST", "/vnfpkgm/v1/vnf_packages_content",
+                                      headers_zip_json, "@b"+test_dir+vnfd_filenames[1],
+                                      (201), r_header_json, "json")
+                    test_vnfd_ids += [engine.last_id if res else None]
+                    res = engine.test("Try to create extra test VNFD", "POST",
+                                      "/vnfpkgm/v1/vnf_packages_content",
+                                      headers_zip_json, "@b"+test_dir+vnfd_filenames[0],
+                                      (422), r_header_json, "json")
+                    test_vnfd_ids += [engine.last_id if res is None else None]
+                    res = engine.test("Try to create extra test VNFD with FORCE",
+                                      "POST", "/vnfpkgm/v1/vnf_packages_content?FORCE",
+                                      headers_zip_json, "@b"+test_dir+vnfd_filenames[0],
+                                      (201), r_header_json, "json")
+                    test_vnfd_ids += [engine.last_id if res else None]
+
+                    # Remove extra VNFDs to prevent further errors
+                    for i in [2, 3]:
+                        if test_vnfd_ids[i]:
+                            res = engine.test("Delete test VNFD #" + str(i), "DELETE",
+                                              "/vnfpkgm/v1/vnf_packages_content/"+test_vnfd_ids[i]+"?FORCE",
+                                              headers_json, {}, (204), {}, 0)
+                            if res:
+                                test_vnfd_ids[i] = None
+
+                    if test_vnfd_ids[0] and test_vnfd_ids[1]:
+
+                        # Test NSD Quotas
+                        res = engine.test("Create test NSD #1", "POST", "/nsd/v1/ns_descriptors_content",
+                                          headers_zip_json, "@b"+test_dir+nsd_filenames[0],
+                                          (201), r_header_json, "json")
+                        test_nsd_ids += [engine.last_id if res else None]
+                        res = engine.test("Create test NSD #2", "POST", "/nsd/v1/ns_descriptors_content",
+                                          headers_zip_json, "@b"+test_dir+nsd_filenames[1],
+                                          (201), r_header_json, "json")
+                        test_nsd_ids += [engine.last_id if res else None]
+                        res = engine.test("Try to create extra test NSD", "POST", "/nsd/v1/ns_descriptors_content",
+                                          headers_zip_json, "@b"+test_dir+nsd_filenames[0],
+                                          (422), r_header_json, "json")
+                        test_nsd_ids += [engine.last_id if res is None else None]
+                        res = engine.test("Try to create extra test NSD with FORCE",
+                                          "POST", "/nsd/v1/ns_descriptors_content?FORCE",
+                                          headers_zip_json, "@b"+test_dir+nsd_filenames[0],
+                                          (201), r_header_json, "json")
+                        test_nsd_ids += [engine.last_id if res else None]
+
+                        # Remove extra NSDs to prevent further errors
+                        for i in [2, 3]:
+                            if test_nsd_ids[i]:
+                                res = engine.test("Delete test NSD #" + str(i), "DELETE",
+                                                  "/nsd/v1/ns_descriptors_content/"+test_nsd_ids[i]+"?FORCE",
+                                                  headers_json, {}, (204), {}, 0)
+                                if res:
+                                    test_nsd_ids[i] = None
+
+                        if test_nsd_ids[0] and test_nsd_ids[1]:
+
+                            # Test NSR Quotas
+                            res = engine.test("Create test NSR #1", "POST", "/nslcm/v1/ns_instances_content",
+                                              headers_json,
+                                              {"nsName": test_username+"_1",
+                                               "nsdId": test_nsd_ids[0],
+                                               "vimAccountId": test_vim_ids[0],
+                                               },
+                                              (201), r_header_json, "json")
+                            test_nsr_ids += [engine.last_id if res else None]
+                            res = engine.test("Create test NSR #2", "POST", "/nslcm/v1/ns_instances_content",
+                                              headers_json,
+                                              {"nsName": test_username+"_2",
+                                               "nsdId": test_nsd_ids[1],
+                                               "vimAccountId": test_vim_ids[0],
+                                               },
+                                              (201), r_header_json, "json")
+                            test_nsr_ids += [engine.last_id if res else None]
+                            res = engine.test("Try to create extra test NSR", "POST", "/nslcm/v1/ns_instances_content",
+                                              headers_json,
+                                              {"nsName": test_username+"_3",
+                                               "nsdId": test_nsd_ids[0],
+                                               "vimAccountId": test_vim_ids[0],
+                                               },
+                                              (422), r_header_json, "json")
+                            test_nsr_ids += [engine.last_id if res is None else None]
+                            res = engine.test("Try to create test NSR with FORCE", "POST",
+                                              "/nslcm/v1/ns_instances_content?FORCE", headers_json,
+                                              {"nsName": test_username+"_4",
+                                               "nsdId": test_nsd_ids[0],
+                                               "vimAccountId": test_vim_ids[0],
+                                               },
+                                              (201), r_header_json, "json")
+                            test_nsr_ids += [engine.last_id if res else None]
+
+                            # Test NST Quotas
+                            res = engine.test("Create test NST", "POST", "/nst/v1/netslice_templates_content",
+                                              headers_txt_json, "@b"+test_dir+nst_filenames[0],
+                                              (201), r_header_json, "json")
+                            test_nst_ids += [engine.last_id if res else None]
+                            res = engine.test("Try to create extra test NST", "POST",
+                                              "/nst/v1/netslice_templates_content",
+                                              headers_txt_json, "@b"+test_dir+nst_filenames[0],
+                                              (422), r_header_json, "json")
+                            test_nst_ids += [engine.last_id if res is None else None]
+                            res = engine.test("Try to create extra test NST with FORCE", "POST",
+                                              "/nst/v1/netslice_templates_content?FORCE",
+                                              headers_txt_json, "@b"+test_dir+nst_filenames[0],
+                                              (201), r_header_json, "json")
+                            test_nst_ids += [engine.last_id if res else None]
+
+                            if test_nst_ids[0]:
+                                # Remove NSR Quota
+                                engine.set_header({"Authorization": "Bearer {}".format(admin_token)})
+                                res = engine.test("Remove NSR Quota", "PUT", "/admin/v1/projects/"+test_project_id,
+                                                  headers_json,
+                                                  {"quotas": {"nsrs": None}},
+                                                  (204), {}, 0)
+                                engine.set_header({"Authorization": "Bearer {}".format(user_token)})
+                                if res:
+                                    # Test NSI Quotas
+                                    res = engine.test("Create test NSI", "POST",
+                                                      "/nsilcm/v1/netslice_instances_content", headers_json,
+                                                      {"nsiName": test_username,
+                                                       "nstId": test_nst_ids[0],
+                                                       "vimAccountId": test_vim_ids[0],
+                                                       },
+                                                      (201), r_header_json, "json")
+                                    test_nsi_ids += [engine.last_id if res else None]
+                                    res = engine.test("Try to create extra test NSI", "POST",
+                                                      "/nsilcm/v1/netslice_instances_content", headers_json,
+                                                      {"nsiName": test_username,
+                                                       "nstId": test_nst_ids[0],
+                                                       "vimAccountId": test_vim_ids[0],
+                                                       },
+                                                      (400), r_header_json, "json")
+                                    test_nsi_ids += [engine.last_id if res is None else None]
+                                    res = engine.test("Try to create extra test NSI with FORCE", "POST",
+                                                      "/nsilcm/v1/netslice_instances_content?FORCE", headers_json,
+                                                      {"nsiName": test_username,
+                                                       "nstId": test_nst_ids[0],
+                                                       "vimAccountId": test_vim_ids[0],
+                                                       },
+                                                      (201), r_header_json, "json")
+                                    test_nsi_ids += [engine.last_id if res else None]
+
+                    # Test PDU Quotas
+                    with open(test_dir+pdu_filenames[0], "rb") as file:
+                        pdu_text = re.sub(r"ip-address: *\[[^\]]*\]", "ip-address: '0.0.0.0'",
+                                          file.read().decode("utf-8"))
+                    with open(test_dir+pdu_filenames[0], "wb") as file:
+                        file.write(pdu_text.encode("utf-8"))
+                    res = engine.test("Create test PDU", "POST", "/pdu/v1/pdu_descriptors",
+                                      headers_yaml, "@b"+test_dir+pdu_filenames[0],
+                                      (201), r_header_yaml, "yaml")
+                    test_pdu_ids += [engine.last_id if res else None]
+                    res = engine.test("Try to create extra test PDU", "POST", "/pdu/v1/pdu_descriptors",
+                                      headers_yaml, "@b"+test_dir+pdu_filenames[0],
+                                      (422), r_header_yaml, "yaml")
+                    test_pdu_ids += [engine.last_id if res is None else None]
+                    res = engine.test("Try to create extra test PDU with FORCE", "POST",
+                                      "/pdu/v1/pdu_descriptors?FORCE",
+                                      headers_yaml, "@b"+test_dir+pdu_filenames[0],
+                                      (201), r_header_yaml, "yaml")
+                    test_pdu_ids += [engine.last_id if res else None]
+
+                    # Cleanup
+                    for i, id in enumerate(test_nsi_ids):
+                        if id:
+                            engine.test("Delete test NSI #"+str(i), "DELETE",
+                                        "/nsilcm/v1/netslice_instances_content/"+id+"?FORCE",
+                                        headers_json, {}, (204), {}, 0)
+                    for i, id in enumerate(test_nsr_ids):
+                        if id:
+                            engine.test("Delete test NSR #"+str(i), "DELETE",
+                                        "/nslcm/v1/ns_instances_content/"+id+"?FORCE",
+                                        headers_json, {}, (204), {}, 0)
+                    for i, id in enumerate(test_nst_ids):
+                        if id:
+                            engine.test("Delete test NST #"+str(i), "DELETE",
+                                        "/nst/v1/netslice_templates_content/"+id+"?FORCE",
+                                        headers_json, {}, (204), {}, 0)
+                    for i, id in enumerate(test_nsd_ids):
+                        if id:
+                            engine.test("Delete test NSD #"+str(i), "DELETE",
+                                        "/nsd/v1/ns_descriptors_content/"+id+"?FORCE",
+                                        headers_json, {}, (204), {}, 0)
+                    for i, id in enumerate(test_vnfd_ids):
+                        if id:
+                            engine.test("Delete test VNFD #"+str(i), "DELETE",
+                                        "/vnfpkgm/v1/vnf_packages_content/"+id+"?FORCE",
+                                        headers_json, {}, (204), {}, 0)
+                    for i, id in enumerate(test_pdu_ids):
+                        if id:
+                            engine.test("Delete test PDU #"+str(i), "DELETE",
+                                        "/pdu/v1/pdu_descriptors/"+id+"?FORCE",
+                                        headers_json, {}, (204), {}, 0)
+
+                    # END Test NBI Quotas
+
+            # Test WIM Quotas
+            res = engine.test("Create test WIM", "POST", "/admin/v1/wim_accounts", headers_json,
+                              {"name": test_wim,
+                               "wim_type": "onos",
+                               "wim_url": "https://0.0.0.0:0/v0.0",
+                               },
+                              (202), r_header_json, "json")
+            test_wim_ids += [engine.last_id if res else None]
+            res = engine.test("Try to create second test WIM", "POST", "/admin/v1/wim_accounts", headers_json,
+                              {"name": test_wim + "_2",
+                               "wim_type": "onos",
+                               "wim_url": "https://0.0.0.0:0/v0.0",
+                               },
+                              (422), r_header_json, "json")
+            test_wim_ids += [engine.last_id if res is None else None]
+            res = engine.test("Try to create second test WIM with FORCE", "POST", "/admin/v1/wim_accounts?FORCE",
+                              headers_json,
+                              {"name": test_wim + "_3",
+                               "wim_type": "onos",
+                               "wim_url": "https://0.0.0.0:0/v0.0",
+                               },
+                              (202), r_header_json, "json")
+            test_wim_ids += [engine.last_id if res else None]
+
+            # Test SDN Quotas
+            res = engine.test("Create test SDN", "POST", "/admin/v1/sdns", headers_json,
+                              {"name": test_sdn,
+                               "type": "onos",
+                               "ip": "0.0.0.0",
+                               "port": 9999,
+                               "dpid": "00:00:00:00:00:00:00:00",
+                               },
+                              (202), r_header_json, "json")
+            test_sdn_ids += [engine.last_id if res else None]
+            res = engine.test("Try to create second test SDN", "POST", "/admin/v1/sdns", headers_json,
+                              {"name": test_sdn + "_2",
+                               "type": "onos",
+                               "ip": "0.0.0.0",
+                               "port": 9999,
+                               "dpid": "00:00:00:00:00:00:00:00",
+                               },
+                              (422), r_header_json, "json")
+            test_sdn_ids += [engine.last_id if res is None else None]
+            res = engine.test("Try to create second test SDN with FORCE", "POST", "/admin/v1/sdns?FORCE", headers_json,
+                              {"name": test_sdn + "_3",
+                               "type": "onos",
+                               "ip": "0.0.0.0",
+                               "port": 9999,
+                               "dpid": "00:00:00:00:00:00:00:00",
+                               },
+                              (202), r_header_json, "json")
+            test_sdn_ids += [engine.last_id if res else None]
+
+            # Cleanup
+            for i, id in enumerate(test_vim_ids):
+                if id:
+                    engine.test("Delete test VIM #"+str(i), "DELETE", "/admin/v1/vim_accounts/"+id+"?FORCE",
+                                headers_json, {}, (202), {}, 0)
+            for i, id in enumerate(test_wim_ids):
+                if id:
+                    engine.test("Delete test WIM #"+str(i), "DELETE", "/admin/v1/wim_accounts/"+id+"?FORCE",
+                                headers_json, {}, (202), {}, 0)
+            for i, id in enumerate(test_sdn_ids):
+                if id:
+                    engine.test("Delete test SDN #"+str(i), "DELETE", "/admin/v1/sdns/"+id+"?FORCE",
+                                headers_json, {}, (202), {}, 0)
+
+            # Release user access
+            engine.remove_authorization()
+
+        # Cleanup
+        engine.user = admin_username
+        engine.password = admin_password
+        engine.project = admin_project
+        engine.get_autorization()
+        if test_user_id:
+            engine.test("Delete test user", "DELETE", "/admin/v1/users/"+test_user_id+"?FORCE",
+                        headers_json, {}, (204), {}, 0)
+        if test_project_id:
+            engine.test("Delete test project", "DELETE", "/admin/v1/projects/"+test_project_id+"?FORCE",
+                        headers_json, {}, (204), {}, 0)
+        engine.remove_authorization()
+
+    # END class TestNbiQuotas
+
+
 if __name__ == "__main__":
     global logger
     test = ""
@@ -2440,6 +3158,8 @@ if __name__ == "__main__":
             "Deploy-Slice-Instance": TestNetSliceInstances,
             "Deploy-SimpleCharm": TestDeploySimpleCharm,
             "Deploy-SimpleCharm2": TestDeploySimpleCharm2,
+            "Authentication": TestAuthentication,
+            "NBI-Quotas": TestNbiQuotas,
         }
         test_to_do = []
         test_params = {}