github.com/thanos-io/thanos@v0.32.5/pkg/extkingpin/path_content_reloader_test.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package extkingpin 5 6 import ( 7 "context" 8 "os" 9 "path" 10 "sync" 11 "testing" 12 "time" 13 14 "github.com/pkg/errors" 15 16 "github.com/thanos-io/thanos/pkg/runutil" 17 18 "github.com/efficientgo/core/testutil" 19 "github.com/go-kit/log" 20 ) 21 22 func TestPathContentReloader(t *testing.T) { 23 t.Parallel() 24 type args struct { 25 runSteps func(t *testing.T, testFile string, pathContent *staticPathContent, reloadTime time.Duration) 26 } 27 tests := []struct { 28 name string 29 args args 30 wantReloads int 31 }{ 32 { 33 name: "Many operations, only rewrite triggers one reload + plus the initial reload", 34 args: args{ 35 runSteps: func(t *testing.T, testFile string, pathContent *staticPathContent, reloadTime time.Duration) { 36 testutil.Ok(t, os.Chmod(testFile, 0777)) 37 testutil.Ok(t, os.Remove(testFile)) 38 testutil.Ok(t, pathContent.Rewrite([]byte("test modified"))) 39 }, 40 }, 41 wantReloads: 2, 42 }, 43 { 44 name: "Many operations, two rewrites trigger two reloads + the initial reload", 45 args: args{ 46 runSteps: func(t *testing.T, testFile string, pathContent *staticPathContent, reloadTime time.Duration) { 47 testutil.Ok(t, os.Chmod(testFile, 0777)) 48 testutil.Ok(t, os.Remove(testFile)) 49 testutil.Ok(t, pathContent.Rewrite([]byte("test modified"))) 50 time.Sleep(2 * reloadTime) 51 testutil.Ok(t, pathContent.Rewrite([]byte("test modified again"))) 52 }, 53 }, 54 wantReloads: 3, 55 }, 56 { 57 name: "Chmod doesn't trigger reload, we have only the initial reload", 58 args: args{ 59 runSteps: func(t *testing.T, testFile string, pathContent *staticPathContent, reloadTime time.Duration) { 60 testutil.Ok(t, os.Chmod(testFile, 0777)) 61 testutil.Ok(t, os.Chmod(testFile, 0666)) 62 testutil.Ok(t, os.Chmod(testFile, 0777)) 63 }, 64 }, 65 wantReloads: 1, 66 }, 67 { 68 name: "Remove doesn't trigger reload, we have only the initial reload", 69 args: args{ 70 runSteps: func(t *testing.T, testFile string, pathContent *staticPathContent, reloadTime time.Duration) { 71 testutil.Ok(t, os.Remove(testFile)) 72 }, 73 }, 74 wantReloads: 1, 75 }, 76 } 77 for _, tt := range tests { 78 tt := tt 79 t.Run(tt.name, func(t *testing.T) { 80 t.Parallel() 81 testFile := path.Join(t.TempDir(), "test") 82 testutil.Ok(t, os.WriteFile(testFile, []byte("test"), 0666)) 83 84 pathContent, err := NewStaticPathContent(testFile) 85 testutil.Ok(t, err) 86 87 wg := &sync.WaitGroup{} 88 wg.Add(tt.wantReloads) 89 90 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 91 defer cancel() 92 reloadCount := 0 93 configReloadTime := 500 * time.Millisecond 94 err = PathContentReloader(ctx, pathContent, log.NewLogfmtLogger(os.Stdout), func() { 95 reloadCount++ 96 wg.Done() 97 }, configReloadTime) 98 testutil.Ok(t, err) 99 // wait for the initial reload 100 testutil.NotOk(t, runutil.Repeat(configReloadTime, ctx.Done(), func() error { 101 if reloadCount != 1 { 102 return nil 103 } 104 return errors.New("reload count matched") 105 })) 106 107 tt.args.runSteps(t, testFile, pathContent, configReloadTime) 108 wg.Wait() 109 110 // wait for final reload 111 testutil.NotOk(t, runutil.Repeat(2*configReloadTime, ctx.Done(), func() error { 112 if reloadCount != tt.wantReloads { 113 return nil 114 } 115 return errors.New("reload count matched") 116 })) 117 }) 118 } 119 }