active_encode 0.1.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -2
  4. data/Gemfile +35 -0
  5. data/README.md +15 -14
  6. data/Rakefile +5 -10
  7. data/active_encode.gemspec +8 -5
  8. data/app/jobs/active_encode/polling_job.rb +20 -0
  9. data/app/models/active_encode/encode_record.rb +5 -0
  10. data/db/migrate/20180822021048_create_active_encode_encode_records.rb +13 -0
  11. data/lib/active_encode.rb +1 -0
  12. data/lib/active_encode/base.rb +6 -2
  13. data/lib/active_encode/callbacks.rb +18 -35
  14. data/lib/active_encode/core.rb +64 -20
  15. data/lib/active_encode/engine.rb +7 -0
  16. data/lib/active_encode/engine_adapter.rb +2 -2
  17. data/lib/active_encode/engine_adapters/active_job_adapter.rb +7 -3
  18. data/lib/active_encode/engine_adapters/elastic_transcoder_adapter.rb +15 -15
  19. data/lib/active_encode/engine_adapters/inline_adapter.rb +6 -1
  20. data/lib/active_encode/engine_adapters/matterhorn_adapter.rb +18 -18
  21. data/lib/active_encode/engine_adapters/shingoncoder_adapter.rb +13 -9
  22. data/lib/active_encode/engine_adapters/test_adapter.rb +19 -12
  23. data/lib/active_encode/engine_adapters/zencoder_adapter.rb +10 -10
  24. data/lib/active_encode/global_id.rb +16 -0
  25. data/lib/active_encode/input.rb +9 -0
  26. data/lib/active_encode/output.rb +9 -0
  27. data/lib/active_encode/persistence.rb +45 -0
  28. data/lib/active_encode/polling.rb +24 -0
  29. data/lib/active_encode/status.rb +2 -6
  30. data/lib/active_encode/technical_metadata.rb +16 -1
  31. data/lib/active_encode/version.rb +1 -1
  32. data/spec/fixtures/elastic_transcoder/job_canceled.json +1 -1
  33. data/spec/fixtures/elastic_transcoder/job_completed.json +1 -1
  34. data/spec/fixtures/elastic_transcoder/job_created.json +1 -1
  35. data/spec/fixtures/elastic_transcoder/job_failed.json +1 -1
  36. data/spec/fixtures/elastic_transcoder/job_progressing.json +1 -1
  37. data/spec/integration/elastic_transcoder_adapter_spec.rb +87 -167
  38. data/spec/integration/matterhorn_adapter_spec.rb +34 -79
  39. data/spec/integration/shingoncoder_adapter_spec.rb +1 -1
  40. data/spec/integration/zencoder_adapter_spec.rb +1 -1
  41. data/spec/rails_helper.rb +22 -0
  42. data/spec/shared_specs/engine_adapter_specs.rb +124 -0
  43. data/spec/test_app_templates/lib/generators/test_app_generator.rb +15 -0
  44. data/spec/units/callbacks_spec.rb +16 -17
  45. data/spec/units/core_spec.rb +121 -2
  46. data/spec/units/engine_adapter_spec.rb +0 -12
  47. data/spec/units/global_id_spec.rb +49 -0
  48. data/spec/units/input_spec.rb +12 -0
  49. data/spec/units/output_spec.rb +12 -0
  50. data/spec/units/persistence_spec.rb +57 -0
  51. data/spec/units/polling_job_spec.rb +86 -0
  52. data/spec/units/polling_spec.rb +22 -0
  53. data/spec/units/status_spec.rb +21 -2
  54. metadata +89 -20
@@ -7,7 +7,7 @@ describe ActiveEncode::EngineAdapters::ShingoncoderAdapter do
7
7
  ActiveEncode::Base.engine_adapter = :shingoncoder
8
8
  end
9
9
  after(:all) do
10
- ActiveEncode::Base.engine_adapter = :inline
10
+ ActiveEncode::Base.engine_adapter = :test
11
11
  end
12
12
 
13
13
  let(:create_response) { Shingoncoder::Response.new(body: JSON.parse(File.read('spec/fixtures/zencoder/job_create.json'))) }
@@ -7,7 +7,7 @@ describe ActiveEncode::EngineAdapters::ZencoderAdapter do
7
7
  ActiveEncode::Base.engine_adapter = :zencoder
8
8
  end
9
9
  after(:all) do
10
- ActiveEncode::Base.engine_adapter = :inline
10
+ ActiveEncode::Base.engine_adapter = :test
11
11
  end
