heroku_hatchet 7.1.1 → 7.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,9 +1,15 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe "GitAppTest" do
4
- it "can deploy git app" do
5
- Hatchet::GitApp.new("rails5_ruby_schema_format").deploy do |app|
6
- expect(app.run("ruby -v")).to match("2.6.6")
4
+ it "can deploy git app to the main branch" do
5
+ Hatchet::GitApp.new("lock_fail_main", allow_failure: true).deploy do |app|
6
+ expect(app.output).to match("INTENTIONAL ERROR")
7
7
  end
8
8
  end
9
+
10
+ it "returns the correct branch name on circle CI" do
11
+ skip("only runs on circle") unless ENV["CIRCLE_BRANCH"]
12
+
13
+ expect(Hatchet.git_branch).to eq(ENV["CIRCLE_BRANCH"])
14
+ end
9
15
  end
@@ -13,14 +13,15 @@ describe "LocalRepoTest" do
13
13
 
14
14
  it "repos checked into git" do
15
15
  begin
16
- app = Hatchet::App.new("repo_fixtures/different-folder-for-checked-in-repos/default_ruby")
17
- app.in_directory do
18
- expect(Dir.exist?(".git")).to eq(false)
19
- app.setup!
20
- expect(Dir.exist?(".git")).to eq(true)
16
+ fixture_dir = "repo_fixtures/different-folder-for-checked-in-repos/default_ruby"
17
+ app = Hatchet::App.new(fixture_dir)
18
+ def app.push_with_retry!; end
19
+
20
+ expect(Dir.exist?("#{fixture_dir}/.git")).to be_falsey
21
+
22
+ app.deploy do
23
+ expect(Dir.exist?(".git")).to be_truthy
21
24
  end
22
- ensure
23
- app.teardown! if app
24
25
  end
25
26
  end
26
27
  end
@@ -57,7 +57,7 @@ describe "isolated lock tests" do
57
57
  end
58
58
 
59
59
  dir.join("hatchet.lock").open("w+") do |f|
60
- f.puts <<~EOM
60
+ f.puts <<-EOM.strip_heredoc
61
61
  ---
62
62
  - - "./repos/foo/lock_fail_main_default_is_master"
63
63
  - main
@@ -14,7 +14,8 @@ RSpec.configure do |config|
14
14
  end
15
15
  end
16
16
 
17
- ENV['HATCHET_BUILDPACK_BRANCH'] = "master"
17
+ ENV['HATCHET_BUILDPACK_BASE'] = "https://github.com/heroku/heroku-buildpack-ruby.git"
18
+ ENV['HATCHET_BUILDPACK_BRANCH'] = "main"
18
19
 
19
20
  require 'parallel_tests/test/runtime_logger' if ENV['RECORD_RUNTIME']
20
21
 
