guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[no subject]


From: Mathieu Othacehe
Date: Sat, 1 May 2021 11:33:24 -0400 (EDT)

branch: wip-dependencies
commit 53023bae525154b2ce22ba37cda0b9ce6af32354
Author: Mathieu Othacehe <othacehe@gnu.org>
AuthorDate: Sat May 1 17:30:19 2021 +0200

    Add build dependencies support.
    
    * src/schema.sql (BuildDependencies): New table.
    * src/cuirass/database.scm (db-add-build-dependencies,
    db-get-build-dependencies): New procedures.
    * tests/database.scm ("db-add-build-dependencies",
    "db-get-build-dependencies", "dependencies trigger", "dependencies trigger
    restart"): New tests.
---
 src/cuirass/database.scm | 28 ++++++++++++++++++++
 src/schema.sql           | 36 ++++++++++++++++++++++++++
 tests/database.scm       | 66 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 130 insertions(+)

diff --git a/src/cuirass/database.scm b/src/cuirass/database.scm
index 4f4fd98..259008d 100644
--- a/src/cuirass/database.scm
+++ b/src/cuirass/database.scm
@@ -71,6 +71,8 @@
             db-get-build-percentages
             db-get-jobs
             db-get-jobs-history
+            db-add-build-dependencies
+            db-get-build-dependencies
             db-register-builds
             db-update-build-status!
             db-update-build-worker!
@@ -788,6 +790,32 @@ AND Jobs.name = ANY(:names);")
                                (#:jobs . ,(list job)))
                              evaluations))))))))))
 
