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  }