github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/ruler/storage/instance/manager_test.go (about) 1 // This directory was copied and adapted from https://github.com/grafana/agent/tree/main/pkg/metrics. 2 // We cannot vendor the agent in since the agent vendors loki in, which would cause a cyclic dependency. 3 // NOTE: many changes have been made to the original code for our use-case. 4 package instance 5 6 import ( 7 "context" 8 "fmt" 9 "os" 10 "testing" 11 12 "github.com/go-kit/log" 13 "github.com/prometheus/prometheus/scrape" 14 "github.com/prometheus/prometheus/storage" 15 "github.com/stretchr/testify/require" 16 ) 17 18 func TestBasicManager_ApplyConfig(t *testing.T) { 19 logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) 20 21 baseMock := mockInstance{ 22 RunFunc: func(ctx context.Context) error { 23 logger.Log("msg", "starting an instance") 24 <-ctx.Done() 25 return nil 26 }, 27 UpdateFunc: func(c Config) error { 28 return nil 29 }, 30 TargetsActiveFunc: func() map[string][]*scrape.Target { 31 return nil 32 }, 33 } 34 35 t.Run("dynamic update successful", func(t *testing.T) { 36 spawnedCount := 0 37 spawner := func(c Config) (ManagedInstance, error) { 38 spawnedCount++ 39 40 newMock := baseMock 41 return &newMock, nil 42 } 43 44 cm := NewBasicManager(DefaultBasicManagerConfig, NewMetrics(nil), logger, spawner) 45 46 for i := 0; i < 10; i++ { 47 err := cm.ApplyConfig(Config{Name: "test"}) 48 require.NoError(t, err) 49 } 50 51 require.Equal(t, 1, spawnedCount) 52 }) 53 54 t.Run("dynamic update unsuccessful", func(t *testing.T) { 55 spawnedCount := 0 56 spawner := func(c Config) (ManagedInstance, error) { 57 spawnedCount++ 58 59 newMock := baseMock 60 newMock.UpdateFunc = func(c Config) error { 61 return ErrInvalidUpdate{ 62 Inner: fmt.Errorf("cannot dynamically update for testing reasons"), 63 } 64 } 65 return &newMock, nil 66 } 67 68 cm := NewBasicManager(DefaultBasicManagerConfig, NewMetrics(nil), logger, spawner) 69 70 for i := 0; i < 10; i++ { 71 err := cm.ApplyConfig(Config{Name: "test"}) 72 require.NoError(t, err) 73 } 74 75 require.Equal(t, 10, spawnedCount) 76 }) 77 78 t.Run("dynamic update errored", func(t *testing.T) { 79 spawnedCount := 0 80 spawner := func(c Config) (ManagedInstance, error) { 81 spawnedCount++ 82 83 newMock := baseMock 84 newMock.UpdateFunc = func(c Config) error { 85 return fmt.Errorf("something really bad happened") 86 } 87 return &newMock, nil 88 } 89 90 cm := NewBasicManager(DefaultBasicManagerConfig, NewMetrics(nil), logger, spawner) 91 92 // Creation should succeed 93 err := cm.ApplyConfig(Config{Name: "test"}) 94 require.NoError(t, err) 95 96 // ...but the update should fail 97 err = cm.ApplyConfig(Config{Name: "test"}) 98 require.Error(t, err, "something really bad happened") 99 require.Equal(t, 1, spawnedCount) 100 }) 101 } 102 103 type mockInstance struct { 104 RunFunc func(ctx context.Context) error 105 UpdateFunc func(c Config) error 106 TargetsActiveFunc func() map[string][]*scrape.Target 107 StorageDirectoryFunc func() string 108 AppenderFunc func() storage.Appender 109 } 110 111 func (m mockInstance) Ready() bool { 112 return true 113 } 114 115 func (m mockInstance) Stop() error { 116 return nil 117 } 118 119 func (m mockInstance) Tenant() string { 120 return "" 121 } 122 123 func (m mockInstance) Run(ctx context.Context) error { 124 if m.RunFunc != nil { 125 return m.RunFunc(ctx) 126 } 127 panic("RunFunc not provided") 128 } 129 130 func (m mockInstance) Update(c Config) error { 131 if m.UpdateFunc != nil { 132 return m.UpdateFunc(c) 133 } 134 panic("UpdateFunc not provided") 135 } 136 137 func (m mockInstance) TargetsActive() map[string][]*scrape.Target { 138 if m.TargetsActiveFunc != nil { 139 return m.TargetsActiveFunc() 140 } 141 panic("TargetsActiveFunc not provided") 142 } 143 144 func (m mockInstance) StorageDirectory() string { 145 if m.StorageDirectoryFunc != nil { 146 return m.StorageDirectoryFunc() 147 } 148 panic("StorageDirectoryFunc not provided") 149 } 150 151 func (m mockInstance) Appender(_ context.Context) storage.Appender { 152 if m.AppenderFunc != nil { 153 return m.AppenderFunc() 154 } 155 panic("AppenderFunc not provided") 156 }