12
12
 
13
13
  let(:create_response) { Zencoder::Response.new(body: JSON.parse(File.read('spec/fixtures/zencoder/job_create.json'))) }
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ require 'engine_cart'
4
+ EngineCart.load_application!
5
+
6
+ require 'rspec/rails'
7
+ ActiveJob::Base.queue_adapter = :test
8
+
9
+ require 'database_cleaner'
10
+
11
+ RSpec.configure do |config|
12
+ config.before do |example|
13
+ if example.metadata[:db_clean]
14
+ DatabaseCleaner.clean_with(:truncation)
15
+ DatabaseCleaner.strategy = :truncation
16
+ end
17
+ end
18
+
19
+ config.after do |example|
20
+ DatabaseCleaner.clean if example.metadata[:db_clean]
21
+ end
22
+ end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
3
+ before do
4
+ raise 'adapter must be set with `let(:created_job)`' unless defined? created_job
5
+ raise 'adapter must be set with `let(:running_job)`' unless defined? running_job
6
+ raise 'adapter must be set with `let(:canceled_job)`' unless defined? canceled_job
7
+ raise 'adapter must be set with `let(:completed_job)`' unless defined? completed_job
8
+ raise 'adapter must be set with `let(:failed_job)`' unless defined? failed_job
9
+ end
10
+
11
+ it { is_expected.to respond_to :create }
12
+ it { is_expected.to respond_to :find }
13
+ it { is_expected.to respond_to :cancel }
14
+
15
+ describe "#create" do
16
+ subject { created_job }
17
+
18
+ it { is_expected.to be_a ActiveEncode::Base }
19
+ its(:id) { is_expected.not_to be_empty }
20
+ it { is_expected.to be_running }
21
+ its(:current_operations) { is_expected.to be_empty }
22
+ its(:percent_complete) { is_expected.to be < 100 }
23
+ its(:errors) { is_expected.to be_empty }
24
+ its(:created_at) { is_expected.to be_kind_of Time }
25
+ its(:updated_at) { is_expected.to be_nil }
26
+ its(:finished_at) { is_expected.to be_nil }
27
+ its(:tech_metadata) { is_expected.to be_empty }
28
+ end
29
+
30
+ describe "#find" do
31
+ context "a running encode" do
32
+ subject { running_job }
33
+
34
+ it 'returns an ActiveEncode::Base object' do
35
+ expect(subject.class).to be ActiveEncode::Base
36
+ end
37
+ its(:id) { is_expected.to eq 'running-id' }
38
+ it { is_expected.to be_running }
39
+ its(:percent_complete) { is_expected.to be > 0 }
40
+ its(:errors) { is_expected.to be_empty }
41
+ its(:created_at) { is_expected.to be_kind_of Time }
42
+ its(:updated_at) { is_expected.to be > subject.created_at }
43
+ its(:finished_at) { is_expected.to be_nil }
44
+ end
45
+
46
+ context "a cancelled encode" do
47
+ subject { canceled_job }
48
+
49
+ it 'returns an ActiveEncode::Base object' do
50
+ expect(subject.class).to be ActiveEncode::Base
51
+ end
52
+ its(:id) { is_expected.to eq 'cancelled-id' }
53
+ it { is_expected.to be_cancelled }
54
+ its(:percent_complete) { is_expected.to be > 0 }
55
+ its(:errors) { is_expected.to be_empty }
56
+ its(:created_at) { is_expected.to be_kind_of Time }
57
+ its(:finished_at) { is_expected.to be >= subject.created_at }
58
+ its(:tech_metadata) { is_expected.to be_empty }
59
+ end
60
+
61
+ context "a completed encode" do
62
+ subject { completed_job }
63
+
64
+ it 'returns an ActiveEncode::Base object' do
65
+ expect(subject.class).to be ActiveEncode::Base
66
+ end
67
+ its(:id) { is_expected.to eq 'completed-id' }
68
+ it { is_expected.to be_completed }
69
+ its(:output) { is_expected.to eq completed_output }
70
+ its(:percent_complete) { is_expected.to eq 100 }
71
+ its(:errors) { is_expected.to be_empty }
72
+ its(:created_at) { is_expected.to be_kind_of Time }
73
+ its(:updated_at) { is_expected.to be > subject.created_at }
74
+ its(:finished_at) { is_expected.to be >= subject.updated_at }
75
+ its(:tech_metadata) { is_expected.to include completed_tech_metadata }
76
+ end
77
+
78
+ context "a failed encode" do
79
+ subject { failed_job }
80
+
81
+ it 'returns an ActiveEncode::Base object' do
82
+ expect(subject.class).to be ActiveEncode::Base
83
+ end
84
+ its(:id) { is_expected.to eq 'failed-id' }
85
+ it { is_expected.to be_failed }
86
+ its(:percent_complete) { is_expected.to be > 0 }
87
+ its(:errors) { is_expected.not_to be_empty }
88
+ its(:created_at) { is_expected.to be_kind_of Time }
89
+ its(:updated_at) { is_expected.to be > subject.created_at }
90
+ its(:finished_at) { is_expected.to be >= subject.updated_at }
91
+ its(:tech_metadata) { is_expected.to include failed_tech_metadata }
92
+ end
93
+ end
94
+
95
+ describe "#cancel!" do
96
+ subject { cancelling_job.cancel! }
97
+
98
+ it 'returns an ActiveEncode::Base object' do
99
+ expect(subject.class).to be ActiveEncode::Base
100
+ end
101
+ its(:id) { is_expected.to eq 'cancelled-id' }
102
+ it { is_expected.to be_cancelled }
103
+ its(:percent_complete) { is_expected.to be > 0 }
104
+ its(:errors) { is_expected.to be_empty }
105
+ its(:created_at) { is_expected.to be_kind_of Time }
106
+ its(:finished_at) { is_expected.to be >= subject.created_at }
107
+ its(:tech_metadata) { is_expected.to be_empty }
108
+ end
109
+
110
+ describe "reload" do
111
+ subject { running_job.reload }
112
+
113
+ it 'returns an ActiveEncode::Base object' do
114
+ expect(subject.class).to be ActiveEncode::Base
115
+ end
116
+ its(:id) { is_expected.to eq 'running-id' }
117
+ it { is_expected.to be_running }
118
+ its(:percent_complete) { is_expected.to be > 0 }
119
+ its(:errors) { is_expected.to be_empty }
120
+ its(:created_at) { is_expected.to be_kind_of Time }
121
+ its(:updated_at) { is_expected.to be > subject.created_at }
122
+ its(:finished_at) { is_expected.to be_nil }
123
+ end
124
+ end
@@ -0,0 +1,15 @@
1
+ require 'rails/generators'
2
+
3
+ class TestAppGenerator < Rails::Generators::Base
4
+ source_root "./spec/test_app_templates"
5
+
6
+ # if you need to generate any additional configuration
7
+ # into the test app, this generator will be run immediately
8
+ # after setting up the application
9
+
10
+ def install_engine
11
+ generate 'active_encode:install'
12
+ rake 'active_encode:install:migrations'
13
+ end
14
+ end
15
+
@@ -3,15 +3,16 @@ require 'spec_helper'
3
3
  describe ActiveEncode::Callbacks do