@@ -0,0 +1,115 @@
1
+ require "spec_helper"
2
+
3
+ describe "HerokuRun" do
4
+ def fake_app
5
+ app = Object.new
6
+ def app.name; "fake_app"; end
7
+ app
8
+ end
9
+
10
+ describe "options" do
11
+ it "escapes by default" do
12
+ run_obj = Hatchet::HerokuRun.new("ruby -v", app: fake_app)
13
+ expect(run_obj.command).to eq("heroku run --app=fake_app --exit-code -- ruby\\ -v")
14
+ end
15
+
16
+ it "escapes by default" do
17
+ run_obj = Hatchet::HerokuRun.new("ruby -v", app: fake_app, heroku: { "exit-code" => Hatchet::App::SkipDefaultOption })
18
+ expect(run_obj.command).to eq("heroku run --app=fake_app -- ruby\\ -v")
19
+ end
20
+
21
+ it "allows setting switch values by default" do
22
+ run_obj = Hatchet::HerokuRun.new("ruby -v", app: fake_app, heroku: { "no-tty" => nil })
23
+ expect(run_obj.command).to eq("heroku run --app=fake_app --exit-code --no-tty -- ruby\\ -v")
24
+ end
25
+
26
+ it "can be used to pass env vars" do
27
+ run_obj = Hatchet::HerokuRun.new("ruby -v", app: fake_app, heroku: { "env" => "HELLO=ohai;NAME=world" })
28
+ expect(run_obj.command).to eq("heroku run --app=fake_app --exit-code --env=HELLO\\=ohai\\;NAME\\=world -- ruby\\ -v")
29
+ end
30
+
31
+
32
+ it "lets me use raw values" do
33
+ run_obj = Hatchet::HerokuRun.new("ruby -v", app: fake_app, raw: true )
34
+ expect(run_obj.command).to eq("heroku run --app=fake_app --exit-code -- ruby -v")
35
+ end
36
+ end
37
+
38
+ describe "retry on empty" do
39
+ before(:all) do
40
+ @app = Hatchet::Runner.new("default_ruby")
41
+ @app.setup!
42
+ end
43
+
44
+ after(:all) do
45
+ @app.teardown!
46
+ end
47
+
48
+ it "retries 3 times on empty result" do
49
+ stderr = StringIO.new
50
+ run_obj = Hatchet::HerokuRun.new("ruby -v", app: @app, stderr: stderr)
51
+
52
+ def run_obj.run_shell!
53
+ @output = ""
54
+ @status = Object.new
55
+ end
56
+
57
+ run_obj.call
58
+
59
+ expect(run_obj.instance_variable_get(:@empty_fail_count)).to eq(3)
60
+ expect(stderr.string).to include("retrying the command.")
61
+ end
62
+
63
+ it "retries 0 times on NON empty result" do
64
+ stderr = StringIO.new
65
+ run_obj = Hatchet::HerokuRun.new("ruby -v", app: @app, stderr: stderr)
66
+
67
+ def run_obj.run_shell!
68
+ @output = "not empty"
69
+ @status = Object.new
70
+ end
71
+
72
+ run_obj.call
73
+
74
+ expect(run_obj.instance_variable_get(:@empty_fail_count)).to eq(0)
75
+ expect(run_obj.output).to eq("not empty")
76
+ end
77
+
78
+ it "retries 0 times on empty result when disabled" do
79
+ stderr = StringIO.new
80
+ run_obj = Hatchet::HerokuRun.new("ruby -v", app: @app, stderr: stderr, retry_on_empty: false)
81
+
82
+ def run_obj.run_shell!
83
+ @output = ""
84
+ @status = Object.new
85
+ end
86
+
87
+ run_obj.call
88
+
89
+ expect(run_obj.instance_variable_get(:@empty_fail_count)).to eq(0)
90
+ expect(stderr.string).to_not include("retrying the command.")
91
+ end
92
+
93
+ it "retries 0 times on empty result when disabled via ENV var" do
94
+ begin
95
+ original_env = ENV["HATCHET_DISABLE_EMPTY_RUN_RETRY"]
96
+ ENV["HATCHET_DISABLE_EMPTY_RUN_RETRY"] = "1"
97
+ stderr = StringIO.new
98
+ run_obj = Hatchet::HerokuRun.new("ruby -v", app: @app, stderr: stderr)
99
+
100
+ def run_obj.run_shell!
101
+ @output = ""
102
+ @status = Object.new
103
+ end
104
+
105
+ run_obj.call
106
+
107
+ expect(run_obj.instance_variable_get(:@empty_fail_count)).to eq(0)
108
+ expect(stderr.string).to_not include("retrying the command.")
109
+ ensure
110
+ ENV["HATCHET_DISABLE_EMPTY_RUN_RETRY"] = original_env
111
+ end
112
+ end
113
+ end
114
+ end
115
+
@@ -0,0 +1,52 @@
1
+ require "spec_helper"
2
+
3
+ describe "Hatchet::Init" do
4
+ def fake_buildpack_dir
5
+ Dir.mktmpdir do |dir|
6
+ FileUtils.mkdir_p("#{dir}/bin")
7
+ yield dir
8
+ end
9
+ end
10
+ it "raises an error when not pointing at the right directory" do
11
+ Dir.mktmpdir do |dir|
12
+ expect {
13
+ Hatchet::InitProject.new(dir: dir)
14
+ }.to raise_error(/Must run in a directory with a buildpack/)
15
+ end
16
+ end
17
+
18
+ # write_target(target: ".circleci/config.yml", template: "circleci_template.erb")
19
+ # write_target(target: "Gemfile", template: "Gemfile.erb")
20
+ # write_target(target: "hatchet.json", contents: "{}")
21
+ # write_target(target: "hatchet.lock", contents: YAML.dump({}))
22
+ # write_target(target: "spec/spec_helper.rb", template: "spec_helper.erb")
23
+ # write_target(target: "spec/hatchet/buildpack_spec.rb", template: "buildpack_spec.erb")
24
+ # write_target(target: ".github/dependabot.yml", template: "dependabot.erb")
25
+
26
+ it "generates files" do
27
+ fake_buildpack_dir do |dir|
28
+ fake_stdout = StringIO.new
29
+ init = Hatchet::InitProject.new(dir: dir, io: fake_stdout)
30
+ init.call
31
+
32
+ circle_ci_file = Pathname.new(dir).join(".circleci/config.yml")
33
+ expect(circle_ci_file.read).to match("parallel_split_test")
34
+
35
+ %W{
36
+ .circleci/config.yml
37
+ Gemfile
38
+ hatchet.json
39
+ hatchet.lock
40
+ spec/spec_helper.rb
41
+ spec/hatchet/buildpack_spec.rb
42
+ .github/dependabot.yml
43
+ .github/workflows/check_changelog.yml
44
+ .gitignore
45
+ }.each do |path|
46
+ expect(Pathname.new(dir).join(path)).to exist
47
+ end
48
+
49
+ expect(fake_stdout.string).to match("Bundle complete")
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,94 @@
1
+ require "spec_helper"
2
+
3
+ describe "ShellThrottle" do
4
+ before(:each) do
5
+ throttle = PlatformAPI.rate_throttle
6
+ def throttle.sleep(value)
7
+ # No sleep, faster tests
8
+ end
9
+ end
10
+
11
+ after(:each) do
12
+ throttle = PlatformAPI.rate_throttle
13
+ def throttle.sleep(value)
14
+ super # Unstub
15
+ end
16
+ end
17
+
18
+ describe "class unit test" do
19
+ before(:all) do
20
+ @platform_api = Hatchet::Runner.new("default_ruby").platform_api
21
+ end
22
+
23
+ it "throttles when throw is called" do
24
+ @count = 0
25
+ Hatchet::ShellThrottle.new(platform_api: @platform_api).call do
26
+ @count += 1
27
+ if @count >= 2
28
+ # No throttle
29
+ else
30
+ throw(:throttle)
31
+ end
32
+ end
33
+ expect(@count).to eq(2)
34
+ end
35
+
36
+ it "does not throttle when throw is NOT called" do
37
+ @count = 0
38
+ Hatchet::ShellThrottle.new(platform_api: @platform_api).call do
39
+ @count += 1
40
+ end
41
+ expect(@count).to eq(1)
42
+ end
43
+ end
44
+
45
+ describe "git push throttle" do
46
+ it "rate throttles `git push` " do
47
+ app = Hatchet::GitApp.new("default_ruby")
48
+ def app.git_push_heroku_yall
49
+ @_git_push_heroku_yall_call_count ||= 0
50
+ @_git_push_heroku_yall_call_count += 1
51
+ if @_git_push_heroku_yall_call_count >= 2
52
+ "Success"
53
+ else
54
+ raise Hatchet::App::FailedDeployError.new(
55
+ self,
56
+ "message",
57
+ output: "Your account reached the API rate limit Please wait a few minutes before making new requests"
58
+ )
59
+ end
60
+ end
61
+
62
+ def app.sleep_called?; @sleep_called; end
63
+ def app.what_is_git_push_heroku_yall_call_count; @_git_push_heroku_yall_call_count; end
64
+
65
+ app.push_without_retry!
66
+
67
+ expect(app.what_is_git_push_heroku_yall_call_count).to be(2)
68
+ end
69
+
70
+ it "rate throttles `git push` with different output" do
71
+ app = Hatchet::GitApp.new("default_ruby")
72
+ def app.git_push_heroku_yall
73
+ @_git_push_heroku_yall_call_count ||= 0
74
+ @_git_push_heroku_yall_call_count += 1
75
+ if @_git_push_heroku_yall_call_count >= 2
76
+ "Success"
77
+ else
78
+ raise Hatchet::App::FailedDeployError.new(
79
+ self,
80
+ "message",
81
+ output: "RPC failed; HTTP 429 curl 22 The requested URL returned error: 429 Too Many Requests"
82
+ )
83
+ end
84
+ end
85
+
86
+ def app.sleep_called?; @sleep_called; end
87
+ def app.what_is_git_push_heroku_yall_call_count; @_git_push_heroku_yall_call_count; end
88
+
89
+ app.push_without_retry!
90
+
91
+ expect(app.what_is_git_push_heroku_yall_call_count).to be(2)
92
+ end
93
+ end
94
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heroku_hatchet
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.1
4
+ version: 7.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Schneeman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-02 00:00:00.000000000 Z
11
+ date: 2020-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: platform-api
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '1'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '1'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: threaded
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -136,20 +136,6 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: travis
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '1'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '1'
153
139
  - !ruby/object:Gem::Dependency
