Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add deployment tracking models #749

Merged
merged 1 commit into from
Dec 15, 2022
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
3 changes: 3 additions & 0 deletions app/models/district.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ class District < ActiveRecord::Base
has_many :endpoints, inverse_of: :district, dependent: :destroy
has_many :notifications, inverse_of: :district, dependent: :destroy

has_many :services, through: :heritages
has_many :service_deployments, through: :services

validates :name, presence: true, uniqueness: true, immutable: true
validates :region, :s3_bucket_name, :stack_name, :cidr_block, presence: true, immutable: true
validates :nat_type, inclusion: {in: %w[instance managed_gateway managed_gateway_multi_az]}, allow_nil: true
Expand Down
1 change: 1 addition & 0 deletions app/models/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class Service < ActiveRecord::Base
belongs_to :heritage, inverse_of: :services
has_many :listeners, inverse_of: :service, dependent: :destroy
has_many :port_mappings, inverse_of: :service, dependent: :destroy
has_many :service_deployments, inverse_of: :service, dependent: :destroy

serialize :hosts, JSON
serialize :health_check, JSON
Expand Down
37 changes: 37 additions & 0 deletions app/models/service_deployment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class ServiceDeployment < ApplicationRecord
belongs_to :service

validates :service, presence: true
validate :finished_cannot_both_be_true

def finished_cannot_both_be_true
if completed_at.present? && failed_at.present?
errors.add(:completed_at, "can't be true with failed_at")
end
end

scope :unfinished, -> { where('completed_at is null and failed_at is null') }

def finished?
completed? || failed?
end

def completed?
!completed_at.nil?
end

def failed?
!failed_at.nil?
end

def complete!
self.completed_at = Time.now
self.save!
end

def fail!
self.failed_at = Time.now
self.save!
end

end
13 changes: 13 additions & 0 deletions db/migrate/20221208045503_create_service_deployments.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class CreateServiceDeployments < ActiveRecord::Migration[5.2]
def change
create_table :service_deployments do |t|
t.references :service, foreign_key: true, null: false
t.datetime :completed_at
t.datetime :failed_at

t.timestamps
end

add_index :service_deployments, [:completed_at, :failed_at]
end
end
13 changes: 12 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2020_11_13_090000) do
ActiveRecord::Schema.define(version: 2022_12_08_045503) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -182,6 +182,16 @@
t.index ["token"], name: "index_review_groups_on_token", unique: true
end

create_table "service_deployments", force: :cascade do |t|
t.bigint "service_id", null: false
t.datetime "completed_at"
t.datetime "failed_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["completed_at", "failed_at"], name: "index_service_deployments_on_completed_at_and_failed_at"
t.index ["service_id"], name: "index_service_deployments_on_service_id"
end

create_table "services", force: :cascade do |t|
t.string "name", null: false
t.integer "cpu"
Expand Down Expand Up @@ -236,6 +246,7 @@
add_foreign_key "review_apps", "heritages"
add_foreign_key "review_apps", "review_groups"
add_foreign_key "review_groups", "endpoints"
add_foreign_key "service_deployments", "services"
add_foreign_key "services", "heritages"
add_foreign_key "users_districts", "districts"
add_foreign_key "users_districts", "users"
Expand Down
5 changes: 5 additions & 0 deletions spec/factories/service_deployments.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FactoryBot.define do
factory :service_deployment do
service
end
end
57 changes: 57 additions & 0 deletions spec/models/district_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,61 @@
district.publish_sns("message")
end
end

describe '#services' do
it 'finds the services for the current district' do
d1 = create :district, name: 'd1'
d1h1 = create :heritage, district: d1, name: 'd1h1'
d1h1s1 = create :service, heritage: d1h1, name: 'd1h1s1'
d1h1s2 = create :service, heritage: d1h1, name: 'd1h1s2'
d1h1s3 = create :service, heritage: d1h1, name: 'd1h1s3'

d1h2 = create :heritage, district: d1, name: 'd1h2'
d1h2s1 = create :service, heritage: d1h2, name: 'd1h2s1'
d1h2s2 = create :service, heritage: d1h2, name: 'd1h2s2'

d2 = create :district, name: 'd2'
d2h1 = create :heritage, district: d2, name: 'd2h1'
d2h1s1 = create :service, heritage: d2h1, name: 'd2h1s1'
d2h1s2 = create :service, heritage: d2h1, name: 'd2h1s2'

d2h2 = create :heritage, district: d2, name: 'd2h2'
d2h2s1 = create :service, heritage: d2h2, name: 'd2h2s1'
d2h2s2 = create :service, heritage: d2h2, name: 'd2h2s2'

