diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 1c30a637..9bf486f7 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -10,7 +10,18 @@ on: jobs: integration-tests: + strategy: + fail-fast: false + matrix: + database: + - name: mysql + pretty_name: MySQL + - name: pgsql + pretty_name: PostgreSQL + + name: ${{ matrix.database.pretty_name }} runs-on: ubuntu-latest + steps: - name: Checkout uses: actions/checkout@v2 @@ -28,8 +39,10 @@ jobs: - name: Run Integration Tests run: ./icingadb-test -icingatesting.debuglog debug.log -test.v env: + ICINGADB_TESTS_DATABASE_TYPE: ${{ matrix.database.name }} ICINGA_TESTING_ICINGADB_BINARY: ${{ github.workspace }}/icingadb - ICINGA_TESTING_ICINGADB_SCHEMA: ${{ github.workspace }}/schema/mysql/schema.sql + ICINGA_TESTING_ICINGADB_SCHEMA_MYSQL: ${{ github.workspace }}/schema/mysql/schema.sql + ICINGA_TESTING_ICINGADB_SCHEMA_PGSQL: ${{ github.workspace }}/schema/pgsql/schema.sql - name: Compress Debug Log if: ${{ always() }} run: xz -9 debug.log diff --git a/tests/environment_test.go b/tests/environment_test.go index 5aef492a..b4cedbcc 100644 --- a/tests/environment_test.go +++ b/tests/environment_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "github.com/icinga/icinga-testing/services" "github.com/icinga/icinga-testing/utils/eventually" + "github.com/jmoiron/sqlx" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" @@ -14,13 +15,12 @@ import ( ) func TestMultipleEnvironments(t *testing.T) { - m := it.MysqlDatabaseT(t) - m.ImportIcingaDbSchema() + rdb := getDatabase(t) numEnvs := 3 icinga2Instances := make([]services.Icinga2, numEnvs) - // Start numEnvs icinga2 instances with an icingadb instance each, all writing to the same mysql database. + // Start numEnvs icinga2 instances with an icingadb instance each, all writing to the same SQL database. var g errgroup.Group for i := range icinga2Instances { i := i @@ -30,7 +30,7 @@ func TestMultipleEnvironments(t *testing.T) { icinga2Instances[i] = it.Icinga2NodeT(t, "master") icinga2Instances[i].EnableIcingaDb(r) icinga2Instances[i].Reload() - it.IcingaDbInstanceT(t, r, m) + it.IcingaDbInstanceT(t, r, rdb) return nil }) } @@ -53,23 +53,32 @@ func TestMultipleEnvironments(t *testing.T) { require.NotEqual(t, expectedEnvs[i], expectedEnvs[i+1], "all environment IDs should be distinct") } - db, err := m.Open() - require.NoError(t, err, "mysql open") + db, err := sqlx.Open(rdb.Driver(), rdb.DSN()) + require.NoError(t, err, "SQL database open") t.Cleanup(func() { _ = db.Close() }) t.Run("Table", func(t *testing.T) { t.Parallel() eventually.Assert(t, func(t require.TestingT) { - rows, err := db.Query("SELECT LOWER(HEX(id)), name FROM environment ORDER BY id") - require.NoError(t, err, "mysql query") + var query string + switch rdb.Driver() { + case "mysql": + query = "SELECT LOWER(HEX(id)), name FROM environment ORDER BY id" + case "postgres": + query = "SELECT LOWER(ENCODE(id, 'hex')), name FROM environment ORDER BY id" + default: + panic("unknown database driver") + } + rows, err := db.Query(query) + require.NoError(t, err, "SQL query") defer rows.Close() var gotEnvs []string for rows.Next() { var id, name string err := rows.Scan(&id, &name) - require.NoError(t, err, "mysql scan") + require.NoError(t, err, "SQL scan") require.Equal(t, id, name, "name should be initialized to the environment id") gotEnvs = append(gotEnvs, id) } @@ -83,7 +92,7 @@ func TestMultipleEnvironments(t *testing.T) { eventually.Assert(t, func(t require.TestingT) { rows, err := db.Query("SELECT environment_id, COUNT(*) FROM icingadb_instance WHERE responsible = 'y' GROUP BY environment_id") - require.NoError(t, err, "mysql query") + require.NoError(t, err, "SQL query") defer rows.Close() numRows := 0 @@ -91,7 +100,7 @@ func TestMultipleEnvironments(t *testing.T) { var env []byte var count int err := rows.Scan(&env, &count) - require.NoError(t, err, "mysql scan") + require.NoError(t, err, "SQL scan") assert.LessOrEqualf(t, count, 1, "environment %s must have at most one active instance", hex.EncodeToString(env)) diff --git a/tests/go.mod b/tests/go.mod index 3c57bffa..76c1cdc3 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -6,7 +6,7 @@ require ( github.com/containerd/containerd v1.5.6 // indirect github.com/go-redis/redis/v8 v8.11.3 github.com/google/uuid v1.3.0 - github.com/icinga/icinga-testing v0.0.0-20220309154907-12cf833da4f3 + github.com/icinga/icinga-testing v0.0.0-20220315141514-b316c93f8d77 github.com/jmoiron/sqlx v1.3.4 github.com/stretchr/testify v1.7.0 go.uber.org/zap v1.19.1 diff --git a/tests/go.sum b/tests/go.sum index 3e48f68f..04869cf9 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -390,8 +390,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/icinga/icinga-testing v0.0.0-20220309154907-12cf833da4f3 h1:w+d7+9iXWr06sNi9p2gwKhRqLU77FdpNmFm9DVsWbl0= -github.com/icinga/icinga-testing v0.0.0-20220309154907-12cf833da4f3/go.mod h1:VzB7xVUPFvAUgX1nDrheKHpQddvUIN24Sei4mLGelpo= +github.com/icinga/icinga-testing v0.0.0-20220315141514-b316c93f8d77 h1:BD9nPWVdUJY9kIGuuvtOiNGd4fsvpd26N8gU/33rVh8= +github.com/icinga/icinga-testing v0.0.0-20220315141514-b316c93f8d77/go.mod h1:W9pLmq2dsgLSag568N/LDHNu4oah6qWvjT05Drz2RYw= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= @@ -429,8 +429,9 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= +github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= diff --git a/tests/history_test.go b/tests/history_test.go index 98f4cf9f..e720f024 100644 --- a/tests/history_test.go +++ b/tests/history_test.go @@ -40,8 +40,7 @@ func TestHistory(t *testing.T) { } func testHistory(t *testing.T, numNodes int) { - m := it.MysqlDatabaseT(t) - m.ImportIcingaDbSchema() + rdb := getDatabase(t) ca, err := pki.NewCA() require.NoError(t, err, "generating a CA should succeed") @@ -101,7 +100,7 @@ func testHistory(t *testing.T, numNodes int) { n.Icinga2.EnableIcingaDb(n.ConsistencyRedis) err = n.Icinga2.Reload() require.NoError(t, err, "icinga2 should reload without error") - it.IcingaDbInstanceT(t, n.Redis, m) + it.IcingaDbInstanceT(t, n.Redis, rdb) { n := n @@ -143,7 +142,7 @@ func testHistory(t *testing.T, numNodes int) { } }, 15*time.Second, 200*time.Millisecond) - db, err := sqlx.Connect("mysql", m.DSN()) + db, err := sqlx.Connect(rdb.Driver(), rdb.DSN()) require.NoError(t, err, "connecting to mysql") t.Cleanup(func() { _ = db.Close() }) @@ -195,10 +194,10 @@ func testHistory(t *testing.T, numNodes int) { } var rows []Row - err = db.Select(&rows, "SELECT a.author, a.comment FROM history h"+ + err = db.Select(&rows, db.Rebind("SELECT a.author, a.comment FROM history h"+ " JOIN host ON host.id = h.host_id"+ " JOIN acknowledgement_history a ON a.id = h.acknowledgement_history_id"+ - " WHERE host.name = ? AND ? < h.event_time AND h.event_time < ?", + " WHERE host.name = ? AND ? < h.event_time AND h.event_time < ?"), hostname, ackTime.Add(-time.Second).UnixMilli(), ackTime.Add(time.Second).UnixMilli()) require.NoError(t, err, "select acknowledgement_history") @@ -301,11 +300,11 @@ func testHistory(t *testing.T, numNodes int) { eventually.Assert(t, func(t require.TestingT) { var rows []HistoryEvent - err = db.Select(&rows, "SELECT h.event_type, c.author, c.comment, c.removed_by"+ + err = db.Select(&rows, db.Rebind("SELECT h.event_type, c.author, c.comment, c.removed_by"+ " FROM history h"+ " JOIN comment_history c ON c.comment_id = h.comment_history_id"+ " JOIN host ON host.id = c.host_id WHERE host.name = ?"+ - " ORDER BY h.event_time", hostname) + " ORDER BY h.event_time"), hostname) require.NoError(t, err, "select comment_history") assert.Equal(t, expected, rows, "comment history should match") @@ -424,12 +423,13 @@ func testHistory(t *testing.T, numNodes int) { if !eventually.Assert(t, func(t require.TestingT) { var got []HistoryEvent - err = db.Select(&got, "SELECT h.event_type, d.author, d.comment, d.has_been_cancelled FROM history h"+ + err = db.Select(&got, db.Rebind("SELECT h.event_type, d.author, d.comment, d.has_been_cancelled"+ + " FROM history h"+ " JOIN host ON host.id = h.host_id"+ // Joining downtime_history checks that events are written to it. " JOIN downtime_history d ON d.downtime_id = h.downtime_history_id"+ " WHERE host.name = ? AND ? < h.event_time AND h.event_time < ?"+ - " ORDER BY h.event_time", + " ORDER BY h.event_time"), hostname, downtimeStart.Add(-time.Second).UnixMilli(), downtimeEnd.Add(time.Second).UnixMilli()) require.NoError(t, err, "select downtime_history") @@ -479,12 +479,12 @@ func testHistory(t *testing.T, numNodes int) { eventually.Assert(t, func(t require.TestingT) { var rows []string - err = db.Select(&rows, "SELECT h.event_type FROM history h"+ + err = db.Select(&rows, db.Rebind("SELECT h.event_type FROM history h"+ " JOIN host ON host.id = h.host_id"+ // Joining flapping_history checks that events are written to it. " JOIN flapping_history f ON f.id = h.flapping_history_id"+ " WHERE host.name = ? AND ? < h.event_time AND h.event_time < ?"+ - " ORDER BY h.event_time", + " ORDER BY h.event_time"), hostname, timeBefore.Add(-time.Second).UnixMilli(), timeAfter.Add(time.Second).UnixMilli()) require.NoError(t, err, "select flapping_history") @@ -557,13 +557,13 @@ func testHistory(t *testing.T, numNodes int) { eventually.Assert(t, func(t require.TestingT) { var rows []Notification - err = db.Select(&rows, "SELECT n.type, COALESCE(u.name, '') AS username FROM history h"+ + err = db.Select(&rows, db.Rebind("SELECT n.type, COALESCE(u.name, '') AS username FROM history h"+ " JOIN host ON host.id = h.host_id"+ " JOIN notification_history n ON n.id = h.notification_history_id"+ " LEFT JOIN user_notification_history un ON un.notification_history_id = n.id"+ - " LEFT JOIN user u ON u.id = un.user_id"+ + ` LEFT JOIN "user" u ON u.id = un.user_id`+ " WHERE host.name = ? AND ? < h.event_time AND h.event_time < ?"+ - " ORDER BY h.event_time, username", + " ORDER BY h.event_time, username"), hostname, timeBefore.Add(-time.Second).UnixMilli(), timeAfter.Add(time.Second).UnixMilli()) require.NoError(t, err, "select notification_history") @@ -624,10 +624,10 @@ func testHistory(t *testing.T, numNodes int) { eventually.Assert(t, func(t require.TestingT) { var rows []State - err = db.Select(&rows, "SELECT s.state_type, s.soft_state, s.hard_state FROM history h"+ + err = db.Select(&rows, db.Rebind("SELECT s.state_type, s.soft_state, s.hard_state FROM history h"+ " JOIN host ON host.id = h.host_id JOIN state_history s ON s.id = h.state_history_id"+ " WHERE host.name = ? AND ? < h.event_time AND h.event_time < ?"+ - " ORDER BY h.event_time", + " ORDER BY h.event_time"), hostname, timeBefore.Add(-time.Second).UnixMilli(), timeAfter.Add(time.Second).UnixMilli()) require.NoError(t, err, "select state_history") diff --git a/tests/main_test.go b/tests/main_test.go index 05aa46a0..256c81ce 100644 --- a/tests/main_test.go +++ b/tests/main_test.go @@ -1,7 +1,10 @@ package icingadb_test import ( + "fmt" "github.com/icinga/icinga-testing" + "github.com/icinga/icinga-testing/services" + "os" "testing" ) @@ -13,3 +16,23 @@ func TestMain(m *testing.M) { m.Run() } + +func getDatabase(t testing.TB) services.RelationalDatabase { + k := "ICINGADB_TESTS_DATABASE_TYPE" + v := os.Getenv(k) + + var rdb services.RelationalDatabase + + switch v { + case "mysql": + rdb = it.MysqlDatabaseT(t) + case "pgsql": + rdb = it.PostgresqlDatabaseT(t) + default: + panic(fmt.Sprintf(`unknown database in %s environment variable: %q (must be "mysql" or "pgsql")`, k, v)) + } + + rdb.ImportIcingaDbSchema() + + return rdb +} diff --git a/tests/object_sync_test.go b/tests/object_sync_test.go index ab33c318..7d438780 100644 --- a/tests/object_sync_test.go +++ b/tests/object_sync_test.go @@ -67,7 +67,7 @@ func TestObjectSync(t *testing.T) { } r := it.RedisServerT(t) - m := it.MysqlDatabaseT(t) + rdb := getDatabase(t) i := it.Icinga2NodeT(t, "master") conf := bytes.NewBuffer(nil) err := testSyncConfTemplate.Execute(conf, data) @@ -100,10 +100,10 @@ func TestObjectSync(t *testing.T) { // Only after that, start Icinga DB. logger.Debug("starting icingadb") - it.IcingaDbInstanceT(t, r, m) + it.IcingaDbInstanceT(t, r, rdb) - db, err := sqlx.Open("mysql", m.DSN()) - require.NoError(t, err, "connecting to mysql shouldn't fail") + db, err := sqlx.Open(rdb.Driver(), rdb.DSN()) + require.NoError(t, err, "connecting to SQL database shouldn't fail") t.Cleanup(func() { _ = db.Close() }) t.Run("Host", func(t *testing.T) { @@ -355,7 +355,7 @@ func TestObjectSync(t *testing.T) { require.Eventuallyf(t, func() bool { var count int - err := db.Get(&count, "SELECT COUNT(*) FROM service WHERE name = ?", service.Name) + err := db.Get(&count, db.Rebind("SELECT COUNT(*) FROM service WHERE name = ?"), service.Name) require.NoError(t, err, "querying service count should not fail") return count == 0 }, 20*time.Second, 1*time.Second, "service with name=%q should be removed from database", service.Name) @@ -381,7 +381,7 @@ func TestObjectSync(t *testing.T) { }) require.Eventuallyf(t, func() bool { var count int - err := db.Get(&count, "SELECT COUNT(*) FROM service WHERE name = ?", service.Name) + err := db.Get(&count, db.Rebind("SELECT COUNT(*) FROM service WHERE name = ?"), service.Name) require.NoError(t, err, "querying service count should not fail") return count == 1 }, 20*time.Second, 1*time.Second, "service with name=%q should exist in database", service.Name) @@ -437,7 +437,7 @@ func TestObjectSync(t *testing.T) { require.Eventuallyf(t, func() bool { var count int - err := db.Get(&count, "SELECT COUNT(*) FROM user WHERE name = ?", user.Name) + err := db.Get(&count, db.Rebind(`SELECT COUNT(*) FROM "user" WHERE name = ?`), user.Name) require.NoError(t, err, "querying user count should not fail") return count == 0 }, 20*time.Second, 1*time.Second, "user with name=%q should be removed from database", user.Name) @@ -454,7 +454,7 @@ func TestObjectSync(t *testing.T) { }) require.Eventuallyf(t, func() bool { var count int - err := db.Get(&count, "SELECT COUNT(*) FROM user WHERE name = ?", userName) + err := db.Get(&count, db.Rebind(`SELECT COUNT(*) FROM "user" WHERE name = ?`), userName) require.NoError(t, err, "querying user count should not fail") return count == 1 }, 20*time.Second, 1*time.Second, "user with name=%q should exist in database", userName) @@ -499,7 +499,7 @@ func TestObjectSync(t *testing.T) { require.Eventuallyf(t, func() bool { var count int - err := db.Get(&count, "SELECT COUNT(*) FROM notification WHERE name = ?", notification.fullName()) + err := db.Get(&count, db.Rebind("SELECT COUNT(*) FROM notification WHERE name = ?"), notification.fullName()) require.NoError(t, err, "querying notification count should not fail") return count == 0 }, 20*time.Second, 200*time.Millisecond, "notification with name=%q should be removed from database", notification.fullName()) @@ -525,7 +525,7 @@ func TestObjectSync(t *testing.T) { require.Eventuallyf(t, func() bool { var count int - err := db.Get(&count, "SELECT COUNT(*) FROM notification WHERE name = ?", baseNotification.fullName()) + err := db.Get(&count, db.Rebind("SELECT COUNT(*) FROM notification WHERE name = ?"), baseNotification.fullName()) require.NoError(t, err, "querying notification count should not fail") return count == 1 }, 20*time.Second, 200*time.Millisecond, "notification with name=%q should exist in database", baseNotification.fullName()) @@ -918,10 +918,10 @@ func (n Notification) verify(t require.TestingT, db *sqlx.DB) { // Check if the "notification_user" table has been populated correctly { - query := "SELECT u.name FROM notification n JOIN notification_user nu ON n.id = nu.notification_id JOIN user u ON u.id = nu.user_id WHERE n.name = ? ORDER BY u.name" + query := `SELECT u.name FROM notification n JOIN notification_user nu ON n.id = nu.notification_id JOIN "user" u ON u.id = nu.user_id WHERE n.name = ? ORDER BY u.name` var rows []string - err := db.Select(&rows, query, n.fullName()) - require.NoError(t, err, "mysql query") + err := db.Select(&rows, db.Rebind(query), n.fullName()) + require.NoError(t, err, "SQL query") expected := append([]string(nil), n.Users...) sort.Strings(expected) @@ -933,8 +933,8 @@ func (n Notification) verify(t require.TestingT, db *sqlx.DB) { { query := "SELECT ug.name FROM notification n JOIN notification_usergroup ng ON n.id = ng.notification_id JOIN usergroup ug ON ug.id = ng.usergroup_id WHERE n.name = ? ORDER BY ug.name" var rows []string - err := db.Select(&rows, query, n.fullName()) - require.NoError(t, err, "mysql query") + err := db.Select(&rows, db.Rebind(query), n.fullName()) + require.NoError(t, err, "SQL query") expected := append([]string(nil), n.UserGroups...) sort.Strings(expected) @@ -991,15 +991,15 @@ func (n Notification) verify(t require.TestingT, db *sqlx.DB) { query := "SELECT u.name AS username, ug.name AS groupname FROM notification n " + "JOIN notification_recipient nr ON n.id = nr.notification_id " + - "LEFT JOIN user u ON u.id = nr.user_id " + + `LEFT JOIN "user" u ON u.id = nr.user_id ` + "LEFT JOIN usergroup ug ON ug.id = nr.usergroup_id " + "WHERE n.name = ? " + - "ORDER BY u.name, ug.name" + "ORDER BY u.name IS NOT NULL, u.name, ug.name IS NOT NULL, ug.name" var rows []Row - err := db.Select(&rows, query, n.fullName()) + err := db.Select(&rows, db.Rebind(query), n.fullName()) - require.NoError(t, err, "mysql query") + require.NoError(t, err, "SQL query") require.Equal(t, expected, rows, "Recipients in database should be equal") } } @@ -1114,7 +1114,11 @@ func verifyIcingaDbRow(t require.TestingT, db *sqlx.DB, obj interface{}) { joinColumns := func(cs []ColumnValueExpected) string { var c []string for i := range cs { - c = append(c, cs[i].Column) + var quotedParts []string + for _, part := range strings.Split(cs[i].Column, ".") { + quotedParts = append(quotedParts, `"`+part+`"`) + } + c = append(c, strings.Join(quotedParts, ".")) } return strings.Join(c, ", ") } @@ -1153,24 +1157,25 @@ func verifyIcingaDbRow(t require.TestingT, db *sqlx.DB, obj interface{}) { joinsQuery := "" for join := range joins { - joinsQuery += fmt.Sprintf(" LEFT JOIN %s ON %s.id = %s.%s_id", join, join, table, join) + joinsQuery += fmt.Sprintf(` LEFT JOIN "%s" ON "%s"."id" = "%s"."%s_id"`, join, join, table, join) } - query := "SELECT " + joinColumns(columns) + " FROM " + table + joinsQuery + " WHERE " + table + ".name = ?" - rows, err := db.Query(query, name) - require.NoError(t, err, "mysql query") + query := fmt.Sprintf(`SELECT %s FROM "%s" %s WHERE "%s"."name" = ?`, + joinColumns(columns), table, joinsQuery, table) + rows, err := db.Query(db.Rebind(query), name) + require.NoError(t, err, "SQL query: %s", query) defer func() { _ = rows.Close() }() - require.True(t, rows.Next(), "mysql query should return a row") + require.True(t, rows.Next(), "SQL query should return a row: %s", query) err = rows.Scan(scanSlice(columns)...) - require.NoError(t, err, "mysql scan") + require.NoError(t, err, "SQL scan: %s", query) for _, col := range columns { got := reflect.ValueOf(col.Value).Elem().Interface() assert.Equalf(t, col.Expected, got, "%s should match", col.Column) } - require.False(t, rows.Next(), "mysql query should return only one row") + require.False(t, rows.Next(), "SQL query should return only one row: %s", query) } // newString allocates a new *string and initializes it. This helper function exists as @@ -1228,9 +1233,9 @@ func (c *CustomVarTestData) verify(t require.TestingT, logger *zap.Logger, db *s } query += "WHERE " + table + ".name = ?" - rows, err := db.Query(query, name) - defer func() { _ = rows.Close() }() + rows, err := db.Query(db.Rebind(query), name) require.NoError(t, err, "querying customvars") + defer func() { _ = rows.Close() }() expectedSrc := c.Vars if flat { diff --git a/tests/regression_394_test.go b/tests/regression_394_test.go index a34266d4..73062937 100644 --- a/tests/regression_394_test.go +++ b/tests/regression_394_test.go @@ -21,7 +21,7 @@ func TestRegression394(t *testing.T) { logger := it.Logger(t) r := it.RedisServerT(t) - m := it.MysqlDatabaseT(t) + rdb := getDatabase(t) i := it.Icinga2NodeT(t, "master") i.EnableIcingaDb(r) err := i.Reload() @@ -34,12 +34,12 @@ func TestRegression394(t *testing.T) { // Only after that, start Icinga DB. logger.Debug("starting icingadb") - it.IcingaDbInstanceT(t, r, m) + it.IcingaDbInstanceT(t, r, rdb) client := i.ApiClient() - db, err := sqlx.Open("mysql", m.DSN()) - require.NoError(t, err, "connecting to mysql shouldn't fail") + db, err := sqlx.Open(rdb.Driver(), rdb.DSN()) + require.NoError(t, err, "connecting to SQL database shouldn't fail") t.Cleanup(func() { _ = db.Close() }) waitForPendingRuntimeUpdates := func(t *testing.T) { @@ -50,7 +50,7 @@ func TestRegression394(t *testing.T) { client.CreateHost(t, markerName, nil) eventually.Require(t, func(t require.TestingT) { var count int - err = db.Get(&count, "SELECT COUNT(*) FROM host WHERE name = ?", markerName) + err = db.Get(&count, db.Rebind("SELECT COUNT(*) FROM host WHERE name = ?"), markerName) require.NoError(t, err, "select host count from database") assert.Equalf(t, 1, count, "marker host %q should appear in database", markerName) }, 10*time.Second, 100*time.Millisecond) @@ -58,7 +58,7 @@ func TestRegression394(t *testing.T) { client.DeleteHost(t, markerName, true) eventually.Require(t, func(t require.TestingT) { var count int - err = db.Get(&count, "SELECT COUNT(*) FROM host WHERE name = ?", markerName) + err = db.Get(&count, db.Rebind("SELECT COUNT(*) FROM host WHERE name = ?"), markerName) require.NoError(t, err, "select host count from database") assert.Zerof(t, count, "marker host %q should disappear from database", markerName) }, 10*time.Second, 100*time.Millisecond) @@ -82,7 +82,7 @@ func TestRegression394(t *testing.T) { waitForPendingRuntimeUpdates(t) var countAfter int - err = db.Get(&countAfter, "SELECT COUNT(*) FROM host WHERE name LIKE ?", namePrefix+"%") + err = db.Get(&countAfter, db.Rebind("SELECT COUNT(*) FROM host WHERE name LIKE ?"), namePrefix+"%") require.NoError(t, err, "select host count from database") assert.Zero(t, countAfter, "no hosts should be left in database") @@ -106,7 +106,7 @@ func TestRegression394(t *testing.T) { waitForPendingRuntimeUpdates(t) var countBefore int - err = db.Get(&countBefore, "SELECT COUNT(*) FROM host WHERE name LIKE ?", namePrefix+"%") + err = db.Get(&countBefore, db.Rebind("SELECT COUNT(*) FROM host WHERE name LIKE ?"), namePrefix+"%") require.NoError(t, err, "select host count from database") assert.Equal(t, numObjects, countBefore, "all hosts should exist in database before recreation") @@ -118,7 +118,7 @@ func TestRegression394(t *testing.T) { waitForPendingRuntimeUpdates(t) var countAfter int - err = db.Get(&countAfter, "SELECT COUNT(*) FROM host WHERE name LIKE ?", namePrefix+"%") + err = db.Get(&countAfter, db.Rebind("SELECT COUNT(*) FROM host WHERE name LIKE ?"), namePrefix+"%") require.NoError(t, err, "select host count from database") assert.Equal(t, numObjects, countAfter, "all hosts should exist in database after recreation") })