Skip to content

Commit

Permalink
adding more SQL test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
willianpc committed Nov 20, 2023
1 parent 8411d90 commit 63b11aa
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 10 deletions.
6 changes: 4 additions & 2 deletions instrumentation_sql_go1.10_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,5 +186,7 @@ func TestWrapSQLConnector_Query_Error(t *testing.T) {

type sqlConnector struct{ Error error }

func (c sqlConnector) Connect(context.Context) (driver.Conn, error) { return sqlConn{c.Error}, nil } //nolint:gosimple
func (sqlConnector) Driver() driver.Driver { return sqlDriver{} }
func (c sqlConnector) Connect(context.Context) (driver.Conn, error) {
return sqlConn{Error: c.Error}, nil
} //nolint:gosimple
func (sqlConnector) Driver() driver.Driver { return sqlDriver{} }
251 changes: 243 additions & 8 deletions instrumentation_sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,206 @@ func TestOpenSQLDB_RedisConnString(t *testing.T) {
}, data.Tags)
}

func TestConnPrepareContext(t *testing.T) {
recorder := instana.NewTestRecorder()
s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{
Service: "go-sensor-test",
AgentClient: alwaysReadyClient{},
}, recorder))
defer instana.ShutdownSensor()

instana.InstrumentSQLDriver(s, "fake_pc", sqlDriver{})
require.Contains(t, sql.Drivers(), "fake_pc_with_instana")

db, err := instana.SQLOpen("fake_pc", "conn string")
require.NoError(t, err)

ctx := context.Background()

stmt, err := db.PrepareContext(ctx, "select 1 from table")
require.NoError(t, err)

_, err = stmt.QueryContext(ctx)
require.NoError(t, err)

spans := recorder.GetQueuedSpans()

require.Len(t, spans, 1)

require.IsType(t, instana.SDKSpanData{}, spans[0].Data)
data := spans[0].Data.(instana.SDKSpanData)

assert.Equal(t, instana.SDKSpanTags{
Name: "sdk.database",
Type: "exit",
Custom: map[string]interface{}{
"tags": ot.Tags{
"span.kind": ext.SpanKindRPCClientEnum,
"db.instance": "conn string",
"db.statement": "select 1 from table",
"db.type": "sql",
"peer.address": "conn string",
},
},
}, data.Tags)
}

func TestConnPrepareContextWithError(t *testing.T) {
recorder := instana.NewTestRecorder()
s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{
Service: "go-sensor-test",
AgentClient: alwaysReadyClient{},
}, recorder))
defer instana.ShutdownSensor()

instana.InstrumentSQLDriver(s, "fake_conn_pc_error", sqlDriver{Error: errors.New("some error")})
require.Contains(t, sql.Drivers(), "fake_conn_pc_error_with_instana")

db, err := instana.SQLOpen("fake_conn_pc_error", "conn string")
require.NoError(t, err)

ctx := context.Background()

stmt, err := db.PrepareContext(ctx, "select 1 from table")
require.NoError(t, err)

_, err = stmt.QueryContext(ctx)
require.Error(t, err)

spans := recorder.GetQueuedSpans()

require.Len(t, spans, 2)

assert.Equal(t, spans[0].Ec, 1)

require.IsType(t, instana.SDKSpanData{}, spans[0].Data)
data := spans[0].Data.(instana.SDKSpanData)

assert.Equal(t, instana.SDKSpanTags{
Name: "sdk.database",
Type: "exit",
Custom: map[string]interface{}{
"tags": ot.Tags{
"span.kind": ext.SpanKindRPCClientEnum,
"db.error": "some error",
"db.instance": "conn string",
"db.statement": "select 1 from table",
"db.type": "sql",
"peer.address": "conn string",
},
},
}, data.Tags)
}

func TestStmtExecContext(t *testing.T) {
recorder := instana.NewTestRecorder()
s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{
Service: "go-sensor-test",
AgentClient: alwaysReadyClient{},
}, recorder))
defer instana.ShutdownSensor()

instana.InstrumentSQLDriver(s, "fake_stmt_ec", sqlDriver{})
require.Contains(t, sql.Drivers(), "fake_stmt_ec_with_instana")

db, err := instana.SQLOpen("fake_stmt_ec", "conn string")
require.NoError(t, err)

ctx := context.Background()

stmt, err := db.PrepareContext(ctx, "select 1 from table")
require.NoError(t, err)

_, err = stmt.ExecContext(ctx)
require.NoError(t, err)

spans := recorder.GetQueuedSpans()

require.Len(t, spans, 1)

require.IsType(t, instana.SDKSpanData{}, spans[0].Data)
data := spans[0].Data.(instana.SDKSpanData)

assert.Equal(t, instana.SDKSpanTags{
Name: "sdk.database",
Type: "exit",
Custom: map[string]interface{}{
"tags": ot.Tags{
"span.kind": ext.SpanKindRPCClientEnum,
"db.instance": "conn string",
"db.statement": "select 1 from table",
"db.type": "sql",
"peer.address": "conn string",
},
},
}, data.Tags)
}

func TestStmtExecContextWithError(t *testing.T) {
recorder := instana.NewTestRecorder()
s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{
Service: "go-sensor-test",
AgentClient: alwaysReadyClient{},
}, recorder))
defer instana.ShutdownSensor()

instana.InstrumentSQLDriver(s, "fake_stmt_ec_with_error", sqlDriver{Error: errors.New("oh no")})
require.Contains(t, sql.Drivers(), "fake_stmt_ec_with_error_with_instana")

