123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- package dbconnect_tests
- import (
- "context"
- "log"
- "net/url"
- "os"
- "testing"
- "github.com/stretchr/testify/assert"
- "github.com/cloudflare/cloudflared/dbconnect"
- )
- func TestIntegrationPostgreSQL(t *testing.T) {
- ctx, pq := helperNewSQLClient(t, "POSTGRESQL_URL")
- err := pq.Ping(ctx)
- assert.NoError(t, err)
- _, err = pq.Submit(ctx, &dbconnect.Command{
- Statement: "CREATE TABLE t (a TEXT, b UUID, c JSON, d INET[], e SERIAL);",
- Mode: "exec",
- })
- assert.NoError(t, err)
- _, err = pq.Submit(ctx, &dbconnect.Command{
- Statement: "INSERT INTO t VALUES ($1, $2, $3, $4);",
- Mode: "exec",
- Arguments: dbconnect.Arguments{
- Positional: []interface{}{
- "text",
- "6b8d686d-bd8e-43bc-b09a-cfcbbe702c10",
- "{\"bool\":true,\"array\":[\"a\", 1, 3.14],\"embed\":{\"num\":21}}",
- []string{"1.1.1.1", "1.0.0.1"},
- },
- },
- })
- assert.NoError(t, err)
- _, err = pq.Submit(ctx, &dbconnect.Command{
- Statement: "UPDATE t SET b = NULL;",
- Mode: "exec",
- })
- assert.NoError(t, err)
- res, err := pq.Submit(ctx, &dbconnect.Command{
- Statement: "SELECT * FROM t;",
- Mode: "query",
- })
- assert.NoError(t, err)
- assert.IsType(t, make([]map[string]interface{}, 0), res)
- actual := res.([]map[string]interface{})[0]
- expected := map[string]interface{}{
- "a": "text",
- "b": nil,
- "c": map[string]interface{}{
- "bool": true,
- "array": []interface{}{"a", float64(1), 3.14},
- "embed": map[string]interface{}{"num": float64(21)},
- },
- "d": "{1.1.1.1,1.0.0.1}",
- "e": int64(1),
- }
- assert.EqualValues(t, expected, actual)
- _, err = pq.Submit(ctx, &dbconnect.Command{
- Statement: "DROP TABLE t;",
- Mode: "exec",
- })
- assert.NoError(t, err)
- }
- func TestIntegrationMySQL(t *testing.T) {
- ctx, my := helperNewSQLClient(t, "MYSQL_URL")
- err := my.Ping(ctx)
- assert.NoError(t, err)
- _, err = my.Submit(ctx, &dbconnect.Command{
- Statement: "CREATE TABLE t (a CHAR, b TINYINT, c FLOAT, d JSON, e YEAR);",
- Mode: "exec",
- })
- assert.NoError(t, err)
- _, err = my.Submit(ctx, &dbconnect.Command{
- Statement: "INSERT INTO t VALUES (?, ?, ?, ?, ?);",
- Mode: "exec",
- Arguments: dbconnect.Arguments{
- Positional: []interface{}{
- "a",
- 10,
- 3.14,
- "{\"bool\":true}",
- 2000,
- },
- },
- })
- assert.NoError(t, err)
- _, err = my.Submit(ctx, &dbconnect.Command{
- Statement: "ALTER TABLE t ADD COLUMN f GEOMETRY;",
- Mode: "exec",
- })
- assert.NoError(t, err)
- res, err := my.Submit(ctx, &dbconnect.Command{
- Statement: "SELECT * FROM t;",
- Mode: "query",
- })
- assert.NoError(t, err)
- assert.IsType(t, make([]map[string]interface{}, 0), res)
- actual := res.([]map[string]interface{})[0]
- expected := map[string]interface{}{
- "a": "a",
- "b": float64(10),
- "c": 3.14,
- "d": map[string]interface{}{"bool": true},
- "e": float64(2000),
- "f": nil,
- }
- assert.EqualValues(t, expected, actual)
- _, err = my.Submit(ctx, &dbconnect.Command{
- Statement: "DROP TABLE t;",
- Mode: "exec",
- })
- assert.NoError(t, err)
- }
- func TestIntegrationMSSQL(t *testing.T) {
- ctx, ms := helperNewSQLClient(t, "MSSQL_URL")
- err := ms.Ping(ctx)
- assert.NoError(t, err)
- _, err = ms.Submit(ctx, &dbconnect.Command{
- Statement: "CREATE TABLE t (a BIT, b DECIMAL, c MONEY, d TEXT);",
- Mode: "exec"})
- assert.NoError(t, err)
- _, err = ms.Submit(ctx, &dbconnect.Command{
- Statement: "INSERT INTO t VALUES (?, ?, ?, ?);",
- Mode: "exec",
- Arguments: dbconnect.Arguments{
- Positional: []interface{}{
- 0,
- 3,
- "$0.99",
- "text",
- },
- },
- })
- assert.NoError(t, err)
- _, err = ms.Submit(ctx, &dbconnect.Command{
- Statement: "UPDATE t SET d = NULL;",
- Mode: "exec",
- })
- assert.NoError(t, err)
- res, err := ms.Submit(ctx, &dbconnect.Command{
- Statement: "SELECT * FROM t;",
- Mode: "query",
- })
- assert.NoError(t, err)
- assert.IsType(t, make([]map[string]interface{}, 0), res)
- actual := res.([]map[string]interface{})[0]
- expected := map[string]interface{}{
- "a": false,
- "b": float64(3),
- "c": float64(0.99),
- "d": nil,
- }
- assert.EqualValues(t, expected, actual)
- _, err = ms.Submit(ctx, &dbconnect.Command{
- Statement: "DROP TABLE t;",
- Mode: "exec",
- })
- assert.NoError(t, err)
- }
- func TestIntegrationClickhouse(t *testing.T) {
- ctx, ch := helperNewSQLClient(t, "CLICKHOUSE_URL")
- err := ch.Ping(ctx)
- assert.NoError(t, err)
- _, err = ch.Submit(ctx, &dbconnect.Command{
- Statement: "CREATE TABLE t (a UUID, b String, c Float64, d UInt32, e Int16, f Array(Enum8('a'=1, 'b'=2, 'c'=3))) engine=Memory;",
- Mode: "exec",
- })
- assert.NoError(t, err)
- _, err = ch.Submit(ctx, &dbconnect.Command{
- Statement: "INSERT INTO t VALUES (?, ?, ?, ?, ?, ?);",
- Mode: "exec",
- Arguments: dbconnect.Arguments{
- Positional: []interface{}{
- "ec65f626-6f50-4c86-9628-6314ef1edacd",
- "",
- 3.14,
- 314,
- -144,
- []string{"a", "b", "c"},
- },
- },
- })
- assert.NoError(t, err)
- res, err := ch.Submit(ctx, &dbconnect.Command{
- Statement: "SELECT * FROM t;",
- Mode: "query",
- })
- assert.NoError(t, err)
- assert.IsType(t, make([]map[string]interface{}, 0), res)
- actual := res.([]map[string]interface{})[0]
- expected := map[string]interface{}{
- "a": "ec65f626-6f50-4c86-9628-6314ef1edacd",
- "b": "",
- "c": float64(3.14),
- "d": uint32(314),
- "e": int16(-144),
- "f": []string{"a", "b", "c"},
- }
- assert.EqualValues(t, expected, actual)
- _, err = ch.Submit(ctx, &dbconnect.Command{
- Statement: "DROP TABLE t;",
- Mode: "exec",
- })
- assert.NoError(t, err)
- }
- func helperNewSQLClient(t *testing.T, env string) (context.Context, dbconnect.Client) {
- _, ok := os.LookupEnv("DBCONNECT_INTEGRATION_TEST")
- if ok {
- t.Helper()
- } else {
- t.SkipNow()
- }
- val, ok := os.LookupEnv(env)
- if !ok {
- log.Fatalf("must provide database url as environment variable: %s", env)
- }
- parsed, err := url.Parse(val)
- if err != nil {
- log.Fatalf("cannot provide invalid database url: %s=%s", env, val)
- }
- ctx := context.Background()
- client, err := dbconnect.NewSQLClient(ctx, parsed)
- if err != nil {
- log.Fatalf("could not start test client: %s", err)
- }
- return ctx, client
- }
|