@@ -31,6 +31,9 @@ import (
3131var testSyncConfRaw string
3232var testSyncConfTemplate = template .Must (template .New ("testdata.conf" ).Parse (testSyncConfRaw ))
3333
34+ //go:embed config_sync_delta_slalifecycle.conf
35+ var slaLifecycleConfigSync []byte
36+
3437var usergroups = []string {
3538 "testusergroup1" ,
3639 "testusergroup2" ,
@@ -92,9 +95,9 @@ func TestObjectSync(t *testing.T) {
9295 require .NoError (t , err , "generate icinga2 notification config" )
9396 }
9497 //logger.Sugar().Infof("config:\n\n%s\n\n", conf.String())
95- i .WriteConfig ("etc/icinga2/conf.d/testdata.conf" , conf . Bytes () )
98+ i .WriteConfig ("etc/icinga2/conf.d/testdata.conf" , slaLifecycleConfigSync )
9699 i .EnableIcingaDb (r )
97- i .Reload ()
100+ require . NoError ( t , i .Reload (), "Icinga 2 reload" )
98101
99102 // Wait for Icinga 2 to signal a successful dump before starting
100103 // Icinga DB to ensure that we actually test the initial sync.
@@ -105,10 +108,54 @@ func TestObjectSync(t *testing.T) {
105108 logger .Debug ("starting icingadb" )
106109 it .IcingaDbInstanceT (t , r , rdb )
107110
111+ // Wait some time to give Icinga DB a chance to finish syncing the 5 dummy hosts and services.
112+ time .Sleep (2 * time .Second )
113+
108114 db , err := sqlx .Open (rdb .Driver (), rdb .DSN ())
109115 require .NoError (t , err , "connecting to SQL database shouldn't fail" )
110116 t .Cleanup (func () { _ = db .Close () })
111117
118+ dummyHostIdsMap := map [string ]SlaLifecycle {}
119+ dummyServiceIdsMap := map [string ]SlaLifecycle {}
120+ scanDummyObjFunc := func (typ string ) {
121+ var query string
122+ if typ == "service" {
123+ query = `SELECT service.name AS service_name, host.name as host_name, service.id AS service_id, host_id FROM service INNER JOIN host ON host.id=host_id`
124+ } else {
125+ query = `SELECT "name" AS host_name, id AS host_id FROM host`
126+ }
127+
128+ rows , err := db .Queryx (query )
129+ assert .NoError (t , err , "select all dummy %s ids" , typ )
130+ defer rows .Close ()
131+
132+ for rows .Next () {
133+ obj := & struct {
134+ HostName string `db:"host_name"`
135+ ServiceName string `db:"service_name"`
136+ SlaLifecycle `db:",inline"`
137+ }{
138+ SlaLifecycle : SlaLifecycle {CreateTime : types .UnixMilli (time .Now ())},
139+ }
140+
141+ require .NoError (t , rows .StructScan (obj ), "scan dummy %s" , typ )
142+
143+ if typ == "host" {
144+ dummyHostIdsMap [obj .HostName ] = obj .SlaLifecycle
145+ } else {
146+ dummyServiceIdsMap [obj .HostName + "!" + obj .ServiceName ] = obj .SlaLifecycle
147+ }
148+ }
149+ }
150+
151+ // Fetch the dummy host and service ids from the database before reloading Icinga 2 with the new config.
152+ go scanDummyObjFunc ("host" )
153+ go scanDummyObjFunc ("service" )
154+
155+ // Write the regular conf bytes excluding the dummy bytes we wrote earlier and reload the Icinga 2 instance.
156+ i .WriteConfig ("etc/icinga2/conf.d/testdata.conf" , conf .Bytes ())
157+ require .NoError (t , i .Reload (), "Icinga 2 reload" )
158+
112159 t .Run ("Host" , func (t * testing.T ) {
113160 t .Parallel ()
114161
@@ -173,23 +220,21 @@ func TestObjectSync(t *testing.T) {
173220 t .Run ("SlaLifeCycle" , func (t * testing.T ) {
174221 t .Parallel ()
175222
176- createTime := types .UnixMilli (time .Now ())
177-
223+ deleteTime := types .UnixMilli (time .Now ())
178224 t .Run ("Hosts" , func (t * testing.T ) {
179225 t .Parallel ()
180226
181- for hostId , host := range data .Hosts {
182- t .Run ("Verify-Host-" + fmt .Sprint (hostId ), func (t * testing.T ) {
227+ for i := 0 ; i < 5 ; i ++ {
228+ host := & Host {Name : "sla-lifecycle-host-" + fmt .Sprint (i )}
229+
230+ t .Run ("Verify-Host-" + fmt .Sprint (i ), func (t * testing.T ) {
183231 t .Parallel ()
184232
185- slinfo := & SlaLifecycle {CreateTime : createTime }
233+ slinfo := dummyHostIdsMap [host .Name ]
234+ slinfo .DeleteTime = deleteTime
186235
187236 eventually .Assert (t , func (t require.TestingT ) {
188- // We can't join on the host table, as the sla lifecycle entries may reference hosts that have
189- // already been deleted. So fetch the host id from DB before performing the actual test.
190- require .NoError (t , fetchCheckableId (db , slinfo , host .Name , "" ))
191-
192- verifySlaLifecycleRow (t , db , slinfo , false )
237+ verifySlaLifecycleRow (t , db , & slinfo , false )
193238 }, 20 * time .Second , 1 * time .Second )
194239 })
195240 }
@@ -198,18 +243,17 @@ func TestObjectSync(t *testing.T) {
198243 t .Run ("Services" , func (t * testing.T ) {
199244 t .Parallel ()
200245
201- for serviceId , service := range data .Services {
202- t .Run ("Verify-Service-" + fmt .Sprint (serviceId ), func (t * testing.T ) {
246+ for i := 0 ; i < 5 ; i ++ {
247+ service := & Service {Name : "sla-lifecycle-service" , HostName : newString ("sla-lifecycle-host-" + fmt .Sprint (i ))}
248+
249+ t .Run ("Verify-Service-" + fmt .Sprint (i ), func (t * testing.T ) {
203250 t .Parallel ()
204251
205- slinfo := & SlaLifecycle {CreateTime : createTime }
252+ slinfo := dummyServiceIdsMap [* service .HostName + "!" + service .Name ]
253+ slinfo .DeleteTime = deleteTime
206254
207255 eventually .Assert (t , func (t require.TestingT ) {
208- // We can't join on the service table, as the sla lifecycle entries may reference services that
209- // have already been deleted. So fetch the service id from DB before performing the actual test.
210- require .NoError (t , fetchCheckableId (db , slinfo , * service .HostName , service .Name ))
211-
212- verifySlaLifecycleRow (t , db , slinfo , false )
256+ verifySlaLifecycleRow (t , db , & slinfo , false )
213257 }, 20 * time .Second , 1 * time .Second )
214258 })
215259 }
@@ -1306,8 +1350,7 @@ func verifyIcingaDbRow(t require.TestingT, db *sqlx.DB, obj interface{}) {
13061350// two sla lifecycle entries to exist that match the checkables id.
13071351func verifySlaLifecycleRow (t require.TestingT , db * sqlx.DB , slinfo * SlaLifecycle , isRecreated bool ) {
13081352 query := `SELECT "create_time", "delete_time" FROM "sla_lifecycle" WHERE "host_id" = ?`
1309- var args []interface {}
1310- args = []interface {}{slinfo .HostID }
1353+ args := []interface {}{slinfo .HostID }
13111354 if ! slinfo .ServiceID .Valid () {
13121355 query += ` AND "service_id" IS NULL`
13131356 } else {
0 commit comments