From a5bc70b36486fd9764c8b10aaf6cde660180b02f Mon Sep 17 00:00:00 2001 From: Alessandro Bellucci Date: Wed, 4 Sep 2024 13:20:59 +0200 Subject: [PATCH 1/2] feature(dg-min-req): cleanup, additional tests --- .../nuvla/server/resources/deployment_set.clj | 46 +-- .../server/resources/deployment_set/utils.clj | 2 - .../deployment_set_lifecycle_test.clj | 329 ++++++++++++++---- 3 files changed, 260 insertions(+), 117 deletions(-) diff --git a/code/src/com/sixsq/nuvla/server/resources/deployment_set.clj b/code/src/com/sixsq/nuvla/server/resources/deployment_set.clj index a136f8648..0d60a7f05 100644 --- a/code/src/com/sixsq/nuvla/server/resources/deployment_set.clj +++ b/code/src/com/sixsq/nuvla/server/resources/deployment_set.clj @@ -32,48 +32,6 @@ These resources represent a deployment set that regroups deployments. (def collection-acl {:query ["group/nuvla-user"] :add ["group/nuvla-user"]}) -(def actions [{:name utils/action-start - :uri utils/action-start - :description "start deployment set" - :method "POST" - :input-message "application/json" - :output-message "application/json"} - - {:name utils/action-stop - :uri utils/action-stop - :description "stop deployment set" - :method "POST" - :input-message "application/json" - :output-message "application/json"} - - {:name utils/action-cancel - :uri utils/action-cancel - :description "cancel running action on deployment set" - :method "POST" - :input-message "application/json" - :output-message "application/json"} - - {:name utils/action-update - :uri utils/action-update - :description "cancel running action on deployment set" - :method "POST" - :input-message "application/json" - :output-message "application/json"} - - {:name utils/action-plan - :uri utils/action-plan - :description "get an action plan for deployment set" - :method "POST" - :input-message "application/json" - :output-message "application/json"} - - {:name utils/action-check-requirements - :uri utils/action-check-requirements - :description "check whether the edges in the deployment set satisfy the apps requirements" - :method "POST" - :input-message "application/json" - :output-message "application/json"}]) - (defmethod sm/state-machine resource-type [_resource] utils/state-machine) @@ -248,13 +206,13 @@ These resources represent a deployment set that regroups deployments. (crud/get-resource-throw-nok request))] (r/json-response (utils/check-requirements deployment-set applications-sets)))) -(defn operationnal-status-content +(defn operational-status-content [resource _request] (-> resource :operational-status r/json-response)) (defmethod crud/do-action [resource-type utils/action-operational-status] [request] - (standard-action request operationnal-status-content)) + (standard-action request operational-status-content)) (defmethod crud/do-action [resource-type utils/action-start] [request] diff --git a/code/src/com/sixsq/nuvla/server/resources/deployment_set/utils.clj b/code/src/com/sixsq/nuvla/server/resources/deployment_set/utils.clj index 05e48b798..db8ccf02b 100644 --- a/code/src/com/sixsq/nuvla/server/resources/deployment_set/utils.clj +++ b/code/src/com/sixsq/nuvla/server/resources/deployment_set/utils.clj @@ -71,8 +71,6 @@ (def guard-fleet-filter-defined? :fleet-filter-defined) -(def guard-admin? :fleet-filter-defined) - (defn transition-ok [to-state] {::tk/on action-ok ::tk/to to-state ::tk/guards [sm/guard-is-admin?]}) diff --git a/code/test/com/sixsq/nuvla/server/resources/deployment_set_lifecycle_test.clj b/code/test/com/sixsq/nuvla/server/resources/deployment_set_lifecycle_test.clj index 4e72a2111..0a4e779c2 100644 --- a/code/test/com/sixsq/nuvla/server/resources/deployment_set_lifecycle_test.clj +++ b/code/test/com/sixsq/nuvla/server/resources/deployment_set_lifecycle_test.clj @@ -1352,84 +1352,271 @@ session-user (header session-anon authn-info-header (str "user/jane user/jane group/nuvla-user group/nuvla-anon " session-id))] - (testing "create must be possible for user" - (let [module-id (resource-creation/create-module session-user "a" "a/b") - _ (module/initialize) - _ (-> session-user - (request (str p/service-context module-id) - :request-method :put - :body (json/write-str {:content {:docker-compose "a" - :architectures ["x86_64"] - :minimum-requirements {:min-cpu 2.0 - :min-ram 200 - :min-disk 10} - :author "user/jane"}})) - ltu/body->edn - (ltu/is-status 200)) - module-id-2 (resource-creation/create-module session-user "c" "c/d") - _ (-> session-user - (request (str p/service-context module-id-2) - :request-method :put - :body (json/write-str {:content {:docker-compose "a" - :architectures ["x86_64" "sparc"] - :minimum-requirements {:min-cpu 0.5 - :min-ram 100 - :min-disk 100} - :author "user/jane"}})) - ltu/body->edn - (ltu/is-status 200)) - fleet ["nuvlabox/1"] - dep-set-url (with-redefs [utils/get-missing-edges (constantly #{})] - (-> session-user - (request base-uri - :request-method :post - :body (json/write-str {:name dep-set-name - :modules [module-id module-id-2] - :fleet fleet})) - ltu/body->edn - (ltu/is-status 201) - ltu/location-url))] - - (testing "check deployment set requirements" - (let [check-requirements-op-url (-> session-user - (request dep-set-url) - ltu/body->edn - (ltu/is-status 200) - (ltu/get-op-url utils/action-check-requirements)) - retrieve-by-id-as-admin-orig crud/retrieve-by-id-as-admin - check-req-results (with-redefs [crud/query-as-admin - (fn [collection-id options] - (case collection-id - "nuvlabox" - [{:count 1} - '({:id "nuvlabox/1" - :name "NuvlaBox 01" - :nuvlabox-status "nuvlabox-status/1"})] - "nuvlabox-status" - [{:count 1} - '({:id "nuvlabox-status/1" - :architecture "x86_64" - :resources {:cpu {:capacity 2} - :ram {:capacity 1024} - :disks [{:capacity 20} - {:capacity 200}]}})]))] - (-> session-user - (request check-requirements-op-url) - ltu/body->edn - (ltu/is-status 200) - ltu/body))] + (let [module-id (resource-creation/create-module session-user "a" "a/b") + _ (module/initialize) + module-id-2 (resource-creation/create-module session-user "c" "c/d") + fleet ["nuvlabox/1"]] + + (testing "check deployment set requirements" + (let [check-req-results (fn [module1-req module2-req status] + (-> session-user + (request (str p/service-context module-id) + :request-method :put + :body (json/write-str {:content (merge {:docker-compose "a" + :author "user/jane"} + module1-req)})) + ltu/body->edn + (ltu/is-status 200)) + (-> session-user + (request (str p/service-context module-id-2) + :request-method :put + :body (json/write-str {:content (merge {:docker-compose "a" + :author "user/jane"} + module2-req)})) + ltu/body->edn + (ltu/is-status 200)) + (let [dep-set-url (with-redefs [utils/get-missing-edges (constantly #{})] + (-> session-user + (request base-uri + :request-method :post + :body (json/write-str {:name dep-set-name + :modules [module-id module-id-2] + :fleet fleet})) + ltu/body->edn + (ltu/is-status 201) + ltu/location-url)) + check-requirements-op-url (-> session-user + (request dep-set-url) + ltu/body->edn + (ltu/is-status 200) + (ltu/get-op-url utils/action-check-requirements))] + (with-redefs [crud/query-as-admin + (fn [collection-id _options] + (case collection-id + "nuvlabox" + [{:count 1} + '({:id "nuvlabox/1" + :name "NuvlaBox 01" + :nuvlabox-status "nuvlabox-status/1"})] + "nuvlabox-status" + [{:count 1} + [(merge {:id "nuvlabox-status/1"} status)]]))] + (-> session-user + (request check-requirements-op-url) + ltu/body->edn + (ltu/is-status 200) + ltu/body))))] + (is (= {:minimum-requirements {:architectures ["x86_64"] + :min-cpu 2.5 + :min-ram 300 + :min-disk 110} + :unmet-requirements {:first-mismatches [] + :n-edges 0}} + (check-req-results {:architectures ["x86_64"] + :minimum-requirements {:min-cpu 2.0 + :min-ram 200 + :min-disk 10}} + {:architectures ["x86_64" "sparc"] + :minimum-requirements {:min-cpu 0.5 + :min-ram 100 + :min-disk 100}} + {:architecture "x86_64" + :resources {:cpu {:capacity 3} + :ram {:capacity 1024} + :disks [{:capacity 200}]}}))) + (is (= {:minimum-requirements {:architectures ["x86_64"] + :min-cpu 2.5 + :min-ram 300 + :min-disk 110} + :unmet-requirements {:first-mismatches [{:edge-id "nuvlabox/1" + :edge-name "NuvlaBox 01" + :cpu {:available 2 + :min 2.5} + :disk {:available 20 + :min 110}}] + :n-edges 1}} + (check-req-results {:architectures ["x86_64"] + :minimum-requirements {:min-cpu 2.0 + :min-ram 200 + :min-disk 10}} + {:architectures ["x86_64" "sparc"] + :minimum-requirements {:min-cpu 0.5 + :min-ram 100 + :min-disk 100}} + {:architecture "x86_64" + :resources {:cpu {:capacity 2} + :ram {:capacity 1024} + :disks [{:capacity 20} + {:capacity 200}]}}))) + (is (= {:minimum-requirements {:architectures ["x86_64"] + :min-cpu 2.5 + :min-ram 300 + :min-disk 110} + :unmet-requirements {:first-mismatches [{:edge-id "nuvlabox/1" + :edge-name "NuvlaBox 01" + :architecture {:edge-architecture "sparc" + :supported ["x86_64"]}}] + :n-edges 1}} + (check-req-results {:architectures ["x86_64"] + :minimum-requirements {:min-cpu 2.0 + :min-ram 200 + :min-disk 10}} + {:architectures ["x86_64" "sparc"] + :minimum-requirements {:min-cpu 0.5 + :min-ram 100 + :min-disk 100}} + {:architecture "sparc" + :resources {:cpu {:capacity 3} + :ram {:capacity 1024} + :disks [{:capacity 200}]}}))) + (testing "The check should pass if required architecture is not specified" + (is (= {:minimum-requirements {:architectures nil + :min-cpu 2.5 + :min-ram 300 + :min-disk 110} + :unmet-requirements {:first-mismatches [] + :n-edges 0}} + (check-req-results {:minimum-requirements {:min-cpu 2.0 + :min-ram 200 + :min-disk 10}} + {:minimum-requirements {:min-cpu 0.5 + :min-ram 100 + :min-disk 100}} + {:architecture ["x86_64"] + :resources {:cpu {:capacity 3} + :ram {:capacity 1024} + :disks [{:capacity 200}]}})))) + (testing "The check should pass if required cpu is not specified" + (is (= {:minimum-requirements {:architectures ["x86_64"] + :min-cpu 0.0 + :min-ram 300 + :min-disk 110} + :unmet-requirements {:first-mismatches [] + :n-edges 0}} + (check-req-results {:architectures ["x86_64"] + :minimum-requirements {:min-ram 200 + :min-disk 10}} + {:architectures ["x86_64" "sparc"] + :minimum-requirements {:min-ram 100 + :min-disk 100}} + {:architecture "x86_64" + :resources {:cpu {:capacity 1} + :ram {:capacity 1024} + :disks [{:capacity 200}]}})))) + (testing "The check should pass if required ram is not specified" + (is (= {:minimum-requirements {:architectures ["x86_64"] + :min-cpu 2.5 + :min-ram 0 + :min-disk 110} + :unmet-requirements {:first-mismatches [] + :n-edges 0}} + (check-req-results {:architectures ["x86_64"] + :minimum-requirements {:min-cpu 2.0 + :min-disk 10}} + {:architectures ["x86_64" "sparc"] + :minimum-requirements {:min-cpu 0.5 + :min-disk 100}} + {:architecture "x86_64" + :resources {:cpu {:capacity 3} + :ram {:capacity 40} + :disks [{:capacity 200}]}})))) + (testing "The check should pass if required disk space is not specified" + (is (= {:minimum-requirements {:architectures ["x86_64"] + :min-cpu 2.5 + :min-ram 300 + :min-disk 0} + :unmet-requirements {:first-mismatches [] + :n-edges 0}} + (check-req-results {:architectures ["x86_64"] + :minimum-requirements {:min-cpu 2.0 + :min-ram 200}} + {:architectures ["x86_64" "sparc"] + :minimum-requirements {:min-cpu 0.5 + :min-ram 100}} + {:architecture "x86_64" + :resources {:cpu {:capacity 3} + :ram {:capacity 1024} + :disks [{:capacity 10}]}})))) + (testing "The check should pass if the edge does not provide supported architecture" + (is (= {:minimum-requirements {:architectures ["x86_64"] + :min-cpu 2.5 + :min-ram 300 + :min-disk 110} + :unmet-requirements {:first-mismatches [] + :n-edges 0}} + (check-req-results {:architectures ["x86_64"] + :minimum-requirements {:min-cpu 2.0 + :min-ram 200 + :min-disk 10}} + {:architectures ["x86_64" "sparc"] + :minimum-requirements {:min-cpu 0.5 + :min-ram 100 + :min-disk 100}} + {:architecture nil + :resources {:cpu {:capacity 3} + :ram {:capacity 1024} + :disks [{:capacity 200}]}})))) + (testing "The check should NOT pass if the edge does not provide available resources" + (is (= {:minimum-requirements {:architectures ["x86_64"] + :min-cpu 2.5 + :min-ram 300 + :min-disk 110} + :unmet-requirements {:first-mismatches [{:cpu {:available 0 + :min 2.5} + :edge-id "nuvlabox/1" + :edge-name "NuvlaBox 01"}] + :n-edges 1}} + (check-req-results {:architectures ["x86_64"] + :minimum-requirements {:min-cpu 2.0 + :min-ram 200 + :min-disk 10}} + {:architectures ["x86_64" "sparc"] + :minimum-requirements {:min-cpu 0.5 + :min-ram 100 + :min-disk 100}} + {:architecture "x86_64" + :resources {:ram {:capacity 1024} + :disks [{:capacity 200}]}}))) (is (= {:minimum-requirements {:architectures ["x86_64"] :min-cpu 2.5 :min-ram 300 :min-disk 110} :unmet-requirements {:first-mismatches [{:edge-id "nuvlabox/1" :edge-name "NuvlaBox 01" - :cpu {:available 2 - :min 2.5} - :disk {:available 20 - :min 110}}] + :ram {:available 0 + :min 300}}] + :n-edges 1}} + (check-req-results {:architectures ["x86_64"] + :minimum-requirements {:min-cpu 2.0 + :min-ram 200 + :min-disk 10}} + {:architectures ["x86_64" "sparc"] + :minimum-requirements {:min-cpu 0.5 + :min-ram 100 + :min-disk 100}} + {:architecture "x86_64" + :resources {:cpu {:capacity 3} + :disks [{:capacity 200}]}}))) + (is (= {:minimum-requirements {:architectures ["x86_64"] + :min-cpu 2.5 + :min-ram 300 + :min-disk 110} + :unmet-requirements {:first-mismatches [{:disk {:available 0 + :min 110} + :edge-id "nuvlabox/1" + :edge-name "NuvlaBox 01"}] :n-edges 1}} - check-req-results)))))))) + (check-req-results {:architectures ["x86_64"] + :minimum-requirements {:min-cpu 2.0 + :min-ram 200 + :min-disk 10}} + {:architectures ["x86_64" "sparc"] + :minimum-requirements {:min-cpu 0.5 + :min-ram 100 + :min-disk 100}} + {:architecture "x86_64" + :resources {:cpu {:capacity 3} + :ram {:capacity 1024}}}))))))))) (deftest bad-methods From 745c951b5b3991d1a6b48e17baec0bddbb6dbc63 Mon Sep 17 00:00:00 2001 From: Alessandro Bellucci Date: Wed, 4 Sep 2024 16:00:16 +0200 Subject: [PATCH 2/2] fix(dg-min-req): add back action map, used to generate resource-metadata --- .../nuvla/server/resources/deployment_set.clj | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/code/src/com/sixsq/nuvla/server/resources/deployment_set.clj b/code/src/com/sixsq/nuvla/server/resources/deployment_set.clj index 0d60a7f05..2cf3329e0 100644 --- a/code/src/com/sixsq/nuvla/server/resources/deployment_set.clj +++ b/code/src/com/sixsq/nuvla/server/resources/deployment_set.clj @@ -32,6 +32,48 @@ These resources represent a deployment set that regroups deployments. (def collection-acl {:query ["group/nuvla-user"] :add ["group/nuvla-user"]}) +(def actions [{:name utils/action-start + :uri utils/action-start + :description "start deployment set" + :method "POST" + :input-message "application/json" + :output-message "application/json"} + + {:name utils/action-stop + :uri utils/action-stop + :description "stop deployment set" + :method "POST" + :input-message "application/json" + :output-message "application/json"} + + {:name utils/action-cancel + :uri utils/action-cancel + :description "cancel running action on deployment set" + :method "POST" + :input-message "application/json" + :output-message "application/json"} + + {:name utils/action-update + :uri utils/action-update + :description "cancel running action on deployment set" + :method "POST" + :input-message "application/json" + :output-message "application/json"} + + {:name utils/action-plan + :uri utils/action-plan + :description "get an action plan for deployment set" + :method "POST" + :input-message "application/json" + :output-message "application/json"} + + {:name utils/action-check-requirements + :uri utils/action-check-requirements + :description "check whether the edges in the deployment set satisfy the apps requirements" + :method "POST" + :input-message "application/json" + :output-message "application/json"}]) + (defmethod sm/state-machine resource-type [_resource] utils/state-machine)