Skip to content
Open
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
264 changes: 106 additions & 158 deletions spec/migrations/20190712210940_backfill_status_for_deployments_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,169 +12,117 @@

let(:app) { VCAP::CloudController::AppModel.make }

context 'when a deployment has state DEPLOYED' do
let!(:deployment_with_state_deployed) do
VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-deployed',
state: VCAP::CloudController::DeploymentModel::DEPLOYED_STATE,
app: app,
original_web_process_instance_count: 1
)
end

it 'sets status_value to FINALIZED without changing the state' do
Sequel::Migrator.run(VCAP::CloudController::DeploymentModel.db, tmp_migrations_dir, table: :my_fake_table)
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_with_state_deployed.guid).first

expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::DEPLOYED_STATE)
expect(deployment.status_value).to eq(VCAP::CloudController::DeploymentModel::FINALIZED_STATUS_VALUE)
expect(deployment.status_reason).to be_nil
end
end
it 'backfills status_value based on deployment state' do
# Create all deployment variations
deployment_deployed = VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-deployed',
state: VCAP::CloudController::DeploymentModel::DEPLOYED_STATE,
app: app,
original_web_process_instance_count: 1
)

context 'when a deployment has state CANCELED' do
let!(:deployment_with_state_canceled) do
VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-canceled',
state: VCAP::CloudController::DeploymentModel::CANCELED_STATE,
app: app,
original_web_process_instance_count: 1
)
end

it 'sets status_value to FINALIZED without changing the state' do
Sequel::Migrator.run(VCAP::CloudController::DeploymentModel.db, tmp_migrations_dir, table: :my_fake_table)
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_with_state_canceled.guid).first

expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::CANCELED_STATE)
expect(deployment.status_value).to eq(VCAP::CloudController::DeploymentModel::FINALIZED_STATUS_VALUE)
expect(deployment.status_reason).to be_nil
end
end
deployment_canceled = VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-canceled',
state: VCAP::CloudController::DeploymentModel::CANCELED_STATE,
app: app,
original_web_process_instance_count: 1
)

context 'when a deployment has state FAILED' do
let!(:deployment_with_state_failed) do
VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-failed',
state: 'FAILED',
app: app,
original_web_process_instance_count: 1
)
end

it 'sets status_value to FINALIZED without changing the state' do
Sequel::Migrator.run(VCAP::CloudController::DeploymentModel.db, tmp_migrations_dir, table: :my_fake_table)
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_with_state_failed.guid).first

expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::DEPLOYED_STATE)
expect(deployment.status_value).to eq(VCAP::CloudController::DeploymentModel::FINALIZED_STATUS_VALUE)
expect(deployment.status_reason).to be_nil
end
end
deployment_failed = VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-failed',
state: 'FAILED',
app: app,
original_web_process_instance_count: 1
)

context 'when a deployment has state DEPLOYING' do
let!(:deployment_with_state_deploying) do
VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-deploying',
state: VCAP::CloudController::DeploymentModel::DEPLOYING_STATE,
app: app,
original_web_process_instance_count: 1
)
end

it 'sets status_value to DEPLOYING without changing the state' do
Sequel::Migrator.run(VCAP::CloudController::DeploymentModel.db, tmp_migrations_dir, table: :my_fake_table)
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_with_state_deploying.guid).first

expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::DEPLOYING_STATE)
expect(deployment.status_value).to eq('DEPLOYING')
expect(deployment.status_reason).to be_nil
end
end
deployment_deploying = VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-deploying',
state: VCAP::CloudController::DeploymentModel::DEPLOYING_STATE,
app: app,
original_web_process_instance_count: 1
)

context 'when a deployment has state CANCELING' do
let!(:deployment_with_state_canceling) do
VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-canceling',
state: VCAP::CloudController::DeploymentModel::CANCELING_STATE,
app: app,
original_web_process_instance_count: 1
)
end

it 'sets status_value to DEPLOYING without changing the state' do
Sequel::Migrator.run(VCAP::CloudController::DeploymentModel.db, tmp_migrations_dir, table: :my_fake_table)
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_with_state_canceling.guid).first

expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::CANCELING_STATE)
expect(deployment.status_value).to eq('DEPLOYING')
expect(deployment.status_reason).to be_nil
end
end
deployment_canceling = VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-canceling',
state: VCAP::CloudController::DeploymentModel::CANCELING_STATE,
app: app,
original_web_process_instance_count: 1
)

context 'when a deployment has state FAILING' do
let!(:deployment_with_state_failing) do
VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-failing',
state: 'FAILING',
app: app,
original_web_process_instance_count: 1
)
end

