Skip to content

Commit a07a9e6

Browse files
ikappakibbatsov
authored andcommitted
Add nREPL server logging, inc time out, don't kill server buf on err
This is a temporary hack for the Clojure cli and shadow integration tests, which intermittently timing out on eval (see #3298), to capture and dump out the input and output traffic on the nREPL server for post-mortem investigation. The time out period is also increased to 30secs. In addition to this, the `nrepl-server-sentinel' does not kill the `server-buffer` when there is a startup error, since the buffer can hold valuable information for the user to inspect what might have gone wrong during start up (this is probably a regression from the integration tests restructuring).
1 parent 6d1f6de commit a07a9e6

File tree

2 files changed

+138
-100
lines changed

2 files changed

+138
-100
lines changed

nrepl-client.el

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,12 +1200,12 @@ an `error' if the nREPL PROCESS exited because it couldn't start up."
12001200
server-buffer))
12011201
(buffer-list))))
12021202
;; close any known open client connections
1203-
(when server-buffer
1204-
(kill-buffer server-buffer))
12051203
(mapc #'cider--close-connection clients)
12061204

12071205
(if (process-get process :cider--nrepl-server-ready)
1208-
(message "nREPL server exited.")
1206+
(progn
1207+
(when server-buffer (kill-buffer server-buffer))
1208+
(message "nREPL server exited."))
12091209
(let ((problem (when (and server-buffer (buffer-live-p server-buffer))
12101210
(with-current-buffer server-buffer
12111211
(buffer-substring (point-min) (point-max))))))

test/integration/integration-tests.el

Lines changed: 135 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -101,62 +101,79 @@
101101
;; Create a project in temp dir
102102
(let* ((project-dir temp-dir)
103103
(deps-edn (expand-file-name "deps.edn" project-dir)))
104-
(write-region "{}" nil deps-edn)
104+
(write-region "{:deps {ikappaki/nrepl-mdlw-log {:git/sha \"d00fecf9f299ffde90b413751f28c1d2e7b56d17\"
105+
:git/url \"https://github.com/ikappaki/nrepl-mdlw-log.git\"}}}"
106+
nil deps-edn)
105107

106108
(let (;; some times responses on GH CI slow runners might take more
107109
;; than the default timeout period to complete.
108-
(nrepl-sync-request-timeout (+ nrepl-sync-request-timeout 10)))
110+
(nrepl-sync-request-timeout 30)
111+
112+
(cider-jack-in-nrepl-middlewares
113+
(append '("ikappaki.nrepl-mdlw-log/middleware") cider-jack-in-nrepl-middlewares)))
109114

110115
(with-temp-buffer
111116
;; set default directory to temp project
112117
(setq-local default-directory project-dir)
113118

114-
(let* (;; Get a gv reference so as to poll if the client has
115-
;; connected to the nREPL server.
116-
(client-is-connected* (cider-itu-nrepl-client-connected-ref-make!))
117-
118-
;; jack in and get repl buffer
119-
(nrepl-proc (cider-jack-in-clj `()))
120-
(nrepl-buf (process-buffer nrepl-proc)))
121-
122-
;; wait until the client has successfully connected to the
123-
;; nREPL server. High duration since on windows it takes a
124-
;; long time to startup
125-
(cider-itu-poll-until (eq (gv-deref client-is-connected*) 'connected) 90)
126-
127-
;; give it some time to setup the clj REPL
128-
(cider-itu-poll-until (cider-repls 'clj nil) 90)
129-
130-
;; send command to the REPL, and push stdout/stderr to
131-
;; corresponding eval-xxx variables.
132-
(let ((repl-buffer (cider-current-repl))
133-
(eval-err '())
134-
(eval-out '()))
135-
(expect repl-buffer :not :to-be nil)
136-
137-
;; send command to the REPL
138-
(cider-interactive-eval
139-
;; ask REPL to return a string that uniquely identifies it.
140-
"(print :clojure? (some? (clojure-version)))"
141-
(lambda (return)
142-
(nrepl-dbind-response
143-
return
144-
(out err)
145-
(when err (push err eval-err))
146-
(when out (push out eval-out)))) )
147-
148-
;; wait for a response to come back.
149-
(cider-itu-poll-until (or eval-err eval-out) 10)
150-
151-
;; ensure there are no errors and response is as expected.
152-
(expect eval-err :to-equal '())
153-
(expect eval-out :to-equal '(":clojure? true"))
154-
155-
;; exit the REPL.
156-
(cider-quit repl-buffer)
157-
;; wait for the REPL to exit
158-
(cider-itu-poll-until (not (eq (process-status nrepl-proc) 'run)) 15)
159-
(expect (member (process-status nrepl-proc) '(exit signal)))))))))))
119+
(unwind-protect ;; clojure-emacs/cider#3298
120+
121+
(let* (;; Get a gv reference so as to poll if the client has
122+
;; connected to the nREPL server.
123+
(client-is-connected* (cider-itu-nrepl-client-connected-ref-make!))
124+
125+
;; jack in and get repl buffer
126+
(nrepl-proc (cider-jack-in-clj `()))
127+
(nrepl-buf (process-buffer nrepl-proc)))
128+
129+
;; wait until the client has successfully connected to the
130+
;; nREPL server. High duration since on windows it takes a
131+
;; long time to startup
132+
(cider-itu-poll-until (eq (gv-deref client-is-connected*) 'connected) 90)
133+
134+
;; give it some time to setup the clj REPL
135+
(cider-itu-poll-until (cider-repls 'clj nil) 90)
136+
137+
;; send command to the REPL, and push stdout/stderr to
138+
;; corresponding eval-xxx variables.
139+
(let ((repl-buffer (cider-current-repl))
140+
(eval-err '())
141+
(eval-out '()))
142+
(expect repl-buffer :not :to-be nil)
143+
144+
;; send command to the REPL
145+
(cider-interactive-eval
146+
;; ask REPL to return a string that uniquely identifies it.
147+
"(print :clojure? (some? (clojure-version)))"
148+
(lambda (return)
149+
(nrepl-dbind-response
150+
return
151+
(out err)
152+
(when err (push err eval-err))
153+
(when out (push out eval-out)))) )
154+
155+
;; wait for a response to come back.
156+
(cider-itu-poll-until (or eval-err eval-out) 10)
157+
158+
;; ensure there are no errors and response is as expected.
159+
(expect eval-err :to-equal '())
160+
(expect eval-out :to-equal '(":clojure? true"))
161+
162+
;; exit the REPL.
163+
(cider-quit repl-buffer)
164+
;; wait for the REPL to exit
165+
(cider-itu-poll-until (not (eq (process-status nrepl-proc) 'run)) 15)
166+
(expect (member (process-status nrepl-proc) '(exit signal)))
167+
))
168+
169+
;; as part of investigating clojure-emacs/cider#3298, whereby a
170+
;; timeout might occur intermittedly on eval while assessing the
171+
;; nREPL's capabilities, we dump out the log file generated by
172+
;; the `ikappaki/nrepl-mdlw-log.log` middleware setup on the
173+
;; server earlier.
174+
(with-temp-buffer
175+
(insert-file-contents "nrepl-mdlw-log.log")
176+
(message ":ikappaki/nrepl-mdlw-log-dump\n%s\n" (buffer-string))))))))))
160177

161178
(it "to leiningen"
162179
(with-cider-test-sandbox
@@ -287,8 +304,13 @@
287304
;; Create a project in temp dir
288305
(let* ((project-dir temp-dir)
289306
(shadow-cljs-edn (expand-file-name "shadow-cljs.edn" project-dir))
307+
(deps-edn (expand-file-name "deps.edn" project-dir))
290308
(package-json (expand-file-name "package.json" project-dir)))
291-
(write-region "{}" nil shadow-cljs-edn)
309+
(write-region "{:deps true, :nrepl {:middleware [ikappaki.nrepl-mdlw-log/middleware]}}" nil shadow-cljs-edn)
310+
(write-region "{:deps {ikappaki/nrepl-mdlw-log {:git/sha \"d00fecf9f299ffde90b413751f28c1d2e7b56d17\"
311+
:git/url \"https://github.com/ikappaki/nrepl-mdlw-log.git\"}
312+
thheller/shadow-cljs {:mvn/version \"2.20.13\"}}}"
313+
nil deps-edn)
292314
(write-region "{\"dependencies\":{\"shadow-cljs\": \"^2.20.13\"}}" nil package-json)
293315
(let ((default-directory project-dir))
294316
(message ":npm-install...")
@@ -297,61 +319,77 @@
297319

298320
(let (;; some times responses on GH CI slow runners might take more than the default
299321
;; timeout period to complete
300-
(nrepl-sync-request-timeout (+ nrepl-sync-request-timeout 10))
322+
(nrepl-sync-request-timeout 30)
323+
324+
(cider-jack-in-cljs-nrepl-middlewares
325+
(append '("ikappaki.nrepl-mdlw-log/middleware") cider-jack-in-cljs-nrepl-middlewares))
326+
(cider-preferred-build-tool 'shadow-cljs)
327+
301328
;; request for a node repl, so that shadow forks one.
302329
(cider-shadow-default-options ":node-repl"))
303330

304331
(with-temp-buffer
305332
;; set default directory to temp project
306333
(setq-local default-directory project-dir)
307334

308-
(let* (;; Get a gv reference so as to poll if the client has
309-
;; connected to the nREPL server.
310-
(client-is-connected* (cider-itu-nrepl-client-connected-ref-make!))
311-
312-
;; jack in and get repl buffer
313-
(nrepl-proc (cider-jack-in-cljs '(:cljs-repl-type shadow)))
314-
(nrepl-buf (process-buffer nrepl-proc)))
315-
316-
;; wait until the client has successfully connected to the
317-
;; nREPL server.
318-
(cider-itu-poll-until (eq (gv-deref client-is-connected*) 'connected) 120)
319-
320-
;; give it some to switch from shadow clj to cljs REPL.
321-
(cider-itu-poll-until (cider-repls 'cljs nil) 120)
322-
323-
;; send command to the REPL, and push stdout/stderr to
324-
;; corresponding eval-xxx variables.
325-
(let ((repl-buffer (cider-current-repl))
326-
(eval-err '())
327-
(eval-out '()))
328-
(expect repl-buffer :not :to-be nil)
329-
(sleep-for 2)
330-
331-
;; send command to the REPL
332-
(cider-interactive-eval
333-
;; ask REPL to return a string that uniquely identifies it.
334-
"(print :cljs? (some? *clojurescript-version*))"
335-
(lambda (return)
336-
(nrepl-dbind-response
337-
return
338-
(out err)
339-
(when err (push err eval-err))
340-
(when out (push out eval-out)))) )
341-
342-
;; wait for a response to come back.
343-
(cider-itu-poll-until (or eval-err eval-out) 10)
344-
345-
;; ensure there are no errors and response is as expected.
346-
(expect eval-err :to-equal '())
347-
(expect eval-out :to-equal '(":cljs? true\n"))
348-
349-
;; exit the REPL.
350-
(cider-quit repl-buffer)
351-
352-
;; wait for the REPL to exit
353-
(cider-itu-poll-until (not (eq (process-status nrepl-proc) 'run)) 15)
354-
(expect (member (process-status nrepl-proc) '(exit signal))))))))))))
335+
(unwind-protect ;; clojure-emacs/cider#3298
336+
337+
(let* (;; Get a gv reference so as to poll if the client has
338+
;; connected to the nREPL server.
339+
(client-is-connected* (cider-itu-nrepl-client-connected-ref-make!))
340+
341+
;; jack in and get repl buffer
342+
(nrepl-proc (cider-jack-in-cljs '(:cljs-repl-type shadow)))
343+
(nrepl-buf (process-buffer nrepl-proc)))
344+
345+
;; wait until the client has successfully connected to the
346+
;; nREPL server.
347+
(cider-itu-poll-until (eq (gv-deref client-is-connected*) 'connected) 120)
348+
349+
;; give it some to switch from shadow clj to cljs REPL.
350+
(cider-itu-poll-until (cider-repls 'cljs nil) 120)
351+
352+
;; send command to the REPL, and push stdout/stderr to
353+
;; corresponding eval-xxx variables.
354+
(let ((repl-buffer (cider-current-repl))
355+
(eval-err '())
356+
(eval-out '()))
357+
(expect repl-buffer :not :to-be nil)
358+
(sleep-for 2)
359+
360+
;; send command to the REPL
361+
(cider-interactive-eval
362+
;; ask REPL to return a string that uniquely identifies it.
363+
"(print :cljs? (some? *clojurescript-version*))"
364+
(lambda (return)
365+
(nrepl-dbind-response
366+
return
367+
(out err)
368+
(when err (push err eval-err))
369+
(when out (push out eval-out)))) )
370+
371+
;; wait for a response to come back.
372+
(cider-itu-poll-until (or eval-err eval-out) 10)
373+
374+
;; ensure there are no errors and response is as expected.
375+
(expect eval-err :to-equal '())
376+
(expect eval-out :to-equal '(":cljs? true\n"))
377+
378+
;; exit the REPL.
379+
(cider-quit repl-buffer)
380+
381+
;; wait for the REPL to exit
382+
(cider-itu-poll-until (not (eq (process-status nrepl-proc) 'run)) 15)
383+
(expect (member (process-status nrepl-proc) '(exit signal)))))
384+
385+
;; as part of investigating clojure-emacs/cider#3298, whereby a
386+
;; timeout might occur intermittedly on eval while assessing the
387+
;; nREPL's capabilities, we dump out the log file generated by
388+
;; the `ikappaki/nrepl-mdlw-log.log` middleware setup on the
389+
;; server earlier.
390+
(with-temp-buffer
391+
(insert-file-contents "nrepl-mdlw-log.log")
392+
(message ":ikappaki/nrepl-mdlw-log-dump\n%s\n" (buffer-string)))))))))))
355393

356394
(provide 'integration-tests)
357395

0 commit comments

Comments
 (0)