Skip to content

Commit

Permalink
[#243] Support Send Messages by local gRPC Fixtures a Server
Browse files Browse the repository at this point in the history
  • Loading branch information
feelform committed Dec 12, 2024
1 parent 820450e commit a32c58a
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 141 deletions.
299 changes: 158 additions & 141 deletions test/instrumentation/context/nested-async-trace.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,155 +249,172 @@ test(`nested mysql async query with express`, async (t) => {
})
})

test.skip(`nested mysql2 async query with express`, async (t) => {
agent.bindHttpWithCallSite()
const source = path.resolve(fixtures, 'mysql.sql')
const container = await new MySqlContainer()
.withCommand(['--default-authentication-plugin=mysql_native_password'])
.withEnvironment({
'MYSQL_DATABASE': 'test',
'TZ': 'Asia/Seoul',
})
.withCopyFilesToContainer([{
source: source,
target: '/docker-entrypoint-initdb.d/mysql.sql'
}])
.start()

const app = new express()
app.get('/test1', async (req, res) => {
const connection = mysql2.createConnection({
host: container.getHost(),
port: container.getPort(),
database: 'test',
user: container.getUsername(),
password: container.getUserPassword(),
timezone: '+09:00'
})
test(`nested mysql2 async query with express`, async (t) => {
const collectorServer = new grpc.Server()
collectorServer.addService(services.AgentService, {
pingSession: unaryService
})
collectorServer.addService(services.StatService, {
sendAgentStat: unaryService
})
collectorServer.addService(services.SpanService, {
sendSpan: spanMessageStreamService
})

collectorServer.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), async (err, port) => {
agent.bindHttpWithCallSite()
const source = path.resolve(fixtures, 'mysql.sql')
const container = await new MySqlContainer()
.withCommand(['--default-authentication-plugin=mysql_native_password'])
.withEnvironment({
'MYSQL_DATABASE': 'test',
'TZ': 'Asia/Seoul',
})
.withCopyFilesToContainer([{
source: source,
target: '/docker-entrypoint-initdb.d/mysql.sql'
}])
.start()

const app = new express()
app.get('/test1', async (req, res) => {
const connection = mysql2.createConnection({
host: container.getHost(),
port: container.getPort(),
database: 'test',
user: container.getUsername(),
password: container.getUserPassword(),
timezone: '+09:00'
})

connection.query(`SELECT * FROM member`, async function (error, results) {
if (error) throw error
t.equal(results[0].id, 'a', 'SELECT member id')
t.equal(results[0].name, 'name1', 'SELECT member name')
t.equal(results[0].joined.getDate(), new Date('2023-01-18T00:00:00+09:00').getDate(), 'SELECT member joined')

connection.query(`SELECT * FROM member WHERE id = ?`, results[0].id, async function (error, results) {

})
})

const [rows] = await connection.promise().query(`SELECT * FROM member WHERE id = ?`, 'a')
t.equal(rows[0].id, 'a', 'id in SELECT query hooking')
t.equal(rows[0].name, 'name1', 'name in SELECT query hooking')
t.equal(rows[0].joined.toISOString().slice(0, 10), '2023-01-17', 'joined in SELECT query hooking')

setTimeout(() => {
res.send('ok get')
}, 1000)

agent.callbackTraceClose(async (trace) => {
let actualBuilder = new MethodDescriptorBuilder(expected('get', 'app.get'))
.setClassName(expected('app', 'Function'))
.setLineNumber(280)
.setFileName('nested-async-trace.test.js')
let actualMethodDescriptor = apiMetaService.cacheApiWithBuilder(actualBuilder)
let actualSpanEvent = trace.spanBuilder.spanEventList.find(spanEvent => spanEvent.sequence === 0)
t.equal(actualMethodDescriptor.apiId, actualSpanEvent.apiId, 'apiId is equal')
t.equal(actualMethodDescriptor.apiDescriptor, expected('app.get', 'Function.app.get'), 'apiDescriptor is equal')
t.equal(actualMethodDescriptor.className, expected('app', 'Function'), 'className is equal')
t.equal(actualMethodDescriptor.methodName, 'get', 'methodName is equal')
t.equal(actualSpanEvent.sequence, 0, 'sequence is 0')
t.equal(actualSpanEvent.depth, 1, 'depth is 0')
t.equal(actualSpanEvent.serviceType, expressServiceType.getCode(), 'serviceType is express')

actualBuilder = new MethodDescriptorBuilder('createConnection')
.setLineNumber(281)
.setFileName('nested-async-trace.test.js')
actualMethodDescriptor = apiMetaService.cacheApiWithBuilder(actualBuilder)
actualSpanEvent = trace.spanBuilder.spanEventList.find(spanEvent => spanEvent.sequence === 1)
t.equal(actualMethodDescriptor.apiId, actualSpanEvent.apiId, 'apiId is equal')
t.equal(actualSpanEvent.endPoint, 'localhost', 'endPoint is equal')
t.equal(actualSpanEvent.destinationId, 'test', 'destinationId is equal')
t.equal(actualSpanEvent.sequence, 1, 'sequence is 1')
t.equal(actualSpanEvent.depth, 2, 'depth is 2')
t.equal(actualSpanEvent.serviceType, mysqlServiceType.getCode(), 'serviceType is mysql')

connection.query(`SELECT * FROM member`, async function (error, results) {
if (error) throw error
t.equal(results[0].id, 'a', 'SELECT member id')
t.equal(results[0].name, 'name1', 'SELECT member name')
t.equal(results[0].joined.getDate(), new Date('2023-01-18T00:00:00+09:00').getDate(), 'SELECT member joined')
actualBuilder = new MethodDescriptorBuilder('query')
.setClassName('Connection')
.setLineNumber(290)
.setFileName('nested-async-trace.test.js')
actualMethodDescriptor = apiMetaService.cacheApiWithBuilder(actualBuilder)
actualSpanEvent = trace.spanBuilder.spanEventList.find(spanEvent => spanEvent.sequence === 2)
t.equal(actualMethodDescriptor.apiId, actualSpanEvent.apiId, 'apiId is equal')
t.equal(actualSpanEvent.sequence, 2, 'sequence is 2')
t.equal(actualSpanEvent.depth, 2, 'depth is 2')
t.equal(actualSpanEvent.serviceType, mysqlExecuteQueryServiceType.getCode(), 'serviceType is mysql')
let actualNextAsyncId = actualSpanEvent.asyncId

let actualSpanChunk = trace.repository.dataSender.findSpanChunk(actualNextAsyncId)
t.equal(actualSpanChunk.spanId, actualSpanEvent.spanId, 'spanId is equal')
t.equal(actualSpanChunk.getTraceRoot().getTransactionId(), trace.spanBuilder.getTraceRoot().getTransactionId(), 'transactionIdObject is equal')
t.equal(actualSpanChunk.localAsyncId.asyncId, actualSpanEvent.asyncId.asyncId, 'localAsyncId is equal')
t.equal(actualSpanChunk.localAsyncId.sequence, 1, 'localAsyncId.sequence is equal')
t.equal(actualSpanChunk.spanEventList[0].apiId, defaultPredefinedMethodDescriptorRegistry.asyncInvocationDescriptor.apiId, 'apiId is equal')
t.equal(actualSpanChunk.spanEventList[0].depth, 1, 'depth is equal')
t.equal(actualSpanChunk.spanEventList[0].sequence, 0, 'sequence is equal')
t.equal(actualSpanChunk.spanEventList[0].serviceType, ServiceType.async.getCode(), 'serviceType is mysql')

connection.query(`SELECT * FROM member WHERE id = ?`, results[0].id, async function (error, results) {
actualBuilder = new MethodDescriptorBuilder('query')
.setClassName('Connection')
.setLineNumber(296)
.setFileName('nested-async-trace.test.js')
actualMethodDescriptor = apiMetaService.cacheApiWithBuilder(actualBuilder)
actualSpanEvent = actualSpanChunk.spanEventList[1]
t.equal(actualMethodDescriptor.apiId, actualSpanEvent.apiId, 'apiId is equal')
t.equal(actualSpanEvent.depth, 2, 'depth is 3')
t.equal(actualSpanEvent.sequence, 1, 'sequence is 2')
t.equal(actualSpanEvent.serviceType, mysqlExecuteQueryServiceType.getCode(), 'serviceType is mysql')
actualNextAsyncId = actualSpanEvent.asyncId

actualSpanChunk = trace.repository.dataSender.findSpanChunk(actualNextAsyncId)
t.equal(actualSpanChunk.spanId, actualSpanEvent.spanId, 'spanId is equal')
t.equal(actualSpanChunk.getTraceRoot().getTransactionId(), trace.spanBuilder.getTraceRoot().getTransactionId(), 'transactionIdObject is equal')
t.equal(actualSpanChunk.localAsyncId.asyncId, actualNextAsyncId.asyncId, 'localAsyncId is equal')
t.equal(actualSpanChunk.localAsyncId.sequence, 1, 'localAsyncId.sequence is equal')
t.equal(actualSpanChunk.spanEventList[0].apiId, defaultPredefinedMethodDescriptorRegistry.asyncInvocationDescriptor.apiId, 'apiId is equal')
t.equal(actualSpanChunk.spanEventList[0].depth, 1, 'depth is equal')
t.equal(actualSpanChunk.spanEventList[0].sequence, 0, 'sequence is equal')
t.equal(actualSpanChunk.spanEventList[0].serviceType, ServiceType.async.getCode(), 'serviceType is mysql')

actualBuilder = new MethodDescriptorBuilder('query')
.setClassName('Connection')
.setLineNumber(103)
.setFileName('promise.js')
actualMethodDescriptor = apiMetaService.cacheApiWithBuilder(actualBuilder)
actualSpanEvent = trace.spanBuilder.spanEventList.find(spanEvent => spanEvent.sequence === 3)
t.equal(actualMethodDescriptor.apiId, actualSpanEvent.apiId, 'apiId is equal')
t.equal(actualSpanEvent.sequence, 3, 'sequence is 3')
t.equal(actualSpanEvent.depth, 2, 'depth is 2')
t.equal(actualSpanEvent.serviceType, mysqlExecuteQueryServiceType.getCode(), 'serviceType is mysql')
actualNextAsyncId = actualSpanEvent.asyncId

actualSpanChunk = trace.repository.dataSender.findSpanChunk(actualNextAsyncId)
t.equal(actualSpanChunk.spanId, actualSpanEvent.spanId, 'spanId is equal')
t.equal(actualSpanChunk.getTraceRoot().getTransactionId(), trace.spanBuilder.getTraceRoot().getTransactionId(), 'transactionIdObject is equal')
t.equal(actualSpanChunk.localAsyncId.asyncId, actualNextAsyncId.asyncId, 'localAsyncId is equal')
t.equal(actualSpanChunk.localAsyncId.sequence, 1, 'localAsyncId.sequence is equal')
t.equal(actualSpanChunk.spanEventList[0].apiId, defaultPredefinedMethodDescriptorRegistry.asyncInvocationDescriptor.apiId, 'apiId is equal')
t.equal(actualSpanChunk.spanEventList[0].depth, 1, 'depth is equal')
t.equal(actualSpanChunk.spanEventList[0].sequence, 0, 'sequence is equal')
t.equal(actualSpanChunk.spanEventList[0].serviceType, ServiceType.async.getCode(), 'serviceType is mysql')

connection.end()
await container.stop()
})
})

const [rows] = await connection.promise().query(`SELECT * FROM member WHERE id = ?`, 'a')
t.equal(rows[0].id, 'a', 'id in SELECT query hooking')
t.equal(rows[0].name, 'name1', 'name in SELECT query hooking')
t.equal(rows[0].joined.toISOString().slice(0, 10), '2023-01-17', 'joined in SELECT query hooking')

setTimeout(() => {
res.send('ok get')
}, 1000)

agent.callbackTraceClose(async (trace) => {
let actualBuilder = new MethodDescriptorBuilder(expected('get', 'app.get'))
.setClassName(expected('app', 'Function'))
.setLineNumber(218)
.setFileName('nested-async-trace.test.js')
let actualMethodDescriptor = apiMetaService.cacheApiWithBuilder(actualBuilder)
let actualSpanEvent = trace.spanBuilder.spanEventList.find(spanEvent => spanEvent.sequence === 0)
t.equal(actualMethodDescriptor.apiId, actualSpanEvent.apiId, 'apiId is equal')
t.equal(actualMethodDescriptor.apiDescriptor, expected('app.get', 'Function.app.get'), 'apiDescriptor is equal')
t.equal(actualMethodDescriptor.className, expected('app', 'Function'), 'className is equal')
t.equal(actualMethodDescriptor.methodName, 'get', 'methodName is equal')
t.equal(actualSpanEvent.sequence, 0, 'sequence is 0')
t.equal(actualSpanEvent.depth, 1, 'depth is 0')
t.equal(actualSpanEvent.serviceType, expressServiceType.getCode(), 'serviceType is express')

actualBuilder = new MethodDescriptorBuilder('createConnection')
.setLineNumber(219)
.setFileName('nested-async-trace.test.js')
actualMethodDescriptor = apiMetaService.cacheApiWithBuilder(actualBuilder)
actualSpanEvent = trace.spanBuilder.spanEventList.find(spanEvent => spanEvent.sequence === 1)
t.equal(actualMethodDescriptor.apiId, actualSpanEvent.apiId, 'apiId is equal')
t.equal(actualSpanEvent.endPoint, 'localhost', 'endPoint is equal')
t.equal(actualSpanEvent.destinationId, 'test', 'destinationId is equal')
t.equal(actualSpanEvent.sequence, 1, 'sequence is 1')
t.equal(actualSpanEvent.depth, 2, 'depth is 2')
t.equal(actualSpanEvent.serviceType, mysqlServiceType.getCode(), 'serviceType is mysql')

actualBuilder = new MethodDescriptorBuilder('query')
.setClassName('Connection')
.setLineNumber(228)
.setFileName('nested-async-trace.test.js')
actualMethodDescriptor = apiMetaService.cacheApiWithBuilder(actualBuilder)
actualSpanEvent = trace.spanBuilder.spanEventList.find(spanEvent => spanEvent.sequence === 2)
t.equal(actualMethodDescriptor.apiId, actualSpanEvent.apiId, 'apiId is equal')
t.equal(actualSpanEvent.sequence, 2, 'sequence is 2')
t.equal(actualSpanEvent.depth, 2, 'depth is 2')
t.equal(actualSpanEvent.serviceType, mysqlExecuteQueryServiceType.getCode(), 'serviceType is mysql')
let actualNextAsyncId = actualSpanEvent.asyncId

let actualSpanChunk = trace.repository.dataSender.findSpanChunk(actualNextAsyncId)
t.equal(actualSpanChunk.spanId, actualSpanEvent.spanId, 'spanId is equal')
t.equal(actualSpanChunk.getTraceRoot().getTransactionId(), trace.spanBuilder.getTraceRoot().getTransactionId(), 'transactionIdObject is equal')
t.equal(actualSpanChunk.localAsyncId.asyncId, actualSpanEvent.asyncId.asyncId, 'localAsyncId is equal')
t.equal(actualSpanChunk.localAsyncId.sequence, 1, 'localAsyncId.sequence is equal')
t.equal(actualSpanChunk.spanEventList[0].apiId, defaultPredefinedMethodDescriptorRegistry.asyncInvocationDescriptor.apiId, 'apiId is equal')
t.equal(actualSpanChunk.spanEventList[0].depth, 1, 'depth is equal')
t.equal(actualSpanChunk.spanEventList[0].sequence, 0, 'sequence is equal')
t.equal(actualSpanChunk.spanEventList[0].serviceType, ServiceType.async.getCode(), 'serviceType is mysql')

actualBuilder = new MethodDescriptorBuilder('query')
.setClassName('Connection')
.setLineNumber(234)
.setFileName('nested-async-trace.test.js')
actualMethodDescriptor = apiMetaService.cacheApiWithBuilder(actualBuilder)
actualSpanEvent = actualSpanChunk.spanEventList[1]
t.equal(actualMethodDescriptor.apiId, actualSpanEvent.apiId, 'apiId is equal')
t.equal(actualSpanEvent.depth, 2, 'depth is 3')
t.equal(actualSpanEvent.sequence, 1, 'sequence is 2')
t.equal(actualSpanEvent.serviceType, mysqlExecuteQueryServiceType.getCode(), 'serviceType is mysql')
actualNextAsyncId = actualSpanEvent.asyncId

actualSpanChunk = trace.repository.dataSender.findSpanChunk(actualNextAsyncId)
t.equal(actualSpanChunk.spanId, actualSpanEvent.spanId, 'spanId is equal')
t.equal(actualSpanChunk.getTraceRoot().getTransactionId(), trace.spanBuilder.getTraceRoot().getTransactionId(), 'transactionIdObject is equal')
t.equal(actualSpanChunk.localAsyncId.asyncId, actualNextAsyncId.asyncId, 'localAsyncId is equal')
t.equal(actualSpanChunk.localAsyncId.sequence, 1, 'localAsyncId.sequence is equal')
t.equal(actualSpanChunk.spanEventList[0].apiId, defaultPredefinedMethodDescriptorRegistry.asyncInvocationDescriptor.apiId, 'apiId is equal')
t.equal(actualSpanChunk.spanEventList[0].depth, 1, 'depth is equal')
t.equal(actualSpanChunk.spanEventList[0].sequence, 0, 'sequence is equal')
t.equal(actualSpanChunk.spanEventList[0].serviceType, ServiceType.async.getCode(), 'serviceType is mysql')

actualBuilder = new MethodDescriptorBuilder('query')
.setClassName('Connection')
.setLineNumber(103)
.setFileName('promise.js')
actualMethodDescriptor = apiMetaService.cacheApiWithBuilder(actualBuilder)
actualSpanEvent = trace.spanBuilder.spanEventList.find(spanEvent => spanEvent.sequence === 3)
t.equal(actualMethodDescriptor.apiId, actualSpanEvent.apiId, 'apiId is equal')
t.equal(actualSpanEvent.sequence, 3, 'sequence is 3')
t.equal(actualSpanEvent.depth, 2, 'depth is 2')
t.equal(actualSpanEvent.serviceType, mysqlExecuteQueryServiceType.getCode(), 'serviceType is mysql')
actualNextAsyncId = actualSpanEvent.asyncId

actualSpanChunk = trace.repository.dataSender.findSpanChunk(actualNextAsyncId)
t.equal(actualSpanChunk.spanId, actualSpanEvent.spanId, 'spanId is equal')
t.equal(actualSpanChunk.getTraceRoot().getTransactionId(), trace.spanBuilder.getTraceRoot().getTransactionId(), 'transactionIdObject is equal')
t.equal(actualSpanChunk.localAsyncId.asyncId, actualNextAsyncId.asyncId, 'localAsyncId is equal')
t.equal(actualSpanChunk.localAsyncId.sequence, 1, 'localAsyncId.sequence is equal')
t.equal(actualSpanChunk.spanEventList[0].apiId, defaultPredefinedMethodDescriptorRegistry.asyncInvocationDescriptor.apiId, 'apiId is equal')
t.equal(actualSpanChunk.spanEventList[0].depth, 1, 'depth is equal')
t.equal(actualSpanChunk.spanEventList[0].sequence, 0, 'sequence is equal')
t.equal(actualSpanChunk.spanEventList[0].serviceType, ServiceType.async.getCode(), 'serviceType is mysql')

connection.end()
await container.stop()
const server = app.listen(5006, async () => {
const result = await axios.get('http://localhost:5006/test1')
t.equal(result.status, 200, 'status is 200')

t.end()
server.close()
})
})

const server = app.listen(5006, async () => {
const result = await axios.get('http://localhost:5006/test1')
t.equal(result.status, 200, 'status is 200')

t.end()
server.close()
t.teardown(() => {
collectorServer.forceShutdown()
})
})
Loading

0 comments on commit a32c58a

Please sign in to comment.