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.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -0
  3. data/Gemfile +20 -5
  4. data/LICENSE.md +22 -0
  5. data/README.md +158 -19
  6. data/Rakefile +56 -3
  7. data/config/paths.yml +15 -0
  8. data/cuboid.gemspec +61 -23
  9. data/lib/cuboid.rb +96 -4
  10. data/lib/cuboid/application.rb +326 -0
  11. data/lib/cuboid/application/parts/data.rb +18 -0
  12. data/lib/cuboid/application/parts/report.rb +29 -0
  13. data/lib/cuboid/application/parts/state.rb +274 -0
  14. data/lib/cuboid/application/runtime.rb +25 -0
  15. data/lib/cuboid/banner.rb +13 -0
  16. data/lib/cuboid/data.rb +86 -0
  17. data/lib/cuboid/data/application.rb +52 -0
  18. data/lib/cuboid/error.rb +9 -0
  19. data/lib/cuboid/option_group.rb +129 -0
  20. data/lib/cuboid/option_groups.rb +8 -0
  21. data/lib/cuboid/option_groups/datastore.rb +23 -0
  22. data/lib/cuboid/option_groups/dispatcher.rb +38 -0
  23. data/lib/cuboid/option_groups/output.rb +14 -0
  24. data/lib/cuboid/option_groups/paths.rb +184 -0
  25. data/lib/cuboid/option_groups/report.rb +39 -0
  26. data/lib/cuboid/option_groups/rpc.rb +105 -0
  27. data/lib/cuboid/option_groups/scheduler.rb +27 -0
  28. data/lib/cuboid/option_groups/snapshot.rb +13 -0
  29. data/lib/cuboid/option_groups/system.rb +10 -0
  30. data/lib/cuboid/options.rb +254 -0
  31. data/lib/cuboid/processes.rb +13 -0
  32. data/lib/cuboid/processes/dispatchers.rb +140 -0
  33. data/lib/cuboid/processes/executables/base.rb +54 -0
  34. data/lib/cuboid/processes/executables/dispatcher.rb +5 -0
  35. data/lib/cuboid/processes/executables/instance.rb +12 -0
  36. data/lib/cuboid/processes/executables/rest_service.rb +13 -0
  37. data/lib/cuboid/processes/executables/scheduler.rb +5 -0
  38. data/lib/cuboid/processes/helpers.rb +4 -0
  39. data/lib/cuboid/processes/helpers/dispatchers.rb +23 -0
  40. data/lib/cuboid/processes/helpers/instances.rb +39 -0
  41. data/lib/cuboid/processes/helpers/processes.rb +23 -0
  42. data/lib/cuboid/processes/helpers/schedulers.rb +23 -0
  43. data/lib/cuboid/processes/instances.rb +203 -0
  44. data/lib/cuboid/processes/manager.rb +262 -0
  45. data/lib/cuboid/processes/schedulers.rb +128 -0
  46. data/lib/cuboid/report.rb +220 -0
  47. data/lib/cuboid/rest/server.rb +165 -0
  48. data/lib/cuboid/rest/server/instance_helpers.rb +99 -0
  49. data/lib/cuboid/rest/server/routes/dispatcher.rb +41 -0
  50. data/lib/cuboid/rest/server/routes/grid.rb +41 -0
  51. data/lib/cuboid/rest/server/routes/instances.rb +131 -0
  52. data/lib/cuboid/rest/server/routes/scheduler.rb +140 -0
  53. data/lib/cuboid/rpc/client.rb +3 -0
  54. data/lib/cuboid/rpc/client/base.rb +58 -0
  55. data/lib/cuboid/rpc/client/dispatcher.rb +58 -0
  56. data/lib/cuboid/rpc/client/instance.rb +100 -0
  57. data/lib/cuboid/rpc/client/instance/service.rb +37 -0
  58. data/lib/cuboid/rpc/client/scheduler.rb +46 -0
  59. data/lib/cuboid/rpc/serializer.rb +92 -0
  60. data/lib/cuboid/rpc/server/active_options.rb +38 -0
  61. data/lib/cuboid/rpc/server/application_wrapper.rb +138 -0
  62. data/lib/cuboid/rpc/server/base.rb +63 -0
  63. data/lib/cuboid/rpc/server/dispatcher.rb +317 -0
  64. data/lib/cuboid/rpc/server/dispatcher/node.rb +247 -0
  65. data/lib/cuboid/rpc/server/dispatcher/service.rb +145 -0
  66. data/lib/cuboid/rpc/server/instance.rb +338 -0
  67. data/lib/cuboid/rpc/server/output.rb +92 -0
  68. data/lib/cuboid/rpc/server/scheduler.rb +482 -0
  69. data/lib/cuboid/ruby.rb +4 -0
  70. data/lib/cuboid/ruby/array.rb +17 -0
  71. data/lib/cuboid/ruby/hash.rb +41 -0
  72. data/lib/cuboid/ruby/object.rb +32 -0
  73. data/lib/cuboid/snapshot.rb +186 -0
  74. data/lib/cuboid/state.rb +94 -0
  75. data/lib/cuboid/state/application.rb +309 -0
  76. data/lib/cuboid/state/options.rb +27 -0
  77. data/lib/cuboid/support.rb +11 -0
  78. data/lib/cuboid/support/buffer.rb +3 -0
  79. data/lib/cuboid/support/buffer/autoflush.rb +61 -0
  80. data/lib/cuboid/support/buffer/base.rb +91 -0
  81. data/lib/cuboid/support/cache.rb +7 -0
  82. data/lib/cuboid/support/cache/base.rb +226 -0
  83. data/lib/cuboid/support/cache/least_cost_replacement.rb +77 -0
  84. data/lib/cuboid/support/cache/least_recently_pushed.rb +21 -0
  85. data/lib/cuboid/support/cache/least_recently_used.rb +31 -0
  86. data/lib/cuboid/support/cache/preference.rb +31 -0
  87. data/lib/cuboid/support/cache/random_replacement.rb +20 -0
  88. data/lib/cuboid/support/crypto.rb +2 -0
  89. data/lib/cuboid/support/crypto/rsa_aes_cbc.rb +86 -0
  90. data/lib/cuboid/support/database.rb +5 -0
  91. data/lib/cuboid/support/database/base.rb +177 -0
  92. data/lib/cuboid/support/database/categorized_queue.rb +195 -0
  93. data/lib/cuboid/support/database/hash.rb +300 -0
  94. data/lib/cuboid/support/database/queue.rb +149 -0
  95. data/lib/cuboid/support/filter.rb +3 -0
  96. data/lib/cuboid/support/filter/base.rb +110 -0
  97. data/lib/cuboid/support/filter/set.rb +29 -0
  98. data/lib/cuboid/support/glob.rb +27 -0
  99. data/lib/cuboid/support/mixins.rb +8 -0
  100. data/lib/cuboid/support/mixins/observable.rb +99 -0
  101. data/lib/cuboid/support/mixins/parts.rb +20 -0
  102. data/lib/cuboid/support/mixins/profiler.rb +93 -0
  103. data/lib/cuboid/support/mixins/spec_instances.rb +65 -0
  104. data/lib/cuboid/support/mixins/terminal.rb +57 -0
  105. data/lib/cuboid/system.rb +119 -0
  106. data/lib/cuboid/system/platforms.rb +84 -0
  107. data/lib/cuboid/system/platforms/linux.rb +26 -0
  108. data/lib/cuboid/system/platforms/mixins/unix.rb +46 -0
  109. data/lib/cuboid/system/platforms/osx.rb +25 -0
  110. data/lib/cuboid/system/platforms/windows.rb +81 -0
  111. data/lib/cuboid/system/slots.rb +143 -0
  112. data/lib/cuboid/ui/output.rb +52 -0
  113. data/lib/cuboid/ui/output_interface.rb +43 -0
  114. data/lib/cuboid/ui/output_interface/abstract.rb +68 -0
  115. data/lib/cuboid/ui/output_interface/controls.rb +84 -0
  116. data/lib/cuboid/ui/output_interface/error_logging.rb +119 -0
  117. data/lib/cuboid/ui/output_interface/implemented.rb +58 -0
  118. data/lib/cuboid/ui/output_interface/personalization.rb +62 -0
  119. data/lib/cuboid/utilities.rb +155 -0
  120. data/lib/cuboid/version.rb +4 -3
  121. data/lib/version +1 -0
  122. data/logs/placeholder +0 -0
  123. data/spec/cuboid/application/parts/data_spec.rb +12 -0
  124. data/spec/cuboid/application/parts/report_spec.rb +6 -0
  125. data/spec/cuboid/application/parts/state_spec.rb +192 -0
  126. data/spec/cuboid/application/runtime_spec.rb +21 -0
  127. data/spec/cuboid/application_spec.rb +37 -0
  128. data/spec/cuboid/data/application_spec.rb +22 -0
  129. data/spec/cuboid/data_spec.rb +47 -0
  130. data/spec/cuboid/error_spec.rb +23 -0
  131. data/spec/cuboid/option_groups/datastore_spec.rb +54 -0
  132. data/spec/cuboid/option_groups/dispatcher_spec.rb +12 -0
  133. data/spec/cuboid/option_groups/output_spec.rb +11 -0
  134. data/spec/cuboid/option_groups/paths_spec.rb +184 -0
  135. data/spec/cuboid/option_groups/report_spec.rb +26 -0
  136. data/spec/cuboid/option_groups/rpc_spec.rb +53 -0
  137. data/spec/cuboid/option_groups/snapshot_spec.rb +26 -0
  138. data/spec/cuboid/option_groups/system.rb +12 -0
  139. data/spec/cuboid/options_spec.rb +218 -0
  140. data/spec/cuboid/report_spec.rb +221 -0
  141. data/spec/cuboid/rest/server_spec.rb +1205 -0
  142. data/spec/cuboid/rpc/client/base_spec.rb +151 -0
  143. data/spec/cuboid/rpc/client/dispatcher_spec.rb +13 -0
  144. data/spec/cuboid/rpc/client/instance_spec.rb +38 -0
  145. data/spec/cuboid/rpc/server/active_options_spec.rb +21 -0
  146. data/spec/cuboid/rpc/server/base_spec.rb +60 -0
  147. data/spec/cuboid/rpc/server/dispatcher/node_spec.rb +222 -0
  148. data/spec/cuboid/rpc/server/dispatcher/service_spec.rb +112 -0
  149. data/spec/cuboid/rpc/server/dispatcher_spec.rb +317 -0
  150. data/spec/cuboid/rpc/server/instance_spec.rb +307 -0
  151. data/spec/cuboid/rpc/server/output_spec.rb +32 -0
  152. data/spec/cuboid/rpc/server/scheduler_spec.rb +400 -0
  153. data/spec/cuboid/ruby/array_spec.rb +77 -0
  154. data/spec/cuboid/ruby/hash_spec.rb +63 -0
  155. data/spec/cuboid/ruby/object_spec.rb +22 -0
  156. data/spec/cuboid/snapshot_spec.rb +123 -0
  157. data/spec/cuboid/state/application_spec.rb +538 -0
  158. data/spec/cuboid/state/options_spec.rb +37 -0
  159. data/spec/cuboid/state_spec.rb +53 -0
  160. data/spec/cuboid/support/buffer/autoflush_spec.rb +78 -0
  161. data/spec/cuboid/support/buffer/base_spec.rb +193 -0
  162. data/spec/cuboid/support/cache/least_cost_replacement_spec.rb +61 -0
  163. data/spec/cuboid/support/cache/least_recently_pushed_spec.rb +90 -0
  164. data/spec/cuboid/support/cache/least_recently_used_spec.rb +80 -0
  165. data/spec/cuboid/support/cache/preference_spec.rb +37 -0
  166. data/spec/cuboid/support/cache/random_replacement_spec.rb +42 -0
  167. data/spec/cuboid/support/crypto/rsa_aes_cbc_spec.rb +28 -0
  168. data/spec/cuboid/support/database/categorized_queue_spec.rb +327 -0
  169. data/spec/cuboid/support/database/hash_spec.rb +204 -0
  170. data/spec/cuboid/support/database/scheduler_spec.rb +325 -0
  171. data/spec/cuboid/support/filter/set_spec.rb +19 -0
  172. data/spec/cuboid/support/glob_spec.rb +75 -0
  173. data/spec/cuboid/support/mixins/observable_spec.rb +95 -0
  174. data/spec/cuboid/system/platforms/linux_spec.rb +31 -0
  175. data/spec/cuboid/system/platforms/osx_spec.rb +32 -0
  176. data/spec/cuboid/system/platforms/windows_spec.rb +41 -0
  177. data/spec/cuboid/system/slots_spec.rb +202 -0
  178. data/spec/cuboid/system_spec.rb +105 -0
  179. data/spec/cuboid/utilities_spec.rb +131 -0
  180. data/spec/spec_helper.rb +46 -0
  181. data/spec/support/factories/placeholder +0 -0
  182. data/spec/support/factories/scan_report.rb +18 -0
  183. data/spec/support/fixtures/empty/placeholder +0 -0
  184. data/spec/support/fixtures/executables/node.rb +50 -0
  185. data/spec/support/fixtures/mock_app.rb +61 -0
  186. data/spec/support/fixtures/mock_app/test_service.rb +64 -0
  187. data/spec/support/fixtures/services/echo.rb +64 -0
  188. data/spec/support/helpers/framework.rb +3 -0
  189. data/spec/support/helpers/matchers.rb +5 -0
  190. data/spec/support/helpers/misc.rb +3 -0
  191. data/spec/support/helpers/paths.rb +15 -0
  192. data/spec/support/helpers/request_helpers.rb +38 -0
  193. data/spec/support/helpers/requires.rb +8 -0
  194. data/spec/support/helpers/resets.rb +52 -0
  195. data/spec/support/helpers/web_server.rb +15 -0
  196. data/spec/support/lib/factory.rb +107 -0
  197. data/spec/support/lib/web_server_client.rb +41 -0
  198. data/spec/support/lib/web_server_dispatcher.rb +25 -0
  199. data/spec/support/lib/web_server_manager.rb +118 -0
  200. data/spec/support/logs/placeholder +0 -0
  201. data/spec/support/pems/cacert.pem +37 -0
  202. data/spec/support/pems/client/cert.pem +37 -0
  203. data/spec/support/pems/client/foo-cert.pem +39 -0
  204. data/spec/support/pems/client/foo-key.pem +51 -0
  205. data/spec/support/pems/client/key.pem +51 -0
  206. data/spec/support/pems/server/cert.pem +37 -0
  207. data/spec/support/pems/server/key.pem +51 -0
  208. data/spec/support/reports/placeholder +0 -0
  209. data/spec/support/shared/application.rb +10 -0
  210. data/spec/support/shared/component.rb +31 -0
  211. data/spec/support/shared/component/options/base.rb +187 -0
  212. data/spec/support/shared/option_group.rb +98 -0
  213. data/spec/support/shared/support/cache.rb +419 -0
  214. data/spec/support/shared/support/filter.rb +143 -0
  215. data/spec/support/shared/system/platforms/base.rb +25 -0
  216. data/spec/support/shared/system/platforms/mixins/unix.rb +37 -0
  217. data/spec/support/snapshots/placeholder +0 -0
  218. metadata +566 -21
  219. data/.gitignore +0 -8
  220. data/bin/console +0 -15
  221. data/bin/setup +0 -8
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cuboid::Support::Filter::Set do
4
+ it_behaves_like 'filter'
5
+
6
+ describe '#merge' do
7
+ it 'merges 2 sets' do
8
+ new = described_class.new
9
+
10
+ subject << 'test'
11
+ new << 'test2'
12
+
13
+ subject.merge new
14
+ expect(subject).to include 'test'
15
+ expect(subject).to include 'test2'
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cuboid::Support::Glob do
4
+
5
+ let(:conversions) do
6
+ {
7
+ '*' => /^.*?$/i,
8
+ 'test*' => /^test.*?$/i,
9
+ '*test*' => /^.*?test.*?$/i,
10
+ '*/*' => /^.*?\/.*?$/i
11
+ }
12
+ end
13
+
14
+ let(:matches) do
15
+ [
16
+ ['*', '', true],
17
+ ['*', 'stuff', true],
18
+
19
+ ['test*', 'stuff', false],
20
+ ['test*', 'teststuff', true],
21
+ ['test*', 'tEsTstuff', true],
22
+ ['test*', 'stuffteststuff', false],
23
+
24
+ ['*test*', 'stuffteststuff', true],
25
+ ['*test*', 'stufftEsTstuff', true],
26
+ ['*test*', 'stuff', false],
27
+ ['*test*', 'teststuff', true],
28
+ ['*test*', 'stufftest', true],
29
+
30
+ ['*/*', 'test', false],
31
+ ['*/*', 'test/', true],
32
+ ['*/*', 'test/stuff', true]
33
+ ]
34
+ end
35
+
36
+ describe '.to_regexp' do
37
+ it 'converts a glog to a regexp' do
38
+ conversions.each do |glob, regexp|
39
+ expect(described_class.to_regexp( glob )).to eq regexp
40
+ end
41
+ end
42
+ end
43
+
44
+ describe '#regexp' do
45
+ it 'returns the glob as a regexp' do
46
+ conversions.each do |glob, regexp|
47
+ expect(described_class.new( glob ).regexp).to eq regexp
48
+ end
49
+ end
50
+ end
51
+
52
+ describe '#match?' do
53
+ it 'checks whether or not the glob matches the string' do
54
+ matches.each do |glob, string, result|
55
+ expect(described_class.new( glob ).match?( string )).to eq result
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '#matches?' do
61
+ it 'checks whether or not the glob matches the string' do
62
+ matches.each do |glob, string, result|
63
+ expect(described_class.new( glob ).matches?( string )).to eq result
64
+ end
65
+ end
66
+ end
67
+
68
+ describe '=~' do
69
+ it 'checks whether or not the glob matches the string' do
70
+ matches.each do |glob, string, result|
71
+ expect(described_class.new( glob ) =~ string ).to eq result
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ class ObservableTest
4
+ include Cuboid::Support::Mixins::Observable
5
+
6
+ public :clear_observers
7
+
8
+ advertise :my_event, :my_other_event
9
+
10
+ def notify( event, *args )
11
+ send "notify_#{event}", *args
12
+ end
13
+
14
+ end
15
+
16
+ describe Cuboid::Support::Mixins::Observable do
17
+
18
+ subject{ ObservableTest.new }
19
+
20
+ describe '#<event>' do
21
+ it 'adds an observer' do
22
+ called = false
23
+ subject.my_event { called = true }
24
+ subject.notify :my_event
25
+
26
+ expect(called).to be_truthy
27
+ end
28
+
29
+ it 'returns self' do
30
+ expect(subject.my_event { }).to eq(subject)
31
+ end
32
+
33
+ context 'when no block is given' do
34
+ it 'raises ArgumentError' do
35
+ expect { subject.my_event }.to raise_error ArgumentError
36
+ end
37
+ end
38
+
39
+ context 'when the observer expects arguments' do
40
+ it 'forwards them' do
41
+ received_args = nil
42
+ sent_args = [ 1, 2, 3]
43
+
44
+ subject.my_other_event do |one, two, three|
45
+ received_args = [one, two, three]
46
+ end
47
+ subject.notify :my_other_event, sent_args
48
+
49
+ expect(received_args).to eq(sent_args)
50
+ end
51
+ end
52
+
53
+ describe 'when the event does not exist' do
54
+ it "raises #{NoMethodError}" do
55
+ expect { subject.blah_event }.to raise_error NoMethodError
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '#notify' do
61
+ it 'returns nil' do
62
+ subject.my_event { }
63
+ expect(subject.notify( :my_event )).to be_nil
64
+ end
65
+
66
+ context 'when a callback raises an exception' do
67
+ it 'does not affect other callbacks' do
68
+ called = []
69
+
70
+ subject.my_event { called << 1 }
71
+ subject.my_event { called << 2; raise }
72
+ subject.my_event { called << 3 }
73
+
74
+ subject.notify( :my_event )
75
+
76
+ expect(called).to eq([1, 2, 3])
77
+ end
78
+ end
79
+ end
80
+
81
+ describe '#clear_observers' do
82
+ it 'removes all observers' do
83
+ called = false
84
+
85
+ subject.my_event { called = true }
86
+ subject.clear_observers
87
+
88
+ subject.notify :my_event
89
+
90
+ expect(called).to be_falsey
91
+
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cuboid::System::Platforms::Linux do
4
+ it_should_behave_like 'Cuboid::System::Platforms::Mixins::Unix'
5
+
6
+ describe '#memory_free' do
7
+ it 'returns the amount of free memory' do
8
+ o = Object.new
9
+ expect(o).to receive(:available_bytes).and_return(1000)
10
+ expect(subject).to receive(:memory).at_least(:once).and_return(o)
11
+
12
+ expect(subject.memory_free).to eq 1000
13
+ end
14
+ end
15
+
16
+ describe '.current?' do
17
+ context 'when running on Linux' do
18
+ it 'returns true' do
19
+ expect(Cuboid).to receive(:linux?).and_return( true )
20
+ expect(described_class).to be_current
21
+ end
22
+ end
23
+
24
+ context 'when not running on Linux' do
25
+ it 'returns false' do
26
+ expect(Cuboid).to receive(:linux?).and_return( false )
27
+ expect(described_class).to_not be_current
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cuboid::System::Platforms::OSX do
4
+ it_should_behave_like 'Cuboid::System::Platforms::Mixins::Unix'
5
+
6
+ describe '#memory_free' do
7
+ it 'returns the amount of free memory' do
8
+ o = Object.new
9
+ expect(o).to receive(:free).and_return(1000)
10
+ expect(o).to receive(:pagesize).and_return(4096)
11
+ expect(subject).to receive(:memory).at_least(:once).and_return(o)
12
+
13
+ expect(subject.memory_free).to eq 4096000
14
+ end
15
+ end
16
+
17
+ describe '.current?' do
18
+ context 'when running on OSX' do
19
+ it 'returns true' do
20
+ expect(Cuboid).to receive(:mac?).and_return( true )
21
+ expect(described_class).to be_current
22
+ end
23
+ end
24
+
25
+ context 'when not running on OSX' do
26
+ it 'returns false' do
27
+ expect(Cuboid).to receive(:mac?).and_return( false )
28
+ expect(described_class).to_not be_current
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cuboid::System::Platforms::Windows, if: Cuboid.windows? do
4
+ it_should_behave_like 'Cuboid::System::Platforms::Base'
5
+
6
+ subject { described_class.new }
7
+
8
+ describe '#memory_free' do
9
+ it 'returns the amount of free memory' do
10
+ expect(subject.memory_free).to be > 0
11
+ end
12
+ end
13
+
14
+ describe '#disk_space_free' do
15
+ it 'returns the amount of free disk space' do
16
+ expect(subject.disk_space_free).to be > 0
17
+ end
18
+ end
19
+
20
+ describe '#memory_for_process_group' do
21
+ it 'returns bytes of memory used by the group' do
22
+ expect(subject.memory_for_process_group( Process.pid )).to be > 0
23
+ end
24
+ end
25
+
26
+ describe '.current?' do
27
+ context 'when running on Windows' do
28
+ it 'returns true'do
29
+ expect(Cuboid).to receive(:windows?).and_return( true )
30
+ expect(described_class).to be_current
31
+ end
32
+ end
33
+
34
+ context 'when not running on Windows' do
35
+ it 'returns false' do
36
+ expect(Cuboid).to receive(:windows?).and_return( false )
37
+ expect(described_class).to_not be_current
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,202 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cuboid::System::Slots do
4
+ subject { system.slots }
5
+ let(:system) { Cuboid::System.instance }
6
+
7
+ before :each do
8
+ subject.reset
9
+ end
10
+
11
+ describe '#available' do
12
+ context 'when OptionGroups::system#max_slots is set' do
13
+ before do
14
+ Cuboid::Options.system.max_slots = 5
15
+ end
16
+
17
+ it 'uses it to calculate available slots' do
18
+ expect(subject.available).to eq 5
19
+ end
20
+
21
+ context 'when some slots have been used' do
22
+ it 'subtracts them' do
23
+ allow(subject).to receive(:used).and_return( 2 )
24
+ expect(subject.available).to eq 3
25
+ end
26
+ end
27
+ end
28
+
29
+ context 'when OptionGroups::system#max_slots is not set' do
30
+ before do
31
+ Cuboid::Options.system.max_slots = nil
32
+ end
33
+
34
+ it 'uses #available_auto' do
35
+ expect(subject).to receive(:available_auto).and_return( 25 )
36
+ expect(subject.available).to eq 25
37
+ end
38
+ end
39
+ end
40
+
41
+ describe '#available_auto' do
42
+ before do
43
+ Cuboid::Options.system.max_slots = nil
44
+ end
45
+
46
+ it 'calculates slots based on available resources' do
47
+ expect(subject).to receive(:available_in_memory).and_return( 25 )
48
+ expect(subject).to receive(:available_in_cpu).and_return( 25 )
49
+ expect(subject).to receive(:available_in_disk).and_return( 25 )
50
+
51
+ expect(subject.available).to eq 25
52
+ end
53
+
54
+ context 'when restricted by memory' do
55
+ it 'bases the calculation on memory slots' do
56
+ expect(subject).to receive(:available_in_memory).and_return( 10 )
57
+ expect(subject).to receive(:available_in_cpu).and_return( 25 )
58
+ expect(subject).to receive(:available_in_disk).and_return( 20 )
59
+
60
+ expect(subject.available).to eq 10
61
+ end
62
+ end
63
+
64
+ context 'when restricted by CPUs' do
65
+ it 'bases the calculation on CPU slots' do
66
+ expect(subject).to receive(:available_in_memory).and_return( 10 )
67
+ expect(subject).to receive(:available_in_cpu).and_return( 5 )
68
+ expect(subject).to receive(:available_in_disk).and_return( 20 )
69
+
70
+ expect(subject.available).to eq 5
71
+ end
72
+ end
73
+
74
+ context 'when restricted by disk space' do
75
+ it 'bases the calculation on disk space' do
76
+ expect(subject).to receive(:available_in_memory).and_return( 10 )
77
+ expect(subject).to receive(:available_in_cpu).and_return( 5 )
78
+ expect(subject).to receive(:available_in_disk).and_return( 4 )
79
+
80
+ expect(subject.available).to eq 4
81
+ end
82
+ end
83
+ end
84
+
85
+ describe '#used' do
86
+ it 'returns the amount of active instances' do
87
+ expect(subject.used).to eq 0
88
+
89
+ subject.use Process.pid
90
+ expect(subject.used).to eq 1
91
+ end
92
+
93
+ context 'when a process dies' do
94
+ it 'gets removed from the count'
95
+ end
96
+ end
97
+
98
+ describe '#total' do
99
+ it 'sums up free and used slots' do
100
+ expect(subject).to receive(:available).and_return( 3 )
101
+ expect(subject).to receive(:used).and_return( 5 )
102
+
103
+ expect(subject.total).to eq 8
104
+ end
105
+ end
106
+
107
+ describe '#available_in_memory' do
108
+ it 'returns amount of free memory slots' do
109
+ expect(subject).to receive(:unallocated_memory).and_return( subject.memory_size * 2 )
110
+
111
+ expect(subject.available_in_memory).to eq 2
112
+ end
113
+ end
114
+
115
+ describe '#available_in_cpu' do
116
+ it 'returns amount of free CPUs splots' do
117
+ expect(system).to receive(:cpu_count).and_return( 12 )
118
+ expect(subject).to receive(:used).and_return( 5 )
119
+
120
+ expect(subject.available_in_cpu).to eq 7
121
+ end
122
+ end
123
+
124
+ describe '#unallocated_memory' do
125
+ context 'when there are no scans running' do
126
+ it 'returns the amount of free memory' do
127
+ free = subject.memory_size * 2
128
+
129
+ expect(system).to receive(:memory_free).and_return( free )
130
+
131
+ expect(subject.unallocated_memory).to eq free
132
+ end
133
+ end
134
+
135
+ context 'when there are scans running' do
136
+ context 'using part of their allocation' do
137
+ it 'removes their allocated slots' do
138
+ used_allocation = subject.memory_size / 3
139
+
140
+ expect(system).to receive(:memory_free).and_return( subject.memory_size * 2 - used_allocation )
141
+
142
+ subject.use 123
143
+ expect(subject).to receive(:remaining_memory_for).with(123).and_return( subject.memory_size - used_allocation )
144
+
145
+ expect(subject.unallocated_memory).to eq subject.memory_size
146
+ end
147
+ end
148
+ end
149
+ end
150
+
151
+ describe '#remaining_memory_for' do
152
+ it 'returns the amount of allocated memory available to the scan' do
153
+ expect(system).to receive(:memory_for_process_group).with(123).and_return( subject.memory_size / 3 )
154
+ expect(subject.remaining_memory_for(123)).to eq( subject.memory_size - subject.memory_size / 3 )
155
+ end
156
+ end
157
+
158
+ describe '#unallocated_disk_space' do
159
+ context 'when there are no scans running' do
160
+ it 'returns the amount of free disk space' do
161
+ free = subject.disk_space * 2
162
+
163
+ expect(system).to receive(:disk_space_free).and_return( free )
164
+
165
+ expect(subject.unallocated_disk_space).to eq free
166
+ end
167
+ end
168
+
169
+ context 'when there are scans running' do
170
+ context 'using part of their allocation' do
171
+ it 'removes their allocated slots' do
172
+ used_allocation = subject.disk_space / 3
173
+
174
+ expect(system).to receive(:disk_space_free).and_return( subject.disk_space * 2 - used_allocation )
175
+
176
+ subject.use 123
177
+ expect(subject).to receive(:remaining_disk_space_for).with(123).and_return( subject.disk_space - used_allocation )
178
+
179
+ expect(subject.unallocated_disk_space.to_i).to eq subject.disk_space.to_i
180
+ end
181
+ end
182
+ end
183
+ end
184
+
185
+ describe '#remaining_disk_space_for' do
186
+ it 'returns the amount of allocated disk space available to the scan' do
187
+ expect(system).to receive(:disk_space_for_process).with(123).and_return( subject.disk_space / 3 )
188
+ expect(subject.remaining_disk_space_for(123)).to eq( subject.disk_space - subject.disk_space / 3 )
189
+ end
190
+ end
191
+
192
+ describe '#memory_size' do
193
+ before do
194
+ Cuboid::Options.reset
195
+ end
196
+ let(:memory_size) { subject.memory_size }
197
+
198
+ it 'is approx 0.2GB with default options' do
199
+ expect(memory_size).to eq MockApp.max_memory
200
+ end
201
+ end
202
+ end