masamune 0.17.15 → 0.18.0

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/lib/masamune/actions/aws_emr.rb +5 -5
  3. data/lib/masamune/actions/hadoop_filesystem.rb +1 -1
  4. data/lib/masamune/actions/hadoop_streaming.rb +3 -3
  5. data/lib/masamune/actions/hive.rb +5 -5
  6. data/lib/masamune/actions/postgres.rb +5 -5
  7. data/lib/masamune/actions/s3cmd.rb +1 -1
  8. data/lib/masamune/cached_filesystem.rb +1 -1
  9. data/lib/masamune/commands/aws_emr.rb +11 -11
  10. data/lib/masamune/commands/hadoop_filesystem.rb +8 -8
  11. data/lib/masamune/commands/hadoop_streaming.rb +2 -2
  12. data/lib/masamune/commands/hive.rb +19 -19
  13. data/lib/masamune/commands/postgres.rb +19 -19
  14. data/lib/masamune/commands/postgres_admin.rb +13 -13
  15. data/lib/masamune/commands/s3cmd.rb +7 -7
  16. data/lib/masamune/configuration.rb +36 -52
  17. data/lib/masamune/environment.rb +4 -3
  18. data/lib/masamune/method_logger.rb +4 -0
  19. data/lib/masamune/schema/store.rb +17 -5
  20. data/lib/masamune/thor.rb +1 -3
  21. data/lib/masamune/version.rb +1 -1
  22. data/spec/masamune/actions/aws_emr_spec.rb +4 -4
  23. data/spec/masamune/actions/hadoop_filesystem_spec.rb +1 -1
  24. data/spec/masamune/actions/hadoop_streaming_spec.rb +5 -5
  25. data/spec/masamune/actions/hive_spec.rb +4 -4
  26. data/spec/masamune/actions/postgres_spec.rb +2 -2
  27. data/spec/masamune/actions/s3cmd_spec.rb +1 -1
  28. data/spec/masamune/commands/aws_emr_spec.rb +1 -1
  29. data/spec/masamune/commands/hadoop_filesystem_spec.rb +1 -1
  30. data/spec/masamune/commands/hadoop_streaming_spec.rb +1 -1
  31. data/spec/masamune/commands/hive_spec.rb +1 -1
  32. data/spec/masamune/commands/postgres_admin_spec.rb +15 -2
  33. data/spec/masamune/commands/postgres_spec.rb +1 -1
  34. data/spec/masamune/commands/s3cmd_spec.rb +1 -1
  35. data/spec/masamune/configuration_spec.rb +96 -1
  36. data/spec/masamune/environment_spec.rb +28 -1
  37. data/spec/masamune/schema/catalog_spec.rb +1 -1
  38. data/spec/masamune/tasks/aws_emr_thor_spec.rb +2 -2
  39. data/spec/masamune/tasks/hive_thor_spec.rb +7 -7
  40. data/spec/masamune/tasks/postgres_thor_spec.rb +4 -4
  41. data/spec/masamune/tasks/shell_thor_spec.rb +1 -1
  42. data/spec/masamune/thor_spec.rb +8 -13
  43. data/spec/support/masamune/example_group.rb +4 -3
  44. data/spec/support/masamune/job_example_group.rb +26 -27
  45. data/spec/support/masamune/mock_command.rb +3 -3
  46. data/spec/support/masamune/shared_example_group.rb +8 -10
  47. data/spec/support/masamune/step_example_group.rb +25 -28
  48. data/spec/support/masamune/task_example_group.rb +75 -28
  49. data/spec/support/masamune/thor_mute.rb +4 -2
  50. data/spec/support/rspec/example/action_example_group.rb +5 -3
  51. data/spec/support/rspec/example/task_example_group.rb +4 -67
  52. data/spec/support/rspec/example/transform_example_group.rb +7 -5
  53. metadata +16 -2
@@ -23,6 +23,23 @@
23
23
  describe Masamune::Environment do
24
24
  let(:instance) { described_class.new }
