aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--doc/cuirass.texi55
-rw-r--r--src/cuirass/base.scm25
-rw-r--r--src/cuirass/database.scm174
-rw-r--r--src/schema.sql28
-rw-r--r--src/sql/upgrade-2.sql49
-rw-r--r--tests/database.scm78
-rw-r--r--tests/http.scm20
8 files changed, 193 insertions, 239 deletions
diff --git a/Makefile.am b/Makefile.am
index ac22601..db56165 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -65,7 +65,8 @@ nodist_webobject_DATA = \
dist_pkgdata_DATA = src/schema.sql
dist_sql_DATA = \
- src/sql/upgrade-1.sql
+ src/sql/upgrade-1.sql \
+ src/sql/upgrade-2.sql
dist_css_DATA = \
src/static/css/bootstrap.css \
diff --git a/doc/cuirass.texi b/doc/cuirass.texi
index d4c6ae1..b51cfad 100644
--- a/doc/cuirass.texi
+++ b/doc/cuirass.texi
@@ -249,9 +249,8 @@ 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{Derivations},
-@code{Builds} and @code{Outputs}. The purpose of each of these tables is
-explained below.
+@code{Inputs}, @code{Stamps}, @code{Evaluations}, @code{Builds} and
+@code{Outputs}. The purpose of each of these tables is explained below.
@section Specifications
@cindex specifications, database
@@ -349,9 +348,8 @@ and @code{stamp}, which holds the revisions (space separated commit hashes).
@section Evaluations
@cindex evaluations, database
-An evaluation relates a specification with the revision of the
-repository specified therein. Derivations and builds (see below) each
-belong to a specific evaluation.
+An evaluation relates a specification with the revision of the repository
+specified therein. Builds (see below) belong to a specific evaluation.
The @code{Evaluations} table has the following columns:
@@ -368,20 +366,21 @@ This text field holds the revisions (space separated commit hashes) of the
repositories specified as inputs of the related specification.
@end table
-@section Derivations
-@cindex derivations, database
+@section Builds
+@cindex builds, database
-This table associates a tuple of the absolute derivation file name and
-evaluation identifier with a job name.
+This table holds records of the derivations and their build status. Note that
+a job will be registered here only if its derivation doesn't already exist.
@table @code
@item derivation
-This column holds the absolute file name of the Guix derivation that is
-supposed to be evaluated for this job.
+This text field holds the absolute name of the derivation file that
+resulted in this build.
@item evaluation
-This field holds the @code{id} of an evaluation from the
-@code{Evaluations} table.
+This integer field references the evaluation identifier from the
+@code{Evaluations} table, indicating to which evaluation this build
+belongs.
@item job_name
This text field holds the name of the job.
@@ -393,28 +392,6 @@ This text field holds the system name of the derivation.
This text field holds the name of the derivation ---e.g.,
@code{coreutils-8.24}.
-@end table
-
-@section Builds
-@cindex builds, database
-
-This table holds records of completed or failed package builds. Note
-that builds are not in a one to one relationship with derivations in
-order to keep track of non-deterministic compilations.
-
-@table @code
-@item id
-This is an automatically incrementing numeric identifier.
-
-@item derivation
-This text field holds the absolute name of the derivation file that
-resulted in this build.
-
-@item evaluation
-This integer field references the evaluation identifier from the
-@code{Evaluations} table, indicating to which evaluation this build
-belongs.
-
@item log
This text field holds the absolute file name of the build log file.
@@ -442,9 +419,9 @@ stored in @code{Builds} table may have zero (if it has failed), one or
multiple outputs.
@table @code
-@item build
-This field holds the @code{id} of a build from the
-@code{Builds} table.
+@item derivation
+This field holds the @code{derivation} of a build from the @code{Builds}
+table.
@item name
This text field holds the name of the output.
diff --git a/src/cuirass/base.scm b/src/cuirass/base.scm
index 82f49a4..ab1ad31 100644
--- a/src/cuirass/base.scm
+++ b/src/cuirass/base.scm
@@ -280,11 +280,9 @@ Return a list of jobs."
db `((#:specification . ,spec-name)
(#:commits . ,commits)))))
(log-message "created evaluation ~a for '~a'" eval-id spec-name)
- (let ((jobs (map (lambda (job)
- (augment-job job eval-id))
- jobs)))
- (for-each (cut db-add-derivation db <>) jobs)
- jobs))))))
+ (map (lambda (job)
+ (augment-job job eval-id))
+ jobs))))))
;;;
@@ -546,6 +544,9 @@ procedure is meant to be called at startup."
(let* ((name (assq-ref job #:job-name))
(drv (assq-ref job #:derivation))
(eval-id (assq-ref job #:eval-id))
+ (job-name (assq-ref job #:job-name))
+ (system (assq-ref job #:system))
+ (nix-name (assq-ref job #:nix-name))
;; XXX: How to keep logs from several attempts?
(log (log-file store drv))
(outputs (filter-map (lambda (res)
@@ -556,6 +557,9 @@ procedure is meant to be called at startup."
(cur-time (time-second (current-time time-utc))))
(let ((build `((#:derivation . ,drv)
(#:eval-id . ,eval-id)
+ (#:job-name . ,job-name)
+ (#:system . ,system)
+ (#:nix-name . ,nix-name)
;; XXX: We'd leave LOG to #f (i.e., NULL) but that
;; currently violates the non-NULL constraint.
@@ -568,13 +572,12 @@ procedure is meant to be called at startup."
(#:stoptime . 0))))
(db-add-build db build))))
- (define build-ids
- (map register jobs))
+ (define derivations
+ (filter-map register jobs))
- (spawn-builds store db
- (map (cut assq-ref <> #:derivation) jobs))
+ (spawn-builds store db derivations)
- (let* ((results (filter-map (cut db-get-build db <>) build-ids))
+ (let* ((results (filter-map (cut db-get-build db <>) derivations))
(status (map (cut assq-ref <> #:status) results))
(success (count (lambda (status)
(= status (build-status succeeded)))
@@ -584,7 +587,7 @@ procedure is meant to be called at startup."
(((_ (#:path . (? string? outputs))) ...)
outputs))
outputs))
- (fail (- (length jobs) success)))
+ (fail (- (length derivations) success)))
(log-message "outputs:\n~a" (string-join outs "\n"))
(log-message "success: ~a, fail: ~a" success fail)
results))
diff --git a/src/cuirass/database.scm b/src/cuirass/database.scm
index e73b648..138da22 100644
--- a/src/cuirass/database.scm
+++ b/src/cuirass/database.scm
@@ -41,8 +41,6 @@
db-add-stamp
db-get-stamp
db-add-evaluation
- db-add-derivation
- db-get-derivation
db-get-pending-derivations
build-status
db-add-build
@@ -312,32 +310,6 @@ package_path_inputs, proc_input, proc_file, proc, proc_args) \
(#:inputs . ,(db-get-inputs db name)))
specs))))))
-(define (db-add-derivation db job)
- "Store a derivation result in database DB and return its ID."
- (catch 'sqlite-error
- (lambda ()
- (sqlite-exec db "\
-INSERT INTO Derivations (derivation, job_name, system, nix_name, evaluation)\
- VALUES ("
- (assq-ref job #:derivation) ", "
- (assq-ref job #:job-name) ", "
- (assq-ref job #:system) ", "
- (assq-ref job #:nix-name) ", "
- (assq-ref job #:eval-id) ");")
- (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 (derivation,eval-id) tuple. That happens
- ;; when several jobs produce the same derivation, and we can ignore it.
- (if (= code SQLITE_CONSTRAINT_PRIMARYKEY)
- (sqlite-exec db "SELECT * FROM Derivations WHERE derivation="
- (assq-ref job #:derivation) ";")
- (apply throw key who code rest)))))
-
-(define (db-get-derivation db id)
- "Retrieve a job in database DB which corresponds to ID."
- (car (sqlite-exec db "SELECT * FROM Derivations WHERE derivation=" id ";")))
-
(define (db-add-evaluation db eval)
(sqlite-exec db "\
INSERT INTO Evaluations (specification, commits) VALUES ("
@@ -384,27 +356,39 @@ string."
(define (db-add-build db build)
"Store BUILD in database DB. BUILD eventual outputs are stored
in the OUTPUTS table."
- (let* ((build-exec
- (sqlite-exec db "\
-INSERT INTO Builds (derivation, evaluation, log, status, timestamp, starttime, stoptime)\
- VALUES ("
- (assq-ref build #:derivation) ", "
- (assq-ref build #:eval-id) ", "
- (assq-ref build #:log) ", "
- (or (assq-ref build #:status)
- (build-status scheduled)) ", "
- (or (assq-ref build #:timestamp) 0) ", "
- (or (assq-ref build #:starttime) 0) ", "
- (or (assq-ref build #:stoptime) 0) ");"))
- (build-id (last-insert-rowid db)))
- (for-each (lambda (output)
- (match output
- ((name . path)
- (sqlite-exec db "\
-INSERT INTO Outputs (build, name, path) VALUES ("
- build-id ", " name ", " path ");"))))
- (assq-ref build #:outputs))
- build-id))
+ (catch 'sqlite-error
+ (lambda ()
+ (sqlite-exec db "
+INSERT INTO Builds (derivation, evaluation, job_name, system, nix_name, log,
+status, timestamp, starttime, stoptime)
+VALUES ("
+ (assq-ref build #:derivation) ", "
+ (assq-ref build #:eval-id) ", "
+ (assq-ref build #:job-name) ", "
+ (assq-ref build #:system) ", "
+ (assq-ref build #:nix-name) ", "
+ (assq-ref build #:log) ", "
+ (or (assq-ref build #:status)
+ (build-status scheduled)) ", "
+ (or (assq-ref build #:timestamp) 0) ", "
+ (or (assq-ref build #:starttime) 0) ", "
+ (or (assq-ref build #:stoptime) 0) ");")
+ (let ((derivation (assq-ref build #:derivation)))
+ (for-each (lambda (output)
+ (match output
+ ((name . path)
+ (sqlite-exec db "\
+INSERT INTO Outputs (derivation, name, path) VALUES ("
+ derivation ", " name ", " path ");"))))
+ (assq-ref build #:outputs))
+ derivation))
+ (lambda (key who code message . rest)
+ ;; If we get a unique-constraint-failed error, that means we have
+ ;; already inserted the same build. That happens when several jobs
+ ;; produce the same derivation, and we can ignore it.
+ (if (= code SQLITE_CONSTRAINT_PRIMARYKEY)
+ #f
+ (apply throw key who code rest)))))
(define* (db-update-build-status! db drv status #:key log-file)
"Update DB so that DRV's status is STATUS. This also updates the
@@ -429,11 +413,11 @@ log file for DRV."
", status=" status
"WHERE derivation=" drv " AND status != " status ";"))))
-(define (db-get-outputs db build-id)
- "Retrieve the OUTPUTS of the build identified by BUILD-ID in DB database."
+(define (db-get-outputs db derivation)
+ "Retrieve the OUTPUTS of the build identified by DERIVATION in DB database."
(let loop ((rows
- (sqlite-exec db "SELECT name, path FROM Outputs WHERE build="
- build-id ";"))
+ (sqlite-exec db "SELECT name, path FROM Outputs
+WHERE derivation =" derivation ";"))
(outputs '()))
(match rows
(() outputs)
@@ -445,56 +429,56 @@ log file for DRV."
(define (filters->order filters)
(match (assq 'order filters)
- (('order . 'build-id) "id ASC")
- (('order . 'decreasing-build-id) "id DESC")
+ (('order . 'build-id) "rowid ASC")
+ (('order . 'decreasing-build-id) "rowid DESC")
(('order . 'finish-time) "stoptime DESC")
- (('order . 'finish-time+build-id) "stoptime DESC, id DESC")
+ (('order . 'finish-time+build-id) "stoptime DESC, rowid DESC")
(('order . 'start-time) "starttime DESC")
(('order . 'submission-time) "timestamp DESC")
;; With this order, builds in 'running' state (-1) appear
;; before those in 'scheduled' state (-2).
(('order . 'status+submission-time) "status DESC, timestamp DESC")
- (_ "id DESC")))
+ (_ "rowid DESC")))
(define (db-get-builds db filters)
"Retrieve all builds in database DB which are matched by given FILTERS.
-FILTERS is an assoc list whose possible keys are 'id | 'jobset | 'job |
-'system | 'nr | 'order | 'status | 'evaluation."
+FILTERS is an assoc list whose possible keys are 'derivation | 'id | 'jobset |
+'job | 'system | 'nr | 'order | 'status | 'evaluation."
(let* ((order (filters->order filters))
(stmt-text (format #f "SELECT * FROM (
-SELECT Builds.id, Builds.timestamp, Builds.starttime, Builds.stoptime,
-Builds.log, Builds.status, Builds.derivation, Derivations.job_name,
-Derivations.system, Derivations.nix_name, Specifications.name
+SELECT Builds.derivation, Builds.rowid, Builds.timestamp, Builds.starttime,
+Builds.stoptime, Builds.log, Builds.status, Builds.job_name, Builds.system,
+Builds.nix_name, Specifications.name
FROM Builds
-INNER JOIN Derivations ON Builds.derivation = Derivations.derivation
-AND Builds.evaluation = Derivations.evaluation
-INNER JOIN Evaluations ON Derivations.evaluation = Evaluations.id
+INNER JOIN Evaluations ON Builds.evaluation = Evaluations.id
INNER JOIN Specifications ON Evaluations.specification = Specifications.name
-WHERE (:id IS NULL OR (:id = Builds.id))
+WHERE (:id IS NULL OR (:id = Builds.rowid))
+AND (:derivation IS NULL OR (:derivation = Builds.derivation))
AND (:jobset IS NULL OR (:jobset = Specifications.name))
-AND (:job IS NULL OR (:job = Derivations.job_name))
-AND (:system IS NULL OR (:system = Derivations.system))
+AND (:job IS NULL OR (:job = Builds.job_name))
+AND (:system IS NULL OR (:system = Builds.system))
AND (:evaluation IS NULL OR (:evaluation = Builds.evaluation))
AND (:status IS NULL OR (:status = 'done' AND Builds.status >= 0)
OR (:status = 'pending' AND Builds.status < 0))
AND (:borderlowtime IS NULL OR :borderlowid IS NULL
- OR ((:borderlowtime, :borderlowid) < (Builds.stoptime, Builds.id)))
+ OR ((:borderlowtime, :borderlowid) < (Builds.stoptime, Builds.rowid)))
AND (:borderhightime IS NULL OR :borderhighid IS NULL
- OR ((:borderhightime, :borderhighid) > (Builds.stoptime, Builds.id)))
+ OR ((:borderhightime, :borderhighid) > (Builds.stoptime, Builds.rowid)))
ORDER BY
CASE WHEN :borderlowtime IS NULL
OR :borderlowid IS NULL THEN Builds.stoptime
ELSE -Builds.stoptime
END DESC,
CASE WHEN :borderlowtime IS NULL
- OR :borderlowid IS NULL THEN Builds.id
- ELSE -Builds.id
+ OR :borderlowid IS NULL THEN Builds.rowid
+ ELSE -Builds.rowid
END DESC
LIMIT :nr)
-ORDER BY ~a, id ASC;" order))
+ORDER BY ~a, rowid ASC;" order))
(stmt (sqlite-prepare db stmt-text #:cache? #t)))
(sqlite-bind-arguments
stmt
+ #:derivation (assq-ref filters 'derivation)
#:id (assq-ref filters 'id)
#:jobset (assq-ref filters 'jobset)
#:job (assq-ref filters 'job)
@@ -513,45 +497,37 @@ ORDER BY ~a, id ASC;" order))
(builds '()))
(match rows
(() (reverse builds))
- ((#(id timestamp starttime stoptime log status derivation job-name
- system nix-name specification) . rest)
+ ((#(derivation id timestamp starttime stoptime log status job-name
+ system nix-name specification) . rest)
(loop rest
- (cons `((#:id . ,id)
+ (cons `((#:derivation . ,derivation)
+ (#:id . ,id)
(#:timestamp . ,timestamp)
(#:starttime . ,starttime)
(#:stoptime . ,stoptime)
(#:log . ,log)
(#:status . ,status)
- (#:derivation . ,derivation)
(#:job-name . ,job-name)
(#:system . ,system)
(#:nix-name . ,nix-name)
(#:specification . ,specification)
- (#:outputs . ,(db-get-outputs db id)))
+ (#:outputs . ,(db-get-outputs db derivation)))
builds)))))))
-(define (db-get-build db id)
- "Retrieve a build in database DB which corresponds to ID."
- (match (db-get-builds db `((id . ,id)))
- ((build)
- build)
- (() #f)))
+(define (db-get-build db derivation-or-id)
+ "Retrieve a build in database DB which corresponds to DERIVATION-OR-ID."
+ (let ((key (if (number? derivation-or-id) 'id 'derivation)))
+ (match (db-get-builds db `((,key . ,derivation-or-id)))
+ ((build)
+ build)
+ (() #f))))
(define (db-get-pending-derivations db)
"Return the list of derivation file names corresponding to pending builds in
DB. The returned list is guaranteed to not have any duplicates."
- ;; This is of course much more efficient than calling 'delete-duplicates' on
- ;; a list of results obtained without DISTINCT, both in space and time.
- ;;
- ;; Here we use a subquery so that sqlite can use two indexes instead of
- ;; creating a "TEMP B-TREE" when doing a single flat query, as "EXPLAIN
- ;; QUERY PLAN" shows.
(map (match-lambda (#(drv) drv))
(sqlite-exec db "
-SELECT DISTINCT derivation FROM (
- SELECT Derivations.derivation FROM Derivations INNER JOIN Builds
- WHERE Derivations.derivation = Builds.derivation AND Builds.status < 0
-);")))
+SELECT derivation FROM Builds WHERE Builds.status < 0;")))
(define (db-get-stamp db spec)
"Return a stamp corresponding to specification SPEC in database DB."
@@ -596,7 +572,7 @@ AND (" border-high "IS NULL OR (id <" border-high "))
ORDER BY CASE WHEN " border-low "IS NULL THEN id ELSE -id END DESC
LIMIT " limit ") E
LEFT JOIN
-(SELECT id, evaluation, SUM(status=0) as succeeded,
+(SELECT rowid, evaluation, SUM(status=0) as succeeded,
SUM(status>0) as failed, SUM(status<0) as scheduled
FROM Builds
GROUP BY evaluation) B
@@ -632,8 +608,8 @@ WHERE specification=" spec)))
"Return the min build (stoptime, id) pair for
the given evaluation EVAL."
(let ((rows (sqlite-exec db "
-SELECT stoptime, MIN(id) FROM
-(SELECT id, stoptime FROM Builds
+SELECT stoptime, MIN(rowid) FROM
+(SELECT rowid, stoptime FROM Builds
WHERE evaluation=" eval " AND
stoptime = (SELECT MIN(stoptime)
FROM Builds WHERE evaluation=" eval "))")))
@@ -643,8 +619,8 @@ FROM Builds WHERE evaluation=" eval "))")))
"Return the max build (stoptime, id) pair for
the given evaluation EVAL."
(let ((rows (sqlite-exec db "
-SELECT stoptime, MAX(id) FROM
-(SELECT id, stoptime FROM Builds
+SELECT stoptime, MAX(rowid) FROM
+(SELECT rowid, stoptime FROM Builds
WHERE evaluation=" eval " AND
stoptime = (SELECT MAX(stoptime)
FROM Builds WHERE evaluation=" eval "))")))
diff --git a/src/schema.sql b/src/schema.sql
index eb0f7e9..0452495 100644
--- a/src/schema.sql
+++ b/src/schema.sql
@@ -37,43 +37,31 @@ CREATE TABLE Evaluations (
FOREIGN KEY (specification) REFERENCES Specifications (name)
);
-CREATE TABLE Derivations (
- derivation TEXT NOT NULL,
- evaluation INTEGER NOT NULL,
- job_name TEXT NOT NULL,
- system TEXT NOT NULL,
- nix_name TEXT NOT NULL,
- PRIMARY KEY (derivation, evaluation),
- FOREIGN KEY (evaluation) REFERENCES Evaluations (id)
-);
-
CREATE TABLE Outputs (
- build INTEGER NOT NULL,
+ derivation TEXT NOT NULL,
name TEXT NOT NULL,
path TEXT NOT NULL,
- PRIMARY KEY (build, name),
- FOREIGN KEY (build) REFERENCES Builds (id)
+ PRIMARY KEY (derivation, name),
+ FOREIGN KEY (derivation) REFERENCES Builds (derivation)
);
--- Builds are not in a one to one relationship with derivations in order to
--- keep track of non deterministic compilations.
CREATE TABLE Builds (
- id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- derivation TEXT NOT NULL,
+ derivation TEXT NOT NULL PRIMARY KEY,
evaluation INTEGER NOT NULL,
+ job_name TEXT NOT NULL,
+ system TEXT NOT NULL,
+ nix_name TEXT NOT NULL,
log TEXT NOT NULL,
status INTEGER NOT NULL,
timestamp INTEGER NOT NULL,
starttime INTEGER NOT NULL,
stoptime INTEGER NOT NULL,
- FOREIGN KEY (derivation) REFERENCES Derivations (derivation),
FOREIGN KEY (evaluation) REFERENCES Evaluations (id)
);
-- Create indexes to speed up common queries, in particular those
-- corresponding to /api/latestbuilds and /api/queue HTTP requests.
-CREATE INDEX Builds_Derivations_index ON Builds(status ASC, timestamp ASC, id, derivation, evaluation, stoptime DESC);
+CREATE INDEX Builds_index ON Builds(job_name, system, status ASC, timestamp ASC, derivation, evaluation, stoptime DESC);
CREATE INDEX Inputs_index ON Inputs(specification, name, branch);
-CREATE INDEX Derivations_index ON Derivations(derivation, evaluation, job_name, system);
COMMIT;
diff --git a/src/sql/upgrade-2.sql b/src/sql/upgrade-2.sql
new file mode 100644
index 0000000..dfb919b
--- /dev/null
+++ b/src/sql/upgrade-2.sql
@@ -0,0 +1,49 @@
+BEGIN TRANSACTION;
+
+DROP INDEX Derivations_index;
+DROP INDEX Builds_Derivations_index;
+
+ALTER TABLE Outputs RENAME TO tmp_Outputs;
+ALTER TABLE Builds RENAME TO tmp_Builds;
+
+CREATE TABLE Builds (
+ derivation TEXT NOT NULL PRIMARY KEY,
+ evaluation INTEGER NOT NULL,
+ job_name TEXT NOT NULL,
+ system TEXT NOT NULL,
+ nix_name TEXT NOT NULL,
+ log TEXT NOT NULL,
+ status INTEGER NOT NULL,
+ timestamp INTEGER NOT NULL,
+ starttime INTEGER NOT NULL,
+ stoptime INTEGER NOT NULL,
+ FOREIGN KEY (evaluation) REFERENCES Evaluations (id)
+);
+
+CREATE TABLE Outputs (
+ derivation TEXT NOT NULL,
+ name TEXT NOT NULL,
+ path TEXT NOT NULL,
+ PRIMARY KEY (derivation, name),
+ FOREIGN KEY (derivation) REFERENCES Builds (derivation)
+);
+
+INSERT OR IGNORE INTO Builds (derivation, evaluation, job_name, system, nix_name, log, status, timestamp, starttime, stoptime)
+SELECT Derivations.derivation, Derivations.evaluation, Derivations.job_name, Derivations.system, Derivations.nix_name,
+ tmp_Builds.log, tmp_Builds.status, tmp_Builds.timestamp, tmp_Builds.starttime, tmp_Builds.stoptime
+FROM Derivations
+INNER JOIN tmp_Builds ON tmp_Builds.derivation = Derivations.derivation
+ AND tmp_Builds.evaluation = Derivations.evaluation;
+
+INSERT OR IGNORE INTO Outputs (derivation, name, path)
+SELECT tmp_Builds.derivation, tmp_Outputs.name, tmp_Outputs.path
+FROM tmp_Outputs
+INNER JOIN tmp_Builds on tmp_Builds.id = tmp_Outputs.build;
+
+CREATE INDEX Builds_index ON Builds(job_name, system, status ASC, timestamp ASC, derivation, evaluation, stoptime DESC);
+
+DROP TABLE tmp_Builds;
+DROP TABLE tmp_Outputs;
+DROP TABLE Derivations;
+
+COMMIT;
diff --git a/tests/database.scm b/tests/database.scm
index 17d48f5..af518bd 100644
--- a/tests/database.scm
+++ b/tests/database.scm
@@ -50,27 +50,14 @@
`((#:specification . "guix")
(#:commits . ,commits)))
-(define* (make-dummy-job #:optional (name "foo"))
- `((#:name . ,name)
- (#:job-name . "job")
- (#:system . "x86_64-linux")
- (#:derivation . ,(string-append name ".drv"))
- (#:nix-name . "foo")
- (#:specification 0)
- (#:eval-id . 42)))
-
-(define* (make-dummy-derivation drv #:optional (eval-id 0))
+(define* (make-dummy-build drv
+ #:optional (eval-id 42)
+ #:key (outputs '(("foo" . "/foo"))))
`((#:derivation . ,drv)
+ (#:eval-id . ,eval-id)
(#:job-name . "job")
(#:system . "x86_64-linux")
- (#:nix-name . ,(basename drv ".drv"))
- (#:eval-id . ,eval-id)))
-
-(define* (make-dummy-build #:optional (eval-id 42)
- #:key (drv "/foo.drv")
- (outputs '(("foo" . "/foo"))))
- `((#:derivation . ,drv)
- (#:eval-id . ,eval-id)
+ (#:nix-name . "foo")
(#:log . "log")
(#:outputs . (("foo" . "/foo")))))
@@ -86,10 +73,6 @@
;; Global Slot for a database object.
(make-parameter #t))
-(define %id
- ;; Global Slot for a job ID in the database.
- (make-parameter #t))
-
(define database-name
;; Use an empty and temporary database for the tests.
(string-append (getcwd) "/" (number->string (getpid)) "-tmp.db"))
@@ -114,21 +97,13 @@ INSERT INTO Evaluations (specification, commits) VALUES (3, 3);")
(db-add-specification (%db) example-spec)
(car (db-get-specifications (%db)))))
- (test-assert "db-add-derivation"
- (let* ((job (make-dummy-job))
- (key (assq-ref job #:derivation)))
- (db-add-derivation (%db) job)
- (db-add-derivation (%db) job) ;idempotent
- (%id key)))
-
- (test-assert "db-get-derivation"
- (db-get-derivation (%db) (%id)))
-
- (test-assert "db-add-build"
- (let ((build (make-dummy-build)))
+ (test-equal "db-add-build"
+ #f
+ (let ((build (make-dummy-build "/foo.drv")))
(db-add-build (%db) build)
- ;; This should be idempotent, see <https://bugs.gnu.org/28094>.
+ ;; Should return #f when adding a build whose derivation is already
+ ;; there, see <https://bugs.gnu.org/28094>.
(db-add-build (%db) build)))
(test-equal "db-update-build-status!"
@@ -137,13 +112,12 @@ INSERT INTO Evaluations (specification, commits) VALUES (3, 3);")
(build-status succeeded)
"/foo.drv.log")
(with-temporary-database db
- (let* ((id (db-add-build
- db
- (make-dummy-build 1 #:drv "/foo.drv"
- #:outputs '(("out" . "/foo")))))
+ (let* ((derivation (db-add-build
+ db
+ (make-dummy-build "/foo.drv" 1
+ #:outputs '(("out" . "/foo")))))
(get-status (lambda* (#:optional (key #:status))
- (assq-ref (db-get-build db id) key))))
- (db-add-derivation db (make-dummy-derivation "/foo.drv" 1))
+ (assq-ref (db-get-build db derivation) key))))
(db-add-evaluation db (make-dummy-eval))
(db-add-specification db example-spec)
@@ -171,18 +145,15 @@ INSERT INTO Evaluations (specification, commits) VALUES (3, 3);")
((3 "/baz.drv")) ;nr = 1
((2 "/bar.drv") (1 "/foo.drv") (3 "/baz.drv"))) ;status+submission-time
(with-temporary-database db
- ;; Populate the 'Builds', 'Derivations', 'Evaluations', and
+ ;; Populate the 'Builds'', 'Evaluations', and
;; 'Specifications' tables in a consistent way, as expected by the
;; 'db-get-builds' query.
- (db-add-build db (make-dummy-build 1 #:drv "/foo.drv"
+ (db-add-build db (make-dummy-build "/foo.drv" 1
#:outputs `(("out" . "/foo"))))
- (db-add-build db (make-dummy-build 2 #:drv "/bar.drv"
+ (db-add-build db (make-dummy-build "/bar.drv" 2
#:outputs `(("out" . "/bar"))))
- (db-add-build db (make-dummy-build 3 #:drv "/baz.drv"
+ (db-add-build db (make-dummy-build "/baz.drv" 3
#:outputs `(("out" . "/baz"))))
- (db-add-derivation db (make-dummy-derivation "/foo.drv" 1))
- (db-add-derivation db (make-dummy-derivation "/bar.drv" 2))
- (db-add-derivation db (make-dummy-derivation "/baz.drv" 3))
(db-add-evaluation db (make-dummy-eval))
(db-add-evaluation db (make-dummy-eval))
(db-add-evaluation db (make-dummy-eval))
@@ -206,19 +177,16 @@ INSERT INTO Evaluations (specification, commits) VALUES (3, 3);")
(test-equal "db-get-pending-derivations"
'("/bar.drv" "/foo.drv")
(with-temporary-database db
- ;; Populate the 'Builds', 'Derivations', 'Evaluations', and
+ ;; Populate the 'Builds', 'Evaluations', and
;; 'Specifications' tables. Here, two builds map to the same derivation
;; but the result of 'db-get-pending-derivations' must not contain any
;; duplicate.
- (db-add-build db (make-dummy-build 1 #:drv "/foo.drv"
+ (db-add-build db (make-dummy-build "/foo.drv" 1
#:outputs `(("out" . "/foo"))))
- (db-add-build db (make-dummy-build 2 #:drv "/bar.drv"
+ (db-add-build db (make-dummy-build "/bar.drv" 2
#:outputs `(("out" . "/bar"))))
- (db-add-build db (make-dummy-build 3 #:drv "/foo.drv"
+ (db-add-build db (make-dummy-build "/foo.drv" 3
#:outputs `(("out" . "/foo"))))
- (db-add-derivation db (make-dummy-derivation "/foo.drv" 1))
- (db-add-derivation db (make-dummy-derivation "/bar.drv" 2))
- (db-add-derivation db (make-dummy-derivation "/foo.drv" 3))
(db-add-evaluation db (make-dummy-eval))
(db-add-evaluation db (make-dummy-eval))
(db-add-evaluation db (make-dummy-eval))
diff --git a/tests/http.scm b/tests/http.scm
index e05fdc5..a9fc3ef 100644
--- a/tests/http.scm
+++ b/tests/http.scm
@@ -142,6 +142,9 @@
(let* ((build1
`((#:derivation . "/gnu/store/fake.drv")
(#:eval-id . 1)
+ (#:job-name . "fake-job")
+ (#:system . "x86_64-linux")
+ (#:nix-name . "fake-1.0")
(#:log . "unused so far")
(#:status . ,(build-status succeeded))
(#:outputs . (("out" . "/gnu/store/fake-1.0")))
@@ -151,24 +154,15 @@
(build2
`((#:derivation . "/gnu/store/fake2.drv")
(#:eval-id . 1)
+ (#:job-name . "fake-job")
+ (#:system . "x86_64-linux")
+ (#:nix-name . "fake-2.0")
(#:log . "unused so far")
(#:status . ,(build-status scheduled))
(#:outputs . (("out" . "/gnu/store/fake-2.0")))
(#:timestamp . 1501347493)
(#:starttime . 0)
(#:stoptime . 0)))
- (derivation1
- '((#:derivation . "/gnu/store/fake.drv")
- (#:job-name . "fake-job")
- (#:system . "x86_64-linux")
- (#:nix-name . "fake-1.0")
- (#:eval-id . 1)))
- (derivation2
- '((#:derivation . "/gnu/store/fake2.drv")
- (#:job-name . "fake-job")
- (#:system . "x86_64-linux")
- (#:nix-name . "fake-2.0")
- (#:eval-id . 1)))
(specification
'((#:name . "guix")
(#:load-path-inputs . ("savannah"))
@@ -192,8 +186,6 @@
(#:commits . ("fakesha2" "fakesha3")))))
(db-add-build (%db) build1)
(db-add-build (%db) build2)
- (db-add-derivation (%db) derivation1)
- (db-add-derivation (%db) derivation2)
(db-add-specification (%db) specification)
(db-add-evaluation (%db) evaluation1)
(db-add-evaluation (%db) evaluation2)))