2020-03-27 08:07:43 -04:00
# frozen_string_literal: true
require 'spec_helper'
2020-06-24 02:09:01 -04:00
RSpec . describe Terraform :: State do
2020-11-23 07:09:11 -05:00
subject { create ( :terraform_state , :with_version ) }
2020-03-27 08:07:43 -04:00
2020-09-16 08:10:15 -04:00
it { is_expected . to belong_to ( :project ) }
2020-04-21 11:21:10 -04:00
it { is_expected . to belong_to ( :locked_by_user ) . class_name ( 'User' ) }
2021-01-28 13:09:27 -05:00
it { is_expected . to validate_presence_of ( :name ) }
2020-03-27 08:07:43 -04:00
it { is_expected . to validate_presence_of ( :project_id ) }
2021-01-28 13:09:27 -05:00
it { is_expected . to validate_uniqueness_of ( :name ) . scoped_to ( :project_id ) }
2020-09-30 08:09:53 -04:00
describe 'scopes' do
describe '.ordered_by_name' do
let_it_be ( :project ) { create ( :project ) }
2021-06-28 23:07:32 -04:00
2020-09-30 08:09:53 -04:00
let ( :names ) { %w( state_d state_b state_a state_c ) }
subject { described_class . ordered_by_name }
before do
names . each do | name |
create ( :terraform_state , project : project , name : name )
end
end
it { expect ( subject . map ( & :name ) ) . to eq ( names . sort ) }
end
2021-01-20 19:11:07 -05:00
describe '.with_name' do
let_it_be ( :matching_name ) { create ( :terraform_state , name : 'matching-name' ) }
let_it_be ( :other_name ) { create ( :terraform_state , name : 'other-name' ) }
subject { described_class . with_name ( matching_name . name ) }
it { is_expected . to contain_exactly ( matching_name ) }
end
2020-09-30 08:09:53 -04:00
end
2021-01-05 19:10:23 -05:00
describe '#destroy' do
let ( :terraform_state ) { create ( :terraform_state ) }
let ( :user ) { terraform_state . project . creator }
it 'deletes when the state is unlocked' do
expect ( terraform_state . destroy ) . to be_truthy
end
it 'fails to delete when the state is locked' , :aggregate_failures do
terraform_state . update! ( lock_xid : SecureRandom . uuid , locked_by_user : user , locked_at : Time . current )
expect ( terraform_state . destroy ) . to be_falsey
expect ( terraform_state . errors . full_messages ) . to eq ( [ " You cannot remove the State file because it's locked. Unlock the State file first before removing it. " ] )
end
end
2020-09-16 08:10:15 -04:00
describe '#latest_file' do
2020-11-23 07:09:11 -05:00
let ( :terraform_state ) { create ( :terraform_state , :with_version ) }
let ( :latest_version ) { terraform_state . latest_version }
2020-09-16 08:10:15 -04:00
2020-11-23 07:09:11 -05:00
subject { terraform_state . latest_file }
2020-09-16 08:10:15 -04:00
2020-11-23 07:09:11 -05:00
it { is_expected . to eq latest_version . file }
2020-10-13 05:08:27 -04:00
2020-11-23 07:09:11 -05:00
context 'but no version exists yet' do
let ( :terraform_state ) { create ( :terraform_state ) }
2020-10-13 05:08:27 -04:00
2020-11-23 07:09:11 -05:00
it { is_expected . to be_nil }
2020-09-16 08:10:15 -04:00
end
end
describe '#update_file!' do
2020-10-25 20:09:02 -04:00
let_it_be ( :build ) { create ( :ci_build ) }
let_it_be ( :version ) { 3 }
let_it_be ( :data ) { Hash [ terraform_version : '0.12.21' ] . to_json }
2020-09-16 08:10:15 -04:00
2020-10-25 20:09:02 -04:00
subject { terraform_state . update_file! ( CarrierWaveStringFile . new ( data ) , version : version , build : build ) }
2020-09-16 08:10:15 -04:00
context 'versioning is enabled' do
let ( :terraform_state ) { create ( :terraform_state ) }
it 'creates a new version' do
expect { subject } . to change { Terraform :: StateVersion . count }
expect ( terraform_state . latest_version . version ) . to eq ( version )
2020-10-25 20:09:02 -04:00
expect ( terraform_state . latest_version . build ) . to eq ( build )
2020-09-16 08:10:15 -04:00
expect ( terraform_state . latest_version . file . read ) . to eq ( data )
end
end
2020-11-23 07:09:11 -05:00
context 'versioning is disabled (migration to versioned in progress)' do
let ( :terraform_state ) { create ( :terraform_state , versioning_enabled : false ) }
let! ( :migrated_version ) { create ( :terraform_state_version , terraform_state : terraform_state , version : 0 ) }
2020-09-16 08:10:15 -04:00
2020-11-23 07:09:11 -05:00
it 'creates a new version, corrects the migrated version number, and marks the state as versioned' do
expect { subject } . to change { Terraform :: StateVersion . count }
2020-10-13 05:08:27 -04:00
2020-11-23 07:09:11 -05:00
expect ( migrated_version . reload . version ) . to eq ( 1 )
expect ( migrated_version . file . read ) . to eq ( fixture_file ( 'terraform/terraform.tfstate' ) )
2020-10-13 05:08:27 -04:00
2020-11-23 07:09:11 -05:00
expect ( terraform_state . reload . latest_version . version ) . to eq ( version )
expect ( terraform_state . latest_version . file . read ) . to eq ( data )
expect ( terraform_state ) . to be_versioning_enabled
end
2020-10-13 05:08:27 -04:00
2020-11-23 07:09:11 -05:00
context 'the current version cannot be determined' do
before do
migrated_version . update! ( file : CarrierWaveStringFile . new ( 'invalid-json' ) )
2020-10-13 05:08:27 -04:00
end
2020-11-23 07:09:11 -05:00
it 'uses version - 1 to correct the migrated version number' do
expect { subject } . to change { Terraform :: StateVersion . count }
2020-10-13 05:08:27 -04:00
2020-11-23 07:09:11 -05:00
expect ( migrated_version . reload . version ) . to eq ( 2 )
2020-10-13 05:08:27 -04:00
end
end
2020-09-16 08:10:15 -04:00
end
end
2020-03-27 08:07:43 -04:00
end