marathon-api 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/bin/marathon +1 -1
- data/lib/marathon.rb +4 -6
- data/lib/marathon/app.rb +27 -21
- data/lib/marathon/connection.rb +11 -11
- data/lib/marathon/constraint.rb +1 -1
- data/lib/marathon/container.rb +2 -2
- data/lib/marathon/container_docker.rb +2 -2
- data/lib/marathon/container_docker_port_mapping.rb +2 -2
- data/lib/marathon/container_volume.rb +1 -1
- data/lib/marathon/deployment.rb +4 -1
- data/lib/marathon/deployment_action.rb +1 -0
- data/lib/marathon/deployment_info.rb +3 -2
- data/lib/marathon/deployment_step.rb +1 -1
- data/lib/marathon/error.rb +24 -16
- data/lib/marathon/event_subscriptions.rb +1 -1
- data/lib/marathon/group.rb +2 -1
- data/lib/marathon/health_check.rb +7 -7
- data/lib/marathon/leader.rb +1 -1
- data/lib/marathon/queue.rb +2 -1
- data/lib/marathon/task.rb +7 -3
- data/lib/marathon/util.rb +7 -7
- data/lib/marathon/version.rb +1 -1
- data/spec/marathon/app_spec.rb +58 -54
- data/spec/marathon/base_spec.rb +10 -10
- data/spec/marathon/container_docker_port_mapping_spec.rb +7 -7
- data/spec/marathon/container_docker_spec.rb +13 -13
- data/spec/marathon/container_spec.rb +9 -9
- data/spec/marathon/container_volume_spec.rb +4 -4
- data/spec/marathon/deployment_action_spec.rb +1 -1
- data/spec/marathon/deployment_info_spec.rb +2 -2
- data/spec/marathon/deployment_spec.rb +19 -19
- data/spec/marathon/deployment_step_spec.rb +4 -4
- data/spec/marathon/error_spec.rb +7 -7
- data/spec/marathon/group_spec.rb +47 -47
- data/spec/marathon/marathon_spec.rb +1 -1
- data/spec/marathon/queue_spec.rb +9 -9
- data/spec/marathon/task_spec.rb +12 -12
- data/spec/marathon/util_spec.rb +17 -17
- metadata +2 -2
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
CONTAINER_DOCKER_EXAMPLE = {
|
4
|
-
:network
|
5
|
-
:image
|
6
|
-
:privileged =>
|
7
|
-
|
4
|
+
:network => 'HOST',
|
5
|
+
:image => 'felixb/yocto-httpd',
|
6
|
+
:privileged => false
|
7
|
+
}
|
8
8
|
|
9
9
|
describe Marathon::ContainerDocker do
|
10
10
|
|
@@ -13,12 +13,12 @@ describe Marathon::ContainerDocker do
|
|
13
13
|
|
14
14
|
it 'should fail with invalid network' do
|
15
15
|
expect { subject.new(:network => 'foo', :image => 'foo') }
|
16
|
-
|
16
|
+
.to raise_error(Marathon::Error::ArgumentError, /network must be one of /)
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'should fail w/o image' do
|
20
20
|
expect { subject.new({}) }
|
21
|
-
|
21
|
+
.to raise_error(Marathon::Error::ArgumentError, /image must not be/)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -27,17 +27,17 @@ describe Marathon::ContainerDocker do
|
|
27
27
|
|
28
28
|
its(:network) { should == 'HOST' }
|
29
29
|
its(:image) { should == 'felixb/yocto-httpd' }
|
30
|
-
its(:portMappings){ should == [] }
|
31
|
-
its(:privileged){ should == false}
|
30
|
+
its(:portMappings) { should == [] }
|
31
|
+
its(:privileged) { should == false }
|
32
32
|
end
|
33
33
|
describe '#privileged' do
|
34
34
|
subject { described_class.new({
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
:network => 'HOST',
|
36
|
+
:image => 'felixb/yocto-httpd',
|
37
|
+
:privileged => true
|
38
|
+
})
|
39
39
|
}
|
40
|
-
its(:privileged){ should == true}
|
40
|
+
its(:privileged) { should == true }
|
41
41
|
end
|
42
42
|
|
43
43
|
describe '#to_s' do
|
@@ -2,15 +2,15 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
def container_helper type
|
4
4
|
return {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
5
|
+
:type => type,
|
6
|
+
:docker => {
|
7
|
+
:image => 'felixb/yocto-httpd',
|
8
|
+
:portMappings => [{:containerPort => 8080}]
|
9
|
+
},
|
10
|
+
:volumes => [{
|
11
|
+
:containerPath => '/data',
|
12
|
+
:hostPath => '/var/opt/foo'
|
13
|
+
}]
|
14
14
|
}
|
15
15
|
end
|
16
16
|
|
@@ -4,7 +4,7 @@ CONTAINER_VOLUME_EXAMPLE = {
|
|
4
4
|
:containerPath => '/data',
|
5
5
|
:hostPath => '/var/opt/foo',
|
6
6
|
:mode => 'RO'
|
7
|
-
|
7
|
+
}
|
8
8
|
|
9
9
|
describe Marathon::ContainerVolume do
|
10
10
|
|
@@ -13,14 +13,14 @@ describe Marathon::ContainerVolume do
|
|
13
13
|
|
14
14
|
it 'should fail with invalid mode' do
|
15
15
|
expect { subject.new(:containerPath => '/', :hostPath => '/', :mode => 'foo') }
|
16
|
-
|
16
|
+
.to raise_error(Marathon::Error::ArgumentError, /mode must be one of /)
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'should fail with invalid path' do
|
20
20
|
expect { subject.new(:hostPath => '/') }
|
21
|
-
|
21
|
+
.to raise_error(Marathon::Error::ArgumentError, /containerPath .* not be nil/)
|
22
22
|
expect { subject.new(:containerPath => '/') }
|
23
|
-
|
23
|
+
.to raise_error(Marathon::Error::ArgumentError, /hostPath .* not be nil/)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -1,25 +1,25 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
DEPLOYMENT_EXAMPLE = {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
4
|
+
:affectedApps => ["/test"],
|
5
|
+
:id => "867ed450-f6a8-4d33-9b0e-e11c5513990b",
|
6
|
+
:steps => [
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:action => "ScaleApplication",
|
10
|
+
:app => "/test"
|
11
|
+
}
|
12
|
+
]
|
13
|
+
],
|
14
|
+
:currentActions => [
|
15
|
+
{
|
16
|
+
:action => "ScaleApplication",
|
17
|
+
:app => "/test"
|
18
|
+
}
|
19
|
+
],
|
20
|
+
:version => "2014-08-26T08:18:03.595Z",
|
21
|
+
:currentStep => 1,
|
22
|
+
:totalSteps => 1
|
23
23
|
}
|
24
24
|
|
25
25
|
describe Marathon::Deployment do
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
DEPLOYMENT_STEP_EXAMPLE = {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
"actions" => [
|
5
|
+
{"app" => "app1", "type" => "StartApplication"},
|
6
|
+
{"app" => "app2", "type" => "StartApplication"}
|
7
|
+
]
|
8
8
|
}
|
9
9
|
|
10
10
|
describe Marathon::DeploymentStep do
|
data/spec/marathon/error_spec.rb
CHANGED
@@ -7,22 +7,22 @@ describe Marathon::Error do
|
|
7
7
|
|
8
8
|
it 'returns ClientError on 400' do
|
9
9
|
expect(subject.error_class(Net::HTTPResponse.new(1.1, 400, 'Client Error')))
|
10
|
-
|
10
|
+
.to be(Marathon::Error::ClientError)
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'returns ClientError on 422' do
|
14
14
|
expect(subject.error_class(Net::HTTPResponse.new(1.1, 422, 'Client Error')))
|
15
|
-
|
15
|
+
.to be(Marathon::Error::ClientError)
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'returns NotFoundError on 404' do
|
19
19
|
expect(subject.error_class(Net::HTTPResponse.new(1.1, 404, 'Not Found')))
|
20
|
-
|
20
|
+
.to be(Marathon::Error::NotFoundError)
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'returns UnexpectedResponseError anything else' do
|
24
24
|
expect(subject.error_class(Net::HTTPResponse.new(1.1, 599, 'Whatever')))
|
25
|
-
|
25
|
+
.to be(Marathon::Error::UnexpectedResponseError)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -30,19 +30,19 @@ describe Marathon::Error do
|
|
30
30
|
subject { described_class }
|
31
31
|
|
32
32
|
it 'returns "message" from respose json' do
|
33
|
-
r = {
|
33
|
+
r = {'message' => 'fooo'}
|
34
34
|
expect(r).to receive(:parsed_response) { r }
|
35
35
|
expect(subject.error_message(r)).to eq('fooo')
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'returns "errors" from respose json' do
|
39
|
-
r = {
|
39
|
+
r = {'errors' => 'fooo'}
|
40
40
|
expect(r).to receive(:parsed_response) { r }
|
41
41
|
expect(subject.error_message(r)).to eq('fooo')
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'returns full hash from respose json, if keys are missing' do
|
45
|
-
r = {
|
45
|
+
r = {'bars' => 'fooo'}
|
46
46
|
expect(r).to receive(:parsed_response) { r }
|
47
47
|
expect(subject.error_message(r)).to eq(r)
|
48
48
|
end
|
data/spec/marathon/group_spec.rb
CHANGED
@@ -1,42 +1,42 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
EXAMPLE_GROUP = {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
4
|
+
"id" => "/test-group",
|
5
|
+
"apps" => [
|
6
|
+
{
|
7
|
+
"backoffFactor" => 1.15,
|
8
|
+
"backoffSeconds" => 1,
|
9
|
+
"maxLaunchDelaySeconds" => 3600,
|
10
|
+
"cmd" => "sleep 30",
|
11
|
+
"constraints" => [],
|
12
|
+
"cpus" => 1.0,
|
13
|
+
"dependencies" => [],
|
14
|
+
"disk" => 0.0,
|
15
|
+
"env" => {},
|
16
|
+
"executor" => "",
|
17
|
+
"id" => "app",
|
18
|
+
"instances" => 1,
|
19
|
+
"mem" => 128.0,
|
20
|
+
"ports" => [10000],
|
21
|
+
"requirePorts" => false,
|
22
|
+
"storeUrls" => [],
|
23
|
+
"upgradeStrategy" => {
|
24
|
+
"minimumHealthCapacity" => 1.0
|
25
|
+
},
|
26
|
+
"tasks" => []
|
27
|
+
}
|
28
|
+
],
|
29
|
+
"dependencies" => [],
|
30
|
+
"groups" => []
|
31
31
|
}
|
32
32
|
|
33
33
|
describe Marathon::Group do
|
34
34
|
|
35
35
|
describe '#init' do
|
36
36
|
it 'fails with group + apps' do
|
37
|
-
expect{described_class.new({:apps => [{:id => 'app'}], :groups => [{:id => 'group'}], :id => '/foo'},
|
38
|
-
|
39
|
-
|
37
|
+
expect { described_class.new({:apps => [{:id => 'app'}], :groups => [{:id => 'group'}], :id => '/foo'},
|
38
|
+
double(Marathon::MarathonInstance)) }
|
39
|
+
.to raise_error(Marathon::Error::ArgumentError, /Group can have either/)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -48,7 +48,7 @@ describe Marathon::Group do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
let(:expected_pretty_string) do
|
51
|
-
|
51
|
+
"Group ID: /test-group\n" + \
|
52
52
|
" App ID: app\n" + \
|
53
53
|
" Instances: 0/1\n" + \
|
54
54
|
" Command: sleep 30\n" + \
|
@@ -72,8 +72,8 @@ describe Marathon::Group do
|
|
72
72
|
|
73
73
|
it 'starts the group' do
|
74
74
|
expect(@groups).to receive(:start)
|
75
|
-
|
76
|
-
|
75
|
+
.with({:dependencies => [], :id => '/group/foo'}) do
|
76
|
+
Marathon::DeploymentInfo.new({'version' => 'new-version'}, @marathon_instance)
|
77
77
|
end
|
78
78
|
expect(@subject.start!.version).to eq('new-version')
|
79
79
|
end
|
@@ -84,12 +84,12 @@ describe Marathon::Group do
|
|
84
84
|
|
85
85
|
@groups = double(Marathon::Groups)
|
86
86
|
@marathon_instance = double(Marathon::MarathonInstance, :groups => @groups)
|
87
|
-
@subject
|
87
|
+
@subject = described_class.new({'id' => '/app/foo'}, @marathon_instance)
|
88
88
|
end
|
89
89
|
|
90
90
|
it 'refreshes the group' do
|
91
91
|
expect(@groups).to receive(:get).with('/app/foo') do
|
92
|
-
described_class.new({
|
92
|
+
described_class.new({'id' => '/app/foo', 'refreshed' => true}, @marathon_instance)
|
93
93
|
end
|
94
94
|
@subject.refresh
|
95
95
|
expect(@subject.info[:refreshed]).to be(true)
|
@@ -104,26 +104,26 @@ describe Marathon::Group do
|
|
104
104
|
end
|
105
105
|
|
106
106
|
it 'changes the group' do
|
107
|
-
expect(@groups).to receive(:change).with('/app/foo', {:instances => 9000
|
107
|
+
expect(@groups).to receive(:change).with('/app/foo', {:instances => 9000}, false, false)
|
108
108
|
@subject.change!('instances' => 9000)
|
109
109
|
end
|
110
110
|
|
111
111
|
it 'changes the group and strips :version' do
|
112
|
-
expect(@groups).to receive(:change).with('/app/foo', {:instances => 9000
|
112
|
+
expect(@groups).to receive(:change).with('/app/foo', {:instances => 9000}, false, false)
|
113
113
|
@subject.change!('instances' => 9000, :version => 'old-version')
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
117
|
describe '#roll_back!' do
|
118
|
-
subject { described_class.new({
|
118
|
+
subject { described_class.new({'id' => '/app/foo', 'instances' => 10}, double(Marathon::MarathonInstance)) }
|
119
119
|
|
120
120
|
it 'changes the group' do
|
121
|
-
expect(subject).to receive(:change!).with({'version' => 'old_version'
|
121
|
+
expect(subject).to receive(:change!).with({'version' => 'old_version'}, false)
|
122
122
|
subject.roll_back!('old_version')
|
123
123
|
end
|
124
124
|
|
125
125
|
it 'changes the group with force' do
|
126
|
-
expect(subject).to receive(:change!).with({'version' => 'old_version'
|
126
|
+
expect(subject).to receive(:change!).with({'version' => 'old_version'}, true)
|
127
127
|
subject.roll_back!('old_version', true)
|
128
128
|
end
|
129
129
|
end
|
@@ -156,7 +156,7 @@ describe Marathon::Group do
|
|
156
156
|
describe '.get' do
|
157
157
|
subject { described_class }
|
158
158
|
|
159
|
-
|
159
|
+
it 'gets the group', :vcr do
|
160
160
|
group = subject.get('/test-group')
|
161
161
|
expect(group).to be_instance_of(described_class)
|
162
162
|
expect(group.id).to eq('/test-group')
|
@@ -174,15 +174,15 @@ describe Marathon::Group do
|
|
174
174
|
subject { described_class }
|
175
175
|
|
176
176
|
it 'previews changes', :vcr do
|
177
|
-
steps = subject.change('/test-group', {
|
177
|
+
steps = subject.change('/test-group', {'instances' => 20}, false, true)
|
178
178
|
expect(steps).to be_instance_of(Array)
|
179
179
|
end
|
180
180
|
|
181
181
|
it 'changes the group', :vcr do
|
182
|
-
expect(subject.change('/test-group', {
|
183
|
-
|
184
|
-
expect(subject.change('/test-group', {
|
185
|
-
|
182
|
+
expect(subject.change('/test-group', {'instances' => 2}, true))
|
183
|
+
.to be_instance_of(Marathon::DeploymentInfo)
|
184
|
+
expect(subject.change('/test-group', {'instances' => 1}, true))
|
185
|
+
.to be_instance_of(Marathon::DeploymentInfo)
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|
@@ -191,7 +191,7 @@ describe Marathon::Group do
|
|
191
191
|
|
192
192
|
it 'deletes the group', :vcr do
|
193
193
|
expect(subject.delete('/test-group', true))
|
194
|
-
|
194
|
+
.to be_instance_of(Marathon::DeploymentInfo)
|
195
195
|
end
|
196
196
|
|
197
197
|
it 'fails deleting not existing app', :vcr do
|
@@ -48,7 +48,7 @@ describe Marathon do
|
|
48
48
|
it 'adds :basic_auth options for :username and :password' do
|
49
49
|
described_class.options = {:username => 'user', :password => 'password'}
|
50
50
|
expect(described_class.connection.options)
|
51
|
-
|
51
|
+
.to eq({:basic_auth => {:username => 'user', :password => 'password'}})
|
52
52
|
|
53
53
|
# reset connection after running this spec
|
54
54
|
described_class.options = nil
|
data/spec/marathon/queue_spec.rb
CHANGED
@@ -4,9 +4,9 @@ describe Marathon::Queue do
|
|
4
4
|
|
5
5
|
describe '#attributes' do
|
6
6
|
subject { described_class.new({
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
'app' => {'id' => '/app/foo'},
|
8
|
+
'delay' => {'overdue' => true}
|
9
|
+
}, double(Marathon::MarathonInstance)) }
|
10
10
|
|
11
11
|
it 'has app' do
|
12
12
|
expect(subject.app).to be_instance_of(Marathon::App)
|
@@ -25,9 +25,9 @@ describe Marathon::Queue do
|
|
25
25
|
|
26
26
|
describe '#to_s' do
|
27
27
|
subject { described_class.new({
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
'app' => {'id' => '/app/foo'},
|
29
|
+
'delay' => {'overdue' => true}
|
30
|
+
}, double(Marathon::MarathonInstance)) }
|
31
31
|
|
32
32
|
let(:expected_string) do
|
33
33
|
'Marathon::Queue { :appId => /app/foo :delay => {:overdue=>true} }'
|
@@ -38,9 +38,9 @@ describe Marathon::Queue do
|
|
38
38
|
|
39
39
|
describe '#to_json' do
|
40
40
|
subject { described_class.new({
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
'app' => {'id' => '/app/foo'},
|
42
|
+
'delay' => {'overdue' => true}
|
43
|
+
}, double(Marathon::MarathonInstance)) }
|
44
44
|
|
45
45
|
let(:expected_string) do
|
46
46
|
'{"app":{"id":"/app/foo"},"delay":{"overdue":true}}'
|