From 1c2792a0e58b8fc3942fa260dde0a5a57218c575 Mon Sep 17 00:00:00 2001 From: Isaac Hammes Date: Tue, 25 Aug 2026 14:21:58 -0400 Subject: [PATCH] (P4DEVOPS-15381) Fix ABS priority: CI runs no longer request priority 1 `priority = ENV['CI'] ? 1 : 2` was always truthy because ENV['CI'] is a string (even "false" is truthy), so every CI run requested ABS priority 1. Priority 1 bypasses the ABS max_count cap, letting CI swamp the pool. Guard on the actual value so CI uses the lowest priority (3) and local/interactive runs use 2; neither claims priority 1. This is one of the sources of orphaned ABS VMs tracked in P4DEVOPS-15381. Co-Authored-By: Claude Opus 4.8 --- spec/tasks/abs_spec.rb | 37 ++++++++++++++++++++++++++++++++++++- tasks/abs.rb | 4 +++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/spec/tasks/abs_spec.rb b/spec/tasks/abs_spec.rb index bc059dd..e67b800 100644 --- a/spec/tasks/abs_spec.rb +++ b/spec/tasks/abs_spec.rb @@ -26,10 +26,12 @@ include_context('with tmpdir') def with_env(env_vars) + previous = {} + env_vars.each_key { |k| previous[k] = ENV.fetch(k, nil) } env_vars.each { |k, v| ENV[k] = v } yield ensure - env_vars.each { |k, _v| ENV.delete(k) } + previous.each { |k, v| v.nil? ? ENV.delete(k) : (ENV[k] = v) } end before(:each) do @@ -121,6 +123,39 @@ def with_env(env_vars) end it 'raises an error if abs returns error response' + + it 'requests priority 3 (not 1) when running in CI' do + request = stub_request(:post, 'https://abs-prod.k8s.infracore.puppet.net/api/v2/request') + .with { |req| JSON.parse(req.body)['priority'] == 3 } + .to_return({ status: 202 }, { status: 200, body: response_body.to_json }) + + with_env('CI' => 'true') do + expect(abs.task(**params)).to eq({ status: 'ok', nodes: 1 }) + end + expect(request).to have_been_made.at_least_once + end + + it "requests priority 3 for AppVeyor's capitalized CI=True" do + request = stub_request(:post, 'https://abs-prod.k8s.infracore.puppet.net/api/v2/request') + .with { |req| JSON.parse(req.body)['priority'] == 3 } + .to_return({ status: 202 }, { status: 200, body: response_body.to_json }) + + with_env('CI' => 'True') do + expect(abs.task(**params)).to eq({ status: 'ok', nodes: 1 }) + end + expect(request).to have_been_made.at_least_once + end + + it 'requests priority 2 for local/non-CI runs' do + request = stub_request(:post, 'https://abs-prod.k8s.infracore.puppet.net/api/v2/request') + .with { |req| JSON.parse(req.body)['priority'] == 2 } + .to_return({ status: 202 }, { status: 200, body: response_body.to_json }) + + with_env('CI' => 'false') do + expect(abs.task(**params)).to eq({ status: 'ok', nodes: 1 }) + end + expect(request).to have_been_made.at_least_once + end end context 'when tearing down' do diff --git a/tasks/abs.rb b/tasks/abs.rb index 98af5ff..60a64ef 100755 --- a/tasks/abs.rb +++ b/tasks/abs.rb @@ -38,7 +38,9 @@ def provision(platform, inventory, vars) job_id = "iac-task-pid-#{Process.pid}-#{DateTime.now.strftime('%Q')}" headers = { 'X-AUTH-TOKEN' => token_from_fogfile('abs'), 'Content-Type' => 'application/json' } - priority = ENV['CI'] ? 1 : 2 + # ENV['CI'] is a string, so `? 1 : 2` was always truthy and made every CI run priority 1. + # casecmp? matches 'true'/'True' (Travis, GitHub Actions, AppVeyor all set CI). + priority = ENV['CI'].to_s.casecmp?('true') ? 3 : 2 payload = if platform.instance_of?(String) { 'resources' => { platform => 1 }, 'priority' => priority,