Commit 7f09a474 authored by Thong Kuah's avatar Thong Kuah

Merge branch 'add-deploy-board-spec' into 'master'

Add Spec for Existing Deploy Boards Behavior

See merge request gitlab-org/gitlab!43364
parents 14025583 8921946c
......@@ -28,7 +28,7 @@ module EE
pods = filter_by_project_environment(data[:pods], project.full_path_slug, environment.slug)
legacy_deployments = filter_by_legacy_label(data[:deployments], project.full_path_slug, environment.slug)
::Gitlab::Kubernetes::RolloutStatus.from_deployments(*deployments, pods: pods, legacy_deployments: legacy_deployments)
::Gitlab::Kubernetes::RolloutStatus.from_deployments(*deployments, pods_attrs: pods, legacy_deployments: legacy_deployments)
end
private
......
......@@ -7,7 +7,7 @@ module Gitlab
STABLE_TRACK_VALUE = 'stable'.freeze
def initialize(attributes = {}, pods: {})
def initialize(attributes = {}, pods: [])
@attributes = attributes
@pods = pods
end
......
......@@ -30,10 +30,10 @@ module Gitlab
@status == :found
end
def self.from_deployments(*deployments, pods: {}, legacy_deployments: [])
def self.from_deployments(*deployments, pods_attrs: [], legacy_deployments: [])
return new([], status: :not_found, legacy_deployments: legacy_deployments) if deployments.empty?
deployments = deployments.map { |deploy| ::Gitlab::Kubernetes::Deployment.new(deploy, pods: pods) }
deployments = deployments.map { |deploy| ::Gitlab::Kubernetes::Deployment.new(deploy, pods: pods_attrs) }
deployments.sort_by!(&:order)
new(deployments, legacy_deployments: legacy_deployments)
end
......
......@@ -27,7 +27,7 @@ RSpec.describe Gitlab::Kubernetes::RolloutStatus do
]
end
subject(:rollout_status) { described_class.from_deployments(*specs, pods: pods, legacy_deployments: legacy_deployments) }
subject(:rollout_status) { described_class.from_deployments(*specs, pods_attrs: pods, legacy_deployments: legacy_deployments) }
describe '#has_legacy_app_label?' do
let(:specs) { [] }
......@@ -85,7 +85,7 @@ RSpec.describe Gitlab::Kubernetes::RolloutStatus do
create_pods(name: "one", count: 3, track: 'stable') + create_pods(name: "two", count: 3, track: track)
end
it 'stores the union of deployment instances' do
it 'sorts stable instances last' do
expected = [
{ status: 'running', pod_name: "two", tooltip: 'two (Running)', track: 'canary', stable: false },
{ status: 'running', pod_name: "two", tooltip: 'two (Running)', track: 'canary', stable: false },
......@@ -104,6 +104,8 @@ RSpec.describe Gitlab::Kubernetes::RolloutStatus do
subject { rollout_status.completion }
context 'when all instances are finished' do
let(:track) { 'canary' }
it { is_expected.to eq(100) }
end
......@@ -118,12 +120,83 @@ RSpec.describe Gitlab::Kubernetes::RolloutStatus do
it { is_expected.to eq(50) }
end
context 'with one deployment' do
it 'sets the completion percentage when a deployment has more running pods than desired' do
deployments = [kube_deployment(name: 'one', track: 'one', replicas: 2)]
pods = create_pods(name: 'one', track: 'one', count: 3)
rollout_status = described_class.from_deployments(*deployments, pods_attrs: pods)
expect(rollout_status.completion).to eq(100)
end
end
context 'with two deployments on different tracks' do
it 'sets the completion percentage when all pods are complete' do
deployments = [
kube_deployment(name: 'one', track: 'one', replicas: 2),
kube_deployment(name: 'two', track: 'two', replicas: 2)
]
pods = create_pods(name: 'one', track: 'one', count: 2) + create_pods(name: 'two', track: 'two', count: 2)
rollout_status = described_class.from_deployments(*deployments, pods_attrs: pods)
expect(rollout_status.completion).to eq(100)
end
end
context 'with two deployments that both have track set to "stable"' do
it 'sets the completion percentage when all pods are complete' do
deployments = [
kube_deployment(name: 'one', track: 'stable', replicas: 2),
kube_deployment(name: 'two', track: 'stable', replicas: 2)
]
pods = create_pods(name: 'one', track: 'stable', count: 2) + create_pods(name: 'two', track: 'stable', count: 2)
rollout_status = described_class.from_deployments(*deployments, pods_attrs: pods)
expect(rollout_status.completion).to eq(100)
end
it 'sets the completion percentage when no pods are complete' do
deployments = [
kube_deployment(name: 'one', track: 'stable', replicas: 3),
kube_deployment(name: 'two', track: 'stable', replicas: 7)
]
rollout_status = described_class.from_deployments(*deployments, pods_attrs: [])
expect(rollout_status.completion).to eq(0)
end
end
context 'with two deployments, one with track set to "stable" and one with no track label' do
it 'sets the completion percentage when all pods are complete' do
deployments = [
kube_deployment(name: 'one', track: 'stable', replicas: 3),
kube_deployment(name: 'two', track: nil, replicas: 3)
]
pods = create_pods(name: 'one', track: 'stable', count: 3) + create_pods(name: 'two', track: nil, count: 3)
rollout_status = described_class.from_deployments(*deployments, pods_attrs: pods)
expect(rollout_status.completion).to eq(100)
end
it 'sets the completion percentage when no pods are complete' do
deployments = [
kube_deployment(name: 'one', track: 'stable', replicas: 1),
kube_deployment(name: 'two', track: nil, replicas: 1)
]
rollout_status = described_class.from_deployments(*deployments, pods_attrs: [])
expect(rollout_status.completion).to eq(0)
end
end
end
describe '#complete?' do
subject { rollout_status.complete? }
context 'when all instances are finished' do
let(:track) { 'canary' }
it { is_expected.to be_truthy }
end
......
......@@ -121,11 +121,28 @@ RSpec.describe Clusters::Platforms::Kubernetes do
end
end
context 'with no deployments but there are pods' do
let(:deployments) do
[]
end
let(:pods) do
[
kube_pod(name: 'pod-1', environment_slug: environment.slug, project_slug: project.full_path_slug),
kube_pod(name: 'pod-2', environment_slug: environment.slug, project_slug: project.full_path_slug)
]
end
it 'returns an empty array' do
expect(rollout_status.instances).to eq([])
end
end
context 'with valid deployments' do
let(:matched_deployment) { kube_deployment(environment_slug: environment.slug, project_slug: project.full_path_slug) }
let(:matched_deployment) { kube_deployment(environment_slug: environment.slug, project_slug: project.full_path_slug, replicas: 2) }
let(:unmatched_deployment) { kube_deployment }
let(:matched_pod) { kube_pod(environment_slug: environment.slug, project_slug: project.full_path_slug) }
let(:unmatched_pod) { kube_pod(environment_slug: environment.slug, project_slug: project.full_path_slug, status: 'Pending') }
let(:matched_pod) { kube_pod(environment_slug: environment.slug, project_slug: project.full_path_slug, status: 'Pending') }
let(:unmatched_pod) { kube_pod(environment_slug: environment.slug + '-test', project_slug: project.full_path_slug) }
let(:deployments) { [matched_deployment, unmatched_deployment] }
let(:pods) { [matched_pod, unmatched_pod] }
......@@ -134,6 +151,16 @@ RSpec.describe Clusters::Platforms::Kubernetes do
expect(rollout_status.deployments.map(&:annotations)).to eq([
{ 'app.gitlab.com/app' => project.full_path_slug, 'app.gitlab.com/env' => 'env-000000' }
])
expect(rollout_status.instances).to eq([{ pod_name: "kube-pod",
stable: true,
status: "pending",
tooltip: "kube-pod (Pending)",
track: "stable" },
{ pod_name: "Not provided",
stable: true,
status: "pending",
tooltip: "Not provided (Pending)",
track: "stable" }])
end
end
......@@ -143,6 +170,145 @@ RSpec.describe Clusters::Platforms::Kubernetes do
expect(rollout_status).to be_not_found
end
end
context 'when the pod track does not match the deployment track' do
let(:deployments) do
[
kube_deployment(name: 'deployment-a', environment_slug: environment.slug, project_slug: project.full_path_slug, replicas: 1, track: 'weekly')
]
end
let(:pods) do
[
kube_pod(name: 'pod-a-1', environment_slug: environment.slug, project_slug: project.full_path_slug, track: 'weekly'),
kube_pod(name: 'pod-a-2', environment_slug: environment.slug, project_slug: project.full_path_slug, track: 'daily')
]
end
it 'does not return the pod' do
expect(rollout_status.instances.map { |p| p[:pod_name] }).to eq(['pod-a-1'])
end
end
context 'when the pod track is not stable' do
let(:deployments) do
[
kube_deployment(name: 'deployment-a', environment_slug: environment.slug, project_slug: project.full_path_slug, replicas: 1, track: 'something')
]
end
let(:pods) do
[
kube_pod(name: 'pod-a-1', environment_slug: environment.slug, project_slug: project.full_path_slug, track: 'something')
]
end
it 'the pod is not stable' do
expect(rollout_status.instances.map { |p| p.slice(:stable, :track) }).to eq([{ stable: false, track: 'something' }])
end
end
context 'when the pod track is stable' do
let(:deployments) do
[
kube_deployment(name: 'deployment-a', environment_slug: environment.slug, project_slug: project.full_path_slug, replicas: 1, track: 'stable')
]
end
let(:pods) do
[
kube_pod(name: 'pod-a-1', environment_slug: environment.slug, project_slug: project.full_path_slug, track: 'stable')
]
end
it 'the pod is stable' do
expect(rollout_status.instances.map { |p| p.slice(:stable, :track) }).to eq([{ stable: true, track: 'stable' }])
end
end
context 'when the pod track is not provided' do
let(:deployments) do
[
kube_deployment(name: 'deployment-a', environment_slug: environment.slug, project_slug: project.full_path_slug, replicas: 1)
]
end
let(:pods) do
[
kube_pod(name: 'pod-a-1', environment_slug: environment.slug, project_slug: project.full_path_slug)
]
end
it 'the pod is stable' do
expect(rollout_status.instances.map { |p| p.slice(:stable, :track) }).to eq([{ stable: true, track: 'stable' }])
end
end
context 'when the number of matching pods does not match the number of replicas' do
let(:deployments) do
[
kube_deployment(name: 'deployment-a', environment_slug: environment.slug, project_slug: project.full_path_slug, replicas: 3)
]
end
let(:pods) do
[
kube_pod(name: 'pod-a-1', environment_slug: environment.slug, project_slug: project.full_path_slug)
]
end
it 'returns a pending pod for each missing replica' do
expect(rollout_status.instances.map { |p| p.slice(:pod_name, :status) }).to eq([
{ pod_name: 'pod-a-1', status: 'running' },
{ pod_name: 'Not provided', status: 'pending' },
{ pod_name: 'Not provided', status: 'pending' }
])
end
end
context 'when pending pods are returned for missing replicas' do
let(:deployments) do
[
kube_deployment(name: 'deployment-a', environment_slug: environment.slug, project_slug: project.full_path_slug, replicas: 2, track: 'canary'),
kube_deployment(name: 'deployment-b', environment_slug: environment.slug, project_slug: project.full_path_slug, replicas: 2, track: 'stable')
]
end
let(:pods) do
[
kube_pod(name: 'pod-a-1', environment_slug: environment.slug, project_slug: project.full_path_slug, track: 'canary')
]
end
it 'returns the correct track for the pending pods' do
expect(rollout_status.instances.map { |p| p.slice(:pod_name, :status, :track) }).to eq([
{ pod_name: 'pod-a-1', status: 'running', track: 'canary' },
{ pod_name: 'Not provided', status: 'pending', track: 'canary' },
{ pod_name: 'Not provided', status: 'pending', track: 'stable' },
{ pod_name: 'Not provided', status: 'pending', track: 'stable' }
])
end
end
context 'when two deployments with the same track are missing instances' do
let(:deployments) do
[
kube_deployment(name: 'deployment-a', environment_slug: environment.slug, project_slug: project.full_path_slug, replicas: 1, track: 'mytrack'),
kube_deployment(name: 'deployment-b', environment_slug: environment.slug, project_slug: project.full_path_slug, replicas: 1, track: 'mytrack')
]
end
let(:pods) do
[]
end
it 'returns the correct number of pending pods' do
expect(rollout_status.instances.map { |p| p.slice(:pod_name, :status, :track) }).to eq([
{ pod_name: 'Not provided', status: 'pending', track: 'mytrack' },
{ pod_name: 'Not provided', status: 'pending', track: 'mytrack' }
])
end
end
end
describe '#calculate_reactive_cache_for' do
......
......@@ -604,7 +604,7 @@ module KubernetesHelpers
}
end
def kube_deployment(name: "kube-deployment", environment_slug: "production", project_slug: "project-path-slug", track: nil)
def kube_deployment(name: "kube-deployment", environment_slug: "production", project_slug: "project-path-slug", track: nil, replicas: 3)
{
"metadata" => {
"name" => name,
......@@ -617,7 +617,7 @@ module KubernetesHelpers
"track" => track
}.compact
},
"spec" => { "replicas" => 3 },
"spec" => { "replicas" => replicas },
"status" => {
"observedGeneration" => 4
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment