plezi 0.12.22 → 0.14.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/LICENSE.txt +17 -18
- data/README.md +54 -698
- data/Rakefile +7 -4
- data/bin/config.ru +22 -0
- data/{test → bin}/console +4 -6
- data/bin/hello_world +52 -0
- data/bin/setup +8 -0
- data/exe/plezi +145 -0
- data/lib/plezi.rb +24 -137
- data/lib/plezi/activation.rb +28 -0
- data/lib/plezi/api.rb +62 -0
- data/lib/plezi/controller/controller.rb +259 -0
- data/lib/plezi/controller/controller_class.rb +176 -0
- data/lib/plezi/controller/cookies.rb +40 -0
- data/lib/plezi/helpers.rb +60 -0
- data/lib/plezi/rake.rb +2 -24
- data/lib/plezi/render/erb.rb +34 -0
- data/lib/plezi/render/has_cache.rb +36 -0
- data/lib/plezi/render/markdown.rb +63 -0
- data/lib/plezi/render/render.rb +49 -0
- data/lib/plezi/render/sass.rb +55 -0
- data/lib/plezi/render/slim.rb +33 -0
- data/lib/plezi/router/adclient.rb +23 -0
- data/lib/plezi/router/assets.rb +67 -0
- data/lib/plezi/router/errors.rb +29 -0
- data/lib/plezi/router/route.rb +112 -0
- data/lib/plezi/router/router.rb +120 -0
- data/lib/plezi/version.rb +1 -1
- data/lib/plezi/websockets/message_dispatch.rb +91 -0
- data/lib/plezi/websockets/redis.rb +55 -0
- data/plezi.gemspec +25 -16
- data/resources/404.erb +5 -4
- data/resources/500.erb +5 -4
- data/resources/{500.html → 503.html} +8 -9
- data/resources/client.js +253 -0
- data/resources/config.ru +5 -36
- data/resources/ctrlr.rb +34 -0
- data/resources/gemfile +4 -0
- data/resources/mini_app.rb +28 -82
- data/resources/mini_exec +7 -0
- data/resources/mini_welcome_page.html +0 -0
- data/resources/procfile +3 -0
- data/resources/rakefile +4 -8
- data/resources/routes.rb +9 -26
- data/resources/{websockets.js → simple-client.js} +3 -3
- metadata +60 -85
- data/bin/plezi +0 -104
- data/docs/async_helpers.md +0 -245
- data/docs/controllers.md +0 -27
- data/docs/logging.md +0 -49
- data/docs/routes.md +0 -209
- data/docs/websockets.md +0 -213
- data/lib/plezi/builders/ac_model.rb +0 -59
- data/lib/plezi/builders/app_builder.rb +0 -137
- data/lib/plezi/builders/builder.rb +0 -43
- data/lib/plezi/builders/form_builder.rb +0 -27
- data/lib/plezi/common/api.rb +0 -92
- data/lib/plezi/common/cache.rb +0 -122
- data/lib/plezi/common/defer.rb +0 -21
- data/lib/plezi/common/dsl.rb +0 -94
- data/lib/plezi/common/redis.rb +0 -65
- data/lib/plezi/common/renderer.rb +0 -141
- data/lib/plezi/common/settings.rb +0 -52
- data/lib/plezi/handlers/controller_core.rb +0 -106
- data/lib/plezi/handlers/controller_magic.rb +0 -284
- data/lib/plezi/handlers/http_router.rb +0 -205
- data/lib/plezi/handlers/placebo.rb +0 -112
- data/lib/plezi/handlers/route.rb +0 -216
- data/lib/plezi/handlers/session.rb +0 -109
- data/lib/plezi/handlers/stubs.rb +0 -156
- data/lib/plezi/handlers/ws_identity.rb +0 -253
- data/lib/plezi/handlers/ws_object.rb +0 -308
- data/lib/plezi/helpers/http_sender.rb +0 -84
- data/lib/plezi/helpers/magic_helpers.rb +0 -104
- data/lib/plezi/helpers/mime_types.rb +0 -1995
- data/lib/plezi/oauth.rb +0 -5
- data/lib/plezi/oauth/auth_controller.rb +0 -229
- data/logo/dark.png +0 -0
- data/logo/light.png +0 -0
- data/logo/sign.png +0 -0
- data/resources/404.haml +0 -121
- data/resources/404.html +0 -124
- data/resources/404.slim +0 -120
- data/resources/500.haml +0 -120
- data/resources/500.slim +0 -120
- data/resources/Gemfile +0 -86
- data/resources/code.rb +0 -8
- data/resources/controller.rb +0 -142
- data/resources/database.yml +0 -33
- data/resources/db_ac_config.rb +0 -59
- data/resources/db_dm_config.rb +0 -51
- data/resources/db_sequel_config.rb +0 -33
- data/resources/en.yml +0 -204
- data/resources/haml_config.rb +0 -6
- data/resources/i18n_config.rb +0 -14
- data/resources/initialize.rb +0 -49
- data/resources/mini_exec.rb +0 -7
- data/resources/oauth_config.rb +0 -24
- data/resources/plezi_client.js +0 -198
- data/resources/plezi_websockets.html +0 -47
- data/resources/redis_config.rb +0 -42
- data/resources/slim_config.rb +0 -11
- data/resources/welcome_page.html +0 -272
- data/test/dispatch +0 -58
- data/test/hello_world +0 -13
- data/test/plezi_tests.rb +0 -581
data/test/dispatch
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
|
4
|
-
require 'benchmark'
|
5
|
-
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), __FILE__ )
|
6
|
-
require "plezi"
|
7
|
-
require "bundler/setup"
|
8
|
-
|
9
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
10
|
-
# with your gem easier. You can also use a different console, if you like.
|
11
|
-
|
12
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
13
|
-
# require "pry"
|
14
|
-
# Pry.start
|
15
|
-
|
16
|
-
class DispatchTest
|
17
|
-
@auto_dispatch = true
|
18
|
-
def before
|
19
|
-
{event: :failed, data: :forbidden}.to_json
|
20
|
-
end
|
21
|
-
def _hidden
|
22
|
-
{event: :failed, data: :forbidden}.to_json
|
23
|
-
end
|
24
|
-
def html
|
25
|
-
{event: 'html', data: 'only'}.to_json
|
26
|
-
end
|
27
|
-
def test data = {}
|
28
|
-
data[:data] ||= "test"
|
29
|
-
{event: 'alert', data: data[:data]}.to_json
|
30
|
-
end
|
31
|
-
def index event = nil
|
32
|
-
%q{<html><head><script src='/client.js'></script>
|
33
|
-
</head>
|
34
|
-
<body>
|
35
|
-
<button onclick='connection.emit({event: "test", data: "Woohooo!"});' value='test'>Test!</button>
|
36
|
-
<script>
|
37
|
-
document.body.onload = function() {
|
38
|
-
connection = new PleziClient();
|
39
|
-
connection.alert = function(data) {
|
40
|
-
alert(JSON.stringify(data));
|
41
|
-
}
|
42
|
-
connection.emit_timeout = 3000;
|
43
|
-
connection.log_events = true;
|
44
|
-
// connection.err = function(data) {
|
45
|
-
// alert("Error: " + JSON.stringify(data));
|
46
|
-
// console.log(data);
|
47
|
-
// }
|
48
|
-
// connection.unknown = function(data) {
|
49
|
-
// alert("Unknown event: " + JSON.stringify(data));
|
50
|
-
// console.log(data);
|
51
|
-
// }
|
52
|
-
}
|
53
|
-
</script></body></html>}
|
54
|
-
end
|
55
|
-
end
|
56
|
-
host
|
57
|
-
route '/client.js', :client
|
58
|
-
route '/', DispatchTest
|
data/test/hello_world
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
|
4
|
-
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), __FILE__ )
|
5
|
-
require "plezi"
|
6
|
-
|
7
|
-
Iodine.logger = nil
|
8
|
-
|
9
|
-
HELLO = 'Hello Plezi'
|
10
|
-
Plezi.route('*') { HELLO }
|
11
|
-
|
12
|
-
# ab -n 10000 -c 200 -k http://127.0.0.1:3000/
|
13
|
-
# ~/ruby/wrk/wrk -c400 -d10 -t12 http://localhost:3000/
|
data/test/plezi_tests.rb
DELETED
@@ -1,581 +0,0 @@
|
|
1
|
-
# I started writing tests... but I haven't finished quite yet.
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'open-uri'
|
5
|
-
require 'plezi'
|
6
|
-
require 'objspace'
|
7
|
-
|
8
|
-
def report_before_filter(result= true)
|
9
|
-
return true if $before_tested
|
10
|
-
puts(" * Before filter test: #{PleziTestTasks::RESULTS[result]}")
|
11
|
-
$before_tested = true
|
12
|
-
true
|
13
|
-
end
|
14
|
-
def report_after_filter(result= true)
|
15
|
-
return true if $after_tested
|
16
|
-
puts(" * After filter test: #{PleziTestTasks::RESULTS[result]}")
|
17
|
-
$after_tested = true
|
18
|
-
true
|
19
|
-
end
|
20
|
-
|
21
|
-
class Nothing
|
22
|
-
end
|
23
|
-
class TestCtrl
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
# this will be called before every request.
|
28
|
-
def before
|
29
|
-
report_before_filter
|
30
|
-
end
|
31
|
-
|
32
|
-
# this will be called after every request.
|
33
|
-
def after
|
34
|
-
report_after_filter
|
35
|
-
end
|
36
|
-
|
37
|
-
# shouldn't be available (return 404).
|
38
|
-
def _hidden
|
39
|
-
"do you see me?"
|
40
|
-
end
|
41
|
-
def index
|
42
|
-
"test"
|
43
|
-
end
|
44
|
-
def headers
|
45
|
-
"HTTP request: #{request[:method]} #{request[:query]} - version: #{request[:version]}\n" + (request.headers.map {|k, v| "#{k}: #{v}"} .join "\n")
|
46
|
-
end
|
47
|
-
|
48
|
-
# returns the url used to access this method
|
49
|
-
def my_url
|
50
|
-
dest = params.dup
|
51
|
-
url_for dest
|
52
|
-
end
|
53
|
-
# should return a 500 internal server error message.
|
54
|
-
def fail
|
55
|
-
raise "Hell!"
|
56
|
-
end
|
57
|
-
|
58
|
-
# called when request is GET and params\[:id] == "new".
|
59
|
-
def new
|
60
|
-
"new"
|
61
|
-
end
|
62
|
-
# called when request is GET and params\[:id] exists (unless params\[:id] == "new").
|
63
|
-
def show
|
64
|
-
"show #{params[:id]}"
|
65
|
-
end
|
66
|
-
# called when request is POST / PUT and params\[:id] exists and isn't 'new'
|
67
|
-
def update
|
68
|
-
"update #{params[:id]}"
|
69
|
-
end
|
70
|
-
def delete
|
71
|
-
"delete #{params[:id]}"
|
72
|
-
end
|
73
|
-
# called when request is POST / PUT and params\[:id] is 'new'
|
74
|
-
def save
|
75
|
-
params[:data].to_s
|
76
|
-
end
|
77
|
-
def sleeper
|
78
|
-
sleep 1
|
79
|
-
"slept"
|
80
|
-
end
|
81
|
-
# should return a 404 error.
|
82
|
-
def get404
|
83
|
-
false
|
84
|
-
end
|
85
|
-
# path to test for chuncked encoding and response streaming.
|
86
|
-
def streamer
|
87
|
-
response.stream_async &method(:_stream_out)
|
88
|
-
true
|
89
|
-
end
|
90
|
-
def _stream_out
|
91
|
-
response << "streamed"
|
92
|
-
true
|
93
|
-
end
|
94
|
-
def file_test
|
95
|
-
if params[:file]
|
96
|
-
send_data params[:file][:data], type: params[:file][:type], inline: true, filename: params[:file][:filename]
|
97
|
-
return true
|
98
|
-
end
|
99
|
-
false
|
100
|
-
end
|
101
|
-
|
102
|
-
|
103
|
-
############
|
104
|
-
## WebSockets
|
105
|
-
|
106
|
-
def fail_unicast
|
107
|
-
unicast (params[:uuid] || (Plezi::Settings.uuid + SecureRandom.hex(12))), :psedo, "agrument1"
|
108
|
-
"Sent a psedo unicast... It should fail."
|
109
|
-
end
|
110
|
-
|
111
|
-
# called once the websocket was connected
|
112
|
-
def on_open
|
113
|
-
response << "connected"
|
114
|
-
end
|
115
|
-
|
116
|
-
# called when new Websocket data is recieved
|
117
|
-
#
|
118
|
-
# data is a string that contains binary or UTF8 (message dependent) data.
|
119
|
-
def on_message data
|
120
|
-
case data
|
121
|
-
when 'get uuid'
|
122
|
-
response << "uuid: #{uuid}"
|
123
|
-
when /to: ([^\s]*)/
|
124
|
-
# puts "unicasting to target: #{data.match(/to: ([^\s]*)/)[1]}"
|
125
|
-
unicast data.match(/to: ([^\s]*)/)[1], :_push, "unicast"
|
126
|
-
# broadcast :_push, "unicast"
|
127
|
-
else
|
128
|
-
broadcast :_push, data
|
129
|
-
_push data
|
130
|
-
end
|
131
|
-
return true
|
132
|
-
end
|
133
|
-
|
134
|
-
# called when a disconnect packet has been recieved or the connection has been cut
|
135
|
-
# (ISN'T called after a disconnect message has been sent).
|
136
|
-
def on_close
|
137
|
-
end
|
138
|
-
|
139
|
-
def self.failed_unicast target, method, args
|
140
|
-
puts "#{Process.pid}: Failed Unicast, on purpose, for target: #{target}, method: #{method} with: #{args}"
|
141
|
-
end
|
142
|
-
|
143
|
-
# a demo event method that recieves a broadcast from instance siblings.
|
144
|
-
def _push data
|
145
|
-
response << data.to_s
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
class WSsizeTestCtrl
|
150
|
-
# called when new Websocket data is recieved
|
151
|
-
#
|
152
|
-
# data is a string that contains binary or UTF8 (message dependent) data.
|
153
|
-
def on_message data
|
154
|
-
response << data
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
class WSIdentity
|
159
|
-
def index
|
160
|
-
"identity api testing path\n#{params}"
|
161
|
-
end
|
162
|
-
def show
|
163
|
-
if params[:message]
|
164
|
-
if notify params[:id], :notification, params[:message]
|
165
|
-
"Sent notification for #{params[:id]}: #{params[:message]}"
|
166
|
-
else
|
167
|
-
"The identity requested (#{params[:id]}) doesn't exist."
|
168
|
-
end
|
169
|
-
else
|
170
|
-
%{<html><head><script>
|
171
|
-
// Your websocket URI should be an absolute path. The following sets the base URI.
|
172
|
-
// remember to update to the specific controller's path to your websocket URI.
|
173
|
-
var ws_controller_path = window.location.pathname;
|
174
|
-
var ws_uri = (window.location.protocol.match(/https/) ? 'wss' : 'ws') + '://' + window.document.location.host + ws_controller_path
|
175
|
-
var websocket = 100
|
176
|
-
var websocket_fail_count = 0
|
177
|
-
|
178
|
-
function init_websocket()
|
179
|
-
{
|
180
|
-
if(websocket && websocket.readyState == 1) return true; // console.log('no need to renew socket connection');
|
181
|
-
websocket = new WebSocket(ws_uri);
|
182
|
-
websocket.onopen = function(e) {
|
183
|
-
//restart fail count
|
184
|
-
websocket_fail = 0
|
185
|
-
// what do you want to do now?
|
186
|
-
var msg = document.createElement("li");
|
187
|
-
msg.className = 'system_message'
|
188
|
-
msg.innerHTML = "Connected.";
|
189
|
-
document.getElementById("output").appendChild(msg);
|
190
|
-
};
|
191
|
-
|
192
|
-
websocket.onclose = function(e) {
|
193
|
-
// what do you want to do now?
|
194
|
-
if(websocket_fail == 0) {
|
195
|
-
var msg = document.createElement("li");
|
196
|
-
msg.className = 'system_message'
|
197
|
-
msg.innerHTML = "Disconnected.";
|
198
|
-
document.getElementById("output").appendChild(msg);
|
199
|
-
};
|
200
|
-
// you probably want to reopen the websocket if it closes (unless the issue repeats).
|
201
|
-
if(websocket_fail <= 5) {websocket_fail += 1; init_websocket(); };
|
202
|
-
};
|
203
|
-
websocket.onerror = function(e) {
|
204
|
-
// what do you want to do now?
|
205
|
-
};
|
206
|
-
websocket.onmessage = function(e) {
|
207
|
-
// what do you want to do now?
|
208
|
-
console.log(e.data);
|
209
|
-
var msg = document.createElement("li");
|
210
|
-
msg.innerHTML = e.data;
|
211
|
-
document.getElementById("output").appendChild(msg);
|
212
|
-
// to use JSON, use:
|
213
|
-
// msg = JSON.parse(e.data); // remember to use JSON also in your Plezi controller.
|
214
|
-
};
|
215
|
-
}
|
216
|
-
window.addEventListener("load", init_websocket, false);
|
217
|
-
</script></head>
|
218
|
-
<body>
|
219
|
-
<h3>You are now #{params[:id]}</h3>
|
220
|
-
<ul id='output'>
|
221
|
-
</ul>
|
222
|
-
</body></html>}
|
223
|
-
end
|
224
|
-
end
|
225
|
-
def pre_connect
|
226
|
-
params[:id] && true
|
227
|
-
end
|
228
|
-
def on_open
|
229
|
-
@id_count = self.class.counter
|
230
|
-
register_as params[:id], max_connections: 3, lifetime: 120
|
231
|
-
end
|
232
|
-
def on_message data
|
233
|
-
puts "websocket message (for identity #{@id_count}) : #{data}"
|
234
|
-
end
|
235
|
-
|
236
|
-
protected
|
237
|
-
|
238
|
-
def notification message
|
239
|
-
write message
|
240
|
-
puts "Identity #{@id_count} Got: #{message}"
|
241
|
-
end
|
242
|
-
def self.counter
|
243
|
-
@count ||= 0
|
244
|
-
@count += 1
|
245
|
-
end
|
246
|
-
|
247
|
-
end
|
248
|
-
|
249
|
-
module PleziTestTasks
|
250
|
-
module_function
|
251
|
-
|
252
|
-
|
253
|
-
RESULTS = {true => "\e[32mpassed\e[0m", :waiting => "\e[32mwaiting validation\e[0m", :failed => "\e[31mFAILED!\e[0m"}
|
254
|
-
RESULTS.default = RESULTS[:failed]
|
255
|
-
|
256
|
-
def run_tests
|
257
|
-
(public_methods(false)).each {|m| method(m).call if m.to_s.match /^test_/}
|
258
|
-
report_before_filter false
|
259
|
-
report_after_filter false
|
260
|
-
true
|
261
|
-
end
|
262
|
-
def test_sleep
|
263
|
-
Plezi.run do
|
264
|
-
begin
|
265
|
-
puts " * Sleeper test: #{RESULTS[URI.parse("http://localhost:3000/sleeper").read == 'slept']}"
|
266
|
-
puts " * ASync tasks test: #{RESULTS[true]}"
|
267
|
-
rescue => e
|
268
|
-
puts " **** Sleeper test FAILED TO RUN!!!"
|
269
|
-
puts e
|
270
|
-
end
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
def test_index
|
275
|
-
begin
|
276
|
-
puts " * Index test: #{RESULTS[URI.parse("http://localhost:3000/").read == 'test']}"
|
277
|
-
rescue => e
|
278
|
-
puts " **** Index test FAILED TO RUN!!!"
|
279
|
-
puts e
|
280
|
-
end
|
281
|
-
end
|
282
|
-
# # Starting with Iodine, Plezi can listen only to one port at a time, either SSL or NOT.
|
283
|
-
# def test_ssl
|
284
|
-
# puts " * Connection to non-ssl and unique route test: #{RESULTS[URI.parse("http://localhost:3000/ssl").read == 'false']}"
|
285
|
-
# uri = URI.parse("https://localhost:3030/ssl")
|
286
|
-
# Net::HTTP.start(uri.host, uri.port, use_ssl: (uri.scheme == "https"), verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
|
287
|
-
# puts " * Connection to ssl and unique ssl route test: #{RESULTS[ http.request(Net::HTTP::Get.new(uri)).body == 'true' ]}"
|
288
|
-
# end
|
289
|
-
# rescue => e
|
290
|
-
# puts " **** SSL Tests FAILED to complete!!!"
|
291
|
-
# puts e
|
292
|
-
# end
|
293
|
-
|
294
|
-
def test_new
|
295
|
-
puts " * New RESTful path test: #{RESULTS[URI.parse("http://localhost:3000/new").read == 'new']}"
|
296
|
-
|
297
|
-
rescue => e
|
298
|
-
puts " **** New RESTful path test FAILED TO RUN!!!"
|
299
|
-
puts e
|
300
|
-
end
|
301
|
-
def test_show
|
302
|
-
puts " * Show RESTful path test: #{RESULTS[URI.parse("http://localhost:3000/3").read == 'show 3']}"
|
303
|
-
|
304
|
-
rescue => e
|
305
|
-
puts " **** Show RESTful path test FAILED TO RUN!!!"
|
306
|
-
puts e
|
307
|
-
end
|
308
|
-
def test_update
|
309
|
-
puts " * Update RESTful path test: #{RESULTS[Net::HTTP.post_form( URI.parse("http://localhost:3000/"), id: 3).body == 'update 3']}"
|
310
|
-
|
311
|
-
rescue => e
|
312
|
-
puts " **** Update RESTful path test FAILED TO RUN!!!"
|
313
|
-
puts e.message
|
314
|
-
end
|
315
|
-
def test_delete
|
316
|
-
puts " * Delete RESTful path test: #{RESULTS[Net::HTTP.post_form( URI.parse("http://localhost:3000/"), id: 3, _method: :delete).body == 'delete 3']}"
|
317
|
-
|
318
|
-
rescue => e
|
319
|
-
puts " **** Delete RESTful path test FAILED TO RUN!!!"
|
320
|
-
puts e
|
321
|
-
end
|
322
|
-
def test_save
|
323
|
-
puts " * Save RESTful path test: #{RESULTS[Net::HTTP.post_form( URI.parse("http://localhost:3000/new"), data: "passed").body == 'passed']}"
|
324
|
-
|
325
|
-
rescue => e
|
326
|
-
puts " **** Save RESTful path test FAILED TO RUN!!!"
|
327
|
-
puts e
|
328
|
-
end
|
329
|
-
def test_streamed
|
330
|
-
begin
|
331
|
-
puts " * Streaming test: #{RESULTS[URI.parse("http://localhost:3000/streamer").read == 'streamed']}"
|
332
|
-
rescue => e
|
333
|
-
puts " **** Streaming test FAILED TO RUN #{e.message}!!!"
|
334
|
-
puts e
|
335
|
-
end
|
336
|
-
end
|
337
|
-
def test_url_for
|
338
|
-
test_url = "/some/path/test/my_url/ask"
|
339
|
-
puts " * simple #url_for test: #{RESULTS[(URI.parse("http://localhost:3000" + test_url).read == test_url) || puts("Got path: #{URI.parse("http://localhost:3000" + test_url).read}")]}"
|
340
|
-
test_url = "/some/another_path/my_url/ask"
|
341
|
-
puts " * missing arguments #url_for test: #{RESULTS[URI.parse("http://localhost:3000" + test_url).read == test_url]}"
|
342
|
-
|
343
|
-
rescue => e
|
344
|
-
puts " **** #url_for test FAILED TO RUN!!!"
|
345
|
-
puts e
|
346
|
-
end
|
347
|
-
def placebo_test
|
348
|
-
puts " * Starting placebo tests..."
|
349
|
-
ws = Iodine::Http::WebsocketClient.connect("ws://localhost:3000/ws/placebo") {|ws| 'ME?'}
|
350
|
-
ws << " * Placebo WS connected."
|
351
|
-
sleep 2
|
352
|
-
ws.close
|
353
|
-
rescue => e
|
354
|
-
puts " **** Placebo test FAILED TO RUN!!!"
|
355
|
-
puts e
|
356
|
-
end
|
357
|
-
def test_websocket
|
358
|
-
connection_test = broadcast_test = echo_test = unicast_test = nil
|
359
|
-
begin
|
360
|
-
ws4 = Iodine::Http::WebsocketClient.connect("ws://localhost:3000/") do |data|
|
361
|
-
if data == "unicast"
|
362
|
-
puts " * Websocket unicast testing: #{RESULTS[false]}"
|
363
|
-
unicast_test = :failed
|
364
|
-
end
|
365
|
-
end
|
366
|
-
ws2 = Iodine::Http::WebsocketClient.connect("ws://localhost:3000/") do |data|
|
367
|
-
next unless @is_connected || !( ( @is_connected = true ) == true )
|
368
|
-
if data == "unicast"
|
369
|
-
puts " * Websocket unicast message test: #{RESULTS[false]}"
|
370
|
-
unicast_test = :failed
|
371
|
-
next
|
372
|
-
else
|
373
|
-
puts " * Websocket broadcast message test: #{RESULTS[broadcast_test = (data == 'echo test')]}"
|
374
|
-
go_test = false
|
375
|
-
end
|
376
|
-
end
|
377
|
-
ws3 = Iodine::Http::WebsocketClient.connect("ws://localhost:3000/", on_open: -> { write 'get uuid' } ) do |data|
|
378
|
-
if data.match /uuid: ([^s]*)/
|
379
|
-
ws3 << "to: #{data.match(/^uuid: ([^s]*)/)[1]}"
|
380
|
-
puts " * Websocket UUID for unicast testing: #{data.match(/^uuid: ([^s]*)/)[1]}"
|
381
|
-
elsif data == "unicast"
|
382
|
-
puts " * Websocket unicast testing: #{RESULTS[:waiting]} (target received data)"
|
383
|
-
unicast_test ||= true
|
384
|
-
end
|
385
|
-
end
|
386
|
-
puts " * Websocket client test: #{RESULTS[ws2 && true]}"
|
387
|
-
ws1 = Iodine::Http::WebsocketClient.connect("ws://localhost:3000/") do |data|
|
388
|
-
unless @connected
|
389
|
-
puts " * Websocket connection message test: #{RESULTS[connection_test = (data == 'connected')]}"
|
390
|
-
@connected = true
|
391
|
-
write "echo test"
|
392
|
-
next
|
393
|
-
end
|
394
|
-
if data == "unicast"
|
395
|
-
puts " * Websocket unicast testing: #{RESULTS[false]}"
|
396
|
-
unicast_test = :failed
|
397
|
-
next
|
398
|
-
end
|
399
|
-
puts " * Websocket echo message test: #{RESULTS[echo_test = (data == 'echo test')]}"
|
400
|
-
end
|
401
|
-
|
402
|
-
rescue => e
|
403
|
-
puts " **** Websocket tests FAILED TO RUN!!!"
|
404
|
-
puts e.message
|
405
|
-
end
|
406
|
-
remote = Iodine::Http::WebsocketClient.connect("wss://echo.websocket.org/") {|data| puts " * Extra Websocket Remote test (SSL: echo.websocket.org): #{RESULTS[data == 'Hello websockets!']}"; close}
|
407
|
-
if remote.closed?
|
408
|
-
puts " * Extra Websocket Remote test (SSL: echo.websocket.org): #{RESULTS[false]}"
|
409
|
-
else
|
410
|
-
remote << "Hello websockets!"
|
411
|
-
end
|
412
|
-
Iodine.run_after(30) { [ws1, ws2, ws3, ws4, remote].each {|ws| ws.close} }
|
413
|
-
PL.on_shutdown {puts " * Websocket connection message test: #{RESULTS[connection_test]}" unless connection_test}
|
414
|
-
PL.on_shutdown {puts " * Websocket echo message test: #{RESULTS[echo_test]}" unless echo_test}
|
415
|
-
PL.on_shutdown {puts " * Websocket broadcast message test: #{RESULTS[broadcast_test]}" unless broadcast_test}
|
416
|
-
PL.on_shutdown {puts " * Websocket unicast message test: #{RESULTS[unicast_test]}"}
|
417
|
-
end
|
418
|
-
def test_websocket_sizes
|
419
|
-
should_disconnect = false
|
420
|
-
ws = Iodine::Http::WebsocketClient.connect("ws://localhost:3000/ws/size") do |data|
|
421
|
-
if should_disconnect
|
422
|
-
puts " * Websocket size disconnection test: #{RESULTS[false]}"
|
423
|
-
else
|
424
|
-
puts " * Websocket message size test: got #{data.bytesize} bytes starting with #{data[0..10]}"
|
425
|
-
end
|
426
|
-
end
|
427
|
-
ws.on_close do
|
428
|
-
puts " * Websocket size disconnection test: #{RESULTS[should_disconnect]}"
|
429
|
-
end
|
430
|
-
str = 'a'
|
431
|
-
time_now = Time.now
|
432
|
-
7.times {|i| str = str * 2**i;puts " * Websocket message size test: sending #{str.bytesize} bytes"; ws << str; }
|
433
|
-
str.clear
|
434
|
-
to_sleep = (Time.now - time_now)*2 + 1
|
435
|
-
puts "will now sleep for #{to_sleep} seconds, waiting allowing the server to respond"
|
436
|
-
sleep to_sleep rescue true
|
437
|
-
Plezi::Settings.ws_message_size_limit = 1024
|
438
|
-
should_disconnect = true
|
439
|
-
ws << ('0123'*258)
|
440
|
-
sleep 0.3
|
441
|
-
should_disconnect = false
|
442
|
-
end
|
443
|
-
def test_broadcast_stress
|
444
|
-
PlaceboStressTestCtrl.create_listeners
|
445
|
-
PlaceboStressTestCtrl.run_test
|
446
|
-
PlaceboStressTestCtrl.unicast ($failed_uuid = Plezi::Settings.uuid + PlaceboStressTestCtrl.object_id.to_s(16) ), :review
|
447
|
-
end
|
448
|
-
def test_404
|
449
|
-
puts " * 404 not found and router continuity tests: #{RESULTS[ Net::HTTP.get_response(URI.parse "http://localhost:3000/get404" ).code == '404' ]}"
|
450
|
-
|
451
|
-
rescue => e
|
452
|
-
puts " **** 404 not found test FAILED TO RUN!!!"
|
453
|
-
puts e
|
454
|
-
end
|
455
|
-
def test_500
|
456
|
-
puts " * 500 internal error test: #{RESULTS[ Net::HTTP.get_response(URI.parse "http://localhost:3000/fail" ).code == '500' ]}"
|
457
|
-
rescue => e
|
458
|
-
puts " **** 500 internal error test FAILED TO RUN!!!"
|
459
|
-
puts e
|
460
|
-
end
|
461
|
-
end
|
462
|
-
|
463
|
-
class PlaceboTestCtrl
|
464
|
-
# called when new Websocket data is recieved
|
465
|
-
#
|
466
|
-
# data is a string that contains binary or UTF8 (message dependent) data.
|
467
|
-
def index
|
468
|
-
false
|
469
|
-
end
|
470
|
-
def on_open
|
471
|
-
puts " * Placebo multicasting to placebo test: #{PleziTestTasks::RESULTS[ multicast :send_back, uuid: uuid, test: true, type: 'multicast' ] }"
|
472
|
-
end
|
473
|
-
def on_message data
|
474
|
-
puts data
|
475
|
-
end
|
476
|
-
def _get_uuid data
|
477
|
-
puts " * Placebo send #{data[:type]} test: #{PleziTestTasks::RESULTS[data[:test]]}"
|
478
|
-
unicast( data[:uuid], :send_back, {test: true, type: 'unicast'}) if data[:uuid]
|
479
|
-
end
|
480
|
-
end
|
481
|
-
|
482
|
-
class PlaceboCtrl
|
483
|
-
def send_back data
|
484
|
-
puts " * Placebo recieve test for #{data[:type]}: #{PleziTestTasks::RESULTS[data[:test]]}"
|
485
|
-
if data[:uuid]
|
486
|
-
unicast( data[:uuid], :_get_uuid, {test: true, uuid: uuid, type: 'unicast'})
|
487
|
-
else
|
488
|
-
broadcast WSsizeTestCtrl, :_get_uuid, test: true, type: 'broadcast'
|
489
|
-
multicast :_get_uuid, test: true, type: 'multicast'
|
490
|
-
end
|
491
|
-
end
|
492
|
-
end
|
493
|
-
|
494
|
-
|
495
|
-
class PlaceboStressTestCtrl
|
496
|
-
def review start_time, fin = false, uni = false
|
497
|
-
if fin
|
498
|
-
time_now = Time.now
|
499
|
-
average = (((time_now - start_time)*1.0/(LISTENERS*REPEATS))*1000.0).round(4)
|
500
|
-
total = (time_now - start_time).round(3)
|
501
|
-
puts " * Placebo stress test - Total of #{LISTENERS*REPEATS} events) finished in #{total} seconds"
|
502
|
-
puts " * Placebo stress test - average: (#{average} seconds per event."
|
503
|
-
PlaceboStressTestCtrl.run_unicast_test unless uni
|
504
|
-
end
|
505
|
-
end
|
506
|
-
def self.failed_unicast target, method, data
|
507
|
-
puts " * Unicasting failure callback testing: #{PleziTestTasks::RESULTS[$failed_uuid == target]}"
|
508
|
-
end
|
509
|
-
def self.run_test
|
510
|
-
puts "\n * Placebo Broadcast stress test starting - (#{LISTENERS} listening objects with #{REPEATS} messages."
|
511
|
-
start_time = Time.now
|
512
|
-
(REPEATS - 1).times {|i| PlaceboStressTestCtrl.broadcast :review, start_time}
|
513
|
-
PlaceboStressTestCtrl.unicast @uuid, :review, start_time, true
|
514
|
-
puts " * Placebo stress test - sending messages required: (#{Time.now - start_time} seconds."
|
515
|
-
end
|
516
|
-
def self.run_unicast_test
|
517
|
-
puts "\n * Placebo Unicast stress test starting - (#{LISTENERS} listening objects with #{REPEATS} messages."
|
518
|
-
start_time = Time.now
|
519
|
-
(REPEATS - 1).times {|i| PlaceboStressTestCtrl.unicast @uuid, :review, start_time, false, true}
|
520
|
-
PlaceboStressTestCtrl.unicast @uuid, :review, start_time, true, true
|
521
|
-
puts " * Placebo stress test - sending messages required: (#{Time.now - start_time} seconds."
|
522
|
-
end
|
523
|
-
def self.create_listeners
|
524
|
-
@uuid = nil
|
525
|
-
LISTENERS.times { @uuid = Plezi::Placebo.new(PlaceboStressTestCtrl).uuid }
|
526
|
-
sleep 0.5
|
527
|
-
puts " * Placebo creation test: #{PleziTestTasks::RESULTS[ Iodine.to_a.length >= LISTENERS ] }"
|
528
|
-
end
|
529
|
-
REPEATS = 1000
|
530
|
-
LISTENERS = 100
|
531
|
-
end
|
532
|
-
|
533
|
-
host
|
534
|
-
|
535
|
-
shared_route 'id/(:id)/(:message)', WSIdentity
|
536
|
-
|
537
|
-
shared_route 'ws/no', Nothing
|
538
|
-
shared_route 'ws/placebo', PlaceboTestCtrl
|
539
|
-
shared_route 'ws/size', WSsizeTestCtrl
|
540
|
-
shared_route '/some/:multi{path|another_path}/(:option){route|test}/(:id)/(:optional)', TestCtrl
|
541
|
-
shared_route '/', TestCtrl
|
542
|
-
|
543
|
-
|
544
|
-
mem_print_proc = Proc.new do
|
545
|
-
h = GC.stat.merge ObjectSpace.count_objects_size
|
546
|
-
ObjectSpace.each_object {|o| h[o.class] = h[o.class].to_i + 1}
|
547
|
-
puts (h.to_a.map {|i| i.join ': '} .join "\n")
|
548
|
-
h.clear
|
549
|
-
GC.start
|
550
|
-
end
|
551
|
-
# puts ("\n\n*** GC.stat:\n" + ((GC.stat.merge ObjectSpace.count_objects_size).to_a.map {|i| i.join ': '} .join "\n"))
|
552
|
-
# mem_print_proc.call
|
553
|
-
# Plezi.run_every 30, &mem_print_proc
|
554
|
-
|
555
|
-
# require 'redis'
|
556
|
-
# ENV['PL_REDIS_URL'] ||= ENV['REDIS_URL'] || ENV['REDISCLOUD_URL'] || ENV['REDISTOGO_URL'] || "redis://test:1234@pub-redis-11008.us-east-1-4.5.ec2.garantiadata.com:11008"
|
557
|
-
# Plezi.processes = 3
|
558
|
-
|
559
|
-
Plezi.threads = 9
|
560
|
-
PL.logger = nil
|
561
|
-
|
562
|
-
Plezi.run do
|
563
|
-
|
564
|
-
puts " --- Plezi #{Plezi::VERSION} will start a server, performing some tests."
|
565
|
-
puts " --- Starting tests"
|
566
|
-
puts " --- Failed tests should read: #{PleziTestTasks::RESULTS[false]}"
|
567
|
-
|
568
|
-
PleziTestTasks.run_tests
|
569
|
-
|
570
|
-
r = Plezi::Placebo.new PlaceboCtrl
|
571
|
-
puts " * Create Placebo test: #{PleziTestTasks::RESULTS[r && true]}"
|
572
|
-
puts " * Placebo admists to being placebo: #{PleziTestTasks::RESULTS[PlaceboCtrl.placebo?]}"
|
573
|
-
puts " * Regular controller answers placebo: #{PleziTestTasks::RESULTS[!PlaceboTestCtrl.placebo?]}"
|
574
|
-
PleziTestTasks.placebo_test
|
575
|
-
|
576
|
-
shoutdown_test = false
|
577
|
-
Plezi.on_shutdown { puts " * Shutdown test: #{ PleziTestTasks::RESULTS[shoutdown_test] }" }
|
578
|
-
Plezi.on_shutdown { shoutdown_test = true }
|
579
|
-
puts "Press ^C to exit."
|
580
|
-
|
581
|
-
end
|