github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/ruler/store_mock_test.go (about) 1 package ruler 2 3 import ( 4 "context" 5 "encoding/base64" 6 "fmt" 7 "sync" 8 "time" 9 10 "github.com/cortexproject/cortex/pkg/ruler/rulespb" 11 "github.com/cortexproject/cortex/pkg/ruler/rulestore" 12 ) 13 14 type mockRuleStore struct { 15 rules map[string]rulespb.RuleGroupList 16 mtx sync.Mutex 17 } 18 19 var ( 20 delim = "/" 21 interval, _ = time.ParseDuration("1m") 22 mockRulesNamespaces = map[string]rulespb.RuleGroupList{ 23 "user1": { 24 &rulespb.RuleGroupDesc{ 25 Name: "group1", 26 Namespace: "namespace1", 27 User: "user1", 28 Rules: []*rulespb.RuleDesc{ 29 { 30 Record: "UP_RULE", 31 Expr: "up", 32 }, 33 { 34 Alert: "UP_ALERT", 35 Expr: "up < 1", 36 }, 37 }, 38 Interval: interval, 39 }, 40 &rulespb.RuleGroupDesc{ 41 Name: "fail", 42 Namespace: "namespace2", 43 User: "user1", 44 Rules: []*rulespb.RuleDesc{ 45 { 46 Record: "UP2_RULE", 47 Expr: "up", 48 }, 49 { 50 Alert: "UP2_ALERT", 51 Expr: "up < 1", 52 }, 53 }, 54 Interval: interval, 55 }, 56 }, 57 } 58 mockRules = map[string]rulespb.RuleGroupList{ 59 "user1": { 60 &rulespb.RuleGroupDesc{ 61 Name: "group1", 62 Namespace: "namespace1", 63 User: "user1", 64 Rules: []*rulespb.RuleDesc{ 65 { 66 Record: "UP_RULE", 67 Expr: "up", 68 }, 69 { 70 Alert: "UP_ALERT", 71 Expr: "up < 1", 72 }, 73 }, 74 Interval: interval, 75 }, 76 }, 77 "user2": { 78 &rulespb.RuleGroupDesc{ 79 Name: "group1", 80 Namespace: "namespace1", 81 User: "user2", 82 Rules: []*rulespb.RuleDesc{ 83 { 84 Record: "UP_RULE", 85 Expr: "up", 86 }, 87 }, 88 Interval: interval, 89 }, 90 }, 91 } 92 93 mockSpecialCharRules = map[string]rulespb.RuleGroupList{ 94 "user1": { 95 &rulespb.RuleGroupDesc{ 96 Name: ")(_+?/|group1+/?", 97 Namespace: ")(_+?/|namespace1+/?", 98 User: "user1", 99 Rules: []*rulespb.RuleDesc{ 100 { 101 Record: "UP_RULE", 102 Expr: "up", 103 }, 104 { 105 Alert: "UP_ALERT", 106 Expr: "up < 1", 107 }, 108 }, 109 Interval: interval, 110 }, 111 }, 112 } 113 ) 114 115 func newMockRuleStore(rules map[string]rulespb.RuleGroupList) *mockRuleStore { 116 return &mockRuleStore{ 117 rules: rules, 118 } 119 } 120 121 func (m *mockRuleStore) ListAllUsers(_ context.Context) ([]string, error) { 122 m.mtx.Lock() 123 defer m.mtx.Unlock() 124 125 var result []string 126 for u := range m.rules { 127 result = append(result, u) 128 } 129 return result, nil 130 } 131 132 func (m *mockRuleStore) ListAllRuleGroups(_ context.Context) (map[string]rulespb.RuleGroupList, error) { 133 m.mtx.Lock() 134 defer m.mtx.Unlock() 135 136 result := make(map[string]rulespb.RuleGroupList) 137 for k, v := range m.rules { 138 for _, r := range v { 139 result[k] = append(result[k], &rulespb.RuleGroupDesc{ 140 Namespace: r.Namespace, 141 Name: r.Name, 142 User: k, 143 Interval: r.Interval, 144 }) 145 } 146 } 147 148 return result, nil 149 } 150 151 func (m *mockRuleStore) ListRuleGroupsForUserAndNamespace(_ context.Context, userID, namespace string) (rulespb.RuleGroupList, error) { 152 m.mtx.Lock() 153 defer m.mtx.Unlock() 154 155 var result rulespb.RuleGroupList 156 for _, r := range m.rules[userID] { 157 if namespace != "" && namespace != r.Namespace { 158 continue 159 } 160 161 result = append(result, &rulespb.RuleGroupDesc{ 162 Namespace: r.Namespace, 163 Name: r.Name, 164 User: userID, 165 Interval: r.Interval, 166 }) 167 } 168 return result, nil 169 } 170 171 func (m *mockRuleStore) LoadRuleGroups(ctx context.Context, groupsToLoad map[string]rulespb.RuleGroupList) error { 172 m.mtx.Lock() 173 defer m.mtx.Unlock() 174 175 gm := make(map[string]*rulespb.RuleGroupDesc) 176 for _, gs := range m.rules { 177 for _, gr := range gs { 178 user, namespace, name := gr.GetUser(), gr.GetNamespace(), gr.GetName() 179 key := user + delim + base64.URLEncoding.EncodeToString([]byte(namespace)) + delim + base64.URLEncoding.EncodeToString([]byte(name)) 180 gm[key] = gr 181 } 182 } 183 184 for _, gs := range groupsToLoad { 185 for _, gr := range gs { 186 user, namespace, name := gr.GetUser(), gr.GetNamespace(), gr.GetName() 187 key := user + delim + base64.URLEncoding.EncodeToString([]byte(namespace)) + delim + base64.URLEncoding.EncodeToString([]byte(name)) 188 mgr, ok := gm[key] 189 if !ok { 190 return fmt.Errorf("failed to get rule group user %s", gr.GetUser()) 191 } 192 *gr = *mgr 193 } 194 } 195 return nil 196 } 197 198 func (m *mockRuleStore) GetRuleGroup(_ context.Context, userID string, namespace string, group string) (*rulespb.RuleGroupDesc, error) { 199 m.mtx.Lock() 200 defer m.mtx.Unlock() 201 202 userRules, exists := m.rules[userID] 203 if !exists { 204 return nil, rulestore.ErrUserNotFound 205 } 206 207 if namespace == "" { 208 return nil, rulestore.ErrGroupNamespaceNotFound 209 } 210 211 for _, rg := range userRules { 212 if rg.Namespace == namespace && rg.Name == group { 213 return rg, nil 214 } 215 } 216 217 return nil, rulestore.ErrGroupNotFound 218 } 219 220 func (m *mockRuleStore) SetRuleGroup(ctx context.Context, userID string, namespace string, group *rulespb.RuleGroupDesc) error { 221 m.mtx.Lock() 222 defer m.mtx.Unlock() 223 224 userRules, exists := m.rules[userID] 225 if !exists { 226 userRules = rulespb.RuleGroupList{} 227 m.rules[userID] = userRules 228 } 229 230 if namespace == "" { 231 return rulestore.ErrGroupNamespaceNotFound 232 } 233 234 for i, rg := range userRules { 235 if rg.Namespace == namespace && rg.Name == group.Name { 236 userRules[i] = group 237 return nil 238 } 239 } 240 241 m.rules[userID] = append(userRules, group) 242 return nil 243 } 244 245 func (m *mockRuleStore) DeleteRuleGroup(ctx context.Context, userID string, namespace string, group string) error { 246 m.mtx.Lock() 247 defer m.mtx.Unlock() 248 249 userRules, exists := m.rules[userID] 250 if !exists { 251 userRules = rulespb.RuleGroupList{} 252 m.rules[userID] = userRules 253 } 254 255 if namespace == "" { 256 return rulestore.ErrGroupNamespaceNotFound 257 } 258 259 for i, rg := range userRules { 260 if rg.Namespace == namespace && rg.Name == group { 261 m.rules[userID] = append(userRules[:i], userRules[:i+1]...) 262 return nil 263 } 264 } 265 266 return nil 267 } 268 269 func (m *mockRuleStore) DeleteNamespace(ctx context.Context, userID, namespace string) error { 270 m.mtx.Lock() 271 defer m.mtx.Unlock() 272 273 userRules, exists := m.rules[userID] 274 if !exists { 275 userRules = rulespb.RuleGroupList{} 276 m.rules[userID] = userRules 277 } 278 279 if namespace == "" { 280 return rulestore.ErrGroupNamespaceNotFound 281 } 282 283 for i, rg := range userRules { 284 if rg.Namespace == namespace { 285 286 // Only here to assert on partial failures. 287 if rg.Name == "fail" { 288 return fmt.Errorf("unable to delete rg") 289 } 290 291 m.rules[userID] = append(userRules[:i], userRules[i+1:]...) 292 } 293 } 294 295 return nil 296 }