diff --git a/test/fixtures/for_unit_tests/deployment_test.yml b/test/fixtures/for_unit_tests/deployment_test.yml index e5977b012..b262abdce 100644 --- a/test/fixtures/for_unit_tests/deployment_test.yml +++ b/test/fixtures/for_unit_tests/deployment_test.yml @@ -8,6 +8,7 @@ metadata: "deployment.kubernetes.io/revision": "1" spec: replicas: 3 + progressDeadlineSeconds: 10 strategy: type: RollingUpdate rollingUpdate: diff --git a/test/unit/kubernetes-deploy/kubernetes_resource/deployment_test.rb b/test/unit/kubernetes-deploy/kubernetes_resource/deployment_test.rb index 7a35e4869..51bcf3cf7 100644 --- a/test/unit/kubernetes-deploy/kubernetes_resource/deployment_test.rb +++ b/test/unit/kubernetes-deploy/kubernetes_resource/deployment_test.rb @@ -148,6 +148,84 @@ def test_deploy_succeeded_not_fooled_by_stale_rs_data_in_deploy_status refute deploy.deploy_succeeded? end + def test_deploy_timed_out_with_hard_timeout + Timecop.freeze do + deploy = build_synced_deployment(status: { "replicas" => 3, "conditions" => [] }, + new_rs_status: { "replicas" => 1 }, max_unavail: 1) + deploy.deploy_started_at = Time.now.utc - KubernetesDeploy::Deployment::TIMEOUT + refute deploy.deploy_timed_out? + + deploy.deploy_started_at = Time.now.utc - KubernetesDeploy::Deployment::TIMEOUT - 1 + assert deploy.deploy_timed_out? + assert_equal "Timeout reason: hard deadline for Deployment\nLatest ReplicaSet: web-1", + deploy.timeout_message.strip + end + end + + def test_deploy_timed_out_based_on_progress_deadline + Timecop.freeze do + status = { + "replicas" => 3, + "conditions" => [{ + "type" => "Progressing", + "status" => 'False', + "lastUpdateTime" => Time.now.utc - 10.seconds, + "reason" => "Failed to progress" + }] + } + deploy = build_synced_deployment(status: status, new_rs_status: { "replicas" => 1 }, max_unavail: 1) + deploy.deploy_started_at = Time.now.utc - 3.minutes + deploy.kubectl.expects(:server_version).returns(Gem::Version.new("1.8")) + + assert deploy.deploy_timed_out? + assert_equal "Timeout reason: Failed to progress\nLatest ReplicaSet: web-1", deploy.timeout_message.strip + end + end + + def test_deploy_timed_out_based_on_progress_deadline_ignores_conditions_older_than_the_deploy + Timecop.freeze do + status = { + "replicas" => 3, + "conditions" => [{ + "type" => "Progressing", + "status" => 'False', + "lastUpdateTime" => Time.now.utc - 10.seconds, + "reason" => "Failed to progress" + }] + } + deploy = build_synced_deployment(status: status, new_rs_status: { "replicas" => 1 }, max_unavail: 1) + deploy.kubectl.expects(:server_version).returns(Gem::Version.new("1.8")).at_least_once + + deploy.deploy_started_at = nil # not started yet + refute deploy.deploy_timed_out? + + deploy.deploy_started_at = Time.now.utc - 4.seconds # 10s ago is before deploy started + refute deploy.deploy_timed_out? + + deploy.deploy_started_at = Time.now.utc - 5.seconds # 10s ago is "equal" to deploy time (fudge for clock skew) + assert deploy.deploy_timed_out? + end + end + + def test_deploy_timed_out_based_on_progress_deadline_accommodates_stale_conditions_bug_in_k8s_176_and_lower + Timecop.freeze do + status = { + "replicas" => 3, + "conditions" => [{ + "type" => "Progressing", + "status" => 'False', + "lastUpdateTime" => Time.now.utc - 5.seconds, + "reason" => "Failed to progress" + }] + } + deploy = build_synced_deployment(status: status, new_rs_status: { "replicas" => 1 }, max_unavail: 1) + deploy.deploy_started_at = Time.now.utc - 5.seconds # progress deadline of 10s has not elapsed + deploy.kubectl.expects(:server_version).returns(Gem::Version.new("1.7.6")) + + refute deploy.deploy_timed_out? + end + end + private def build_synced_deployment(status:, new_rs_status:, rollout: nil, max_unavail:) @@ -173,10 +251,10 @@ def build_synced_deployment(status:, new_rs_status:, rollout: nil, max_unavail:) "spec" => { "replicas" => new_rs_status["replicas"] }, "status" => new_rs_status ) + KubernetesDeploy::ReplicaSet.any_instance.expects(:kubectl).returns(deploy.kubectl) deploy.kubectl.expects(:run).with("get", "pods", "-a", "--output=json", anything).returns( ['{ "items": [] }', "", SystemExit.new(0)] ) - KubernetesDeploy::ReplicaSet.any_instance.expects(:kubectl).returns(deploy.kubectl) end deploy.kubectl.expects(:run).with("get", "replicasets", "--output=json", anything).returns(