From 8d40c49170971ad7bbf8b97336934dbb3d949fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Lassieur?= Date: Sat, 11 Aug 2018 20:30:11 +0200 Subject: [PATCH] database: Add a Checkouts table. It is used to know when a new evaluation must be triggered and to display input changes. * Makefile.am (dist_sql_DATA): Add 'src/sql/upgrade-3.sql'. * bin/cuirass.in (main): Call DB-SET-EVALUATION-DONE at startup to clear 'in-progress' evaluations. * bin/evaluate.in (input-checkout, format-checkouts): Rename '#:name' to '#:input'. * doc/cuirass.texi (Stamps): Remove section. (Checkouts): New section. * src/cuirass/base.scm (fetch-input, fetch-inputs, compile-checkouts): Rename '#:name' to '#:input'. (evaluate): Remove the COMMITS argument. Add an EVAL-ID argument. Don't call DB-ADD-EVALUATION because it was called sooner. Remove the EVAL-ID argument to AUGMENT-JOB because it's a closure. (build-packages): Add an EVAL-ID argument. Call DB-SET-EVALUATION-DONE once all the derivations are registered. (process-specs): Replace the stamping mechanism by the primary key constraint of the Checkouts table: call "evaluate" only when DB-ADD-EVALUATION is true, which means that at least one checkout was added. Change the EVALUATE and BUILD-PACKAGES arguments accordingly. * src/cuirass/database.scm (db-add-stamp, db-get-stamp): Remove procedures. (db-set-evaluations-done, db-set-evaluation-done): New exported procedure. (db-add-checkout): New procedure that returns #f if a checkout with the same revision already exists. (db-add-evaluation): Replace the EVAL argument with a SPEC-NAME and a CHECKOUTS arguments. Insert the evaluation only if at least one checkout was inserted. Return #f otherwise. (db-get-checkouts): New procedure. (db-get-evaluations, db-get-evaluations-build-summary): Handle the 'in_progress' column, remove the 'commits' column. Return the result of DB-GET-CHECKOUTS as part of the evaluation. * src/cuirass/templates.scm (input-changes, evaluation-badges): New procedures. (evaluation-info-table): Rename "Commits" to "Input changes". Use INPUT-CHANGES to display the input changes that triggered the evaluation. Use EVALUATION-BADGES to display a message indicating that the evaluation is in progress. * src/schema.sql (Stamps): Remove table. (Checkouts): New table. (Evaluations): Remove the 'commits' column. Add an 'in_progress' column. * src/sql/upgrade-3.sql: New file with SQL queries to upgrade the database. * tests/database.scm (make-dummy-eval): Remove procedure. (make-dummy-checkouts): New procedure. ("sqlite-exec"): Remove the 'commits' column. Add the 'in_progress' column. ("db-update-build-status!", "db-get-builds", "db-get-pending-derivations"): Update the arguments of DB-ADD-EVALUATION accordingly. * tests/http.scm (hash-table=?): Add support for lists of hash tables. (evaluations-query-result): Replace '#:commits' with '#:checkouts'. Return a list instead of returning one element, for symmetry. ("fill-db"): Add a new input so that the second checkout can refer to it. Replace EVALUATION1 and EVALUATION2 with CHECKOUTS1 and CHECKOUTS2. Update the arguments of DB-ADD-EVALUATION accordingly. ("/api/queue?nr=100"): Take the CAR of the EVALUATIONS-QUERY-RESULT list to make it symmetrical with the other argument of HASH-TABLE=?. --- Makefile.am | 3 +- bin/cuirass.in | 6 +++ bin/evaluate.in | 4 +- doc/cuirass.texi | 33 +++++++++--- src/cuirass/base.scm | 49 ++++++++---------- src/cuirass/database.scm | 105 ++++++++++++++++++++++++++------------ src/cuirass/templates.scm | 35 +++++++++---- src/schema.sql | 16 ++++-- src/sql/upgrade-3.sql | 46 +++++++++++++++++ tests/database.scm | 31 ++++++----- tests/http.scm | 55 ++++++++++++++------ 11 files changed, 266 insertions(+), 117 deletions(-) create mode 100644 src/sql/upgrade-3.sql diff --git a/Makefile.am b/Makefile.am index db56165..2f83659 100644 --- a/Makefile.am +++ b/Makefile.am @@ -66,7 +66,8 @@ dist_pkgdata_DATA = src/schema.sql dist_sql_DATA = \ src/sql/upgrade-1.sql \ - src/sql/upgrade-2.sql + src/sql/upgrade-2.sql \ + src/sql/upgrade-3.sql dist_css_DATA = \ src/static/css/bootstrap.css \ diff --git a/bin/cuirass.in b/bin/cuirass.in index d30f788..a7af5b2 100644 --- a/bin/cuirass.in +++ b/bin/cuirass.in @@ -129,6 +129,12 @@ exec ${GUILE:-@GUILE@} --no-auto-compile -e main -s "$0" "$@" (clear-build-queue) + ;; If Cuirass was stopped during an evaluation, consider + ;; it done. Builds that were not registered during this + ;; evaluation will be registered during the next + ;; evaluation. + (db-set-evaluations-done) + ;; First off, restart builds that had not completed or ;; were not even started on a previous run. (spawn-fiber diff --git a/bin/evaluate.in b/bin/evaluate.in index 3f08b92..19d0f12 100644 --- a/bin/evaluate.in +++ b/bin/evaluate.in @@ -44,7 +44,7 @@ exec ${GUILE:-@GUILE@} --no-auto-compile -e main -s "$0" "$@" (define (input-checkout checkouts input-name) "Find in CHECKOUTS the CHECKOUT corresponding to INPUT-NAME, and return it." (find (lambda (checkout) - (string=? (assq-ref checkout #:name) + (string=? (assq-ref checkout #:input) input-name)) checkouts)) @@ -91,7 +91,7 @@ entries are added because they could be useful during the evaluation." (match in (() (cons name out)) - (((#:name . val) . rest) + (((#:input . val) . rest) (loop rest out (string->symbol val))) (((#:directory . val) . rest) (loop rest (cons `(file-name . ,val) out) name)) diff --git a/doc/cuirass.texi b/doc/cuirass.texi index b51cfad..08ca832 100644 --- a/doc/cuirass.texi +++ b/doc/cuirass.texi @@ -249,7 +249,7 @@ Cuirass uses a SQLite database to store information about jobs and past build results, but also to coordinate the execution of jobs. The database contains the following tables: @code{Specifications}, -@code{Inputs}, @code{Stamps}, @code{Evaluations}, @code{Builds} and +@code{Inputs}, @code{Checkouts}, @code{Evaluations}, @code{Builds} and @code{Outputs}. The purpose of each of these tables is explained below. @section Specifications @@ -334,16 +334,33 @@ When this integer field holds the value @code{1} Cuirass will skip compilation for the specified repository. @end table -@section Stamps -@cindex stamps, database +@section Checkouts +@cindex checkouts, database When a specification is processed, the repositories must be downloaded at a -certain revision as specified. The @code{Stamps} table stores the current -revisions for every specification when it is being processed. +certain revision as specified. The download is called a checkout. The +@code{Checkouts} table stores the new checkouts for every specification when +it is being processed. -The table only has two text columns: @code{specification}, which references a -specification from the @code{Specifications} table via the field @code{name}, -and @code{stamp}, which holds the revisions (space separated commit hashes). +The @code{Checkouts} table has the following columns: + +@table @code +@item specification +The specification associated with the checkout. + +@item revision +The revision of the checkout. Within the same specification, two checkouts +can't be identical: they can't have the same revision. + +@item evaluation +The evaluation that was triggered by the addition of that new checkout. + +@item input +The input associated with the checkout. + +@item directory +The directory into which the checkout was extracted. +@end table @section Evaluations @cindex evaluations, database diff --git a/src/cuirass/base.scm b/src/cuirass/base.scm index 1ec122c..deee05b 100644 --- a/src/cuirass/base.scm +++ b/src/cuirass/base.scm @@ -178,7 +178,7 @@ read-only directory." (string-append (%package-cachedir) "/" name)) directory))) - `((#:name . ,name) + `((#:input . ,name) (#:directory . ,directory) (#:commit . ,commit) (#:load-path . ,(assq-ref input #:load-path)) @@ -248,10 +248,10 @@ fibers." (logior (@ (fibers epoll) EPOLLERR) (@ (fibers epoll) EPOLLHUP))))) -(define (evaluate store spec checkouts commits) +(define (evaluate store spec eval-id checkouts) "Evaluate and build package derivations defined in SPEC, using CHECKOUTS. -Return a list of jobs." - (define (augment-job job eval-id) +Return a list of jobs that are associated to EVAL-ID." + (define (augment-job job) (let ((drv (read-derivation-from-file (assq-ref job #:derivation)))) `((#:eval-id . ,eval-id) @@ -275,14 +275,9 @@ Return a list of jobs." (close-pipe port) (match result (('evaluation jobs) - (let* ((spec-name (assq-ref spec #:name)) - (eval-id (db-add-evaluation - `((#:specification . ,spec-name) - (#:commits . ,commits))))) - (log-message "created evaluation ~a for '~a'" eval-id spec-name) - (map (lambda (job) - (augment-job job eval-id)) - jobs)))))) + (let* ((spec-name (assq-ref spec #:name))) + (log-message "evaluation ~a for '~a' completed" eval-id spec-name) + (map augment-job jobs)))))) ;;; @@ -539,7 +534,7 @@ started)." (spawn-builds store valid) (log-message "done with restarted builds")))) -(define (build-packages store jobs) +(define (build-packages store jobs eval-id) "Build JOBS and return a list of Build results." (define (register job) (let* ((name (assq-ref job #:job-name)) @@ -576,6 +571,10 @@ started)." (define derivations (filter-map register jobs)) + (log-message "evaluation ~a registered ~a new derivations" + eval-id (length derivations)) + (db-set-evaluation-done eval-id) + (spawn-builds store derivations) (let* ((results (filter-map (cut db-get-build <>) derivations)) @@ -625,7 +624,7 @@ started)." (results (par-map %non-blocking thunks))) (map (lambda (checkout) (log-message "fetched input '~a' of spec '~a' (commit ~s)" - (assq-ref checkout #:name) + (assq-ref checkout #:input) (assq-ref spec #:name) (assq-ref checkout #:commit)) checkout) @@ -638,7 +637,7 @@ started)." (lambda (checkout) (lambda () (log-message "compiling input '~a' of spec '~a' (commit ~s)" - (assq-ref checkout #:name) + (assq-ref checkout #:input) (assq-ref spec #:name) (assq-ref checkout #:commit)) (compile checkout))) @@ -646,7 +645,7 @@ started)." (results (par-map %non-blocking thunks))) (map (lambda (checkout) (log-message "compiled input '~a' of spec '~a' (commit ~s)" - (assq-ref checkout #:name) + (assq-ref checkout #:input) (assq-ref spec #:name) (assq-ref checkout #:commit)) checkout) @@ -656,15 +655,10 @@ started)." "Evaluate and build JOBSPECS and store results in the database." (define (process spec) (with-store store - (let* ((stamp (db-get-stamp spec)) - (name (assoc-ref spec #:name)) + (let* ((name (assoc-ref spec #:name)) (checkouts (fetch-inputs spec)) - (commits (map (cut assq-ref <> #:commit) checkouts)) - (commits-str (string-join commits))) - (unless (equal? commits-str stamp) - ;; Immediately mark SPEC's INPUTS as being processed so we don't - ;; spawn a concurrent evaluation of that same commit. - (db-add-stamp spec commits-str) + (eval-id (db-add-evaluation name checkouts))) + (when eval-id (compile-checkouts spec (filter compile? checkouts)) (spawn-fiber (lambda () @@ -672,13 +666,12 @@ started)." (log-message "failed to evaluate spec '~a'" (evaluation-error-spec-name c)) #f)) - (log-message "evaluating spec '~a': stamp ~s different from ~s" - name commits-str stamp) + (log-message "evaluating spec '~a'" name) (with-store store - (let ((jobs (evaluate store spec checkouts commits))) + (let ((jobs (evaluate store spec eval-id checkouts))) (log-message "building ~a jobs for '~a'" (length jobs) name) - (build-packages store jobs)))))) + (build-packages store jobs eval-id)))))) ;; 'spawn-fiber' returns zero values but we need one. *unspecified*)))) diff --git a/src/cuirass/database.scm b/src/cuirass/database.scm index 912039e..6777d28 100644 --- a/src/cuirass/database.scm +++ b/src/cuirass/database.scm @@ -38,9 +38,9 @@ db-close db-add-specification db-get-specifications - db-add-stamp - db-get-stamp db-add-evaluation + db-set-evaluations-done + db-set-evaluation-done db-get-pending-derivations build-status db-add-build @@ -265,6 +265,29 @@ tag, revision, no_compile_p) VALUES (" (if (assq-ref input #:no-compile?) 1 0) ");") (last-insert-rowid db))) +(define (db-add-checkout spec-name eval-id checkout) + "Insert CHECKOUT associated with SPEC-NAME and EVAL-ID. If a checkout with +the same revision already exists for SPEC-NAME, return #f." + (with-db-critical-section db + (catch 'sqlite-error + (lambda () + (sqlite-exec db "\ +INSERT INTO Checkouts (specification, revision, evaluation, input, +directory) VALUES (" + spec-name ", " + (assq-ref checkout #:commit) ", " + eval-id ", " + (assq-ref checkout #:input) ", " + (assq-ref checkout #:directory) ");") + (last-insert-rowid db)) + (lambda (key who code message . rest) + ;; If we get a unique-constraint-failed error, that means we have + ;; already inserted the same checkout. That happens for each input + ;; that doesn't change between two evaluations. + (if (= code SQLITE_CONSTRAINT_PRIMARYKEY) + #f + (apply throw key who code rest)))))) + (define (db-add-specification spec) "Store SPEC in database the database. SPEC inputs are stored in the INPUTS table." @@ -328,13 +351,31 @@ package_path_inputs, proc_input, proc_file, proc, proc_args) \ (#:inputs . ,(db-get-inputs name))) specs))))))) -(define (db-add-evaluation eval) +(define (db-add-evaluation spec-name checkouts) + "Add a new evaluation for SPEC-NAME only if one of the CHECKOUTS is new. +Otherwise, return #f." (with-db-critical-section db - (sqlite-exec db "\ -INSERT INTO Evaluations (specification, commits) VALUES (" - (assq-ref eval #:specification) ", " - (string-join (assq-ref eval #:commits)) ");") - (last-insert-rowid db))) + (sqlite-exec db "BEGIN TRANSACTION;") + (sqlite-exec db "INSERT INTO Evaluations (specification, in_progress) +VALUES (" spec-name ", true);") + (let* ((eval-id (last-insert-rowid db)) + (new-checkouts (filter-map + (cut db-add-checkout spec-name eval-id <>) + checkouts))) + (if (null? new-checkouts) + (begin (sqlite-exec db "ROLLBACK;") + #f) + (begin (sqlite-exec db "COMMIT;") + eval-id))))) + +(define (db-set-evaluations-done) + (with-db-critical-section db + (sqlite-exec db "UPDATE Evaluations SET in_progress = false;"))) + +(define (db-set-evaluation-done eval-id) + (with-db-critical-section db + (sqlite-exec db "UPDATE Evaluations SET in_progress = false +WHERE id = " eval-id ";"))) (define-syntax-rule (with-database body ...) "Run BODY with %DB-CHANNEL being dynamically bound to a channel implementing @@ -568,46 +609,44 @@ the database. The returned list is guaranteed to not have any duplicates." (sqlite-exec db " SELECT derivation FROM Builds WHERE Builds.status < 0;")))) -(define (db-get-stamp spec) - "Return a stamp corresponding to specification SPEC in the database." +(define (db-get-checkouts eval-id) (with-db-critical-section db - (let ((res (sqlite-exec db "SELECT * FROM Stamps WHERE specification=" - (assq-ref spec #:name) ";"))) - (match res - (() #f) - ((#(spec stamp)) stamp))))) - -(define (db-add-stamp spec stamp) - "Associate STAMP to specification SPEC in the database." - (with-db-critical-section db - (if (db-get-stamp spec) - (sqlite-exec db "UPDATE Stamps SET stamp=" stamp - "WHERE specification=" (assq-ref spec #:name) ";") - (sqlite-exec db "\ -INSERT INTO Stamps (specification, stamp) VALUES (" - (assq-ref spec #:name) ", " stamp ");")))) + (let loop ((rows (sqlite-exec + db "SELECT revision, input, directory FROM Checkouts +WHERE evaluation =" eval-id ";")) + (checkouts '())) + (match rows + (() checkouts) + ((#(revision input directory) + . rest) + (loop rest + (cons `((#:commit . ,revision) + (#:input . ,input) + (#:directory . ,directory)) + checkouts))))))) (define (db-get-evaluations limit) (with-db-critical-section db - (let loop ((rows (sqlite-exec db "SELECT id, specification, commits + (let loop ((rows (sqlite-exec db "SELECT id, specification, in_progress FROM Evaluations ORDER BY id DESC LIMIT " limit ";")) (evaluations '())) (match rows (() (reverse evaluations)) - ((#(id specification commits) + ((#(id specification in-progress) . rest) (loop rest (cons `((#:id . ,id) (#:specification . ,specification) - (#:commits . ,(string-tokenize commits))) + (#:in-progress . ,in-progress) + (#:checkouts . ,(db-get-checkouts id))) evaluations))))))) (define (db-get-evaluations-build-summary spec limit border-low border-high) (with-db-critical-section db (let loop ((rows (sqlite-exec db " -SELECT E.id, E.commits, B.succeeded, B.failed, B.scheduled +SELECT E.id, E.in_progress, B.succeeded, B.failed, B.scheduled FROM -(SELECT id, commits +(SELECT id, in_progress FROM Evaluations WHERE (specification=" spec ") AND (" border-low "IS NULL OR (id >" border-low ")) @@ -624,10 +663,12 @@ ORDER BY E.id ASC;")) (evaluations '())) (match rows (() evaluations) - ((#(id commits succeeded failed scheduled) . rest) + ((#(id in-progress succeeded failed scheduled) . rest) (loop rest (cons `((#:id . ,id) - (#:commits . ,commits) + (#:in-progress . ,in-progress) + (#:checkouts . ,(db-get-checkouts id)) + (#:in-progress . ,in-progress) (#:succeeded . ,(or succeeded 0)) (#:failed . ,(or failed 0)) (#:scheduled . ,(or scheduled 0))) diff --git a/src/cuirass/templates.scm b/src/cuirass/templates.scm index 6ba3a06..7ee579c 100644 --- a/src/cuirass/templates.scm +++ b/src/cuirass/templates.scm @@ -100,6 +100,27 @@ (href ,last-link)) "Last >>")))))) +(define (input-changes checkouts) + (let ((changes + (string-join + (map (lambda (checkout) + (let ((input (assq-ref checkout #:input)) + (commit (assq-ref checkout #:commit))) + (format #f "~a → ~a" input (substring commit 0 7)))) + checkouts) + ", "))) + (if (string=? changes "") '(em "None") changes))) + +(define (evaluation-badges evaluation) + (if (zero? (assq-ref evaluation #:in-progress)) + `((a (@ (href "#") (class "badge badge-success")) + ,(assq-ref evaluation #:succeeded)) + (a (@ (href "#") (class "badge badge-danger")) + ,(assq-ref evaluation #:failed)) + (a (@ (href "#") (class "badge badge-secondary")) + ,(assq-ref evaluation #:scheduled))) + '((em "In progress…")))) + (define (evaluation-info-table name evaluations id-min id-max) "Return HTML for the EVALUATION table NAME. ID-MIN and ID-MAX are global minimal and maximal id." @@ -111,7 +132,7 @@ `((thead (tr (th (@ (scope "col")) "#") - (th (@ (scope "col")) Commits) + (th (@ (scope "col")) "Input changes") (th (@ (scope "col")) Success))) (tbody ,@(map @@ -119,16 +140,8 @@ `(tr (th (@ (scope "row")) (a (@ (href "/eval/" ,(assq-ref row #:id))) ,(assq-ref row #:id))) - (td ,(string-join - (map (cut substring <> 0 7) - (string-tokenize (assq-ref row #:commits))) - ", ")) - (td (a (@ (href "#") (class "badge badge-success")) - ,(assq-ref row #:succeeded)) - (a (@ (href "#") (class "badge badge-danger")) - ,(assq-ref row #:failed)) - (a (@ (href "#") (class "badge badge-secondary")) - ,(assq-ref row #:scheduled))))) + (td ,(input-changes (assq-ref row #:checkouts))) + (td ,@(evaluation-badges row)))) evaluations))))) ,(if (null? evaluations) (pagination "" "" "" "") diff --git a/src/schema.sql b/src/schema.sql index 0452495..bfc9ca7 100644 --- a/src/schema.sql +++ b/src/schema.sql @@ -24,16 +24,22 @@ CREATE TABLE Inputs ( FOREIGN KEY (specification) REFERENCES Specifications (name) ); -CREATE TABLE Stamps ( - specification TEXT NOT NULL PRIMARY KEY, - stamp TEXT NOT NULL, - FOREIGN KEY (specification) REFERENCES Specifications (name) +CREATE TABLE Checkouts ( + specification TEXT NOT NULL, + revision TEXT NOT NULL, + evaluation INTEGER NOT NULL, + input TEXT NOT NULL, + directory TEXT NOT NULL, + PRIMARY KEY (specification, revision), + FOREIGN KEY (evaluation) REFERENCES Evaluations (id), + FOREIGN KEY (specification) REFERENCES Specifications (name), + FOREIGN KEY (input) REFERENCES Inputs (name) ); CREATE TABLE Evaluations ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, specification TEXT NOT NULL, - commits TEXT NOT NULL, + in_progress INTEGER NOT NULL, FOREIGN KEY (specification) REFERENCES Specifications (name) ); diff --git a/src/sql/upgrade-3.sql b/src/sql/upgrade-3.sql new file mode 100644 index 0000000..8e4a1bd --- /dev/null +++ b/src/sql/upgrade-3.sql @@ -0,0 +1,46 @@ +BEGIN TRANSACTION; + +ALTER TABLE Evaluations RENAME TO tmp_Evaluations; + +CREATE TABLE Evaluations ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + specification TEXT NOT NULL, + in_progress INTEGER NOT NULL, + FOREIGN KEY (specification) REFERENCES Specifications (name) +); + +CREATE TABLE Checkouts ( + specification TEXT NOT NULL, + revision TEXT NOT NULL, + evaluation INTEGER NOT NULL, + input TEXT NOT NULL, + directory TEXT NOT NULL, + PRIMARY KEY (specification, revision), + FOREIGN KEY (evaluation) REFERENCES Evaluations (id), + FOREIGN KEY (specification) REFERENCES Specifications (name), + FOREIGN KEY (input) REFERENCES Inputs (name) +); + +INSERT INTO Evaluations (id, specification, in_progress) +SELECT id, specification, false +FROM tmp_Evaluations; + +-- Copied from https://www.samuelbosch.com/2018/02/split-into-rows-sqlite.html. +INSERT OR IGNORE INTO Checkouts (specification, revision, evaluation, input, directory) +WITH RECURSIVE split(id, specification, revision, rest) AS ( + SELECT id, specification, '', commits || ' ' FROM tmp_Evaluations + UNION ALL + SELECT id, + specification, + substr(rest, 0, instr(rest, ' ')), + substr(rest, instr(rest, ' ') + 1) + FROM split + WHERE rest <> '') +SELECT specification, revision, id, 'unknown', 'unknown' + FROM split + WHERE revision <> ''; + +DROP TABLE tmp_Evaluations; +DROP TABLE Stamps; + +COMMIT; diff --git a/tests/database.scm b/tests/database.scm index cdc7872..21a12f4 100644 --- a/tests/database.scm +++ b/tests/database.scm @@ -47,9 +47,13 @@ (#:commit . #f) (#:no-compile? . #f)))))) -(define* (make-dummy-eval #:optional (commits '("cabba3e 61730ea"))) - `((#:specification . "guix") - (#:commits . ,commits))) +(define (make-dummy-checkouts fakesha1 fakesha2) + `(((#:commit . ,fakesha1) + (#:input . "guix") + (#:directory . "foo")) + ((#:commit . ,fakesha2) + (#:input . "packages") + (#:directory . "bar")))) (define* (make-dummy-build drv #:optional (eval-id 42) @@ -88,11 +92,11 @@ (test-assert "sqlite-exec" (begin (sqlite-exec (%db) "\ -INSERT INTO Evaluations (specification, commits) VALUES (1, 1);") +INSERT INTO Evaluations (specification, in_progress) VALUES (1, false);") (sqlite-exec (%db) "\ -INSERT INTO Evaluations (specification, commits) VALUES (2, 2);") +INSERT INTO Evaluations (specification, in_progress) VALUES (2, false);") (sqlite-exec (%db) "\ -INSERT INTO Evaluations (specification, commits) VALUES (3, 3);") +INSERT INTO Evaluations (specification, in_progress) VALUES (3, false);") (sqlite-exec (%db) "SELECT * FROM Evaluations;"))) (test-equal "db-add-specification" @@ -121,7 +125,8 @@ INSERT INTO Evaluations (specification, commits) VALUES (3, 3);") #:outputs '(("out" . "/foo"))))) (get-status (lambda* (#:optional (key #:status)) (assq-ref (db-get-build derivation) key)))) - (db-add-evaluation (make-dummy-eval)) + (db-add-evaluation "guix" (make-dummy-checkouts "fakesha1" + "fakesha2")) (db-add-specification example-spec) (let ((status0 (get-status))) @@ -157,9 +162,9 @@ INSERT INTO Evaluations (specification, commits) VALUES (3, 3);") #:outputs `(("out" . "/bar")))) (db-add-build (make-dummy-build "/baz.drv" 3 #:outputs `(("out" . "/baz")))) - (db-add-evaluation (make-dummy-eval)) - (db-add-evaluation (make-dummy-eval)) - (db-add-evaluation (make-dummy-eval)) + (db-add-evaluation "guix" (make-dummy-checkouts "fakesha1" "fakesha2")) + (db-add-evaluation "guix" (make-dummy-checkouts "fakesha1" "fakesha3")) + (db-add-evaluation "guix" (make-dummy-checkouts "fakssha2" "fakesha3")) (db-add-specification example-spec) (db-update-build-status! "/bar.drv" (build-status started) @@ -188,9 +193,9 @@ INSERT INTO Evaluations (specification, commits) VALUES (3, 3);") #:outputs `(("out" . "/bar")))) (db-add-build (make-dummy-build "/foo.drv" 3 #:outputs `(("out" . "/foo")))) - (db-add-evaluation (make-dummy-eval)) - (db-add-evaluation (make-dummy-eval)) - (db-add-evaluation (make-dummy-eval)) + (db-add-evaluation "guix" (make-dummy-checkouts "fakesha1" "fakesha2")) + (db-add-evaluation "guix" (make-dummy-checkouts "fakesha1" "fakesha3")) + (db-add-evaluation "guix" (make-dummy-checkouts "fakssha2" "fakesha3")) (db-add-specification example-spec) (sort (db-get-pending-derivations) string <>)) + (_ equal?)))) (equal? value (hash-ref t2 key))))) #t @@ -95,9 +98,12 @@ (#:buildinputs_builds . #nil))) (define evaluations-query-result - '((#:id . 2) - (#:specification . "guix") - (#:commits . ("fakesha2" "fakesha3")))) + '(((#:id . 2) + (#:specification . "guix") + (#:in-progress . 1) + (#:checkouts . (((#:commit . "fakesha2") + (#:input . "savannah") + (#:directory . "dir3"))))))) (test-group-with-cleanup "http" (test-assert "object->json-string" @@ -175,23 +181,38 @@ (#:proc . hydra-jobs) (#:proc-args (subset . "hello")) (#:inputs . (((#:name . "savannah") + (#:url . "git://git.savannah.gnu.org/guix.git") + (#:load-path . ".") + (#:branch . "master") + (#:tag . #f) + (#:commit . #f) + (#:no-compile? . #f)) + ((#:name . "packages") (#:url . "git://git.savannah.gnu.org/guix.git") (#:load-path . ".") (#:branch . "master") (#:tag . #f) (#:commit . #f) (#:no-compile? . #f)))))) - (evaluation1 - '((#:specification . "guix") - (#:commits . ("fakesha1" "fakesha3")))) - (evaluation2 - '((#:specification . "guix") - (#:commits . ("fakesha2" "fakesha3"))))) + (checkouts1 + '(((#:commit . "fakesha1") + (#:input . "savannah") + (#:directory . "dir1")) + ((#:commit . "fakesha3") + (#:input . "packages") + (#:directory . "dir2")))) + (checkouts2 + '(((#:commit . "fakesha2") + (#:input . "savannah") + (#:directory . "dir3")) + ((#:commit . "fakesha3") + (#:input . "packages") + (#:directory . "dir4"))))) (db-add-build build1) (db-add-build build2) (db-add-specification specification) - (db-add-evaluation evaluation1) - (db-add-evaluation evaluation2))) + (db-add-evaluation "guix" checkouts1) + (db-add-evaluation "guix" checkouts2))) (test-assert "/build/1" (hash-table=? @@ -271,9 +292,9 @@ (and (= (length hash-list) 1) (hash-table=? (car hash-list) - (call-with-input-string - (object->json-string evaluations-query-result) - json->scm))))) + (car (call-with-input-string + (object->json-string evaluations-query-result) + json->scm)))))) (test-assert "db-close" (db-close (%db)))