25
25
  let(:run_dir) { Dir.mktmpdir('masamune') }
26
+ let(:log_dir) { Dir.mktmpdir('masamune') }
27
+
28
+ describe '#log_file_name' do
29
+ subject { instance.log_file_name }
30
+
31
+ context 'when log_dir defined' do
32
+ before do
33
+ instance.filesystem.add_path(:log_dir, log_dir)
34
+ end
35
+
36
+ it { is_expected.to eq(File.join(log_dir, instance.log_file_template)) }
37
+ end
38
+
39
+ context 'when log_dir not defined' do
40
+ it { is_expected.to be_nil }
41
+ end
42
+ end
26
43
 
27
44
  describe '#with_exclusive_lock' do
28
45
  context 'when run_dir not defined' do
@@ -50,7 +67,7 @@ describe Masamune::Environment do
50
67
  it { expect { |b| instance.with_exclusive_lock('some_lock', &b) }.to yield_control }
51
68
  end
52
69
 
53
- context 'when lock cannot be acquired' do
70
+ context 'when lock cannot be acquired and returns 1' do
54
71
  before do
55
72
  instance.filesystem.add_path(:run_dir, run_dir)
56
73
  expect(instance.logger).to receive(:error).with(/acquire lock attempt failed for 'some_lock'/)
@@ -59,5 +76,15 @@ describe Masamune::Environment do
59
76
 
60
77
  it { expect { |b| instance.with_exclusive_lock('some_lock', &b) }.to_not raise_error }
61
78
  end
79
+
80
+ context 'when lock cannot be acquired and returns false' do
81
+ before do
82
+ instance.filesystem.add_path(:run_dir, run_dir)
83
+ expect(instance.logger).to receive(:error).with(/acquire lock attempt failed for 'some_lock'/)
84
+ expect_any_instance_of(File).to receive(:flock).once.and_return(false)
85
+ end
86
+
87
+ it { expect { |b| instance.with_exclusive_lock('some_lock', &b) }.to_not raise_error }
88
+ end
62
89
  end
63
90
  end
@@ -36,7 +36,7 @@ describe Masamune::Schema::Catalog do
36
36
 
37
37
  it { expect(postgres.foo_dimension.id).to eq(:foo) }
38
38
  it { expect(postgres.bar_dimension).to be_nil }
39
- it { expect { postgres.foo_baz }.to raise_error ArgumentError, "unknown attribute type 'baz'" }
39
+ it { expect { postgres.foo_baz }.to raise_error NoMethodError }
40
40
  end
41
41
 
42
42
  describe '#[]' do
@@ -45,7 +45,7 @@ describe Masamune::Tasks::AwsEmrThor do
45
45
  let(:options) { ['--cluster-id=j-XYZ'] }
46
46
  it do
47
47
  expect_any_instance_of(described_class).to receive(:aws_emr).with(hash_including(action: action, cluster_id: 'j-XYZ')).once.and_return(mock_success)
48
- cli_invocation
48
+ execute_command
49
49
  end
50
50
  end
51
51
  end
@@ -57,7 +57,7 @@ describe Masamune::Tasks::AwsEmrThor do
57
57
 
58
58
  it do
59
59
  expect_any_instance_of(described_class).to receive(:aws_emr).with(hash_including(action: action)).once.and_return(mock_success)
60
- cli_invocation
60
+ execute_command
61
61
  end
62
62
 
63
63
  context 'with --help' do
@@ -36,7 +36,7 @@ describe Masamune::Tasks::HiveThor do
36
36
 
37
37
  it do
38
38
  expect_any_instance_of(described_class).to receive(:hive).with(hash_including(retries: 0)).once.and_return(mock_success)
39
- cli_invocation
39
+ execute_command
40
40
  end
41
41
  end
42
42
 
@@ -46,7 +46,7 @@ describe Masamune::Tasks::HiveThor do
46
46
  expect_any_instance_of(described_class).to receive(:hive).with(exec: 'CREATE DATABASE IF NOT EXISTS masamune;', database: nil).and_return(mock_success)
47
47
  expect_any_instance_of(described_class).to receive(:hive).with(file: instance_of(String)).and_return(mock_success)
48
48
  expect_any_instance_of(described_class).to receive(:hive).with(hash_including(file: File.expand_path('zombo.hql'))).once.and_return(mock_success)
49
- cli_invocation
49
+ execute_command
50
50
  end
51
51
  end
52
52
 
@@ -54,7 +54,7 @@ describe Masamune::Tasks::HiveThor do
54
54
  let(:options) { ['--file=zombo.hql'] }
55
55
  it do
56
56
  expect_any_instance_of(described_class).to receive(:hive).with(hash_including(file: File.expand_path('zombo.hql'))).once.and_return(mock_success)
57
- cli_invocation
57
+ execute_command
58
58
  end
59
59
  end
60
60
 
@@ -62,7 +62,7 @@ describe Masamune::Tasks::HiveThor do
62
62
  let(:options) { ['--output=report.txt'] }
63
63
  it do
64
64
  expect_any_instance_of(described_class).to receive(:hive).with(hash_including(output: File.expand_path('report.txt'))).once.and_return(mock_success)
65
- cli_invocation
65
+ execute_command
66
66
  end
67
67
  end
68
68
 
@@ -70,7 +70,7 @@ describe Masamune::Tasks::HiveThor do
70
70
  let(:options) { ['--variables=YEAR:2015', 'MONTH:1'] }
71
71
  it do
72
72
  expect_any_instance_of(described_class).to receive(:hive).with(hash_including(variables: { 'YEAR' => '2015', 'MONTH' => '1' })).once.and_return(mock_success)
73
- cli_invocation
73
+ execute_command
74
74
  end
75
75
  end
76
76
 
@@ -78,7 +78,7 @@ describe Masamune::Tasks::HiveThor do
78
78
  let(:options) { ['-X', 'YEAR:2015', 'MONTH:1'] }
79
79
  it do
80
80
  expect_any_instance_of(described_class).to receive(:hive).with(hash_including(variables: { 'YEAR' => '2015', 'MONTH' => '1' })).once.and_return(mock_success)
81
- cli_invocation
81
+ execute_command
82
82
  end
83
83
  end
84
84
 
@@ -86,7 +86,7 @@ describe Masamune::Tasks::HiveThor do
86
86
  let(:options) { ['--retry'] }
87
87
  it do
88
88
  expect_any_instance_of(described_class).to receive(:hive).with(hash_excluding(retries: 0)).once.and_return(mock_success)
89
- cli_invocation
89
+ execute_command
90
90
  end
91
91
  end
92
92
  end
@@ -33,7 +33,7 @@ describe Masamune::Tasks::PostgresThor do
33
33
 
34
34
  it do
35
35
  expect_any_instance_of(described_class).to receive(:postgres).with(hash_including(retries: 0)).once.and_return(mock_success)
36
- cli_invocation
36
+ execute_command
37
37
  end
38
38
  end
39
39
 
@@ -42,7 +42,7 @@ describe Masamune::Tasks::PostgresThor do
42
42
  it do
43
43
  expect_any_instance_of(described_class).to receive(:postgres).with(file: instance_of(String), retries: 0).once.and_return(mock_success)
44
44
  expect_any_instance_of(described_class).to receive(:postgres).with(hash_including(file: 'zombo.hql')).once.and_return(mock_success)
45
- cli_invocation
45
+ execute_command
46
46
  end
47
47
  end
48
48
 
@@ -50,7 +50,7 @@ describe Masamune::Tasks::PostgresThor do
50
50
  let(:options) { ['--file=zombo.hql'] }
51
51
  it do
52
52
  expect_any_instance_of(described_class).to receive(:postgres).with(hash_including(file: 'zombo.hql')).once.and_return(mock_success)
53
- cli_invocation
53
+ execute_command
54
54
  end
55
55
  end
56
56
 
@@ -58,7 +58,7 @@ describe Masamune::Tasks::PostgresThor do
58
58
  let(:options) { ['--retry'] }