154
140
  name: rspec-retry
155
141
  requirement: !ruby/object:Gem::Requirement
@@ -192,11 +178,20 @@ files:
192
178
  - lib/hatchet/app.rb
193
179
  - lib/hatchet/config.rb
194
180
  - lib/hatchet/git_app.rb
181
+ - lib/hatchet/heroku_run.rb
182
+ - lib/hatchet/init_project.rb
195
183
  - lib/hatchet/reaper.rb
196
184
  - lib/hatchet/reaper/app_age.rb
197
185
  - lib/hatchet/reaper/reaper_throttle.rb
198
186
  - lib/hatchet/shell_throttle.rb
199
187
  - lib/hatchet/tasks.rb
188
+ - lib/hatchet/templates/Gemfile.erb
189
+ - lib/hatchet/templates/buildpack_spec.erb
190
+ - lib/hatchet/templates/check_changelog.erb
191
+ - lib/hatchet/templates/circleci_template.erb
192
+ - lib/hatchet/templates/dependabot.erb
193
+ - lib/hatchet/templates/hatchet_json.erb
194
+ - lib/hatchet/templates/spec_helper.erb
200
195
  - lib/hatchet/test_run.rb
201
196
  - lib/hatchet/version.rb
202
197
  - repo_fixtures/different-folder-for-checked-in-repos/default_ruby/Gemfile
