config_test.go (5378B)
1 /* 2 GoToSocial 3 Copyright (C) 2022 GoToSocial Authors admin@gotosocial.org 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU Affero General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU Affero General Public License for more details. 14 15 You should have received a copy of the GNU Affero General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 package config_test 20 21 import ( 22 "os" 23 "strings" 24 "testing" 25 26 "github.com/spf13/cobra" 27 "github.com/spf13/viper" 28 "github.com/stretchr/testify/assert" 29 "github.com/superseriousbusiness/gotosocial/internal/config" 30 "gopkg.in/yaml.v3" 31 ) 32 33 func expectedKV(kvpairs ...string) map[string]interface{} { 34 ret := make(map[string]interface{}, len(kvpairs)/2) 35 36 for i := 0; i < len(kvpairs)-1; i += 2 { 37 ret[kvpairs[i]] = kvpairs[i+1] 38 } 39 40 return ret 41 } 42 43 func expectedFile(t *testing.T, file string) map[string]interface{} { 44 expectedConfig, err := os.ReadFile(file) 45 if err != nil { 46 t.Errorf("error reading expected config from file %q: %v", file, err) 47 } 48 49 var ret map[string]interface{} 50 if err := yaml.Unmarshal(expectedConfig, &ret); err != nil { 51 t.Errorf("error parsing expected config from file %q: %v", file, err) 52 } 53 54 return ret 55 } 56 57 func TestCLIParsing(t *testing.T) { 58 type testcase struct { 59 cli []string 60 env []string 61 expected map[string]interface{} 62 } 63 64 defaults, _ := config.Defaults.MarshalMap() 65 66 testcases := map[string]testcase{ 67 "Make sure defaults are set correctly": { 68 expected: defaults, 69 }, 70 71 "Override db-address from default using cli flag": { 72 cli: []string{ 73 "--db-address", "some.db.address", 74 }, 75 expected: expectedKV( 76 "db-address", "some.db.address", 77 ), 78 }, 79 80 "Override db-address from default using env var": { 81 env: []string{ 82 "GTS_DB_ADDRESS=some.db.address", 83 }, 84 expected: expectedKV( 85 "db-address", "some.db.address", 86 ), 87 }, 88 89 "Override db-address from default using both env var and cli flag. The cli flag should take priority": { 90 cli: []string{ 91 "--db-address", "some.db.address", 92 }, 93 env: []string{ 94 "GTS_DB_ADDRESS=some.other.db.address", 95 }, 96 expected: expectedKV( 97 "db-address", "some.db.address", 98 ), 99 }, 100 101 "Loading a config file via env var": { 102 env: []string{ 103 "GTS_CONFIG_PATH=testdata/test.yaml", 104 }, 105 expected: expectedFile(t, "testdata/test.yaml"), 106 }, 107 108 "Loading a config file via cli flag": { 109 cli: []string{ 110 "--config-path", "testdata/test.yaml", 111 }, 112 expected: expectedFile(t, "testdata/test.yaml"), 113 }, 114 115 "Loading a config file and overriding one of the variables with a cli flag": { 116 cli: []string{ 117 "--config-path", "testdata/test.yaml", 118 "--account-domain", "my.test.domain", 119 }, 120 // only checking our overridden one and one non-default from the config file here instead of including all of test.yaml 121 expected: expectedKV( 122 "account-domain", "my.test.domain", 123 "host", "gts.example.org", 124 ), 125 }, 126 127 "Loading a config file and overriding one of the variables with an env var": { 128 cli: []string{ 129 "--config-path", "testdata/test.yaml", 130 }, 131 env: []string{ 132 "GTS_ACCOUNT_DOMAIN=my.test.domain", 133 }, 134 // only checking our overridden one and one non-default from the config file here instead of including all of test.yaml 135 expected: expectedKV( 136 "account-domain", "my.test.domain", 137 "host", "gts.example.org", 138 ), 139 }, 140 141 "Loading a config file and overriding one of the variables with both an env var and a cli flag. The cli flag should have priority": { 142 cli: []string{ 143 "--config-path", "testdata/test.yaml", 144 "--account-domain", "my.test.domain", 145 }, 146 env: []string{ 147 "GTS_ACCOUNT_DOMAIN=my.wrong.test.domain", 148 }, 149 // only checking our overridden one and one non-default from the config file here instead of including all of test.yaml 150 expected: expectedKV( 151 "account-domain", "my.test.domain", 152 "host", "gts.example.org", 153 ), 154 }, 155 156 "Loading a config file from json": { 157 cli: []string{ 158 "--config-path", "testdata/test.json", 159 }, 160 expected: expectedFile(t, "testdata/test.json"), 161 }, 162 163 "Loading a partial config file. Default values should be used apart from those set in the config file": { 164 cli: []string{ 165 "--config-path", "testdata/test2.yaml", 166 }, 167 expected: expectedKV( 168 "log-level", "trace", 169 "account-domain", "peepee.poopoo", 170 "application-name", "gotosocial", 171 ), 172 }, 173 } 174 175 for desc, data := range testcases { 176 t.Run(desc, func(t *testing.T) { 177 os.Clearenv() 178 179 if data.env != nil { 180 for _, s := range data.env { 181 kv := strings.SplitN(s, "=", 2) 182 os.Setenv(kv[0], kv[1]) 183 } 184 } 185 186 state := config.NewState() 187 cmd := cobra.Command{} 188 state.AddGlobalFlags(&cmd) 189 state.AddServerFlags(&cmd) 190 191 if data.cli != nil { 192 cmd.ParseFlags(data.cli) 193 } 194 195 state.BindFlags(&cmd) 196 197 state.Reload() 198 199 state.Viper(func(v *viper.Viper) { 200 for k, ev := range data.expected { 201 assert.EqualValues(t, ev, v.Get(k)) 202 } 203 }) 204 }) 205 } 206 }