59
59
  it do
60
60
  expect_any_instance_of(described_class).to receive(:postgres).with(hash_excluding(retries: 0)).once.and_return(mock_success)
61
- cli_invocation
61
+ execute_command
62
62
  end
63
63
  end
64
64
  end
@@ -31,7 +31,7 @@ describe Masamune::Tasks::ShellThor do
31
31
  context 'with no arguments' do
32
32
  it do
33
33
  expect(Pry).to receive(:start)
34
- cli_invocation
34
+ execute_command
35
35
  end
36
36
  end
37
37
 
@@ -41,12 +41,6 @@ describe Masamune::Thor do
41
41
  # NOP
42
42
  end
43
43
 
44
- desc 'current_dir', 'current_dir'
45
- skip
46
- def current_dir_task
47
- console(fs.path(:current_dir))
48
- end
49
-
50
44
  desc 'unknown', 'unknown'
51
45
  target path: fs.path(:unknown_dir, 'target/%Y-%m-%d')
52
46
  source path: fs.path(:unknown_dir, 'source/%Y%m%d*.log')
@@ -70,7 +64,7 @@ describe Masamune::Thor do
70
64
  end
71
65
 
72
66
  it 'continues execution' do
73
- expect { cli_invocation }.to_not raise_error
67
+ expect { execute_command }.to_not raise_error
74
68
  end
75
69
  end
76
70
 
@@ -99,7 +93,7 @@ describe Masamune::Thor do
99
93
  let(:command) { 'command' }
100
94
  let(:options) { ['--version'] }
101
95
  it 'exits with status code 0 and prints version' do
