tataru 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -0
  3. data/bin/console +15 -0
  4. data/bin/setup +8 -0
  5. data/lib/tataru.rb +70 -12
  6. data/lib/tataru/base_resource.rb +49 -0
  7. data/lib/tataru/base_resource_desc.rb +35 -0
  8. data/lib/tataru/compiler.rb +100 -0
  9. data/lib/tataru/create_subroutines.rb +31 -0
  10. data/lib/tataru/delete_subroutines.rb +42 -0
  11. data/lib/tataru/flattener.rb +81 -0
  12. data/lib/tataru/init_hash_compiler.rb +41 -0
  13. data/lib/tataru/instruction.rb +52 -7
  14. data/lib/tataru/instruction_hash.rb +54 -0
  15. data/lib/tataru/instructions/call_instruction.rb +19 -0
  16. data/lib/tataru/instructions/check_create_instruction.rb +27 -0
  17. data/lib/tataru/instructions/check_delete_instruction.rb +20 -0
  18. data/lib/tataru/instructions/check_instruction.rb +26 -0
  19. data/lib/tataru/instructions/check_update_instruction.rb +27 -0
  20. data/lib/tataru/instructions/clear_instruction.rb +12 -0
  21. data/lib/tataru/instructions/compare_instruction.rb +16 -0
  22. data/lib/tataru/instructions/create_instruction.rb +20 -0
  23. data/lib/tataru/instructions/delete_instruction.rb +14 -0
  24. data/lib/tataru/instructions/end_instruction.rb +12 -0
  25. data/lib/tataru/instructions/goto_if_instruction.rb +26 -0
  26. data/lib/tataru/instructions/immediate_mode_instruction.rb +12 -0
  27. data/lib/tataru/instructions/init_instruction.rb +27 -0
  28. data/lib/tataru/instructions/key_instruction.rb +12 -0
  29. data/lib/tataru/instructions/mark_deletable_instruction.rb +13 -0
  30. data/lib/tataru/instructions/read_instruction.rb +28 -0
  31. data/lib/tataru/instructions/rescmp_instruction.rb +34 -0
  32. data/lib/tataru/instructions/resource_instruction.rb +15 -0
  33. data/lib/tataru/instructions/return_instruction.rb +16 -0
  34. data/lib/tataru/instructions/update_instruction.rb +16 -0
  35. data/lib/tataru/instructions/value_instruction.rb +15 -0
  36. data/lib/tataru/instructions/value_rom_instruction.rb +23 -0
  37. data/lib/tataru/instructions/value_update_instruction.rb +18 -0
  38. data/lib/tataru/memory.rb +16 -0
  39. data/lib/tataru/quest.rb +43 -0
  40. data/lib/tataru/representation.rb +22 -0
  41. data/lib/tataru/representations/array_representation.rb +18 -0
  42. data/lib/tataru/representations/hash_representation.rb +20 -0
  43. data/lib/tataru/representations/literal_representation.rb +9 -0
  44. data/lib/tataru/representations/output_representation.rb +19 -0
  45. data/lib/tataru/representations/resource_representation.rb +49 -0
  46. data/lib/tataru/resolver.rb +39 -0
  47. data/lib/tataru/resource_dsl.rb +21 -71
  48. data/lib/tataru/resource_type_pool.rb +22 -0
  49. data/lib/tataru/rom_reader.rb +47 -0
  50. data/lib/tataru/runner.rb +48 -0
  51. data/lib/tataru/sub_planner.rb +41 -0
  52. data/lib/tataru/subroutine_compiler.rb +52 -0
  53. data/lib/tataru/top_dsl.rb +35 -0
  54. data/lib/tataru/update_subroutines.rb +111 -0
  55. data/lib/tataru/version.rb +1 -1
  56. data/spec/compiler_spec.rb +181 -0
  57. data/spec/flattener_spec.rb +88 -0
  58. data/spec/init_hash_compiler_spec.rb +85 -0
  59. data/spec/instruction_hash_spec.rb +63 -0
  60. data/spec/instruction_spec.rb +36 -0
  61. data/spec/instructions/call_instruction_spec.rb +28 -0
  62. data/spec/instructions/check_create_instruction_spec.rb +67 -0
  63. data/spec/instructions/check_delete_instruction_spec.rb +47 -0
  64. data/spec/instructions/check_update_instruction_spec.rb +67 -0
  65. data/spec/instructions/clear_instruction_spec.rb +16 -0
  66. data/spec/instructions/compare_instruction_spec.rb +29 -0
  67. data/spec/instructions/create_instruction_spec.rb +62 -0
  68. data/spec/instructions/delete_instruction_spec.rb +20 -0
  69. data/spec/instructions/end_instruction_spec.rb +15 -0
  70. data/spec/instructions/goto_if_instruction_spec.rb +42 -0
  71. data/spec/instructions/init_instruction_spec.rb +16 -0
  72. data/spec/instructions/key_instruction_spec.rb +15 -0
  73. data/spec/instructions/mark_deletable_instruction_spec.rb +20 -0
  74. data/spec/instructions/read_instruction_spec.rb +34 -0
  75. data/spec/instructions/rescmp_instruction_spec.rb +113 -0
  76. data/spec/instructions/return_instruction_spec.rb +28 -0
  77. data/spec/instructions/update_instruction_spec.rb +39 -0
  78. data/spec/instructions/value_instruction_spec.rb +27 -0
  79. data/spec/instructions/value_rom_instruction_spec.rb +170 -0
  80. data/spec/instructions/value_update_instruction_spec.rb +35 -0
  81. data/spec/quest_spec.rb +9 -0
  82. data/spec/representations/array_representation_spec.rb +29 -0
  83. data/spec/representations/hash_representation_spec.rb +29 -0
  84. data/spec/representations/literal_representation_spec.rb +10 -0
  85. data/spec/representations/output_representation_spec.rb +11 -0
  86. data/spec/representations/resource_representation_spec.rb +50 -0
  87. data/spec/resource_dsl_spec.rb +71 -0
  88. data/spec/runner_spec.rb +99 -0
  89. data/spec/spec_helper.rb +401 -0
  90. data/spec/subroutine_compiler_spec.rb +39 -0
  91. data/spec/taru_spec.rb +616 -0
  92. data/spec/top_dsl_spec.rb +68 -0
  93. data/tataru.gemspec +45 -0
  94. metadata +145 -27
  95. data/Rakefile +0 -8
  96. data/lib/tataru/default_resource_finder.rb +0 -10
  97. data/lib/tataru/execution_step.rb +0 -79
  98. data/lib/tataru/planner.rb +0 -93
  99. data/lib/tataru/requirements.rb +0 -67
  100. data/lib/tataru/requirements_dsl.rb +0 -33
  101. data/lib/tataru/resource.rb +0 -52
  102. data/lib/tataru/state.rb +0 -64
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tataru'
4
+
5
+ describe Tataru::Runner do
6
+ it 'can be made' do
7
+ runner = Tataru::Runner.new([])
8
+ end
9
+
10
+ it 'returns ended when ended' do
11
+ runner = Tataru::Runner.new([])
12
+ expect(runner).to be_ended
13
+ end
14
+
15
+ it 'returns not ended when not ended' do
16
+ runner = Tataru::Runner.new([Tataru::Instruction.new])
17
+ expect(runner).to_not be_ended
18
+ end
19
+
20
+ it 'returns ended when ended' do
21
+ runner = Tataru::Runner.new([Tataru::Instruction.new])
22
+ runner.memory.end = true
23
+ expect(runner).to be_ended
24
+ end
25
+
26
+ it 'returns ended when errored' do
27
+ runner = Tataru::Runner.new([Tataru::Instruction.new])
28
+ runner.memory.error = 'Something'
29
+ expect(runner).to be_ended
30
+ end
31
+
32
+ it 'sets memory error if instruction throws' do
33
+ inst1 = Tataru::Instruction.new
34
+ allow(inst1).to receive(:run) { raise 'hello' }
35
+
36
+ runner = Tataru::Runner.new([inst1])
37
+ runner.run_next
38
+
39
+ expect(runner).to be_ended
40
+ expect(runner.memory.error).to be_a RuntimeError
41
+ end
42
+
43
+ it 'runs instructions in order' do
44
+ inst1 = Tataru::Instruction.new
45
+ inst2 = Tataru::Instruction.new
46
+
47
+ runner = Tataru::Runner.new([
48
+ inst1, inst2
49
+ ])
50
+
51
+ expect(inst1).to receive(:run)
52
+ runner.run_next
53
+
54
+ expect(inst2).to receive(:run)
55
+ runner.run_next
56
+ end
57
+
58
+ it 'records resource instructions' do
59
+ inst1cls = Class.new(Tataru::Instructions::ResourceInstruction)
60
+ stub_const('TestInstruction', inst1cls)
61
+ inst1 = inst1cls.new
62
+
63
+
64
+ runner = Tataru::Runner.new([
65
+ inst1
66
+ ])
67
+
68
+ runner.memory.hash[:temp][:resource_name] = 'abcd'
69
+ runner.run_next
70
+
71
+ expect(runner.oplog).to eq [
72
+ {
73
+ operation: 'TEST',
74
+ resource: 'abcd'
75
+ }
76
+ ]
77
+ end
78
+
79
+ it 'ignores tataru instruction namespace' do
80
+ inst1cls = Class.new(Tataru::Instructions::ResourceInstruction)
81
+ stub_const('Tataru::Instructions::TestInstruction', inst1cls)
82
+ inst1 = inst1cls.new
83
+
84
+
85
+ runner = Tataru::Runner.new([
86
+ inst1
87
+ ])
88
+
89
+ runner.memory.hash[:temp][:resource_name] = 'defg'
90
+ runner.run_next
91
+
92
+ expect(runner.oplog).to eq [
93
+ {
94
+ operation: 'TEST',
95
+ resource: 'defg'
96
+ }
97
+ ]
98
+ end
99
+ end
@@ -0,0 +1,401 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'pry'
5
+ require 'active_support/testing/time_helpers'
6
+ require 'tataru'
7
+
8
+ RSpec.configure do |config|
9
+ config.include ActiveSupport::Testing::TimeHelpers
10
+ end
11
+
12
+ class TestEnvironment
13
+ include Singleton
14
+
15
+ attr_accessor :files, :servers, :ip_addresses
16
+
17
+ def initialize
18
+ clear!
19
+ end
20
+
21
+ def clear!
22
+ # ids decided by user
23
+ @domain_names = {}
24
+ # a resource with mutable fields
25
+ @load_balancers = {}
26
+ # a resource with outputs
27
+ @api_keys = {}
28
+
29
+ # a resource
30
+ @files = {}
31
+ # a resource that overlaps
32
+ @servers = []
33
+
34
+ # ids decided by server
35
+ @ip_addresses = {}
36
+ @server_to_ip_map = {}
37
+ end
38
+
39
+ def create_file(name, contents)
40
+ raise 'Duplicate file name' if @files.key? name
41
+
42
+ @files[name] = {
43
+ name: name,
44
+ contents: contents,
45
+ updated_at: Time.now.utc.to_s,
46
+ created_at: Time.now.utc.to_s
47
+ }
48
+ end
49
+
50
+ def update_file(name, contents)
51
+ raise "Nonexistent file '#{name}'" unless @files.key? name
52
+
53
+ @files[name][:contents] = contents
54
+ @files[name][:updated_at] = Time.now.utc.to_s
55
+ end
56
+
57
+ def delete_file(name)
58
+ raise "Nonexistent file '#{name}'" unless @files.key? name
59
+
60
+ @files.delete name
61
+ end
62
+
63
+ def exists_file?(name)
64
+ @files.key? name
65
+ end
66
+
67
+ def file(name)
68
+ raise "Nonexistent file '#{name}'" unless @files.key? name
69
+
70
+ @files[name]
71
+ end
72
+
73
+
74
+ def create_server(size)
75
+ id = @servers.count
76
+ @servers[id] = {
77
+ size: size,
78
+ created_at: Time.now.utc.to_s
79
+ }
80
+ "server#{id}"
81
+ end
82
+
83
+ def delete_server(server_id)
84
+ id = server_id.sub(/^server/, '').to_i
85
+ raise "Nonexistent server '#{server_id}'" if @servers[id].nil?
86
+
87
+ ip = @server_to_ip_map[server_id]
88
+ if ip != nil
89
+ raise "Cannot delete while connected to #{ip}"
90
+ end
91
+
92
+ @servers[id] = nil
93
+ end
94
+
95
+ def exists_server?(server_id)
96
+ id = server_id.sub(/^server/, '').to_i
97
+ @servers.key? id
98
+ end
99
+
100
+ def server(server_id)
101
+ id = server_id.sub(/^server/, '').to_i
102
+ raise "Nonexistent server '#{server_id}'" if @servers[id].nil?
103
+
104
+ @servers[id]
105
+ end
106
+
107
+ def create_ip(server_id)
108
+ id = server_id.sub(/^server/, '').to_i
109
+ raise "Nonexistent server '#{server_id}'" if @servers[id].nil?
110
+
111
+ (2..254).each do |i|
112
+ addr = "2.3.4.#{i}"
113
+ next if @ip_addresses.key? addr
114
+
115
+ return modify_ip(addr, server_id)
116
+ end
117
+
118
+ raise 'No more ips available'
119
+ end
120
+
121
+ def modify_ip(addr, server_id)
122
+ id = server_id.sub(/^server/, '').to_i
123
+ raise "Nonexistent server '#{server_id}'" if @servers[id].nil?
124
+ raise "Nonexistent IP #{addr}" if !@ip_addresses.key? addr
125
+
126
+ @ip_addresses[addr] = server_id
127
+ @server_to_ip_map[server_id] = addr
128
+ end
129
+
130
+ def delete_ip(addr)
131
+ raise "Nonexistent IP #{addr}" if !@ip_addresses.key? addr
132
+
133
+ server_id = @ip_addresses[addr]
134
+ @server_to_ip_map.delete(server_id)
135
+ @ip_addresses.delete(addr)
136
+ end
137
+ end
138
+
139
+ # base class of resource
140
+ class TestFileResource < Tataru::BaseResource
141
+ def create(params)
142
+ TestEnvironment.instance.create_file(params[:name], params[:contents])
143
+ @remote_id = params[:name]
144
+ end
145
+
146
+ def read(name_array)
147
+ results = {}
148
+ TestEnvironment.instance.file(@remote_id).each do |k, v|
149
+ results[k] = v if name_array.include? k
150
+ end
151
+ results
152
+ end
153
+
154
+ def update(params)
155
+ TestEnvironment.instance.update_file(@remote_id, params[:contents])
156
+ end
157
+
158
+ def delete
159
+ TestEnvironment.instance.delete_file(@remote_id)
160
+ end
161
+
162
+ def outputs
163
+ TestEnvironment.instance.file(@remote_id)
164
+ end
165
+
166
+ def create_complete?
167
+ # check if creation is complete
168
+ true
169
+ end
170
+
171
+ def update_complete?
172
+ # check if update is complete
173
+ true
174
+ end
175
+
176
+ def delete_complete?
177
+ # check if delete is complete
178
+ true
179
+ end
180
+ end
181
+
182
+ # description of a resource
183
+ class TestFileResourceDesc < Tataru::BaseResourceDesc
184
+ def resource_class
185
+ TestFileResource
186
+ end
187
+
188
+ def mutable_fields
189
+ [:contents]
190
+ end
191
+
192
+ def immutable_fields
193
+ [:name]
194
+ end
195
+
196
+ def required_fields
197
+ [:name]
198
+ end
199
+
200
+ def output_fields
201
+ [:created_at, :updated_at]
202
+ end
203
+
204
+ def needs_remote_id?
205
+ true
206
+ end
207
+
208
+ def delete_at_end?
209
+ false
210
+ end
211
+ end
212
+
213
+ # base class of resource
214
+ class TestServerResource < Tataru::BaseResource
215
+ def create(params)
216
+ @remote_id = TestEnvironment.instance.create_server(params[:size])
217
+ end
218
+
219
+ def read(name_array)
220
+ results = {}
221
+ TestEnvironment.instance.server(@remote_id).each do |k, v|
222
+ results[k] = v if name_array.include? k
223
+ end
224
+ results
225
+ end
226
+
227
+ def update(params)
228
+ end
229
+
230
+ def delete
231
+ TestEnvironment.instance.delete_server(@remote_id)
232
+ end
233
+
234
+ def outputs
235
+ TestEnvironment.instance.server(@remote_id)
236
+ end
237
+
238
+ def create_complete?
239
+ # check if creation is complete
240
+ true
241
+ end
242
+
243
+ def update_complete?
244
+ # check if update is complete
245
+ true
246
+ end
247
+
248
+ def delete_complete?
249
+ # check if delete is complete
250
+ true
251
+ end
252
+ end
253
+
254
+ # description of a resource
255
+ class TestServerResourceDesc < Tataru::BaseResourceDesc
256
+ def resource_class
257
+ TestServerResource
258
+ end
259
+
260
+ def mutable_fields
261
+ []
262
+ end
263
+
264
+ def immutable_fields
265
+ [:size]
266
+ end
267
+
268
+ def required_fields
269
+ [:size]
270
+ end
271
+
272
+ def output_fields
273
+ [:created_at]
274
+ end
275
+
276
+ def needs_remote_id?
277
+ true
278
+ end
279
+
280
+ def delete_at_end?
281
+ true
282
+ end
283
+ end
284
+
285
+ # string joiner
286
+ class StringJoinerResource < Tataru::BaseResource
287
+ attr_reader :remote_id
288
+
289
+ def initialize(remote_id)
290
+ @remote_id = remote_id
291
+ end
292
+
293
+ def create(params)
294
+ @remote_id = params[:strings].join("\n")
295
+ end
296
+
297
+ def outputs
298
+ {
299
+ result: @remote_id
300
+ }
301
+ end
302
+ end
303
+
304
+ # description of a StringJoinerResource
305
+ class StringJoinerResourceDesc < Tataru::BaseResourceDesc
306
+ def resource_class
307
+ StringJoinerResource
308
+ end
309
+
310
+ def immutable_fields
311
+ [:strings]
312
+ end
313
+
314
+ def output_fields
315
+ [:result]
316
+ end
317
+
318
+ def required_fields
319
+ [:strings]
320
+ end
321
+
322
+ def needs_remote_id?
323
+ true
324
+ end
325
+
326
+ def delete_at_end?
327
+ false
328
+ end
329
+ end
330
+
331
+ class TestIpAddressResource < Tataru::BaseResource
332
+ def create(params)
333
+ ip = TestEnvironment.instance.create_ip(params[:server_id])
334
+ @remote_id = ip
335
+ end
336
+
337
+ def read(name_array)
338
+ {
339
+ server_id: TestEnvironment.instance.ip_addresses[@remote_id]
340
+ }
341
+ end
342
+
343
+ def update(params)
344
+ TestEnvironment.instance.modify_ip(@remote_id, params[:server_id])
345
+ end
346
+
347
+ def delete
348
+ TestEnvironment.instance.delete_ip(@remote_id)
349
+ end
350
+
351
+ def outputs
352
+ {
353
+ server_id: TestEnvironment.instance.ip_addresses[@remote_id]
354
+ }
355
+ end
356
+
357
+ def create_complete?
358
+ # check if creation is complete
359
+ true
360
+ end
361
+
362
+ def update_complete?
363
+ # check if update is complete
364
+ true
365
+ end
366
+
367
+ def delete_complete?
368
+ # check if delete is complete
369
+ true
370
+ end
371
+ end
372
+
373
+ class TestIpAddressResourceDesc < Tataru::BaseResourceDesc
374
+ def resource_class
375
+ TestIpAddressResource
376
+ end
377
+
378
+ def mutable_fields
379
+ [:server_id]
380
+ end
381
+
382
+ def immutable_fields
383
+ []
384
+ end
385
+
386
+ def required_fields
387
+ [:server_id]
388
+ end
389
+
390
+ def output_fields
391
+ [:ip]
392
+ end
393
+
394
+ def needs_remote_id?
395
+ true
396
+ end
397
+
398
+ def delete_at_end?
399
+ false
400
+ end
401
+ end