it 'sets status_value to DEPLOYING without changing the state' do
Sequel::Migrator.run(VCAP::CloudController::DeploymentModel.db, tmp_migrations_dir, table: :my_fake_table)
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_with_state_failing.guid).first

expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::DEPLOYING_STATE)
expect(deployment.status_value).to eq('DEPLOYING')
expect(deployment.status_reason).to be_nil
end
end
deployment_failing = VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-failing',
state: 'FAILING',
app: app,
original_web_process_instance_count: 1
)

deployment_with_existing_status = VCAP::CloudController::DeploymentModel.create(
guid: 'with-existing-status',
state: VCAP::CloudController::DeploymentModel::DEPLOYED_STATE,
status_value: 'foo',
status_reason: 'bar',
app: app,
original_web_process_instance_count: 1
)

deployment_failing_with_reason = VCAP::CloudController::DeploymentModel.create(
guid: 'failing-with-reason',
state: 'FAILING',
status_value: 'foo',
status_reason: 'bar',
app: app,
original_web_process_instance_count: 1
)

context 'when the deployment already has a status' do
context 'when the deployment has state DEPLOYED' do
let!(:deployment_with_state_deployed) do
VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-deployed',
state: VCAP::CloudController::DeploymentModel::DEPLOYED_STATE,
status_value: 'foo',
status_reason: 'bar',
app: app,
original_web_process_instance_count: 1
)
end

it 'does not reset the status value' do
Sequel::Migrator.run(VCAP::CloudController::DeploymentModel.db, tmp_migrations_dir, table: :my_fake_table)
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_with_state_deployed.guid).first

expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::DEPLOYED_STATE)
expect(deployment.status_value).to eq('foo')
expect(deployment.status_reason).to eq('bar')
end
end

context 'when the deployment has state FAILING' do
let!(:deployment_with_state_failing) do
VCAP::CloudController::DeploymentModel.create(
guid: 'with-state-deployed',
state: 'FAILING',
status_value: 'foo',
status_reason: 'bar',
app: app,
original_web_process_instance_count: 1
)
end

it 'does not reset the status reason' do
Sequel::Migrator.run(VCAP::CloudController::DeploymentModel.db, tmp_migrations_dir, table: :my_fake_table)
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_with_state_failing.guid).first

expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::DEPLOYING_STATE)
expect(deployment.status_value).to eq('DEPLOYING')
expect(deployment.status_reason).to eq('bar')
end
end
# Run migration once
Sequel::Migrator.run(VCAP::CloudController::DeploymentModel.db, tmp_migrations_dir, table: :my_fake_table)

# Test: DEPLOYED state -> FINALIZED status
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_deployed.guid).first
expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::DEPLOYED_STATE)
expect(deployment.status_value).to eq(VCAP::CloudController::DeploymentModel::FINALIZED_STATUS_VALUE)
expect(deployment.status_reason).to be_nil

# Test: CANCELED state -> FINALIZED status
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_canceled.guid).first
expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::CANCELED_STATE)
expect(deployment.status_value).to eq(VCAP::CloudController::DeploymentModel::FINALIZED_STATUS_VALUE)
expect(deployment.status_reason).to be_nil

# Test: FAILED state -> DEPLOYED state + FINALIZED status
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_failed.guid).first
expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::DEPLOYED_STATE)
expect(deployment.status_value).to eq(VCAP::CloudController::DeploymentModel::FINALIZED_STATUS_VALUE)
expect(deployment.status_reason).to be_nil

# Test: DEPLOYING state -> DEPLOYING status
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_deploying.guid).first
expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::DEPLOYING_STATE)
expect(deployment.status_value).to eq('DEPLOYING')
expect(deployment.status_reason).to be_nil

# Test: CANCELING state -> DEPLOYING status
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_canceling.guid).first
expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::CANCELING_STATE)
expect(deployment.status_value).to eq('DEPLOYING')
expect(deployment.status_reason).to be_nil

# Test: FAILING state -> DEPLOYING state + DEPLOYING status
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_failing.guid).first
expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::DEPLOYING_STATE)
expect(deployment.status_value).to eq('DEPLOYING')
expect(deployment.status_reason).to be_nil

# Test: existing status_value is not reset
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_with_existing_status.guid).first
expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::DEPLOYED_STATE)
expect(deployment.status_value).to eq('foo')
expect(deployment.status_reason).to eq('bar')

