/
datasource_connect_test.go
125 lines (113 loc) · 3.47 KB
/
datasource_connect_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package sqlds
import (
"context"
"database/sql"
"encoding/json"
"errors"
"testing"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data/sqlutil"
)
type fakeDriver struct {
openDBfn func(msg json.RawMessage) (*sql.DB, error)
Driver
}
func (d fakeDriver) Connect(_ context.Context, _ backend.DataSourceInstanceSettings, msg json.RawMessage) (db *sql.DB, err error) {
return d.openDBfn(msg)
}
func (d fakeDriver) Macros() Macros {
return Macros{}
}
func (d fakeDriver) Converters() []sqlutil.Converter {
return []sqlutil.Converter{}
}
func Test_getDBConnectionFromQuery(t *testing.T) {
db := &sql.DB{}
db2 := &sql.DB{}
db3 := &sql.DB{}
d := &fakeDriver{openDBfn: func(msg json.RawMessage) (*sql.DB, error) { return db3, nil }}
tests := []struct {
desc string
dsUID string
args string
existingDB *sql.DB
expectedKey string
expectedDB *sql.DB
}{
{
desc: "it should return the default db with no args",
dsUID: "uid1",
args: "",
expectedKey: "uid1-default",
expectedDB: db,
},
{
desc: "it should return the cached connection for the given args",
dsUID: "uid1",
args: "foo",
expectedKey: "uid1-foo",
existingDB: db2,
expectedDB: db2,
},
{
desc: "it should create a new connection with the given args",
dsUID: "uid1",
args: "foo",
expectedKey: "uid1-foo",
expectedDB: db3,
},
}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
ds := &SQLDatasource{c: d, EnableMultipleConnections: true}
settings := backend.DataSourceInstanceSettings{UID: tt.dsUID}
key := defaultKey(tt.dsUID)
// Add the mandatory default db
ds.storeDBConnection(key, dbConnection{db, settings})
if tt.existingDB != nil {
key = keyWithConnectionArgs(tt.dsUID, []byte(tt.args))
ds.storeDBConnection(key, dbConnection{tt.existingDB, settings})
}
key, dbConn, err := ds.getDBConnectionFromQuery(context.Background(), &Query{ConnectionArgs: json.RawMessage(tt.args)}, tt.dsUID)
if err != nil {
t.Fatalf("unexpected error %v", err)
}
if key != tt.expectedKey {
t.Fatalf("unexpected cache key %s", key)
}
if dbConn.db != tt.expectedDB {
t.Fatalf("unexpected result %v", dbConn.db)
}
})
}
t.Run("it should return an error if connection args are used without enabling multiple connections", func(t *testing.T) {
ds := &SQLDatasource{c: d, EnableMultipleConnections: false}
_, _, err := ds.getDBConnectionFromQuery(context.Background(), &Query{ConnectionArgs: json.RawMessage("foo")}, "dsUID")
if err == nil || !errors.Is(err, MissingMultipleConnectionsConfig) {
t.Errorf("expecting error: %v", MissingMultipleConnectionsConfig)
}
})
t.Run("it should return an error if the default connection is missing", func(t *testing.T) {
ds := &SQLDatasource{c: d}
_, _, err := ds.getDBConnectionFromQuery(context.Background(), &Query{}, "dsUID")
if err == nil || !errors.Is(err, MissingDBConnection) {
t.Errorf("expecting error: %v", MissingDBConnection)
}
})
}
func Test_Dispose(t *testing.T) {
t.Run("it should not delete connections", func(t *testing.T) {
ds := &SQLDatasource{}
ds.dbConnections.Store(defaultKey("uid1"), dbConnection{})
ds.dbConnections.Store("foo", dbConnection{})
ds.Dispose()
count := 0
ds.dbConnections.Range(func(key, value interface{}) bool {
count++
return true
})
if count != 2 {
t.Errorf("missing connections")
}
})
}