github.com/gogf/gf/v2@v2.7.4/os/gcron/gcron_z_unit_test.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gcron_test 8 9 import ( 10 "context" 11 "fmt" 12 "os" 13 "os/signal" 14 "syscall" 15 "testing" 16 "time" 17 18 "github.com/gogf/gf/v2/container/garray" 19 "github.com/gogf/gf/v2/frame/g" 20 "github.com/gogf/gf/v2/os/gcron" 21 "github.com/gogf/gf/v2/os/glog" 22 "github.com/gogf/gf/v2/test/gtest" 23 ) 24 25 var ( 26 ctx = context.TODO() 27 ) 28 29 func TestCron_Add_Close(t *testing.T) { 30 gtest.C(t, func(t *gtest.T) { 31 cron := gcron.New() 32 array := garray.New(true) 33 _, err1 := cron.Add(ctx, "* * * * * *", func(ctx context.Context) { 34 g.Log().Print(ctx, "cron1") 35 array.Append(1) 36 }) 37 _, err2 := cron.Add(ctx, "* * * * * *", func(ctx context.Context) { 38 g.Log().Print(ctx, "cron2") 39 array.Append(1) 40 }, "test") 41 t.Assert(err1, nil) 42 t.Assert(err2, nil) 43 t.Assert(cron.Size(), 2) 44 time.Sleep(1300 * time.Millisecond) 45 t.Assert(array.Len(), 2) 46 time.Sleep(1300 * time.Millisecond) 47 t.Assert(array.Len(), 4) 48 cron.Close() 49 time.Sleep(1300 * time.Millisecond) 50 fixedLength := array.Len() 51 time.Sleep(1300 * time.Millisecond) 52 t.Assert(array.Len(), fixedLength) 53 }) 54 } 55 56 func TestCron_Basic(t *testing.T) { 57 gtest.C(t, func(t *gtest.T) { 58 cron := gcron.New() 59 cron.Add(ctx, "* * * * * *", func(ctx context.Context) {}, "add") 60 // fmt.Println("start", time.Now()) 61 cron.DelayAdd(ctx, time.Second, "* * * * * *", func(ctx context.Context) {}, "delay_add") 62 t.Assert(cron.Size(), 1) 63 time.Sleep(1200 * time.Millisecond) 64 t.Assert(cron.Size(), 2) 65 66 cron.Remove("delay_add") 67 t.Assert(cron.Size(), 1) 68 69 entry1 := cron.Search("add") 70 entry2 := cron.Search("test-none") 71 t.AssertNE(entry1, nil) 72 t.Assert(entry2, nil) 73 }) 74 75 // test @ error 76 gtest.C(t, func(t *gtest.T) { 77 cron := gcron.New() 78 defer cron.Close() 79 _, err := cron.Add(ctx, "@aaa", func(ctx context.Context) {}, "add") 80 t.AssertNE(err, nil) 81 }) 82 83 // test @every error 84 gtest.C(t, func(t *gtest.T) { 85 cron := gcron.New() 86 defer cron.Close() 87 _, err := cron.Add(ctx, "@every xxx", func(ctx context.Context) {}, "add") 88 t.AssertNE(err, nil) 89 }) 90 } 91 92 func TestCron_Remove(t *testing.T) { 93 gtest.C(t, func(t *gtest.T) { 94 cron := gcron.New() 95 array := garray.New(true) 96 cron.Add(ctx, "* * * * * *", func(ctx context.Context) { 97 array.Append(1) 98 }, "add") 99 t.Assert(array.Len(), 0) 100 time.Sleep(1200 * time.Millisecond) 101 t.Assert(array.Len(), 1) 102 103 cron.Remove("add") 104 t.Assert(array.Len(), 1) 105 time.Sleep(1200 * time.Millisecond) 106 t.Assert(array.Len(), 1) 107 }) 108 } 109 110 func TestCron_Add_FixedPattern(t *testing.T) { 111 for i := 0; i < 5; i++ { 112 doTestCronAddFixedPattern(t) 113 } 114 } 115 116 func doTestCronAddFixedPattern(t *testing.T) { 117 gtest.C(t, func(t *gtest.T) { 118 var ( 119 now = time.Now() 120 cron = gcron.New() 121 array = garray.New(true) 122 expect = now.Add(time.Second * 2) 123 ) 124 defer cron.Close() 125 126 var pattern = fmt.Sprintf( 127 `%d %d %d %d %d %s`, 128 expect.Second(), expect.Minute(), expect.Hour(), expect.Day(), expect.Month(), expect.Weekday().String(), 129 ) 130 cron.SetLogger(g.Log()) 131 g.Log().Debugf(ctx, `pattern: %s`, pattern) 132 _, err := cron.Add(ctx, pattern, func(ctx context.Context) { 133 array.Append(1) 134 }) 135 t.AssertNil(err) 136 time.Sleep(3000 * time.Millisecond) 137 g.Log().Debug(ctx, `current time`) 138 t.Assert(array.Len(), 1) 139 }) 140 } 141 142 func TestCron_AddSingleton(t *testing.T) { 143 // un used, can be removed 144 gtest.C(t, func(t *gtest.T) { 145 cron := gcron.New() 146 cron.Add(ctx, "* * * * * *", func(ctx context.Context) {}, "add") 147 cron.DelayAdd(ctx, time.Second, "* * * * * *", func(ctx context.Context) {}, "delay_add") 148 t.Assert(cron.Size(), 1) 149 time.Sleep(1200 * time.Millisecond) 150 t.Assert(cron.Size(), 2) 151 152 cron.Remove("delay_add") 153 t.Assert(cron.Size(), 1) 154 155 entry1 := cron.Search("add") 156 entry2 := cron.Search("test-none") 157 t.AssertNE(entry1, nil) 158 t.Assert(entry2, nil) 159 }) 160 // keep this 161 gtest.C(t, func(t *gtest.T) { 162 cron := gcron.New() 163 array := garray.New(true) 164 cron.AddSingleton(ctx, "* * * * * *", func(ctx context.Context) { 165 array.Append(1) 166 time.Sleep(50 * time.Second) 167 }) 168 t.Assert(cron.Size(), 1) 169 time.Sleep(3500 * time.Millisecond) 170 t.Assert(array.Len(), 1) 171 }) 172 173 } 174 175 func TestCron_AddOnce1(t *testing.T) { 176 gtest.C(t, func(t *gtest.T) { 177 cron := gcron.New() 178 array := garray.New(true) 179 cron.AddOnce(ctx, "* * * * * *", func(ctx context.Context) { 180 array.Append(1) 181 }) 182 cron.AddOnce(ctx, "* * * * * *", func(ctx context.Context) { 183 array.Append(1) 184 }) 185 t.Assert(cron.Size(), 2) 186 time.Sleep(2500 * time.Millisecond) 187 t.Assert(array.Len(), 2) 188 t.Assert(cron.Size(), 0) 189 }) 190 } 191 192 func TestCron_AddOnce2(t *testing.T) { 193 gtest.C(t, func(t *gtest.T) { 194 cron := gcron.New() 195 array := garray.New(true) 196 cron.AddOnce(ctx, "@every 2s", func(ctx context.Context) { 197 array.Append(1) 198 }) 199 t.Assert(cron.Size(), 1) 200 time.Sleep(3000 * time.Millisecond) 201 t.Assert(array.Len(), 1) 202 t.Assert(cron.Size(), 0) 203 }) 204 } 205 206 func TestCron_AddTimes(t *testing.T) { 207 gtest.C(t, func(t *gtest.T) { 208 cron := gcron.New() 209 array := garray.New(true) 210 _, _ = cron.AddTimes(ctx, "* * * * * *", 2, func(ctx context.Context) { 211 array.Append(1) 212 }) 213 time.Sleep(3500 * time.Millisecond) 214 t.Assert(array.Len(), 2) 215 t.Assert(cron.Size(), 0) 216 }) 217 } 218 219 func TestCron_DelayAdd(t *testing.T) { 220 gtest.C(t, func(t *gtest.T) { 221 cron := gcron.New() 222 array := garray.New(true) 223 cron.DelayAdd(ctx, 500*time.Millisecond, "* * * * * *", func(ctx context.Context) { 224 array.Append(1) 225 }) 226 t.Assert(cron.Size(), 0) 227 time.Sleep(800 * time.Millisecond) 228 t.Assert(array.Len(), 0) 229 t.Assert(cron.Size(), 1) 230 time.Sleep(1000 * time.Millisecond) 231 t.Assert(array.Len(), 1) 232 t.Assert(cron.Size(), 1) 233 }) 234 } 235 236 func TestCron_DelayAddSingleton(t *testing.T) { 237 gtest.C(t, func(t *gtest.T) { 238 cron := gcron.New() 239 array := garray.New(true) 240 cron.DelayAddSingleton(ctx, 500*time.Millisecond, "* * * * * *", func(ctx context.Context) { 241 array.Append(1) 242 time.Sleep(10 * time.Second) 243 }) 244 t.Assert(cron.Size(), 0) 245 time.Sleep(2200 * time.Millisecond) 246 t.Assert(array.Len(), 1) 247 t.Assert(cron.Size(), 1) 248 }) 249 } 250 251 func TestCron_DelayAddOnce(t *testing.T) { 252 gtest.C(t, func(t *gtest.T) { 253 cron := gcron.New() 254 array := garray.New(true) 255 cron.DelayAddOnce(ctx, 500*time.Millisecond, "* * * * * *", func(ctx context.Context) { 256 array.Append(1) 257 }) 258 t.Assert(cron.Size(), 0) 259 time.Sleep(800 * time.Millisecond) 260 t.Assert(array.Len(), 0) 261 t.Assert(cron.Size(), 1) 262 time.Sleep(2200 * time.Millisecond) 263 t.Assert(array.Len(), 1) 264 t.Assert(cron.Size(), 0) 265 }) 266 } 267 268 func TestCron_DelayAddTimes(t *testing.T) { 269 gtest.C(t, func(t *gtest.T) { 270 cron := gcron.New() 271 array := garray.New(true) 272 cron.DelayAddTimes(ctx, 500*time.Millisecond, "* * * * * *", 2, func(ctx context.Context) { 273 array.Append(1) 274 }) 275 t.Assert(cron.Size(), 0) 276 time.Sleep(800 * time.Millisecond) 277 t.Assert(array.Len(), 0) 278 t.Assert(cron.Size(), 1) 279 time.Sleep(3000 * time.Millisecond) 280 t.Assert(array.Len(), 2) 281 t.Assert(cron.Size(), 0) 282 }) 283 } 284 285 func TestCron_JobWaiter(t *testing.T) { 286 gtest.C(t, func(t *gtest.T) { 287 var err error 288 s1 := garray.New(true) 289 s2 := garray.New(true) 290 _, err = gcron.Add(ctx, "* * * * * *", func(ctx context.Context) { 291 g.Log().Debug(ctx, "Every second") 292 s1.Append(struct{}{}) 293 }, "MyFirstCronJob") 294 t.Assert(err, nil) 295 _, err = gcron.Add(ctx, "*/2 * * * * *", func(ctx context.Context) { 296 g.Log().Debug(ctx, "Every 2s job start") 297 time.Sleep(3 * time.Second) 298 s2.Append(struct{}{}) 299 g.Log().Debug(ctx, "Every 2s job after 3 second end") 300 }, "MySecondCronJob") 301 t.Assert(err, nil) 302 303 quit := make(chan os.Signal, 1) 304 signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) 305 306 go func() { 307 time.Sleep(4 * time.Second) // Ensure that the job is triggered twice 308 glog.Print(ctx, "Sending SIGINT") 309 quit <- syscall.SIGINT // Send SIGINT 310 }() 311 312 sig := <-quit 313 glog.Printf(ctx, "Signal received: %s, stopping cron", sig) 314 315 glog.Print(ctx, "Waiting for all cron jobs to complete...") 316 gcron.StopGracefully() 317 glog.Print(ctx, "All cron jobs completed") 318 t.Assert(s1.Len(), 4) 319 t.Assert(s2.Len(), 2) 320 }) 321 }