# Test: existing status_reason is preserved
deployment = VCAP::CloudController::DeploymentModel.where(guid: deployment_failing_with_reason.guid).first
expect(deployment.state).to eq(VCAP::CloudController::DeploymentModel::DEPLOYING_STATE)
expect(deployment.status_value).to eq('DEPLOYING')
expect(deployment.status_reason).to eq('bar')
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,35 @@
end

describe 'annotation tables' do
it 'converts all legacy key_prefixes to annotations with prefixes in the key_prefix column' do
db[:isolation_segments].insert(name: 'bommel', guid: '123')
db[:isolation_segment_annotations].insert(
guid: 'bommel',
created_at: Time.now - 60,
updated_at: Time.now - 60,
resource_guid: '123',
key: 'mylegacyprefix/mykey',
value: 'some_value'
)
a1 = db[:isolation_segment_annotations].first(resource_guid: '123')
expect { Sequel::Migrator.run(db, migrations_path, target: current_migration_index, allow_missing_migration_files: true) }.not_to raise_error
b1 = db[:isolation_segment_annotations].first(resource_guid: '123')
expect(b1[:guid]).to eq a1[:guid]
expect(b1[:created_at]).to eq a1[:created_at]
expect(b1[:updated_at]).not_to eq a1[:updated_at]
expect(b1[:resource_guid]).to eq a1[:resource_guid]
expect(b1[:key_prefix]).not_to eq a1[:key_prefix]
expect(b1[:key]).not_to eq a1[:key]
expect(b1[:key_prefix]).to eq 'mylegacyprefix'
expect(b1[:key]).to eq 'mykey'
end
it 'converts legacy key_prefixes to prefixes in key_prefix column and leaves non-legacy values unchanged' do
resource_guid = 'iso-seg-guid'
db[:isolation_segments].insert(name: 'iso_seg', guid: resource_guid)
db[:isolation_segment_annotations].insert(guid: 'anno-1-guid', resource_guid: resource_guid, key: 'mylegacyprefix/mykey', value: 'some_value')
db[:isolation_segment_annotations].insert(guid: 'anno-2-guid', resource_guid: resource_guid, key_prefix: 'myprefix', key: 'mykey', value: 'some_value')
db[:isolation_segment_annotations].insert(guid: 'anno-3-guid', resource_guid: resource_guid, key: 'yourkey', value: 'some_other_value')

anno1 = db[:isolation_segment_annotations].first(guid: 'anno-1-guid')
anno2 = db[:isolation_segment_annotations].first(key: 'mykey')
anno3 = db[:isolation_segment_annotations].first(key: 'yourkey')

it 'doesnt touch any values that have no legacy key_prefix in its key field' do
db[:isolation_segments].insert(name: 'bommel', guid: '123')
db[:isolation_segment_annotations].insert(guid: 'bommel', resource_guid: '123', key_prefix: 'myprefix', key: 'mykey', value: 'some_value')
db[:isolation_segment_annotations].insert(guid: 'bommel2', resource_guid: '123', key: 'mykey2', value: 'some_value2')
b1 = db[:isolation_segment_annotations].first(key: 'mykey')
b2 = db[:isolation_segment_annotations].first(key: 'mykey2')
expect { Sequel::Migrator.run(db, migrations_path, target: current_migration_index, allow_missing_migration_files: true) }.not_to raise_error
c1 = db[:isolation_segment_annotations].first(key: 'mykey')
c2 = db[:isolation_segment_annotations].first(key: 'mykey2')
expect(b1.values).to eq(c1.values)
expect(b2.values).to eq(c2.values)

# Check legacy prefix was converted
anno1_after_mig = db[:isolation_segment_annotations].first(guid: 'anno-1-guid')
expect(anno1_after_mig[:guid]).to eq anno1[:guid]
expect(anno1_after_mig[:created_at]).to eq anno1[:created_at]
expect(anno1_after_mig[:updated_at]).not_to eq anno1[:updated_at]
expect(anno1_after_mig[:resource_guid]).to eq anno1[:resource_guid]
expect(anno1_after_mig[:key_prefix]).not_to eq anno1[:key_prefix]
expect(anno1_after_mig[:key]).not_to eq anno1[:key]
expect(anno1_after_mig[:key_prefix]).to eq 'mylegacyprefix'
expect(anno1_after_mig[:key]).to eq 'mykey'

# Check non-legacy values unchanged
anno2_after_mig = db[:isolation_segment_annotations].first(guid: 'anno-2-guid')
anno3_after_mig = db[:isolation_segment_annotations].first(guid: 'anno-3-guid')
expect(anno2.values).to eq(anno2_after_mig.values)
expect(anno3.values).to eq(anno3_after_mig.values)
end
end
end
Loading