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

fix(observability): fix the spans for the abort transaction #2188

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c62584c
chore: integration test fix
surbhigarg92 Jan 11, 2024
e7d385b
Merge branch 'googleapis:main' into main
surbhigarg92 Mar 4, 2024
e57b897
Merge branch 'googleapis:main' into main
surbhigarg92 Mar 4, 2024
c0c935e
Merge branch 'googleapis:main' into main
surbhigarg92 Mar 8, 2024
8875f2c
Merge branch 'googleapis:main' into main
surbhigarg92 Mar 26, 2024
a903eec
Merge branch 'googleapis:main' into main
surbhigarg92 Apr 9, 2024
50914dc
Merge branch 'googleapis:main' into main
surbhigarg92 Jun 17, 2024
95aa578
Merge branch 'googleapis:main' into main
surbhigarg92 Jun 26, 2024
738804b
Merge branch 'googleapis:main' into main
surbhigarg92 Jul 3, 2024
b53a82f
Merge branch 'googleapis:main' into main
surbhigarg92 Jul 31, 2024
eb858ac
Merge branch 'googleapis:main' into main
surbhigarg92 Aug 6, 2024
163699b
Merge branch 'googleapis:main' into main
surbhigarg92 Aug 8, 2024
0f6fda3
Merge branch 'googleapis:main' into main
surbhigarg92 Sep 23, 2024
4b173ba
Merge branch 'googleapis:main' into main
surbhigarg92 Sep 30, 2024
4261105
Merge branch 'googleapis:main' into main
surbhigarg92 Oct 10, 2024
6a77a21
Merge branch 'googleapis:main' into main
surbhigarg92 Oct 21, 2024
c597b74
Merge remote-tracking branch 'upstream/main'
surbhigarg92 Oct 21, 2024
56df6b4
Merge branch 'googleapis:main' into main
surbhigarg92 Oct 22, 2024
bd4647c
Merge branch 'googleapis:main' into main
surbhigarg92 Oct 24, 2024
4b2f196
Merge branch 'googleapis:main' into main
surbhigarg92 Oct 28, 2024
207b382
Merge branch 'googleapis:main' into main
surbhigarg92 Oct 30, 2024
e3b4394
Merge branch 'googleapis:main' into main
surbhigarg92 Nov 7, 2024
22b1c5d
Merge branch 'googleapis:main' into main
surbhigarg92 Nov 8, 2024
fb26cc4
Merge branch 'googleapis:main' into main
surbhigarg92 Nov 11, 2024
02c4c1f
Merge branch 'googleapis:main' into main
surbhigarg92 Nov 12, 2024
6a8a8a0
Spans for abort transactions
surbhigarg92 Nov 12, 2024
430a33c
remove snapshot.run span
surbhigarg92 Nov 19, 2024
f5d21a3
Added span in partialresultStream
surbhigarg92 Nov 21, 2024
09a8451
Merge branch 'main' into abort_test
surbhigarg92 Nov 21, 2024
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
4 changes: 2 additions & 2 deletions observability-test/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@

class FakeSession {
calledWith_: IArguments;
formattedName_: any;

Check warning on line 96 in observability-test/database.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
constructor() {
this.calledWith_ = arguments;
}
Expand Down Expand Up @@ -682,7 +682,7 @@
'Expected that secondRetrySpan is the child to parentSpan'
);

const expectedEventNames = ['No session available'];
const expectedEventNames = ['No session available', 'Using Session'];
assert.deepStrictEqual(
actualEventNames,
expectedEventNames,
Expand Down Expand Up @@ -1558,7 +1558,7 @@
);

