Skip to content

Commit 1bf338f

Browse files
committed
Write simple unit test of execute_request message
This commit also adds a new session adapter for testing.
1 parent c06e3bf commit 1bf338f

File tree

6 files changed

+181
-2
lines changed

6 files changed

+181
-2
lines changed

lib/iruby/kernel.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ class Kernel
99

1010
attr_reader :session
1111

12-
def initialize(config_file)
12+
def initialize(config_file, session_adapter_name=nil)
1313
@config = MultiJson.load(File.read(config_file))
1414
IRuby.logger.debug("IRuby kernel start with config #{@config}")
1515
Kernel.instance = self
1616

17-
@session = Session.new(@config)
17+
@session = Session.new(@config, session_adapter_name)
1818
$stdout = OStream.new(@session, :stdout)
1919
$stderr = OStream.new(@session, :stderr)
2020

lib/iruby/session_adapter.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ def self.available?
1010
false
1111
end
1212

13+
def self.load_requirements
14+
# Do nothing
15+
end
16+
1317
def initialize(config)
1418
@config = config
1519
end
@@ -37,12 +41,14 @@ def make_rep_socket(protocol, host, port)
3741
require_relative 'session_adapter/ffirzmq_adapter'
3842
require_relative 'session_adapter/cztop_adapter'
3943
require_relative 'session_adapter/pyzmq_adapter'
44+
require_relative 'session_adapter/test_adapter'
4045

4146
def self.select_adapter_class(name=nil)
4247
classes = {
4348
'ffi-rzmq' => SessionAdapter::FfirzmqAdapter,
4449
'cztop' => SessionAdapter::CztopAdapter,
4550
# 'pyzmq' => SessionAdapter::PyzmqAdapter
51+
'test' => SessionAdapter::TestAdapter,
4652
}
4753
if (name ||= ENV.fetch('IRUBY_SESSION_ADAPTER', nil))
4854
cls = classes[name]
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
require 'iruby/session/mixin'
2+
3+
module IRuby
4+
module SessionAdapter
5+
class TestAdapter < BaseAdapter
6+
include IRuby::SessionSerialize
7+
8+
DummySocket = Struct.new(:type, :protocol, :host, :port)
9+
10+
def initialize(config)
11+
super
12+
13+
unless config['key'].empty? || config['signature_scheme'].empty?
14+
unless config['signature_scheme'] =~ /\Ahmac-/
15+
raise "Unknown signature_scheme: #{config['signature_scheme']}"
16+
end
17+
digest_algorithm = config['signature_scheme'][/\Ahmac-(.*)\Z/, 1]
18+
@hmac = OpenSSL::HMAC.new(config['key'], OpenSSL::Digest.new(digest_algorithm))
19+
end
20+
21+
@send_callback = nil
22+
@recv_callback = nil
23+
end
24+
25+
attr_accessor :send_callback, :recv_callback
26+
27+
def send(sock, data)
28+
unless @send_callback.nil?
29+
@send_callback.call(sock, unserialize(data))
30+
end
31+
end
32+
33+
def recv(sock)
34+
unless @recv_callback.nil?
35+
serialize(@recv_callback.call(sock))
36+
end
37+
end
38+
39+
def heartbeat_loop(sock)
40+
end
41+
42+
private
43+
44+
def make_socket(type, protocol, host, port)
45+
DummySocket.new(type, protocol, host, port)
46+
end
47+
end
48+
end
49+
end

test/helper.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,53 @@
11
require "iruby"
2+
require "iruby/logger"
3+
require "json"
4+
require 'multi_json'
5+
require "pathname"
26
require "test/unit"
37
require "test/unit/rr"
48
require "tmpdir"
59

