gnu: cran.scm: Add missing module.
[jackhill/guix/guix.git] / gnu / tests / networking.scm
CommitLineData
9260b9d1
TD
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2017 Thomas Danckaert <post@thomasdanckaert.be>
671dbdb9 3;;; Copyright © 2017 Marius Bakke <mbakke@fastmail.com>
9260b9d1
TD
4;;;
5;;; This file is part of GNU Guix.
6;;;
7;;; GNU Guix is free software; you can redistribute it and/or modify it
8;;; under the terms of the GNU General Public License as published by
9;;; the Free Software Foundation; either version 3 of the License, or (at
10;;; your option) any later version.
11;;;
12;;; GNU Guix is distributed in the hope that it will be useful, but
13;;; WITHOUT ANY WARRANTY; without even the implied warranty of
14;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;;; GNU General Public License for more details.
16;;;
17;;; You should have received a copy of the GNU General Public License
18;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
19
20(define-module (gnu tests networking)
21 #:use-module (gnu tests)
22 #:use-module (gnu system)
9260b9d1
TD
23 #:use-module (gnu system vm)
24 #:use-module (gnu services)
9260b9d1
TD
25 #:use-module (gnu services networking)
26 #:use-module (guix gexp)
27 #:use-module (guix store)
28 #:use-module (guix monads)
29 #:use-module (gnu packages bash)
671dbdb9
MB
30 #:use-module (gnu packages networking)
31 #:use-module (gnu services shepherd)
32 #:export (%test-inetd %test-openvswitch))
9260b9d1
TD
33
34(define %inetd-os
35 ;; Operating system with 2 inetd services.
892d9089
LC
36 (simple-operating-system
37 (dhcp-client-service)
38 (service inetd-service-type
39 (inetd-configuration
40 (entries (list
41 (inetd-entry
42 (name "echo")
43 (socket-type 'stream)
44 (protocol "tcp")
45 (wait? #f)
46 (user "root"))
47 (inetd-entry
48 (name "dict")
49 (socket-type 'stream)
50 (protocol "tcp")
51 (wait? #f)
52 (user "root")
53 (program (file-append bash
54 "/bin/bash"))
55 (arguments
56 (list "bash" (plain-file "my-dict.sh" "\
9260b9d1
TD
57while read line
58do
59 if [[ $line =~ ^DEFINE\\ (.*)$ ]]
60 then
61 case ${BASH_REMATCH[1]} in
62 Guix)
63 echo GNU Guix is a package management tool for the GNU system.
64 ;;
65 G-expression)
66 echo Like an S-expression but with a G.
67 ;;
68 *)
69 echo NO DEFINITION FOUND
70 ;;
71 esac
72 else
73 echo ERROR
74 fi
892d9089 75done" ))))))))))
9260b9d1
TD
76
77(define* (run-inetd-test)
78 "Run tests in %INETD-OS, where the inetd service provides an echo service on
79port 7, and a dict service on port 2628."
8b113790
LC
80 (define os
81 (marionette-operating-system %inetd-os))
9260b9d1 82
8b113790
LC
83 (define vm
84 (virtual-machine
85 (operating-system os)
86 (port-forwardings `((8007 . 7)
87 (8628 . 2628)))))
9260b9d1 88
8b113790
LC
89 (define test
90 (with-imported-modules '((gnu build marionette))
91 #~(begin
92 (use-modules (ice-9 rdelim)
93 (srfi srfi-64)
94 (gnu build marionette))
95 (define marionette
96 (make-marionette (list #$vm)))
9260b9d1 97
8b113790
LC
98 (mkdir #$output)
99 (chdir #$output)
9260b9d1 100
8b113790 101 (test-begin "inetd")
9260b9d1 102
8b113790
LC
103 ;; Make sure the PID file is created.
104 (test-assert "PID file"
105 (marionette-eval
106 '(file-exists? "/var/run/inetd.pid")
107 marionette))
9260b9d1 108
8b113790
LC
109 ;; Test the echo service.
110 (test-equal "echo response"
111 "Hello, Guix!"
112 (let ((echo (socket PF_INET SOCK_STREAM 0))
113 (addr (make-socket-address AF_INET INADDR_LOOPBACK 8007)))
114 (connect echo addr)
115 (display "Hello, Guix!\n" echo)
116 (let ((response (read-line echo)))
117 (close echo)
118 response)))
9260b9d1 119
8b113790
LC
120 ;; Test the dict service
121 (test-equal "dict response"
122 "GNU Guix is a package management tool for the GNU system."
123 (let ((dict (socket PF_INET SOCK_STREAM 0))
124 (addr (make-socket-address AF_INET INADDR_LOOPBACK 8628)))
125 (connect dict addr)
126 (display "DEFINE Guix\n" dict)
127 (let ((response (read-line dict)))
128 (close dict)
129 response)))
130
131 (test-end)
132 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
133
134 (gexp->derivation "inetd-test" test))
9260b9d1
TD
135
136(define %test-inetd
137 (system-test
138 (name "inetd")
139 (description "Connect to a host with an INETD server.")
140 (value (run-inetd-test))))
671dbdb9
MB
141
142\f
143;;;
144;;; Open vSwitch
145;;;
146
147(define setup-openvswitch
148 #~(let ((ovs-vsctl (lambda (str)
149 (zero? (apply system*
150 #$(file-append openvswitch "/bin/ovs-vsctl")
151 (string-tokenize str)))))
152 (add-native-port (lambda (if)
153 (string-append "--may-exist add-port br0 " if
154 " vlan_mode=native-untagged"
155 " -- set Interface " if
156 " type=internal"))))
157 (and (ovs-vsctl "--may-exist add-br br0")
158 ;; Connect eth0 as an "untagged" port (no VLANs).
159 (ovs-vsctl "--may-exist add-port br0 eth0 vlan_mode=native-untagged")
160 (ovs-vsctl (add-native-port "ovs0")))))
161
162(define openvswitch-configuration-service
163 (simple-service 'openvswitch-configuration shepherd-root-service-type
164 (list (shepherd-service
165 (provision '(openvswitch-configuration))
166 (requirement '(vswitchd))
167 (start #~(lambda ()
168 #$setup-openvswitch))
169 (respawn? #f)))))
170
171(define %openvswitch-os
172 (simple-operating-system
173 (static-networking-service "ovs0" "10.1.1.1"
174 #:netmask "255.255.255.252"
175 #:requirement '(openvswitch-configuration))
176 (service openvswitch-service-type
177 (openvswitch-configuration
178 (package openvswitch)))
179 openvswitch-configuration-service))
180
181(define (run-openvswitch-test)
182 (define os
183 (marionette-operating-system %openvswitch-os
184 #:imported-modules '((gnu services herd))))
185
186 (define test
187 (with-imported-modules '((gnu build marionette))
188 #~(begin
189 (use-modules (gnu build marionette)
190 (ice-9 popen)
191 (ice-9 rdelim)
192 (srfi srfi-64))
193
194 (define marionette
195 (make-marionette (list #$(virtual-machine os))))
196
197 (mkdir #$output)
198 (chdir #$output)
199
200 (test-begin "openvswitch")
201
202 ;; Make sure the bridge is created.
203 (test-assert "br0 exists"
204 (marionette-eval
205 '(zero? (system* "ovs-vsctl" "br-exists" "br0"))
206 marionette))
207
208 ;; Make sure eth0 is connected to the bridge.
209 (test-equal "eth0 is connected to br0"
210 "br0"
211 (marionette-eval
212 '(begin
213 (use-modules (ice-9 popen) (ice-9 rdelim))
214 (let* ((port (open-pipe*
215 OPEN_READ
216 (string-append #$openvswitch "/bin/ovs-vsctl")
217 "port-to-br" "eth0"))
218 (output (read-line port)))
219 (close-pipe port)
220 output))
221 marionette))
222
223 ;; Make sure the virtual interface got a static IP.
224 (test-assert "networking has started on ovs0"
225 (marionette-eval
226 '(begin
227 (use-modules (gnu services herd)
228 (srfi srfi-1))
229 (live-service-running
230 (find (lambda (live)
231 (memq 'networking-ovs0
232 (live-service-provision live)))
233 (current-services))))
234 marionette))
235
236 (test-end)
237 (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
238
239 (gexp->derivation "openvswitch-test" test))
240
241(define %test-openvswitch
242 (system-test
243 (name "openvswitch")
244 (description "Test a running OpenvSwitch configuration.")
245 (value (run-openvswitch-test))))