Skip to content

Commit 990d72b

Browse files
authored
Adding more SQL test coverage (#488)
* adding more SQL test coverage * ignoring eum.js and sql generator
1 parent 8411d90 commit 990d72b

5 files changed

+252
-11
lines changed

instrumentation_sql_go1.10_test.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -186,5 +186,7 @@ func TestWrapSQLConnector_Query_Error(t *testing.T) {
186186

187187
type sqlConnector struct{ Error error }
188188

189-
func (c sqlConnector) Connect(context.Context) (driver.Conn, error) { return sqlConn{c.Error}, nil } //nolint:gosimple
190-
func (sqlConnector) Driver() driver.Driver { return sqlDriver{} }
189+
func (c sqlConnector) Connect(context.Context) (driver.Conn, error) {
190+
return sqlConn{Error: c.Error}, nil
191+
} //nolint:gosimple
192+
func (sqlConnector) Driver() driver.Driver { return sqlDriver{} }

instrumentation_sql_test.go

+243-8
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,206 @@ func TestOpenSQLDB_RedisConnString(t *testing.T) {
350350
}, data.Tags)
351351
}
352352

353+
func TestConnPrepareContext(t *testing.T) {
354+
recorder := instana.NewTestRecorder()
355+
s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{
356+
Service: "go-sensor-test",
357+
AgentClient: alwaysReadyClient{},
358+
}, recorder))
359+
defer instana.ShutdownSensor()
360+
361+
instana.InstrumentSQLDriver(s, "fake_pc", sqlDriver{})
362+
require.Contains(t, sql.Drivers(), "fake_pc_with_instana")
363+
364+
db, err := instana.SQLOpen("fake_pc", "conn string")
365+
require.NoError(t, err)
366+
367+
ctx := context.Background()
368+
369+
stmt, err := db.PrepareContext(ctx, "select 1 from table")
370+
require.NoError(t, err)
371+
372+
_, err = stmt.QueryContext(ctx)
373+
require.NoError(t, err)
374+
375+
spans := recorder.GetQueuedSpans()
376+
377+
require.Len(t, spans, 1)
378+
379+
require.IsType(t, instana.SDKSpanData{}, spans[0].Data)
380+
data := spans[0].Data.(instana.SDKSpanData)
381+
382+
assert.Equal(t, instana.SDKSpanTags{
383+
Name: "sdk.database",
384+
Type: "exit",
385+
Custom: map[string]interface{}{
386+
"tags": ot.Tags{
387+
"span.kind": ext.SpanKindRPCClientEnum,
388+
"db.instance": "conn string",
389+
"db.statement": "select 1 from table",
390+
"db.type": "sql",
391+
"peer.address": "conn string",
392+
},
393+
},
394+
}, data.Tags)
395+
}
396+
397+
func TestConnPrepareContextWithError(t *testing.T) {
398+
recorder := instana.NewTestRecorder()
399+
s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{
400+
Service: "go-sensor-test",
401+
AgentClient: alwaysReadyClient{},
402+
}, recorder))
403+
defer instana.ShutdownSensor()
404+
405+
instana.InstrumentSQLDriver(s, "fake_conn_pc_error", sqlDriver{Error: errors.New("some error")})
406+
require.Contains(t, sql.Drivers(), "fake_conn_pc_error_with_instana")
407+
408+
db, err := instana.SQLOpen("fake_conn_pc_error", "conn string")
409+
require.NoError(t, err)
410+
411+
ctx := context.Background()
412+
413+
stmt, err := db.PrepareContext(ctx, "select 1 from table")
414+
require.NoError(t, err)
415+
416+
_, err = stmt.QueryContext(ctx)
417+
require.Error(t, err)
418+
419+
spans := recorder.GetQueuedSpans()
420+
421+
require.Len(t, spans, 2)
422+
423+
assert.Equal(t, spans[0].Ec, 1)
424+
425+
require.IsType(t, instana.SDKSpanData{}, spans[0].Data)
426+
data := spans[0].Data.(instana.SDKSpanData)
427+
428+
assert.Equal(t, instana.SDKSpanTags{
429+
Name: "sdk.database",
430+
Type: "exit",
431+
Custom: map[string]interface{}{
432+
"tags": ot.Tags{
433+
"span.kind": ext.SpanKindRPCClientEnum,
434+
"db.error": "some error",
435+
"db.instance": "conn string",
436+
"db.statement": "select 1 from table",
437+
"db.type": "sql",
438+
"peer.address": "conn string",
439+
},
440+
},
441+
}, data.Tags)
442+
}
443+
444+
func TestStmtExecContext(t *testing.T) {
445+
recorder := instana.NewTestRecorder()
446+
s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{
447+
Service: "go-sensor-test",
448+
AgentClient: alwaysReadyClient{},
449+
}, recorder))
450+
defer instana.ShutdownSensor()
451+
452+
instana.InstrumentSQLDriver(s, "fake_stmt_ec", sqlDriver{})
453+
require.Contains(t, sql.Drivers(), "fake_stmt_ec_with_instana")
454+
455+
db, err := instana.SQLOpen("fake_stmt_ec", "conn string")
456+
require.NoError(t, err)
457+
458+
ctx := context.Background()
459+
460+
stmt, err := db.PrepareContext(ctx, "select 1 from table")
461+
require.NoError(t, err)
462+
463+
_, err = stmt.ExecContext(ctx)
464+
require.NoError(t, err)
465+
466+
spans := recorder.GetQueuedSpans()
467+
468+
require.Len(t, spans, 1)
469+
470+
require.IsType(t, instana.SDKSpanData{}, spans[0].Data)
471+
data := spans[0].Data.(instana.SDKSpanData)
472+
473+
assert.Equal(t, instana.SDKSpanTags{
474+
Name: "sdk.database",
475+
Type: "exit",
476+
Custom: map[string]interface{}{
477+
"tags": ot.Tags{
478+
"span.kind": ext.SpanKindRPCClientEnum,
479+
"db.instance": "conn string",
480+
"db.statement": "select 1 from table",
481+
"db.type": "sql",
482+
"peer.address": "conn string",
483+
},
484+
},
485+
}, data.Tags)
486+
}
487+
488+
func TestStmtExecContextWithError(t *testing.T) {
489+
recorder := instana.NewTestRecorder()
490+
s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{
491+
Service: "go-sensor-test",
492+
AgentClient: alwaysReadyClient{},
493+
}, recorder))
494+
defer instana.ShutdownSensor()
495+
496+
instana.InstrumentSQLDriver(s, "fake_stmt_ec_with_error", sqlDriver{Error: errors.New("oh no")})
497+
require.Contains(t, sql.Drivers(), "fake_stmt_ec_with_error_with_instana")
498+
499+
db, err := instana.SQLOpen("fake_stmt_ec_with_error", "conn string")
500+
require.NoError(t, err)
501+
502+
ctx := context.Background()
503+
504+
stmt, err := db.PrepareContext(ctx, "select 1 from table")
505+
require.NoError(t, err)
506+
507+
_, err = stmt.ExecContext(ctx)
508+
require.Error(t, err)
509+
510+
spans := recorder.GetQueuedSpans()
511+
512+
require.Len(t, spans, 2)
513+
514+
require.IsType(t, instana.SDKSpanData{}, spans[0].Data)
515+
data := spans[0].Data.(instana.SDKSpanData)
516+
517+
assert.Equal(t, instana.SDKSpanTags{
518+
Name: "sdk.database",
519+
Type: "exit",
520+
Custom: map[string]interface{}{
521+
"tags": ot.Tags{
522+
"span.kind": ext.SpanKindRPCClientEnum,
523+
"db.error": "oh no",
524+
"db.instance": "conn string",
525+
"db.statement": "select 1 from table",
526+
"db.type": "sql",
527+
"peer.address": "conn string",
528+
},
529+
},
530+
}, data.Tags)
531+
}
532+
533+
func TestConnPrepareContextWithErrorOnReturn(t *testing.T) {
534+
recorder := instana.NewTestRecorder()
535+
s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{
536+
Service: "go-sensor-test",
537+
AgentClient: alwaysReadyClient{},
538+
}, recorder))
539+
defer instana.ShutdownSensor()
540+
541+
instana.InstrumentSQLDriver(s, "fake_conn_pc_error_on_ret", sqlDriver{PrepareError: errors.New("oh no")})
542+
require.Contains(t, sql.Drivers(), "fake_conn_pc_error_on_ret_with_instana")
543+
544+
db, err := instana.SQLOpen("fake_conn_pc_error_on_ret", "conn string")
545+
require.NoError(t, err)
546+
547+
ctx := context.Background()
548+
549+
_, err = db.PrepareContext(ctx, "select 1 from table")
550+
require.Error(t, err)
551+
}
552+
353553
func TestOpenSQLDB_RedisConnString_WithError(t *testing.T) {
354554
recorder := instana.NewTestRecorder()
355555
s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{
@@ -358,7 +558,7 @@ func TestOpenSQLDB_RedisConnString_WithError(t *testing.T) {
358558
}, recorder))
359559
defer instana.ShutdownSensor()
360560