db, err := instana.SQLOpen("fake_stmt_ec_with_error", "conn string")
require.NoError(t, err)

ctx := context.Background()

stmt, err := db.PrepareContext(ctx, "select 1 from table")
require.NoError(t, err)

_, err = stmt.ExecContext(ctx)
require.Error(t, err)

spans := recorder.GetQueuedSpans()

require.Len(t, spans, 2)

require.IsType(t, instana.SDKSpanData{}, spans[0].Data)
data := spans[0].Data.(instana.SDKSpanData)

assert.Equal(t, instana.SDKSpanTags{
Name: "sdk.database",
Type: "exit",
Custom: map[string]interface{}{
"tags": ot.Tags{
"span.kind": ext.SpanKindRPCClientEnum,
"db.error": "oh no",
"db.instance": "conn string",
"db.statement": "select 1 from table",
"db.type": "sql",
"peer.address": "conn string",
},
},
}, data.Tags)
}

func TestConnPrepareContextWithErrorOnReturn(t *testing.T) {
recorder := instana.NewTestRecorder()
s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{
Service: "go-sensor-test",
AgentClient: alwaysReadyClient{},
}, recorder))
defer instana.ShutdownSensor()

instana.InstrumentSQLDriver(s, "fake_conn_pc_error_on_ret", sqlDriver{PrepareError: errors.New("oh no")})
require.Contains(t, sql.Drivers(), "fake_conn_pc_error_on_ret_with_instana")

db, err := instana.SQLOpen("fake_conn_pc_error_on_ret", "conn string")
require.NoError(t, err)

ctx := context.Background()

_, err = db.PrepareContext(ctx, "select 1 from table")
require.Error(t, err)
}

func TestOpenSQLDB_RedisConnString_WithError(t *testing.T) {
recorder := instana.NewTestRecorder()
s := instana.NewSensorWithTracer(instana.NewTracerWithEverything(&instana.Options{
Expand All @@ -358,7 +558,7 @@ func TestOpenSQLDB_RedisConnString_WithError(t *testing.T) {
}, recorder))
defer instana.ShutdownSensor()

instana.InstrumentSQLDriver(s, "fake_redis_driver_with_error", sqlDriver{errors.New("oops")})
instana.InstrumentSQLDriver(s, "fake_redis_driver_with_error", sqlDriver{Error: errors.New("oops")})
require.Contains(t, sql.Drivers(), "fake_redis_driver_with_error_with_instana")

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

type sqlDriver struct{ Error error }
type sqlDriver struct {
// Error is a generic error in the SQL execution. It generates spans with errors
Error error
// StmtError will give an error when a method from Stmt returns. It does not generate spans at all
StmtError error
// PrepareError will give an error when a method from Prepare* returns. It does not generate spans at all
PrepareError error
}

func (drv sqlDriver) Open(name string) (driver.Conn, error) { return sqlConn{drv.Error}, nil } //nolint:gosimple
func (drv sqlDriver) Open(name string) (driver.Conn, error) {
return sqlConn{
Error: drv.Error,
StmtError: drv.StmtError,
PrepareError: drv.PrepareError,
}, nil
} //nolint:gosimple

type sqlConn struct{ Error error }
type sqlConn struct {
Error error
StmtError error
PrepareError error
}

func (conn sqlConn) Prepare(query string) (driver.Stmt, error) { return sqlStmt{conn.Error}, nil } //nolint:gosimple
func (s sqlConn) Close() error { return driver.ErrSkip }
func (s sqlConn) Begin() (driver.Tx, error) { return nil, driver.ErrSkip }
var _ driver.Conn = (*sqlConn)(nil)
var _ driver.ConnPrepareContext = (*sqlConn)(nil)

func (conn sqlConn) Prepare(query string) (driver.Stmt, error) {
return sqlStmt{Error: conn.Error}, nil
} //nolint:gosimple
func (conn sqlConn) Close() error { return driver.ErrSkip }
func (conn sqlConn) Begin() (driver.Tx, error) { return nil, driver.ErrSkip }

func (conn sqlConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
return sqlStmt{StmtError: conn.StmtError, Error: conn.Error}, conn.PrepareError //nolint:gosimple
}

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

type sqlStmt struct{ Error error }
type sqlStmt struct {
Error error
StmtError error
}

func (sqlStmt) Close() error { return nil }
func (sqlStmt) NumInput() int { return -1 }
func (stmt sqlStmt) Exec(args []driver.Value) (driver.Result, error) { return sqlResult{}, stmt.Error }
func (stmt sqlStmt) Query(args []driver.Value) (driver.Rows, error) { return sqlRows{}, stmt.Error }
func (stmt sqlStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
return sqlRows{}, stmt.Error
}
func (stmt sqlStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
return sqlResult{}, stmt.Error
}

type sqlResult struct{}

Expand Down
2 changes: 2 additions & 0 deletions sql_execer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
otlog "github.com/opentracing/opentracing-go/log"
)

// Execer interface is deprecated

type wExecer struct {
driver.Execer
connDetails DbConnDetails
Expand Down
2 changes: 2 additions & 0 deletions sql_queryer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
otlog "github.com/opentracing/opentracing-go/log"
)

// Queryer is deprecated since Go v1.8

type wQueryer struct {
driver.Queryer
connDetails DbConnDetails
Expand Down

0 comments on commit 63b11aa

Please sign in to comment.