-
Notifications
You must be signed in to change notification settings - Fork 97
fix: not enough information to count sequential failures #1614
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
Changes from all commits
25e47c3
e2058d6
7d52baf
dd8ced0
ec15d10
af01a37
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| import * as path from 'path'; | ||
| import * as fs from 'fs-extra'; | ||
| import { integTest, withSpecificFixture } from '../../lib'; | ||
|
|
||
| integTest( | ||
| 'multiple deploys track their failures', | ||
| withSpecificFixture('diagnose-app', async (fixture) => { | ||
| const telemetryFile = path.join(fixture.integTestDir, 'telemetry.json'); | ||
|
|
||
| // Deploy a stack that will fail (IAM Policy without PolicyDocument) | ||
| await fixture.cdkDeploy('diagnose-deploy-fail', { | ||
| allowErrExit: true, | ||
| telemetryFile, | ||
| }); | ||
|
|
||
| await fixture.cdkDeploy('diagnose-deploy-fail', { | ||
| allowErrExit: true, | ||
| telemetryFile, | ||
| }); | ||
|
|
||
| // Should see a DEPLOY event with sequentialDeploymentFailures: 2 | ||
| const json = fs.readJSONSync(telemetryFile); | ||
| expect(json).toEqual([ | ||
| expect.objectContaining({ | ||
| event: expect.objectContaining({ | ||
| eventType: 'SYNTH', | ||
| }), | ||
| }), | ||
| expect.objectContaining({ | ||
| event: expect.objectContaining({ | ||
| eventType: 'ASSET', | ||
| }), | ||
| }), | ||
| expect.objectContaining({ | ||
| event: expect.objectContaining({ | ||
| eventType: 'DEPLOY', | ||
| }), | ||
| counters: expect.objectContaining({ | ||
| sequentialDeploymentFailures: 2, | ||
| }), | ||
| }), | ||
| expect.objectContaining({ | ||
| event: expect.objectContaining({ | ||
| eventType: 'INVOKE', | ||
| }), | ||
| }), | ||
| ]); | ||
| }), | ||
| ); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| import * as fs from 'fs/promises'; | ||
| import * as path from 'path'; | ||
| import { ensureCacheDir } from './installation-id'; | ||
| import { cdkCacheDir } from '../../util'; | ||
|
|
||
| /** | ||
| * Telemetry state across CLI invocations | ||
| */ | ||
| export interface TelemetryState { | ||
| /** | ||
| * How many deployment failures we've seen since the last success. | ||
| */ | ||
| sequentialDeploymentFailures?: number; | ||
| } | ||
|
|
||
| /** | ||
| * Run a function that can modify the given telemetry state. | ||
| */ | ||
| export async function withTelemetryState<A>(block: (x: TelemetryState) => A): Promise<A> { | ||
| const state = await loadTelemetryState(); | ||
| const oldState = JSON.stringify(state); | ||
|
|
||
| const ret = block(state); | ||
|
|
||
| // Only write a file if the contents changed. | ||
| if (JSON.stringify(ret) !== oldState) { | ||
| await writeTelemetryState(state); | ||
| } | ||
|
|
||
| return ret; | ||
| } | ||
|
|
||
| /** | ||
| * Load telemetry state | ||
| */ | ||
| export async function loadTelemetryState(): Promise<TelemetryState> { | ||
| try { | ||
| return JSON.parse(await fs.readFile(TELEMETRY_STATE_PATH, 'utf-8')); | ||
| } catch (e: any) { | ||
| if (e.code === 'ENOENT') { | ||
| return {}; | ||
| } | ||
| throw e; | ||
| } | ||
| } | ||
|
|
||
| export async function writeTelemetryState(state: TelemetryState) { | ||
| await ensureCacheDir(); | ||
|
|
||
| await fs.writeFile(TELEMETRY_STATE_PATH, JSON.stringify(state, undefined, 2), 'utf-8'); | ||
| } | ||
|
|
||
| const TELEMETRY_STATE_PATH = path.join(cdkCacheDir(), 'telemetry-state.json'); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we add a test that confirms malformed telemetry state is not passed on?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you under the impression that the whole of
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not today. i am concerned in the future someone adds to TelemetryState a string property that is directly passed on to the server |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we enforce that
TelemetryStateonly ever includes properties of typebooleanornumber(orenumi guess). my worry is that a user can modify their telemetry file however they want andTelemetryStateis the only gate we have to enforce that the data is what we expect. If we in the future addpreviousInstallationIds: string[](we definitely shouldn't do this but I digress) then we open the doors to collecting customer content in these strings