cuboid 0.0.0 → 0.0.1alpha
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 +0 -0
- data/Gemfile +20 -5
- data/LICENSE.md +22 -0
- data/README.md +158 -19
- data/Rakefile +56 -3
- data/config/paths.yml +15 -0
- data/cuboid.gemspec +61 -23
- data/lib/cuboid.rb +96 -4
- data/lib/cuboid/application.rb +326 -0
- data/lib/cuboid/application/parts/data.rb +18 -0
- data/lib/cuboid/application/parts/report.rb +29 -0
- data/lib/cuboid/application/parts/state.rb +274 -0
- data/lib/cuboid/application/runtime.rb +25 -0
- data/lib/cuboid/banner.rb +13 -0
- data/lib/cuboid/data.rb +86 -0
- data/lib/cuboid/data/application.rb +52 -0
- data/lib/cuboid/error.rb +9 -0
- data/lib/cuboid/option_group.rb +129 -0
- data/lib/cuboid/option_groups.rb +8 -0
- data/lib/cuboid/option_groups/datastore.rb +23 -0
- data/lib/cuboid/option_groups/dispatcher.rb +38 -0
- data/lib/cuboid/option_groups/output.rb +14 -0
- data/lib/cuboid/option_groups/paths.rb +184 -0
- data/lib/cuboid/option_groups/report.rb +39 -0
- data/lib/cuboid/option_groups/rpc.rb +105 -0
- data/lib/cuboid/option_groups/scheduler.rb +27 -0
- data/lib/cuboid/option_groups/snapshot.rb +13 -0
- data/lib/cuboid/option_groups/system.rb +10 -0
- data/lib/cuboid/options.rb +254 -0
- data/lib/cuboid/processes.rb +13 -0
- data/lib/cuboid/processes/dispatchers.rb +140 -0
- data/lib/cuboid/processes/executables/base.rb +54 -0
- data/lib/cuboid/processes/executables/dispatcher.rb +5 -0
- data/lib/cuboid/processes/executables/instance.rb +12 -0
- data/lib/cuboid/processes/executables/rest_service.rb +13 -0
- data/lib/cuboid/processes/executables/scheduler.rb +5 -0
- data/lib/cuboid/processes/helpers.rb +4 -0
- data/lib/cuboid/processes/helpers/dispatchers.rb +23 -0
- data/lib/cuboid/processes/helpers/instances.rb +39 -0
- data/lib/cuboid/processes/helpers/processes.rb +23 -0
- data/lib/cuboid/processes/helpers/schedulers.rb +23 -0
- data/lib/cuboid/processes/instances.rb +203 -0
- data/lib/cuboid/processes/manager.rb +262 -0
- data/lib/cuboid/processes/schedulers.rb +128 -0
- data/lib/cuboid/report.rb +220 -0
- data/lib/cuboid/rest/server.rb +165 -0
- data/lib/cuboid/rest/server/instance_helpers.rb +99 -0
- data/lib/cuboid/rest/server/routes/dispatcher.rb +41 -0
- data/lib/cuboid/rest/server/routes/grid.rb +41 -0
- data/lib/cuboid/rest/server/routes/instances.rb +131 -0
- data/lib/cuboid/rest/server/routes/scheduler.rb +140 -0
- data/lib/cuboid/rpc/client.rb +3 -0
- data/lib/cuboid/rpc/client/base.rb +58 -0
- data/lib/cuboid/rpc/client/dispatcher.rb +58 -0
- data/lib/cuboid/rpc/client/instance.rb +100 -0
- data/lib/cuboid/rpc/client/instance/service.rb +37 -0
- data/lib/cuboid/rpc/client/scheduler.rb +46 -0
- data/lib/cuboid/rpc/serializer.rb +92 -0
- data/lib/cuboid/rpc/server/active_options.rb +38 -0
- data/lib/cuboid/rpc/server/application_wrapper.rb +138 -0
- data/lib/cuboid/rpc/server/base.rb +63 -0
- data/lib/cuboid/rpc/server/dispatcher.rb +317 -0
- data/lib/cuboid/rpc/server/dispatcher/node.rb +247 -0
- data/lib/cuboid/rpc/server/dispatcher/service.rb +145 -0
- data/lib/cuboid/rpc/server/instance.rb +338 -0
- data/lib/cuboid/rpc/server/output.rb +92 -0
- data/lib/cuboid/rpc/server/scheduler.rb +482 -0
- data/lib/cuboid/ruby.rb +4 -0
- data/lib/cuboid/ruby/array.rb +17 -0
- data/lib/cuboid/ruby/hash.rb +41 -0
- data/lib/cuboid/ruby/object.rb +32 -0
- data/lib/cuboid/snapshot.rb +186 -0
- data/lib/cuboid/state.rb +94 -0
- data/lib/cuboid/state/application.rb +309 -0
- data/lib/cuboid/state/options.rb +27 -0
- data/lib/cuboid/support.rb +11 -0
- data/lib/cuboid/support/buffer.rb +3 -0
- data/lib/cuboid/support/buffer/autoflush.rb +61 -0
- data/lib/cuboid/support/buffer/base.rb +91 -0
- data/lib/cuboid/support/cache.rb +7 -0
- data/lib/cuboid/support/cache/base.rb +226 -0
- data/lib/cuboid/support/cache/least_cost_replacement.rb +77 -0
- data/lib/cuboid/support/cache/least_recently_pushed.rb +21 -0
- data/lib/cuboid/support/cache/least_recently_used.rb +31 -0
- data/lib/cuboid/support/cache/preference.rb +31 -0
- data/lib/cuboid/support/cache/random_replacement.rb +20 -0
- data/lib/cuboid/support/crypto.rb +2 -0
- data/lib/cuboid/support/crypto/rsa_aes_cbc.rb +86 -0
- data/lib/cuboid/support/database.rb +5 -0
- data/lib/cuboid/support/database/base.rb +177 -0
- data/lib/cuboid/support/database/categorized_queue.rb +195 -0
- data/lib/cuboid/support/database/hash.rb +300 -0
- data/lib/cuboid/support/database/queue.rb +149 -0
- data/lib/cuboid/support/filter.rb +3 -0
- data/lib/cuboid/support/filter/base.rb +110 -0
- data/lib/cuboid/support/filter/set.rb +29 -0
- data/lib/cuboid/support/glob.rb +27 -0
- data/lib/cuboid/support/mixins.rb +8 -0
- data/lib/cuboid/support/mixins/observable.rb +99 -0
- data/lib/cuboid/support/mixins/parts.rb +20 -0
- data/lib/cuboid/support/mixins/profiler.rb +93 -0
- data/lib/cuboid/support/mixins/spec_instances.rb +65 -0
- data/lib/cuboid/support/mixins/terminal.rb +57 -0
- data/lib/cuboid/system.rb +119 -0
- data/lib/cuboid/system/platforms.rb +84 -0
- data/lib/cuboid/system/platforms/linux.rb +26 -0
- data/lib/cuboid/system/platforms/mixins/unix.rb +46 -0
- data/lib/cuboid/system/platforms/osx.rb +25 -0
- data/lib/cuboid/system/platforms/windows.rb +81 -0
- data/lib/cuboid/system/slots.rb +143 -0
- data/lib/cuboid/ui/output.rb +52 -0
- data/lib/cuboid/ui/output_interface.rb +43 -0
- data/lib/cuboid/ui/output_interface/abstract.rb +68 -0
- data/lib/cuboid/ui/output_interface/controls.rb +84 -0
- data/lib/cuboid/ui/output_interface/error_logging.rb +119 -0
- data/lib/cuboid/ui/output_interface/implemented.rb +58 -0
- data/lib/cuboid/ui/output_interface/personalization.rb +62 -0
- data/lib/cuboid/utilities.rb +155 -0
- data/lib/cuboid/version.rb +4 -3
- data/lib/version +1 -0
- data/logs/placeholder +0 -0
- data/spec/cuboid/application/parts/data_spec.rb +12 -0
- data/spec/cuboid/application/parts/report_spec.rb +6 -0
- data/spec/cuboid/application/parts/state_spec.rb +192 -0
- data/spec/cuboid/application/runtime_spec.rb +21 -0
- data/spec/cuboid/application_spec.rb +37 -0
- data/spec/cuboid/data/application_spec.rb +22 -0
- data/spec/cuboid/data_spec.rb +47 -0
- data/spec/cuboid/error_spec.rb +23 -0
- data/spec/cuboid/option_groups/datastore_spec.rb +54 -0
- data/spec/cuboid/option_groups/dispatcher_spec.rb +12 -0
- data/spec/cuboid/option_groups/output_spec.rb +11 -0
- data/spec/cuboid/option_groups/paths_spec.rb +184 -0
- data/spec/cuboid/option_groups/report_spec.rb +26 -0
- data/spec/cuboid/option_groups/rpc_spec.rb +53 -0
- data/spec/cuboid/option_groups/snapshot_spec.rb +26 -0
- data/spec/cuboid/option_groups/system.rb +12 -0
- data/spec/cuboid/options_spec.rb +218 -0
- data/spec/cuboid/report_spec.rb +221 -0
- data/spec/cuboid/rest/server_spec.rb +1205 -0
- data/spec/cuboid/rpc/client/base_spec.rb +151 -0
- data/spec/cuboid/rpc/client/dispatcher_spec.rb +13 -0
- data/spec/cuboid/rpc/client/instance_spec.rb +38 -0
- data/spec/cuboid/rpc/server/active_options_spec.rb +21 -0
- data/spec/cuboid/rpc/server/base_spec.rb +60 -0
- data/spec/cuboid/rpc/server/dispatcher/node_spec.rb +222 -0
- data/spec/cuboid/rpc/server/dispatcher/service_spec.rb +112 -0
- data/spec/cuboid/rpc/server/dispatcher_spec.rb +317 -0
- data/spec/cuboid/rpc/server/instance_spec.rb +307 -0
- data/spec/cuboid/rpc/server/output_spec.rb +32 -0
- data/spec/cuboid/rpc/server/scheduler_spec.rb +400 -0
- data/spec/cuboid/ruby/array_spec.rb +77 -0
- data/spec/cuboid/ruby/hash_spec.rb +63 -0
- data/spec/cuboid/ruby/object_spec.rb +22 -0
- data/spec/cuboid/snapshot_spec.rb +123 -0
- data/spec/cuboid/state/application_spec.rb +538 -0
- data/spec/cuboid/state/options_spec.rb +37 -0
- data/spec/cuboid/state_spec.rb +53 -0
- data/spec/cuboid/support/buffer/autoflush_spec.rb +78 -0
- data/spec/cuboid/support/buffer/base_spec.rb +193 -0
- data/spec/cuboid/support/cache/least_cost_replacement_spec.rb +61 -0
- data/spec/cuboid/support/cache/least_recently_pushed_spec.rb +90 -0
- data/spec/cuboid/support/cache/least_recently_used_spec.rb +80 -0
- data/spec/cuboid/support/cache/preference_spec.rb +37 -0
- data/spec/cuboid/support/cache/random_replacement_spec.rb +42 -0
- data/spec/cuboid/support/crypto/rsa_aes_cbc_spec.rb +28 -0
- data/spec/cuboid/support/database/categorized_queue_spec.rb +327 -0
- data/spec/cuboid/support/database/hash_spec.rb +204 -0
- data/spec/cuboid/support/database/scheduler_spec.rb +325 -0
- data/spec/cuboid/support/filter/set_spec.rb +19 -0
- data/spec/cuboid/support/glob_spec.rb +75 -0
- data/spec/cuboid/support/mixins/observable_spec.rb +95 -0
- data/spec/cuboid/system/platforms/linux_spec.rb +31 -0
- data/spec/cuboid/system/platforms/osx_spec.rb +32 -0
- data/spec/cuboid/system/platforms/windows_spec.rb +41 -0
- data/spec/cuboid/system/slots_spec.rb +202 -0
- data/spec/cuboid/system_spec.rb +105 -0
- data/spec/cuboid/utilities_spec.rb +131 -0
- data/spec/spec_helper.rb +46 -0
- data/spec/support/factories/placeholder +0 -0
- data/spec/support/factories/scan_report.rb +18 -0
- data/spec/support/fixtures/empty/placeholder +0 -0
- data/spec/support/fixtures/executables/node.rb +50 -0
- data/spec/support/fixtures/mock_app.rb +61 -0
- data/spec/support/fixtures/mock_app/test_service.rb +64 -0
- data/spec/support/fixtures/services/echo.rb +64 -0
- data/spec/support/helpers/framework.rb +3 -0
- data/spec/support/helpers/matchers.rb +5 -0
- data/spec/support/helpers/misc.rb +3 -0
- data/spec/support/helpers/paths.rb +15 -0
- data/spec/support/helpers/request_helpers.rb +38 -0
- data/spec/support/helpers/requires.rb +8 -0
- data/spec/support/helpers/resets.rb +52 -0
- data/spec/support/helpers/web_server.rb +15 -0
- data/spec/support/lib/factory.rb +107 -0
- data/spec/support/lib/web_server_client.rb +41 -0
- data/spec/support/lib/web_server_dispatcher.rb +25 -0
- data/spec/support/lib/web_server_manager.rb +118 -0
- data/spec/support/logs/placeholder +0 -0
- data/spec/support/pems/cacert.pem +37 -0
- data/spec/support/pems/client/cert.pem +37 -0
- data/spec/support/pems/client/foo-cert.pem +39 -0
- data/spec/support/pems/client/foo-key.pem +51 -0
- data/spec/support/pems/client/key.pem +51 -0
- data/spec/support/pems/server/cert.pem +37 -0
- data/spec/support/pems/server/key.pem +51 -0
- data/spec/support/reports/placeholder +0 -0
- data/spec/support/shared/application.rb +10 -0
- data/spec/support/shared/component.rb +31 -0
- data/spec/support/shared/component/options/base.rb +187 -0
- data/spec/support/shared/option_group.rb +98 -0
- data/spec/support/shared/support/cache.rb +419 -0
- data/spec/support/shared/support/filter.rb +143 -0
- data/spec/support/shared/system/platforms/base.rb +25 -0
- data/spec/support/shared/system/platforms/mixins/unix.rb +37 -0
- data/spec/support/snapshots/placeholder +0 -0
- metadata +566 -21
- data/.gitignore +0 -8
- data/bin/console +0 -15
- data/bin/setup +0 -8
@@ -0,0 +1,64 @@
|
|
1
|
+
class Cuboid::RPC::Server::Dispatcher
|
2
|
+
class Service::Echo < Service
|
3
|
+
|
4
|
+
private :instances
|
5
|
+
public :instances
|
6
|
+
|
7
|
+
def test_dispatcher
|
8
|
+
dispatcher.class == Cuboid::RPC::Server::Dispatcher
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_opts
|
12
|
+
dispatcher.instance_eval{ @options } == options
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_node
|
16
|
+
node.class == Node
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_map_instances( &block )
|
20
|
+
each = proc do |instance, iterator|
|
21
|
+
iterator.return [instance.url, instance.token]
|
22
|
+
end
|
23
|
+
after = proc { |i| block.call Hash[i] }
|
24
|
+
|
25
|
+
map_instances( each, after )
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_each_instance
|
29
|
+
i = 0
|
30
|
+
each_instance do |instance, iterator|
|
31
|
+
i += 1
|
32
|
+
instance.options.set( authorized_by: "test#{i}@test.test") { |p| iterator.next }
|
33
|
+
end
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_iterator_for
|
38
|
+
iterator_for( instances ).class == Arachni::Reactor::Iterator
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_connect_to_dispatcher( url, &block )
|
42
|
+
connect_to_dispatcher( url ).alive? { |b| block.call b }
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_connect_to_instance( *args, &block )
|
46
|
+
connect_to_instance( *args ).busy?{ |b| block.call !!b }
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_defer( *args, &block )
|
50
|
+
defer do
|
51
|
+
block.call args
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_run_asap( *args, &block )
|
56
|
+
run_asap { block.call args }
|
57
|
+
end
|
58
|
+
|
59
|
+
def echo( *args )
|
60
|
+
args
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
def name_from_filename
|
2
|
+
File.basename( caller.first.split( ':' ).first, '_spec.rb' )
|
3
|
+
end
|
4
|
+
|
5
|
+
def spec_path
|
6
|
+
File.expand_path( File.dirname( File.absolute_path( __FILE__ ) ) + '/../../' ) + '/'
|
7
|
+
end
|
8
|
+
|
9
|
+
def support_path
|
10
|
+
"#{spec_path}support/"
|
11
|
+
end
|
12
|
+
|
13
|
+
def fixtures_path
|
14
|
+
"#{support_path}fixtures/"
|
15
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RequestHelpers
|
2
|
+
include Rack::Test::Methods
|
3
|
+
|
4
|
+
def app
|
5
|
+
Cuboid::Rest::Server
|
6
|
+
end
|
7
|
+
|
8
|
+
def response_data
|
9
|
+
JSON.load response.body
|
10
|
+
rescue => e
|
11
|
+
ap response
|
12
|
+
raise
|
13
|
+
end
|
14
|
+
|
15
|
+
def pretty_response_body
|
16
|
+
JSON.pretty_generate( response_data )
|
17
|
+
end
|
18
|
+
|
19
|
+
def response_body
|
20
|
+
response.body
|
21
|
+
end
|
22
|
+
|
23
|
+
def response_code
|
24
|
+
response.status
|
25
|
+
end
|
26
|
+
|
27
|
+
def response
|
28
|
+
last_response
|
29
|
+
end
|
30
|
+
|
31
|
+
%w(get post put delete).each do |m|
|
32
|
+
define_method m do |path, parameters = nil, headers = {}|
|
33
|
+
super( path, (parameters.to_json if parameters), headers )
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
extend self
|
38
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Order is important.
|
2
|
+
INSTANCES = [
|
3
|
+
Cuboid::Application
|
4
|
+
]
|
5
|
+
INSTANCES.each(&:_spec_instances_collect!)
|
6
|
+
|
7
|
+
def reset_options
|
8
|
+
options = Cuboid::Options
|
9
|
+
options.reset
|
10
|
+
|
11
|
+
options.paths.logs = spec_path + 'support/logs/'
|
12
|
+
options.paths.reports = spec_path + 'support/reports/'
|
13
|
+
options.paths.snapshots = spec_path + 'support/snapshots/'
|
14
|
+
options.snapshot.path = options.paths.snapshots
|
15
|
+
|
16
|
+
options.rpc.server_address = '127.0.0.1'
|
17
|
+
|
18
|
+
options
|
19
|
+
end
|
20
|
+
|
21
|
+
def cleanup_instances
|
22
|
+
INSTANCES.each do |i|
|
23
|
+
i._spec_instances_cleanup
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def reset_framework
|
28
|
+
Cuboid::UI::OutputInterface.initialize
|
29
|
+
# Cuboid::UI::Output.debug_on( 999999 )
|
30
|
+
# Cuboid::UI::Output.verbose_on
|
31
|
+
# Cuboid::UI::Output.mute
|
32
|
+
|
33
|
+
Cuboid::Application.reset
|
34
|
+
end
|
35
|
+
|
36
|
+
def reset_all
|
37
|
+
reset_options
|
38
|
+
reset_framework
|
39
|
+
end
|
40
|
+
|
41
|
+
def processes_killall
|
42
|
+
instance_killall
|
43
|
+
dispatcher_killall
|
44
|
+
scheduler_killall
|
45
|
+
process_killall
|
46
|
+
process_kill_reactor
|
47
|
+
end
|
48
|
+
|
49
|
+
def killall
|
50
|
+
processes_killall
|
51
|
+
web_server_killall
|
52
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
def web_server_manager
|
2
|
+
ENV['WEB_SERVER_DISPATCHER'] ? WebServerClient.instance : WebServerManager
|
3
|
+
end
|
4
|
+
|
5
|
+
def web_server_url_for( *args )
|
6
|
+
web_server_manager.url_for( *args )
|
7
|
+
end
|
8
|
+
|
9
|
+
def web_server_spawn( *args )
|
10
|
+
web_server_manager.spawn( *args )
|
11
|
+
end
|
12
|
+
|
13
|
+
def web_server_killall
|
14
|
+
web_server_manager.killall
|
15
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
class Factory
|
2
|
+
class <<self
|
3
|
+
|
4
|
+
# Clears all instructions and aliases.
|
5
|
+
def reset
|
6
|
+
@instructions = {}
|
7
|
+
@aliases = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
# Defines instruction on how to create a given object.
|
11
|
+
#
|
12
|
+
# There are 2 ways to define a factory instruction:
|
13
|
+
#
|
14
|
+
# * Using a `generator` block to return an object.
|
15
|
+
# * Using the `options` to generate an object.
|
16
|
+
#
|
17
|
+
# @param [Symbol] object_name Name of the object.
|
18
|
+
# @param [Hash] options Generation options.
|
19
|
+
# @option options [Class] :class
|
20
|
+
# Class to instantiate.
|
21
|
+
# @option options [Hash] :options
|
22
|
+
# Options to use to instantiate the `:class`.
|
23
|
+
def define( object_name, options = {}, &generator )
|
24
|
+
@instructions[object_name] = {
|
25
|
+
options: options.dup,
|
26
|
+
generator: generator
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param [Symbol] object_name Name of the object.
|
31
|
+
# @param [] args
|
32
|
+
# If a `generator` block has been provided via {#define}, those arguments
|
33
|
+
# will be passed to it.
|
34
|
+
#
|
35
|
+
# If `:options` have been passed to {#define}, the `args` will be merged
|
36
|
+
# with them before instantiating the object.
|
37
|
+
def create( object_name, *args )
|
38
|
+
ensure_defined( object_name )
|
39
|
+
|
40
|
+
instructions = instructions_for( object_name )
|
41
|
+
|
42
|
+
if instructions[:generator]
|
43
|
+
instructions[:generator].call( *args )
|
44
|
+
elsif (options = instructions[:options]).include? :class
|
45
|
+
options[:class].new( options[:options].merge( args.first || {} ) )
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# @param [Symbol] object_name Name of the object.
|
50
|
+
# @return [Hash] Instantiation options passed to {#define}.
|
51
|
+
def options_for( object_name )
|
52
|
+
instructions_for( object_name )[:options][:options].freeze
|
53
|
+
end
|
54
|
+
|
55
|
+
# @note {#create} helper.
|
56
|
+
#
|
57
|
+
# @param [Symbol] object_name Name of the object.
|
58
|
+
# @return [Object] Instantiated object.
|
59
|
+
def []( object_name )
|
60
|
+
create object_name
|
61
|
+
end
|
62
|
+
|
63
|
+
# @param [Symbol] object_name
|
64
|
+
# Name of the new object.
|
65
|
+
# @param [Symbol] existing_object_name
|
66
|
+
# Name of the existing object.
|
67
|
+
def alias( object_name, existing_object_name )
|
68
|
+
ensure_defined( existing_object_name )
|
69
|
+
@aliases[object_name] = existing_object_name
|
70
|
+
end
|
71
|
+
|
72
|
+
# @param [Symbol] object_name Object to delete.
|
73
|
+
def delete( object_name )
|
74
|
+
@instructions.delete object_name
|
75
|
+
end
|
76
|
+
|
77
|
+
# @param [Symbol] object_name Alias to delete.
|
78
|
+
def unalias( object_name )
|
79
|
+
@aliases.delete object_name
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
|
83
|
+
# @param [Symbol] object_name
|
84
|
+
# Name of the new object.
|
85
|
+
# @return [Bool]
|
86
|
+
# `true` if instructions have been {#defined} for the `object_name`,
|
87
|
+
# `false` otherwise.
|
88
|
+
def defined?( object_name )
|
89
|
+
!!instructions_for( object_name ) rescue false
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def instructions_for( object_name )
|
95
|
+
instructions = @instructions[object_name] || @instructions[@aliases[object_name]]
|
96
|
+
return instructions if instructions
|
97
|
+
|
98
|
+
fail ArgumentError, "Factory '#{object_name}' not defined."
|
99
|
+
end
|
100
|
+
|
101
|
+
def ensure_defined( object_name )
|
102
|
+
!!instructions_for( object_name )
|
103
|
+
end
|
104
|
+
end
|
105
|
+
reset
|
106
|
+
|
107
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'arachni/rpc'
|
2
|
+
|
3
|
+
# @note Needs `ENV['WEB_SERVER_DISPATCHER']` in the format of `host:port`.
|
4
|
+
#
|
5
|
+
# {WebServerManager}-API-compatible client for the {WebServerDispatcher}.
|
6
|
+
#
|
7
|
+
# Delegates test webserver creation to the machine running {WebServerDispatcher},
|
8
|
+
# for hosts that lack support for fast servers (like Windows, which can't run
|
9
|
+
# Thin, Puma etc.).
|
10
|
+
#
|
11
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
12
|
+
class WebServerClient < Arachni::RPC::Proxy
|
13
|
+
include Singleton
|
14
|
+
|
15
|
+
def initialize( options = {} )
|
16
|
+
@host, port = ENV['WEB_SERVER_DISPATCHER'].split( ':' )
|
17
|
+
|
18
|
+
Arachni::Reactor.global.run_in_thread if !Arachni::Reactor.global.running?
|
19
|
+
|
20
|
+
client = Arachni::RPC::Client.new( host: @host, port: port )
|
21
|
+
super client, 'server'
|
22
|
+
end
|
23
|
+
|
24
|
+
def protocol_for( name )
|
25
|
+
name.to_s.include?( 'https' ) ? 'https' : 'http'
|
26
|
+
end
|
27
|
+
|
28
|
+
def address_for( name )
|
29
|
+
@host
|
30
|
+
end
|
31
|
+
|
32
|
+
def up?( name )
|
33
|
+
Typhoeus.get(
|
34
|
+
url_for( name, false ),
|
35
|
+
ssl_verifypeer: false,
|
36
|
+
ssl_verifyhost: 0,
|
37
|
+
forbid_reuse: true
|
38
|
+
).code != 0
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative '../../../lib/cuboid/processes/manager'
|
2
|
+
require_relative '../../../lib/cuboid/processes/helpers'
|
3
|
+
require_relative '../../support/helpers/paths'
|
4
|
+
require_relative 'web_server_manager'
|
5
|
+
require 'arachni/rpc'
|
6
|
+
|
7
|
+
# @note Needs `ENV['WEB_SERVER_DISPATCHER']` in the format of `host:port`.
|
8
|
+
#
|
9
|
+
# Exposes the {WebServerManager} over RPC.
|
10
|
+
#
|
11
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
12
|
+
class WebServerDispatcher
|
13
|
+
|
14
|
+
def initialize( options = {} )
|
15
|
+
host, port = ENV['WEB_SERVER_DISPATCHER'].split( ':' )
|
16
|
+
|
17
|
+
manager = WebServerManager.instance
|
18
|
+
manager.address = host
|
19
|
+
|
20
|
+
rpc = Cuboid::RPC::Server.new( host: host, port: port.to_i )
|
21
|
+
rpc.add_handler( 'server', manager )
|
22
|
+
rpc.run
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
class WebServerManager
|
2
|
+
include Singleton
|
3
|
+
include Cuboid::Utilities
|
4
|
+
|
5
|
+
attr_reader :lib
|
6
|
+
attr_accessor :address
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@lib = "#{support_path}/servers/"
|
10
|
+
@servers = {}
|
11
|
+
@address = Socket.gethostname
|
12
|
+
|
13
|
+
Dir.glob( File.join( @lib + '**', '*.rb' ) ) do |path|
|
14
|
+
@servers[normalize_name( File.basename( path, '.rb' ) )] = {
|
15
|
+
path: path
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def spawn( name )
|
21
|
+
server_info = data_for( name )
|
22
|
+
|
23
|
+
10.times do
|
24
|
+
server_info[:port] = Cuboid::Utilities.available_port
|
25
|
+
server_info[:pid] = Process.spawn(
|
26
|
+
RbConfig.ruby, server_info[:path],
|
27
|
+
'-p', server_info[:port].to_s,
|
28
|
+
'-o', address_for( name )
|
29
|
+
)
|
30
|
+
Process.detach server_info[:pid]
|
31
|
+
|
32
|
+
begin
|
33
|
+
Timeout.timeout( 10 ) { sleep 0.1 while !up?( name ) }
|
34
|
+
|
35
|
+
return url_for( name, false )
|
36
|
+
rescue Timeout::Error
|
37
|
+
kill name
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
abort "Server '#{name}' never started!"
|
42
|
+
end
|
43
|
+
|
44
|
+
def url_for( name, lazy_start = true )
|
45
|
+
spawn( name ) if lazy_start && !up?( name )
|
46
|
+
|
47
|
+
"#{protocol_for( name )}://#{address_for( name )}:#{port_for( name )}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def address_for( name )
|
51
|
+
@address
|
52
|
+
end
|
53
|
+
|
54
|
+
def port_for( name )
|
55
|
+
data_for( name )[:port]
|
56
|
+
end
|
57
|
+
|
58
|
+
def protocol_for( name )
|
59
|
+
name.to_s.include?( 'https' ) ? 'https' : 'http'
|
60
|
+
end
|
61
|
+
|
62
|
+
def kill( name )
|
63
|
+
server_info = data_for( name )
|
64
|
+
return if !server_info[:pid]
|
65
|
+
|
66
|
+
r = process_kill( server_info[:pid] )
|
67
|
+
|
68
|
+
if r
|
69
|
+
server_info.delete( :pid )
|
70
|
+
server_info.delete( :port )
|
71
|
+
end
|
72
|
+
|
73
|
+
r
|
74
|
+
end
|
75
|
+
|
76
|
+
def killall
|
77
|
+
@servers.keys.each { |name| kill name }
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
|
81
|
+
def up?( name )
|
82
|
+
return false if !data_for(name)[:port]
|
83
|
+
|
84
|
+
Typhoeus.get(
|
85
|
+
url_for( name, false ),
|
86
|
+
ssl_verifypeer: false,
|
87
|
+
ssl_verifyhost: 0,
|
88
|
+
forbid_reuse: true
|
89
|
+
).code != 0
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.method_missing( sym, *args, &block )
|
93
|
+
if instance.respond_to?( sym )
|
94
|
+
instance.send( sym, *args, &block )
|
95
|
+
else
|
96
|
+
super( sym, *args, &block )
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.respond_to?( m )
|
101
|
+
super( m ) || instance.respond_to?( m )
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def normalize_name( name )
|
107
|
+
name.to_s.to_sym
|
108
|
+
end
|
109
|
+
|
110
|
+
def data_for( name )
|
111
|
+
@servers[normalize_name( name )]
|
112
|
+
end
|
113
|
+
|
114
|
+
def set_data_for(name, data)
|
115
|
+
@servers[normalize_name(name)] = data
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|