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,204 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cuboid::Support::Database::Hash do
4
+
5
+ before :each do
6
+ subject.update seeds
7
+ end
8
+
9
+ subject { described_class.new }
10
+ let(:non_existent) { 'blahblahblah' }
11
+ let(:seeds) do
12
+ {
13
+ 'key' => 'val',
14
+ :key => 'val2',
15
+ { 'key' => 'val' } => 'val4'
16
+ }
17
+ end
18
+
19
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-empty?
20
+ it 'implements #empty?' do
21
+ subject = described_class.new
22
+ expect(subject.empty?).to eq({}.empty?)
23
+
24
+ nh = { :k => 'v' }
25
+ subject[:k] = 'v'
26
+
27
+ expect(subject.empty?).to eq(nh.empty?)
28
+ end
29
+
30
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-5B-5D-3D
31
+ it 'implements #[]=( k, v ) (and store( k, v ))' do
32
+ seeds.each do |k, v|
33
+ expect(subject[k] = v).to eq(v)
34
+ end
35
+ end
36
+
37
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-5B-5D
38
+ it 'implements #[]' do
39
+ seeds.each do |k, v|
40
+ expect(subject[k]).to eq(v)
41
+ end
42
+
43
+ expect(subject[non_existent]).to eq(seeds[non_existent])
44
+ end
45
+
46
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-assoc
47
+ it 'implements #assoc( k )' do
48
+ seeds.dup.each do |k, v|
49
+ expect(subject.assoc( k )).to eq(seeds.assoc( k ))
50
+ end
51
+
52
+ expect(subject.assoc( non_existent )).to eq(seeds.assoc( non_existent ))
53
+ end
54
+
55
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-rassoc
56
+ it 'implements #rassoc( k )' do
57
+ seeds.each do |k, v|
58
+ expect(subject.rassoc( v )).to eq(seeds.rassoc( v ))
59
+ end
60
+
61
+ expect(subject.rassoc( non_existent )).to eq(seeds.rassoc( non_existent ))
62
+ end
63
+
64
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-delete
65
+ it 'implements #delete( k, &block )' do
66
+ expect(subject.delete( non_existent )).to eq(seeds.delete( non_existent ))
67
+ seeds[non_existent] = subject[non_existent] = 'foo'
68
+ expect(subject.delete( non_existent )).to eq(seeds.delete( non_existent ))
69
+
70
+ expect(subject.delete( non_existent ) { |k| k }).to eq(
71
+ seeds.delete( non_existent ) { |k| k }
72
+ )
73
+ end
74
+
75
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-shift
76
+ it 'implements #shift' do
77
+ expect(subject.shift).to eq(seeds.shift)
78
+ end
79
+
80
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-each
81
+ it 'implements #each() (and #each_pair())' do
82
+ subject.each do |k, v|
83
+ expect(seeds[k]).to eq(v)
84
+ end
85
+
86
+ # they must both return enumerators
87
+ expect(subject.each.class).to eq(seeds.each.class)
88
+
89
+ subject.each_pair do |k, v|
90
+ expect(seeds[k]).to eq(v)
91
+ end
92
+
93
+ # they must both return enumerators
94
+ expect(subject.each_pair.class).to eq(seeds.each_pair.class)
95
+ end
96
+
97
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-each_key
98
+ it 'implements #each_key' do
99
+ subject.each_key do |k|
100
+ expect(seeds[k]).to eq(subject[k])
101
+ end
102
+
103
+ # they must both return enumerators
104
+ expect(subject.each_key.class).to eq(seeds.each_key.class)
105
+ end
106
+
107
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-each_value
108
+ it 'implements #each_value' do
109
+ subject.each_value do |v|
110
+ expect(seeds[ seeds.key( v )]).to eq(v)
111
+ end
112
+
113
+ # they must both return enumerators
114
+ expect(subject.each_value.class).to eq(seeds.each_value.class)
115
+ end
116
+
117
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-keys
118
+ it 'implements #keys' do
119
+ expect(subject.keys).to eq(seeds.keys)
120
+ end
121
+
122
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-key
123
+ it 'implement #key' do
124
+ subject.each_key do |k|
125
+ expect(seeds.key( k )).to eq(subject.key( k ))
126
+ end
127
+
128
+ expect(subject.key( non_existent )).to eq(seeds.key( non_existent ))
129
+ end
130
+
131
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-values
132
+ it 'implements #values' do
133
+ expect(subject.values).to eq(seeds.values)
134
+ end
135
+
136
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-include?
137
+ it 'implements #include? (and #member?, #key?, #has_key?)' do
138
+ subject.each_key {
139
+ |k|
140
+ expect(seeds.include?( k )).to eq(subject.include?( k ))
141
+ expect(seeds.member?( k )).to eq(subject.member?( k ))
142
+ expect(seeds.key?( k )).to eq(subject.key?( k ))
143
+ expect(seeds.has_key?( k )).to eq(subject.has_key?( k ))
144
+ }
145
+
146
+ expect(subject.include?( non_existent )).to eq(seeds.include?( non_existent ))
147
+ expect(subject.member?( non_existent )).to eq(seeds.member?( non_existent ))
148
+ expect(subject.key?( non_existent )).to eq(seeds.key?( non_existent ))
149
+ expect(subject.has_key?( non_existent )).to eq(seeds.has_key?( non_existent ))
150
+ end
151
+
152
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-merge
153
+ it 'implements #merge' do
154
+ mh = { :another_key => 'another value' }
155
+
156
+ nh = subject.merge( mh )
157
+ expect(nh.keys).to eq(seeds.merge( mh ).keys)
158
+ expect(nh.values).to eq(seeds.merge( mh ).values)
159
+ end
160
+
161
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-merge!
162
+ it 'implements #merge! (and #update)' do
163
+ mh = { :another_other_key => 'another other value' }
164
+ mh2 = { :another_other_key2 => 'another other value2' }
165
+
166
+ subject.merge!( mh )
167
+ seeds.merge!( mh )
168
+
169
+ subject.update( mh2 )
170
+ seeds.update( mh2 )
171
+
172
+ expect(subject.keys).to eq(seeds.keys)
173
+ expect(subject.values).to eq(seeds.values)
174
+ end
175
+
176
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-to_hash
177
+ it 'implements #to_hash' do
178
+ expect(subject.to_hash).to eq(seeds.to_hash)
179
+ end
180
+
181
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-to_a
182
+ it 'implements #to_a' do
183
+ expect(subject.to_a).to eq(seeds.to_a)
184
+ end
185
+
186
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-size
187
+ it 'implements #size' do
188
+ expect(subject.size).to eq(seeds.size)
189
+ end
190
+
191
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-3D-3D
192
+ it 'implements #== (and #eql?)' do
193
+ expect(subject == subject.merge( {} )).to eq(true)
194
+ expect(subject == seeds).to eq(true)
195
+ end
196
+
197
+ # http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-clear
198
+ it 'implements #clear' do
199
+ subject.clear
200
+ seeds.clear
201
+ expect(subject.size).to eq(seeds.size)
202
+ end
203
+
204
+ end
@@ -0,0 +1,325 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cuboid::Support::Database::Queue do
4
+
5
+ subject { described_class.new }
6
+ let(:sample_size) { 2 * subject.max_buffer_size }
7
+
8
+ it 'maintains stability and consistency under load' do
9
+ subject
10
+
11
+ entries = 1000
12
+ poped = Queue.new
13
+ t = []
14
+
15
+ 10.times do
16
+ t << Thread.new do
17
+ loop do
18
+ poped << subject.pop
19
+ end
20
+ end
21
+ end
22
+
23
+ entries.times do |i|
24
+ subject << 'a' * i
25
+ end
26
+
27
+ sleep 0.1 while !subject.empty?
28
+
29
+ consumed = []
30
+ consumed << poped.pop while !poped.empty?
31
+
32
+ expect(consumed.sort).to eq((0...entries).map { |i| 'a' * i })
33
+ end
34
+
35
+ describe "#{described_class}::DEFAULT_MAX_BUFFER_SIZE" do
36
+ it 'returns 100' do
37
+ expect(described_class::DEFAULT_MAX_BUFFER_SIZE).to eq(100)
38
+ end
39
+ end
40
+
41
+ describe '#initialize' do
42
+ describe ':max_buffer_size' do
43
+ it 'sets #max_buffer_size' do
44
+ expect(
45
+ described_class.new( max_buffer_size: 1 ).max_buffer_size
46
+ ).to eq 1
47
+ end
48
+ end
49
+
50
+ describe ':dumper' do
51
+ it 'defaults to Marshal' do
52
+ d = described_class.new( max_buffer_size: 0 )
53
+ d << 1
54
+
55
+ expect(d.unserialize(IO.binread(d.disk.first))).to eq 1
56
+ end
57
+
58
+ context 'it responds to :dump' do
59
+ it 'gets called to serialize the object' do
60
+ class Dumper; def self.dump(o) o.to_s << '-' end ;end
61
+
62
+ d = described_class.new(
63
+ max_buffer_size: 0,
64
+ dumper: Dumper
65
+ )
66
+ d << 1
67
+
68
+ expect(Zlib::Inflate.inflate IO.binread(d.disk.first)).to eq '1-'
69
+ end
70
+ end
71
+
72
+ context 'it responds to :call' do
73
+ it 'gets called to serialize the object' do
74
+ d = described_class.new(
75
+ max_buffer_size: 0,
76
+ dumper: proc do |o|
77
+ o.to_s << '-'
78
+ end
79
+ )
80
+ d << 1
81
+
82
+ expect(Zlib::Inflate.inflate IO.binread(d.disk.first)).to eq '1-'
83
+ end
84
+ end
85
+ end
86
+
87
+ describe ':load' do
88
+ context 'it responds to :load' do
89
+ it 'gets called to unserialize the object' do
90
+ class Loader; def self.load(o) o + '-' end ;end
91
+
92
+ d = described_class.new(
93
+ max_buffer_size: 0,
94
+ loader: Loader
95
+ )
96
+ d << 1
97
+
98
+ expect(d.pop).to eq Marshal.dump( 1 ) + '-'
99
+ end
100
+ end
101
+
102
+ context 'it responds to :call' do
103
+ it 'gets called to serialize the object' do
104
+ d = described_class.new(
105
+ max_buffer_size: 0,
106
+ loader: proc do |o|
107
+ o + '-'
108
+ end
109
+ )
110
+ d << 1
111
+
112
+ expect(d.pop).to eq Marshal.dump( 1 ) + '-'
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ describe '#buffer' do
119
+ it 'returns the objects stored in the memory buffer' do
120
+ subject << 1
121
+ subject << 2
122
+
123
+ expect(subject.buffer).to eq([1, 2])
124
+ end
125
+ end
126
+
127
+ describe '#disk' do
128
+ it 'returns paths to the files of objects stored to disk' do
129
+ subject.max_buffer_size = 0
130
+ subject << 1
131
+ subject << 2
132
+
133
+ expect(subject.disk.size).to eq(2)
134
+ subject.disk.each do |path|
135
+ expect(File.exists?( path )).to be_truthy
136
+ end
137
+ end
138
+ end
139
+
140
+ describe '#max_buffer_size' do
141
+ context 'by default' do
142
+ it "returns #{described_class}::DEFAULT_MAX_BUFFER_SIZE" do
143
+ expect(subject.max_buffer_size).to eq(described_class::DEFAULT_MAX_BUFFER_SIZE)
144
+ end
145
+ end
146
+ end
147
+
148
+ describe '#max_buffer_size=' do
149
+ it 'sets #max_buffer_size' do
150
+ subject.max_buffer_size = 10
151
+ expect(subject.max_buffer_size).to eq(10)
152
+ end
153
+ end
154
+
155
+ describe '#empty?' do
156
+ context 'when the queue is empty' do
157
+ it 'returns true' do
158
+ expect(subject.empty?).to be_truthy
159
+ end
160
+ end
161
+
162
+ context 'when the queue is not empty' do
163
+ it 'returns false' do
164
+ subject << :stuff
165
+ expect(subject.empty?).to be_falsey
166
+ end
167
+ end
168
+ end
169
+
170
+ describe '#<<' do
171
+ it 'pushes an object' do
172
+ sample_size.times do |i|
173
+ subject << "stuff #{i}"
174
+ end
175
+
176
+ sample_size.times do |i|
177
+ expect(subject.pop).to eq("stuff #{i}")
178
+ end
179
+ end
180
+ end
181
+
182
+ describe '#push' do
183
+ it 'pushes an object' do
184
+ subject.push :stuff
185
+ expect(subject.pop).to eq(:stuff)
186
+ end
187
+
188
+ it 'increments .disk_space' do
189
+ sz = described_class.disk_space
190
+
191
+ subject.max_buffer_size = 0
192
+ subject.push 'a' * 100
193
+
194
+ expect(described_class.disk_space).to be > sz
195
+ end
196
+ end
197
+
198
+ describe '#enq' do
199
+ it 'pushes an object' do
200
+ subject.enq :stuff
201
+ expect(subject.pop).to eq(:stuff)
202
+ end
203
+ end
204
+
205
+ describe '#pop' do
206
+ it 'removes an object' do
207
+ sample_size.times do |i|
208
+ subject << "stuff #{i}"
209
+ end
210
+
211
+ sample_size.times do |i|
212
+ expect(subject.pop).to eq("stuff #{i}")
213
+ end
214
+ end
215
+
216
+ it 'blocks until an entry is available' do
217
+ val = nil
218
+
219
+ t = Thread.new { val = subject.pop }
220
+ sleep 1
221
+ Thread.new { subject << :stuff }
222
+ t.join
223
+
224
+ expect(val).to eq(:stuff)
225
+ end
226
+
227
+ it 'decrements .disk_space' do
228
+ subject.max_buffer_size = 0
229
+ subject.push 'a' * 100
230
+
231
+ sz = described_class.disk_space
232
+ subject.pop
233
+
234
+ expect(described_class.disk_space).to be < sz
235
+ end
236
+ end
237
+
238
+ describe '#deq' do
239
+ it 'removes an object' do
240
+ subject << :stuff
241
+ expect(subject.deq).to eq(:stuff)
242
+ end
243
+ end
244
+
245
+ describe '#shift' do
246
+ it 'removes an object' do
247
+ subject << :stuff
248
+ expect(subject.shift).to eq(:stuff)
249
+ end
250
+ end
251
+
252
+ describe '#size' do
253
+ it 'returns the size of the queue' do
254
+ sample_size.times { |i| subject << i }
255
+ expect(subject.size).to eq(sample_size)
256
+ end
257
+ end
258
+
259
+ describe '#free_buffer_size' do
260
+ it 'returns the size of the available buffer' do
261
+ (subject.max_buffer_size - 2).times { |i| subject << i }
262
+ expect(subject.free_buffer_size).to eq(2)
263
+ end
264
+ end
265
+
266
+ describe '#buffer_size' do
267
+ it 'returns the size of the in-memory entries' do
268
+ expect(subject.buffer_size).to eq(0)
269
+
270
+ (subject.max_buffer_size - 1).times { |i| subject << i }
271
+ expect(subject.buffer_size).to eq(subject.max_buffer_size - 1)
272
+
273
+ subject.clear
274
+
275
+ sample_size.times { |i| subject << i }
276
+ expect(subject.buffer_size).to eq(subject.max_buffer_size)
277
+ end
278
+ end
279
+
280
+ describe '#disk_size' do
281
+ it 'returns the size of the disk entries' do
282
+ expect(subject.buffer_size).to eq(0)
283
+
284
+ (subject.max_buffer_size + 1).times { |i| subject << i }
285
+ expect(subject.disk_size).to eq(1)
286
+
287
+ subject.clear
288
+
289
+ sample_size.times { |i| subject << i }
290
+ expect(subject.disk_size).to eq(sample_size - subject.max_buffer_size)
291
+ end
292
+ end
293
+
294
+ describe '#num_waiting' do
295
+ it 'returns the amount of threads waiting to pop' do
296
+ expect(subject.num_waiting).to eq(0)
297
+
298
+ 2.times do
299
+ Thread.new { subject.pop }
300
+ end
301
+ sleep 0.1
302
+
303
+ expect(subject.num_waiting).to eq(2)
304
+ end
305
+ end
306
+
307
+ describe '#clear' do
308
+ it 'empties the queue' do
309
+ sample_size.times { |i| subject << i }
310
+ subject.clear
311
+ expect(subject.size).to eq(0)
312
+ end
313
+
314
+ it 'decrements .disk_space' do
315
+ subject.max_buffer_size = 0
316
+ subject.push 'a' * 100
317
+
318
+ sz = described_class.disk_space
319
+ subject.clear
320
+
321
+ expect(described_class.disk_space).to be < sz
322
+ end
323
+ end
324
+
325
+ end