// We don't expect events.
const expectedEventNames = [];
const expectedEventNames = ['Using Session'];
assert.deepStrictEqual(
actualEventNames,
expectedEventNames,
Expand Down
16 changes: 14 additions & 2 deletions observability-test/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const cacheSessionEvents = [
'Acquiring session',
'Cache hit: has usable session',
'Acquired session',
'Using Session',
];

/**
Expand Down Expand Up @@ -82,14 +83,25 @@ export async function verifySpansAndEvents(
actualEventNames.push(event.name);
});
});

assert.strictEqual(
actualSpanNames.length,
expectedSpans.length,
`Span count mismatch: Expected ${expectedSpans.length} spans, but received ${actualSpanNames.length} spans`
);
assert.deepStrictEqual(
actualSpanNames,
expectedSpans,
`span names mismatch:\n\tGot: ${actualSpanNames}\n\tWant: ${expectedSpans}`
);
assert.strictEqual(
actualEventNames.length,
expectedEvents.length,
`Event count mismatch: Expected ${expectedEvents.length} events, but received ${actualEventNames.length} events`
);
assert.deepStrictEqual(
actualEventNames,
expectedEvents,
actualEventNames.sort(),
expectedEvents.sort(),
`Unexpected events:\n\tGot: ${actualEventNames}\n\tWant: ${expectedEvents}`
);
}
153 changes: 106 additions & 47 deletions observability-test/spanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ describe('EndToEnd', async () => {
tracerProvider: tracerProvider,
enableExtendedTracing: false,
});
let dbCounter = 1;

function newTestDatabase(): Database {
return instance.database(`database-${dbCounter++}`);
}

const server = setupResult.server;
const spannerMock = setupResult.spannerMock;
Expand Down Expand Up @@ -195,7 +200,6 @@ describe('EndToEnd', async () => {
'CloudSpanner.Snapshot.begin',
'CloudSpanner.Database.getSnapshot',
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Snapshot.run',
];
const expectedEventNames = [
'Begin Transaction',
Expand All @@ -221,7 +225,7 @@ describe('EndToEnd', async () => {
transaction!.commit();

const expectedSpanNames = ['CloudSpanner.Database.getTransaction'];
const expectedEventNames = [...cacheSessionEvents, 'Using Session'];
const expectedEventNames = [...cacheSessionEvents];
await verifySpansAndEvents(
traceExporter,
expectedSpanNames,
Expand All @@ -241,11 +245,7 @@ describe('EndToEnd', async () => {
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Database.runStream',
];
const expectedEventNames = [
'Starting stream',
...cacheSessionEvents,
'Using Session',
];
const expectedEventNames = ['Starting stream', ...cacheSessionEvents];
await verifySpansAndEvents(
traceExporter,
expectedSpanNames,
Expand All @@ -263,11 +263,7 @@ describe('EndToEnd', async () => {
'CloudSpanner.Database.runStream',
'CloudSpanner.Database.run',
];
const expectedEventNames = [
'Starting stream',
...cacheSessionEvents,
'Using Session',
];
const expectedEventNames = ['Starting stream', ...cacheSessionEvents];
await verifySpansAndEvents(
traceExporter,
expectedSpanNames,
Expand All @@ -283,16 +279,15 @@ describe('EndToEnd', async () => {
await transaction!.end();
const expectedSpanNames = [
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Snapshot.run',
'CloudSpanner.Transaction.commit',
'CloudSpanner.Database.runTransaction',
];
const expectedEventNames = [
'Starting stream',
'Transaction Creation Done',
'Starting Commit',
'Commit Done',
...cacheSessionEvents,
'Transaction Creation Done',
];

await verifySpansAndEvents(
Expand All @@ -311,14 +306,12 @@ describe('EndToEnd', async () => {

const expectedSpanNames = [
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Snapshot.run',
'CloudSpanner.Database.runTransactionAsync',
];
const expectedEventNames = [
'Starting stream',
'Transaction Creation Done',
...cacheSessionEvents,
'Using Session',
'Transaction Creation Done',
];
await verifySpansAndEvents(
traceExporter,
Expand All @@ -327,6 +320,101 @@ describe('EndToEnd', async () => {
);
});

it.skip('runTransaction with abort', done => {
let attempts = 0;
let rowCount = 0;
const database = newTestDatabase();
database.runTransaction(async (err, transaction) => {
assert.ifError(err);
if (!attempts) {
spannerMock.abortTransaction(transaction!);
}
attempts++;
transaction!.run(selectSql, (err, rows) => {
assert.ifError(err);
rows.forEach(() => rowCount++);
transaction!
.commit()
.catch(done)
.then(async () => {
const expectedSpanNames = [
'CloudSpanner.Database.batchCreateSessions',
'CloudSpanner.SessionPool.createSessions',
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Snapshot.begin',
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Transaction.commit',
'CloudSpanner.Database.runTransaction',
];
const expectedEventNames = [
...batchCreateSessionsEvents,
'Starting stream',
'Begin Transaction',
'Transaction Creation Done',
'Starting stream',
'Starting Commit',
'Commit Done',
...waitingSessionsEvents,
'Retrying transaction',
];
await verifySpansAndEvents(
traceExporter,
expectedSpanNames,
expectedEventNames
);
database
.close()
.catch(done)
.then(() => done());
});
});
});
});

it('runTransactionAsync with abort', async () => {
let attempts = 0;
const database = newTestDatabase();
await database.runTransactionAsync((transaction): Promise<number> => {
if (!attempts) {
spannerMock.abortTransaction(transaction);
}
attempts++;
return transaction.run(selectSql).then(([rows]) => {
let count = 0;
rows.forEach(() => count++);
return transaction.commit().then(() => count);
});
});
assert.strictEqual(attempts, 2);
const expectedSpanNames = [
'CloudSpanner.Database.batchCreateSessions',
'CloudSpanner.SessionPool.createSessions',
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Snapshot.begin',
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Transaction.commit',
'CloudSpanner.Database.runTransactionAsync',
];
const expectedEventNames = [
...batchCreateSessionsEvents,
'Starting stream',
'Stream broken. Not safe to retry',
'Begin Transaction',
'Transaction Creation Done',
'Starting stream',
'Starting Commit',
'Commit Done',
...waitingSessionsEvents,
'Retrying transaction',
];
await verifySpansAndEvents(
traceExporter,
expectedSpanNames,
expectedEventNames
);
await database.close();
});

it('writeAtLeastOnce', done => {
const blankMutations = new MutationSet();
database.writeAtLeastOnce(blankMutations, async (err, response) => {
Expand All @@ -340,7 +428,6 @@ describe('EndToEnd', async () => {
'Starting Commit',
'Commit Done',
...cacheSessionEvents,
'Using Session',
];
await verifySpansAndEvents(
traceExporter,
Expand Down Expand Up @@ -371,7 +458,6 @@ describe('EndToEnd', async () => {
const expectedSpanNames = [
'CloudSpanner.Snapshot.begin',
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Snapshot.run',
'CloudSpanner.Dml.runUpdate',
'CloudSpanner.PartitionedDml.runUpdate',
'CloudSpanner.Database.runPartitionedUpdate',
Expand Down Expand Up @@ -530,7 +616,6 @@ describe('ObservabilityOptions injection and propagation', async () => {
const expectedSpanNames = [
'CloudSpanner.Database.getTransaction',
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Snapshot.run',
];
assert.deepStrictEqual(
actualSpanNames,
Expand All @@ -540,7 +625,6 @@ describe('ObservabilityOptions injection and propagation', async () => {

const expectedEventNames = [
...cacheSessionEvents,
'Using Session',
'Starting stream',
'Transaction Creation Done',
];
Expand Down Expand Up @@ -585,7 +669,6 @@ describe('ObservabilityOptions injection and propagation', async () => {
const expectedSpanNames = [
'CloudSpanner.Snapshot.begin',
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Snapshot.run',
'CloudSpanner.Dml.runUpdate',
];
assert.deepStrictEqual(
Expand Down Expand Up @@ -649,7 +732,6 @@ describe('ObservabilityOptions injection and propagation', async () => {

const expectedEventNames = [
...cacheSessionEvents,
'Using Session',
'Starting stream',
];
assert.deepStrictEqual(
Expand Down Expand Up @@ -694,7 +776,6 @@ describe('ObservabilityOptions injection and propagation', async () => {
const expectedSpanNames = [
'CloudSpanner.Snapshot.begin',
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Snapshot.run',
'CloudSpanner.Dml.runUpdate',
'CloudSpanner.Transaction.rollback',
];
Expand Down Expand Up @@ -1247,7 +1328,6 @@ SELECT 1p
'CloudSpanner.Database.batchCreateSessions',
'CloudSpanner.SessionPool.createSessions',
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Snapshot.run',
'CloudSpanner.Snapshot.begin',
'CloudSpanner.Snapshot.begin',
'CloudSpanner.Transaction.commit',
Expand All @@ -1259,19 +1339,6 @@ SELECT 1p
expectedSpanNames,
`span names mismatch:\n\tGot: ${actualSpanNames}\n\tWant: ${expectedSpanNames}`
);
const spanSnapshotRun = spans[3];
assert.strictEqual(spanSnapshotRun.name, 'CloudSpanner.Snapshot.run');
const wantSpanErr = '6 ALREADY_EXISTS: ' + messageBadInsertAlreadyExistent;
assert.deepStrictEqual(
spanSnapshotRun.status.code,
SpanStatusCode.ERROR,
'Unexpected status code'
);
assert.deepStrictEqual(
spanSnapshotRun.status.message,
wantSpanErr,
'Unexpexcted error message'
);

const databaseBatchCreateSessionsSpan = spans[0];
assert.strictEqual(
Expand Down Expand Up @@ -1300,8 +1367,7 @@ SELECT 1p

// We need to ensure a strict relationship between the spans.
// |-Database.runTransactionAsync |-------------------------------------|
// |-Snapshot.run |------------------------|
// |-Snapshot.runStream |---------------------|
// |-Snapshot.runStream |---------------------|
// |-Transaction.commit |--------|
// |-Snapshot.begin |------|
// |-Snapshot.commit |-----|
Expand All @@ -1322,12 +1388,6 @@ SELECT 1p
'Expected that Database.runTransaction is the parent to Transaction.commmit'
);

assert.deepStrictEqual(
spanSnapshotRun.parentSpanId,
spanDatabaseRunTransactionAsync.spanContext().spanId,
'Expected that Database.runTransaction is the parent to Snapshot.run'
);

// Assert that despite all being exported, SessionPool.createSessions
// is not in the same trace as runStream, createSessions is invoked at
// Spanner Client instantiation, thus before database.run is invoked.
Expand Down Expand Up @@ -1848,7 +1908,6 @@ describe('Traces for ExecuteStream broken stream retries', () => {
'CloudSpanner.Database.batchCreateSessions',
'CloudSpanner.SessionPool.createSessions',
'CloudSpanner.Snapshot.runStream',
'CloudSpanner.Snapshot.run',
'CloudSpanner.Dml.runUpdate',
'CloudSpanner.Snapshot.begin',
'CloudSpanner.Transaction.commit',
Expand Down
Loading
Loading