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

tbt-247 - trial timeout #323

Merged
merged 3 commits into from
Jan 2, 2025
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
1 change: 0 additions & 1 deletion lib/travis/scheduler/jobs/capacity/plan.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ def max
end

def billing_allowed?(job)
puts billing_allowance[allowance_key(job)]
return true if billing_allowance[allowance_key(job)]

# Cancel job if it has not been queued for more than a day due to
Expand Down
25 changes: 23 additions & 2 deletions lib/travis/scheduler/record/organization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Organization < ActiveRecord::Base
#
DEFAULT_SUBSCRIBED_TIMEOUT = 120 * 60
DEFAULT_SPONSORED_TIMEOUT = 50 * 60
DEFAULT_TRIAL_TIMEOUT = 30 * 60

def subscription
subs = Subscription.where(owner_id: id, owner_type: 'Organization')
Expand Down Expand Up @@ -39,13 +40,25 @@ def paid_new_plan?
plan = if redis.exists?(redis_key)
JSON.parse(redis.get(redis_key))
else
billing_client.get_plan(self).to_h
billing_plan
end
return false if plan[:error] || plan['plan_name'].nil?

plan['hybrid'] || !plan['plan_name'].include?('free')
end

def billing_plan
@billing_plan ||= billing_client.get_plan(self)&.to_h
end

def v2trial?
!billing_plan['current_trial'].nil?
end

def trial_timeout
@trial_timeout ||= (billing_plan['current_trial'].nil? || !billing_plan['current_trial'].include?('build_timeout')) ? DEFAULT_TRIAL_TIMEOUT : billing_plan['current_trial']['build_timeout']
end

def default_worker_timeout
# When the user is a paid user ("subscribed") or has an active trial, they
# are granted a different default timeout on their jobs.
Expand All @@ -54,9 +67,17 @@ def default_worker_timeout
# those enforced by workers themselves, but we plan to sometime in the
# following weeks/months.
#
if paid? || educational?
if educational?
Travis.logger.info "Default Timeout: DEFAULT_SUBSCRIBED_TIMEOUT for owner=#{id}"
DEFAULT_SUBSCRIBED_TIMEOUT
elsif paid?
if v2trial?
Travis.logger.info "Default Timeout: TRIAL_TIMEOUT #{trial_timeout} for owner=#{id}"
trial_timeout
else
Travis.logger.info "Default Timeout: DEFAULT_SUBSCRIBED_TIMEOUT for owner=#{id}"
DEFAULT_SUBSCRIBED_TIMEOUT
end
else
Travis.logger.info "Default Timeout: DEFAULT_SPONSORED_TIMEOUT for owner=#{id}"
DEFAULT_SPONSORED_TIMEOUT
Expand Down
30 changes: 26 additions & 4 deletions lib/travis/scheduler/record/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class User < ActiveRecord::Base
#
DEFAULT_SUBSCRIBED_TIMEOUT = 120 * 60
DEFAULT_SPONSORED_TIMEOUT = 50 * 60
DEFAULT_TRIAL_TIMEOUT = 30 * 60

def subscription
subs = Subscription.where(owner_id: id, owner_type: 'User')
Expand Down Expand Up @@ -44,13 +45,21 @@ def paid_new_plan?
plan = if redis.exists?(redis_key)
JSON.parse(redis.get(redis_key))
else
billing_client.get_plan(self).to_h
billing_plan
end
return false if plan[:error] || plan['plan_name'].nil?

plan['hybrid'] || !plan['plan_name'].include?('free')
end

def v2trial?
!billing_plan['current_trial'].nil?
end

def trial_timeout
@trial_timeout ||= (billing_plan['current_trial'].nil? || !billing_plan['current_trial'].include?('build_timeout')) ? DEFAULT_TRIAL_TIMEOUT : billing_plan['current_trial']['build_timeout']
end