4
4
  before do
5
5
  class CallbackEncode < ActiveEncode::Base
6
+ after_find ->(encode) { encode.history << "CallbackEncode ran after_find" }
7
+
8
+ after_reload ->(encode) { encode.history << "CallbackEncode ran after_reload" }
9
+
6
10
  before_create ->(encode) { encode.history << "CallbackEncode ran before_create" }
7
11
  after_create ->(encode) { encode.history << "CallbackEncode ran after_create" }
8
12
 
9
13
  before_cancel ->(encode) { encode.history << "CallbackEncode ran before_cancel" }
10
14
  after_cancel ->(encode) { encode.history << "CallbackEncode ran after_cancel" }
11
15
 
12
- before_purge ->(encode) { encode.history << "CallbackEncode ran before_purge" }
13
- after_purge ->(encode) { encode.history << "CallbackEncode ran after_purge" }
14
-
15
16
  around_create do |encode, block|
16
17
  encode.history << "CallbackEncode ran around_create_start"
17
18
  block.call
@@ -24,12 +25,6 @@ describe ActiveEncode::Callbacks do
24
25
  encode.history << "CallbackEncode ran around_cancel_stop"
25
26
  end
26
27
 
27
- around_purge do |encode, block|
28
- encode.history << "CallbackEncode ran around_purge_start"
29
- block.call
30
- encode.history << "CallbackEncode ran around_purge_stop"
31
- end
32
-
33
28
  def history
34
29
  @history ||= []
35
30
  end
@@ -40,6 +35,18 @@ describe ActiveEncode::Callbacks do
40
35
  Object.send(:remove_const, :CallbackEncode)
41
36
  end
