ernie 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +7 -0
- data/README.md +2 -0
- data/Rakefile +135 -47
- data/bin/ernie +15 -6
- data/elib/ernie_access_logger.erl +4 -4
- data/elib/ernie_server.erl +40 -23
- data/elib/logger.erl +8 -8
- data/ernie.gemspec +70 -88
- data/lib/ernie.rb +3 -6
- data/test/helper.rb +1 -1
- data/test/sample/intTest.erl +60 -0
- data/test/sample/sample.cfg +6 -2
- data/test/{ernie_test.rb → test_ernie.rb} +0 -0
- data/test/test_ernie_server.rb +221 -0
- metadata +43 -16
- data/.document +0 -5
- data/.gitignore +0 -2
- data/VERSION.yml +0 -5
- data/test/ernie_server_test.rb +0 -77
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
= 2.5.0 / 2010-11-19
|
2
|
+
* Major Enhancements
|
3
|
+
* Enable multi-node mode (#11)
|
4
|
+
* Bug Fixes
|
5
|
+
* Properly determine whether function or module is missing.
|
6
|
+
* Spawn a process for receive_term to keep acceptor non-blocking.
|
7
|
+
|
1
8
|
= 2.4.0 / 2010-05-21
|
2
9
|
* Minor Additions
|
3
10
|
* Add -E cli option for setting extra Erlang VM options
|
data/README.md
CHANGED
@@ -59,6 +59,8 @@ Running
|
|
59
59
|
-a, --access-log LOGFILE Access log file.
|
60
60
|
-d, --detached Run as a daemon.
|
61
61
|
-P, --pidfile PIDFILE Location to write pid file.
|
62
|
+
--name NAME Erlang process name.
|
63
|
+
--sname SNAME Erlang short process name.
|
62
64
|
-E, --erlang ERLANG_OPTIONS Options passed to Erlang VM.
|
63
65
|
|
64
66
|
Commands:
|
data/Rakefile
CHANGED
@@ -1,67 +1,155 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
|
+
require 'date'
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
5
|
+
#############################################################################
|
6
|
+
#
|
7
|
+
# Helper functions
|
8
|
+
#
|
9
|
+
#############################################################################
|
10
|
+
|
11
|
+
def name
|
12
|
+
@name ||= Dir['*.gemspec'].first.split('.').first
|
13
|
+
end
|
14
|
+
|
15
|
+
def version
|
16
|
+
line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
|
17
|
+
line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
|
18
|
+
end
|
19
|
+
|
20
|
+
def date
|
21
|
+
Date.today.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
def rubyforge_project
|
25
|
+
name
|
26
|
+
end
|
27
|
+
|
28
|
+
def gemspec_file
|
29
|
+
"#{name}.gemspec"
|
23
30
|
end
|
24
31
|
|
32
|
+
def gem_file
|
33
|
+
"#{name}-#{version}.gem"
|
34
|
+
end
|
35
|
+
|
36
|
+
def replace_header(head, header_name)
|
37
|
+
head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
|
38
|
+
end
|
39
|
+
|
40
|
+
#############################################################################
|
41
|
+
#
|
42
|
+
# Standard tasks
|
43
|
+
#
|
44
|
+
#############################################################################
|
45
|
+
|
46
|
+
task :default => :test
|
47
|
+
|
25
48
|
require 'rake/testtask'
|
26
49
|
Rake::TestTask.new(:test) do |test|
|
27
50
|
test.libs << 'lib' << 'test'
|
28
|
-
test.pattern = 'test
|
51
|
+
test.pattern = 'test/**/test_*.rb'
|
29
52
|
test.verbose = true
|
30
53
|
end
|
31
54
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
39
|
-
rescue LoadError
|
40
|
-
task :rcov do
|
41
|
-
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
42
|
-
end
|
55
|
+
desc "Generate RCov test coverage and open in your browser"
|
56
|
+
task :coverage do
|
57
|
+
require 'rcov'
|
58
|
+
sh "rm -fr coverage"
|
59
|
+
sh "rcov test/test_*.rb"
|
60
|
+
sh "open coverage/index.html"
|
43
61
|
end
|
44
62
|
|
45
|
-
|
63
|
+
require 'rake/rdoctask'
|
64
|
+
Rake::RDocTask.new do |rdoc|
|
65
|
+
rdoc.rdoc_dir = 'rdoc'
|
66
|
+
rdoc.title = "#{name} #{version}"
|
67
|
+
rdoc.rdoc_files.include('README*')
|
68
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "Open an irb session preloaded with this library"
|
72
|
+
task :console do
|
73
|
+
sh "irb -rubygems -r ./lib/#{name}.rb"
|
74
|
+
end
|
46
75
|
|
47
|
-
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
|
52
|
-
# else
|
53
|
-
# version = ""
|
54
|
-
# end
|
55
|
-
#
|
56
|
-
# rdoc.rdoc_dir = 'rdoc'
|
57
|
-
# rdoc.title = "ernie #{version}"
|
58
|
-
# rdoc.rdoc_files.include('README*')
|
59
|
-
# rdoc.rdoc_files.include('lib/**/*.rb')
|
60
|
-
# end
|
76
|
+
#############################################################################
|
77
|
+
#
|
78
|
+
# Custom tasks (add your own tasks here)
|
79
|
+
#
|
80
|
+
#############################################################################
|
61
81
|
|
62
82
|
task :ebuild do
|
63
83
|
ERLC_TEST_FLAGS = ""
|
64
84
|
ERLC_FLAGS = "-o ../ebin"
|
65
85
|
cd "elib"
|
66
86
|
sh "erlc #{ERLC_FLAGS} #{ERLC_TEST_FLAGS} #{Dir["**/*.erl"].join(" ")}"
|
67
|
-
end
|
87
|
+
end
|
88
|
+
|
89
|
+
#############################################################################
|
90
|
+
#
|
91
|
+
# Packaging tasks
|
92
|
+
#
|
93
|
+
#############################################################################
|
94
|
+
|
95
|
+
desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
|
96
|
+
task :release => :build do
|
97
|
+
unless `git branch` =~ /^\* master$/
|
98
|
+
puts "You must be on the master branch to release!"
|
99
|
+
exit!
|
100
|
+
end
|
101
|
+
sh "git commit --allow-empty -a -m 'Release #{version}'"
|
102
|
+
sh "git tag v#{version}"
|
103
|
+
sh "git push origin master"
|
104
|
+
sh "git push origin v#{version}"
|
105
|
+
sh "gem push pkg/#{name}-#{version}.gem"
|
106
|
+
end
|
107
|
+
|
108
|
+
desc "Build #{gem_file} into the pkg directory"
|
109
|
+
task :build => :gemspec do
|
110
|
+
sh "mkdir -p pkg"
|
111
|
+
sh "gem build #{gemspec_file}"
|
112
|
+
sh "mv #{gem_file} pkg"
|
113
|
+
end
|
114
|
+
|
115
|
+
desc "Generate #{gemspec_file}"
|
116
|
+
task :gemspec => :validate do
|
117
|
+
# read spec file and split out manifest section
|
118
|
+
spec = File.read(gemspec_file)
|
119
|
+
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
120
|
+
|
121
|
+
# replace name version and date
|
122
|
+
replace_header(head, :name)
|
123
|
+
replace_header(head, :version)
|
124
|
+
replace_header(head, :date)
|
125
|
+
#comment this out if your rubyforge_project has a different name
|
126
|
+
replace_header(head, :rubyforge_project)
|
127
|
+
|
128
|
+
# determine file list from git ls-files
|
129
|
+
files = `git ls-files`.
|
130
|
+
split("\n").
|
131
|
+
sort.
|
132
|
+
reject { |file| file =~ /^\./ }.
|
133
|
+
reject { |file| file =~ /^(rdoc|pkg)/ }.
|
134
|
+
map { |file| " #{file}" }.
|
135
|
+
join("\n")
|
136
|
+
|
137
|
+
# piece file back together and write
|
138
|
+
manifest = " s.files = %w[\n#{files}\n ]\n"
|
139
|
+
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
|
140
|
+
File.open(gemspec_file, 'w') { |io| io.write(spec) }
|
141
|
+
puts "Updated #{gemspec_file}"
|
142
|
+
end
|
143
|
+
|
144
|
+
desc "Validate #{gemspec_file}"
|
145
|
+
task :validate do
|
146
|
+
libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}"]
|
147
|
+
unless libfiles.empty?
|
148
|
+
puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir."
|
149
|
+
exit!
|
150
|
+
end
|
151
|
+
unless Dir['VERSION*'].empty?
|
152
|
+
puts "A `VERSION` file at root level violates Gem best practices."
|
153
|
+
exit!
|
154
|
+
end
|
155
|
+
end
|
data/bin/ernie
CHANGED
@@ -14,14 +14,10 @@ def code_paths
|
|
14
14
|
DEFAULT_ERLANG_CODEPATHS.map {|n| "-pz #{rel(n)}" }.join(" ") + " \\"
|
15
15
|
end
|
16
16
|
|
17
|
-
def version
|
18
|
-
yml = YAML.load(File.read(File.join(File.dirname(__FILE__), *%w[.. VERSION.yml])))
|
19
|
-
"#{yml[:major]}.#{yml[:minor]}.#{yml[:patch]}"
|
20
|
-
end
|
21
|
-
|
22
17
|
require 'optparse'
|
23
18
|
require 'pp'
|
24
19
|
require 'yaml'
|
20
|
+
require 'ernie'
|
25
21
|
|
26
22
|
help = <<HELP
|
27
23
|
Ernie is an Erlang/Ruby BERT-RPC Server.
|
@@ -42,7 +38,7 @@ HELP
|
|
42
38
|
options = {}
|
43
39
|
OptionParser.new do |opts|
|
44
40
|
opts.banner = help
|
45
|
-
opts.version =
|
41
|
+
opts.version = Ernie::VERSION
|
46
42
|
|
47
43
|
opts.on("-c CONFIG", "--config CONFIG", "Config file") do |x|
|
48
44
|
options[:config] = x
|
@@ -64,6 +60,14 @@ OptionParser.new do |opts|
|
|
64
60
|
options[:detached] = true
|
65
61
|
end
|
66
62
|
|
63
|
+
opts.on("--name NAME", "Erlang proccess name") do |x|
|
64
|
+
options[:name] = x
|
65
|
+
end
|
66
|
+
|
67
|
+
opts.on("--sname NAME", "Erlang short proccess name") do |x|
|
68
|
+
options[:sname] = x
|
69
|
+
end
|
70
|
+
|
67
71
|
opts.on("-P", "--pidfile PIDFILE", "Location to write pid file.") do |x|
|
68
72
|
options[:pidfile] = x
|
69
73
|
end
|
@@ -99,9 +103,13 @@ else
|
|
99
103
|
pidfile = options[:pidfile] ? "-ernie_server_app pidfile \"'#{options[:pidfile]}'\"" : ''
|
100
104
|
detached = options[:detached] ? '-detached' : ''
|
101
105
|
access_log = options[:access_log] ? "-ernie_server_app access_log '\"#{options[:access_log]}\"'" : ''
|
106
|
+
name = options[:name] ? "-name #{options[:name]}" : ''
|
107
|
+
sname = options[:sname] ? "-sname #{options[:sname]}" : ''
|
102
108
|
erl_options = options[:erl_options]
|
103
109
|
|
104
110
|
cmd = %Q{erl -boot start_sasl \
|
111
|
+
#{name} \
|
112
|
+
#{sname} \
|
105
113
|
#{detached} \
|
106
114
|
+Bc \
|
107
115
|
+K true \
|
@@ -115,5 +123,6 @@ else
|
|
115
123
|
-run ernie_server_app boot \
|
116
124
|
#{erl_options}}.squeeze(' ')
|
117
125
|
puts cmd
|
126
|
+
STDOUT.flush
|
118
127
|
exec(cmd)
|
119
128
|
end
|
@@ -18,19 +18,19 @@
|
|
18
18
|
%%====================================================================
|
19
19
|
|
20
20
|
start_link(Args) ->
|
21
|
-
gen_server:start_link({
|
21
|
+
gen_server:start_link({local, ?MODULE}, ?MODULE, Args, []).
|
22
22
|
|
23
23
|
start(Args) ->
|
24
24
|
gen_server:start({global, ?MODULE}, ?MODULE, Args, []).
|
25
25
|
|
26
26
|
acc(Request) ->
|
27
|
-
gen_server:cast(
|
27
|
+
gen_server:cast(?MODULE, {acc, Request}).
|
28
28
|
|
29
29
|
err(Request, Msg, Args) ->
|
30
|
-
gen_server:cast(
|
30
|
+
gen_server:cast(?MODULE, {err, Request, Msg, Args}).
|
31
31
|
|
32
32
|
reopen() ->
|
33
|
-
gen_server:cast(
|
33
|
+
gen_server:cast(?MODULE, reopen).
|
34
34
|
|
35
35
|
%%====================================================================
|
36
36
|
%% gen_server callbacks
|
data/elib/ernie_server.erl
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
-include_lib("ernie.hrl").
|
4
4
|
|
5
5
|
%% api
|
6
|
-
-export([start_link/1, start/1, process/1, kick/0, fin/0]).
|
6
|
+
-export([start_link/1, start/1, process/1, enqueue_request/1, kick/0, fin/0]).
|
7
7
|
|
8
8
|
%% gen_server callbacks
|
9
9
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
@@ -14,19 +14,22 @@
|
|
14
14
|
%%====================================================================
|
15
15
|
|
16
16
|
start_link(Args) ->
|
17
|
-
gen_server:start_link({
|
17
|
+
gen_server:start_link({local, ?MODULE}, ?MODULE, Args, []).
|
18
18
|
|
19
19
|
start(Args) ->
|
20
|
-
gen_server:start({
|
20
|
+
gen_server:start({local, ?MODULE}, ?MODULE, Args, []).
|
21
21
|
|
22
22
|
process(Sock) ->
|
23
|
-
gen_server:cast(
|
23
|
+
gen_server:cast(?MODULE, {process, Sock}).
|
24
|
+
|
25
|
+
enqueue_request(Request) ->
|
26
|
+
gen_server:call(?MODULE, {enqueue_request, Request}).
|
24
27
|
|
25
28
|
kick() ->
|
26
|
-
gen_server:cast(
|
29
|
+
gen_server:cast(?MODULE, kick).
|
27
30
|
|
28
31
|
fin() ->
|
29
|
-
gen_server:cast(
|
32
|
+
gen_server:cast(?MODULE, fin).
|
30
33
|
|
31
34
|
%%====================================================================
|
32
35
|
%% gen_server callbacks
|
@@ -57,6 +60,16 @@ init([Port, Configs]) ->
|
|
57
60
|
%% {stop, Reason, State}
|
58
61
|
%% Description: Handling call messages
|
59
62
|
%%--------------------------------------------------------------------
|
63
|
+
handle_call({enqueue_request, Request}, _From, State) ->
|
64
|
+
case Request#request.priority of
|
65
|
+
high ->
|
66
|
+
Hq2 = queue:in(Request, State#state.hq),
|
67
|
+
Lq2 = State#state.lq;
|
68
|
+
low ->
|
69
|
+
Hq2 = State#state.hq,
|
70
|
+
Lq2 = queue:in(Request, State#state.lq)
|
71
|
+
end,
|
72
|
+
{reply, ok, State#state{hq = Hq2, lq = Lq2}};
|
60
73
|
handle_call(_Request, _From, State) ->
|
61
74
|
{reply, ok, State}.
|
62
75
|
|
@@ -71,8 +84,9 @@ handle_cast({process, Sock}, State) ->
|
|
71
84
|
lq = queue:len(State#state.lq),
|
72
85
|
taccept = erlang:now()},
|
73
86
|
Request = #request{sock = Sock, log = Log},
|
74
|
-
|
75
|
-
|
87
|
+
spawn(fun() -> receive_term(Request, State) end),
|
88
|
+
logger:debug("Spawned receiver~n", []),
|
89
|
+
{noreply, State};
|
76
90
|
handle_cast(kick, State) ->
|
77
91
|
case queue:out(State#state.hq) of
|
78
92
|
{{value, Request}, Hq2} ->
|
@@ -175,20 +189,11 @@ receive_term(Request, State) ->
|
|
175
189
|
_Any ->
|
176
190
|
Request2 = Request#request{action = BinaryTerm},
|
177
191
|
close_if_cast(Term, Request2),
|
178
|
-
|
179
|
-
|
180
|
-
Hq2 = queue:in(Request2, State#state.hq),
|
181
|
-
Lq2 = State#state.lq;
|
182
|
-
low ->
|
183
|
-
Hq2 = State#state.hq,
|
184
|
-
Lq2 = queue:in(Request2, State#state.lq)
|
185
|
-
end,
|
186
|
-
ernie_server:kick(),
|
187
|
-
State#state{hq = Hq2, lq = Lq2}
|
192
|
+
ernie_server:enqueue_request(Request2),
|
193
|
+
ernie_server:kick()
|
188
194
|
end;
|
189
195
|
{error, closed} ->
|
190
|
-
ok = gen_tcp:close(Sock)
|
191
|
-
State
|
196
|
+
ok = gen_tcp:close(Sock)
|
192
197
|
end.
|
193
198
|
|
194
199
|
process_info(Request, priority, [Priority]) ->
|
@@ -200,16 +205,28 @@ process_request(Request, Priority, Q2, State) ->
|
|
200
205
|
ActionTerm = bert:decode(Request#request.action),
|
201
206
|
{_Type, Mod, _Fun, _Args} = ActionTerm,
|
202
207
|
Specs = lists:filter(fun({X, _Id}) -> Mod =:= X end, State#state.map),
|
203
|
-
|
208
|
+
case Specs of
|
209
|
+
[] -> no_module(Mod, Request, Priority, Q2, State);
|
210
|
+
_Else -> process_module(ActionTerm, Specs, Request, Priority, Q2, State)
|
211
|
+
end.
|
204
212
|
|
205
|
-
|
206
|
-
{_Type, Mod, _Fun, _Args} = ActionTerm,
|
213
|
+
no_module(Mod, Request, Priority, Q2, State) ->
|
207
214
|
logger:debug("No such module ~p~n", [Mod]),
|
208
215
|
Sock = Request#request.sock,
|
209
216
|
Class = <<"ServerError">>,
|
210
217
|
Message = list_to_binary(io_lib:format("No such module '~p'", [Mod])),
|
211
218
|
gen_tcp:send(Sock, term_to_binary({error, [server, 0, Class, Message, []]})),
|
212
219
|
ok = gen_tcp:close(Sock),
|
220
|
+
finish(Priority, Q2, State).
|
221
|
+
|
222
|
+
process_module(ActionTerm, [], Request, Priority, Q2, State) ->
|
223
|
+
{_Type, Mod, Fun, _Args} = ActionTerm,
|
224
|
+
logger:debug("No such function ~p:~p~n", [Mod, Fun]),
|
225
|
+
Sock = Request#request.sock,
|
226
|
+
Class = <<"ServerError">>,
|
227
|
+
Message = list_to_binary(io_lib:format("No such function '~p:~p'", [Mod, Fun])),
|
228
|
+
gen_tcp:send(Sock, term_to_binary({error, [server, 0, Class, Message, []]})),
|
229
|
+
ok = gen_tcp:close(Sock),
|
213
230
|
finish(Priority, Q2, State);
|
214
231
|
process_module(ActionTerm, Specs, Request, Priority, Q2, State) ->
|
215
232
|
[{_Mod, Id} | OtherSpecs] = Specs,
|
data/elib/logger.erl
CHANGED
@@ -15,28 +15,28 @@
|
|
15
15
|
%%====================================================================
|
16
16
|
|
17
17
|
start_link(Args) ->
|
18
|
-
gen_server:start_link({
|
18
|
+
gen_server:start_link({local, ?MODULE}, ?MODULE, Args, []).
|
19
19
|
|
20
20
|
start(Args) ->
|
21
|
-
gen_server:start({
|
21
|
+
gen_server:start({local, ?MODULE}, ?MODULE, Args, []).
|
22
22
|
|
23
23
|
set_log_level(Level) ->
|
24
|
-
gen_server:call(
|
24
|
+
gen_server:call(?MODULE, {set_log_level, Level}).
|
25
25
|
|
26
26
|
debug(Msg, Args) ->
|
27
|
-
gen_server:cast(
|
27
|
+
gen_server:cast(?MODULE, {debug, Msg, Args}).
|
28
28
|
|
29
29
|
info(Msg, Args) ->
|
30
|
-
gen_server:cast(
|
30
|
+
gen_server:cast(?MODULE, {info, Msg, Args}).
|
31
31
|
|
32
32
|
warn(Msg, Args) ->
|
33
|
-
gen_server:cast(
|
33
|
+
gen_server:cast(?MODULE, {warn, Msg, Args}).
|
34
34
|
|
35
35
|
error(Msg, Args) ->
|
36
|
-
gen_server:cast(
|
36
|
+
gen_server:cast(?MODULE, {error, Msg, Args}).
|
37
37
|
|
38
38
|
fatal(Msg, Args) ->
|
39
|
-
gen_server:cast(
|
39
|
+
gen_server:cast(?MODULE, {fatal, Msg, Args}).
|
40
40
|
|
41
41
|
%%====================================================================
|
42
42
|
%% gen_server callbacks
|
data/ernie.gemspec
CHANGED
@@ -1,95 +1,77 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in rakefile, and run the gemspec command
|
4
|
-
# -*- encoding: utf-8 -*-
|
5
|
-
|
6
1
|
Gem::Specification.new do |s|
|
7
|
-
s.
|
8
|
-
s.version = "2.4.0"
|
9
|
-
|
2
|
+
s.specification_version = 2 if s.respond_to? :specification_version=
|
10
3
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.
|
12
|
-
|
13
|
-
s.
|
14
|
-
s.
|
15
|
-
s.
|
16
|
-
s.
|
4
|
+
s.rubygems_version = '1.3.6'
|
5
|
+
|
6
|
+
s.name = 'ernie'
|
7
|
+
s.version = '2.5.0'
|
8
|
+
s.date = '2010-11-19'
|
9
|
+
s.rubyforge_project = 'ernie'
|
10
|
+
|
11
|
+
s.summary = "Ernie is a BERT-RPC server implementation."
|
12
|
+
s.description = "Ernie is an Erlang/Ruby hybrid BERT-RPC server implementation packaged as a gem."
|
13
|
+
|
14
|
+
s.authors = ["Tom Preston-Werner"]
|
15
|
+
s.email = 'tom@mojombo.com'
|
16
|
+
s.homepage = 'http://github.com/mojombo/ernie'
|
17
|
+
|
18
|
+
s.require_paths = %w[lib]
|
19
|
+
|
17
20
|
s.extensions = ["ext/extconf.rb", "ext/extconf.rb"]
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
s.files = [
|
23
|
-
".document",
|
24
|
-
".gitignore",
|
25
|
-
"History.txt",
|
26
|
-
"LICENSE",
|
27
|
-
"README.md",
|
28
|
-
"Rakefile",
|
29
|
-
"VERSION.yml",
|
30
|
-
"bin/ernie",
|
31
|
-
"contrib/ebench.erl",
|
32
|
-
"ebin/ernie_server_app.app",
|
33
|
-
"elib/asset_pool.erl",
|
34
|
-
"elib/asset_pool_sup.erl",
|
35
|
-
"elib/bert.erl",
|
36
|
-
"elib/ernie.hrl",
|
37
|
-
"elib/ernie_access_logger.erl",
|
38
|
-
"elib/ernie_access_logger_sup.erl",
|
39
|
-
"elib/ernie_admin.erl",
|
40
|
-
"elib/ernie_config.erl",
|
41
|
-
"elib/ernie_native.erl",
|
42
|
-
"elib/ernie_server.erl",
|
43
|
-
"elib/ernie_server_app.erl",
|
44
|
-
"elib/ernie_server_sup.erl",
|
45
|
-
"elib/logger.erl",
|
46
|
-
"elib/logger_sup.erl",
|
47
|
-
"elib/port_wrapper.erl",
|
48
|
-
"ernie.gemspec",
|
49
|
-
"examples/example.cfg",
|
50
|
-
"examples/example.config",
|
51
|
-
"examples/ext.erl",
|
52
|
-
"examples/ext.rb",
|
53
|
-
"examples/nat.erl",
|
54
|
-
"ext/Makefile",
|
55
|
-
"ext/extconf.rb",
|
56
|
-
"lib/ernie.rb",
|
57
|
-
"test/ernie_server_test.rb",
|
58
|
-
"test/ernie_test.rb",
|
59
|
-
"test/helper.rb",
|
60
|
-
"test/load.rb",
|
61
|
-
"test/sample/ext.rb",
|
62
|
-
"test/sample/sample.cfg"
|
63
|
-
]
|
64
|
-
s.homepage = %q{http://github.com/mojombo/ernie}
|
21
|
+
|
22
|
+
s.executables = ["ernie"]
|
23
|
+
s.default_executable = 'ernie'
|
24
|
+
|
65
25
|
s.rdoc_options = ["--charset=UTF-8"]
|
66
|
-
s.
|
67
|
-
s.rubyforge_project = %q{ernie}
|
68
|
-
s.rubygems_version = %q{1.3.6}
|
69
|
-
s.summary = %q{Ernie is a BERT-RPC server implementation.}
|
70
|
-
s.test_files = [
|
71
|
-
"test/ernie_server_test.rb",
|
72
|
-
"test/ernie_test.rb",
|
73
|
-
"test/helper.rb",
|
74
|
-
"test/load.rb",
|
75
|
-
"test/sample/ext.rb",
|
76
|
-
"examples/ext.rb"
|
77
|
-
]
|
26
|
+
s.extra_rdoc_files = %w[LICENSE README.md]
|
78
27
|
|
79
|
-
|
80
|
-
|
81
|
-
s.specification_version = 3
|
28
|
+
s.add_dependency('bert', [">= 1.1.0"])
|
29
|
+
s.add_dependency('bertrpc', [">= 1.0.0"])
|
82
30
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
31
|
+
s.add_development_dependency('shoulda', [">= 2.11.3", "< 3.0.0"])
|
32
|
+
|
33
|
+
# = MANIFEST =
|
34
|
+
s.files = %w[
|
35
|
+
History.txt
|
36
|
+
LICENSE
|
37
|
+
README.md
|
38
|
+
Rakefile
|
39
|
+
bin/ernie
|
40
|
+
contrib/ebench.erl
|
41
|
+
ebin/ernie_server_app.app
|
42
|
+
elib/asset_pool.erl
|
43
|
+
elib/asset_pool_sup.erl
|
44
|
+
elib/bert.erl
|
45
|
+
elib/ernie.hrl
|
46
|
+
elib/ernie_access_logger.erl
|
47
|
+
elib/ernie_access_logger_sup.erl
|
48
|
+
elib/ernie_admin.erl
|
49
|
+
elib/ernie_config.erl
|
50
|
+
elib/ernie_native.erl
|
51
|
+
elib/ernie_server.erl
|
52
|
+
elib/ernie_server_app.erl
|
53
|
+
elib/ernie_server_sup.erl
|
54
|
+
elib/logger.erl
|
55
|
+
elib/logger_sup.erl
|
56
|
+
elib/port_wrapper.erl
|
57
|
+
ernie.gemspec
|
58
|
+
examples/example.cfg
|
59
|
+
examples/example.config
|
60
|
+
examples/ext.erl
|
61
|
+
examples/ext.rb
|
62
|
+
examples/nat.erl
|
63
|
+
ext/Makefile
|
64
|
+
ext/extconf.rb
|
65
|
+
lib/ernie.rb
|
66
|
+
test/helper.rb
|
67
|
+
test/load.rb
|
68
|
+
test/sample/ext.rb
|
69
|
+
test/sample/intTest.erl
|
70
|
+
test/sample/sample.cfg
|
71
|
+
test/test_ernie.rb
|
72
|
+
test/test_ernie_server.rb
|
73
|
+
]
|
74
|
+
# = MANIFEST =
|
95
75
|
|
76
|
+
s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
|
77
|
+
end
|
data/lib/ernie.rb
CHANGED
@@ -3,6 +3,8 @@ require 'bert'
|
|
3
3
|
require 'logger'
|
4
4
|
|
5
5
|
class Ernie
|
6
|
+
VERSION = '2.5.0'
|
7
|
+
|
6
8
|
class << self
|
7
9
|
attr_accessor :mods, :current_mod, :log
|
8
10
|
attr_accessor :auto_start
|
@@ -185,13 +187,8 @@ class Ernie
|
|
185
187
|
end
|
186
188
|
|
187
189
|
def self.version
|
188
|
-
|
189
|
-
"#{yml[:major]}.#{yml[:minor]}.#{yml[:patch]}"
|
190
|
-
rescue
|
191
|
-
'unknown'
|
190
|
+
VERSION
|
192
191
|
end
|
193
|
-
|
194
|
-
VERSION = self.version
|
195
192
|
end
|
196
193
|
|
197
194
|
class Ernie::ServerError < StandardError; end
|
data/test/helper.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
-module(intTest).
|
2
|
+
|
3
|
+
-export([zeronary/0, unary/1, binary/2, ternary/3, big/1, set_state/1, get_state/0, connect_nodes/0, sleep/1]).
|
4
|
+
|
5
|
+
connect_nodes() ->
|
6
|
+
net_adm:ping('ernie0@127.0.0.1').
|
7
|
+
|
8
|
+
zeronary() ->
|
9
|
+
foo.
|
10
|
+
|
11
|
+
unary(A) ->
|
12
|
+
A.
|
13
|
+
|
14
|
+
binary(A,B) ->
|
15
|
+
A + B.
|
16
|
+
|
17
|
+
ternary(A,B,C) ->
|
18
|
+
A + B + C.
|
19
|
+
|
20
|
+
big(A) ->
|
21
|
+
string:copies("a", A).
|
22
|
+
|
23
|
+
sleep(Time) ->
|
24
|
+
receive after Time ->
|
25
|
+
ok
|
26
|
+
end.
|
27
|
+
|
28
|
+
get_state() ->
|
29
|
+
case catch global:send(test_saved_state, {get_state, self()}) of
|
30
|
+
{'EXIT',{badarg, _}} ->
|
31
|
+
{error, no_record};
|
32
|
+
_ ->
|
33
|
+
receive
|
34
|
+
{ok, State} ->
|
35
|
+
State
|
36
|
+
after 1000 ->
|
37
|
+
{error, timeout}
|
38
|
+
end
|
39
|
+
end.
|
40
|
+
|
41
|
+
set_state(State) ->
|
42
|
+
spawn(fun() -> wrapper(State) end),
|
43
|
+
ok.
|
44
|
+
|
45
|
+
wrapper(State) ->
|
46
|
+
case global:register_name(test_saved_state, self()) of
|
47
|
+
no ->
|
48
|
+
global:send(test_saved_state, {set_state, State});
|
49
|
+
yes ->
|
50
|
+
recv(State)
|
51
|
+
end.
|
52
|
+
|
53
|
+
recv(State) ->
|
54
|
+
receive
|
55
|
+
{set_state, NewState} ->
|
56
|
+
recv(NewState);
|
57
|
+
{get_state, Pid} ->
|
58
|
+
Pid ! {ok, State},
|
59
|
+
recv(State)
|
60
|
+
end.
|
data/test/sample/sample.cfg
CHANGED
File without changes
|
@@ -0,0 +1,221 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
PORT = 27118
|
4
|
+
|
5
|
+
class ErnieServerTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
# global setup
|
8
|
+
def setup
|
9
|
+
@servers ||= []
|
10
|
+
Dir.chdir(ERNIE_ROOT)
|
11
|
+
`erlc -o test/sample #{ERNIE_ROOT}/test/sample/intTest.erl`
|
12
|
+
Signal.trap("INT") do
|
13
|
+
puts "Shutting Down"
|
14
|
+
shutdown_servers
|
15
|
+
teardown
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def teardown
|
21
|
+
`rm test/sample/intTest.beam`
|
22
|
+
end
|
23
|
+
|
24
|
+
context "An Ernie Server" do
|
25
|
+
setup do
|
26
|
+
start_server
|
27
|
+
end
|
28
|
+
|
29
|
+
context "call" do
|
30
|
+
should "handle zeronary" do
|
31
|
+
assert_equal :foo, svc.call.ext.zeronary
|
32
|
+
assert_equal :foo, svc.call.intTest.zeronary
|
33
|
+
end
|
34
|
+
|
35
|
+
should "handle unary" do
|
36
|
+
assert_equal 5, svc.call.ext.unary(5)
|
37
|
+
assert_equal 5, svc.call.intTest.unary(5)
|
38
|
+
end
|
39
|
+
|
40
|
+
should "handle binary" do
|
41
|
+
assert_equal 7, svc.call.ext.binary(5, 2)
|
42
|
+
assert_equal 7, svc.call.intTest.binary(5, 2)
|
43
|
+
end
|
44
|
+
|
45
|
+
should "handle ternary" do
|
46
|
+
assert_equal 10, svc.call.ext.ternary(5, 2, 3)
|
47
|
+
assert_equal 10, svc.call.intTest.ternary(5, 2, 3)
|
48
|
+
end
|
49
|
+
|
50
|
+
should "handle massive binaries" do
|
51
|
+
assert_equal 8 * 1024 * 1024, svc.call.ext.big(8 * 1024 * 1024).size
|
52
|
+
assert_equal 8 * 1024 * 1024, svc.call.intTest.big(8 * 1024 * 1024).size
|
53
|
+
end
|
54
|
+
|
55
|
+
should "not block on internal modules" do
|
56
|
+
time = Time.now
|
57
|
+
svc.call.intTest.sleep(1000)
|
58
|
+
assert(Time.now >= time + 1)
|
59
|
+
|
60
|
+
time = Time.now
|
61
|
+
svc.cast.intTest.sleep(1000)
|
62
|
+
svc.cast.intTest.sleep(1000)
|
63
|
+
svc.cast.intTest.sleep(1000)
|
64
|
+
svc.call.intTest.zeronary
|
65
|
+
assert(Time.now < time + 1)
|
66
|
+
end
|
67
|
+
|
68
|
+
should "get an error on missing module" do
|
69
|
+
begin
|
70
|
+
svc.call.failboat.mcfail(:fail)
|
71
|
+
fail "Expected a BERTRPC::ServerError"
|
72
|
+
rescue BERTRPC::ServerError => e
|
73
|
+
assert_equal "No such module 'failboat'", e.message
|
74
|
+
else
|
75
|
+
assert false, 'failed to raise on missing module'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
should "get an error on missing function" do
|
80
|
+
begin
|
81
|
+
svc.call.ext.mcfail(:fail)
|
82
|
+
fail "Expected a BERTRPC::ServerError"
|
83
|
+
rescue BERTRPC::ServerError => e
|
84
|
+
assert_equal "No such function 'ext:mcfail'", e.message
|
85
|
+
else
|
86
|
+
assert false, 'failed to raise on missing function'
|
87
|
+
end
|
88
|
+
|
89
|
+
begin
|
90
|
+
svc.call.intTest.mcfail(:fail)
|
91
|
+
fail "Expected a BERTRPC::ServerError"
|
92
|
+
rescue BERTRPC::ServerError => e
|
93
|
+
assert_equal "No such function 'intTest:mcfail'", e.message
|
94
|
+
else
|
95
|
+
assert false, 'failed to raise on missing function'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "cast" do
|
101
|
+
should "be received and return immediately" do
|
102
|
+
t0 = Time.now
|
103
|
+
assert_equal nil, svc.cast.ext.set_state(7)
|
104
|
+
assert Time.now - t0 < 1
|
105
|
+
assert_equal 7, svc.call.ext.get_state
|
106
|
+
|
107
|
+
t0 = Time.now
|
108
|
+
assert_equal nil, svc.cast.intTest.set_state(7)
|
109
|
+
assert Time.now - t0 < 1
|
110
|
+
sleep 0.25
|
111
|
+
assert_equal 7, svc.call.intTest.get_state
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
teardown do
|
116
|
+
shutdown_server
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "Two Ernie Servers" do
|
121
|
+
setup do
|
122
|
+
start_servers(2)
|
123
|
+
@servers.each do |svc|
|
124
|
+
svc.cast.intTest.connect_nodes
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context "call" do
|
129
|
+
|
130
|
+
should "handle zeronary" do
|
131
|
+
@servers.each do |svc|
|
132
|
+
assert_equal :foo, svc.call.ext.zeronary
|
133
|
+
assert_equal :foo, svc.call.intTest.zeronary
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
should "handle unary" do
|
138
|
+
@servers.each do |svc|
|
139
|
+
assert_equal 5, svc.call.ext.unary(5)
|
140
|
+
assert_equal 5, svc.call.intTest.unary(5)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
should "handle binary" do
|
145
|
+
@servers.each do |svc|
|
146
|
+
assert_equal 7, svc.call.ext.binary(5, 2)
|
147
|
+
assert_equal 7, svc.call.intTest.binary(5, 2)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
should "handle ternary" do
|
152
|
+
@servers.each do |svc|
|
153
|
+
assert_equal 10, svc.call.ext.ternary(5, 2, 3)
|
154
|
+
assert_equal 10, svc.call.intTest.ternary(5, 2, 3)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
should "handle massive binaries" do
|
159
|
+
@servers.each do |svc|
|
160
|
+
assert_equal 8 * 1024 * 1024, svc.call.ext.big(8 * 1024 * 1024).size
|
161
|
+
assert_equal 8 * 1024 * 1024, svc.call.intTest.big(8 * 1024 * 1024).size
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
should "make joined erlang nodes possible" do
|
166
|
+
assert_equal nil, @servers.first.cast.intTest.set_state(7)
|
167
|
+
sleep 0.25
|
168
|
+
assert_equal 7, @servers.last.call.intTest.get_state
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
teardown do
|
174
|
+
shutdown_servers(2)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
protected
|
179
|
+
|
180
|
+
def svc
|
181
|
+
@servers[rand(@servers.size-1)]
|
182
|
+
end
|
183
|
+
|
184
|
+
def start_server
|
185
|
+
start_servers(1)
|
186
|
+
end
|
187
|
+
|
188
|
+
def shutdown_server
|
189
|
+
shutdown_servers(1)
|
190
|
+
end
|
191
|
+
|
192
|
+
def start_servers(n = 1)
|
193
|
+
n.times do
|
194
|
+
`#{ERNIE_ROOT}/bin/ernie -c #{ERNIE_ROOT}/test/sample/sample.cfg \
|
195
|
+
-P /tmp/ernie#{@servers.size}.pid \
|
196
|
+
-p #{PORT + @servers.size} \
|
197
|
+
--name ernie#{@servers.size}@127.0.0.1 \
|
198
|
+
-d`
|
199
|
+
|
200
|
+
@servers << BERTRPC::Service.new('localhost', PORT + @servers.size)
|
201
|
+
loop do
|
202
|
+
begin
|
203
|
+
@servers.last.call.ext.zeronary
|
204
|
+
break
|
205
|
+
rescue Object => e
|
206
|
+
sleep 0.1
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def shutdown_servers(n = nil)
|
213
|
+
start = @servers.size - 1
|
214
|
+
last = start - (n || start)
|
215
|
+
(start).downto(last >= 0 ? last : 0) do |i|
|
216
|
+
pid = File.read("/tmp/ernie#{i}.pid")
|
217
|
+
`kill -9 #{pid}`
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ernie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 2
|
7
|
-
-
|
8
|
+
- 5
|
8
9
|
- 0
|
9
|
-
version: 2.
|
10
|
+
version: 2.5.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Tom Preston-Werner
|
@@ -14,16 +15,18 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-11-19 00:00:00 -06:00
|
18
19
|
default_executable: ernie
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: bert
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
24
26
|
requirements:
|
25
27
|
- - ">="
|
26
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 19
|
27
30
|
segments:
|
28
31
|
- 1
|
29
32
|
- 1
|
@@ -35,9 +38,11 @@ dependencies:
|
|
35
38
|
name: bertrpc
|
36
39
|
prerelease: false
|
37
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
38
42
|
requirements:
|
39
43
|
- - ">="
|
40
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 23
|
41
46
|
segments:
|
42
47
|
- 1
|
43
48
|
- 0
|
@@ -45,6 +50,30 @@ dependencies:
|
|
45
50
|
version: 1.0.0
|
46
51
|
type: :runtime
|
47
52
|
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: shoulda
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 37
|
62
|
+
segments:
|
63
|
+
- 2
|
64
|
+
- 11
|
65
|
+
- 3
|
66
|
+
version: 2.11.3
|
67
|
+
- - <
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
hash: 7
|
70
|
+
segments:
|
71
|
+
- 3
|
72
|
+
- 0
|
73
|
+
- 0
|
74
|
+
version: 3.0.0
|
75
|
+
type: :development
|
76
|
+
version_requirements: *id003
|
48
77
|
description: Ernie is an Erlang/Ruby hybrid BERT-RPC server implementation packaged as a gem.
|
49
78
|
email: tom@mojombo.com
|
50
79
|
executables:
|
@@ -56,13 +85,10 @@ extra_rdoc_files:
|
|
56
85
|
- LICENSE
|
57
86
|
- README.md
|
58
87
|
files:
|
59
|
-
- .document
|
60
|
-
- .gitignore
|
61
88
|
- History.txt
|
62
89
|
- LICENSE
|
63
90
|
- README.md
|
64
91
|
- Rakefile
|
65
|
-
- VERSION.yml
|
66
92
|
- bin/ernie
|
67
93
|
- contrib/ebench.erl
|
68
94
|
- ebin/ernie_server_app.app
|
@@ -90,12 +116,13 @@ files:
|
|
90
116
|
- ext/Makefile
|
91
117
|
- ext/extconf.rb
|
92
118
|
- lib/ernie.rb
|
93
|
-
- test/ernie_server_test.rb
|
94
|
-
- test/ernie_test.rb
|
95
119
|
- test/helper.rb
|
96
120
|
- test/load.rb
|
97
121
|
- test/sample/ext.rb
|
122
|
+
- test/sample/intTest.erl
|
98
123
|
- test/sample/sample.cfg
|
124
|
+
- test/test_ernie.rb
|
125
|
+
- test/test_ernie_server.rb
|
99
126
|
has_rdoc: true
|
100
127
|
homepage: http://github.com/mojombo/ernie
|
101
128
|
licenses: []
|
@@ -106,30 +133,30 @@ rdoc_options:
|
|
106
133
|
require_paths:
|
107
134
|
- lib
|
108
135
|
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
109
137
|
requirements:
|
110
138
|
- - ">="
|
111
139
|
- !ruby/object:Gem::Version
|
140
|
+
hash: 3
|
112
141
|
segments:
|
113
142
|
- 0
|
114
143
|
version: "0"
|
115
144
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
116
146
|
requirements:
|
117
147
|
- - ">="
|
118
148
|
- !ruby/object:Gem::Version
|
149
|
+
hash: 3
|
119
150
|
segments:
|
120
151
|
- 0
|
121
152
|
version: "0"
|
122
153
|
requirements: []
|
123
154
|
|
124
155
|
rubyforge_project: ernie
|
125
|
-
rubygems_version: 1.3.
|
156
|
+
rubygems_version: 1.3.7
|
126
157
|
signing_key:
|
127
|
-
specification_version:
|
158
|
+
specification_version: 2
|
128
159
|
summary: Ernie is a BERT-RPC server implementation.
|
129
160
|
test_files:
|
130
|
-
- test/
|
131
|
-
- test/
|
132
|
-
- test/helper.rb
|
133
|
-
- test/load.rb
|
134
|
-
- test/sample/ext.rb
|
135
|
-
- examples/ext.rb
|
161
|
+
- test/test_ernie.rb
|
162
|
+
- test/test_ernie_server.rb
|
data/.document
DELETED
data/.gitignore
DELETED
data/VERSION.yml
DELETED
data/test/ernie_server_test.rb
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/helper'
|
2
|
-
|
3
|
-
PORT = 27118
|
4
|
-
|
5
|
-
class ErnieServerTest < Test::Unit::TestCase
|
6
|
-
context "An Ernie Server" do
|
7
|
-
setup do
|
8
|
-
`#{ERNIE_ROOT}/bin/ernie -c #{ERNIE_ROOT}/test/sample/sample.cfg \
|
9
|
-
-P /tmp/ernie.pid \
|
10
|
-
-p #{PORT} \
|
11
|
-
-d`
|
12
|
-
@svc = BERTRPC::Service.new('localhost', PORT)
|
13
|
-
loop do
|
14
|
-
begin
|
15
|
-
@svc.call.ext.zeronary
|
16
|
-
break
|
17
|
-
rescue Object => e
|
18
|
-
sleep 0.1
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
context "call" do
|
24
|
-
should "handle zeronary" do
|
25
|
-
assert_equal :foo, @svc.call.ext.zeronary
|
26
|
-
end
|
27
|
-
|
28
|
-
should "handle unary" do
|
29
|
-
assert_equal 5, @svc.call.ext.unary(5)
|
30
|
-
end
|
31
|
-
|
32
|
-
should "handle binary" do
|
33
|
-
assert_equal 7, @svc.call.ext.binary(5, 2)
|
34
|
-
end
|
35
|
-
|
36
|
-
should "handle ternary" do
|
37
|
-
assert_equal 10, @svc.call.ext.ternary(5, 2, 3)
|
38
|
-
end
|
39
|
-
|
40
|
-
should "handle massive binaries" do
|
41
|
-
assert_equal 8 * 1024 * 1024, @svc.call.ext.big(8 * 1024 * 1024).size
|
42
|
-
end
|
43
|
-
|
44
|
-
should "get an error on missing module" do
|
45
|
-
begin
|
46
|
-
@svc.call.failboat.mcfail(:fail)
|
47
|
-
fail "Expected a BERTRPC::ServerError"
|
48
|
-
rescue BERTRPC::ServerError => e
|
49
|
-
assert_equal "No such module 'failboat'", e.message
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
should "get an error on missing function" do
|
54
|
-
begin
|
55
|
-
@svc.call.ext.mcfail(:fail)
|
56
|
-
fail "Expected a BERTRPC::ServerError"
|
57
|
-
rescue BERTRPC::ServerError => e
|
58
|
-
assert_equal "No such function 'ext:mcfail'", e.message
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
context "cast" do
|
64
|
-
should "be received and return immediately" do
|
65
|
-
t0 = Time.now
|
66
|
-
assert_equal nil, @svc.cast.ext.set_state(7)
|
67
|
-
assert Time.now - t0 < 1
|
68
|
-
assert_equal 7, @svc.call.ext.get_state
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
teardown do
|
73
|
-
pid = File.read('/tmp/ernie.pid')
|
74
|
-
`kill -9 #{pid}`
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|