+(define (db-add-build-dependencies source-derivation target-derivations)
+  "Insert into the BuildDependencies table the TARGET-DERIVATIONS as
+dependencies of the given SOURCE-DERIVATION."
+  (define target
+    (format #f "{~a}"
+            (string-join target-derivations ",")))
+
+  (with-db-worker-thread db
+    (exec-query/bind db "
+INSERT INTO BuildDependencies
+(SELECT Builds.id, deps.id FROM Builds,
+(SELECT id FROM Builds WHERE derivation = ANY(" target ")) deps
+WHERE Builds.derivation = " source-derivation ");")))
+
+(define (db-get-build-dependencies build)
+  "Return the list of the given BUILD dependencies."
+  (with-db-worker-thread db
+    (let loop ((rows (exec-query/bind db "
+SELECT target FROM BuildDependencies WHERE source = " build))
+               (dependencies '()))
+      (match rows
+        (() (reverse dependencies))
+        (((target) . rest)
+         (loop rest
+               (cons (string->number target) dependencies)))))))
+
 (define (db-register-builds jobs eval-id specification)
   (define (new-outputs? outputs)
     (let ((new-outputs
diff --git a/src/schema.sql b/src/schema.sql
index d1479a0..17e1147 100644
--- a/src/schema.sql
+++ b/src/schema.sql
@@ -58,6 +58,13 @@ CREATE TABLE Builds (
   FOREIGN KEY (evaluation) REFERENCES Evaluations(id) ON DELETE CASCADE
 );
 
+CREATE TABLE BuildDependencies (
+  source        INTEGER NOT NULL,
+  target        INTEGER NOT NULL,
+  FOREIGN KEY (source) REFERENCES Builds(id) ON DELETE CASCADE,
+  FOREIGN KEY (target) REFERENCES Builds(id) ON DELETE CASCADE
+);
+
 CREATE TABLE Jobs (
   name          TEXT NOT NULL,
   evaluation    INTEGER NOT NULL,
@@ -145,6 +152,35 @@ CREATE TRIGGER build_status AFTER UPDATE ON Builds
 FOR EACH ROW
 EXECUTE PROCEDURE update_job_status();
 
+CREATE OR REPLACE FUNCTION pending_dependencies(build bigint)
+RETURNS TABLE (pending_count bigint) AS $$
+SELECT COALESCE(count(dep.id), 0) AS pending_count FROM Builds
+LEFT JOIN BuildDependencies AS bd ON builds.id = bd.source
+LEFT JOIN Builds AS dep ON bd.target = dep.id AND dep.status != 0
+WHERE Builds.id = $1 GROUP BY builds.id;
+$$ LANGUAGE sql;
+
+CREATE OR REPLACE FUNCTION update_build_dependencies()
+RETURNS TRIGGER AS $$
+BEGIN
+IF NEW.status = ANY('{-2, 1, 2, 3, 4}') THEN
+UPDATE builds SET status = dep.status FROM
+(SELECT source,
+CASE
+WHEN NEW.status = 1 OR NEW.status = 2 OR NEW.status = 3 THEN 2
+WHEN NEW.status = 4 THEN 4
+ELSE NEW.status END status
+FROM BuildDependencies WHERE target = NEW.id) AS dep
+WHERE dep.source = Builds.id;
+END IF;
+RETURN null;
+END
+$$ LANGUAGE plpgsql;
+
+CREATE TRIGGER build_dependencies AFTER UPDATE ON Builds
+FOR EACH ROW
+EXECUTE PROCEDURE update_build_dependencies();
+
 CREATE INDEX Jobs_name ON Jobs (name);
 CREATE INDEX Jobs_system_status ON Jobs (system, status);
 CREATE INDEX Jobs_build ON Jobs (build); --speeds up delete cascade.
diff --git a/tests/database.scm b/tests/database.scm
index b54bae2..a6ed03b 100644
--- a/tests/database.scm
+++ b/tests/database.scm
@@ -679,6 +679,72 @@ timestamp, checkouttime, evaltime) VALUES ('guix', 0, 0, 
0, 0);")
     (let ((id (db-register-dashboard "guix" "emacs")))
       (assq-ref (db-get-dashboard id) #:specification)))
 
+  (test-assert "db-add-build-dependencies"
+    (begin
+      (db-add-build-dependencies "/build-1.drv"
+                                 (list "/build-2.drv"))))
+
+  (test-assert "db-get-build-dependencies"
+    (begin
+      (let* ((drv1 "/build-1.drv")
+             (drv2 "/build-2.drv")
+             (id1 (assq-ref (db-get-build drv1) #:id))
+             (id2 (assq-ref (db-get-build drv2) #:id)))
+        (match (db-get-build-dependencies id1)
+          ((id) (eq? id id2))))))
+
+  (test-assert "dependencies trigger"
+    (begin
+      (let ((drv-1
+             (db-add-build (make-dummy-build "/build-dep-1.drv")))
+            (drv-2
+             (db-add-build (make-dummy-build "/build-dep-2.drv")))
+            (drv-3
+             (db-add-build (make-dummy-build "/build-dep-3.drv")))
+            (drv-4
+             (db-add-build (make-dummy-build "/build-dep-4.drv")))
+            (drv-5
+             (db-add-build (make-dummy-build "/build-dep-5.drv")))
+            (drv-6
+             (db-add-build (make-dummy-build "/build-dep-6.drv")))
+            (drv-7
+             (db-add-build (make-dummy-build "/build-dep-7.drv")))
+            (status (lambda (drv)
+                      (assq-ref (db-get-build drv) #:status))))
+        (db-add-build-dependencies "/build-dep-2.drv"
+                                   (list "/build-dep-1.drv"))
+        (db-add-build-dependencies "/build-dep-4.drv"
+                                   (list "/build-dep-1.drv"
+                                         "/build-dep-3.drv"))
+        (db-add-build-dependencies "/build-dep-6.drv"
+                                   (list "/build-dep-4.drv"
+                                         "/build-dep-5.drv"))
+        (db-add-build-dependencies "/build-dep-7.drv"
+                                   (list "/build-dep-4.drv"))
+        (db-update-build-status! drv-1 (build-status failed))
+        (db-update-build-status! drv-2 (build-status succeeded))
+        (db-update-build-status! drv-5 (build-status canceled))
+        (and (eq? (status drv-4) (build-status failed-dependency))
+             (eq? (status drv-6) (build-status canceled))
+             (eq? (status drv-7) (build-status failed-dependency))))))
+
+  (test-assert "dependencies trigger restart"
+    (begin
+      (let ((drv-1 "/build-dep-1.drv")
+            (drv-2 "/build-dep-2.drv")
+            (drv-4 "/build-dep-4.drv")
+            (drv-5 "/build-dep-5.drv")
+            (drv-6 "/build-dep-6.drv")
+            (drv-7 "/build-dep-7.drv")
+            (status (lambda (drv)
+                      (assq-ref (db-get-build drv) #:status))))
+        (db-update-build-status! drv-1 (build-status scheduled))
+        (and (eq? (status drv-2) (build-status scheduled))
+             (eq? (status drv-4) (build-status scheduled))
+             (eq? (status drv-5) (build-status canceled))
+             (eq? (status drv-6) (build-status scheduled))
+             (eq? (status drv-7) (build-status scheduled))))))
+
   (test-assert "db-close"
     (begin
       (false-if-exception (delete-file tmp-mail))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]