github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/module/updatable_configs/manager_test.go (about) 1 package updatable_configs_test 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/stretchr/testify/assert" 8 "github.com/stretchr/testify/require" 9 "google.golang.org/protobuf/types/known/structpb" 10 11 "github.com/onflow/flow-go/model/flow" 12 "github.com/onflow/flow-go/module/updatable_configs" 13 "github.com/onflow/flow-go/module/util" 14 "github.com/onflow/flow-go/utils/unittest" 15 ) 16 17 func TestRegisterDuplicateConfig(t *testing.T) { 18 mgr := updatable_configs.NewManager() 19 20 // should be able to register a config the first time 21 err := mgr.RegisterBoolConfig("field", 22 func() bool { return true }, 23 func(_ bool) error { return nil }) 24 require.NoError(t, err) 25 26 // should fail to register the same field name again, regardless of type 27 err = mgr.RegisterUintConfig("field", 28 func() uint { return 0 }, 29 func(_ uint) error { return nil }) 30 assert.ErrorIs(t, err, updatable_configs.ErrAlreadyRegistered) 31 } 32 33 func TestManager_RegisterBoolConfig(t *testing.T) { 34 mgr := updatable_configs.NewManager() 35 36 // should be able to register config 37 fieldSet := make(chan struct{}) // closed when field is successfully set 38 err := mgr.RegisterBoolConfig("field", 39 func() bool { return true }, 40 func(_ bool) error { close(fieldSet); return nil }) 41 require.NoError(t, err) 42 43 // should be able to get the field 44 field, ok := mgr.GetField("field") 45 assert.True(t, ok) 46 // field must be parseable by structpb (otherwise admin server will error) 47 _, err = structpb.NewValue(field.Get()) 48 require.NoError(t, err) 49 50 // should fail to set incorrect type 51 err = field.Set(struct{}{}) 52 assert.Error(t, err) 53 assert.True(t, updatable_configs.IsValidationError(err)) 54 55 // should succeed setting correct type 56 err = field.Set(true) 57 assert.NoError(t, err) 58 assert.True(t, util.CheckClosed(fieldSet)) 59 } 60 61 func TestManager_RegisterUintConfig(t *testing.T) { 62 mgr := updatable_configs.NewManager() 63 64 // should be able to register config 65 fieldSet := make(chan struct{}) // closed when field is successfully set 66 err := mgr.RegisterUintConfig("field", 67 func() uint { return 0 }, 68 func(_ uint) error { close(fieldSet); return nil }) 69 require.NoError(t, err) 70 71 // should be able to get the field 72 field, ok := mgr.GetField("field") 73 assert.True(t, ok) 74 // field must be parseable by structpb (otherwise admin server will error) 75 _, err = structpb.NewValue(field.Get()) 76 require.NoError(t, err) 77 78 // should fail to set incorrect type 79 err = field.Set(struct{}{}) 80 assert.Error(t, err) 81 assert.True(t, updatable_configs.IsValidationError(err)) 82 83 // should succeed setting correct type 84 err = field.Set(float64(1)) // JSON uints parse to float64 85 assert.NoError(t, err) 86 assert.True(t, util.CheckClosed(fieldSet)) 87 } 88 89 func TestManager_RegisterDurationConfig(t *testing.T) { 90 mgr := updatable_configs.NewManager() 91 92 // should be able to register config 93 fieldSet := make(chan struct{}) // closed when field is successfully set 94 err := mgr.RegisterDurationConfig("field", 95 func() time.Duration { return time.Second }, 96 func(_ time.Duration) error { close(fieldSet); return nil }) 97 require.NoError(t, err) 98 99 // should be able to get the field 100 field, ok := mgr.GetField("field") 101 assert.True(t, ok) 102 // field must be parseable by structpb (otherwise admin server will error) 103 _, err = structpb.NewValue(field.Get()) 104 require.NoError(t, err) 105 106 // should fail to set incorrect type 107 err = field.Set(struct{}{}) 108 assert.Error(t, err) 109 assert.True(t, updatable_configs.IsValidationError(err)) 110 // should fail to set with correct type, but unparseable 111 err = field.Set("not a parseable duration string") 112 assert.Error(t, err) 113 assert.True(t, updatable_configs.IsValidationError(err)) 114 115 // should succeed setting correct type 116 err = field.Set("1h") 117 assert.NoError(t, err) 118 assert.True(t, util.CheckClosed(fieldSet)) 119 } 120 121 func TestManager_RegisterIdentifierListConfig(t *testing.T) { 122 mgr := updatable_configs.NewManager() 123 124 // should be able to register config 125 fieldSet := make(chan struct{}) // closed when field is successfully set 126 err := mgr.RegisterIdentifierListConfig("field", 127 func() flow.IdentifierList { return nil }, 128 func(_ flow.IdentifierList) error { close(fieldSet); return nil }) 129 require.NoError(t, err) 130 131 // should be able to get the field 132 field, ok := mgr.GetField("field") 133 assert.True(t, ok) 134 // field must be parseable by structpb (otherwise admin server will error) 135 _, err = structpb.NewValue(field.Get()) 136 require.NoError(t, err) 137 138 // should fail to set incorrect type 139 err = field.Set(struct{}{}) 140 assert.Error(t, err) 141 assert.True(t, updatable_configs.IsValidationError(err)) 142 // should fail to set with correct type, but un-parseable 143 err = field.Set([]string{"un-parseable"}) 144 assert.Error(t, err) 145 assert.True(t, updatable_configs.IsValidationError(err)) 146 err = field.Set([]string{unittest.IdentifierFixture().String(), "un-parseable"}) 147 assert.Error(t, err) 148 assert.True(t, updatable_configs.IsValidationError(err)) 149 150 // should succeed setting correct type 151 err = field.Set(util.DetypeSlice(unittest.IdentifierListFixture(5).Strings())) 152 assert.NoError(t, err) 153 assert.True(t, util.CheckClosed(fieldSet)) 154 }