Files
Diego Augusto Molina 7d32d5eff4 Unistore: Reuse MySQL and Postgres Grafana core config instead of the object (#94223)
* Reuse MySQL and Postgres Grafana config instead of the object

- Only reuse the Grafana DB object for SQLite. Support for SQLite will be added in a different PR
- Fail when reusing the Grafana DB object if it is using DB instrumentation
- In the case that we have to reuse a Grafana DB with its instrumentation, fail with an error that describes a workaround
- Add regression tests to reproduce incident 2144

* remove temp file

* fix linter

* fix linter x2

* fix linter x3
2024-10-04 12:07:20 +00:00

150 lines
3.8 KiB
Go

package dbimpl
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/setting"
)
var invalidUTF8ByteSequence = []byte{0xff, 0xfe, 0xfd}
func setSectionKeyValues(section *setting.DynamicSection, m map[string]string) {
for k, v := range m {
section.Key(k).SetValue(v)
}
}
func newTestConfGetter(m map[string]string, keyPrefix string) confGetter {
section := setting.NewCfg().SectionWithEnvOverrides("entity_api")
setSectionKeyValues(section, m)
return newConfGetter(section, keyPrefix)
}
func TestSectionGetter(t *testing.T) {
t.Parallel()
var (
key = "the key"
keyBoolTrue = "I'm true"
keyBoolFalse = "not me!"
prefix = "this is some prefix"
val = string(invalidUTF8ByteSequence)
)
t.Run("with prefix", func(t *testing.T) {
t.Parallel()
g := newTestConfGetter(map[string]string{
prefix + key: val,
prefix + keyBoolTrue: "YES",
prefix + keyBoolFalse: "0",
}, prefix)
require.False(t, g.Bool("whatever bool"))
require.NoError(t, g.Err())
require.False(t, g.Bool(keyBoolFalse))
require.NoError(t, g.Err())
require.True(t, g.Bool(keyBoolTrue))
require.NoError(t, g.Err())
require.Empty(t, g.String("whatever string"))
require.NoError(t, g.Err())
require.Empty(t, g.String(key))
require.Error(t, g.Err())
require.ErrorIs(t, g.Err(), errInvalidUTF8Sequence)
})
t.Run("without prefix", func(t *testing.T) {
t.Parallel()
g := newTestConfGetter(map[string]string{
key: val,
keyBoolTrue: "true",
keyBoolFalse: "f",
}, "")
require.False(t, g.Bool("whatever bool"))
require.NoError(t, g.Err())
require.False(t, g.Bool(keyBoolFalse))
require.NoError(t, g.Err())
require.True(t, g.Bool(keyBoolTrue))
require.NoError(t, g.Err())
require.Empty(t, g.String("whatever string"))
require.NoError(t, g.Err())
require.Empty(t, g.String(key))
require.Error(t, g.Err())
require.ErrorIs(t, g.Err(), errInvalidUTF8Sequence)
})
}
func TestMakeDSN(t *testing.T) {
t.Parallel()
s, err := MakeDSN(map[string]string{
"db_name": string(invalidUTF8ByteSequence),
})
require.Empty(t, s)
require.Error(t, err)
require.ErrorIs(t, err, errInvalidUTF8Sequence)
s, err = MakeDSN(map[string]string{
"skip": "",
"user": `shou'ld esc\ape`,
"pass": "noescape",
})
require.NoError(t, err)
require.Equal(t, `pass=noescape user='shou\'ld esc\\ape'`, s)
}
func TestSplitHostPort(t *testing.T) {
t.Parallel()
testCases := []struct {
hostport string
defaultHost string
defaultPort string
fails bool
host string
port string
}{
{hostport: "192.168.0.140:456", defaultHost: "", defaultPort: "", host: "192.168.0.140", port: "456"},
{hostport: "192.168.0.140", defaultHost: "", defaultPort: "123", host: "192.168.0.140", port: "123"},
{hostport: "[::1]:456", defaultHost: "", defaultPort: "", host: "::1", port: "456"},
{hostport: "[::1]", defaultHost: "", defaultPort: "123", host: "::1", port: "123"},
{hostport: ":456", defaultHost: "1.2.3.4", defaultPort: "", host: "1.2.3.4", port: "456"},
{hostport: "xyz.rds.amazonaws.com", defaultHost: "", defaultPort: "123", host: "xyz.rds.amazonaws.com", port: "123"},
{hostport: "xyz.rds.amazonaws.com:123", defaultHost: "", defaultPort: "", host: "xyz.rds.amazonaws.com", port: "123"},
{hostport: "", defaultHost: "localhost", defaultPort: "1433", host: "localhost", port: "1433"},
{hostport: "1:1:1", fails: true},
}
for i, tc := range testCases {
t.Run(fmt.Sprintf("test index #%d", i), func(t *testing.T) {
t.Parallel()
host, port, err := splitHostPortDefault(tc.hostport, tc.defaultHost, tc.defaultPort)
if tc.fails {
require.Error(t, err)
require.Empty(t, host)
require.Empty(t, port)
} else {
require.NoError(t, err)
require.Equal(t, tc.host, host)
require.Equal(t, tc.port, port)
}
})
}
}