Skip to content

Commit

Permalink
tbt-247 - trial timeout (#323)
Browse files Browse the repository at this point in the history
* trials timeout

* trial timeout

* spec
  • Loading branch information
GbArc authored Jan 2, 2025
1 parent 80046c5 commit 214043c
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 9 deletions.
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

0 comments on commit 214043c

Please sign in to comment.