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

log command from scripts #126

Merged
merged 4 commits into from
Jan 14, 2020
Merged
Show file tree
Hide file tree
Changes from 2 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
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"author": "Adobe Inc.",
"bugs": "https://github.com/adobe/aio-cli-plugin-app/issues",
"dependencies": {
"@adobe/aio-app-scripts": "^0.7.0",
"@adobe/aio-app-scripts": "^0.8.0",
"@adobe/aio-lib-core-config": ">=1.2.3",
"@adobe/generator-aio-app": "^0.2.0",
"@oclif/command": "^1.5.11",
Expand All @@ -19,7 +19,6 @@
"inquirer": "^7.0.0",
"npm-package-arg": "^8.0.0",
"open": "^7.0.0",
"openwhisk": "^3.20.0",
"ora": "^4.0.3",
"request-promise": "^4.2.4",
"resolve": "^1.10.0",
Expand Down
55 changes: 17 additions & 38 deletions src/commands/app/logs.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag
governing permissions and limitations under the License.
*/

const openwhisk = require('openwhisk')
const aioConfig = require('@adobe/aio-lib-core-config')
const AppScripts = require('@adobe/aio-app-scripts')

const { flags } = require('@oclif/command')
// const { cli } = require('cli-ux')
Expand All @@ -20,57 +19,37 @@ const BaseCommand = require('../../BaseCommand')
class Logs extends BaseCommand {
async run () {
const { flags } = this.parse(Logs)
this.foundLogs = false
this.aioConfig = aioConfig.get() || {}
this.validateConfig()
await this.getLogs(flags.limit)
if (this.foundLogs) { this.log('✔ Finished fetching logs!') } else { this.log('No Logs Found') }
}

async getLogs (limit) {
const options = {
apihost: this.aioConfig.runtime.apihost,
api_key: this.aioConfig.runtime.auth,
namespace: this.aioConfig.runtime.namespace
}
const ow = openwhisk(options)
// get activations
const listOptions = { limit: limit, skip: 0 }
const activations = await ow.activations.list(listOptions)
for (let i = 0; i < activations.length; i++) {
await this.getActivationLogs(activations[i], ow)
}
}
const scripts = AppScripts({ listeners: {} })

async getActivationLogs (activation, ow) {
const logOptions = { activationId: activation.activationId }
const results = await ow.activations.logs(logOptions)
// send fetched logs to console
if (results.logs && results.logs.length > 0) {
this.foundLogs = true
const logger = this.log
logger(activation.name + ':' + activation.activationId)
results.logs.forEach(function (log) {
logger(log)
})
const logOptions = {
logger: this.log,
limit: flags.limit
}
}

validateConfig () {
if (!this.aioConfig) { throw new Error('Missing aio config') } else if (!this.aioConfig.runtime || !this.aioConfig.runtime.auth || !this.aioConfig.runtime.namespace) { throw new Error('Missing aio runtime config') }
try {
const foundLogs = await scripts.logs([], logOptions)
if (foundLogs) {
this.log('✔ Finished fetching logs!')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we keep adding extra text? what value does this add?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just reproduce the previous behavior of the log command, didn't want to change anything behavior wise.
but agree there is not much value, will remove it.

} else {
this.log('No logs found')
}
} catch (error) {
this.error(error)
}
}
}

Logs.description = `Fetch logs for an Adobe I/O App
`

Logs.flags = {
...BaseCommand.flags,
limit: flags.integer({
description: 'Limit number of activations to fetch logs from',
default: 1,
char: 'l'
}),
...BaseCommand.flags
})
}

// Logs.args = [
Expand Down
3 changes: 2 additions & 1 deletion test/__mocks__/@adobe/aio-app-scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const mockScripts = {
undeployUI: jest.fn(() => mockWithCallbacks()),
undeployActions: jest.fn(() => mockWithCallbacks()),
runDev: jest.fn(() => mockWithCallbacks()),
addAuth: jest.fn(() => mockWithCallbacks())
addAuth: jest.fn(() => mockWithCallbacks()),
logs: jest.fn(() => mockWithCallbacks())
}

const mockWithCallbacks = () => {
Expand Down
67 changes: 67 additions & 0 deletions test/commands/app/logs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ governing permissions and limitations under the License.
const TheCommand = require('../../../src/commands/app/logs')
const BaseCommand = require('../../../src/BaseCommand')

jest.mock('@adobe/aio-app-scripts')
const mockScripts = require('@adobe/aio-app-scripts')()

beforeEach(() => {
jest.restoreAllMocks()
})
Expand All @@ -36,3 +39,67 @@ test('flags', async () => {
expect(typeof TheCommand.flags.limit.description).toBe('string')
expect(TheCommand.flags.limit.default).toEqual(1)
})

describe('run', () => {
beforeEach(() => {
mockScripts.logs.mockReset()
})

test('when there is an error in app scripts', async () => {
const command = new TheCommand([])
command.error = jest.fn()
command.log = jest.fn()

mockScripts.logs.mockRejectedValue('error')
await command.run()
expect(command.error).toHaveBeenCalledWith('error')
})

test('when there are no logs, no flags', async () => {
const command = new TheCommand([])
command.error = jest.fn()
command.log = jest.fn()

mockScripts.logs.mockResolvedValue(false)
await command.run()
expect(command.error).toHaveBeenCalledTimes(0)
expect(mockScripts.logs).toBeCalledWith([], { logger: command.log, limit: 1 })
expect(command.log).toHaveBeenCalledWith('No logs found')
})

test('when there are logs, no flags', async () => {
const command = new TheCommand([])
command.error = jest.fn()
command.log = jest.fn()

mockScripts.logs.mockResolvedValue(true)
await command.run()
expect(command.error).toHaveBeenCalledTimes(0)
expect(mockScripts.logs).toBeCalledWith([], { logger: command.log, limit: 1 })
expect(command.log).toHaveBeenCalledWith('✔ Finished fetching logs!')
})

test('when there are logs, -l 2', async () => {
const command = new TheCommand(['-l', '2'])
command.error = jest.fn()
command.log = jest.fn()

mockScripts.logs.mockResolvedValue(true)
await command.run()
expect(command.error).toHaveBeenCalledTimes(0)
expect(mockScripts.logs).toBeCalledWith([], { logger: command.log, limit: 2 })
expect(command.log).toHaveBeenCalledWith('✔ Finished fetching logs!')
})

test('when there are logs, --limit 2', async () => {
const command = new TheCommand(['--limit', '2'])
command.error = jest.fn()
command.log = jest.fn()

mockScripts.logs.mockResolvedValue(true)
await command.run()
expect(command.error).toHaveBeenCalledTimes(0)
expect(mockScripts.logs).toBeCalledWith([], { logger: command.log, limit: 2 })
expect(command.log).toHaveBeenCalledWith('✔ Finished fetching logs!')
})
})