Skip to content

Commit ae5dad9

Browse files
committed
Split ZMQ dependent tests into test/jupyter-zmq-test.el
* test/jupyter-test.el: Move all zmq related tests (and code) to `test/jupyter-zmq-test.el`, add a `zmq` tag to the tests. * test/test-helper.el (zmq, jupyter-zmq-channel-ioloop) (jupyter-zmq-channel-ioloop-comm): Remove requires. (jupyter-test-ioloop-eval-event, jupyter-test-channel-ioloop) (initialize-instance) [jupyter-echo-client]: Remove uses of ZMQ by using a `jupyter-mock-comm-layer` for the `kcomm` slot. (jupyter-test-zmq-sockets): Move to `test/jupyter-zmq-test.el` along with all related code. * test/jupyter-zmq-test.el: Add tests moved from `test/jupyter-test.el` and all related code.
1 parent 0e202a0 commit ae5dad9

File tree

3 files changed

+422
-384
lines changed

3 files changed

+422
-384
lines changed

test/jupyter-test.el

Lines changed: 0 additions & 335 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626

2727
;;; Code:
2828

29-
(require 'zmq)
30-
(require 'jupyter-zmq-channel-comm)
3129
(require 'jupyter-env)
3230
(require 'jupyter-client)
3331
(require 'jupyter-repl)
@@ -493,58 +491,6 @@
493491
msg)
494492
(cons "idle" "foo")))))
495493