42
37
 
38
+ describe 'find callback' do
39
+ let(:encode) { CallbackEncode.create("sample.mp4") }
40
+ subject { CallbackEncode.find(encode.id).history }
41
+ it { is_expected.to include("CallbackEncode ran after_find") }
42
+ end
43
+
44
+ describe 'reload callback' do
45
+ let(:encode) { CallbackEncode.create("sample.mp4") }
46
+ subject { encode.reload.history }
47
+ it { is_expected.to include("CallbackEncode ran after_reload") }
48
+ end
49
+
43
50
  describe 'create callbacks' do
44
51
  subject { CallbackEncode.create("sample.mp4").history }
45
52
  it { is_expected.to include("CallbackEncode ran before_create") }
@@ -55,12 +62,4 @@ describe ActiveEncode::Callbacks do
55
62
  it { is_expected.to include("CallbackEncode ran around_cancel_start") }
56
63
  it { is_expected.to include("CallbackEncode ran around_cancel_stop") }
57
64
  end
58
-
59
- describe 'purge callbacks' do
60
- subject { CallbackEncode.create("sample.mp4").purge!.history }
61
- it { is_expected.to include("CallbackEncode ran before_purge") }
62
- it { is_expected.to include("CallbackEncode ran after_purge") }
63
- it { is_expected.to include("CallbackEncode ran around_purge_start") }
64
- it { is_expected.to include("CallbackEncode ran around_purge_stop") }
65
- end
66
65
  end
@@ -1,9 +1,128 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ActiveEncode::Core do
4
+ before do
5
+ class CustomEncode < ActiveEncode::Base
6
+ end
7
+ end
8
+ after do
9
+ Object.send(:remove_const, :CustomEncode)
10
+ end
11
+
12
+ let(:encode_class) { ActiveEncode::Base }
13
+
14
+ describe 'attributes' do
15
+ subject { encode_class.new(nil) }
16
+
17
+ it { is_expected.to respond_to(:id, :input, :output, :options, :percent_complete, :current_operations) }
18
+
19
+ context 'with an ActiveEncode::Base subclass' do
20
+ let(:encode_class) { CustomEncode }
21
+
22
+ it { is_expected.to respond_to(:id, :input, :output, :options, :percent_complete, :current_operations) }
23
+ end
24
+ end
25
+
4
26
  describe 'find' do
5
- it "raises NotFound when no id is supplied" do
6
- expect { ActiveEncode::Base.find(nil) }.to raise_error(ArgumentError)
27
+ let(:id) { encode_class.create(nil).id }
28
+ subject { encode_class.find(id) }
29
+
30
+ it { is_expected.to be_a encode_class }
31
+ its(:id) { is_expected.to eq id }
32
+
33
+ context 'with no id' do
34
+ let(:id) { nil }
35
+
36
+ it 'raises an error' do
37
+ expect { subject }.to raise_error(ArgumentError)
38
+ end
39
+ end
40
+
41
+ context 'with an ActiveEncode::Base subclass' do
42
+ let(:encode_class) { CustomEncode }
43
+
44
+ it { is_expected.to be_a encode_class }
45
+ its(:id) { is_expected.to eq id }
46
+
47
+ context 'casting' do
48
+ let(:id) { ActiveEncode::Base.create(nil).id }
49
+
50
+ it { is_expected.to be_a encode_class }
51
+ its(:id) { is_expected.to eq id }
52
+ end
53
+ end
54
+ end
55
+
56
+ describe 'create' do
57
+ subject { encode_class.create(nil) }
58
+
59
+ it { is_expected.to be_a encode_class }
60
+ its(:id) { is_expected.not_to be nil }
61
+ its(:state) { is_expected.not_to be nil }
62
+
63
+ context 'with an ActiveEncode::Base subclass' do
64
+ let(:encode_class) { CustomEncode }
65
+
66
+ it { is_expected.to be_a encode_class }
67
+ its(:id) { is_expected.not_to be nil }
68
+ its(:state) { is_expected.not_to be nil }
69
+ end
70
+ end
71
+
72
+ describe '#create!' do
73
+ let(:encode) { encode_class.new(nil) }
74
+ subject { encode.create! }
75
+
76
+ it { is_expected.to equal encode }
77
+ it { is_expected.to be_a encode_class }
78
+ its(:id) { is_expected.not_to be nil }
79
+ its(:state) { is_expected.not_to be nil }
80
+
81
+ context 'with an ActiveEncode::Base subclass' do
82
+ let(:encode_class) { CustomEncode }
83
+
84
+ it { is_expected.to equal encode }
85
+ it { is_expected.to be_a encode_class }
86
+ its(:id) { is_expected.not_to be nil }
87
+ its(:state) { is_expected.not_to be nil }
88
+ end
89
+ end
90
+
91
+ describe '#cancel!' do
92
+ let(:encode) { encode_class.create(nil) }
93
+ subject { encode.cancel! }
94
+
95
+ it { is_expected.to equal encode }
96
+ it { is_expected.to be_a encode_class }
97
+ its(:id) { is_expected.not_to be nil }
98
+ it { is_expected.to be_cancelled }
99
+
100
+ context 'with an ActiveEncode::Base subclass' do
101
+ let(:encode_class) { CustomEncode }
102
+
103
+ it { is_expected.to equal encode }
104
+ it { is_expected.to be_a encode_class }
105
+ its(:id) { is_expected.not_to be nil }
106
+ it { is_expected.to be_cancelled }
107
+ end
108
+ end
109
+
110
+ describe '#reload' do
111
+ let(:encode) { encode_class.create(nil) }
112
+ subject { encode.reload }
113
+
114
+ it { is_expected.to equal encode }
115
+ it { is_expected.to be_a encode_class }
116
+ its(:id) { is_expected.not_to be nil }
117
+ its(:state) { is_expected.not_to be nil }
118
+
119
+ context 'with an ActiveEncode::Base subclass' do
120
+ let(:encode_class) { CustomEncode }
121
+
122
+ it { is_expected.to equal encode }
123
+ it { is_expected.to be_a encode_class }
124
+ its(:id) { is_expected.not_to be nil }
125
+ its(:state) { is_expected.not_to be nil }
7
126
  end
