Skip to content

Commit b164b6c

Browse files
committed
Add integration tests for checkable SlaLifecycle
1 parent f2fa48d commit b164b6c

File tree

3 files changed

+129
-8
lines changed

3 files changed

+129
-8
lines changed

tests/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ require (
66
github.com/go-sql-driver/mysql v1.8.1
77
github.com/goccy/go-yaml v1.12.0
88
github.com/google/uuid v1.6.0
9+
github.com/icinga/icinga-go-library v0.3.0
910
github.com/icinga/icinga-testing v0.0.0-20240322142451-494ccd6d03e8
1011
github.com/jmoiron/sqlx v1.4.0
1112
github.com/lib/pq v1.10.9
1213
github.com/redis/go-redis/v9 v9.7.0
1314
github.com/stretchr/testify v1.9.0
1415
go.uber.org/zap v1.27.0
15-
golang.org/x/exp v0.0.0-20221012112151-59b0eab1532e
1616
golang.org/x/sync v0.8.0
1717
)
1818

tests/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
6666
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
6767
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
6868
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
69+
github.com/icinga/icinga-go-library v0.3.0 h1:BeoomAiQC5RTRWCNqNkgbdTGxQ7ZFfkruR4HCSn5e0k=
70+
github.com/icinga/icinga-go-library v0.3.0/go.mod h1:YN7XJN3W0FodD+j4kirO89zk2tgvanXWt1RMV8UgOLo=
6971
github.com/icinga/icinga-testing v0.0.0-20240322142451-494ccd6d03e8 h1:PI+39IY1BjN24JC3B6Jy0rhwm3hqC4SnQFxbZjXOaHk=
7072
github.com/icinga/icinga-testing v0.0.0-20240322142451-494ccd6d03e8/go.mod h1:xjNiwePgnSVKJWPG/iFG7pNOibU/OWp01Zdl08o+EeI=
7173
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
@@ -171,8 +173,6 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
171173
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
172174
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
173175
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
174-
golang.org/x/exp v0.0.0-20221012112151-59b0eab1532e h1:/SJUJZl3kz7J5GzAx5lgaKvqKGd4OfzshwDMr6YJCC4=
175-
golang.org/x/exp v0.0.0-20221012112151-59b0eab1532e/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
176176
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
177177
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
178178
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=

tests/object_sync_test.go