496-
;;; Channels
497-
498-
(ert-deftest jupyter-zmq-channel ()
499-
:tags '(channels zmq)
500-
(let* ((port (car (jupyter-available-local-ports 1)))
501-
(channel (jupyter-zmq-channel
502-
:type :shell
503-
:endpoint (format "tcp://127.0.0.1:%s" port))))
504-
(ert-info ("Starting the channel")
505-
(should-not (jupyter-channel-alive-p channel))
506-
(jupyter-start-channel channel :identity "foo")
507-
(should (jupyter-channel-alive-p channel))
508-
(should (equal (zmq-socket-get (oref channel socket)
509-
zmq-ROUTING-ID)
510-
"foo")))
511-
(ert-info ("Stopping the channel")
512-
(let ((sock (oref channel socket)))
513-
(jupyter-stop-channel channel)
514-
(should-not (jupyter-channel-alive-p channel))
515-
;; Ensure the socket was disconnected
516-
(should-error (zmq-send sock "foo" zmq-NOBLOCK) :type 'zmq-EAGAIN)))))
517-
518-
(ert-deftest jupyter-hb-channel ()
519-
:tags '(channels)
520-
(should (eq (oref (jupyter-hb-channel) type) :hb))
521-
(let* ((port (car (jupyter-available-local-ports 1)))
522-
(channel (jupyter-hb-channel
523-
:endpoint (format "tcp://127.0.0.1:%s" port)
524-
:session (jupyter-session)))
525-
(died-cb-called nil)
526-
(jupyter-hb-max-failures 1))
527-
(oset channel time-to-dead 0.1)
528-
(should-not (jupyter-channel-alive-p channel))
529-
(should-not (jupyter-hb-beating-p channel))
530-
(should (oref channel paused))
531-
(oset channel beating t)
532-
(jupyter-start-channel channel)
533-
(jupyter-hb-on-kernel-dead channel (lambda () (setq died-cb-called t)))
534-
(should (jupyter-channel-alive-p channel))
535-
;; `jupyter-hb-unpause' needs to explicitly called
536-
(should (oref channel paused))
537-
(jupyter-hb-unpause channel)
538-
(sleep-for 0.2)
539-
;; It seems the timers are run after returning from the first `sleep-for'
540-
;; call.
541-
(sleep-for 0.1)
542-
(should (oref channel paused))
543-
(should-not (oref channel beating))
544-
(should died-cb-called)
545-
(should (jupyter-channel-alive-p channel))
546-
(should-not (jupyter-hb-beating-p channel))))
547-
548494
;;; GC
549495

550496
(ert-deftest jupyter-weak-ref ()
@@ -609,45 +555,6 @@
609555
(lambda (_) nil)))
610556
(should-error (jupyter-locate-python))))
611557

612-
(ert-deftest jupyter-kernel-lifetime ()
613-
:tags '(kernel)
614-
(let* ((conn-info (jupyter-local-tcp-conn-info))
615-
(kernel (jupyter-spec-kernel
616-
:spec (jupyter-guess-kernelspec "python")
617-
:session (jupyter-session
618-
:key (plist-get conn-info :key)
619-
:conn-info conn-info))))
620-
(should-not (jupyter-kernel-alive-p kernel))
621-
(jupyter-start-kernel kernel)
622-
(should (jupyter-kernel-alive-p kernel))
623-
(jupyter-kill-kernel kernel)
624-
(should-not (jupyter-kernel-alive-p kernel))
625-
(setq conn-info (jupyter-local-tcp-conn-info))
626-
(ert-info ("`jupyter-kernel-manager'")
627-
;; TODO: Should the manager create a session if one isn't present?
628-
(oset kernel session (jupyter-session
629-
:key (plist-get conn-info :key)
630-
:conn-info conn-info))
631-
(let* ((manager (jupyter-kernel-process-manager :kernel kernel))
632-
(control-channel (oref manager control-channel))
633-
process)
634-
(should-not (jupyter-kernel-alive-p manager))
635-
(should-not control-channel)
636-
(jupyter-start-kernel manager)
637-
(setq process (oref kernel process))
638-
(setq control-channel (oref manager control-channel))
639-
(should (jupyter-zmq-channel-p control-channel))
640-
(should (jupyter-kernel-alive-p manager))
641-
(should (jupyter-kernel-alive-p kernel))
642-
(jupyter-shutdown-kernel manager)
643-
(ert-info ("Kernel shutdown is clean")
644-
(should-not (process-live-p process))
645-
(should (zerop (process-exit-status process)))
646-
(should-not (jupyter-kernel-alive-p manager))
647-
(should-not (jupyter-kernel-alive-p kernel)))
648-
(setq control-channel (oref manager control-channel))
649-
(should-not (jupyter-zmq-channel-p control-channel))))))
650-
651558
(ert-deftest jupyter-command-kernel ()
652559
:tags '(kernel)
653560
(let ((kernel (jupyter-command-kernel
@@ -703,49 +610,6 @@
703610

704611
;;; Client
705612

706-
;; TODO: Different values of the session argument
707-
;; TODO: Update for new `jupyter-channel-ioloop-comm'
708-
(ert-deftest jupyter-comm-initialize ()
709-
:tags '(client init)
710-
(skip-unless nil)
711-
;; The default comm is a jupyter-channel-ioloop-comm
712-
(let ((conn-info (jupyter-test-conn-info-plist))
713-
(client (jupyter-kernel-client)))
714-
(oset client kcomm (jupyter-zmq-channel-comm))
715-
(jupyter-comm-initialize client conn-info)
716-
;; kcomm by default is a `jupyter-channel-ioloop-comm'
717-
(with-slots (session kcomm) client
718-
(ert-info ("Client session")
719-
(should (string= (jupyter-session-key session)
720-
(plist-get conn-info :key)))
721-
(should (equal (jupyter-session-conn-info session)
722-
conn-info)))
723-
(ert-info ("Heartbeat channel initialized")
724-
(should (eq session (oref (oref kcomm hb) session)))
725-
(should (string= (oref (oref kcomm hb) endpoint)
726-
(format "tcp://127.0.0.1:%d"
727-
(plist-get conn-info :hb_port)))))
728-
(ert-info ("Shell, iopub, stdin initialized")
729-
(cl-loop
730-
for channel in '(:shell :iopub :stdin)
731-
for port_sym = (intern (concat (symbol-name channel) "_port"))
732-
do
733-
(should (plist-member (plist-get channels channel) :alive-p))
734-
(should (plist-member (plist-get channels channel) :endpoint))
735-
(should
736-
(string= (plist-get (plist-get channels channel) :endpoint)
737-
(format "tcp://127.0.0.1:%d"
738-
(plist-get conn-info port_sym))))))
739-
(ert-info ("Initialization stops any running channels")
740-
(should-not (jupyter-channels-running-p client))
741-
(jupyter-start-channels client)
742-
(should (jupyter-channels-running-p client))
743-
(jupyter-comm-initialize client conn-info)
744-
(should-not (jupyter-channels-running-p client)))
745-
(ert-info ("Invalid signature scheme")
746-
(plist-put conn-info :signature_scheme "hmac-foo")
747-
(should-error (jupyter-comm-initialize client conn-info))))))
748-
749613
(ert-deftest jupyter-write-connection-file ()
750614
:tags '(client)
751615
(skip-unless (not (memq system-type '(ms-dos windows-nt cygwin))))
@@ -771,28 +635,6 @@
771635
(delete-file file)))
772636
(should-not (memq fun kill-emacs-hook))))
773637

774-
(ert-deftest jupyter-client-channels ()
775-
:tags '(client channels)
776-
(ert-info ("Starting/stopping channels")
777-
(let ((conn-info (jupyter-test-conn-info-plist))
778-
(client (jupyter-kernel-client)))
779-
(oset client kcomm (jupyter-zmq-channel-comm))
780-
(jupyter-comm-initialize client conn-info)
781-
(cl-loop
782-
for channel in '(:hb :shell :iopub :stdin)
783-
for alive-p = (jupyter-channel-alive-p client channel)
784-
do (should-not alive-p))
785-
(jupyter-start-channels client)
786-
(cl-loop
787-
for channel in '(:hb :shell :iopub :stdin)
788-
for alive-p = (jupyter-channel-alive-p client channel)
789-
do (should alive-p))
790-
(jupyter-stop-channels client)
791-
(cl-loop
792-
for channel in '(:hb :shell :iopub :stdin)
793-
for alive-p = (jupyter-channel-alive-p client channel)
794-
do (should-not alive-p)))))
795-
796638
(ert-deftest jupyter-inhibited-handlers ()
797639
:tags '(client handlers)
798640
(jupyter-test-with-python-client client
@@ -908,183 +750,6 @@
908750
(should (memq r1 mapped))
909751
(should-not (memq r2 mapped)))))
910752

911-
;;; IOloop
912-
913-
(ert-deftest jupyter-ioloop-lifetime ()
914-
:tags '(ioloop)
915-
(let ((ioloop (jupyter-ioloop))
916-
(jupyter-default-timeout 2))
917-
(should-not (process-live-p (oref ioloop process)))
918-
(jupyter-ioloop-start ioloop :tag1)
919-
(should (equal (jupyter-ioloop-last-event ioloop) '(start)))
920-
(with-slots (process) ioloop
921-
(should (process-live-p process))
922-
(jupyter-ioloop-stop ioloop)
923-
(should (equal (jupyter-ioloop-last-event ioloop) '(quit)))
924-
(sleep-for 0.1)
925-
(should-not (process-live-p process)))))
926-
927-
(defvar jupyter-ioloop-test-handler-called nil
928-
"Flag variable used for testing the `juyter-ioloop'.")
929-
930-
(cl-defmethod jupyter-ioloop-handler ((_ioloop jupyter-ioloop)
931-
(_tag (eql :test))
932-
(event (head test)))
933-
(should (equal (cadr event) "message"))
934-
(setq jupyter-ioloop-test-handler-called t))
935-
936-
(ert-deftest jupyter-ioloop-wait-until ()
937-
:tags '(ioloop)
938-
(let ((ioloop (jupyter-ioloop)))
939-
(should-not (jupyter-ioloop-last-event ioloop))
940-
(jupyter-ioloop-start ioloop :test)
941-
(should (equal (jupyter-ioloop-last-event ioloop) '(start)))
942-
(jupyter-ioloop-stop ioloop)))
943-
944-
(ert-deftest jupyter-ioloop-callbacks ()
945-
:tags '(ioloop)
946-
(ert-info ("Callback added before starting the ioloop")
947-
(let ((ioloop (jupyter-ioloop)))
948-
(setq jupyter-ioloop-test-handler-called nil)
949-
(jupyter-ioloop-add-callback ioloop
950-
`(lambda () (zmq-prin1 (list 'test "message"))))
951-
(jupyter-ioloop-start ioloop :test)
952-
(jupyter-ioloop-stop ioloop)
953-
(should jupyter-ioloop-test-handler-called)))
954-
(ert-info ("Callback added after starting the ioloop")
955-
(let ((ioloop (jupyter-ioloop)))
956-
(setq jupyter-ioloop-test-handler-called nil)
957-
(jupyter-ioloop-start ioloop :test)
958-
(should (process-live-p (oref ioloop process)))
959-
(jupyter-ioloop-add-callback ioloop
960-
`(lambda () (zmq-prin1 (list 'test "message"))))
961-
(jupyter-ioloop-wait-until ioloop 'test #'identity)
962-
(jupyter-ioloop-stop ioloop)
963-
(should jupyter-ioloop-test-handler-called))))
964-
965-
(ert-deftest jupyter-ioloop-setup ()
966-
:tags '(ioloop)
967-
(let ((ioloop (jupyter-ioloop)))
968-
(setq jupyter-ioloop-test-handler-called nil)
969-
(jupyter-ioloop-add-setup ioloop
970-
(zmq-prin1 (list 'test "message")))
971-
(jupyter-ioloop-start ioloop :test)
972-
(jupyter-ioloop-stop ioloop)
973-
(should jupyter-ioloop-test-handler-called)))
974-
975-
(ert-deftest jupyter-ioloop-teardown ()
976-
:tags '(ioloop)
977-
(let ((ioloop (jupyter-ioloop)))
978-
(setq jupyter-ioloop-test-handler-called nil)
979-
(jupyter-ioloop-add-teardown ioloop
980-
(zmq-prin1 (list 'test "message")))
981-
(jupyter-ioloop-start ioloop :test)
982-
(jupyter-ioloop-stop ioloop)
983-
(should jupyter-ioloop-test-handler-called)))
984-
985-
(ert-deftest jupyter-ioloop-add-event ()
986-
:tags '(ioloop)
987-
(let ((ioloop (jupyter-ioloop)))
988-
(setq jupyter-ioloop-test-handler-called nil)
989-
(jupyter-ioloop-add-event ioloop test (data)
990-
"Echo DATA back to the parent process."
991-
(list 'test data))
992-
(jupyter-ioloop-start ioloop :test)
993-
(jupyter-send ioloop 'test "message")
994-
(jupyter-ioloop-stop ioloop)
995-
(should jupyter-ioloop-test-handler-called)))
996-
997-
(ert-deftest jupyter-channel-ioloop-send-event ()
998-
:tags '(ioloop)
999-
(jupyter-test-channel-ioloop
1000-
(ioloop (jupyter-zmq-channel-ioloop))
1001-
(cl-letf (((symbol-function #'jupyter-send)
1002-
(lambda (_channel _msg-type _msg msg-id) msg-id)))
1003-
(setq jupyter-channel-ioloop-session (jupyter-session :key "foo"))
1004-
(push (jupyter-zmq-channel :type :shell) jupyter-channel-ioloop-channels)
1005-
(let* ((msg-id (jupyter-new-uuid))
1006-
(event `(list 'send :shell :execute-request '(msg) ,msg-id)))
1007-
(jupyter-test-ioloop-eval-event ioloop event)
1008-
(ert-info ("Return value to parent process")
1009-
(let ((result (read (buffer-string))))
1010-
(should (equal result `(sent :shell ,msg-id)))))))))
1011-
1012-
(ert-deftest jupyter-channel-ioloop-start-channel-event ()
1013-
:tags '(ioloop)
1014-
(jupyter-test-channel-ioloop
1015-
(ioloop (jupyter-zmq-channel-ioloop))
1016-
(setq jupyter-channel-ioloop-session (jupyter-session :key "foo"))
1017-
(let ((channel-endpoint "tcp://127.0.0.1:5555"))
1018-
(ert-info ("start-channel event creates channel")
1019-
(should (null jupyter-channel-ioloop-channels))
1020-
(let ((event `(list 'start-channel :shell ,channel-endpoint)))
1021-
(jupyter-test-ioloop-eval-event ioloop event))
1022-
(should-not (null jupyter-channel-ioloop-channels))
1023-
(let ((channel (object-assoc :shell :type jupyter-channel-ioloop-channels)))
1024-
(should (jupyter-zmq-channel-p channel))))
1025-
(let ((channel (object-assoc :shell :type jupyter-channel-ioloop-channels)))
1026-
(with-slots (type socket endpoint) channel
1027-
(ert-info ("Verify the requested channel was started")
1028-
(should (eq type :shell))
1029-
(should (zmq-socket-p socket))
1030-
(should (equal endpoint channel-endpoint))
1031-
(should (equal (zmq-socket-get socket zmq-LAST-ENDPOINT) channel-endpoint))
1032-
(ert-info ("Identity of socket matches session")
1033-
(should (equal (zmq-socket-get socket zmq-IDENTITY)
1034-
(jupyter-session-id jupyter-channel-ioloop-session)))))
1035-
(ert-info ("Ensure the channel was added to the poller")
1036-
;; FIXME: Does it make sense to have this side effect as part of starting
1037-
;; a channel? It makes it so that we don't reference any `zmq' functions
1038-
;; in `jupyter-channel-ioloop'.
1039-
(should-error
1040-
(zmq-poller-add jupyter-ioloop-poller socket (list zmq-POLLIN))
1041-
:type 'zmq-EINVAL)))
1042-
(ert-info ("Return value to parent process")
1043-
(let ((result (read (buffer-string))))
1044-
(should (equal result `(start-channel :shell)))))))))
1045-
1046-
(ert-deftest jupyter-channel-ioloop-stop-channel-event ()
1047-
:tags '(ioloop)
1048-
(jupyter-test-channel-ioloop
1049-
(ioloop (jupyter-zmq-channel-ioloop))
1050-
(setq jupyter-channel-ioloop-session (jupyter-session :key "foo"))
1051-
(let ((event `(list 'start-channel :shell "tcp://127.0.0.1:5556")))
1052-
(jupyter-test-ioloop-eval-event ioloop event)
1053-
(erase-buffer))
1054-
(let* ((channel (object-assoc :shell :type jupyter-channel-ioloop-channels))
1055-
(socket (oref channel socket)))
1056-
(ert-info ("Verify the requested channel stops")
1057-
(should (jupyter-channel-alive-p channel))
1058-
(should (progn (zmq-poller-modify
1059-
jupyter-ioloop-poller
1060-
(oref channel socket) (list zmq-POLLIN zmq-POLLOUT))
1061-
t))
1062-
(jupyter-test-ioloop-eval-event ioloop `(list 'stop-channel :shell))
1063-
(should-not (jupyter-channel-alive-p channel)))
1064-
(ert-info ("Ensure the channel was removed from the poller")
1065-
(should-error
1066-
(zmq-poller-modify jupyter-ioloop-poller socket (list zmq-POLLIN))
1067-
:type 'zmq-EINVAL))
1068-
(ert-info ("Return value to parent process")
1069-
(let ((result (read (buffer-string))))
1070-
(should (equal result `(stop-channel :shell))))))))
1071-
1072-
(ert-deftest jupyter-zmq-channel-ioloop-send-fast ()
1073-
:tags '(ioloop queue)
1074-
;; :expected-result :failed
1075-
(jupyter-test-with-python-client client
1076-
(let ((jupyter-current-client client))
1077-
(jupyter-send-execute-request client :code "1 + 1")
1078-
(jupyter-send-execute-request client :code "1 + 1")
1079-
(jupyter-send-execute-request client :code "1 + 1")
1080-
(let ((req (jupyter-send-execute-request client :code "1 + 1")))
1081-
(should
1082-
(equal
1083-
(jupyter-message-data
1084-
(jupyter-wait-until-received :execute-result req jupyter-long-timeout)
1085-
:text/plain)
1086-
"2"))))))
1087-
1088753
;;; Completion
1089754

1090755
(ert-deftest jupyter-completion-number-p ()

0 commit comments

Comments
 (0)