102
- expect { cli_invocation }.to raise_error { |e|
96
+ expect { execute_command }.to raise_error { |e|
103
97
  expect(e).to be_a(SystemExit)
104
98
  expect(e.message).to eq('exit')
105
99
  expect(e.status).to eq(0)
@@ -188,7 +182,7 @@ describe Masamune::Thor do
188
182
  expect_any_instance_of(Logger).to receive(:error).with(/random exception/)
189
183
  allow(thor_class).to receive(:dispatch).and_raise('random exception')
190
184
  end
191
- it { expect { cli_invocation }.to raise_error(/random exception/) }
185
+ it { expect { execute_command }.to raise_error(/random exception/) }
192
186
  end
193
187
 
194
188
  context 'with command that raises exception after initialization' do
@@ -198,14 +192,14 @@ describe Masamune::Thor do
198
192
  expect_any_instance_of(Logger).to receive(:error).with(/random exception/)
199
193
  allow(thor_class).to receive(:after_initialize_invoke).and_raise('random exception')
200
194
  end
201
- it { expect { cli_invocation }.to raise_error(/random exception/) }
195
+ it { expect { execute_command }.to raise_error(/random exception/) }
202
196
  end
203
197
 
204
198
  context 'with command that raises exception during execution' do
205
199
  let(:command) { 'unknown' }
206
200
  let(:options) { ['--start', '2013-01-01'] }
207
201
  it 'exits with status code 1 and prints error to stderr' do
208
- expect { cli_invocation }.to raise_error { |e|
202
+ expect { execute_command }.to raise_error { |e|
209
203
  expect(e).to be_a(SystemExit)
210
204
  expect(e.message).to eq('Path :unknown_dir not defined')
211
205
  expect(e.status).to eq(1)
@@ -222,15 +216,16 @@ describe Masamune::Thor do
222
216
  include Masamune::Thor
223
217
 
224
218
  desc 'current_dir', 'current_dir'
225
- def current_dir
219
+ def current_dir_task
226
220
  console(fs.path(:current_dir))
227
221
  end
228
222
  end
229
223
  end
230
224
 
231
225
  let(:command) { 'current_dir' }
226
+ let(:options) { ['--no-quiet'] }
232
227
  it 'prints :current_dir' do
233
- cli_invocation
228
+ execute_command
234
229
  expect(stdout.string).to eq(File.dirname(__FILE__) + "\n")
235
230
  expect(stderr.string).to be_blank
236
231
  end
@@ -24,13 +24,14 @@ require 'masamune/has_environment'
24
24
 
25
25
  # Separate environment for test harness itself
26
26
  module Masamune::ExampleGroup
27
+ extend ActiveSupport::Concern
28
+
27
29
  include Masamune::HasEnvironment
28
30
  extend self # rubocop:disable Style/ModuleFunction
29
31
 
30
- def self.included(base)
31
- base.before(:all) do
32
+ included do
33
+ before(:all) do
32
34
  filesystem.environment = self.environment = Masamune::ExampleGroup.environment
33
- Thor.send(:include, Masamune::ThorMute)
34
35
  end
35
36
  end
36
37
  end
@@ -20,40 +20,39 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
21
  # THE SOFTWARE.
22
22
 
23
+ require_relative 'shared_example_group'
24
+
23
25
  module Masamune::JobExampleGroup
24
- module JobFixtureContext
25
- shared_context 'job_fixture' do |context_options = {}|
26
- fixture_file = example_fixture_file(context_options.slice(:fixture, :file, :path))
27
- let(:fixture) { example_fixture(file: fixture_file) }
28
-
29
- before :all do
30
- load_example_config!
31
- clean_example_run!
32
- end
26
+ extend ActiveSupport::Concern
33
27
 
34
- before do
35
- setup_example_input!(fixture)
36
- end
28
+ include Masamune::ExampleGroup
29
+ include Masamune::SharedExampleGroup
30
+ include Masamune::Actions::Filesystem
31
+ include Masamune::Actions::Hive
32
+ include Masamune::Actions::Postgres
33
+
34
+ shared_context 'job_fixture' do |context_options = {}|
35
+ fixture_file = example_fixture_file(context_options.slice(:fixture, :file, :path))
36
+ let(:fixture) { example_fixture(file: fixture_file) }
37
+
38
+ before :all do
39
+ load_example_config!
40
+ clean_example_run!
41
+ end
42
+
43
+ before do
44
+ setup_example_input!(fixture)
45
+ end
37
46
 
38
- it "should match #{fixture_file}" do
39
- aggregate_failures 'generates expected output' do
40
- gather_example_output(fixture) do |actual_data, expect_file, expect_data|
41
- expect(File.exist?(expect_file)).to eq(true)
42
- expect(actual_data).to eq(expect_data)
43
- end
47
+ it "should match #{fixture_file}" do
48
+ aggregate_failures 'generates expected output' do
49
+ gather_example_output(fixture) do |actual_data, expect_file, expect_data|
50
+ expect(File.exist?(expect_file)).to eq(true)
51
+ expect(actual_data).to eq(expect_data)
44
52
  end
45
53
  end
46
54
  end
47
55
  end
48
-
49
- def self.included(base)
50
- base.send(:include, Masamune::ExampleGroup)
51
- base.send(:include, Masamune::SharedExampleGroup)
52
- base.send(:include, Masamune::Actions::Filesystem)
53
- base.send(:include, Masamune::Actions::Hive)
54
- base.send(:include, Masamune::Actions::Postgres)
55
- base.send(:include, JobFixtureContext)
56
- end
57
56
  end
58
57
 
59
58
  RSpec.configure do |config|
@@ -68,15 +68,15 @@ module Masamune::MockCommand
68
68
  end
69
69
  end
70
70
 
71
- included do |base|
72
- base.before do
71
+ included do
72
+ before do
73
73
  new_method = Masamune::Commands::Shell.method(:new)
74
74
  allow(Masamune::Commands::Shell).to receive(:new) do |command, options|
75
75
  new_method.call(CommandMatcher.new(command), options || {})
76
76
  end
77
77
  end
78
78
 
79
- base.after do
79
+ after do
80
80
  CommandMatcher.reset!
81
81
  end
82
82
  end
@@ -34,22 +34,20 @@ module Masamune::SharedExampleGroup
34
34
  stdout.string
35
35
  end
36
36
 
37
- def capture_output
38
- @stdout = StringIO.new
39
- @stderr = StringIO.new
37
+ def capture_output(stdout, stderr)
40
38
  tmp_stdout = $stdout
41
- $stdout = @stdout
39
+ $stdout = stdout
42
40
  tmp_stderr = $stderr
43
- $stderr = @stderr
41
+ $stderr = stderr
44
42
  yield
45
43
  ensure
46
44
  $stdout = tmp_stdout
47
45
  $stderr = tmp_stderr
48
46
  end
49
47
 
50
- def capture(enable = true)
48
+ def capture(stdout: StringIO.new, stderr: StringIO.new, enable: true)
51
49
  if enable
52
- capture_output do
50
+ capture_output(stdout, stderr) do
53
51
  yield
54
52
  end
55
53
  else
@@ -77,9 +75,9 @@ module Masamune::SharedExampleGroup
77
75
 
78
76
  # TODO: iterate over databases
79
77
  def clean_example_run!
80
- if configuration.postgres[:clean]
81
- postgres_admin(action: :drop, database: configuration.postgres[:database])
82
- postgres_admin(action: :create, database: configuration.postgres[:database])
78
+ if configuration.commands.postgres[:clean]
79
+ postgres_admin(action: :drop, database: configuration.commands.postgres[:database])
80
+ postgres_admin(action: :create, database: configuration.commands.postgres[:database])
83
81
  postgres(file: define_schema(catalog, :postgres).to_file, retries: 0)
84
82
  end
85
83
  filesystem.paths.each do |_, (path, options)|
@@ -21,44 +21,41 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  module Masamune::StepExampleGroup
24
- module StepFixtureContext
25
- shared_context 'step_fixture' do |context_options = {}|
26
- fixture_file = example_fixture_file(context_options.slice(:fixture, :file, :path))
27
- step_file = example_step
24
+ extend ActiveSupport::Concern
28
25
 
29
- args = context_options[:args]
30
- subject do
31
- capture_popen([step_file, args].compact.join(' '), input)
32
- end
26
+ include Masamune::SharedExampleGroup
27
+
28
+ shared_context 'step_fixture' do |context_options = {}|
29
+ fixture_file = example_fixture_file(context_options.slice(:fixture, :file, :path))
30
+ step_file = example_step
33
31
 
34
- context "with #{fixture_file} fixture" do
35
- let(:fixture) { Masamune::StepFixture.load({ file: fixture_file }, binding) }
32
+ args = context_options[:args]
33
+ subject do
34
+ capture_popen([step_file, args].compact.join(' '), input)
35
+ end
36
36
 
37
- let(:input) { fixture.input }
38
- let(:output) { fixture.output }
37
+ context "with #{fixture_file} fixture" do
38
+ let(:fixture) { Masamune::StepFixture.load({ file: fixture_file }, binding) }
39
39
 
40
- it 'should match output' do
41
- is_expected.to eq(output)
42
- end
40
+ let(:input) { fixture.input }
41
+ let(:output) { fixture.output }
43
42
 
44
- after(:each) do |example|
45
- if example.exception && ENV['MASAMUNE_RECORD']
46
- shell = Thor::Shell::Basic.new
47
- shell.say(example.exception)
48
- if shell.yes?('Save recording?')
49
- fixture.output = subject
50
- fixture.save
51
- end
43
+ it 'should match output' do
44
+ is_expected.to eq(output)
45
+ end
46
+
47
+ after(:each) do |example|
48
+ if example.exception && ENV['MASAMUNE_RECORD']
49
+ shell = Thor::Shell::Basic.new
50
+ shell.say(example.exception)
51
+ if shell.yes?('Save recording?')
52
+ fixture.output = subject
53
+ fixture.save
52
54
  end
53
55
  end
54
56
  end
55
57
  end
56
58
  end
57
-
58
- def self.included(base)
59
- base.send(:include, Masamune::SharedExampleGroup)
60
- base.send(:include, StepFixtureContext)
61
- end
62
59
  end
63
60
 
64
61
  RSpec.configure do |config|