361-
instana.InstrumentSQLDriver(s, "fake_redis_driver_with_error", sqlDriver{errors.New("oops")})
561+
instana.InstrumentSQLDriver(s, "fake_redis_driver_with_error", sqlDriver{Error: errors.New("oops")})
362562
require.Contains(t, sql.Drivers(), "fake_redis_driver_with_error_with_instana")
363563

364564
db, err := instana.SQLOpen("fake_redis_driver_with_error", ":[email protected]:6790")
@@ -482,15 +682,41 @@ func TestProcedureWithNoDefaultChecker(t *testing.T) {
482682
assert.NoError(t, err)
483683
}
484684

485-
type sqlDriver struct{ Error error }
685+
type sqlDriver struct {
686+
// Error is a generic error in the SQL execution. It generates spans with errors
687+
Error error
688+
// StmtError will give an error when a method from Stmt returns. It does not generate spans at all
689+
StmtError error
690+
// PrepareError will give an error when a method from Prepare* returns. It does not generate spans at all
691+
PrepareError error
692+
}
486693

487-
func (drv sqlDriver) Open(name string) (driver.Conn, error) { return sqlConn{drv.Error}, nil } //nolint:gosimple
694+
func (drv sqlDriver) Open(name string) (driver.Conn, error) {
695+
return sqlConn{
696+
Error: drv.Error,
697+
StmtError: drv.StmtError,
698+
PrepareError: drv.PrepareError,
699+
}, nil
700+
} //nolint:gosimple
488701