@@ -211,8 +206,10 @@ files:
211
206
  - spec/hatchet/local_repo_spec.rb
212
207
  - spec/hatchet/lock_spec.rb
213
208
  - spec/spec_helper.rb
209
+ - spec/unit/heroku_run_spec.rb
210
+ - spec/unit/init_spec.rb
214
211
  - spec/unit/reaper_spec.rb
215
- - spec/unit/shell_throttle.rb
212
+ - spec/unit/shell_throttle_spec.rb
216
213
  - tmp/parallel_runtime_test.log
217
214
  homepage: https://github.com/heroku/hatchet
218
215
  licenses:
@@ -226,14 +223,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
226
223
  requirements:
227
224
  - - ">="
228
225
  - !ruby/object:Gem::Version
229
- version: '0'
226
+ version: 2.2.0
230
227
  required_rubygems_version: !ruby/object:Gem::Requirement
231
228
  requirements:
232
229
  - - ">="
233
230
  - !ruby/object:Gem::Version
234
231
  version: '0'
235
232
  requirements: []
236
- rubygems_version: 3.1.2
233
+ rubygems_version: 3.1.4
237
234
  signing_key:
238
235
  specification_version: 4
239
236
  summary: Hatchet is a an integration testing library for developing Heroku buildpacks.
@@ -248,5 +245,7 @@ test_files:
248
245
  - spec/hatchet/local_repo_spec.rb
249
246
  - spec/hatchet/lock_spec.rb
250
247
  - spec/spec_helper.rb
248
+ - spec/unit/heroku_run_spec.rb
249
+ - spec/unit/init_spec.rb
251
250
  - spec/unit/reaper_spec.rb
252
- - spec/unit/shell_throttle.rb
251
+ - spec/unit/shell_throttle_spec.rb
@@ -1,28 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "ShellThrottle" do
4
- it "throttles when throw is called" do
5
- platform_api = Hatchet::Runner.new("default_ruby").platform_api
6
-
7
- @count = 0
8
- Hatchet::ShellThrottle.new(platform_api: platform_api).call do
9
- @count += 1
10
- if @count >= 2
11
- # No throttle
12
- else
13
- throw(:throttle)
14
- end
15
- end
16
- expect(@count).to eq(2)
17
- end
18
-
19
- it "does not throttle when throw is NOT called" do
20
- platform_api = Hatchet::Runner.new("default_ruby").platform_api
21
-
22
- @count = 0
23
- Hatchet::ShellThrottle.new(platform_api: platform_api).call do
24
- @count += 1
25
- end
26
- expect(@count).to eq(1)
27
- end
28
- end