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,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hash do
4
+ let( :with_symbols ) do
5
+ {
6
+ stuff: 'blah',
7
+ more: {
8
+ stuff: {
9
+ blah: 'stuff'
10
+ }
11
+ }
12
+ }
13
+ end
14
+
15
+ let( :with_strings ) do
16
+ {
17
+ 'stuff' => 'blah',
18
+ 'more' => {
19
+ 'stuff' => {
20
+ 'blah' => 'stuff'
21
+ }
22
+ }
23
+ }
24
+ end
25
+
26
+ describe '#my_stringify_keys' do
27
+ it 'recursively converts keys to strings' do
28
+ expect(with_symbols.my_stringify_keys).to eq(with_strings)
29
+ end
30
+
31
+ context 'when the recursive is set to false' do
32
+ it 'only converts the keys at depth 1' do
33
+ expect(with_symbols.my_stringify_keys( false )).to eq({
34
+ 'stuff' => 'blah',
35
+ 'more' => {
36
+ stuff: {
37
+ blah: 'stuff'
38
+ }
39
+ }
40
+ })
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#my_symbolize_keys' do
46
+ it 'recursively converts keys to symbols' do
47
+ expect(with_strings.my_symbolize_keys).to eq(with_symbols)
48
+ end
49
+
50
+ context 'when the recursive is set to false' do
51
+ it 'only converts the keys at depth 1' do
52
+ expect(with_strings.my_symbolize_keys( false )).to eq({
53
+ stuff: 'blah',
54
+ more: {
55
+ 'stuff' => {
56
+ 'blah' => 'stuff'
57
+ }
58
+ }
59
+ })
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ class Empty
4
+ end
5
+
6
+ class MyClass
7
+ attr_accessor :stuff
8
+ end
9
+
10
+ describe Object do
11
+
12
+ describe '#deep_clone' do
13
+ it 'returns a deep copy of the object' do
14
+ a = [ [1,2] ]
15
+ b = a.deep_clone
16
+ a[0] << 3
17
+
18
+ expect(b).to eq([ [1,2] ])
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cuboid::Snapshot do
4
+
5
+ subject { described_class }
6
+ let(:dump_archive) do
7
+ "#{Cuboid::Options.paths.tmpdir}/snapshot-#{Cuboid::Utilities.generate_token}.#{described_class::EXTENSION}"
8
+ end
9
+
10
+ describe '.summary' do
11
+ let(:summary) { subject.summary }
12
+
13
+ it 'includes :data' do
14
+ expect(summary[:data]).to eq(Cuboid::Data.statistics)
15
+ end
16
+
17
+ it 'includes :state' do
18
+ expect(summary[:state]).to eq(Cuboid::State.statistics)
19
+ end
20
+ end
21
+
22
+ describe '.metadata' do
23
+ context 'when dealing with a restored snapshot' do
24
+ it 'returns the stored metadata from the snapshot archive' do
25
+ subject.dump( dump_archive )
26
+ subject.load( dump_archive )
27
+
28
+ expect(subject.metadata).to eq(subject.read_metadata( dump_archive ))
29
+ end
30
+ end
31
+
32
+ context 'when not dealing with a restored snapshot' do
33
+ it 'returns nil' do
34
+ expect(subject.metadata).to be_nil
35
+ end
36
+ end
37
+ end
38
+
39
+ describe '.restored?' do
40
+ context 'when dealing with a restored snapshot' do
41
+ it 'returns true' do
42
+ subject.dump( dump_archive )
43
+ subject.load( dump_archive )
44
+
45
+ expect(subject).to be_restored
46
+ end
47
+ end
48
+
49
+ context 'when not dealing with a restored snapshot' do
50
+ it 'returns false' do
51
+ expect(subject).not_to be_restored
52
+ end
53
+ end
54
+ end
55
+
56
+ describe '.location' do
57
+ context 'when dealing with a restored snapshot' do
58
+ it 'returns the location of the loaded snapshot' do
59
+ subject.dump( dump_archive )
60
+ subject.load( dump_archive )
61
+
62
+ expect(subject.location).to eq(dump_archive)
63
+ end
64
+ end
65
+
66
+ context 'when not dealing with a restored snapshot' do
67
+ it 'returns nil' do
68
+ expect(subject.location).to be_nil
69
+ end
70
+ end
71
+ end
72
+
73
+ describe '.read_metadata' do
74
+ let(:metadata) do
75
+ subject.dump( dump_archive )
76
+ subject.read_metadata( dump_archive )
77
+ end
78
+
79
+ it 'includes a :timestamp' do
80
+ expect(metadata[:timestamp]).to be_kind_of Time
81
+ end
82
+
83
+ it 'includes a :version' do
84
+ expect(metadata[:version]).to eq(Cuboid::VERSION)
85
+ end
86
+
87
+ it 'includes a #summary' do
88
+ expect(metadata[:summary]).to eq(subject.summary)
89
+ end
90
+
91
+ context 'when trying to read an invalid file' do
92
+ it "raises #{described_class::Error::InvalidFile}" do
93
+ expect { subject.read_metadata( __FILE__ ) }.to raise_error described_class::Error::InvalidFile
94
+ end
95
+ end
96
+ end
97
+
98
+ describe '.dump' do
99
+ it "stores #{Cuboid::State} to disk" do
100
+ expect(Cuboid::State).to receive(:dump)
101
+ expect(Cuboid::Data).to receive(:dump)
102
+
103
+ subject.dump( dump_archive )
104
+ end
105
+ end
106
+
107
+ describe '.load' do
108
+ it "stores #{Cuboid::State} to disk" do
109
+ subject.dump( dump_archive )
110
+
111
+ expect(Cuboid::State).to receive(:load)
112
+ expect(Cuboid::Data).to receive(:load)
113
+
114
+ subject.load( dump_archive )
115
+ end
116
+
117
+ context 'when trying to load an invalid file' do
118
+ it "raises #{described_class::Error::InvalidFile}" do
119
+ expect { subject.load( __FILE__ ) }.to raise_error described_class::Error::InvalidFile
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,538 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cuboid::State::Application do
4
+
5
+ subject { described_class.new }
6
+ before(:each) { subject.clear }
7
+
8
+ let(:dump_directory) do
9
+ "#{Dir.tmpdir}/framework-#{Cuboid::Utilities.generate_token}"
10
+ end
11
+
12
+ describe '#status_messages' do
13
+ it 'returns the assigned status messages' do
14
+ message = 'Hey!'
15
+ subject.set_status_message message
16
+ expect(subject.status_messages).to eq([message])
17
+ end
18
+
19
+ context 'by defaults' do
20
+ it 'returns an empty array' do
21
+ expect(subject.status_messages).to eq([])
22
+ end
23
+ end
24
+ end
25
+
26
+ describe '#set_status_message' do
27
+ it 'sets the #status_messages to the given message' do
28
+ message = 'Hey!'
29
+ subject.set_status_message message
30
+ subject.set_status_message message
31
+ expect(subject.status_messages).to eq([message])
32
+ end
33
+ end
34
+
35
+ describe '#add_status_message' do
36
+ context 'when given a message of type' do
37
+ context 'String' do
38
+ it 'pushes it to #status_messages' do
39
+ message = 'Hey!'
40
+ subject.add_status_message message
41
+ subject.add_status_message message
42
+ expect(subject.status_messages).to eq([message, message])
43
+ end
44
+ end
45
+
46
+ context 'Symbol' do
47
+ context 'and it exists in #available_status_messages' do
48
+ it 'pushes the associated message to #status_messages' do
49
+ subject.add_status_message :suspending
50
+ expect(subject.status_messages).to eq([subject.available_status_messages[:suspending]])
51
+ end
52
+ end
53
+
54
+ context 'and it does not exist in #available_status_messages' do
55
+ it "raises #{described_class::Error::InvalidStatusMessage}" do
56
+ expect do
57
+ subject.add_status_message :stuff
58
+ end.to raise_error described_class::Error::InvalidStatusMessage
59
+ end
60
+ end
61
+
62
+ context 'when given sprintf arguments' do
63
+ it 'uses them to fill in the placeholders' do
64
+ location = '/blah/stuff.ses'
65
+ subject.add_status_message :snapshot_location, location
66
+ expect(subject.status_messages).to eq([subject.available_status_messages[:snapshot_location] % location])
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ describe '#statistics' do
74
+ let(:statistics) { subject.statistics }
75
+ end
76
+
77
+ describe '#running=' do
78
+ it 'sets #running' do
79
+ expect(subject.running).to be_falsey
80
+
81
+ subject.running = true
82
+ expect(subject.running).to be_truthy
83
+ end
84
+ end
85
+
86
+ describe '#running?' do
87
+ context 'when #running is true' do
88
+ it 'returns true' do
89
+ subject.running = true
90
+ expect(subject).to be_running
91
+ end
92
+ end
93
+
94
+ context 'when #running is false' do
95
+ it 'returns false' do
96
+ subject.running = false
97
+ expect(subject).not_to be_running
98
+ end
99
+ end
100
+ end
101
+
102
+ describe '#suspend' do
103
+ context 'when #running?' do
104
+ before(:each) { subject.running = true }
105
+
106
+ context 'when non-blocking' do
107
+ it 'sets the #status to :suspending' do
108
+ subject.suspend
109
+ expect(subject.status).to eq(:suspending)
110
+ end
111
+
112
+ it 'sets the status message to :suspending' do
113
+ subject.suspend
114
+ expect(subject.status_messages).to eq(
115
+ [subject.available_status_messages[:suspending]]
116
+ )
117
+ end
118
+
119
+ it 'returns true' do
120
+ expect(subject.suspend).to be_truthy
121
+ end
122
+ end
123
+
124
+ context 'when already #suspending?' do
125
+ it 'returns false' do
126
+ expect(subject.suspend).to be_truthy
127
+ expect(subject).to be_suspending
128
+ expect(subject.suspend).to be_falsey
129
+ end
130
+ end
131
+
132
+ context 'when already #suspended?' do
133
+ it 'returns false' do
134
+ expect(subject.suspend).to be_truthy
135
+ subject.suspended
136
+ expect(subject).to be_suspended
137
+
138
+ expect(subject.suspend).to be_falsey
139
+ end
140
+ end
141
+
142
+ context 'when #pausing?' do
143
+ it "raises #{described_class::Error::StateNotSuspendable}" do
144
+ subject.pause
145
+
146
+ expect{ subject.suspend }.to raise_error described_class::Error::StateNotSuspendable
147
+ end
148
+ end
149
+
150
+ context 'when #paused?' do
151
+ it "raises #{described_class::Error::StateNotSuspendable}" do
152
+ subject.pause
153
+ subject.paused
154
+
155
+ expect{ subject.suspend }.to raise_error described_class::Error::StateNotSuspendable
156
+ end
157
+ end
158
+ end
159
+
160
+ context 'when not #running?' do
161
+ it "raises #{described_class::Error::StateNotSuspendable}" do
162
+ expect{ subject.suspend }.to raise_error described_class::Error::StateNotSuspendable
163
+ end
164
+ end
165
+ end
166
+
167
+ describe '#suspended' do
168
+ it 'sets the #status to :suspended' do
169
+ subject.suspended
170
+ expect(subject.status).to eq(:suspended)
171
+ end
172
+ end
173
+
174
+ describe '#suspended?' do
175
+ context 'when #suspended' do
176
+ it 'returns true' do
177
+ subject.suspended
178
+ expect(subject).to be_suspended
179
+ end
180
+ end
181
+
182
+ context 'when not #suspended' do
183
+ it 'returns false' do
184
+ expect(subject).not_to be_suspended
185
+ end
186
+ end
187
+ end
188
+
189
+ describe '#suspending?' do
190
+ before(:each) { subject.running = true }
191
+
192
+ context 'while suspending' do
193
+ it 'returns true' do
194
+ subject.suspend
195
+ expect(subject).to be_suspending
196
+ end
197
+ end
198
+
199
+ context 'while not suspending' do
200
+ it 'returns false' do
201
+ expect(subject).not_to be_suspending
202
+
203
+ subject.suspend
204
+ subject.suspended
205
+ expect(subject).not_to be_suspending
206
+ end
207
+ end
208
+ end
209
+
210
+ describe '#suspend?' do
211
+ before(:each) { subject.running = true }
212
+
213
+ context 'when a #suspend signal is in place' do
214
+ it 'returns true' do
215
+ subject.suspend
216
+ expect(subject).to be_suspend
217
+ end
218
+ end
219
+
220
+ context 'when a #suspend signal is not in place' do
221
+ it 'returns false' do
222
+ expect(subject).not_to be_suspend
223
+
224
+ subject.suspend
225
+ subject.suspended
226
+ expect(subject).not_to be_suspend
227
+ end
228
+ end
229
+ end
230
+
231
+ describe '#abort' do
232
+ context 'when #running?' do
233
+ before(:each) { subject.running = true }
234
+
235
+ context 'when non-blocking' do
236
+ it 'sets the #status to :aborting' do
237
+ subject.abort
238
+ expect(subject.status).to eq(:aborting)
239
+ end
240
+
241
+ it 'sets the status message to :aborting' do
242
+ subject.abort
243
+ expect(subject.status_messages).to eq(
244
+ [subject.available_status_messages[:aborting]]
245
+ )
246
+ end
247
+
248
+ it 'returns true' do
249
+ expect(subject.abort).to be_truthy
250
+ end
251
+ end
252
+
253
+ context 'when already #aborting?' do
254
+ it 'returns false' do
255
+ expect(subject.abort).to be_truthy
256
+ expect(subject).to be_aborting
257
+ expect(subject.abort).to be_falsey
258
+ end
259
+ end
260
+
261
+ context 'when already #aborted?' do
262
+ it 'returns false' do
263
+ expect(subject.abort).to be_truthy
264
+ subject.aborted
265
+ expect(subject).to be_aborted
266
+
267
+ expect(subject.abort).to be_falsey
268
+ end
269
+ end
270
+ end
271
+
272
+ context 'when not #running?' do
273
+ it "raises #{described_class::Error::StateNotAbortable}" do
274
+ expect{ subject.abort }.to raise_error described_class::Error::StateNotAbortable
275
+ end
276
+ end
277
+ end
278
+
279
+ describe '#done?' do
280
+ context 'when #status is :done' do
281
+ it 'returns true' do
282
+ subject.status = :done
283
+ expect(subject).to be_done
284
+ end
285
+ end
286
+
287
+ context 'when not done' do
288
+ it 'returns false' do
289
+ expect(subject).not_to be_done
290
+ end
291
+ end
292
+ end
293
+
294
+ describe '#aborted' do
295
+ it 'sets the #status to :aborted' do
296
+ subject.aborted
297
+ expect(subject.status).to eq(:aborted)
298
+ end
299
+ end
300
+
301
+ describe '#aborted?' do
302
+ context 'when #aborted' do
303
+ it 'returns true' do
304
+ subject.aborted
305
+ expect(subject).to be_aborted
306
+ end
307
+ end
308
+
309
+ context 'when not #aborted' do
310
+ it 'returns false' do
311
+ expect(subject).not_to be_aborted
312
+ end
313
+ end
314
+ end
315
+
316
+ describe '#aborting?' do
317
+ before(:each) { subject.running = true }
318
+
319
+ context 'while aborting' do
320
+ it 'returns true' do
321
+ subject.abort
322
+ expect(subject).to be_aborting
323
+ end
324
+ end
325
+
326
+ context 'while not aborting' do
327
+ it 'returns false' do
328
+ expect(subject).not_to be_aborting
329
+
330
+ subject.abort
331
+ subject.aborted
332
+ expect(subject).not_to be_aborting
333
+ end
334
+ end
335
+ end
336
+
337
+ describe '#abort?' do
338
+ before(:each) { subject.running = true }
339
+
340
+ context 'when a #abort signal is in place' do
341
+ it 'returns true' do
342
+ subject.abort
343
+ expect(subject).to be_abort
344
+ end
345
+ end
346
+
347
+ context 'when a #abort signal is not in place' do
348
+ it 'returns false' do
349
+ expect(subject).not_to be_abort
350
+
351
+ subject.abort
352
+ subject.aborted
353
+ expect(subject).not_to be_abort
354
+ end
355
+ end
356
+ end
357
+
358
+ describe '#timed_out' do
359
+ it 'sets the #status to :timed_out' do
360
+ subject.timed_out
361
+ expect(subject.status).to eq(:timed_out)
362
+ end
363
+ end
364
+
365
+ describe '#timed_out?' do
366
+ context 'when a #timed_out signal is in place' do
367
+ it 'returns true' do
368
+ subject.timed_out
369
+ expect(subject).to be_timed_out
370
+ end
371
+ end
372
+
373
+ context 'when a #timed_out signal is not in place' do
374
+ it 'returns false' do
375
+ expect(subject).not_to be_timed_out
376
+ end
377
+ end
378
+ end
379
+
380
+ describe '#pause' do
381
+ context 'when #running?' do
382
+ before(:each) { subject.running = true }
383
+
384
+ context 'when non-blocking' do
385
+ it 'sets the #status to :pausing' do
386
+ subject.pause
387
+ expect(subject.status).to eq(:pausing)
388
+ end
389
+
390
+ it 'returns true' do
391
+ expect(subject.pause).to be_truthy
392
+ end
393
+ end
394
+ end
395
+
396
+ context 'when not #running?' do
397
+ before(:each) { subject.running = false }
398
+
399
+ it 'sets the #status directly to :paused' do
400
+ t = Thread.new do
401
+ sleep 1
402
+ subject.paused
403
+ end
404
+
405
+ time = Time.now
406
+ subject.pause
407
+ expect(subject.status).to eq(:paused)
408
+ expect(Time.now - time).to be < 1
409
+ t.join
410
+ end
411
+ end
412
+ end
413
+
414
+ describe '#paused' do
415
+ it 'sets the #status to :paused' do
416
+ subject.paused
417
+ expect(subject.status).to eq(:paused)
418
+ end
419
+ end
420
+
421
+ describe '#pausing?' do
422
+ before(:each) { subject.running = true }
423
+
424
+ context 'while pausing' do
425
+ it 'returns true' do
426
+ subject.pause
427
+ expect(subject).to be_pausing
428
+ end
429
+ end
430
+
431
+ context 'while not pausing' do
432
+ it 'returns false' do
433
+ expect(subject).not_to be_pausing
434
+
435
+ subject.pause
436
+ subject.paused
437
+ expect(subject).not_to be_pausing
438
+ end
439
+ end
440
+ end
441
+
442
+ describe '#pause?' do
443
+ context 'when a #pause signal is in place' do
444
+ it 'returns true' do
445
+ subject.pause
446
+ expect(subject).to be_pause
447
+ end
448
+ end
449
+
450
+ context 'when a #pause signal is not in place' do
451
+ it 'returns false' do
452
+ expect(subject).not_to be_pause
453
+
454
+ subject.pause
455
+ subject.paused
456
+ subject.resume
457
+ expect(subject).not_to be_pause
458
+ end
459
+ end
460
+ end
461
+
462
+ describe '#resume' do
463
+ before(:each) { subject.running = true }
464
+
465
+ it 'removes #pause signals' do
466
+ subject.pause
467
+ subject.resume
468
+ expect(subject).not_to be_paused
469
+ end
470
+
471
+ it 'sets status to :resuming' do
472
+ subject.status = :my_status
473
+
474
+ subject.pause
475
+ subject.paused
476
+ expect(subject.status).to be :paused
477
+
478
+ subject.resume
479
+ expect(subject.status).to be :resuming
480
+ end
481
+
482
+ context 'when called before a #pause signal has been sent' do
483
+ it '#pause? returns false' do
484
+ subject.pause
485
+ subject.resume
486
+ expect(subject).not_to be_pause
487
+ end
488
+
489
+ it '#paused? returns false' do
490
+ subject.pause
491
+ subject.resume
492
+ expect(subject).not_to be_paused
493
+ end
494
+ end
495
+
496
+ context 'when there are no more signals' do
497
+ it 'returns true' do
498
+ subject.pause
499
+ subject.paused
500
+
501
+ expect(subject.resume).to be_truthy
502
+ end
503
+ end
504
+
505
+ context 'when there are more signals' do
506
+ it 'returns true' do
507
+ subject.pause
508
+ subject.pause
509
+ subject.paused
510
+
511
+ expect(subject.resume).to be_truthy
512
+ end
513
+ end
514
+ end
515
+
516
+ describe '#resumed' do
517
+ it 'restores the previous #status' do
518
+ subject.status = :my_status
519
+
520
+ subject.pause
521
+ subject.paused
522
+ expect(subject.status).to be :paused
523
+
524
+ subject.resumed
525
+ expect(subject.status).to be :my_status
526
+ end
527
+
528
+ end
529
+
530
+ describe '#dump' do
531
+ end
532
+
533
+ describe '.load' do
534
+ end
535
+
536
+ describe '#clear' do
537
+ end
538
+ end