From 40640b82e98864c1533f269426a2e8f6d8100ce3 Mon Sep 17 00:00:00 2001 From: Nicholas Hulston Date: Mon, 11 Nov 2024 13:21:54 -0500 Subject: [PATCH] Unit tests --- .../datadog-plugin-aws-sdk/test/s3.spec.js | 73 +++++++++++++++++++ packages/dd-trace/test/span_pointers.spec.js | 62 ++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 packages/dd-trace/test/span_pointers.spec.js diff --git a/packages/datadog-plugin-aws-sdk/test/s3.spec.js b/packages/datadog-plugin-aws-sdk/test/s3.spec.js index 9ffb9a67215..c1b6bb626bd 100644 --- a/packages/datadog-plugin-aws-sdk/test/s3.spec.js +++ b/packages/datadog-plugin-aws-sdk/test/s3.spec.js @@ -4,6 +4,7 @@ const agent = require('../../dd-trace/test/plugins/agent') const { setup } = require('./spec_helpers') const axios = require('axios') const { rawExpectedSchema } = require('./s3-naming') +const { SPAN_LINK_KIND, S3_PTR_KIND, SPAN_POINTER_DIRECTION } = require('../../dd-trace/src/span_pointers') const bucketName = 's3-bucket-name-test' @@ -74,6 +75,78 @@ describe('Plugin', () => { rawExpectedSchema.outbound ) + describe('span pointers', () => { + it('should add span pointer for putObject operation', (done) => { + agent.use(traces => { + const span = traces[0][0] + const links = span.links || [] + + expect(links).to.have.lengthOf(1) + expect(links[0].attributes).to.include({ + 'ptr.kind': S3_PTR_KIND, + 'ptr.dir': SPAN_POINTER_DIRECTION.DOWNSTREAM, + 'link.kind': SPAN_LINK_KIND, + 'ptr.hash': 'abcdefg' + }) + }) + + s3.putObject({ + Bucket: bucketName, + Key: 'test-key', + Body: 'test body' + }, done) + }) + + it('should add span pointer for copyObject operation', (done) => { + agent.use(traces => { + const span = traces[0][0] + const links = span.links || [] + + expect(links).to.have.lengthOf(1) + expect(links[0].attributes).to.include({ + 'ptr.kind': S3_PTR_KIND, + 'ptr.dir': SPAN_POINTER_DIRECTION.DOWNSTREAM, + 'link.kind': SPAN_LINK_KIND, + 'ptr.hash': 'abcdefg' + }) + }) + + s3.copyObject({ + Bucket: bucketName, + Key: 'copy-key', + CopySource: `${bucketName}/test-key` + }, done) + }) + + it('should not add span pointer for getObject operation', (done) => { + agent.use(traces => { + const span = traces[0][0] + const links = span.links || [] + expect(links).to.have.lengthOf(0) + }) + + s3.getObject({ + Bucket: bucketName, + Key: 'test-key' + }, done) + }) + + it('should handle missing parameters gracefully', (done) => { + agent.use(traces => { + const span = traces[0][0] + const links = span.links || [] + expect(links).to.have.lengthOf(0) + }) + + // Force a failure to get ETag + s3.putObject({ + Bucket: 'non-existent-bucket', + Key: 'test-key', + Body: 'test body' + }, () => done()) + }) + }) + it('should allow disabling a specific span kind of a service', (done) => { let total = 0 diff --git a/packages/dd-trace/test/span_pointers.spec.js b/packages/dd-trace/test/span_pointers.spec.js new file mode 100644 index 00000000000..c3c227bf9c6 --- /dev/null +++ b/packages/dd-trace/test/span_pointers.spec.js @@ -0,0 +1,62 @@ +'use strict' + +require('./setup/tap') + +const { + ZERO_CONTEXT, + SPAN_LINK_KIND, + S3_PTR_KIND, + SPAN_POINTER_DIRECTION, + generateS3PointerHash +} = require('../../dd-trace/src/span_pointers') + +describe('span_pointers', () => { + describe('ZERO_CONTEXT', () => { + it('should have trace and span IDs of 0', () => { + expect(ZERO_CONTEXT.toTraceId()).to.equal('0') + expect(ZERO_CONTEXT.toSpanId()).to.equal('0') + }) + }) + + // datadog-lambda-js imports these and will error if they are not found (moved or renamed) + describe('constants', () => { + it('should export the correct constant values', () => { + expect(SPAN_LINK_KIND).to.equal('span-pointer') + expect(S3_PTR_KIND).to.equal('aws.s3.object') + expect(SPAN_POINTER_DIRECTION.UPSTREAM).to.equal('u') + expect(SPAN_POINTER_DIRECTION.DOWNSTREAM).to.equal('d') + }) + }) + + describe('generateS3PointerHash', () => { + it('should generate a valid hash for a basic S3 object', () => { + const hash = generateS3PointerHash('some-bucket', 'some-key.data', 'ab12ef34') + expect(hash).to.equal('e721375466d4116ab551213fdea08413') + }) + + it('should generate a valid hash for an S3 object with a non-ascii key', () => { + const hash1 = generateS3PointerHash('some-bucket', 'some-key.你好', 'ab12ef34') + expect(hash1).to.equal('d1333a04b9928ab462b5c6cadfa401f4') + }) + + it('should generate a valid hash for multipart-uploaded S3 object', () => { + const hash1 = generateS3PointerHash('some-bucket', 'some-key.data', 'ab12ef34-5') + expect(hash1).to.equal('2b90dffc37ebc7bc610152c3dc72af9f') + }) + + it('should handle quoted ETags', () => { + const hash1 = generateS3PointerHash('bucket', 'key', 'etag') + const hash2 = generateS3PointerHash('bucket', 'key', '"etag"') + expect(hash1).to.equal(hash2) + }) + + it('should return null if any required parameter is missing', () => { + expect(generateS3PointerHash(null, 'key', 'etag')).to.be.null + expect(generateS3PointerHash('bucket', null, 'etag')).to.be.null + expect(generateS3PointerHash('bucket', 'key', null)).to.be.null + expect(generateS3PointerHash('', 'key', 'etag')).to.be.null + expect(generateS3PointerHash('bucket', '', 'etag')).to.be.null + expect(generateS3PointerHash('bucket', 'key', '')).to.be.null + }) + }) +})