@@ -276,3 +276,251 @@ func (s *confdbHandlerSuite) TestDatabagMultipleSetsAndAccounts(c *C) {
276276 },
277277 })
278278}
279+
280+ func (s * confdbHandlerSuite ) TestUpdateEntireValidationSet (c * C ) {
281+ s .st .Lock ()
282+ defer s .st .Unlock ()
283+
284+ assertstate .UpdateValidationSet (s .st , & assertstate.ValidationSetTracking {
285+ AccountID : "my-account" ,
286+ Name : "my-set" ,
287+ Mode : assertstate .Monitor ,
288+ Current : 1 ,
289+ })
290+
291+ tx , err := confdbstate .NewTransaction (s .st , "system" , "validation-sets" )
292+ c .Assert (err , IsNil )
293+
294+ // set the entire validation set map
295+ err = s .view .Set (tx , "my-account.my-set" , map [string ]any {"mode" : "enforce" , "pinned-sequence" : 5 })
296+ c .Assert (err , IsNil )
297+
298+ handler := & assertstateconfdb.ValsetsConfdbHandler {}
299+ _ , err = handler .Commit (s .st , tx )
300+ c .Assert (err , IsNil )
301+
302+ var tr assertstate.ValidationSetTracking
303+ err = assertstate .GetValidationSet (s .st , "my-account" , "my-set" , & tr )
304+ c .Assert (err , IsNil )
305+ c .Check (tr .Mode , Equals , assertstate .Enforce )
306+ c .Check (tr .PinnedAt , Equals , 5 )
307+ }
308+
309+ func (s * confdbHandlerSuite ) TestCommitUpdatesOnlyMode (c * C ) {
310+ s .st .Lock ()
311+ defer s .st .Unlock ()
312+
313+ assertstate .UpdateValidationSet (s .st , & assertstate.ValidationSetTracking {
314+ AccountID : "my-account" ,
315+ Name : "my-set" ,
316+ Mode : assertstate .Enforce ,
317+ PinnedAt : 3 ,
318+ Current : 1 ,
319+ })
320+
321+ tx , err := confdbstate .NewTransaction (s .st , "system" , "validation-sets" )
322+ c .Assert (err , IsNil )
323+
324+ // set specific path and check other data isn't affected
325+ err = s .view .Set (tx , "my-account.my-set.mode" , "monitor" )
326+ c .Assert (err , IsNil )
327+
328+ handler := & assertstateconfdb.ValsetsConfdbHandler {}
329+ _ , err = handler .Commit (s .st , tx )
330+ c .Assert (err , IsNil )
331+
332+ var tr assertstate.ValidationSetTracking
333+ err = assertstate .GetValidationSet (s .st , "my-account" , "my-set" , & tr )
334+ c .Assert (err , IsNil )
335+ c .Check (tr .Mode , Equals , assertstate .Monitor )
336+ c .Check (tr .PinnedAt , Equals , 3 )
337+
338+ // if we set the entire validation set map without pinned-sequence, it's removed
339+ tx , err = confdbstate .NewTransaction (s .st , "system" , "validation-sets" )
340+ c .Assert (err , IsNil )
341+
342+ err = s .view .Set (tx , "my-account.my-set" , map [string ]any {"mode" : "enforce" })
343+ c .Assert (err , IsNil )
344+
345+ _ , err = handler .Commit (s .st , tx )
346+ c .Assert (err , IsNil )
347+
348+ err = assertstate .GetValidationSet (s .st , "my-account" , "my-set" , & tr )
349+ c .Assert (err , IsNil )
350+ c .Check (tr .Mode , Equals , assertstate .Enforce )
351+ c .Check (tr .PinnedAt , Equals , 0 )
352+ }
353+
354+ func (s * confdbHandlerSuite ) TestCommitUnsetsPinnedSequence (c * C ) {
355+ s .st .Lock ()
356+ defer s .st .Unlock ()
357+
358+ assertstate .UpdateValidationSet (s .st , & assertstate.ValidationSetTracking {
359+ AccountID : "my-account" ,
360+ Name : "my-set" ,
361+ Mode : assertstate .Enforce ,
362+ PinnedAt : 7 ,
363+ Current : 1 ,
364+ })
365+
366+ tx , err := confdbstate .NewTransaction (s .st , "system" , "validation-sets" )
367+ c .Assert (err , IsNil )
368+
369+ // unset part of the data
370+ err = s .view .Unset (tx , "my-account.my-set.pinned-sequence" )
371+ c .Assert (err , IsNil )
372+
373+ handler := & assertstateconfdb.ValsetsConfdbHandler {}
374+ _ , err = handler .Commit (s .st , tx )
375+ c .Assert (err , IsNil )
376+
377+ var tr assertstate.ValidationSetTracking
378+ err = assertstate .GetValidationSet (s .st , "my-account" , "my-set" , & tr )
379+ c .Assert (err , IsNil )
380+ c .Check (tr .Mode , Equals , assertstate .Enforce )
381+ c .Check (tr .PinnedAt , Equals , 0 )
382+ }
383+
384+ func (s * confdbHandlerSuite ) TestCannotUnsetMode (c * C ) {
385+ s .st .Lock ()
386+ defer s .st .Unlock ()
387+
388+ assertstate .UpdateValidationSet (s .st , & assertstate.ValidationSetTracking {
389+ AccountID : "my-account" ,
390+ Name : "my-set" ,
391+ Mode : assertstate .Enforce ,
392+ PinnedAt : 7 ,
393+ Current : 1 ,
394+ })
395+
396+ tx , err := confdbstate .NewTransaction (s .st , "system" , "validation-sets" )
397+ c .Assert (err , IsNil )
398+
399+ val , err := s .view .Get (tx , "my-account.my-set.mode" , nil , confdb .AdminAccess )
400+ c .Assert (err , IsNil )
401+ c .Assert (val , Equals , "enforce" )
402+
403+ err = s .view .Set (tx , "my-account.my-set" , map [string ]any {
404+ "pinned-sequence" : 5 ,
405+ })
406+ c .Assert (err , ErrorMatches , `.*cannot find required combinations of keys` )
407+
408+ // unsetting mode fails because the storage schema marks it as required
409+ err = s .view .Unset (tx , "my-account.my-set.mode" )
410+ c .Assert (err , ErrorMatches , `.*cannot find required combinations of keys` )
411+ }
412+
413+ func (s * confdbHandlerSuite ) TestCommitForgetsDeletedValidationSet (c * C ) {
414+ s .st .Lock ()
415+ defer s .st .Unlock ()
416+
417+ assertstate .UpdateValidationSet (s .st , & assertstate.ValidationSetTracking {
418+ AccountID : "my-account" ,
419+ Name : "my-set" ,
420+ Mode : assertstate .Monitor ,
421+ Current : 1 ,
422+ })
423+
424+ tx , err := confdbstate .NewTransaction (s .st , "system" , "validation-sets" )
425+ c .Assert (err , IsNil )
426+
427+ // unset through confdb
428+ err = s .view .Unset (tx , "my-account.my-set" )
429+ c .Assert (err , IsNil )
430+
431+ handler := & assertstateconfdb.ValsetsConfdbHandler {}
432+ _ , err = handler .Commit (s .st , tx )
433+ c .Assert (err , IsNil )
434+
435+ // check it was deleted from state
436+ var tr assertstate.ValidationSetTracking
437+ err = assertstate .GetValidationSet (s .st , "my-account" , "my-set" , & tr )
438+ c .Assert (err , testutil .ErrorIs , state .ErrNoState )
439+ }
440+
441+ func (s * confdbHandlerSuite ) TestCommitRejectsUnsupportedStorageVersion (c * C ) {
442+ s .st .Lock ()
443+ defer s .st .Unlock ()
444+
445+ tx , err := confdbstate .NewTransaction (s .st , "system" , "validation-sets" )
446+ c .Assert (err , IsNil )
447+
448+ path , err := confdb .ParsePathIntoAccessors ("v2.my-account.my-set.mode" , confdb.ParseOptions {})
449+ c .Assert (err , IsNil )
450+ err = tx .Set (path , "enforce" )
451+ c .Assert (err , IsNil )
452+
453+ handler := & assertstateconfdb.ValsetsConfdbHandler {}
454+ _ , err = handler .Commit (s .st , tx )
455+ c .Assert (err , ErrorMatches , `internal error: cannot write to system/validation-sets: unsupported storage version "v2"` )
456+ }
457+
458+ func (s * confdbHandlerSuite ) TestCommitMultipleSetsAcrossAccounts (c * C ) {
459+ s .st .Lock ()
460+ defer s .st .Unlock ()
461+
462+ s .addValidationSetAssert (c , "acct1" , "set-a" , 1 , nil )
463+ assertstate .UpdateValidationSet (s .st , & assertstate.ValidationSetTracking {
464+ AccountID : "acct1" ,
465+ Name : "set-a" ,
466+ Mode : assertstate .Monitor ,
467+ Current : 1 ,
468+ })
469+ s .addValidationSetAssert (c , "acct1" , "set-b" , 1 , nil )
470+ assertstate .UpdateValidationSet (s .st , & assertstate.ValidationSetTracking {
471+ AccountID : "acct1" ,
472+ Name : "set-b" ,
473+ Mode : assertstate .Enforce ,
474+ PinnedAt : 1 ,
475+ Current : 1 ,
476+ })
477+ s .addValidationSetAssert (c , "acct2" , "set-c" , 1 , nil )
478+ assertstate .UpdateValidationSet (s .st , & assertstate.ValidationSetTracking {
479+ AccountID : "acct2" ,
480+ Name : "set-c" ,
481+ Mode : assertstate .Enforce ,
482+ PinnedAt : 2 ,
483+ Current : 1 ,
484+ })
485+
486+ tx , err := confdbstate .NewTransaction (s .st , "system" , "validation-sets" )
487+ c .Assert (err , IsNil )
488+
489+ err = s .view .Set (tx , "acct1.set-a" , map [string ]any {
490+ "mode" : "enforce" ,
491+ "pinned-sequence" : 10 ,
492+ })
493+ c .Assert (err , IsNil )
494+ err = s .view .Set (tx , "acct1.set-b" , map [string ]any {
495+ "mode" : "monitor" ,
496+ "pinned-sequence" : 1 ,
497+ })
498+ c .Assert (err , IsNil )
499+ err = s .view .Set (tx , "acct2.set-c" , map [string ]any {
500+ "mode" : "monitor" ,
501+ "pinned-sequence" : 2 ,
502+ })
503+ c .Assert (err , IsNil )
504+
505+ handler := & assertstateconfdb.ValsetsConfdbHandler {}
506+ _ , err = handler .Commit (s .st , tx )
507+ c .Assert (err , IsNil )
508+
509+ for _ , tc := range []struct {
510+ account string
511+ name string
512+ mode assertstate.ValidationSetMode
513+ pin int
514+ }{
515+ {account : "acct1" , name : "set-a" , mode : assertstate .Enforce , pin : 10 },
516+ {account : "acct1" , name : "set-b" , mode : assertstate .Monitor , pin : 1 },
517+ {account : "acct2" , name : "set-c" , mode : assertstate .Monitor , pin : 2 },
518+ } {
519+ var tr assertstate.ValidationSetTracking
520+ err = assertstate .GetValidationSet (s .st , tc .account , tc .name , & tr )
521+ c .Assert (err , IsNil )
522+ c .Check (tr .Mode , Equals , tc .mode )
523+ c .Check (tr .Current , Equals , 1 )
524+ c .Check (tr .PinnedAt , Equals , tc .pin )
525+ }
526+ }
0 commit comments