Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions app/fetchers/app_revisions_fetcher.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
module VCAP::CloudController
class AppRevisionsFetcher
def self.fetch(app, message)
dataset = RevisionModel.where(app_guid: app.guid)
dataset = RevisionModel.where(Sequel[:revisions][:app_guid] => app.guid)

if message.requested?(:versions)
dataset = dataset.where(app_guid: app.guid, version: message.versions)
dataset = dataset.where(Sequel[:revisions][:app_guid] => app.guid, version: message.versions)
end

if message.requested?(:deployable)
dataset = dataset.join(:droplets, guid: :droplet_guid).where(Sequel[:revisions][:app_guid] => app.guid, Sequel[:droplets][:state] => DropletModel::STAGED_STATE)
end

if message.requested?(:label_selector)
Expand Down
4 changes: 4 additions & 0 deletions app/messages/app_revisions_list_message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ module VCAP::CloudController
class AppRevisionsListMessage < MetadataListMessage
register_allowed_keys [
:versions,
:deployable,
]

validates_with NoAdditionalParamsValidator

validates :versions, array: true, allow_nil: true
validates :deployable,
inclusion: { in: [true, false], message: 'must be a boolean' },
allow_nil: true

def self.from_params(params)
super(params, %w(versions))
Expand Down
8 changes: 7 additions & 1 deletion app/presenters/v3/revision_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ def to_hash
metadata: {
labels: hashified_labels(revision.labels),
annotations: hashified_annotations(revision.annotations),
}
},
deployable: deployable

}
end

Expand Down Expand Up @@ -68,6 +70,10 @@ def sidecars
}
end
end

def deployable
revision.droplet.staged?
end
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions docs/v3/source/includes/api_resources/_revisions.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
}
],
"description": "Initial revision.",
"deployable": true,
"relationships": {
"app": {
"data": {
Expand Down Expand Up @@ -81,6 +82,7 @@
}
],
"description": "Initial revision.",
"deployable": true,
"relationships": {
"app": {
"data": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Name | Type | Description
**created_at** | _datetime_ | The time with zone when the object was created.
**updated_at** | _datetime_ | The time with zone when the object was last updated.
**description** | _string_ | A short description of the reason for revision.
**deployable** _(experimental)_ | _boolean_ | Indicates if the revision's droplet is staged and the revision can be used to [create a deployment](#create-a-deployment).
**relationships.app** | [_to-one relationship_](#to-one-relationships) | The app the revision is associated with.
**metadata.labels** | [_label object_](#labels) | Labels applied to the revision.
**metadata.annotations** | [_annotation object_](#annotations) | Annotations applied to the revision.
Expand Down
10 changes: 9 additions & 1 deletion spec/request/revisions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
'command' => 'run-sidecar',
'process_types' => ['web'],
'memory_in_mb' => 300,
}]
}],
'deployable' => true
}
)
end
Expand Down Expand Up @@ -146,6 +147,7 @@
},
},
'sidecars' => [],
'deployable' => true
},
{
'guid' => revision2.guid,
Expand Down Expand Up @@ -181,6 +183,7 @@
},
},
'sidecars' => [],
'deployable' => true
}
]
}
Expand Down Expand Up @@ -244,6 +247,7 @@
},
},
'sidecars' => [],
'deployable' => true
},
{
'guid' => revision3.guid,
Expand Down Expand Up @@ -279,6 +283,7 @@
},
},
'sidecars' => [],
'deployable' => true
}
]
}
Expand Down Expand Up @@ -367,6 +372,7 @@
},
},
'sidecars' => [],
'deployable' => true
}
)
end
Expand Down Expand Up @@ -461,6 +467,7 @@
},
},
'sidecars' => [],
'deployable' => true
},
{
'guid' => revision2.guid,
Expand Down Expand Up @@ -496,6 +503,7 @@
},
},
'sidecars' => [],
'deployable' => true
}
]
}
Expand Down
19 changes: 16 additions & 3 deletions spec/unit/fetchers/app_revisions_fetcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ module VCAP::CloudController
RSpec.describe AppRevisionsFetcher do
let(:fetcher) { AppRevisionsFetcher }
let!(:app) { AppModel.make }
let!(:revision1) { RevisionModel.make(version: 21, app: app) }
let!(:revision2) { RevisionModel.make(version: 34, app: app) }

