mirror of
https://github.com/Icinga/icingadb.git
synced 2026-05-28 04:35:54 -04:00
Merge pull request #418 from Icinga/feature/postgresql-tests
Port integration tests to PostgreSQL
This commit is contained in:
commit
1da2dfdcce
8 changed files with 122 additions and 71 deletions
15
.github/workflows/integration-tests.yml
vendored
15
.github/workflows/integration-tests.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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=
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue