package proxy import ( "reflect" "testing" "github.com/mholt/caddy" "github.com/mholt/caddy/caddyhttp/httpserver" ) func TestSetup(t *testing.T) { for i, test := range []struct { input string shouldErr bool expectedHosts map[string]struct{} }{ // test #0 test usual to destination still works normally { "proxy / localhost:80", false, map[string]struct{}{ "http://localhost:80": {}, }, }, // test #1 test usual to destination with port range { "proxy / localhost:8080-8082", false, map[string]struct{}{ "http://localhost:8080": {}, "http://localhost:8081": {}, "http://localhost:8082": {}, }, }, // test #2 test upstream directive { "proxy / {\n upstream localhost:8080\n}", false, map[string]struct{}{ "http://localhost:8080": {}, }, }, // test #3 test upstream directive with port range { "proxy / {\n upstream localhost:8080-8081\n}", false, map[string]struct{}{ "http://localhost:8080": {}, "http://localhost:8081": {}, }, }, // test #4 test to destination with upstream directive { "proxy / localhost:8080 {\n upstream localhost:8081-8082\n}", false, map[string]struct{}{ "http://localhost:8080": {}, "http://localhost:8081": {}, "http://localhost:8082": {}, }, }, // test #5 test with unix sockets { "proxy / localhost:8080 {\n upstream unix:/var/foo\n}", false, map[string]struct{}{ "http://localhost:8080": {}, "unix:/var/foo": {}, }, }, // test #6 test fail on malformed port range { "proxy / localhost:8090-8080", true, nil, }, // test #7 test fail on malformed port range 2 { "proxy / {\n upstream localhost:80-A\n}", true, nil, }, // test #8 test upstreams without ports work correctly { "proxy / http://localhost {\n upstream testendpoint\n}", false, map[string]struct{}{ "http://localhost": {}, "http://testendpoint": {}, }, }, // test #9 test several upstream directives { "proxy / localhost:8080 {\n upstream localhost:8081-8082\n upstream localhost:8083-8085\n}", false, map[string]struct{}{ "http://localhost:8080": {}, "http://localhost:8081": {}, "http://localhost:8082": {}, "http://localhost:8083": {}, "http://localhost:8084": {}, "http://localhost:8085": {}, }, }, // test #10 test hyphen without port range { "proxy / http://localhost:8001/a--b", false, map[string]struct{}{ "http://localhost:8001/a--b": {}, }, }, // test #11 test hyphen with port range { "proxy / http://localhost:8001-8005/a--b", false, map[string]struct{}{ "http://localhost:8001/a--b": {}, "http://localhost:8002/a--b": {}, "http://localhost:8003/a--b": {}, "http://localhost:8004/a--b": {}, "http://localhost:8005/a--b": {}, }, }, // test #12 test value is optional when remove upstream header { "proxy / localhost:1984 {\n header_upstream -server \n}", false, map[string]struct{}{ "http://localhost:1984": {}, }, }, // test #13 test value is optional when remove downstream header { "proxy / localhost:1984 {\n header_downstream -server \n}", false, map[string]struct{}{ "http://localhost:1984": {}, }, }, // test #14 test QUIC { "proxy / quic://localhost:443", false, map[string]struct{}{ "quic://localhost:443": {}, }, }, } { c := caddy.NewTestController("http", test.input) err := setup(c) if err != nil && !test.shouldErr { t.Errorf("Test case #%d received an error of %v", i, err) } else if test.shouldErr { continue } mids := httpserver.GetConfig(c).Middleware() mid := mids[len(mids)-1] upstreams := mid(nil).(Proxy).Upstreams for _, upstream := range upstreams { val := reflect.ValueOf(upstream).Elem() hosts := val.FieldByName("Hosts").Interface().(HostPool) if len(hosts) != len(test.expectedHosts) { t.Errorf("Test case #%d expected %d hosts but received %d", i, len(test.expectedHosts), len(hosts)) } else { for _, host := range hosts { if _, found := test.expectedHosts[host.Name]; !found { t.Errorf("Test case #%d has an unexpected host %s", i, host.Name) } } } } } }