expect(d1.services).to eq [d1h1s1, d1h1s2, d1h1s3, d1h2s1, d1h2s2]
expect(d2.services).to eq [d2h1s1, d2h1s2, d2h2s1, d2h2s2]
end
end

describe '#service_deployments' do
it 'finds the service deployments for the current district' do
d1 = create :district, name: 'd1'
d1h1 = create :heritage, district: d1, name: 'd1h1'
d1h1s1 = create :service, heritage: d1h1, name: 'd1h1s1'

dep1 = create :service_deployment, service: d1h1s1

d1h1s2 = create :service, heritage: d1h1, name: 'd1h1s2'
d1h1s3 = create :service, heritage: d1h1, name: 'd1h1s3'

dep2 = create :service_deployment, service: d1h1s3

d1h2 = create :heritage, district: d1, name: 'd1h2'
d1h2s1 = create :service, heritage: d1h2, name: 'd1h2s1'
d1h2s2 = create :service, heritage: d1h2, name: 'd1h2s2'

d2 = create :district, name: 'd2'
d2h1 = create :heritage, district: d2, name: 'd2h1'
d2h1s1 = create :service, heritage: d2h1, name: 'd2h1s1'
d2h1s2 = create :service, heritage: d2h1, name: 'd2h1s2'

d2h2 = create :heritage, district: d2, name: 'd2h2'
d2h2s1 = create :service, heritage: d2h2, name: 'd2h2s1'
d2h2s2 = create :service, heritage: d2h2, name: 'd2h2s2'

expect(d1.service_deployments).to eq [dep1, dep2]
end
end

end
100 changes: 100 additions & 0 deletions spec/models/service_deployment_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
require 'rails_helper'

describe ServiceDeployment do

it { should validate_presence_of :service }

describe 'both completed and failed true' do
it 'will not be valid' do
sd = build :service_deployment, completed_at: DateTime.now, failed_at: DateTime.now
expect(sd).to_not be_valid
end
end

describe '#completed?' do
it 'returns true if completed' do
sd = create :service_deployment, completed_at: DateTime.now
expect(sd).to be_completed
end

it 'returns false if not completed' do
sd = create :service_deployment, completed_at: nil
expect(sd).to_not be_completed
end
end

describe '#failed?' do
it 'returns true if failed' do
sd = create :service_deployment, failed_at: DateTime.now
expect(sd).to be_failed
end

it 'returns false if not failed' do
sd = create :service_deployment, failed_at: nil
expect(sd).to_not be_failed
end
end

describe '#finished?' do
it 'returns true if completed' do
sd = create :service_deployment, completed_at: DateTime.now
expect(sd).to be_finished
end

it 'returns true if failed' do
sd = create :service_deployment, failed_at: DateTime.now
expect(sd).to be_finished
end

it 'returns false if not failed or completed' do
sd = create :service_deployment, failed_at: nil, completed_at: nil
expect(sd).to_not be_finished
end
end

let(:example_time) { Time.zone.local(2004, 11, 24, 01, 04, 44) }
describe 'fail!' do
it 'sets failed' do
sd = create :service_deployment
expect(sd).to_not be_failed
sd.fail!
expect(sd).to be_failed
end

it 'sets failed_at to current time' do
travel_to example_time do
sd = create :service_deployment
expect(sd.failed_at).to be_nil
sd.fail!
expect(sd.failed_at).to eq example_time
end
end
end

describe 'complete!' do
it 'sets completed' do
sd = create :service_deployment
expect(sd).to_not be_completed
sd.complete!
expect(sd).to be_completed
end

it 'sets completed_at to current time' do
travel_to example_time do
sd = create :service_deployment
expect(sd.completed_at).to be_nil
sd.complete!
expect(sd.completed_at).to eq example_time
end
end
end

describe '.unfinished' do
it 'returns unfinished deployments' do
sd1 = create :service_deployment, completed_at: nil
sd2 = create :service_deployment, completed_at: DateTime.now

expect(ServiceDeployment.unfinished).to eq [sd1]
end
end
end
14 changes: 14 additions & 0 deletions spec/models/service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,18 @@
end
end
end

describe '#service_deployments' do
it 'finds the service deployments for the current district' do
s1 = create :service
s1d1 = create :service_deployment, service: s1
s1d2 = create :service_deployment, service: s1

s2 = create :service
s2d1 = create :service_deployment, service: s2

expect(s1.service_deployments).to eq [s1d1, s1d2]
expect(s2.service_deployments).to eq [s2d1]
end
end
end