github.com/mier85/go-sensor@v1.30.1-0.20220920111756-9bf41b3bc7e0/instrumentation_sql_go1.10_test.go (about) 1 // (c) Copyright IBM Corp. 2021 2 // (c) Copyright Instana Inc. 2020 3 4 //go:build go1.10 5 // +build go1.10 6 7 package instana_test 8 9 import ( 10 "context" 11 "database/sql" 12 "database/sql/driver" 13 "errors" 14 "testing" 15 16 "github.com/instana/testify/assert" 17 "github.com/instana/testify/require" 18 instana "github.com/mier85/go-sensor" 19 ot "github.com/opentracing/opentracing-go" 20 "github.com/opentracing/opentracing-go/ext" 21 ) 22 23 func TestWrapSQLConnector_Exec(t *testing.T) { 24 recorder := instana.NewTestRecorder() 25 s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{ 26 Service: "go-sensor-test", 27 }, recorder)) 28 29 db := sql.OpenDB(instana.WrapSQLConnector(s, "connection string", sqlConnector{})) 30 31 res, err := db.Exec("TEST QUERY") 32 require.NoError(t, err) 33 34 lastID, err := res.LastInsertId() 35 require.NoError(t, err) 36 assert.Equal(t, int64(42), lastID) 37 38 spans := recorder.GetQueuedSpans() 39 require.Len(t, spans, 1) 40 41 span := spans[0] 42 assert.Equal(t, 0, span.Ec) 43 assert.EqualValues(t, instana.ExitSpanKind, span.Kind) 44 45 require.IsType(t, instana.SDKSpanData{}, span.Data) 46 data := span.Data.(instana.SDKSpanData) 47 48 assert.Equal(t, instana.SDKSpanTags{ 49 Name: "sdk.database", 50 Type: "exit", 51 Custom: map[string]interface{}{ 52 "tags": ot.Tags{ 53 "span.kind": ext.SpanKindRPCClientEnum, 54 "db.instance": "connection string", 55 "db.statement": "TEST QUERY", 56 "db.type": "sql", 57 "peer.address": "connection string", 58 }, 59 }, 60 }, data.Tags) 61 } 62 63 func TestWrapSQLConnector_Exec_Error(t *testing.T) { 64 recorder := instana.NewTestRecorder() 65 s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{ 66 Service: "go-sensor-test", 67 }, recorder)) 68 69 db := sql.OpenDB(instana.WrapSQLConnector(s, "connection string", sqlConnector{ 70 Error: errors.New("something went wrong"), 71 })) 72 73 _, err := db.Exec("TEST QUERY") 74 assert.Error(t, err) 75 76 spans := recorder.GetQueuedSpans() 77 require.Len(t, spans, 2) 78 79 span, logSpan := spans[0], spans[1] 80 assert.Equal(t, 1, span.Ec) 81 assert.EqualValues(t, instana.ExitSpanKind, span.Kind) 82 83 require.IsType(t, instana.SDKSpanData{}, span.Data) 84 85 assert.Equal(t, span.TraceID, logSpan.TraceID) 86 assert.Equal(t, span.SpanID, logSpan.ParentID) 87 assert.Equal(t, "log.go", logSpan.Name) 88 89 // assert that log message has been recorded within the span interval 90 assert.GreaterOrEqual(t, logSpan.Timestamp, span.Timestamp) 91 assert.LessOrEqual(t, logSpan.Duration, span.Duration) 92 93 require.IsType(t, instana.LogSpanData{}, logSpan.Data) 94 logData := logSpan.Data.(instana.LogSpanData) 95 96 assert.Equal(t, instana.LogSpanTags{ 97 Level: "ERROR", 98 Message: `error: "something went wrong"`, 99 }, logData.Tags) 100 } 101 102 func TestWrapSQLConnector_Query(t *testing.T) { 103 recorder := instana.NewTestRecorder() 104 s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{ 105 Service: "go-sensor-test", 106 }, recorder)) 107 108 db := sql.OpenDB(instana.WrapSQLConnector(s, "connection string", sqlConnector{})) 109 110 res, err := db.Query("TEST QUERY") 111 require.NoError(t, err) 112 113 cols, err := res.Columns() 114 require.NoError(t, err) 115 assert.Equal(t, []string{"col1", "col2"}, cols) 116 117 spans := recorder.GetQueuedSpans() 118 require.Len(t, spans, 1) 119 120 span := spans[0] 121 assert.Equal(t, 0, span.Ec) 122 assert.EqualValues(t, instana.ExitSpanKind, span.Kind) 123 124 require.IsType(t, instana.SDKSpanData{}, span.Data) 125 data := span.Data.(instana.SDKSpanData) 126 127 assert.Equal(t, instana.SDKSpanTags{ 128 Name: "sdk.database", 129 Type: "exit", 130 Custom: map[string]interface{}{ 131 "tags": ot.Tags{ 132 "span.kind": ext.SpanKindRPCClientEnum, 133 "db.instance": "connection string", 134 "db.statement": "TEST QUERY", 135 "db.type": "sql", 136 "peer.address": "connection string", 137 }, 138 }, 139 }, data.Tags) 140 } 141 142 func TestWrapSQLConnector_Query_Error(t *testing.T) { 143 recorder := instana.NewTestRecorder() 144 s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{ 145 Service: "go-sensor-test", 146 }, recorder)) 147 148 dbErr := errors.New("something went wrong") 149 db := sql.OpenDB(instana.WrapSQLConnector(s, "connection string", sqlConnector{ 150 Error: dbErr, 151 })) 152 153 _, err := db.Query("TEST QUERY") 154 assert.Error(t, err) 155 156 spans := recorder.GetQueuedSpans() 157 require.Len(t, spans, 2) 158 159 span, logSpan := spans[0], spans[1] 160 assert.Equal(t, 1, span.Ec) 161 assert.EqualValues(t, instana.ExitSpanKind, span.Kind) 162 163 require.IsType(t, instana.SDKSpanData{}, span.Data) 164 165 assert.Equal(t, span.TraceID, logSpan.TraceID) 166 assert.Equal(t, span.SpanID, logSpan.ParentID) 167 assert.Equal(t, "log.go", logSpan.Name) 168 169 // assert that log message has been recorded within the span interval 170 assert.GreaterOrEqual(t, logSpan.Timestamp, span.Timestamp) 171 assert.LessOrEqual(t, logSpan.Duration, span.Duration) 172 173 require.IsType(t, instana.LogSpanData{}, logSpan.Data) 174 logData := logSpan.Data.(instana.LogSpanData) 175 176 assert.Equal(t, instana.LogSpanTags{ 177 Level: "ERROR", 178 Message: `error: "something went wrong"`, 179 }, logData.Tags) 180 } 181 182 type sqlConnector struct{ Error error } 183 184 func (c sqlConnector) Connect(context.Context) (driver.Conn, error) { return sqlConn{c.Error}, nil } //nolint:gosimple 185 func (sqlConnector) Driver() driver.Driver { return sqlDriver{} }