github.com/outbrain/consul@v1.4.5/agent/structs/service_definition_test.go (about) 1 package structs 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 "testing" 8 "time" 9 10 "github.com/pascaldekloe/goe/verify" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestAgentStructs_CheckTypes(t *testing.T) { 15 t.Parallel() 16 svc := new(ServiceDefinition) 17 18 // Singular Check field works 19 svc.Check = CheckType{ 20 ScriptArgs: []string{"/foo/bar"}, 21 Interval: 10 * time.Second, 22 } 23 24 // Returns HTTP checks 25 svc.Checks = append(svc.Checks, &CheckType{ 26 HTTP: "http://foo/bar", 27 Interval: 10 * time.Second, 28 }) 29 30 // Returns Script checks 31 svc.Checks = append(svc.Checks, &CheckType{ 32 ScriptArgs: []string{"/foo/bar"}, 33 Interval: 10 * time.Second, 34 }) 35 36 // Returns TTL checks 37 svc.Checks = append(svc.Checks, &CheckType{ 38 TTL: 10 * time.Second, 39 }) 40 41 // Validate checks 42 cases := []struct { 43 in *CheckType 44 err error 45 desc string 46 }{ 47 {&CheckType{HTTP: "http://foo/baz"}, fmt.Errorf("Interval must be > 0 for Script, HTTP, or TCP checks"), "Missing interval"}, 48 {&CheckType{TTL: -1}, fmt.Errorf("TTL must be > 0 for TTL checks"), "Negative TTL"}, 49 {&CheckType{TTL: 20 * time.Second, Interval: 10 * time.Second}, fmt.Errorf("Interval and TTL cannot both be specified"), "Interval and TTL both set"}, 50 } 51 for _, tc := range cases { 52 svc.Check = *tc.in 53 checks, err := svc.CheckTypes() 54 verify.Values(t, tc.desc, err.Error(), tc.err.Error()) 55 if len(checks) != 0 { 56 t.Fatalf("bad: %#v", svc) 57 } 58 } 59 } 60 61 func TestServiceDefinitionValidate(t *testing.T) { 62 cases := []struct { 63 Name string 64 Modify func(*ServiceDefinition) 65 Err string 66 }{ 67 { 68 "valid", 69 func(x *ServiceDefinition) {}, 70 "", 71 }, 72 73 { 74 "managed proxy with a port set", 75 func(x *ServiceDefinition) { 76 x.Port = 8080 77 x.Connect = &ServiceConnect{ 78 Proxy: &ServiceDefinitionConnectProxy{}, 79 } 80 }, 81 "", 82 }, 83 84 { 85 "managed proxy with no port set", 86 func(x *ServiceDefinition) { 87 x.Port = 0 // Explicitly unset this as the test default sets it sanely 88 x.Connect = &ServiceConnect{ 89 Proxy: &ServiceDefinitionConnectProxy{}, 90 } 91 }, 92 "must have a port", 93 }, 94 95 { 96 "managed proxy with native set", 97 func(x *ServiceDefinition) { 98 x.Port = 8080 99 x.Connect = &ServiceConnect{ 100 Native: true, 101 Proxy: &ServiceDefinitionConnectProxy{}, 102 } 103 }, 104 "may not have a proxy", 105 }, 106 } 107 108 for _, tc := range cases { 109 t.Run(tc.Name, func(t *testing.T) { 110 require := require.New(t) 111 service := TestServiceDefinition(t) 112 tc.Modify(service) 113 114 err := service.Validate() 115 if tc.Err == "" { 116 require.NoError(err) 117 } else { 118 require.Error(err) 119 require.Contains(strings.ToLower(err.Error()), strings.ToLower(tc.Err)) 120 } 121 }) 122 } 123 } 124 125 func TestServiceDefinitionConnectProxy_json(t *testing.T) { 126 cases := []struct { 127 Name string 128 Input *ServiceDefinitionConnectProxy 129 Expected string 130 Err string 131 }{ 132 { 133 "no config", 134 &ServiceDefinitionConnectProxy{ 135 Command: []string{"foo"}, 136 ExecMode: "bar", 137 }, 138 ` 139 { 140 "Command": [ 141 "foo" 142 ], 143 "ExecMode": "bar" 144 } 145 `, 146 "", 147 }, 148 149 { 150 "basic config", 151 &ServiceDefinitionConnectProxy{ 152 Config: map[string]interface{}{ 153 "foo": "bar", 154 }, 155 }, 156 ` 157 { 158 "Config": { 159 "foo": "bar" 160 } 161 } 162 `, 163 "", 164 }, 165 166 { 167 "config with upstreams", 168 &ServiceDefinitionConnectProxy{ 169 Config: map[string]interface{}{ 170 "upstreams": []interface{}{ 171 map[interface{}]interface{}{ 172 "key": []byte("value"), 173 }, 174 }, 175 }, 176 }, 177 ` 178 { 179 "Config": { 180 "upstreams": [ 181 { 182 "key": "value" 183 } 184 ] 185 } 186 } 187 `, 188 "", 189 }, 190 } 191 192 for _, tc := range cases { 193 t.Run(tc.Name, func(t *testing.T) { 194 require := require.New(t) 195 result, err := json.MarshalIndent(tc.Input, "", "\t") 196 t.Logf("error: %s", err) 197 require.Equal(err != nil, tc.Err != "") 198 if err != nil { 199 require.Contains(strings.ToLower(err.Error()), strings.ToLower(tc.Err)) 200 return 201 } 202 203 require.Equal(strings.TrimSpace(tc.Expected), strings.TrimSpace(string(result))) 204 }) 205 } 206 }