plezi 0.11.2 → 0.12.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 +20 -0
- data/README.md +32 -33
- data/docs/async_helpers.md +90 -40
- data/docs/logging.md +38 -3
- data/docs/routes.md +177 -5
- data/docs/websockets.md +5 -0
- data/lib/plezi.rb +2 -10
- data/lib/plezi/common/api.rb +48 -101
- data/lib/plezi/common/defer.rb +4 -4
- data/lib/plezi/common/dsl.rb +13 -24
- data/lib/plezi/common/redis.rb +9 -5
- data/lib/plezi/common/settings.rb +4 -24
- data/lib/plezi/handlers/controller_core.rb +7 -14
- data/lib/plezi/handlers/controller_magic.rb +12 -10
- data/lib/plezi/handlers/http_router.rb +27 -22
- data/lib/plezi/handlers/placebo.rb +40 -33
- data/lib/plezi/handlers/route.rb +233 -234
- data/lib/plezi/handlers/session.rb +2 -2
- data/lib/plezi/handlers/stubs.rb +7 -0
- data/lib/plezi/handlers/ws_object.rb +25 -15
- data/lib/plezi/helpers/http_sender.rb +3 -3
- data/lib/plezi/helpers/magic_helpers.rb +3 -3
- data/lib/plezi/version.rb +1 -1
- data/plezi.gemspec +1 -1
- data/resources/config.ru +12 -18
- data/resources/environment.rb +6 -7
- data/resources/mini_app.rb +22 -22
- data/resources/redis_config.rb +4 -2
- data/test/plezi_tests.rb +76 -87
- data/websocket chatroom.md +3 -5
- metadata +6 -6
- data/docs/http_helpers.md +0 -9
@@ -5,7 +5,7 @@ module Plezi
|
|
5
5
|
# returns a session object
|
6
6
|
def fetch id
|
7
7
|
return Plezi::Session.new(id) if Plezi.redis # avoid a local cache if Redis is used.
|
8
|
-
|
8
|
+
Iodine::Http::SessionManager::FileSessionStorage.fetch id # use the tmp-file-session logic if Redis isn't present
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -90,5 +90,5 @@ module Plezi
|
|
90
90
|
|
91
91
|
end
|
92
92
|
end
|
93
|
-
|
93
|
+
Iodine::Http::SessionManager.storage = Plezi::Base::SessionStorage
|
94
94
|
end
|
data/lib/plezi/handlers/stubs.rb
CHANGED
@@ -120,6 +120,13 @@ module Plezi
|
|
120
120
|
response << data.to_s
|
121
121
|
end
|
122
122
|
|
123
|
+
# a CLASS level callback that will be called when a unicast doesn't find it's target.
|
124
|
+
#
|
125
|
+
# the lack of this callback being called does NOT imply that the unicast was processed without errors,
|
126
|
+
# it's only called if the target itself wasn't found.
|
127
|
+
def self.failed_unicast target, method, arguments_array
|
128
|
+
end
|
129
|
+
|
123
130
|
#####
|
124
131
|
## It is possible to use RESTful methods to help emulate long XHR pulling.
|
125
132
|
## a RESTful controller can also be a WebSockets controller (these are not exclusive qualities).
|
@@ -27,10 +27,9 @@ module Plezi
|
|
27
27
|
module InstanceMethods
|
28
28
|
public
|
29
29
|
# handles broadcasts / unicasts
|
30
|
-
def on_broadcast
|
31
|
-
data
|
32
|
-
|
33
|
-
GReactor.warn "Broadcast message unknown... falling back on base broadcasting"
|
30
|
+
def on_broadcast data
|
31
|
+
unless data.is_a?(Hash) && (data[:type] || data[:target]) && data[:method] && data[:data]
|
32
|
+
Iodine.warn "Broadcast message unknown... falling back on base broadcasting"
|
34
33
|
return super(data) if defined? super
|
35
34
|
return false
|
36
35
|
end
|
@@ -73,12 +72,10 @@ module Plezi
|
|
73
72
|
#
|
74
73
|
# This UUID is also used to make sure Radis broadcasts don't triger the
|
75
74
|
# boadcasting object's event.
|
76
|
-
def uuid
|
75
|
+
def uuid
|
77
76
|
return @uuid if @uuid
|
78
|
-
if
|
79
|
-
return (@uuid ||=
|
80
|
-
elsif @io
|
81
|
-
return (@uuid ||= (@io[:uuid] ||= SecureRandom.uuid) + Plezi::Settings.uuid)
|
77
|
+
if __get_io
|
78
|
+
return (@uuid ||= Plezi::Settings.uuid + @io.id)
|
82
79
|
end
|
83
80
|
nil
|
84
81
|
end
|
@@ -86,7 +83,7 @@ module Plezi
|
|
86
83
|
|
87
84
|
protected
|
88
85
|
def __get_io
|
89
|
-
@io ||= (@request ? @request
|
86
|
+
@io ||= (@request ? @request[:io] : nil)
|
90
87
|
end
|
91
88
|
end
|
92
89
|
module ClassMethods
|
@@ -111,6 +108,7 @@ module Plezi
|
|
111
108
|
@exposed_methods_list ||= ( (self.public_instance_methods - Class.new.instance_methods - Plezi::ControllerMagic::InstanceMethods.instance_methods - [:before, :after, :save, :show, :update, :delete, :initialize, :on_message, :on_broadcast, :pre_connect, :on_open, :on_close]).delete_if {|m| m.to_s[0] == '_'} ).to_set
|
112
109
|
@exposed_methods_list.include? method_name
|
113
110
|
end
|
111
|
+
|
114
112
|
protected
|
115
113
|
|
116
114
|
# a callback that resets the class router whenever a method (a potential route) is added
|
@@ -163,7 +161,7 @@ module Plezi
|
|
163
161
|
def unicast target_uuid, method_name, *args
|
164
162
|
raise 'No target specified for unicasting!' unless target_uuid
|
165
163
|
@@uuid_cutoff ||= Plezi::Settings.uuid.length
|
166
|
-
_inner_broadcast method: method_name, data: args, target: target_uuid[
|
164
|
+
_inner_broadcast method: method_name, data: args, target: target_uuid[@@uuid_cutoff..-1], to_server: target_uuid[0...@@uuid_cutoff], type: self
|
167
165
|
end
|
168
166
|
|
169
167
|
# Use this to multicast an event to ALL websocket connections on EVERY controller, including Placebo controllers.
|
@@ -183,9 +181,12 @@ module Plezi
|
|
183
181
|
# sends the broadcast
|
184
182
|
def _inner_broadcast data, ignore_io = nil
|
185
183
|
if data[:target]
|
186
|
-
|
184
|
+
if data[:target] && (data[:to_server] == Plezi::Settings.uuid )
|
185
|
+
return ( ::Iodine::Http::Websockets.unicast( data[:target], data ) || ___faild_unicast( data ) )
|
186
|
+
end
|
187
|
+
return ( data[:to_server].nil? && ::Iodine::Http::Websockets.unicast(data[:target], data) ) || ( Plezi::Base::AutoRedis.away?(data[:to_server]) && ___faild_unicast( data ) ) || __inner_redis_broadcast(data)
|
187
188
|
else
|
188
|
-
|
189
|
+
::Iodine::Http::Websockets.broadcast data, ignore_io
|
189
190
|
__inner_redis_broadcast data
|
190
191
|
end
|
191
192
|
true
|
@@ -194,16 +195,25 @@ module Plezi
|
|
194
195
|
def __inner_redis_broadcast data
|
195
196
|
return unless conn = Plezi.redis
|
196
197
|
data = data.dup
|
197
|
-
data[:type] = data[:type].name if data[:type]
|
198
|
+
data[:type] = data[:type].name if data[:type].is_a?(Class)
|
198
199
|
data[:server] = Plezi::Settings.uuid
|
199
|
-
return conn.publish( ( data[:to_server]
|
200
|
+
return conn.publish( ( data[:to_server] || Plezi::Settings.redis_channel_name ), data.to_yaml ) if conn
|
200
201
|
false
|
201
202
|
end
|
202
203
|
|
204
|
+
def ___faild_unicast data
|
205
|
+
has_class_method?(:failed_unicast) && failed_unicast( data[:to_server].to_s + data[:target], data[:method], data[:data] )
|
206
|
+
true
|
207
|
+
end
|
208
|
+
|
203
209
|
def has_method? method_name
|
204
210
|
@methods_list ||= self.instance_methods.to_set
|
205
211
|
@methods_list.include? method_name
|
206
212
|
end
|
213
|
+
def has_class_method? method_name
|
214
|
+
@class_methods_list ||= self.methods.to_set - Object.methods
|
215
|
+
@class_methods_list.include? method_name
|
216
|
+
end
|
207
217
|
end
|
208
218
|
end
|
209
219
|
end
|
@@ -18,7 +18,7 @@ module Plezi
|
|
18
18
|
# sends a response for an error code, rendering the relevent file (if exists).
|
19
19
|
def send_by_code request, response, code, headers = {}
|
20
20
|
begin
|
21
|
-
base_code_path = request
|
21
|
+
base_code_path = request[:host_settings][:templates] || File.expand_path('.')
|
22
22
|
fn = File.join(base_code_path, "#{code}.html")
|
23
23
|
rendered = ::Plezi::Renderer.render fn, binding #CodeContext.new(request)
|
24
24
|
return send_raw_data request, response, rendered, 'text/html', code, headers if rendered
|
@@ -34,14 +34,14 @@ module Plezi
|
|
34
34
|
#
|
35
35
|
# returns true if data was sent.
|
36
36
|
def send_static_file request, response
|
37
|
-
root = request
|
37
|
+
root = request[:host_settings][:public]
|
38
38
|
return false unless root
|
39
39
|
file_requested = request[:path].to_s.split('/')
|
40
40
|
unless file_requested.include? '..'
|
41
41
|
file_requested.shift
|
42
42
|
file_requested = File.join(root, *file_requested)
|
43
43
|
return true if send_file request, response, file_requested
|
44
|
-
return send_file request, response, File.join(file_requested, request
|
44
|
+
return send_file request, response, File.join(file_requested, request[:host_settings][:index_file])
|
45
45
|
end
|
46
46
|
false
|
47
47
|
end
|
@@ -32,7 +32,7 @@ module Plezi
|
|
32
32
|
(str.to_s.gsub(/[^a-z0-9\*\.\_\-]/i) {|m| '%%%02x'.freeze % m.ord }).force_encoding(::Encoding::ASCII_8BIT)
|
33
33
|
end
|
34
34
|
|
35
|
-
# Adds paramaters to a Hash object, according to the
|
35
|
+
# Adds paramaters to a Hash object, according to the Iodine's server conventions.
|
36
36
|
def self.add_param_to_hash name, value, target
|
37
37
|
begin
|
38
38
|
c = target
|
@@ -64,8 +64,8 @@ module Plezi
|
|
64
64
|
end
|
65
65
|
val
|
66
66
|
rescue => e
|
67
|
-
|
68
|
-
|
67
|
+
Iodine.error e
|
68
|
+
Iodine.error "(Silent): parameters parse error for #{name} ... maybe conflicts with a different set?"
|
69
69
|
target[name] = val
|
70
70
|
end
|
71
71
|
end
|
data/lib/plezi/version.rb
CHANGED
data/plezi.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "
|
21
|
+
spec.add_dependency "iodine", "~> 0.1.0"
|
22
22
|
spec.add_development_dependency "bundler", "~> 1.7"
|
23
23
|
spec.add_development_dependency "rake", "~> 10.0"
|
24
24
|
|
data/resources/config.ru
CHANGED
@@ -3,14 +3,11 @@
|
|
3
3
|
#
|
4
4
|
# using Rack with Plezi poses some limitations...:
|
5
5
|
#
|
6
|
-
# 1.
|
7
|
-
# (only the first `listen` call and all it's related `host` calls)
|
6
|
+
# 1. there is NO WebSockets support for Rack apps.
|
8
7
|
#
|
9
|
-
# 2.
|
8
|
+
# 2. this might break any streaming / asynchronous methods calls, such as Iodine's Http streaming.
|
10
9
|
#
|
11
|
-
# 3.
|
12
|
-
#
|
13
|
-
# 4. Plezi parameters and file uploads are different then Rack - HTML Form code might be incompatible!
|
10
|
+
# 3. Plezi parameters and file uploads are different then Rack - HTML Form code might be incompatible!
|
14
11
|
# This MIGHT BREAKE YOUR CODE! (changing this requires Plezi to re-parse the HTML, and costs in performance).
|
15
12
|
#
|
16
13
|
# also, all Plezi server specific configuration will be ignored.
|
@@ -21,8 +18,12 @@
|
|
21
18
|
#
|
22
19
|
# 2. you have better control over Middleware then you could have with Plezi.
|
23
20
|
# ("wait", you might say, "there is no Middleware in Plezi!"... "Ahhh", I will answer, "so much to discover...")
|
24
|
-
|
25
|
-
|
21
|
+
#
|
22
|
+
#
|
23
|
+
##############
|
24
|
+
#
|
25
|
+
# For now, Rack mode is NOT supported unless using the Iodine Http server,
|
26
|
+
# even than you're 404 not found pages will break unless using a catch-all route.
|
26
27
|
|
27
28
|
# load all framework and gems
|
28
29
|
load ::File.expand_path(File.join("..", "environment.rb"), __FILE__)
|
@@ -31,15 +32,8 @@ load ::File.expand_path(File.join("..", "environment.rb"), __FILE__)
|
|
31
32
|
load ::File.expand_path(File.join("..", "routes.rb"), __FILE__)
|
32
33
|
|
33
34
|
# start the plezi EM, to make sure that the plezi async code doesn't break.
|
34
|
-
if Rack::Handler.default ==
|
35
|
-
run(Proc.new { [404, {}, []] })
|
35
|
+
if Rack::Handler.default == Iodine::Http::Rack
|
36
|
+
run(Proc.new { [404, {}, ["not found"]] })
|
36
37
|
else
|
37
|
-
|
38
|
-
GReactor.start Plezi::Settings.max_threads
|
39
|
-
|
40
|
-
# run the Rack app - not yet supported
|
41
|
-
# run Plezi::Base::Rack
|
42
|
-
|
43
|
-
# # exit rack to start the plezi server
|
44
|
-
# Process.kill 'TERM'
|
38
|
+
raise "Unsupported Server - Plezi only runs using Iodine."
|
45
39
|
end
|
data/resources/environment.rb
CHANGED
@@ -24,13 +24,13 @@ Bundler.require(:default, ENV['ENV'].to_s.to_sym)
|
|
24
24
|
require 'tilt/sass' if defined?(::Slim) && defined?(::Sass)
|
25
25
|
|
26
26
|
# set up Plezi's logs - Heroku logs to STDOUT, this machine logs to log file
|
27
|
-
|
27
|
+
Iodine.logger = Logger.new(File.expand_path(File.join 'logs','server.log'))
|
28
28
|
|
29
29
|
# set the session token name
|
30
|
-
|
30
|
+
Iodine::Http.session_token = 'appname_uui'
|
31
31
|
|
32
32
|
## Allow forking? ONLY if your code is fully scalable across processes.
|
33
|
-
#
|
33
|
+
# Iodine.processes = 4
|
34
34
|
|
35
35
|
# load all config files
|
36
36
|
Dir[File.join "{config}", "**" , "*.rb"].each {|file| load File.expand_path(file)}
|
@@ -41,10 +41,9 @@ Dir[File.join "{lib}", "**" , "*.rb"].each {|file| load File.expand_path(file)}
|
|
41
41
|
# load all application files
|
42
42
|
Dir[File.join "{app}", "**" , "*.rb"].each {|file| load File.expand_path(file)}
|
43
43
|
|
44
|
-
#
|
45
|
-
|
46
|
-
|
44
|
+
# change some of the default settings here.
|
45
|
+
host :default,
|
46
|
+
public: Root.join('public').to_s,
|
47
47
|
assets: Root.join('assets').to_s,
|
48
48
|
assets_public: '/assets',
|
49
49
|
templates: Root.join('app','views').to_s,
|
50
|
-
ssl: false
|
data/resources/mini_app.rb
CHANGED
@@ -5,14 +5,12 @@
|
|
5
5
|
require 'pathname'
|
6
6
|
## Set up root object, it might be used by the environment and\or the plezi extension gems.
|
7
7
|
Root ||= Pathname.new(File.dirname(__FILE__)).expand_path
|
8
|
-
|
8
|
+
|
9
9
|
## If this app is independant, use bundler to load gems (including the plezi gem).
|
10
|
-
##
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
# Plesi.start_rack # remember
|
15
|
-
GRHttp.session_token = 'appname_uui'
|
10
|
+
## otherwise, use the original app's Gemfile and start Plezi's Rack mode.
|
11
|
+
require 'bundler'
|
12
|
+
Bundler.require(:default, ENV['ENV'].to_s.to_sym)
|
13
|
+
|
16
14
|
## make sure all file access and file loading is relative to the application's root folder
|
17
15
|
# Dir.chdir Root.to_s
|
18
16
|
## load code from a subfolder called 'app'
|
@@ -21,14 +19,18 @@
|
|
21
19
|
# Dir[File.join File.dirname(__FILE__), "*.rb"].each {|file| load File.expand_path(file) unless file == __FILE__}
|
22
20
|
|
23
21
|
## Uncomment to create a log file
|
24
|
-
#
|
22
|
+
# Iodine.logger = Logger.new File.expand_path(Root.join('server.log').to_s)
|
25
23
|
|
26
|
-
|
27
|
-
|
28
|
-
#
|
29
|
-
|
24
|
+
# # Options for Scaling the app (across processes or machines):
|
25
|
+
# # uncomment to set up forking for 3 more processes (total of 4).
|
26
|
+
# Iodine.processes = 4
|
27
|
+
#
|
28
|
+
# # Redis scaling
|
30
29
|
# Plezi::Settings.redis_channel_name = 'appsecret'
|
31
30
|
# ENV['PL_REDIS_URL'] ||= ENV['REDIS_URL'] || ENV['REDISCLOUD_URL'] || ENV['REDISTOGO_URL'] || "redis://username:password@my.host:6389"
|
31
|
+
#
|
32
|
+
# # Consider setting a common session token for Redis supported sessions.
|
33
|
+
# Iodine::Http.session_token = 'appname_uui'
|
32
34
|
|
33
35
|
|
34
36
|
# The basic appname controller, to get you started
|
@@ -60,19 +62,17 @@ class MyController
|
|
60
62
|
end
|
61
63
|
|
62
64
|
|
63
|
-
#
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
# public: Root.join('public').to_s,
|
69
|
-
ssl: false
|
65
|
+
# change some of the default settings here.
|
66
|
+
host :default,
|
67
|
+
# public: Root.join('public').to_s,
|
68
|
+
assets: Root.join('assets').to_s,
|
69
|
+
templates: Root.join('templates').to_s
|
70
70
|
|
71
|
-
|
72
|
-
|
71
|
+
# # Optional stuff:
|
72
|
+
# # I18n re-write, i.e.: `/en/home` will be rewriten as `/home`, while setting params[:locale] to "en"
|
73
73
|
# route "/:locale{#{I18n.available_locales.join "|"}}/*" , false if defined? I18n
|
74
74
|
#
|
75
|
-
|
75
|
+
# # OAuth2 - Facebook / Google authentication
|
76
76
|
# require 'plezi/oauth'
|
77
77
|
# ENV["FB_APP_ID"] ||= "app id"; ENV["FB_APP_SECRET"] ||= "secret"; ENV['GOOGLE_APP_ID'] = "app id"; ENV['GOOGLE_APP_SECRET'] = "secret"
|
78
78
|
# create_auth_shared_route do |service_name, auth_token, remote_user_id, remote_user_email, remote_response|
|
data/resources/redis_config.rb
CHANGED
@@ -10,9 +10,11 @@ if defined? Redis
|
|
10
10
|
# ## Sets up Plezi to use Radis broadcast.
|
11
11
|
# ##
|
12
12
|
# ## If Plezi Redis Automation is enabled:
|
13
|
-
# ## Plezi creates is own listening thread for each Controller class that broadcasts using Redis.
|
13
|
+
# ## Plezi creates is own listening thread that listens for each Controller class that broadcasts using Redis.
|
14
14
|
# ## (using the Controller.redis_connection and Controller.redis_channel_name class methods)
|
15
15
|
# ##
|
16
|
+
# ## Only one thread will be created and initiated during startup (dynamically created controller routes might be ignored).
|
17
|
+
# ##
|
16
18
|
# ## this overrides the default Controller#broadcast method which is very powerful but
|
17
19
|
# ## is limited to one process.
|
18
20
|
# ##
|
@@ -33,7 +35,7 @@ if defined? Redis
|
|
33
35
|
# on.message do |channel, msg|
|
34
36
|
# msg = JSON.parse(msg)
|
35
37
|
# # do stuff, i.e.:
|
36
|
-
# # Plezi.
|
38
|
+
# # Plezi.run(msg) { |m| Plezi.info m.to_s }
|
37
39
|
# end
|
38
40
|
# end
|
39
41
|
# end
|
data/test/plezi_tests.rb
CHANGED
@@ -103,6 +103,11 @@ class TestCtrl
|
|
103
103
|
############
|
104
104
|
## WebSockets
|
105
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
|
+
|
106
111
|
# called once the websocket was connected
|
107
112
|
def on_open
|
108
113
|
response << "connected"
|
@@ -116,7 +121,7 @@ class TestCtrl
|
|
116
121
|
when 'get uuid'
|
117
122
|
response << "uuid: #{uuid}"
|
118
123
|
when /to: ([^\s]*)/
|
119
|
-
# puts "
|
124
|
+
# puts "unicasting to target: #{data.match(/to: ([^\s]*)/)[1]}"
|
120
125
|
unicast data.match(/to: ([^\s]*)/)[1], :_push, "unicast"
|
121
126
|
# broadcast :_push, "unicast"
|
122
127
|
else
|
@@ -131,6 +136,10 @@ class TestCtrl
|
|
131
136
|
def on_close
|
132
137
|
end
|
133
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
|
+
|
134
143
|
# a demo event method that recieves a broadcast from instance siblings.
|
135
144
|
def _push data
|
136
145
|
response << data.to_s
|
@@ -160,7 +169,7 @@ module PleziTestTasks
|
|
160
169
|
true
|
161
170
|
end
|
162
171
|
def test_sleep
|
163
|
-
Plezi.
|
172
|
+
Plezi.run do
|
164
173
|
begin
|
165
174
|
puts " * Sleeper test: #{RESULTS[URI.parse("http://localhost:3000/sleeper").read == 'slept']}"
|
166
175
|
puts " * ASync tasks test: #{RESULTS[true]}"
|
@@ -179,16 +188,18 @@ module PleziTestTasks
|
|
179
188
|
puts e
|
180
189
|
end
|
181
190
|
end
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
191
|
+
# # Starting with Iodine, Plezi can listen only to one port at a time, either SSL or NOT.
|
192
|
+
# def test_ssl
|
193
|
+
# puts " * Connection to non-ssl and unique route test: #{RESULTS[URI.parse("http://localhost:3000/ssl").read == 'false']}"
|
194
|
+
# uri = URI.parse("https://localhost:3030/ssl")
|
195
|
+
# Net::HTTP.start(uri.host, uri.port, use_ssl: (uri.scheme == "https"), verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
|
196
|
+
# puts " * Connection to ssl and unique ssl route test: #{RESULTS[ http.request(Net::HTTP::Get.new(uri)).body == 'true' ]}"
|
197
|
+
# end
|
198
|
+
# rescue => e
|
199
|
+
# puts " **** SSL Tests FAILED to complete!!!"
|
200
|
+
# puts e
|
201
|
+
# end
|
202
|
+
|
192
203
|
def test_new
|
193
204
|
puts " * New RESTful path test: #{RESULTS[URI.parse("http://localhost:3000/new").read == 'new']}"
|
194
205
|
|
@@ -244,7 +255,7 @@ module PleziTestTasks
|
|
244
255
|
end
|
245
256
|
def test_placebo
|
246
257
|
puts " * Starting placebo tests..."
|
247
|
-
ws =
|
258
|
+
ws = Iodine::Http::WebsocketClient.connect("ws://localhost:3000/ws/placebo") {|ws| 'ME?'}
|
248
259
|
ws << " * Placebo WS connected."
|
249
260
|
sleep 2
|
250
261
|
ws.close
|
@@ -255,54 +266,53 @@ module PleziTestTasks
|
|
255
266
|
def test_websocket
|
256
267
|
connection_test = broadcast_test = echo_test = unicast_test = false
|
257
268
|
begin
|
258
|
-
ws4 =
|
259
|
-
if
|
269
|
+
ws4 = Iodine::Http::WebsocketClient.connect("ws://localhost:3000") do |data|
|
270
|
+
if data == "unicast"
|
260
271
|
puts " * Websocket unicast testing: #{RESULTS[false]}"
|
261
272
|
unicast_test = :failed
|
262
273
|
end
|
263
274
|
end
|
264
|
-
ws2 =
|
265
|
-
next unless @is_connected || !(@is_connected = true)
|
266
|
-
if
|
275
|
+
ws2 = Iodine::Http::WebsocketClient.connect("ws://localhost:3000") do |data|
|
276
|
+
next unless @is_connected || !( (@is_connected = true) )
|
277
|
+
if data == "unicast"
|
267
278
|
puts " * Websocket unicast message test: #{RESULTS[false]}"
|
268
279
|
unicast_test = :failed
|
269
280
|
next
|
270
281
|
else
|
271
|
-
puts " * Websocket broadcast message test: #{RESULTS[broadcast_test = (
|
282
|
+
puts " * Websocket broadcast message test: #{RESULTS[broadcast_test = (data == 'echo test')]}"
|
272
283
|
go_test = false
|
273
284
|
end
|
274
285
|
end
|
275
|
-
ws3 =
|
276
|
-
if
|
277
|
-
ws2 << "to: #{
|
278
|
-
puts " * Websocket UUID for unicast testing: #{
|
279
|
-
elsif
|
286
|
+
ws3 = Iodine::Http::WebsocketClient.connect("ws://localhost:3000", on_open: -> { write 'get uuid' } ) do |data|
|
287
|
+
if data.match /uuid: ([^s]*)/
|
288
|
+
ws2 << "to: #{data.match(/^uuid: ([^s]*)/)[1]}"
|
289
|
+
puts " * Websocket UUID for unicast testing: #{data.match(/^uuid: ([^s]*)/)[1]}"
|
290
|
+
elsif data == "unicast"
|
280
291
|
puts " * Websocket unicast testing: #{RESULTS[:waiting]}"
|
281
292
|
unicast_test ||= true
|
282
293
|
end
|
283
294
|
end
|
284
|
-
|
285
|
-
|
286
|
-
ws1 = GRHttp::WSClient.connect_to("ws://localhost:3000") do |ws|
|
295
|
+
puts " * Websocket client test: #{RESULTS[ws2 && true]}"
|
296
|
+
ws1 = Iodine::Http::WebsocketClient.connect("ws://localhost:3000") do |data|
|
287
297
|
unless @connected
|
288
|
-
puts " * Websocket connection message test: #{RESULTS[connection_test = (
|
298
|
+
puts " * Websocket connection message test: #{RESULTS[connection_test = (data == 'connected')]}"
|
289
299
|
@connected = true
|
290
|
-
|
300
|
+
write "echo test"
|
291
301
|
next
|
292
302
|
end
|
293
|
-
if
|
303
|
+
if data == "unicast"
|
294
304
|
puts " * Websocket unicast testing: #{RESULTS[false]}"
|
295
305
|
unicast_test = :failed
|
296
306
|
next
|
297
307
|
end
|
298
|
-
puts " * Websocket echo message test: #{RESULTS[echo_test = (
|
308
|
+
puts " * Websocket echo message test: #{RESULTS[echo_test = (data == 'echo test')]}"
|
299
309
|
end
|
300
310
|
|
301
311
|
rescue => e
|
302
312
|
puts " **** Websocket tests FAILED TO RUN!!!"
|
303
313
|
puts e.message
|
304
314
|
end
|
305
|
-
remote =
|
315
|
+
remote = Iodine::Http::WebsocketClient.connect("wss://echo.websocket.org/") {|data| puts " * Extra Websocket Remote test (SSL: echo.websocket.org): #{RESULTS[data == 'Hello websockets!']}"; close}
|
306
316
|
if remote.closed?
|
307
317
|
puts " * Extra Websocket Remote test (SSL: echo.websocket.org): #{RESULTS[false]}"
|
308
318
|
else
|
@@ -317,13 +327,12 @@ module PleziTestTasks
|
|
317
327
|
end
|
318
328
|
def test_websocket_sizes
|
319
329
|
should_disconnect = false
|
320
|
-
ws =
|
330
|
+
ws = Iodine::Http::WebsocketClient.connect("ws://localhost:3000/ws/size") do |data|
|
321
331
|
if should_disconnect
|
322
332
|
puts " * Websocket size disconnection test: #{RESULTS[false]}"
|
323
333
|
else
|
324
|
-
puts " * Websocket message size test: got #{
|
334
|
+
puts " * Websocket message size test: got #{data.bytesize} bytes"
|
325
335
|
end
|
326
|
-
|
327
336
|
end
|
328
337
|
ws.on_close do
|
329
338
|
puts " * Websocket size disconnection test: #{RESULTS[should_disconnect]}"
|
@@ -335,13 +344,16 @@ module PleziTestTasks
|
|
335
344
|
to_sleep = (Time.now - time_now)*2 + 1
|
336
345
|
puts "will now sleep for #{to_sleep} seconds, waiting allowing the server to respond"
|
337
346
|
sleep to_sleep rescue true
|
338
|
-
should_disconnect = true
|
339
347
|
Plezi::Settings.ws_message_size_limit = 1024
|
348
|
+
should_disconnect = true
|
340
349
|
ws << ('0123'*258)
|
350
|
+
sleep 0.3
|
351
|
+
should_disconnect = false
|
341
352
|
end
|
342
353
|
def test_broadcast_stress
|
343
354
|
PlaceboStressTestCtrl.create_listeners
|
344
355
|
PlaceboStressTestCtrl.run_test
|
356
|
+
PlaceboStressTestCtrl.unicast ($failed_uuid = Plezi::Settings.uuid + PlaceboStressTestCtrl.object_id.to_s(16) ), :review
|
345
357
|
end
|
346
358
|
def test_404
|
347
359
|
puts " * 404 not found and router continuity tests: #{RESULTS[ Net::HTTP.get_response(URI.parse "http://localhost:3000/get404" ).code == '404' ]}"
|
@@ -351,14 +363,7 @@ module PleziTestTasks
|
|
351
363
|
puts e
|
352
364
|
end
|
353
365
|
def test_500
|
354
|
-
|
355
|
-
print " * 500 internal error test: #{RESULTS[ Net::HTTP.get_response(URI.parse "http://localhost:3000/fail" ).code == '500' ]}"
|
356
|
-
# cause 10 more exceptions to be raised... testing thread survival.
|
357
|
-
10.times { putc "."; Net::HTTP.get_response(URI.parse "http://localhost:3000/fail" ).code }
|
358
|
-
putc "\n"
|
359
|
-
workers_after_test = GReactor.instance_exec {@threads.select {|t| t.alive?} .count}
|
360
|
-
puts " * Worker survival test: #{RESULTS[workers_after_test == workers]} (#{workers_after_test} out of #{workers})"
|
361
|
-
|
366
|
+
puts " * 500 internal error test: #{RESULTS[ Net::HTTP.get_response(URI.parse "http://localhost:3000/fail" ).code == '500' ]}"
|
362
367
|
rescue => e
|
363
368
|
puts " **** 500 internal error test FAILED TO RUN!!!"
|
364
369
|
puts e
|
@@ -408,6 +413,9 @@ class PlaceboStressTestCtrl
|
|
408
413
|
PlaceboStressTestCtrl.run_unicast_test unless uni
|
409
414
|
end
|
410
415
|
end
|
416
|
+
def self.failed_unicast target, method, data
|
417
|
+
puts " * Unicasting failure callback testing: #{PleziTestTasks::RESULTS[$failed_uuid == target]}"
|
418
|
+
end
|
411
419
|
def self.run_test
|
412
420
|
puts "\n * Placebo Broadcast stress test starting - (#{LISTENERS} listening objects with #{REPEATS} messages."
|
413
421
|
start_time = Time.now
|
@@ -424,28 +432,19 @@ class PlaceboStressTestCtrl
|
|
424
432
|
end
|
425
433
|
def self.create_listeners
|
426
434
|
@uuid = nil
|
427
|
-
LISTENERS.times {@uuid = Plezi::Placebo.new(PlaceboStressTestCtrl).uuid}
|
435
|
+
LISTENERS.times { @uuid = Plezi::Placebo.new(PlaceboStressTestCtrl).uuid }
|
436
|
+
sleep 0.5
|
437
|
+
puts " * Placebo creation test: #{PleziTestTasks::RESULTS[ Iodine.to_a.length >= LISTENERS ] }"
|
428
438
|
end
|
429
439
|
REPEATS = 1000
|
430
|
-
LISTENERS =
|
440
|
+
LISTENERS = 100
|
431
441
|
end
|
432
442
|
|
433
|
-
|
434
|
-
# PL::Settings.max_threads = 4
|
435
|
-
|
436
|
-
listen port: 3000
|
437
|
-
|
438
|
-
route("/ssl") {|req, res| res << "false" }
|
439
|
-
listen port: 3030, ssl: true
|
440
|
-
route("/ssl") {|req, res| res << "true" }
|
443
|
+
host
|
441
444
|
|
442
445
|
shared_route 'ws/no', Nothing
|
443
446
|
shared_route 'ws/placebo', PlaceboTestCtrl
|
444
447
|
shared_route 'ws/size', WSsizeTestCtrl
|
445
|
-
|
446
|
-
|
447
|
-
# puts Nothing.ancestors.join "\n"
|
448
|
-
|
449
448
|
shared_route '/some/:multi{path|another_path}/(:option){route|test}/(:id)/(:optional)', TestCtrl
|
450
449
|
shared_route '/', TestCtrl
|
451
450
|
|
@@ -459,40 +458,30 @@ mem_print_proc = Proc.new do
|
|
459
458
|
end
|
460
459
|
# puts ("\n\n*** GC.stat:\n" + ((GC.stat.merge ObjectSpace.count_objects_size).to_a.map {|i| i.join ': '} .join "\n"))
|
461
460
|
# mem_print_proc.call
|
462
|
-
#
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
puts " --- Plezi will ran async, performing some tests that than hang"
|
468
|
-
|
469
|
-
puts " --- Starting tests"
|
470
|
-
puts " --- Failed tests should read: #{PleziTestTasks::RESULTS[false]}"
|
471
|
-
|
472
|
-
r = Plezi::Placebo.new PlaceboCtrl
|
473
|
-
puts " * Create Placebo test: #{PleziTestTasks::RESULTS[r && true]}"
|
474
|
-
puts " * Placebo admists to being placebo: #{PleziTestTasks::RESULTS[PlaceboCtrl.placebo?]}"
|
475
|
-
puts " * Regular controller answers placebo: #{PleziTestTasks::RESULTS[!PlaceboTestCtrl.placebo?]}"
|
476
|
-
|
477
|
-
|
478
|
-
Plezi.start_async
|
479
|
-
PleziTestTasks.run_tests
|
461
|
+
# Plezi.run_every 30, &mem_print_proc
|
480
462
|
|
463
|
+
# require 'redis'
|
481
464
|
# 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"
|
482
|
-
#
|
483
|
-
# GR.run_async { PleziTestTasks.run_tests }
|
484
|
-
# start_services
|
485
|
-
|
486
|
-
shoutdown_test = false
|
487
|
-
Plezi.on_shutdown { shoutdown_test = true }
|
465
|
+
# Plezi.processes = 3
|
488
466
|
|
489
|
-
|
490
|
-
|
491
|
-
# Plezi::EventMachine.clear_timers
|
467
|
+
Plezi.threads = 9
|
468
|
+
PL.logger = nil
|
492
469
|
|
493
|
-
|
470
|
+
Plezi.run do
|
494
471
|
|
472
|
+
puts " --- Plezi #{Plezi::VERSION} will start a server, performing some tests."
|
473
|
+
puts " --- Starting tests"
|
474
|
+
puts " --- Failed tests should read: #{PleziTestTasks::RESULTS[false]}"
|
495
475
|
|
496
|
-
|
476
|
+
r = Plezi::Placebo.new PlaceboCtrl
|
477
|
+
puts " * Create Placebo test: #{PleziTestTasks::RESULTS[r && true]}"
|
478
|
+
puts " * Placebo admists to being placebo: #{PleziTestTasks::RESULTS[PlaceboCtrl.placebo?]}"
|
479
|
+
puts " * Regular controller answers placebo: #{PleziTestTasks::RESULTS[!PlaceboTestCtrl.placebo?]}"
|
497
480
|
|
481
|
+
PleziTestTasks.run_tests
|
498
482
|
|
483
|
+
shoutdown_test = false
|
484
|
+
Plezi.on_shutdown { puts " * Shutdown test: #{ PleziTestTasks::RESULTS[shoutdown_test] }" }
|
485
|
+
Plezi.on_shutdown { shoutdown_test = true }
|
486
|
+
|
487
|
+
end
|