10+
11+
IRuby.logger = IRuby::MultiLogger.new(*Logger.new(STDERR, level: Logger::Severity::INFO))
12+
613
module IRubyTest
714
class TestBase < Test::Unit::TestCase
15+
def self.startup
16+
@__config_dir = Dir.mktmpdir("iruby-test")
17+
@__config_path = Pathname.new(@__config_dir) + "config.json"
18+
File.write(@__config_path, {
19+
control_port: 50160,
20+
shell_port: 57503,
21+
transport: "tcp",
22+
signature_scheme: "hmac-sha256",
23+
stdin_port: 52597,
24+
hb_port: 42540,
25+
ip: "127.0.0.1",
26+
iopub_port: 40885,
27+
key: "a0436f6c-1916-498b-8eb9-e81ab9368e84"
28+
}.to_json)
29+
30+
@__original_kernel_instance = IRuby::Kernel.instance
31+
end
32+
33+
def self.shutdown
34+
FileUtils.remove_entry_secure(@__config_dir)
35+
end
36+
37+
def self.test_config_filename
38+
@__config_path.to_s
39+
end
40+
41+
def teardown
42+
IRuby::Kernel.instance = @__original_kernel_instance
43+
end
44+
45+
def with_session_adapter(session_adapter_name)
46+
IRuby::Kernel.new(self.class.test_config_filename, session_adapter_name)
47+
$stdout = STDOUT
48+
$stderr = STDERR
49+
end
50+
851
def assert_output(stdout=nil, stderr=nil)
952
flunk "assert_output requires a block to capture output." unless block_given?
1053

test/iruby/kernel_test.rb

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
require "base64"
2+
3+
module IRubyTest
4+
class KernelTest < TestBase
5+
def setup
6+
super
7+
with_session_adapter("test")
8+
@kernel = IRuby::Kernel.instance
9+
end
10+
11+
def test_execute_request
12+
obj = Object.new
13+
14+
class << obj
15+
def to_html
16+
"<b>HTML</b>"
17+
end
18+
19+
def inspect
20+
"!!! inspect !!!"
21+
end
22+
end
23+
24+
::IRubyTest.define_singleton_method(:test_object) { obj }
25+
26+
msg_types = []
27+
execute_reply = nil
28+
execute_result = nil
29+
@kernel.session.adapter.send_callback = ->(sock, msg) do
30+
header = msg[:header]
31+
content = msg[:content]
32+
msg_types << header["msg_type"]
33+
case header["msg_type"]
34+
when "execute_reply"
35+
execute_reply = content
36+
when "execute_result"
37+
execute_result = content
38+
end
39+
end
40+
41+
msg = {
42+
content: {
43+
"code" => "IRubyTest.test_object",
44+
"silent" => false,
45+
"store_history" => false,
46+
"user_expressions" => {},
47+
"allow_stdin" => false,
48+
"stop_on_error" => true,
49+
}
50+
}
51+
@kernel.execute_request(msg)
52+
53+
assert_equal({
54+
msg_types: [ "execute_input", "execute_reply", "execute_result" ],
55+
execute_reply: {
56+
status: "ok",
57+
user_expressions: {},
58+
},
59+
execute_result: {
60+
data: {
61+
"text/html" => "<b>HTML</b>",
62+
"text/plain" => "!!! inspect !!!"
63+
},
64+
metadata: {},
65+
}
66+
},
67+
{
68+
msg_types: msg_types,
69+
execute_reply: {
70+
status: execute_reply["status"],
71+
user_expressions: execute_reply["user_expressions"]
72+
},
73+
execute_result: {
74+
data: execute_result["data"],
75+
metadata: execute_result["metadata"]
76+
}
77+
})
78+
end
79+
end
80+
end

test/iruby/session_test.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def test_without_any_session_adapter
3838
stub(IRuby::SessionAdapter::CztopAdapter).available? { false }
3939
stub(IRuby::SessionAdapter::FfirzmqAdapter).available? { false }
4040
stub(IRuby::SessionAdapter::PyzmqAdapter).available? { false }
41+
stub(IRuby::SessionAdapter::TestAdapter).available? { false }
4142
assert_raises IRuby::SessionAdapterNotFound do
4243
IRuby::Session.new(@session_config)
4344
end

0 commit comments

Comments
 (0)