gnu: parted: Update to 3.2.
[jackhill/guix/guix.git] / tests / graph.scm
CommitLineData
88856916
LC
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2015 Ludovic Courtès <ludo@gnu.org>
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (test-graph)
20 #:use-module (guix tests)
21 #:use-module (guix scripts graph)
22 #:use-module (guix packages)
23 #:use-module (guix derivations)
24 #:use-module (guix store)
25 #:use-module (guix monads)
26 #:use-module (guix build-system gnu)
27 #:use-module (guix gexp)
28 #:use-module (gnu packages)
29 #:use-module (gnu packages bootstrap)
30 #:use-module (ice-9 match)
31 #:use-module (srfi srfi-1)
32 #:use-module (srfi srfi-11)
33 #:use-module (srfi srfi-26)
34 #:use-module (srfi srfi-64))
35
36(define %store
37 (open-connection-for-tests))
38
39(define (make-recording-backend)
40 "Return a <graph-backend> and a thunk that returns the recorded nodes and
41edges."
42 (let ((nodes '())
43 (edges '()))
44 (define (record-node id label port)
45 (set! nodes (cons (list id label) nodes)))
46 (define (record-edge source target port)
47 (set! edges (cons (list source target) edges)))
48 (define (return)
49 (values (reverse nodes) (reverse edges)))
50
51 (values (graph-backend (const #t) (const #t)
52 record-node record-edge)
53 return)))
54
55(define (package->tuple package)
56 "Return a tuple representing PACKAGE as produced by %PACKAGE-NODE-TYPE."
57 (list (object-address package)
58 (package-full-name package)))
59
60(define (edge->tuple source target)
61 "Likewise for an edge from SOURCE to TARGET."
62 (list (object-address source)
63 (object-address target)))
64
65\f
66(test-begin "graph")
67
68(test-assert "package DAG"
69 (let-values (((backend nodes+edges) (make-recording-backend)))
70 (let* ((p1 (dummy-package "p1"))
71 (p2 (dummy-package "p2" (inputs `(("p1" ,p1)))))
72 (p3 (dummy-package "p3" (inputs `(("p2" ,p2) ("p1", p1))))))
73 (run-with-store %store
74 (export-graph (list p3) 'port
75 #:node-type %package-node-type
76 #:backend backend))
77 ;; We should see nothing more than these 3 packages.
78 (let-values (((nodes edges) (nodes+edges)))
79 (and (equal? nodes (map package->tuple (list p3 p2 p1)))
80 (equal? edges
81 (map edge->tuple
82 (list p3 p3 p2)
83 (list p2 p1 p1))))))))
84
85(test-assert "bag-emerged DAG"
86 (let-values (((backend nodes+edges) (make-recording-backend)))
87 (let ((p (dummy-package "p"))
88 (implicit (map (match-lambda
89 ((label package) package))
90 (standard-packages))))
91 (run-with-store %store
92 (export-graph (list p) 'port
93 #:node-type %bag-emerged-node-type
94 #:backend backend))
95 ;; We should see exactly P and IMPLICIT, with one edge from P to each
96 ;; element of IMPLICIT.
97 (let-values (((nodes edges) (nodes+edges)))
98 (and (equal? (match nodes
99 (((labels names) ...)
100 names))
101 (map package-full-name (cons p implicit)))
102 (equal? (match edges
103 (((sources destinations) ...)
104 (zip (map store-path-package-name sources)
105 (map store-path-package-name destinations))))
106 (map (lambda (destination)
107 (list "p-0.drv"
108 (string-append
109 (package-full-name destination)
110 ".drv")))
111 implicit)))))))
112
113(test-assert "bag DAG"
114 (let-values (((backend nodes+edges) (make-recording-backend)))
115 (let ((p (dummy-package "p")))
116 (run-with-store %store
117 (export-graph (list p) 'port
118 #:node-type %bag-node-type
119 #:backend backend))
120 ;; We should see P, its implicit inputs as well as the whole DAG, which
121 ;; should include bootstrap binaries.
122 (let-values (((nodes edges) (nodes+edges)))
123 (every (lambda (name)
124 (find (cut string=? name <>)
125 (match nodes
126 (((labels names) ...)
127 names))))
128 (match %bootstrap-inputs
129 (((labels packages) ...)
130 (map package-full-name packages))))))))
131
132(test-assert "derivation DAG"
133 (let-values (((backend nodes+edges) (make-recording-backend)))
134 (run-with-store %store
135 (mlet* %store-monad ((txt (text-file "text-file" "Hello!"))
136 (guile (package->derivation %bootstrap-guile))
137 (drv (gexp->derivation "output"
138 #~(symlink #$txt #$output)
139 #:guile-for-build
140 guile)))
141 ;; We should get at least these 3 nodes and corresponding edges.
142 (mbegin %store-monad
143 (export-graph (list drv) 'port
144 #:node-type %derivation-node-type
145 #:backend backend)
146 (let-values (((nodes edges) (nodes+edges)))
147 ;; XXX: For some reason we need to throw in some 'basename'.
148 (return (and (match nodes
149 (((ids labels) ...)
150 (let ((ids (map basename ids)))
151 (every (lambda (item)
152 (member (basename item) ids))
153 (list txt
154 (derivation-file-name drv)
155 (derivation-file-name guile))))))
156 (every (cut member <>
157 (map (lambda (edge)
158 (map basename edge))
159 edges))
160 (list (map (compose basename derivation-file-name)
161 (list drv guile))
162 (list (basename (derivation-file-name drv))
163 (basename txt))))))))))))
164
165(test-assert "reference DAG"
166 (let-values (((backend nodes+edges) (make-recording-backend)))
167 (run-with-store %store
168 (mlet* %store-monad ((txt (text-file "text-file" "Hello!"))
169 (guile (package->derivation %bootstrap-guile))
170 (drv (gexp->derivation "output"
171 #~(symlink #$txt #$output)
172 #:guile-for-build
173 guile))
174 (out -> (derivation->output-path drv)))
175 ;; We should see only OUT and TXT, with an edge from the former to the
176 ;; latter.
177 (mbegin %store-monad
178 (built-derivations (list drv))
179 (export-graph (list (derivation->output-path drv)) 'port
180 #:node-type %reference-node-type
181 #:backend backend)
182 (let-values (((nodes edges) (nodes+edges)))
183 (return
184 (and (equal? (match nodes
185 (((ids labels) ...)
186 ids))
187 (list out txt))
188 (equal? edges `((,out ,txt)))))))))))
189
190(test-end "graph")
191
192\f
193(exit (= (test-runner-fail-count (test-runner-current)) 0))