-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
68fe99a
commit 9e1048a
Showing
12 changed files
with
295 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,53 @@ | ||
import { isPromise } from "node:util/types"; | ||
|
||
import type * as AppMap from "./AppMap"; | ||
import { exceptionMetadata } from "./metadata"; | ||
|
||
import { recording, start } from "./recorder"; | ||
import { | ||
disableGlobalRecording, | ||
startCodeBlockRecording, | ||
stopCodeBlockRecording, | ||
} from "./recorderControl"; | ||
import Recording from "./Recording"; | ||
|
||
// Since _this_ module is loaded, we'll do code block recording only. | ||
recording.abandon(); | ||
disableGlobalRecording(); | ||
|
||
function isInstrumented() { | ||
return "AppMapRecordHook" in global; | ||
} | ||
|
||
type NotPromise<T> = T extends Promise<unknown> ? never : T; | ||
|
||
export function record<T>(block: () => NotPromise<T>): AppMap.AppMap | undefined; | ||
export function record<T>(block: () => Promise<T>): Promise<AppMap.AppMap | undefined>; | ||
|
||
export function record( | ||
block: () => unknown, | ||
): AppMap.AppMap | Promise<AppMap.AppMap | undefined> | undefined { | ||
if (!isInstrumented()) | ||
throw Error("Code is not instrumented. Please run the project with appmap-node."); | ||
|
||
start(new Recording("block", "block", new Date().toISOString())); | ||
startCodeBlockRecording(); | ||
try { | ||
const result = block(); | ||
if (isPromise(result)) return result.then(() => finishRecording(), finishRecording); | ||
} catch (exn) { | ||
return finishRecording(exn); | ||
} | ||
return finishRecording(); | ||
} | ||
|
||
function finishRecording(exn?: unknown): AppMap.AppMap | undefined { | ||
stopCodeBlockRecording(); | ||
if (!recording.finish()) return; | ||
|
||
const appmap = recording.readAppMap(); | ||
if (exn && appmap.metadata) appmap.metadata.exception = exceptionMetadata(exn); | ||
return appmap; | ||
} | ||
|
||
export * as AppMap from "./AppMap"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Not put into recorder.ts to prevent circular dependency | ||
let _recorderPaused = false; | ||
export const pauseRecorder = () => (_recorderPaused = true); | ||
export const resumeRecorder = () => (_recorderPaused = false); | ||
export const recorderPaused = () => _recorderPaused; | ||
|
||
let _globalRecordingDisabled = false; | ||
export const disableGlobalRecording = () => (_globalRecordingDisabled = true); | ||
export const enableGlobalRecording = () => (_globalRecordingDisabled = false); | ||
export const globalRecordingDisabled = () => _globalRecordingDisabled; | ||
|
||
let _codeBlockRecordingActive = false; | ||
export const startCodeBlockRecording = () => (_codeBlockRecordingActive = true); | ||
export const stopCodeBlockRecording = () => (_codeBlockRecordingActive = false); | ||
export const codeBlockRecordingActive = () => _codeBlockRecordingActive; | ||
|
||
export const shouldRecord = () => | ||
!recorderPaused() && (!globalRecordingDisabled() || codeBlockRecordingActive()); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`mapping code block recording 1`] = ` | ||
{ | ||
"./tmp/appmap/block/<timestamp 0>.appmap.json": { | ||
"classMap": [ | ||
{ | ||
"children": [ | ||
{ | ||
"children": [ | ||
{ | ||
"location": "index.js:5", | ||
"name": "hello", | ||
"static": true, | ||
"type": "function", | ||
}, | ||
], | ||
"name": "index", | ||
"type": "class", | ||
}, | ||
], | ||
"name": "codeBlock", | ||
"type": "package", | ||
}, | ||
], | ||
"events": [ | ||
{ | ||
"defined_class": "index", | ||
"event": "call", | ||
"id": 1, | ||
"lineno": 5, | ||
"method_id": "hello", | ||
"parameters": [ | ||
{ | ||
"class": "String", | ||
"name": "message", | ||
"value": "'world'", | ||
}, | ||
], | ||
"path": "index.js", | ||
"static": true, | ||
"thread_id": 0, | ||
}, | ||
{ | ||
"elapsed": 31.337, | ||
"event": "return", | ||
"id": 2, | ||
"parent_id": 1, | ||
"thread_id": 0, | ||
}, | ||
], | ||
"metadata": { | ||
"app": "codeBlock", | ||
"client": { | ||
"name": "appmap-node", | ||
"url": "https://github.com/getappmap/appmap-node", | ||
"version": "test node-appmap version", | ||
}, | ||
"language": { | ||
"engine": "Node.js", | ||
"name": "javascript", | ||
"version": "test node version", | ||
}, | ||
"name": "<timestamp 0>", | ||
"recorder": { | ||
"name": "block", | ||
"type": "block", | ||
}, | ||
}, | ||
"version": "1.12", | ||
}, | ||
"./tmp/appmap/block/<timestamp 1>.appmap.json": { | ||
"classMap": [ | ||
{ | ||
"children": [ | ||
{ | ||
"children": [ | ||
{ | ||
"location": "index.js:5", | ||
"name": "hello", | ||
"static": true, | ||
"type": "function", | ||
}, | ||
], | ||
"name": "index", | ||
"type": "class", | ||
}, | ||
], | ||
"name": "codeBlock", | ||
"type": "package", | ||
}, | ||
], | ||
"events": [ | ||
{ | ||
"defined_class": "index", | ||
"event": "call", | ||
"id": 1, | ||
"lineno": 5, | ||
"method_id": "hello", | ||
"parameters": [ | ||
{ | ||
"class": "String", | ||
"name": "message", | ||
"value": "'world async'", | ||
}, | ||
], | ||
"path": "index.js", | ||
"static": true, | ||
"thread_id": 0, | ||
}, | ||
{ | ||
"elapsed": 31.337, | ||
"event": "return", | ||
"id": 2, | ||
"parent_id": 1, | ||
"thread_id": 0, | ||
}, | ||
], | ||
"metadata": { | ||
"app": "codeBlock", | ||
"client": { | ||
"name": "appmap-node", | ||
"url": "https://github.com/getappmap/appmap-node", | ||
"version": "test node-appmap version", | ||
}, | ||
"language": { | ||
"engine": "Node.js", | ||
"name": "javascript", | ||
"version": "test node version", | ||
}, | ||
"name": "<timestamp 1>", | ||
"recorder": { | ||
"name": "block", | ||
"type": "block", | ||
}, | ||
}, | ||
"version": "1.12", | ||
}, | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { spawnSync } from "node:child_process"; | ||
|
||
import { integrationTest, readAppmaps, resolveTarget, runAppmapNode } from "./helpers"; | ||
|
||
integrationTest("mapping code block recording", () => { | ||
expect(runAppmapNode("index.js").status).toBe(0); | ||
expect(readAppmaps()).toMatchSnapshot(); | ||
}); | ||
|
||
integrationTest("throws when not run with appmap-node", () => { | ||
const testDir = resolveTarget(); | ||
const result = spawnSync(process.argv[0], ["index.js"], { cwd: testDir }); | ||
expect(result.stderr?.toString()).toContain( | ||
"Code is not instrumented. Please run the project with appmap-node.", | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
name: codeBlock | ||
appmap_dir: tmp/appmap |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* eslint-disable @typescript-eslint/no-var-requires */ | ||
const assert = require("node:assert"); | ||
const { record } = require("../../dist/facade"); | ||
|
||
function hello(message) { | ||
console.log("hello", message); | ||
} | ||
|
||
async function main() { | ||
hello("darkness my old friend"); | ||
|
||
const appmap1 = record(() => { | ||
hello("world"); | ||
}); | ||
|
||
hello("123"); | ||
|
||
assert(appmap1.events.filter((e) => e.event == "call").length == 1); | ||
|
||
const appmap2 = await record(async () => { | ||
hello("world async"); | ||
}); | ||
|
||
hello("x"); | ||
hello("y"); | ||
hello("z"); | ||
|
||
assert(appmap2.events.filter((e) => e.event == "call").length == 1); | ||
} | ||
|
||
main(); |