def enterprise?
!!context.config[:enterprise]
end
Expand All @@ -63,15 +72,28 @@ def default_worker_timeout
# those enforced by workers themselves, but we plan to sometime in the
# following weeks/months.
#
if enterprise? || paid? || educational?
Travis.logger.info "Default Timeout: DEFAULT_SUBSCRIBED_TIMEOUT for owner=#{id}"
DEFAULT_SUBSCRIBED_TIMEOUT
if enterprise? || educational?
Travis.logger.info "Default Timeout: DEFAULT_SUBSCRIBED_TIMEOUT for owner=#{id}"
DEFAULT_SUBSCRIBED_TIMEOUT
elsif paid?
if v2trial?
Travis.logger.info "Default Timeout: TRIAL_TIMEOUT #{trial_timeout} for owner=#{id}"
trial_timeout
else
Travis.logger.info "Default Timeout: DEFAULT_SUBSCRIBED_TIMEOUT for owner=#{id}"
DEFAULT_SUBSCRIBED_TIMEOUT
end
else
Travis.logger.info "Default Timeout: DEFAULT_SPONSORED_TIMEOUT for owner=#{id}"
DEFAULT_SPONSORED_TIMEOUT
end
end

def billing_plan
@billing_plan ||= billing_client.get_plan(self)&.to_h
end


def preferences
super || {}
end
Expand Down
33 changes: 33 additions & 0 deletions spec/travis/scheduler/record/organization_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@
context 'subscribed? == true' do
before do
org.stubs(:subscribed?).returns(true)
stub_request(:get, authorize_build_url).to_return(
body: MultiJson.dump(plan_name: 'two_concurrent_plan', hybrid: true, free: false, status: 'subscribed',
metered: false)
)
end

it 'returns the DEFAULT_SUBSCRIBED_TIMEOUT' do
Expand All @@ -61,13 +65,42 @@
context 'active_trial? == true' do
before do
org.stubs(:active_trial?).returns(true)
stub_request(:get, authorize_build_url).to_return(
body: MultiJson.dump(plan_name: 'free_tier_plan', hybrid: false, free: true, status: nil, metered: true)
)
end

it 'returns the DEFAULT_SUBSCRIBED_TIMEOUT' do
expect(org.default_worker_timeout).to eq Organization::DEFAULT_SUBSCRIBED_TIMEOUT
end
end

context 'active_v2_trial? == true' do
before do
org.stubs(:paid?).returns(true)
stub_request(:get, authorize_build_url).to_return(
body: MultiJson.dump(plan_name: 'free_tier_plan', hybrid: false, free: true, status: nil, metered: true, current_trial: {build_timeout: 11})
)
end

it 'returns the TRIAL_TIMEOUT = 10' do
expect(org.default_worker_timeout).to eq 11
end
end

context 'active_v2_trial? == true' do
before do
org.stubs(:paid?).returns(true)
stub_request(:get, authorize_build_url).to_return(
body: MultiJson.dump(plan_name: 'free_tier_plan', hybrid: false, free: true, status: nil, metered: true, current_trial: {})
)
end

it 'returns the DEFAULT_TRIAL_TIMEOUT' do
expect(org.default_worker_timeout).to eq Organization::DEFAULT_TRIAL_TIMEOUT
end
end

context 'subscribed? == true' do
before do
org.stubs(:educational?).returns(true)
Expand Down
32 changes: 32 additions & 0 deletions spec/travis/scheduler/record/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
context 'subscribed? == true' do
before do
user.stubs(:subscribed?).returns(true)
stub_request(:get, authorize_build_url).to_return(
body: MultiJson.dump(plan_name: 'free_tier_plan', hybrid: false, free: true, status: nil, metered: true)
)
end

it 'returns the DEFAULT_SUBSCRIBED_TIMEOUT' do
Expand All @@ -77,13 +80,42 @@
context 'active_trial? == true' do
before do
user.stubs(:active_trial?).returns(true)
stub_request(:get, authorize_build_url).to_return(
body: MultiJson.dump(plan_name: 'free_tier_plan', hybrid: false, free: true, status: nil, metered: true)
)
end

