Skip to content

Commit 556e7f3

Browse files
committed
test: add more graceful shutdown tests
1 parent 04f8b57 commit 556e7f3

File tree

2 files changed

+147
-2
lines changed

2 files changed

+147
-2
lines changed

web-server-test/tests/web-server/all-web-server-tests.rkt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"formlets-test.rkt"
1515
"dispatch-test.rkt"
1616
"servlet-env-test.rkt"
17-
"test-tests.rkt")
17+
"test-tests.rkt"
18+
"serve-tests.rkt")
1819
(provide all-web-server-tests)
1920

2021
(define all-web-server-tests
@@ -34,4 +35,5 @@
3435
all-servlet-tests
3536
servlet-env-tests
3637
test-tests
37-
all-e2e-tests))
38+
all-e2e-tests
39+
serve-tests))
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#lang racket/base
2+
3+
(require net/http-client
4+
racket/async-channel
5+
racket/port
6+
racket/promise
7+
rackunit
8+
web-server/http
9+
web-server/safety-limits
10+
web-server/servlet-dispatch
11+
web-server/web-server)
12+
13+
(provide
14+
serve-tests)
15+
16+
(define (call-with-web-server
17+
#:limits [limits (make-safety-limits #:shutdown-grace-period 5)]
18+
handler proc)
19+
(define confirmation-ch
20+
(make-async-channel))
21+
(define stop
22+
(serve
23+
#:port 0
24+
#:dispatch (dispatch/servlet handler)
25+
#:confirmation-channel confirmation-ch
26+
#:safety-limits limits))
27+
(define port-or-exn
28+
(sync confirmation-ch))
29+
(when (exn:fail? port-or-exn)
30+
(raise port-or-exn))
31+
(dynamic-wind
32+
void
33+
(lambda ()
34+
(proc port-or-exn stop))
35+
(lambda ()
36+
(stop))))
37+
38+
(define-check (check-duration proc lo hi timeout)
39+
(define promise
40+
(delay/thread
41+
(define-values (_ _cpu-time real-time _gc-time)
42+
(time-apply proc null))
43+
(/ real-time 1000)))
44+
(define real-time
45+
(sync/timeout
46+
timeout
47+
(handle-evt
48+
promise
49+
(lambda (_)
50+
(force promise)))))
51+
(unless real-time
52+
(fail-check "timed out"))
53+
(check-true
54+
(real-time . >= . lo)
55+
(format "took more than ~a seconds to run" lo))
56+
(check-true
57+
(real-time . <= . hi)
58+
(format "took less than ~a seconds to run" hi)))
59+
60+
(define serve-tests
61+
(test-suite
62+
"serve"
63+
64+
(test-suite
65+
"graceful shutdown"
66+
67+
(test-case "stops immediately if there are no connections"
68+
(call-with-web-server
69+
(lambda (_req)
70+
(response/empty))
71+
(lambda (_port stop)
72+
(check-duration stop 0 1 5))))
73+
74+
(test-case "waits for in-progress requests to finish"
75+
(call-with-web-server
76+
(lambda (_req)
77+
(response/output
78+
(lambda (out)
79+
(for ([idx (in-range 2)])
80+
(displayln idx out)
81+
(sleep 1)))))
82+
(lambda (port stop)
83+
(define hc (http-conn-open "127.0.0.1" #:port port))
84+
(define-values (status _headers in)
85+
(http-conn-sendrecv! hc "/"))
86+
(check-equal? status #"HTTP/1.1 200 OK")
87+
(check-duration stop 2 6 6)
88+
(check-equal? (port->bytes in) #"0\n1\n"))))
89+
90+
(test-case "stops when in-progress requests stop"
91+
(call-with-web-server
92+
(lambda (_req)
93+
(response/output
94+
(lambda (out)
95+
(for ([idx (in-range 10)])
96+
(displayln idx out)
97+
(sleep 1)))))
98+
(lambda (port stop)
99+
(define hc (http-conn-open "127.0.0.1" #:port port))
100+
(define-values (status _headers in)
101+
(http-conn-sendrecv! hc "/"))
102+
(check-equal? status #"HTTP/1.1 200 OK")
103+
(thread
104+
(lambda ()
105+
(read-line in)
106+
(close-input-port in)
107+
(http-conn-close! hc)))
108+
(check-duration stop 1 3 5))))
109+
110+
(test-case "kills the server if stop is called twice"
111+
(define started?-sema
112+
(make-semaphore))
113+
(call-with-web-server
114+
(lambda (_req)
115+
(response/output
116+
(lambda (out)
117+
(displayln "start" out)
118+
(semaphore-post started?-sema)
119+
(sleep 100)
120+
(displayln "end" out))))
121+
(lambda (port stop)
122+
(define hc (http-conn-open "127.0.0.1" #:port port))
123+
(define-values (status _headers in)
124+
(http-conn-sendrecv! hc "/"))
125+
(check-equal? status #"HTTP/1.1 200 OK")
126+
(define data-promise
127+
(delay/thread
128+
(port->bytes in)))
129+
(semaphore-wait started?-sema)
130+
(define stop-thds
131+
(for/list ([_ (in-range 2)])
132+
(thread stop)))
133+
(check-duration
134+
(lambda ()
135+
(for-each thread-wait stop-thds))
136+
0 1 2)
137+
(check-equal?
138+
(force data-promise)
139+
#"start\n")))))))
140+
141+
(module+ test
142+
(require rackunit/text-ui)
143+
(run-tests serve-tests))

0 commit comments

Comments
 (0)