Skip to content

Commit

Permalink
missing timeout + set --telemetry test, fix other tests
Browse files Browse the repository at this point in the history
  • Loading branch information
shazarre committed Dec 13, 2024
1 parent 402bfd8 commit a5b0d5c
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 10 deletions.
101 changes: 100 additions & 1 deletion packages/cli/src/base-l2.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Connection } from '@celo/connect'
import { testWithAnvilL2 } from '@celo/dev-utils/lib/anvil-test'
import { Config, ux } from '@oclif/core'
import http from 'http'
import Web3 from 'web3'
import { BaseCommand } from './base'
import CustomHelp from './help'
import { stripAnsiCodesFromNestedArray, testLocallyWithWeb3Node } from './test-utils/cliUtils'
import * as config from './utils/config'

process.env.NO_SYNCCHECK = 'true'

Expand Down Expand Up @@ -52,6 +54,11 @@ describe('flags', () => {
})

testWithAnvilL2('BaseCommand', (web3: Web3) => {
afterEach(() => {
jest.clearAllMocks()
jest.restoreAllMocks()
})

it('logs command execution error', async () => {
class TestErrorCommand extends BaseCommand {
async run() {
Expand Down Expand Up @@ -126,6 +133,10 @@ testWithAnvilL2('BaseCommand', (web3: Web3) => {
delete process.env.TELEMETRY_ENABLED
process.env.TELEMETRY_URL = 'https://telemetry.example.com'

jest.spyOn(config, 'readConfig').mockImplementation((_: string) => {
return { telemetry: true } as config.CeloConfig
})

const fetchMock = jest.fn().mockResolvedValue({
ok: true,
})
Expand All @@ -149,6 +160,8 @@ testWithAnvilL2('BaseCommand', (web3: Web3) => {
`)
expect(fetchSpy.mock.calls[0][1]?.method).toMatchInlineSnapshot(`"POST"`)
expect(fetchSpy.mock.calls[0][1]?.signal).toBeInstanceOf(AbortSignal)
// Make sure the request was not aborted
expect(fetchSpy.mock.calls[0][1]?.signal?.aborted).toBe(false)
})

it('sends telemetry data successfuly on error', async () => {
Expand All @@ -160,6 +173,10 @@ testWithAnvilL2('BaseCommand', (web3: Web3) => {
}
}

jest.spyOn(config, 'readConfig').mockImplementation((_: string) => {
return { telemetry: true } as config.CeloConfig
})

// here we test also that it works with this env var set to 1 explicitly
process.env.TELEMETRY_ENABLED = '1'
process.env.TELEMETRY_URL = 'https://telemetry.example.com'
Expand Down Expand Up @@ -187,7 +204,89 @@ testWithAnvilL2('BaseCommand', (web3: Web3) => {
`)
expect(fetchSpy.mock.calls[0][1]?.method).toMatchInlineSnapshot(`"POST"`)
expect(fetchSpy.mock.calls[0][1]?.signal).toBeInstanceOf(AbortSignal)
// Make sure the request was not aborted
expect(fetchSpy.mock.calls[0][1]?.signal?.aborted).toBe(false)
})

it('does not send telemetry when disabled by config', async () => {
class TestTelemetryCommand extends BaseCommand {
id = 'test:telemetry-should-not-be-sent'

async run() {
console.log('Successful run')
}
}

jest.spyOn(config, 'readConfig').mockImplementation((_: string) => {
return { telemetry: false } as config.CeloConfig
})

// we leave it here to double check that it is not sent even if the env var is set
process.env.TELEMETRY_ENABLED = '1'
process.env.TELEMETRY_URL = 'https://telemetry.example.com'

const fetchMock = jest.fn().mockResolvedValue({
ok: true,
})
const fetchSpy = jest.spyOn(global, 'fetch').mockImplementation(fetchMock)

await TestTelemetryCommand.run([])

expect(fetchSpy).not.toHaveBeenCalled()
})

// add timeout scenario test
it('times out after TIMEOUT', async () => {
return new Promise<void>((resolve, _) => {
const EXPECTED_COMMAND_RESULT = 'Successful run'

class TestTelemetryCommand extends BaseCommand {
id = 'test:telemetry-timeout'

async run() {
return EXPECTED_COMMAND_RESULT
}
}

jest.spyOn(config, 'readConfig').mockImplementation((_: string) => {
return { telemetry: true } as config.CeloConfig
})

delete process.env.TELEMETRY_ENABLED
process.env.TELEMETRY_URL = 'http://localhost:3000/'

const fetchSpy = jest.spyOn(global, 'fetch')

const server = http.createServer((_, res) => {
setTimeout(() => {
res.end()
}, 5000) // Higher timeout than the telemetry logic uses
})

server.listen(3000, async () => {
// Make sure the command actually returns
await expect(TestTelemetryCommand.run([])).resolves.toBe(EXPECTED_COMMAND_RESULT)

expect(fetchSpy.mock.calls.length).toEqual(1)

expect(fetchSpy.mock.calls[0][0]).toMatchInlineSnapshot(`"http://localhost:3000/"`)
expect(fetchSpy.mock.calls[0][1]?.body).toMatchInlineSnapshot(`
"
test_pag_celocli{success="true", version="telemetry-test", command="test:telemetry-timeout", network="alfajores"} 1
"
`)
expect(fetchSpy.mock.calls[0][1]?.headers).toMatchInlineSnapshot(`
{
"Content-Type": "application/octet-stream",
}
`)
expect(fetchSpy.mock.calls[0][1]?.method).toMatchInlineSnapshot(`"POST"`)
expect(fetchSpy.mock.calls[0][1]?.signal).toBeInstanceOf(AbortSignal)
// Make sure the request was aborted
expect(fetchSpy.mock.calls[0][1]?.signal?.aborted).toBe(true)

server.close()
resolve()
})
})
})
})
63 changes: 63 additions & 0 deletions packages/cli/src/commands/config/set-l2.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { newKitFromWeb3 } from '@celo/contractkit'
import { testWithAnvilL2 } from '@celo/dev-utils/lib/anvil-test'
import { ux } from '@oclif/core'
import Web3 from 'web3'
import {
extractHostFromWeb3,
stripAnsiCodesFromNestedArray,
testLocallyWithWeb3Node,
} from '../../test-utils/cliUtils'
import * as config from '../../utils/config'
import Set from './set'

process.env.NO_SYNCCHECK = 'true'

afterEach(async () => {
jest.clearAllMocks()
jest.restoreAllMocks()
})

testWithAnvilL2('config:set cmd', (web3: Web3) => {
it('shows a warning if gasCurrency is passed', async () => {
const kit = newKitFromWeb3(web3)
const feeCurrencyWhitelist = await kit.contracts.getFeeCurrencyWhitelist()
const consoleMock = jest.spyOn(ux, 'warn')
const writeMock = jest.spyOn(config, 'writeConfig')

await testLocallyWithWeb3Node(
Set,
['--gasCurrency', (await feeCurrencyWhitelist.getWhitelist())[0]],
web3
)
expect(stripAnsiCodesFromNestedArray(consoleMock.mock.calls as string[][]))
.toMatchInlineSnapshot(`
[
[
"
Setting a default gasCurrency has been removed from the config, you may still use the --gasCurrency on every command.
Did you value this feature a lot and would like to see it back? Let us know at https://github.com/celo-org/developer-tooling/discussions/92",
],
]
`)
expect(writeMock.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"node": "${extractHostFromWeb3(web3)}",
}
`)
})

it('allows to disable telemetry', async () => {
const writeMock = jest.spyOn(config, 'writeConfig')

await testLocallyWithWeb3Node(Set, ['--telemetry', '0'], web3)

// --node is passed by testLocalWithWeb3Node, so it will
// in the config as well
expect(writeMock.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"node": "${extractHostFromWeb3(web3)}",
"telemetry": false,
}
`)
})
})
36 changes: 28 additions & 8 deletions packages/cli/src/utils/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,36 @@ describe('writeConfig', () => {
expect(spy.mock.calls[0]).toHaveLength(2)
expect(spy.mock.calls[0][0]).toEqual(file)
expect(spy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"node": "http://localhost:8545",
}
`)
{
"node": "http://localhost:8545",
"telemetry": true,
}
`)
})
it('accepts node', async () => {
const [dir] = getPaths()
await writeConfig(dir, { node: 'SOME_URL', telemetry: true })
expect(spy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"node": "SOME_URL",
}
`)
{
"node": "SOME_URL",
"telemetry": true,
}
`)
})

it('accepts telemetry', async () => {
const [dir] = getPaths()
await writeConfig(dir, {
node: 'http://localhost:8545',
telemetry: false,
})

expect(spy.mock.calls[0][1]).toMatchInlineSnapshot(`
{
"node": "http://localhost:8545",
"telemetry": false,
}
`)
})
})

Expand All @@ -51,6 +68,7 @@ describe('readConfig', () => {
{
"foo": "bar",
"node": "http://localhost:8545",
"telemetry": true,
}
`)
})
Expand All @@ -60,6 +78,7 @@ describe('readConfig', () => {
expect(readConfig(dir)).toMatchInlineSnapshot(`
{
"node": "bar",
"telemetry": true,
}
`)
})
Expand All @@ -69,6 +88,7 @@ describe('readConfig', () => {
expect(readConfig(dir)).toMatchInlineSnapshot(`
{
"node": "http://localhost:8545",
"telemetry": true,
}
`)
})
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/utils/telemetry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('telemetry', () => {
Data being reported is:
- command (for example network:info)
- celocli version (for example 5.2.3)
- success status (0/1)
- success status (false/true)
If you would like to opt out of this data collection, you can do so by running:
Expand Down

0 comments on commit a5b0d5c

Please sign in to comment.