Skip to content

Commit

Permalink
Remove free-2016 flag check & group requests (heroku#105)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ransom Briggs committed Jun 1, 2016
1 parent 625fe28 commit f57a6cc
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 88 deletions.
50 changes: 15 additions & 35 deletions commands/ps/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,6 @@ let time = require('../../lib/time')
// gets the process number from a string like web.19 => 19
let getProcessNum = (s) => parseInt(s.split('.', 2)[1])

function printQuota (quota) {
if (!quota) return
let lbl
if (quota.allow_until) lbl = 'Free quota left'
else if (quota.deny_until) lbl = 'Free quota exhausted. Unidle available in'
if (lbl) {
let timestamp = quota.allow_until ? new Date(quota.allow_until) : new Date(quota.deny_until)
let timeRemaining = time.remaining(new Date(), timestamp)
cli.log(`${lbl}: ${timeRemaining}`)
}
}

function printExtended (dynos) {
const truncate = require('lodash.truncate')
const sortBy = require('lodash.sortby')
Expand All @@ -42,21 +30,13 @@ function printExtended (dynos) {
})
}

function * printAccountQuota (context, heroku) {
let requests = yield {
app: heroku.request({
path: `/apps/${context.app}`,
headers: {Accept: 'application/vnd.heroku+json; version=3.process-tier'}
}),
account: heroku.request({path: '/account'})
}

if (requests.app.process_tier !== 'free') {
function * printAccountQuota (context, heroku, app, account) {
if (app.process_tier !== 'free') {
return
}

let quota = yield heroku.request({
path: `/accounts/${requests.account.id}/actions/get-quota`,
path: `/accounts/${account.id}/actions/get-quota`,
headers: {Accept: 'application/vnd.heroku+json; version=3.account-quotas'}
})
.then(function (data) {
Expand Down Expand Up @@ -123,25 +103,26 @@ function printDynos (dynos) {
})
}

const appquotaheader = {Accept: 'application/vnd.heroku+json; version=3.app-quotas'}

function * run (context, heroku) {
const {app, flags, args} = context
const types = args
const {json, extended} = flags
const suffix = extended ? '?extended=true' : ''

let {quota, dynos, feature} = yield {
quota: heroku.post(`/apps/${app}/actions/get-quota${suffix}`, {headers: appquotaheader}).catch(() => {}),
dynos: heroku.request({path: `/apps/${app}/dynos${suffix}`}),
feature: heroku.get('/account/features/free-2016').catch(function (err) {
if (err.statusCode === 404 && err.body && err.body.id === 'not_found') {
return {enabled: false}
}
throw err
let promises = {
dynos: heroku.request({path: `/apps/${app}/dynos${suffix}`})
}

if (!json && !extended) {
promises.app_info = heroku.request({
path: `/apps/${context.app}`,
headers: {Accept: 'application/vnd.heroku+json; version=3.process-tier'}
})
promises.account_info = heroku.request({path: '/account'})
}

let {dynos, app_info, account_info} = yield promises

if (types.length > 0) {
dynos = dynos.filter(dyno => types.find(t => dyno.type === t))
types.forEach(t => {
Expand All @@ -154,8 +135,7 @@ function * run (context, heroku) {
if (json) cli.styledJSON(dynos)
else if (extended) printExtended(dynos)
else {
if (feature.enabled) yield printAccountQuota(context, heroku)
else printQuota(quota)
yield printAccountQuota(context, heroku, app_info, account_info)
if (dynos.length === 0) cli.log(`No dynos on ${cli.color.app(app)}`)
else printDynos(dynos)
}
Expand Down
71 changes: 18 additions & 53 deletions test/commands/ps/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,6 @@ const strftime = require('strftime')

const hourAgo = new Date(new Date() - 60 * 60 * 1000)
const hourAgoStr = strftime('%Y/%m/%d %H:%M:%S %z', hourAgo)
const hourAhead = new Date(new Date().getTime() + 60 * 60 * 1000)

function stubAccountFeature (code, body) {
nock('https://api.heroku.com:443')
.get('/account/features/free-2016')
.reply(code, body)
}

function stubAccountFeatureDisabled () {
stubAccountFeature(404, {id: 'not_found'})
}

function stubAccountQuota (code, body) {
nock('https://api.heroku.com:443')
Expand Down Expand Up @@ -47,6 +36,18 @@ function stubAccountQuota (code, body) {
.reply(code, body)
}

function stubAppAndAccount () {
nock('https://api.heroku.com:443', {
reqHeaders: {'Accept': 'application/vnd.heroku+json; version=3.process_tier'}
})
.get('/apps/myapp')
.reply(200, {process_tier: 'hobby'})

nock('https://api.heroku.com:443')
.get('/account')
.reply(200, {id: '1234'})
}

describe('ps', function () {
beforeEach(function () {
cli.mockConsole()
Expand All @@ -61,7 +62,7 @@ describe('ps', function () {
{command: 'bash', size: 'Free', name: 'run.1', type: 'run', updated_at: hourAgo, state: 'up'}
])

stubAccountFeatureDisabled()
stubAppAndAccount()

return cmd.run({app: 'myapp', args: [], flags: {}})
.then(() => expect(cli.stdout, 'to equal', `=== web (Free): npm start (1)
Expand All @@ -82,7 +83,9 @@ run.1 (Free): up ${hourAgoStr} (~ 1h ago): bash
{command: 'npm start', size: 'Free', name: 'web.1', type: 'web', updated_at: hourAgo, state: 'up'},
{command: 'bash', size: 'Free', name: 'run.1', type: 'run', updated_at: hourAgo, state: 'up'}
])
stubAccountFeatureDisabled()

stubAppAndAccount()

return expect(cmd.run({app: 'myapp', args: ['foo'], flags: {}}), 'to be rejected with', 'No foo dynos on myapp')
})

Expand All @@ -93,46 +96,12 @@ run.1 (Free): up ${hourAgoStr} (~ 1h ago): bash
{command: 'npm start', size: 'Free', name: 'web.1', type: 'web', updated_at: hourAgo, state: 'up'}
])

stubAccountFeatureDisabled()

return cmd.run({app: 'myapp', args: [], flags: {json: true}})
.then(() => expect(JSON.parse(cli.stdout)[0], 'to satisfy', {command: 'npm start'}))
.then(() => expect(cli.stderr, 'to be empty'))
.then(() => api.done())
})

it('shows free time remaining when free-2016 not found', function () {
let api = nock('https://api.heroku.com:443')
.post('/apps/myapp/actions/get-quota')
.reply(200, {allow_until: hourAhead})
.get('/apps/myapp/dynos')
.reply(200)

stubAccountFeature(404, {id: 'not_found'})

let freeExpression = /^Free quota left: ([\d]+h [\d]{1,2}m|[\d]{1,2}m [\d]{1,2}s|[\d]{1,2}s])\n$/
return cmd.run({app: 'myapp', args: [], flags: {}})
.then(() => expect(cli.stdout, 'to match', freeExpression))
.then(() => expect(cli.stderr, 'to be empty'))
.then(() => api.done())
})

it('shows free time remaining when free-2016 not enabled', function () {
let api = nock('https://api.heroku.com:443')
.post('/apps/myapp/actions/get-quota')
.reply(200, {allow_until: hourAhead})
.get('/apps/myapp/dynos')
.reply(200)

stubAccountFeature(200, {enabled: false})

let freeExpression = /^Free quota left: ([\d]+h [\d]{1,2}m|[\d]{1,2}m [\d]{1,2}s|[\d]{1,2}s])\n$/
return cmd.run({app: 'myapp', args: [], flags: {}})
.then(() => expect(cli.stdout, 'to match', freeExpression))
.then(() => expect(cli.stderr, 'to be empty'))
.then(() => api.done())
})

it('shows extended info', function () {
let api = nock('https://api.heroku.com:443')
.get('/apps/myapp/dynos?extended=true')
Expand All @@ -145,8 +114,6 @@ run.1 (Free): up ${hourAgoStr} (~ 1h ago): bash
}}
])

stubAccountFeatureDisabled()

return cmd.run({app: 'myapp', args: [], flags: {extended: true}})
.then(() => expect(cli.stdout, 'to equal', `ID Process State Region Instance Port AZ Release Command Route Size
─── ─────── ─────────────────────────────────────── ────── ──────── ──── ─────── ─────── ───────── ──────── ────
Expand Down Expand Up @@ -234,8 +201,6 @@ run.1 (Free): up ${hourAgoStr} (~ 1h ago): bash
})

it('does not print out for non-free apps', function () {
stubAccountFeature(200, {enabled: true})

nock('https://api.heroku.com:443')
.get('/account')
.reply(200, {id: '1234'})
Expand Down Expand Up @@ -273,12 +238,12 @@ run.1 (Free): up ${hourAgoStr} (~ 1h ago): bash
})

it('logs to stdout and exits zero when no dynos', function () {
stubAccountFeature(200, {enabled: false})

let dynos = nock('https://api.heroku.com:443')
.get('/apps/myapp/dynos')
.reply(200, [])

stubAppAndAccount()

return cmd.run({app: 'myapp', args: [], flags: {}})
.then(() => expect(cli.stdout, 'to equal', 'No dynos on myapp\n'))
.then(() => expect(cli.stderr, 'to be empty'))
Expand Down

0 comments on commit f57a6cc

Please sign in to comment.