Lines changed: 126 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"database/sql"
77
_ "embed"
88
"fmt"
9+
"github.com/icinga/icinga-go-library/types"
910
"github.com/icinga/icinga-testing/services"
1011
"github.com/icinga/icinga-testing/utils"
1112
"github.com/icinga/icinga-testing/utils/eventually"
@@ -16,9 +17,9 @@ import (
1617
"github.com/stretchr/testify/assert"
1718
"github.com/stretchr/testify/require"
1819
"go.uber.org/zap"
19-
"golang.org/x/exp/slices"
2020
"io"
2121
"reflect"
22+
"slices"
2223
"sort"
2324
"strings"
2425
"testing"
@@ -112,7 +113,6 @@ func TestObjectSync(t *testing.T) {
112113
t.Parallel()
113114

114115
for _, host := range data.Hosts {
115-
host := host
116116
t.Run("Verify-"+host.VariantInfoString(), func(t *testing.T) {
117117
t.Parallel()
118118

@@ -144,7 +144,6 @@ func TestObjectSync(t *testing.T) {
144144
t.Parallel()
145145

146146
for _, service := range data.Services {
147-
service := service
148147
t.Run("Verify-"+service.VariantInfoString(), func(t *testing.T) {
149148
t.Parallel()
150149

@@ -171,6 +170,40 @@ func TestObjectSync(t *testing.T) {
171170
}
172171
})
173172

173+
t.Run("SlaLifeCycle", func(t *testing.T) {
174+
t.Parallel()
175+
176+
slinfo := &SlaLifecycle{CreateTime: types.UnixMilli(time.Now())}
177+
178+
t.Run("Hosts", func(t *testing.T) {
179+
t.Parallel()
180+
181+
for hostId, host := range data.Hosts {
182+
t.Run("Verify-Host-"+fmt.Sprint(hostId), func(t *testing.T) {
183+
t.Parallel()
184+
185+
eventually.Assert(t, func(t require.TestingT) {
186+
verifySlaLifeCycleRow(t, db, slinfo, host.Name, "")
187+
}, 20*time.Second, 1*time.Second)
188+
})
189+
}
190+
})
191+
192+
t.Run("Services", func(t *testing.T) {
193+
t.Parallel()
194+
195+
for serviceId, service := range data.Services {
196+
t.Run("Verify-Service-"+fmt.Sprint(serviceId), func(t *testing.T) {
197+
t.Parallel()
198+
199+
eventually.Assert(t, func(t require.TestingT) {
200+
verifySlaLifeCycleRow(t, db, slinfo, *service.HostName, service.Name)
201+
}, 20*time.Second, 1*time.Second)
202+
})
203+
}
204+
})
205+
})
206+
174207
t.Run("HostGroup", func(t *testing.T) {
175208
t.Parallel()
176209
// TODO(jb): add tests
@@ -324,8 +357,6 @@ func TestObjectSync(t *testing.T) {
324357
t.Parallel()
325358

326359
for _, service := range makeTestSyncServices(t) {
327-
service := service
328-
329360
t.Run("CreateAndDelete-"+service.VariantInfoString(), func(t *testing.T) {
330361
t.Parallel()
331362

@@ -418,6 +449,34 @@ func TestObjectSync(t *testing.T) {
418449
})
419450
})
420451

452+
t.Run("SlaLifeCycle", func(t *testing.T) {
453+
t.Parallel()
454+
455+
for serviceId, service := range makeTestSyncServices(t) {
456+
//service.Name += fmt.Sprint(serviceId)
457+
458+
t.Run("Verify-Service-"+fmt.Sprint(serviceId), func(t *testing.T) {
459+
t.Parallel()
460+
461+
client.CreateObject(t, "services", *service.HostName+"!"+service.Name, map[string]interface{}{
462+
"attrs": makeIcinga2ApiAttributes(service, false),
463+
})
464+
465+
slinfo := &SlaLifecycle{CreateTime: types.UnixMilli(time.Now())}
466+
eventually.Assert(t, func(t require.TestingT) {
467+
verifySlaLifeCycleRow(t, db, slinfo, *service.HostName, service.Name)
468+
}, 20*time.Second, 1*time.Second)
469+
470+
client.DeleteObject(t, "services", *service.HostName+"!"+service.Name, false)
471+
472+
slinfo.DeleteTime = types.UnixMilli(time.Now())
473+
eventually.Assert(t, func(t require.TestingT) {
474+
verifySlaLifeCycleRow(t, db, slinfo, "", "")
475+
}, 20*time.Second, 1*time.Second)
476+
})
477+
}
478+
})
479+
421480
t.Run("User", func(t *testing.T) {
422481
t.Parallel()
423482

@@ -1188,6 +1247,68 @@ func verifyIcingaDbRow(t require.TestingT, db *sqlx.DB, obj interface{}) {
11881247
require.False(t, rows.Next(), "SQL query should return only one row: %s", query)
11891248
}
11901249

1250+
func verifySlaLifeCycleRow(t require.TestingT, db *sqlx.DB, slinfo *SlaLifecycle, host string, service string) {
1251+
query := `SELECT "create_time", "delete_time", "sla_lifecycle"."host_id", "sla_lifecycle"."service_id" FROM "sla_lifecycle"`
1252+
var args []interface{}
1253+
if !slinfo.HostID.Valid() {
1254+
query += ` INNER JOIN "host" ON "host"."id"="sla_lifecycle"."host_id"`
1255+
where := ` WHERE "host"."name"=?`
1256+
1257+
args = append(args, host)
1258+
if service == "" {
1259+
where += ` AND "service_id" IS NULL`
1260+
} else {
1261+
query += ` INNER JOIN "service" ON "service"."id"="sla_lifecycle"."service_id"`
1262+
where += ` AND "service"."name"=?`
1263+
args = append(args, service)
1264+
}
1265+
1266+
query += where + ` AND "delete_time" = 0`
1267+
} else {
1268+
query += ` WHERE "host_id"=?`
1269+
args = []interface{}{slinfo.HostID}
1270+
if !slinfo.ServiceID.Valid() {
1271+
query += ` AND "service_id" IS NULL`
1272+
} else {
1273+
query += ` AND "service_id"=?`
1274+
args = append(args, slinfo.ServiceID)
1275+
}
1276+
}
1277+
1278+
var resultSet []SlaLifecycle
1279+
err := db.Select(&resultSet, db.Rebind(query), args...)
1280+
require.NoError(t, err, "querying sla lifecycle should not fail: Query: %q", query)
1281+
1282+
require.Len(t, resultSet, 1, "there should be one sla lifecycle entry")
1283+
1284+
result := resultSet[0]
1285+
zerotimestamp := time.Unix(0, 0)
1286+
1287+
require.NotEqual(t, zerotimestamp, result.CreateTime.Time())
1288+
assert.WithinDuration(t, slinfo.CreateTime.Time(), result.CreateTime.Time(), time.Minute)
1289+
1290+
if slinfo.DeleteTime.Time().IsZero() {
1291+
// We can't join on the host/service tables, as the sla lifecycle entries may reference entries that have
1292+
// already been deleted. So cache the host/service id to use as a filter when asserting the sla lifecycles
1293+
// delete event.
1294+
slinfo.HostID = result.HostID
1295+
slinfo.ServiceID = result.ServiceID
1296+
1297+
require.Equal(t, zerotimestamp, result.DeleteTime.Time())
1298+
} else {
1299+
require.NotEqual(t, zerotimestamp, result.DeleteTime.Time())
1300+
require.Less(t, result.CreateTime.Time(), result.DeleteTime.Time())
1301+
assert.WithinDuration(t, slinfo.DeleteTime.Time(), result.DeleteTime.Time(), time.Minute)
1302+
}
1303+
}
1304+
1305+
type SlaLifecycle struct {
1306+
CreateTime types.UnixMilli `db:"create_time"`
1307+
DeleteTime types.UnixMilli `db:"delete_time"`
1308+
HostID types.Binary `db:"host_id"`
1309+
ServiceID types.Binary `db:"service_id"`
1310+
}
1311+
11911312
// newString allocates a new *string and initializes it. This helper function exists as
11921313
// there seems to be no way to achieve this within a single statement.
11931314
func newString(s string) *string {

0 commit comments

Comments
 (0)