icingadb/tests/environment_test.go

121 lines
3.5 KiB
Go
Raw Permalink Normal View History

2021-05-07 11:11:40 -04:00
package icingadb_test
import (
"encoding/hex"
"encoding/json"
"github.com/icinga/icinga-testing/services"
"github.com/icinga/icinga-testing/utils/eventually"
2021-11-23 10:54:43 -05:00
"github.com/jmoiron/sqlx"
2021-05-07 11:11:40 -04:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup"
"sort"
2021-05-07 11:11:40 -04:00
"testing"
"time"
)
func TestMultipleEnvironments(t *testing.T) {
2021-11-23 10:54:43 -05:00
rdb := getDatabase(t)
2021-05-07 11:11:40 -04:00
numEnvs := 3
icinga2Instances := make([]services.Icinga2, numEnvs)
2021-05-07 11:11:40 -04:00
2021-11-23 10:54:43 -05:00
// Start numEnvs icinga2 instances with an icingadb instance each, all writing to the same SQL database.
2021-05-07 11:11:40 -04:00
var g errgroup.Group
for i := range icinga2Instances {
i := i
2021-05-07 11:11:40 -04:00
g.Go(func() error {
r := it.RedisServerT(t)
icinga2Instances[i] = it.Icinga2NodeT(t, "master")
icinga2Instances[i].EnableIcingaDb(r)
icinga2Instances[i].Reload()
2021-11-23 10:54:43 -05:00
it.IcingaDbInstanceT(t, r, rdb)
2021-05-07 11:11:40 -04:00
return nil
})
}
_ = g.Wait()
// Query the IcingaDB environment_id from each icinga2 instance.
var expectedEnvs []string
for _, instance := range icinga2Instances {
res, err := instance.ApiClient().GetJson("/v1/objects/icingadbs")
require.NoError(t, err, "requesting IcingaDB objects from API should succeed")
var objects ObjectsIcingaDBsResponse
err = json.NewDecoder(res.Body).Decode(&objects)
require.NoError(t, err, "requesting IcingaDB objects from API should succeed")
require.NotEmpty(t, objects.Results, "API response should return an IcingaDB object")
expectedEnvs = append(expectedEnvs, objects.Results[0].Attrs.EnvironmentId)
}
sort.Strings(expectedEnvs)
for i := 0; i < len(expectedEnvs)-1; i++ {
require.NotEqual(t, expectedEnvs[i], expectedEnvs[i+1], "all environment IDs should be distinct")
}
2021-11-23 10:54:43 -05:00
db, err := sqlx.Open(rdb.Driver(), rdb.DSN())
require.NoError(t, err, "SQL database open")
2021-05-07 11:11:40 -04:00
t.Cleanup(func() { _ = db.Close() })
t.Run("Table", func(t *testing.T) {
t.Parallel()
eventually.Assert(t, func(t require.TestingT) {
2021-11-23 10:54:43 -05:00
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")
2021-05-07 11:11:40 -04:00
defer rows.Close()
var gotEnvs []string
2021-05-07 11:11:40 -04:00
for rows.Next() {
var id, name string
err := rows.Scan(&id, &name)
2021-11-23 10:54:43 -05:00
require.NoError(t, err, "SQL scan")
require.Equal(t, id, name, "name should be initialized to the environment id")
gotEnvs = append(gotEnvs, id)
2021-05-07 11:11:40 -04:00
}
require.Equal(t, expectedEnvs, gotEnvs, "each environment should be present in the environments table")
}, 20*time.Second, 250*time.Millisecond)
2021-05-07 11:11:40 -04:00
})
t.Run("HA", func(t *testing.T) {
t.Parallel()
eventually.Assert(t, func(t require.TestingT) {
2021-05-07 11:11:40 -04:00
rows, err := db.Query("SELECT environment_id, COUNT(*) FROM icingadb_instance WHERE responsible = 'y' GROUP BY environment_id")
2021-11-23 10:54:43 -05:00
require.NoError(t, err, "SQL query")
2021-05-07 11:11:40 -04:00
defer rows.Close()
numRows := 0
for rows.Next() {
var env []byte
var count int
err := rows.Scan(&env, &count)
2021-11-23 10:54:43 -05:00
require.NoError(t, err, "SQL scan")
2021-05-07 11:11:40 -04:00
assert.LessOrEqualf(t, count, 1,
"environment %s must have at most one active instance", hex.EncodeToString(env))
numRows++
}
require.Equal(t, numEnvs, numRows, "each environment should have one active instance")
}, 20*time.Second, 250*time.Millisecond)
2021-05-07 11:11:40 -04:00
})
}
type ObjectsIcingaDBsResponse struct {
Results []struct {
Attrs struct {
EnvironmentId string `json:"environment_id"`
} `json:"attrs"`
} `json:"results"`
}