Skip to content

Commit 40300ea

Browse files
authored
test(node): Add prisma OpenTelemetry integration tests. (#10778)
1 parent fdeaadf commit 40300ea

File tree

10 files changed

+302
-1
lines changed

10 files changed

+302
-1
lines changed

dev-packages/node-integration-tests/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
"build:types": "tsc -p tsconfig.types.json",
1717
"clean": "rimraf -g **/node_modules && run-p clean:script",
1818
"clean:script": "node scripts/clean.js",
19+
"prisma:init": "(cd suites/tracing-experimental/prisma-orm && ts-node ./setup.ts)",
1920
"lint": "eslint . --format stylish",
2021
"fix": "eslint . --format stylish --fix",
2122
"type-check": "tsc",
23+
"pretest": "run-s --silent prisma:init",
2224
"test": "ts-node ./utils/run-tests.ts",
2325
"jest": "jest --config ./jest.config.js",
2426
"test:watch": "yarn test --watch"
@@ -28,7 +30,7 @@
2830
"@nestjs/core": "^10.3.3",
2931
"@nestjs/common": "^10.3.3",
3032
"@nestjs/platform-express": "^10.3.3",
31-
"@prisma/client": "3.15.2",
33+
"@prisma/client": "5.9.1",
3234
"@sentry/node": "7.100.0",
3335
"@sentry/tracing": "7.100.0",
3436
"@sentry/types": "7.100.0",
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: '3.9'
2+
3+
services:
4+
db:
5+
image: postgres:13
6+
restart: always
7+
container_name: integration-tests-prisma
8+
ports:
9+
- '5433:5432'
10+
environment:
11+
POSTGRES_USER: prisma
12+
POSTGRES_PASSWORD: prisma
13+
POSTGRES_DB: tests
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "sentry-prisma-test",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"engines": {
7+
"node": ">=16"
8+
},
9+
"scripts": {
10+
"db-up": "docker-compose up -d",
11+
"generate": "prisma generate",
12+
"migrate": "prisma migrate dev -n sentry-test",
13+
"setup": "run-s --silent db-up generate migrate"
14+
},
15+
"keywords": [],
16+
"author": "",
17+
"license": "ISC",
18+
"dependencies": {
19+
"@prisma/client": "5.9.1",
20+
"prisma": "^5.9.1"
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Please do not edit this file manually
2+
# It should be added in your version-control system (i.e. Git)
3+
provider = "postgresql"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-- CreateTable
2+
CREATE TABLE "User" (
3+
"id" SERIAL NOT NULL,
4+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
5+
"email" TEXT NOT NULL,
6+
"name" TEXT,
7+
8+
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
9+
);
10+
11+
-- CreateIndex
12+
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
datasource db {
2+
url = "postgresql://prisma:prisma@localhost:5433/tests"
3+
provider = "postgresql"
4+
}
5+
6+
generator client {
7+
provider = "prisma-client-js"
8+
previewFeatures = ["tracing"]
9+
}
10+
11+
model User {
12+
id Int @id @default(autoincrement())
13+
createdAt DateTime @default(now())
14+
email String @unique
15+
name String?
16+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const { randomBytes } = require('crypto');
2+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
3+
const { PrismaClient } = require('@prisma/client');
4+
const Sentry = require('@sentry/node');
5+
const { loggingTransport } = require('@sentry-internal/node-integration-tests');
6+
7+
Sentry.init({
8+
dsn: 'https://[email protected]/1337',
9+
release: '1.0',
10+
tracesSampleRate: 1.0,
11+
transport: loggingTransport,
12+
});
13+
14+
// Stop the process from exiting before the transaction is sent
15+
setInterval(() => {}, 1000);
16+
17+
async function run() {
18+
const client = new PrismaClient();
19+
20+
await Sentry.startSpan(
21+
{
22+
name: 'Test Transaction',
23+
op: 'transaction',
24+
},
25+
async span => {
26+
await client.user.create({
27+
data: {
28+
name: 'Tilda',
29+
email: `tilda_${randomBytes(4).toString('hex')}@sentry.io`,
30+
},
31+
});
32+
33+
await client.user.findMany();
34+
35+
await client.user.deleteMany({
36+
where: {
37+
email: {
38+
contains: 'sentry.io',
39+
},
40+
},
41+
});
42+
43+
setTimeout(async () => {
44+
span.end();
45+
await client.$disconnect();
46+
}, 500);
47+
},
48+
);
49+
}
50+
51+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
52+
run();
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { execSync } from 'child_process';
2+
import { parseSemver } from '@sentry/utils';
3+
4+
const NODE_VERSION = parseSemver(process.versions.node);
5+
6+
// Prisma v5 requires Node.js v16+
7+
// https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-5#nodejs-minimum-version-change
8+
if (NODE_VERSION.major && NODE_VERSION.major < 16) {
9+
// eslint-disable-next-line no-console
10+
console.warn(`Skipping Prisma tests on Node: ${NODE_VERSION.major}`);
11+
process.exit(0);
12+
}
13+
14+
try {
15+
execSync('yarn && yarn setup');
16+
} catch (_) {
17+
process.exit(1);
18+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { conditionalTest } from '../../../utils';
2+
import { createRunner } from '../../../utils/runner';
3+
4+
conditionalTest({ min: 16 })('Prisma ORM Tests', () => {
5+
test('CJS - should instrument PostgreSQL queries from Prisma ORM', done => {
6+
const EXPECTED_TRANSACTION = {
7+
transaction: 'Test Transaction',
8+
spans: expect.arrayContaining([
9+
expect.objectContaining({
10+
data: expect.objectContaining({
11+
method: 'create',
12+
model: 'User',
13+
name: 'User.create',
14+
'otel.kind': 'INTERNAL',
15+
'sentry.origin': 'manual',
16+
}),
17+
description: 'prisma:client:operation',
18+
status: 'ok',
19+
}),
20+
expect.objectContaining({
21+
data: expect.objectContaining({
22+
'otel.kind': 'INTERNAL',
23+
'sentry.origin': 'manual',
24+
}),
25+
description: 'prisma:client:serialize',
26+
status: 'ok',
27+
}),
28+
expect.objectContaining({
29+
data: expect.objectContaining({
30+
'otel.kind': 'INTERNAL',
31+
'sentry.origin': 'manual',
32+
}),
33+
description: 'prisma:client:connect',
34+
status: 'ok',
35+
}),
36+
expect.objectContaining({
37+
data: expect.objectContaining({
38+
'otel.kind': 'INTERNAL',
39+
'sentry.origin': 'manual',
40+
}),
41+
description: 'prisma:engine',
42+
status: 'ok',
43+
}),
44+
expect.objectContaining({
45+
data: expect.objectContaining({
46+
'db.type': 'postgres',
47+
'otel.kind': 'INTERNAL',
48+
'sentry.origin': 'manual',
49+
}),
50+
description: 'prisma:engine:connection',
51+
status: 'ok',
52+
}),
53+
expect.objectContaining({
54+
data: expect.objectContaining({
55+
'db.statement': expect.stringContaining(
56+
'INSERT INTO "public"."User" ("createdAt","email","name") VALUES ($1,$2,$3) RETURNING "public"."User"."id", "public"."User"."createdAt", "public"."User"."email", "public"."User"."name" /* traceparent',
57+
),
58+
'otel.kind': 'INTERNAL',
59+
'sentry.origin': 'manual',
60+
}),
61+
description: 'prisma:engine:db_query',
62+
status: 'ok',
63+
}),
64+
expect.objectContaining({
65+
data: expect.objectContaining({
66+
'otel.kind': 'INTERNAL',
67+
'sentry.origin': 'manual',
68+
}),
69+
description: 'prisma:engine:serialize',
70+
status: 'ok',
71+
}),
72+
expect.objectContaining({
73+
data: expect.objectContaining({
74+
'otel.kind': 'INTERNAL',
75+
'sentry.origin': 'manual',
76+
}),
77+
description: 'prisma:engine:response_json_serialization',
78+
status: 'ok',
79+
}),
80+
expect.objectContaining({
81+
data: expect.objectContaining({
82+
method: 'findMany',
83+
model: 'User',
84+
name: 'User.findMany',
85+
'otel.kind': 'INTERNAL',
86+
'sentry.origin': 'manual',
87+
}),
88+
description: 'prisma:client:operation',
89+
status: 'ok',
90+
}),
91+
expect.objectContaining({
92+
data: expect.objectContaining({
93+
'otel.kind': 'INTERNAL',
94+
'sentry.origin': 'manual',
95+
}),
96+
description: 'prisma:client:serialize',
97+
status: 'ok',
98+
}),
99+
expect.objectContaining({
100+
data: expect.objectContaining({
101+
'otel.kind': 'INTERNAL',
102+
'sentry.origin': 'manual',
103+
}),
104+
description: 'prisma:engine',
105+
status: 'ok',
106+
}),
107+
]),
108+
};
109+
110+
createRunner(__dirname, 'scenario.js').expect({ transaction: EXPECTED_TRANSACTION }).start(done);
111+
});
112+
});
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2+
# yarn lockfile v1
3+
4+
5+
6+
version "5.9.1"
7+
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.9.1.tgz#d92bd2f7f006e0316cb4fda9d73f235965cf2c64"
8+
integrity sha512-caSOnG4kxcSkhqC/2ShV7rEoWwd3XrftokxJqOCMVvia4NYV/TPtJlS9C2os3Igxw/Qyxumj9GBQzcStzECvtQ==
9+
10+
11+
version "5.9.1"
12+
resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.9.1.tgz#906274e73d3267f88b69459199fa3c51cd9511a3"
13+
integrity sha512-yAHFSFCg8KVoL0oRUno3m60GAjsUKYUDkQ+9BA2X2JfVR3kRVSJFc/GpQ2fSORi4pSHZR9orfM4UC9OVXIFFTA==
14+
15+
"@prisma/engines-version@5.9.0-32.23fdc5965b1e05fc54e5f26ed3de66776b93de64":
16+
version "5.9.0-32.23fdc5965b1e05fc54e5f26ed3de66776b93de64"
17+
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.9.0-32.23fdc5965b1e05fc54e5f26ed3de66776b93de64.tgz#54d2164f28d23e09d41cf9eb0bddbbe7f3aaa660"
18+
integrity sha512-HFl7275yF0FWbdcNvcSRbbu9JCBSLMcurYwvWc8WGDnpu7APxQo2ONtZrUggU3WxLxUJ2uBX+0GOFIcJeVeOOQ==
19+
20+
21+
version "5.9.1"
22+
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.9.1.tgz#767539afc6f193a182d0495b30b027f61f279073"
23+
integrity sha512-gkdXmjxQ5jktxWNdDA5aZZ6R8rH74JkoKq6LD5mACSvxd2vbqWeWIOV0Py5wFC8vofOYShbt6XUeCIUmrOzOnQ==
24+
dependencies:
25+
"@prisma/debug" "5.9.1"
26+
"@prisma/engines-version" "5.9.0-32.23fdc5965b1e05fc54e5f26ed3de66776b93de64"
27+
"@prisma/fetch-engine" "5.9.1"
28+
"@prisma/get-platform" "5.9.1"
29+
30+
31+
version "5.9.1"
32+
resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.9.1.tgz#5d3b2c9af54a242e37b3f9561b59ab72f8e92818"
33+
integrity sha512-l0goQOMcNVOJs1kAcwqpKq3ylvkD9F04Ioe1oJoCqmz05mw22bNAKKGWuDd3zTUoUZr97va0c/UfLNru+PDmNA==
34+
dependencies:
35+
"@prisma/debug" "5.9.1"
36+
"@prisma/engines-version" "5.9.0-32.23fdc5965b1e05fc54e5f26ed3de66776b93de64"
37+
"@prisma/get-platform" "5.9.1"
38+
39+
40+
version "5.9.1"
41+
resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.9.1.tgz#a66bb46ab4d30db786c84150ef074ab0aad4549e"
42+
integrity sha512-6OQsNxTyhvG+T2Ksr8FPFpuPeL4r9u0JF0OZHUBI/Uy9SS43sPyAIutt4ZEAyqWQt104ERh70EZedkHZKsnNbg==
43+
dependencies:
44+
"@prisma/debug" "5.9.1"
45+
46+
prisma@^5.9.1:
47+
version "5.9.1"
48+
resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.9.1.tgz#baa3dd635fbf71504980978f10f55ea11068f6aa"
49+
integrity sha512-Hy/8KJZz0ELtkw4FnG9MS9rNWlXcJhf98Z2QMqi0QiVMoS8PzsBkpla0/Y5hTlob8F3HeECYphBjqmBxrluUrQ==
50+
dependencies:
51+
"@prisma/engines" "5.9.1"

0 commit comments

Comments
 (0)