ernie 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|