it 'returns the DEFAULT_SUBSCRIBED_TIMEOUT' do
expect(user.default_worker_timeout).to eq User::DEFAULT_SUBSCRIBED_TIMEOUT
end
end

context 'active_v2_trial? == true' do
before do
user.stubs(:paid?).returns(true)
stub_request(:get, authorize_build_url).to_return(
body: MultiJson.dump(plan_name: 'free_tier_plan', hybrid: false, free: true, status: nil, metered: true, current_trial: { build_timeout: 10})
)
end

it 'returns the TRIAL_TIMEOUT' do
expect(user.default_worker_timeout).to eq 10
end
end

context 'active_v2_trial? == true' do
before do
user.stubs(:paid?).returns(true)
stub_request(:get, authorize_build_url).to_return(
body: MultiJson.dump(plan_name: 'free_tier_plan', hybrid: false, free: true, status: nil, metered: true, current_trial: { })
)
end

it 'returns the DEFAULT_TRIAL_TIMEOUT' do
expect(user.default_worker_timeout).to eq User::DEFAULT_TRIAL_TIMEOUT
end
end

context "paid_new_plan? == true" do
before do
user.stubs(:paid_new_plan?).returns(true)
Expand Down
22 changes: 20 additions & 2 deletions spec/travis/scheduler/serialize/worker/repo_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
FactoryBot.create(:repository, owner_name: org.login, owner_id: org.id, owner_type: 'Organization')
end

let(:authorize_build_url) { "http://localhost:9292/organizations/#{org.id}/plan" }
let(:config) { { github: {} } }

let(:unpaid_timeout) { User::DEFAULT_SPONSORED_TIMEOUT }
Expand All @@ -29,7 +30,6 @@

context 'unpaid account' do
let(:authorize_build_url) { "http://localhost:9292/users/#{user.id}/plan" }

before do
stub_request(:get, authorize_build_url).to_return(
body: MultiJson.dump(plan_name: 'free_tier_plan', hybrid: false, free: true, status: 'subscribed',
Expand All @@ -46,8 +46,13 @@
end

context 'paid account' do
let(:authorize_build_url) { "http://localhost:9292/users/#{user.id}/plan" }
before do
User.any_instance.stubs(:subscribed?).returns(true)
stub_request(:get, authorize_build_url).to_return(
body: MultiJson.dump(plan_name: 'free_tier_plan', hybrid: false, free: true, status: 'subscribed',
metered: true)
)
end

it 'returns a hash of timeout values' do
Expand All @@ -59,8 +64,13 @@
end

context 'active trial' do
let(:authorize_build_url) { "http://localhost:9292/users/#{user.id}/plan" }
before do
User.any_instance.stubs(:active_trial?).returns(true)
stub_request(:get, authorize_build_url).to_return(
body: MultiJson.dump(plan_name: 'free_tier_plan', hybrid: false, free: true, status: 'subscribed',
metered: true)
)
end

it 'returns a hash of timeout values' do
Expand All @@ -76,7 +86,6 @@
let(:worker) { described_class.new(org_repo, config) }

context 'unpaid account' do
let(:authorize_build_url) { "http://localhost:9292/organizations/#{org.id}/plan" }

before do
stub_request(:get, authorize_build_url).to_return(
Expand All @@ -96,6 +105,11 @@
context 'paid account' do
before do
Organization.any_instance.stubs(:subscribed?).returns(true)
stub_request(:get, authorize_build_url).to_return(
body: MultiJson.dump(plan_name: 'free_tier_plan', hybrid: false, free: true, status: 'subscribed',
metered: true)
)

end

it 'returns a hash of timeout values' do
Expand All @@ -109,6 +123,10 @@
context 'active trial' do
before do
Organization.any_instance.stubs(:active_trial?).returns(true)
stub_request(:get, authorize_build_url).to_return(
body: MultiJson.dump(plan_name: 'free_tier_plan', hybrid: false, free: true, status: 'subscribed',
metered: true)
)
end

it 'returns a hash of timeout values' do
Expand Down