489-
type sqlConn struct{ Error error }
702+
type sqlConn struct {
703+
Error error
704+
StmtError error
705+
PrepareError error
706+
}
490707

491-
func (conn sqlConn) Prepare(query string) (driver.Stmt, error) { return sqlStmt{conn.Error}, nil } //nolint:gosimple
492-
func (s sqlConn) Close() error { return driver.ErrSkip }
493-
func (s sqlConn) Begin() (driver.Tx, error) { return nil, driver.ErrSkip }
708+
var _ driver.Conn = (*sqlConn)(nil)
709+
var _ driver.ConnPrepareContext = (*sqlConn)(nil)
710+
711+
func (conn sqlConn) Prepare(query string) (driver.Stmt, error) {
712+
return sqlStmt{Error: conn.Error}, nil
713+
} //nolint:gosimple
714+
func (conn sqlConn) Close() error { return driver.ErrSkip }
715+
func (conn sqlConn) Begin() (driver.Tx, error) { return nil, driver.ErrSkip }
716+
717+
func (conn sqlConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
718+
return sqlStmt{StmtError: conn.StmtError, Error: conn.Error}, conn.PrepareError //nolint:gosimple
719+
}
494720

495721
func (conn sqlConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
496722
return sqlResult{}, conn.Error
@@ -500,12 +726,21 @@ func (conn sqlConn) QueryContext(ctx context.Context, query string, args []drive
500726
return sqlRows{}, conn.Error
501727
}
502728

503-
type sqlStmt struct{ Error error }
729+
type sqlStmt struct {
730+
Error error
731+
StmtError error
732+
}
504733

505734
func (sqlStmt) Close() error { return nil }
506735
func (sqlStmt) NumInput() int { return -1 }
507736
func (stmt sqlStmt) Exec(args []driver.Value) (driver.Result, error) { return sqlResult{}, stmt.Error }
508737
func (stmt sqlStmt) Query(args []driver.Value) (driver.Rows, error) { return sqlRows{}, stmt.Error }
738+
func (stmt sqlStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
739+
return sqlRows{}, stmt.Error
740+
}
741+
func (stmt sqlStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
742+
return sqlResult{}, stmt.Error
743+
}
509744

510745
type sqlResult struct{}
511746

sonar-project.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ sonar.links.ci=https://app.circleci.com/pipelines/github/instana/go-sensor
55
sonar.sourceEncoding=utf-8
66
sonar.sources=.
77
sonar.tests=.
8-
sonar.exclusions=example/*.go,example/**/*.go,**/example/*.go,**/**/example/*.go
8+
sonar.exclusions=eum.js,internal/bin/sql/sqlgen.go,example/*.go,example/**/*.go,**/example/*.go,**/**/example/*.go
99
sonar.test.inclusions=**/*_test.go,**/**/*_test.go,instrumentation/**/*_test.go
1010
sonar.go.coverage.reportPaths=coverage.out,instrumentation/**/coverage.out
1111
sonar.go.tests.reportPaths=coverage.json,instrumentation/**/coverage.json

sql_execer.go

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
otlog "github.com/opentracing/opentracing-go/log"
1010
)
1111

12+
// Execer interface is deprecated
13+
1214
type wExecer struct {
1315
driver.Execer
1416
connDetails DbConnDetails

sql_queryer.go

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
otlog "github.com/opentracing/opentracing-go/log"
1010
)
1111

12+
// Queryer is deprecated since Go v1.8
13+
1214
type wQueryer struct {
1315
driver.Queryer
1416
connDetails DbConnDetails

0 commit comments

Comments
 (0)