let(:expired_droplet) { DropletModel.make(:droplet, app: app, state: DropletModel::EXPIRED_STATE) }
let(:staged_droplet) { DropletModel.make(:droplet, app: app, state: DropletModel::STAGED_STATE) }

let!(:revision1) { RevisionModel.make(version: 21, droplet_guid: staged_droplet.guid, app: app) }
let!(:revision2) { RevisionModel.make(version: 34, droplet_guid: expired_droplet.guid, app: app) }

describe '#fetch' do
let(:message) { AppRevisionsListMessage.from_params(filters) }
Expand All @@ -20,7 +24,7 @@ module VCAP::CloudController
end
end

context 'when the revisions are filtered' do
context 'when the revisions are filtered on version' do
let(:filters) { { versions: [revision1.version] } }

it 'returns all of the desired revisions' do
Expand All @@ -29,6 +33,15 @@ module VCAP::CloudController
end
end

context 'when the revisions are filtered on deployable' do
let(:filters) { { deployable: true } }

it 'returns all of the desired revisions' do
expect(subject).to include(revision1)
expect(subject).to_not include(revision2)
end
end

context 'when a label_selector is provided' do
let(:message) { AppRevisionsListMessage.from_params({ 'label_selector' => 'key=value' }) }
let!(:revision1label) { RevisionLabelModel.make(key_name: 'key', value: 'value', revision: revision1) }
Expand Down
19 changes: 18 additions & 1 deletion spec/unit/messages/app_revisions_list_message_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module VCAP::CloudController
'page' => 1,
'per_page' => 5,
'label_selector' => 'key=value',
'deployable' => true
}
end

Expand All @@ -20,6 +21,7 @@ module VCAP::CloudController
expect(message.page).to eq(1)
expect(message.per_page).to eq(5)
expect(message.versions).to eq(['1', '3'])
expect(message.deployable).to eq(true)
expect(message.label_selector).to eq('key=value')
end

Expand All @@ -29,6 +31,7 @@ module VCAP::CloudController
expect(message.requested?(:page)).to be_truthy
expect(message.requested?(:per_page)).to be_truthy
expect(message.requested?(:versions)).to be_truthy
expect(message.requested?(:deployable)).to be_truthy
expect(message.requested?(:label_selector)).to be_truthy
end
end
Expand All @@ -55,7 +58,8 @@ module VCAP::CloudController
AppRevisionsListMessage.from_params({
page: 1,
per_page: 5,
versions: ['1'],
versions: ['1'],
deployable: true,
label_selector: 'key=value',
})
}.not_to raise_error
Expand Down Expand Up @@ -88,6 +92,19 @@ module VCAP::CloudController
end
end

context 'deployable' do
it 'validates deployable to be a boolean' do
message = AppRevisionsListMessage.from_params(deployable: 'not a boolean')
expect(message).to be_invalid
expect(message.errors[:deployable]).to include('must be a boolean')
end

it 'allows deployable to be nil' do
message = AppRevisionsListMessage.from_params(deployable: nil)
expect(message).to be_valid
end
end

it 'validates metadata requirements' do
message = AppRevisionsListMessage.from_params('label_selector' => '')

Expand Down
18 changes: 18 additions & 0 deletions spec/unit/presenters/v3/revision_presenter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,24 @@ module VCAP::CloudController::Presenters::V3
expect(result[:sidecars][0][:memory_in_mb]).to eq(300)
expect(result[:sidecars][0][:process_types]).to eq(['web'])
expect(result[:description]).to eq('Initial revision')
expect(result[:deployable]).to eq(true)
end

context 'when the droplet is not staged' do
let(:droplet) do
VCAP::CloudController::DropletModel.make(
app: app_model,
state: VCAP::CloudController::DropletModel::EXPIRED_STATE,
process_types: {
'web' => 'droplet_web_command',
'worker' => 'droplet_worker_command',
})
end

it 'returns deployable is false' do
result = RevisionPresenter.new(revision).to_hash
expect(result[:deployable]).to eq(false)
end
end
end
end
Expand Down