8
127
  end
9
128
  end
@@ -9,13 +9,7 @@ describe ActiveEncode::EngineAdapter do
9
9
 
10
10
  def find(_, _ = {}); end
11
11
 
12
- def list(*); end
13
-
14
12
  def cancel(_encode); end
15
-
16
- def purge(_encode); end
17
-
18
- def remove_output(_encode, _output_id); end
19
13
  end
20
14
 
21
15
  class StubTwoAdapter
@@ -23,13 +17,7 @@ describe ActiveEncode::EngineAdapter do
23
17
 
24
18
  def find(_id, _opts = {}); end
25
19
 
26
- def list(*); end
27
-
28
20
  def cancel(_encode); end
29
-
30
- def purge(_encode); end
31
-
32
- def remove_output(_encode, _output_id); end
33
21
  end
34
22
  end
35
23
  end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveEncode::GlobalID do
4
+ before do
5
+ class CustomEncode < ActiveEncode::Base
6
+ end
7
+ end
8
+
9
+ after do
10
+ Object.send(:remove_const, :CustomEncode)
11
+ end
12
+
13
+ describe '#to_global_id' do
14
+ let(:encode_class) { ActiveEncode::Base }
15
+ let(:encode) { encode_class.create(nil) }
16
+ subject { encode.to_global_id }
17
+
18
+ it { is_expected.to be_a GlobalID }
19
+ its(:model_class) { is_expected.to eq encode_class }
20
+ its(:model_id) { is_expected.to eq encode.id }
21
+ its(:app) { is_expected.to eq 'ActiveEncode' }
22
+
23
+ context 'with an ActiveEncode::Base subclass' do
24
+ let(:encode_class) { CustomEncode }
25
+
26
+ it { is_expected.to be_a GlobalID }
27
+ its(:model_class) { is_expected.to eq encode_class }
28
+ its(:model_id) { is_expected.to eq encode.id }
29
+ its(:app) { is_expected.to eq 'ActiveEncode' }
30
+ end
31
+ end
32
+
33
+ describe 'GlobalID::Locator#locate' do
34
+ let(:encode_class) { ActiveEncode::Base }
35
+ let(:encode) { encode_class.create(nil) }
36
+ let(:global_id) { encode.to_global_id }
37
+ subject { GlobalID::Locator.locate(global_id) }
38
+
39
+ it { is_expected.to be_a encode_class }
40
+ its(:id) { is_expected.to eq encode.id }
41
+
42
+ context 'with an ActiveEncode::Base subclass' do
43
+ let(:encode_class) { CustomEncode }
44
+
45
+ it { is_expected.to be_a encode_class }
46
+ its(:id) { is_expected.to eq encode.id }
47
+ end
48
+ end
49
+ end