kensa 1.2.0rc7 → 1.2.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.
- data/.gitignore +1 -1
- data/Gemfile +5 -4
- data/Gemfile.lock +21 -27
- data/README.md +1 -1
- data/Rakefile +18 -10
- data/bin/kensa +10 -30
- data/kensa.gemspec +27 -20
- data/lib/heroku/kensa.rb +7 -9
- data/lib/heroku/kensa/check.rb +499 -0
- data/lib/heroku/kensa/client.rb +67 -89
- data/lib/heroku/kensa/git.rb +39 -0
- data/lib/heroku/kensa/manifest.rb +41 -8
- data/lib/heroku/kensa/screen.rb +37 -0
- data/lib/heroku/kensa/sso.rb +22 -22
- data/lib/heroku/kensa/version.rb +1 -2
- data/test/all_check_test.rb +25 -0
- data/test/create_test.rb +40 -6
- data/test/deprovision_check_test.rb +39 -0
- data/test/helper.rb +74 -11
- data/test/init_test.rb +54 -0
- data/test/manifest_check_test.rb +94 -0
- data/test/manifest_test.rb +37 -33
- data/test/plan_change_check_test.rb +31 -0
- data/test/provision_check_test.rb +51 -0
- data/test/provision_response_check_test.rb +81 -0
- data/test/resources/runner.rb +1 -0
- data/test/resources/server.rb +227 -0
- data/test/sso_check_test.rb +58 -0
- data/test/sso_test.rb +113 -53
- metadata +97 -91
- data/test.rb +0 -1
- data/test/deprovision_test.rb +0 -30
- data/test/lib/dependencies.rb +0 -12
- data/test/lib/formatter.rb +0 -84
- data/test/lib/http.rb +0 -60
- data/test/lib/response.rb +0 -12
- data/test/manifest_generation_test.rb +0 -32
- data/test/plan_change_test.rb +0 -30
- data/test/provision_test.rb +0 -84
- data/test/resources/provider_server.rb +0 -81
- data/test/resources/views/index.haml +0 -6
- data/test/sso_launch_test.rb +0 -130
data/lib/heroku/kensa/version.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test/helper'
|
2
|
+
|
3
|
+
class AllCheckTest < Test::Unit::TestCase
|
4
|
+
include Heroku::Kensa
|
5
|
+
|
6
|
+
setup do
|
7
|
+
@data = Manifest.new(:method => :get).skeleton
|
8
|
+
@data['api']['password'] = 'secret'
|
9
|
+
@data['api']['test'] += "working"
|
10
|
+
@file = File.dirname(__FILE__) + "/resources/runner.rb"
|
11
|
+
end
|
12
|
+
|
13
|
+
def check; AllCheck; end
|
14
|
+
|
15
|
+
test "valid on script exit 0" do
|
16
|
+
@data[:args] = ["ruby #{@file}"]
|
17
|
+
assert_valid
|
18
|
+
end
|
19
|
+
|
20
|
+
test "invalid on script exit non 0" do
|
21
|
+
@data[:args] = ["ruby #{@file} fail"]
|
22
|
+
assert_invalid
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/test/create_test.rb
CHANGED
@@ -1,12 +1,46 @@
|
|
1
|
-
|
2
|
-
require 'test/lib/dependencies'
|
1
|
+
require 'test/helper'
|
3
2
|
|
4
3
|
class CreateTest < Test::Unit::TestCase
|
5
|
-
|
6
|
-
|
4
|
+
include Heroku::Kensa
|
5
|
+
|
6
|
+
def setup
|
7
|
+
stub(Git).run
|
8
|
+
any_instance_of Client do |client|
|
9
|
+
stub(client).init
|
10
|
+
end
|
11
|
+
stub(Dir).chdir
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_requires_app_name
|
15
|
+
assert_raise Client::CommandInvalid do
|
16
|
+
kensa "create my_addon"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_requires_template
|
21
|
+
assert_raise Client::CommandInvalid do
|
22
|
+
kensa "create --template foo"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_assumes_heroku_template
|
27
|
+
kensa "create my_addon --template sinatra"
|
28
|
+
assert_received Git do |git|
|
29
|
+
git.run("git clone git://github.com/heroku/kensa-create-sinatra my_addon")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_assumes_github
|
34
|
+
kensa "create my_addon --template heroku/sinatra"
|
35
|
+
assert_received Git do |git|
|
36
|
+
git.run("git clone git://github.com/heroku/sinatra my_addon")
|
37
|
+
end
|
7
38
|
end
|
8
39
|
|
9
|
-
def
|
10
|
-
kensa "create"
|
40
|
+
def test_allows_full_url
|
41
|
+
kensa "create my_addon --template git://heroku.com/sinatra.git"
|
42
|
+
assert_received Git do |git|
|
43
|
+
git.run("git clone git://heroku.com/sinatra.git my_addon")
|
44
|
+
end
|
11
45
|
end
|
12
46
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test/helper'
|
2
|
+
|
3
|
+
class DeprovisionCheckTest < Test::Unit::TestCase
|
4
|
+
include Heroku::Kensa
|
5
|
+
|
6
|
+
%w{get post}.each do |method|
|
7
|
+
context "with SSO #{method}" do
|
8
|
+
setup do
|
9
|
+
@data = Manifest.new(:method => method).skeleton.merge :id => 123
|
10
|
+
@responses = [
|
11
|
+
[200, ""],
|
12
|
+
[401, ""],
|
13
|
+
]
|
14
|
+
end
|
15
|
+
|
16
|
+
def check ; DeprovisionCheck ; end
|
17
|
+
|
18
|
+
test "valid on 200" do
|
19
|
+
assert_valid do |check|
|
20
|
+
kensa_stub :delete, check, @responses
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
test "status other than 200" do
|
25
|
+
@responses[0] = [500, ""]
|
26
|
+
assert_invalid do |check|
|
27
|
+
kensa_stub :delete, check, @responses
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
test "runs auth check" do
|
32
|
+
@responses[1] = [200, ""]
|
33
|
+
assert_invalid do |check|
|
34
|
+
kensa_stub :delete, check, @responses
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/test/helper.rb
CHANGED
@@ -1,21 +1,84 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'heroku/kensa'
|
2
|
+
require 'heroku/kensa/client'
|
3
|
+
require 'contest'
|
3
4
|
require 'timecop'
|
4
5
|
require 'rr'
|
5
|
-
require '
|
6
|
-
require 'lib/heroku/kensa'
|
7
|
-
require 'test/resources/provider_server'
|
6
|
+
require 'yajl'
|
8
7
|
|
9
8
|
class Test::Unit::TestCase
|
10
9
|
include RR::Adapters::TestUnit
|
11
10
|
|
12
|
-
def
|
13
|
-
|
14
|
-
Artifice.activate_with(ProviderServer.new(manifest))
|
11
|
+
def kensa(command)
|
12
|
+
Heroku::Kensa::Client.new(command.split, :silent => true).run!
|
15
13
|
end
|
16
14
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
15
|
+
def read_json(filename)
|
16
|
+
Yajl::Parser.parse(File.open(filename).read)
|
17
|
+
end
|
18
|
+
|
19
|
+
#this prepends a prefix for the provider server
|
20
|
+
#in test/resources/server.rb
|
21
|
+
def use_provider_endpoint(name, type = 'base')
|
22
|
+
if @data['api']['test'].is_a? Hash
|
23
|
+
url = @data['api']['test']["#{type}_url"]
|
24
|
+
path = URI.parse(url).path
|
25
|
+
@data['api']['test']["#{type}_url"] = url.sub(path, "/#{name}#{path}")
|
26
|
+
else
|
27
|
+
@data['api']['test'] += "#{name}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def trace!
|
32
|
+
@screen = Heroku::Kensa::IOScreen.new(STDOUT)
|
33
|
+
end
|
34
|
+
|
35
|
+
def screen
|
36
|
+
@screen ||= Heroku::Kensa::IOScreen.new(StringIO.new("", 'w+'))
|
37
|
+
end
|
38
|
+
|
39
|
+
# call trace! in your test before the
|
40
|
+
# assert to see the output
|
41
|
+
def assert_valid(data=@data, &blk)
|
42
|
+
check = create_check(data, &blk)
|
43
|
+
result = check.call
|
44
|
+
assert result, screen.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def assert_invalid(data=@data, &blk)
|
48
|
+
check = create_check(data, &blk)
|
49
|
+
result = check.call
|
50
|
+
assert !result, screen.to_s
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_check(data, &blk)
|
54
|
+
check = self.check.new(data, screen)
|
55
|
+
blk.call(check) if blk
|
56
|
+
check
|
57
|
+
end
|
58
|
+
|
59
|
+
module Headerize
|
60
|
+
attr_accessor :headers
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_json(data, headers={})
|
64
|
+
body = Yajl::Encoder.encode(data)
|
65
|
+
add_headers(body, headers)
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_headers(o, headers={})
|
69
|
+
o.extend Headerize
|
70
|
+
o.headers = {}
|
71
|
+
o.headers["Content-Type"] ||= "application/json"
|
72
|
+
o.headers.merge!(headers)
|
73
|
+
o
|
74
|
+
end
|
75
|
+
|
76
|
+
def kensa_stub(meth, o, returns)
|
77
|
+
o.instance_eval { @returns = Array(returns) }
|
78
|
+
eval <<-EVAL
|
79
|
+
def o.#{meth}(*args)
|
80
|
+
@returns.shift or fail("Nothing else to return from stub'ed method")
|
81
|
+
end
|
82
|
+
EVAL
|
20
83
|
end
|
21
84
|
end
|
data/test/init_test.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'test/helper'
|
2
|
+
require 'fakefs/safe'
|
3
|
+
|
4
|
+
class InitTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
FakeFS.activate!
|
7
|
+
@filename = 'addon-manifest.json'
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
File.unlink(@filename) if @filename && File.exist?(@filename)
|
12
|
+
FakeFS.deactivate!
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_init_default_so_sso_post
|
16
|
+
kensa "init"
|
17
|
+
manifest = read_json(@filename)
|
18
|
+
%w{test production}.each do |env|
|
19
|
+
%w{base_url sso_url}.each do |url|
|
20
|
+
assert manifest['api'][env][url] =~ /^http/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
assert !File.exist?('.env')
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_init_uses_file_flag
|
27
|
+
@filename = 'foo.json'
|
28
|
+
|
29
|
+
kensa "init -f #{@filename}"
|
30
|
+
assert !File.exist?('./addon-manifest.json')
|
31
|
+
assert !File.exist?('.env')
|
32
|
+
manifest = read_json(@filename)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_init_uses_sso_flag
|
36
|
+
kensa "init --sso get"
|
37
|
+
manifest = read_json(@filename)
|
38
|
+
%w{test production}.each do |env|
|
39
|
+
assert manifest['api'][env] =~ /^http/
|
40
|
+
end
|
41
|
+
assert !File.exist?('.env')
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_init_with_env_flag
|
45
|
+
kensa "init --foreman"
|
46
|
+
env = File.open(".env").read
|
47
|
+
manifest = read_json(@filename)
|
48
|
+
assert manifest['api']['test']['base_url'] =~ /:5000/
|
49
|
+
assert manifest['api']['test']['sso_url'] =~ /:5000/
|
50
|
+
assert env.include?("SSO_SALT=#{manifest['api']['sso_salt']}\n")
|
51
|
+
assert env.include?("HEROKU_USERNAME=#{manifest['id']}\n")
|
52
|
+
assert env.include?("HEROKU_PASSWORD=#{manifest['api']['password']}")
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'test/helper'
|
2
|
+
|
3
|
+
class ManifestCheckTest < Test::Unit::TestCase
|
4
|
+
include Heroku::Kensa
|
5
|
+
|
6
|
+
def check ; ManifestCheck ; end
|
7
|
+
|
8
|
+
%w{get post}.each do |method|
|
9
|
+
context "with sso #{method}" do
|
10
|
+
setup { @data = Manifest.new(:method => method).skeleton }
|
11
|
+
|
12
|
+
test "is valid if no errors" do
|
13
|
+
assert_valid
|
14
|
+
end
|
15
|
+
|
16
|
+
test "has an id" do
|
17
|
+
@data.delete("id")
|
18
|
+
assert_invalid
|
19
|
+
end
|
20
|
+
|
21
|
+
test "api key exists" do
|
22
|
+
@data.delete("api")
|
23
|
+
assert_invalid
|
24
|
+
end
|
25
|
+
|
26
|
+
test "api is a Hash" do
|
27
|
+
@data["api"] = ""
|
28
|
+
assert_invalid
|
29
|
+
end
|
30
|
+
|
31
|
+
test "api has a password" do
|
32
|
+
@data["api"].delete("password")
|
33
|
+
assert_invalid
|
34
|
+
end
|
35
|
+
|
36
|
+
test "api contains test" do
|
37
|
+
@data["api"].delete("test")
|
38
|
+
assert_invalid
|
39
|
+
end
|
40
|
+
|
41
|
+
test "api contains production" do
|
42
|
+
@data["api"].delete("production")
|
43
|
+
assert_invalid
|
44
|
+
end
|
45
|
+
|
46
|
+
test "api contains production of https" do
|
47
|
+
if method == 'get'
|
48
|
+
@data["api"]["production"] = "http://foo.com"
|
49
|
+
else
|
50
|
+
@data["api"]["production"]['base_url'] = "http://foo.com"
|
51
|
+
end
|
52
|
+
assert_invalid
|
53
|
+
end
|
54
|
+
|
55
|
+
if method == 'post'
|
56
|
+
test "sso contains production of https" do
|
57
|
+
@data["api"]["production"]['sso_url'] = "http://foo.com"
|
58
|
+
assert_invalid
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
test "api contains config_vars array" do
|
63
|
+
@data["api"]["config_vars"] = "test"
|
64
|
+
assert_invalid
|
65
|
+
end
|
66
|
+
|
67
|
+
test "api contains at least one config var" do
|
68
|
+
@data["api"]["config_vars"].clear
|
69
|
+
assert_invalid
|
70
|
+
end
|
71
|
+
|
72
|
+
test "all config vars are in upper case" do
|
73
|
+
@data["api"]["config_vars"] << 'MYADDON_invalid_var'
|
74
|
+
assert_invalid
|
75
|
+
end
|
76
|
+
|
77
|
+
test "assert config var prefixes match addon id" do
|
78
|
+
@data["api"]["config_vars"] << 'MONGO_URL'
|
79
|
+
assert_invalid
|
80
|
+
end
|
81
|
+
|
82
|
+
test "replaces dashes for underscores on the config var check" do
|
83
|
+
@data["id"] = "MY-ADDON"
|
84
|
+
@data["api"]["config_vars"] = ["MY_ADDON_URL"]
|
85
|
+
assert_valid
|
86
|
+
end
|
87
|
+
|
88
|
+
test "username is deprecated" do
|
89
|
+
@data["api"]["username"] = "heroku"
|
90
|
+
assert_invalid
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/test/manifest_test.rb
CHANGED
@@ -1,51 +1,55 @@
|
|
1
|
-
$:.unshift(File.expand_path("../..",__FILE__))
|
2
1
|
require 'test/helper'
|
2
|
+
|
3
3
|
class ManifestTest < Test::Unit::TestCase
|
4
|
+
include Heroku::Kensa
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
end
|
6
|
+
context 'GET manifest' do
|
7
|
+
setup { @manifest = Manifest.new(:method => :get) }
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
9
|
+
test 'have sso salt' do
|
10
|
+
assert_not_nil @manifest.skeleton['api']['sso_salt']
|
11
|
+
end
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
test 'generates a new sso salt every time' do
|
14
|
+
assert @manifest.skeleton['api']['sso_salt'] != Manifest.new.skeleton['api']['sso_salt']
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
test 'has an api password' do
|
18
|
+
assert_not_nil @manifest.skeleton['api']['password']
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
test 'generates a new password every time' do
|
22
|
+
assert @manifest.skeleton['api']['password'] != Manifest.new.skeleton['api']['password']
|
23
|
+
end
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
else
|
30
|
-
url = manifest["api"]["production"]
|
25
|
+
test 'uses get format' do
|
26
|
+
assert_equal @manifest.skeleton['api']['test'], 'http://localhost:4567/'
|
27
|
+
assert_equal @manifest.skeleton['api']['production'], 'https://yourapp.com/'
|
31
28
|
end
|
32
|
-
assert url.match(%r{\Ahttps://}), "Production environment must communicate over HTTPS."
|
33
29
|
end
|
34
30
|
|
35
|
-
|
36
|
-
manifest
|
37
|
-
|
31
|
+
context "POST manifest" do
|
32
|
+
setup { @manifest = Manifest.new(:method => :post) }
|
33
|
+
|
34
|
+
test 'uses post format for test url' do
|
35
|
+
assert_equal @manifest.skeleton['api']['test']['base_url'], 'http://localhost:4567/heroku/resources'
|
36
|
+
assert_equal @manifest.skeleton['api']['test']['sso_url'], 'http://localhost:4566/sso/login'
|
38
37
|
end
|
39
|
-
end
|
40
38
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
assert var.match(%r{\A#{id}_}), "All config vars must be prefixed with the add-on ID (#{id}), #{var} is not."
|
39
|
+
test 'uses post format for test url' do
|
40
|
+
assert_equal @manifest.skeleton['api']['production']['base_url'], 'https://yourapp.com/heroku/resources'
|
41
|
+
assert_equal @manifest.skeleton['api']['production']['sso_url'], 'https://yourapp.com/sso/login'
|
45
42
|
end
|
46
43
|
end
|
47
44
|
|
48
|
-
|
49
|
-
|
45
|
+
context 'manifest without sso' do
|
46
|
+
setup do
|
47
|
+
options = { :sso => false, :filename => 'test.txt' }
|
48
|
+
@manifest = Manifest.new options
|
49
|
+
end
|
50
|
+
|
51
|
+
test 'exclude sso salt' do
|
52
|
+
assert_nil @manifest.skeleton['api']['sso_salt']
|
53
|
+
end
|
50
54
|
end
|
51
55
|
end
|