gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }