123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- ;;; GNU Guix --- Functional package management for GNU
- ;;; Copyright © 2018-2022 Ludovic Courtès <ludo@gnu.org>
- ;;;
- ;;; This file is part of GNU Guix.
- ;;;
- ;;; GNU Guix is free software; you can redistribute it and/or modify it
- ;;; under the terms of the GNU General Public License as published by
- ;;; the Free Software Foundation; either version 3 of the License, or (at
- ;;; your option) any later version.
- ;;;
- ;;; GNU Guix is distributed in the hope that it will be useful, but
- ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
- ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;;; GNU General Public License for more details.
- ;;;
- ;;; You should have received a copy of the GNU General Public License
- ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
- (define-module (test-inferior)
- #:use-module (guix tests)
- #:use-module (guix inferior)
- #:use-module (guix packages)
- #:use-module (guix store)
- #:use-module (guix profiles)
- #:use-module (guix derivations)
- #:use-module (gnu packages)
- #:use-module (gnu packages bootstrap)
- #:use-module (gnu packages guile)
- #:use-module (gnu packages sqlite)
- #:use-module (srfi srfi-1)
- #:use-module (srfi srfi-34)
- #:use-module (srfi srfi-64)
- #:use-module (ice-9 match)
- #:use-module (ice-9 rdelim))
- (define %top-srcdir
- (dirname (search-path %load-path "guix.scm")))
- (define %top-builddir
- (dirname (search-path %load-compiled-path "guix.go")))
- (define %store
- (open-connection-for-tests))
- (define (manifest-entry->list entry)
- (list (manifest-entry-name entry)
- (manifest-entry-version entry)
- (manifest-entry-output entry)
- (manifest-entry-search-paths entry)
- (map manifest-entry->list (manifest-entry-dependencies entry))))
- (test-begin "inferior")
- (test-equal "open-inferior"
- '(42 #t)
- (let ((inferior (open-inferior %top-builddir
- #:command "scripts/guix")))
- (and (inferior? inferior)
- (let ((a (inferior-eval '(apply * '(6 7)) inferior))
- (b (inferior-eval '(@ (gnu packages base) coreutils)
- inferior)))
- (close-inferior inferior)
- (list a (inferior-object? b))))))
- (test-equal "close-inferior"
- '((hello) (world))
- (let* ((inferior1 (open-inferior %top-builddir #:command "scripts/guix"))
- (lst1 (inferior-eval '(list 'hello) inferior1))
- (inferior2 (open-inferior %top-builddir #:command "scripts/guix"))
- (lst2 (inferior-eval '(list 'world) inferior2)))
- ;; This call succeeds if and only if INFERIOR2 does not also hold a file
- ;; descriptor to the socketpair beneath INFERIOR1; otherwise it blocks.
- ;; See <https://issues.guix.gnu.org/55441#10>.
- (close-inferior inferior1)
- (close-inferior inferior2)
- (list lst1 lst2)))
- (test-equal "&inferior-exception"
- '(a b c d)
- (let ((inferior (open-inferior %top-builddir
- #:command "scripts/guix")))
- (guard (c ((inferior-exception? c)
- (close-inferior inferior)
- (and (eq? inferior (inferior-exception-inferior c))
- (match (inferior-exception-stack c)
- (((_ (files lines columns)) ..1)
- (member "guix/repl.scm" files)))
- (inferior-exception-arguments c))))
- (inferior-eval '(throw 'a 'b 'c 'd) inferior)
- 'badness)))
- (test-equal "&inferior-exception, legacy mode"
- '(a b c d)
- ;; Omit #:command to open an inferior in "legacy" mode, where Guile runs
- ;; directly.
- (let ((inferior (open-inferior %top-builddir)))
- (guard (c ((inferior-exception? c)
- (close-inferior inferior)
- (and (eq? inferior (inferior-exception-inferior c))
- (inferior-exception-arguments c))))
- (inferior-eval '(throw 'a 'b 'c 'd) inferior)
- 'badness)))
- (test-equal "inferior-packages"
- (take (sort (fold-packages (lambda (package lst)
- (cons (list (package-name package)
- (package-version package)
- (package-home-page package)
- (package-location package))
- lst))
- '())
- (lambda (x y)
- (string<? (car x) (car y))))
- 10)
- (let* ((inferior (open-inferior %top-builddir
- #:command "scripts/guix"))
- (packages (inferior-packages inferior)))
- (and (every string? (map inferior-package-synopsis packages))
- (let ()
- (define result
- (take (sort (map (lambda (package)
- (list (inferior-package-name package)
- (inferior-package-version package)
- (inferior-package-home-page package)
- (inferior-package-location package)))
- packages)
- (lambda (x y)
- (string<? (car x) (car y))))
- 10))
- (close-inferior inferior)
- result))))
- (test-equal "inferior-available-packages"
- (take (sort (fold-available-packages
- (lambda* (name version result
- #:key supported? deprecated?
- #:allow-other-keys)
- (if (and supported? (not deprecated?))
- (alist-cons name version result)
- result))
- '())
- (lambda (x y)
- (string<? (car x) (car y))))
- 10)
- (let* ((inferior (open-inferior %top-builddir
- #:command "scripts/guix"))
- (packages (inferior-available-packages inferior)))
- (close-inferior inferior)
- (take (sort packages (lambda (x y)
- (string<? (car x) (car y))))
- 10)))
- (test-equal "lookup-inferior-packages"
- (let ((->list (lambda (package)
- (list (package-name package)
- (package-version package)
- (package-location package)))))
- (list (map ->list (find-packages-by-name "guile" #f))
- (map ->list (find-packages-by-name "guile" "2.2"))))
- (let* ((inferior (open-inferior %top-builddir
- #:command "scripts/guix"))
- (->list (lambda (package)
- (list (inferior-package-name package)
- (inferior-package-version package)
- (inferior-package-location package))))
- (lst1 (map ->list
- (lookup-inferior-packages inferior "guile")))
- (lst2 (map ->list
- (lookup-inferior-packages inferior
- "guile" "2.2"))))
- (close-inferior inferior)
- (list lst1 lst2)))
- (test-assert "lookup-inferior-packages and eq?-ness"
- (let* ((inferior (open-inferior %top-builddir
- #:command "scripts/guix"))
- (lst1 (lookup-inferior-packages inferior "guile"))
- (lst2 (lookup-inferior-packages inferior "guile")))
- (close-inferior inferior)
- (every eq? lst1 lst2)))
- (test-equal "inferior-package-inputs"
- (let ((->list (match-lambda
- ((label (? package? package) . rest)
- `(,label
- (package ,(package-name package)
- ,(package-version package)
- ,(package-location package))
- ,@rest)))))
- (list (map ->list (package-inputs guile-3.0-latest))
- (map ->list (package-native-inputs guile-3.0-latest))
- (map ->list (package-propagated-inputs guile-3.0-latest))))
- (let* ((inferior (open-inferior %top-builddir
- #:command "scripts/guix"))
- (guile (first (lookup-inferior-packages inferior "guile")))
- (->list (match-lambda
- ((label (? inferior-package? package) . rest)
- `(,label
- (package ,(inferior-package-name package)
- ,(inferior-package-version package)
- ,(inferior-package-location package))
- ,@rest))))
- (result (list (map ->list (inferior-package-inputs guile))
- (map ->list
- (inferior-package-native-inputs guile))
- (map ->list
- (inferior-package-propagated-inputs
- guile)))))
- (close-inferior inferior)
- result))
- (test-equal "inferior-package-search-paths"
- (package-native-search-paths guile-3.0)
- (let* ((inferior (open-inferior %top-builddir
- #:command "scripts/guix"))
- (guile (first (lookup-inferior-packages inferior "guile")))
- (result (inferior-package-native-search-paths guile)))
- (close-inferior inferior)
- result))
- (test-equal "inferior-eval-with-store"
- (add-text-to-store %store "foo" "Hello, world!")
- (let* ((inferior (open-inferior %top-builddir
- #:command "scripts/guix")))
- (inferior-eval-with-store inferior %store
- '(lambda (store)
- (add-text-to-store store "foo"
- "Hello, world!")))))
- (test-assert "inferior-eval-with-store, &store-protocol-error"
- (let* ((inferior (open-inferior %top-builddir
- #:command "scripts/guix")))
- (guard (c ((store-protocol-error? c)
- (string-contains (store-protocol-error-message c)
- "invalid character")))
- (inferior-eval-with-store inferior %store
- '(lambda (store)
- (add-text-to-store store "we|rd/?!@"
- "uh uh")))
- #f)))
- (test-equal "inferior-eval-with-store, exception"
- '(the-answer = 42)
- (let ((inferior (open-inferior %top-builddir
- #:command "scripts/guix")))
- (guard (c ((inferior-exception? c)
- (close-inferior inferior)
- (inferior-exception-arguments c)))
- (inferior-eval-with-store inferior %store
- '(lambda (store)
- (throw 'the-answer '= 42))))))
- (test-equal "inferior-eval-with-store, not a procedure"
- 'wrong-type-arg
- (let ((inferior (open-inferior %top-builddir
- #:command "scripts/guix")))
- (guard (c ((inferior-exception? c)
- (close-inferior inferior)
- (car (inferior-exception-arguments c))))
- (inferior-eval-with-store inferior %store '(+ 1 2)))))
- (test-equal "inferior-package-derivation"
- (map derivation-file-name
- (list (package-derivation %store %bootstrap-guile "x86_64-linux")
- (package-derivation %store %bootstrap-guile "armhf-linux")))
- (let* ((inferior (open-inferior %top-builddir
- #:command "scripts/guix"))
- (packages (inferior-packages inferior))
- (guile (find (lambda (package)
- (string=? (package-name %bootstrap-guile)
- (inferior-package-name package)))
- packages)))
- (map derivation-file-name
- (list (inferior-package-derivation %store guile "x86_64-linux")
- (inferior-package-derivation %store guile "armhf-linux")))))
- (unless (package-replacement sqlite)
- (test-skip 1))
- (test-equal "inferior-package-replacement"
- (package-derivation %store
- (package-replacement sqlite)
- "x86_64-linux")
- (let* ((inferior (open-inferior %top-builddir
- #:command "scripts/guix"))
- (packages (inferior-packages inferior)))
- (match (lookup-inferior-packages inferior
- (package-name sqlite)
- (package-version sqlite))
- ((inferior-sqlite rest ...)
- (inferior-package-derivation %store
- (inferior-package-replacement
- inferior-sqlite)
- "x86_64-linux")))))
- (test-equal "inferior-package->manifest-entry"
- (manifest-entry->list (package->manifest-entry
- (first (find-best-packages-by-name "guile" #f))))
- (let* ((inferior (open-inferior %top-builddir
- #:command "scripts/guix"))
- (guile (first (lookup-inferior-packages inferior "guile")))
- (entry (inferior-package->manifest-entry guile)))
- (close-inferior inferior)
- (manifest-entry->list entry)))
- (test-equal "packages->manifest"
- (map manifest-entry->list
- (manifest-entries (packages->manifest
- (find-best-packages-by-name "guile" #f))))
- (let* ((inferior (open-inferior %top-builddir
- #:command "scripts/guix"))
- (guile (first (lookup-inferior-packages inferior "guile")))
- (manifest (packages->manifest (list guile))))
- (close-inferior inferior)
- (map manifest-entry->list (manifest-entries manifest))))
- (test-equal "#:error-port stderr"
- 42
- ;; There's a special case in open-bidirectional-pipe for
- ;; (current-error-port) being stderr, so this test just checks that
- ;; open-inferior doesn't raise an exception
- (let ((inferior (open-inferior %top-builddir
- #:command "scripts/guix"
- #:error-port (current-error-port))))
- (and (inferior? inferior)
- (inferior-eval '(display "test" (current-error-port)) inferior)
- (let ((result (inferior-eval '(apply * '(6 7)) inferior)))
- (close-inferior inferior)
- result))))
- (test-equal "#:error-port pipe"
- "42"
- (match (pipe)
- ((port-to-read-from . port-to-write-to)
- (setvbuf port-to-read-from 'line)
- (setvbuf port-to-write-to 'line)
- (let ((inferior (open-inferior %top-builddir
- #:command "scripts/guix"
- #:error-port port-to-write-to)))
- (and (inferior? inferior)
- (begin
- (inferior-eval '(display "42\n" (current-error-port)) inferior)
- (let loop ((line (read-line port-to-read-from)))
- (if (string=? line "42")
- (begin
- (close-inferior inferior)
- line)
- (loop (read-line port-to-read-from))))))))))
- (test-end "inferior")
|