github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/model/job/trigger_event_test.go (about) 1 package job_test 2 3 import ( 4 "context" 5 "sync" 6 "testing" 7 "time" 8 9 "github.com/cozy/cozy-stack/model/job" 10 "github.com/cozy/cozy-stack/pkg/config/config" 11 "github.com/cozy/cozy-stack/pkg/couchdb" 12 "github.com/cozy/cozy-stack/pkg/realtime" 13 "github.com/cozy/cozy-stack/tests/testutils" 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 ) 17 18 func TestTrigger(t *testing.T) { 19 if testing.Short() { 20 t.Skip("an instance is required for this test: test skipped due to the use of --short flag") 21 } 22 23 config.UseTestFile(t) 24 setup := testutils.NewSetup(t, t.Name()) 25 testInstance := setup.GetTestInstance() 26 27 t.Run("TriggerEvent", func(t *testing.T) { 28 var wg sync.WaitGroup 29 called := make(map[string]bool) 30 verb := "CREATED" 31 32 bro := job.NewMemBroker() 33 assert.NoError(t, bro.StartWorkers(job.WorkersList{ 34 { 35 WorkerType: "worker_event", 36 Concurrency: 1, 37 MaxExecCount: 1, 38 Timeout: 1 * time.Millisecond, 39 WorkerFunc: func(ctx *job.TaskContext) error { 40 defer wg.Done() 41 var msg string 42 if err := ctx.UnmarshalMessage(&msg); err != nil { 43 assert.NoError(t, err) 44 return err 45 } 46 var evt struct { 47 Domain string `json:"domain"` 48 Verb string `json:"verb"` 49 Doc couchdb.JSONDoc 50 } 51 if err := ctx.UnmarshalEvent(&evt); err != nil { 52 assert.NoError(t, err) 53 return nil 54 } 55 assert.Equal(t, testInstance.Domain, evt.Domain) 56 assert.Equal(t, verb, evt.Verb) 57 assert.Equal(t, "test-id", evt.Doc.ID()) 58 called[msg] = true 59 return nil 60 }, 61 }, 62 })) 63 64 var triggers []job.Trigger 65 triggersInfos := []job.TriggerInfos{ 66 { 67 Type: "@event", 68 Arguments: "io.cozy.testeventobject:DELETED", 69 WorkerType: "worker_event", 70 Message: makeMessage(t, "message-bad-verb"), 71 }, 72 { 73 Type: "@event", 74 Arguments: "io.cozy.testeventobject:CREATED:value:test", 75 WorkerType: "worker_event", 76 Message: makeMessage(t, "message-correct-verb-correct-value"), 77 }, 78 { 79 Type: "@event", 80 Arguments: "io.cozy.testeventobject:CREATED", 81 WorkerType: "worker_event", 82 Message: makeMessage(t, "message-correct-verb"), 83 }, 84 { 85 Type: "@event", 86 Arguments: "io.cozy.testeventobject:CREATED:notvalue:test", 87 WorkerType: "worker_event", 88 Message: makeMessage(t, "message-correct-verb-bad-value"), 89 }, 90 { 91 Type: "@event", 92 Arguments: "io.cozy.testeventobject:UPDATED:!=:test", 93 WorkerType: "worker_event", 94 Message: makeMessage(t, "message-change"), 95 }, 96 { 97 Type: "@event", 98 Arguments: "io.cozy.testeventobject", 99 WorkerType: "worker_event", 100 Message: makeMessage(t, "message-wholetype"), 101 }, 102 } 103 104 sch := job.NewMemScheduler() 105 assert.NoError(t, sch.StartScheduler(bro)) 106 107 for _, infos := range triggersInfos { 108 trigger, err := job.NewTrigger(testInstance, infos, infos.Message) 109 require.NoError(t, err) 110 111 err = sch.AddTrigger(trigger) 112 require.NoError(t, err) 113 114 triggers = append(triggers, trigger) 115 } 116 117 wg.Add(3) 118 119 time.AfterFunc(1*time.Millisecond, func() { 120 doc := couchdb.JSONDoc{ 121 Type: "io.cozy.testeventobject", 122 M: map[string]interface{}{ 123 "_id": "test-id", 124 "_rev": "1-xxabxx", 125 "test": "value", 126 }, 127 } 128 realtime.GetHub().Publish(testInstance, realtime.EventCreate, &doc, nil) 129 }) 130 131 wg.Wait() 132 133 assert.True(t, called["message-correct-verb"]) 134 assert.True(t, called["message-correct-verb-correct-value"]) 135 assert.True(t, called["message-wholetype"]) 136 assert.False(t, called["message-bad-verb"]) 137 assert.False(t, called["message-correct-verb-bad-value"]) 138 assert.False(t, called["message-change"]) 139 140 delete(called, "message-correct-verb") 141 delete(called, "message-correct-verb-correct-value") 142 delete(called, "message-wholetype") 143 144 wg.Add(1) 145 verb = "UPDATED" 146 147 time.AfterFunc(1*time.Millisecond, func() { 148 doc := couchdb.JSONDoc{ 149 Type: "io.cozy.testeventobject", 150 M: map[string]interface{}{ 151 "_id": "test-id", 152 "_rev": "2-xxcdxx", 153 "test": "value", 154 }, 155 } 156 olddoc := couchdb.JSONDoc{ 157 Type: "io.cozy.testeventobject", 158 M: map[string]interface{}{ 159 "_id": "test-id", 160 "_rev": "1-xxabxx", 161 "test": "value", 162 }, 163 } 164 realtime.GetHub().Publish(testInstance, realtime.EventUpdate, &doc, &olddoc) 165 }) 166 167 wg.Wait() 168 169 assert.True(t, called["message-wholetype"]) 170 assert.False(t, called["message-correct-verb"]) 171 assert.False(t, called["message-correct-verb-correct-value"]) 172 assert.False(t, called["message-bad-verb"]) 173 assert.False(t, called["message-correct-verb-bad-value"]) 174 assert.False(t, called["message-change"]) 175 176 delete(called, "message-wholetype") 177 178 wg.Add(2) 179 180 time.AfterFunc(1*time.Millisecond, func() { 181 doc := couchdb.JSONDoc{ 182 Type: "io.cozy.testeventobject", 183 M: map[string]interface{}{ 184 "_id": "test-id", 185 "_rev": "3-xxefxx", 186 "test": "changed", 187 }, 188 } 189 olddoc := couchdb.JSONDoc{ 190 Type: "io.cozy.testeventobject", 191 M: map[string]interface{}{ 192 "_id": "test-id", 193 "_rev": "2-xxcdxx", 194 "test": "value", 195 }, 196 } 197 realtime.GetHub().Publish(testInstance, realtime.EventUpdate, &doc, &olddoc) 198 }) 199 200 wg.Wait() 201 202 assert.False(t, called["message-correct-verb"]) 203 assert.False(t, called["message-correct-verb-correct-value"]) 204 assert.False(t, called["message-bad-verb"]) 205 assert.False(t, called["message-correct-verb-bad-value"]) 206 assert.True(t, called["message-change"]) 207 assert.True(t, called["message-wholetype"]) 208 209 for _, trigger := range triggers { 210 err := sch.DeleteTrigger(testInstance, trigger.ID()) 211 assert.NoError(t, err) 212 } 213 214 err := sch.ShutdownScheduler(context.Background()) 215 assert.NoError(t, err) 216 }) 217 } 218 219 func makeMessage(t *testing.T, msg string) job.Message { 220 out, err := job.NewMessage(msg) 221 assert.NoError(t, err) 222 return out 223 }