1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package main
16
17 import (
18 "bytes"
19 "fmt"
20 "io/ioutil"
21 "net"
22 "net/http"
23 "os"
24 "runtime"
25 "testing"
26 )
27
28 type mockTripper struct {
29 }
30
31 func (m *mockTripper) RoundTrip(r *http.Request) (*http.Response, error) {
32 return &http.Response{StatusCode: 200, Body: ioutil.NopCloser(bytes.NewReader([]byte("{}")))}, nil
33 }
34
35 var mockClient = &http.Client{Transport: &mockTripper{}}
36
37 func TestCreateInstanceConfigs(t *testing.T) {
38 for _, v := range []struct {
39 desc string
40
41 dir string
42 useFuse bool
43 instances []string
44 instancesSrc string
45
46
47
48 wantErr bool
49
50 skipFailedInstanceConfig bool
51
52 supportedOnWindows bool
53 }{
54 {
55 "setting -fuse and -dir",
56 "dir", true, nil, "", false, false, false,
57 }, {
58 "setting -fuse",
59 "", true, nil, "", true, false, false,
60 }, {
61 "setting -fuse, -dir, and -instances",
62 "dir", true, []string{"proj:reg:x"}, "", true, false, false,
63 }, {
64 "setting -fuse, -dir, and -instances_metadata",
65 "dir", true, nil, "md", true, false, false,
66 }, {
67 "setting -dir and -instances (unix socket)",
68 "dir", false, []string{"proj:reg:x"}, "", false, false, false,
69 }, {
70
71 "setting -dir and -instances (unix socket) w/ something invalid",
72 "dir", false, []string{"proj:reg:x", "INVALID_PROJECT_STRING"}, "", false, true, false,
73 }, {
74 "Seting -instance (unix socket)",
75 "", false, []string{"proj:reg:x"}, "", true, false, false,
76 }, {
77 "setting -instance (tcp socket)",
78 "", false, []string{"proj:reg:x=tcp:1234"}, "", false, false, true,
79 }, {
80 "setting -instance (tcp socket) and -instances_metadata",
81 "", false, []string{"proj:reg:x=tcp:1234"}, "md", true, false, true,
82 }, {
83 "setting -dir, -instance (tcp socket), and -instances_metadata",
84 "dir", false, []string{"proj:reg:x=tcp:1234"}, "md", false, false, true,
85 }, {
86 "setting -dir, -instance (unix socket), and -instances_metadata",
87 "dir", false, []string{"proj:reg:x"}, "md", false, false, false,
88 }, {
89 "setting -dir and -instances_metadata",
90 "dir", false, nil, "md", false, false, false,
91 }, {
92 "setting -instances_metadata",
93 "", false, nil, "md", true, false, true,
94 },
95 } {
96 if runtime.GOOS == "windows" && !v.supportedOnWindows {
97 continue
98 }
99 if v.useFuse && testing.Short() {
100 t.Skip("skipping fuse tests in short mode.")
101 }
102 _, err := CreateInstanceConfigs(v.dir, v.useFuse, v.instances, v.instancesSrc, mockClient, v.skipFailedInstanceConfig)
103 if v.wantErr {
104 if err == nil {
105 t.Errorf("CreateInstanceConfigs passed when %s, wanted error", v.desc)
106 }
107 continue
108 }
109 if err != nil {
110 t.Errorf("CreateInstanceConfigs gave error when %s: %v", v.desc, err)
111 }
112 }
113 }
114
115 func TestParseInstanceConfig(t *testing.T) {
116
117 var (
118 anyLoopbackAddress = "<any loopback address>"
119 wantErr = instanceConfig{"<want error>", "", ""}
120 )
121
122 tcs := []struct {
123
124 dir, instance string
125
126 wantCfg instanceConfig
127 }{
128 {
129 "/x", "domain.com:my-proj:my-reg:my-instance",
130 instanceConfig{"domain.com:my-proj:my-reg:my-instance", "unix", "/x/domain.com:my-proj:my-reg:my-instance"},
131 }, {
132 "/x", "my-proj:my-reg:my-instance",
133 instanceConfig{"my-proj:my-reg:my-instance", "unix", "/x/my-proj:my-reg:my-instance"},
134 }, {
135 "/x", "my-proj:my-reg:my-instance=unix:socket_name",
136 instanceConfig{"my-proj:my-reg:my-instance", "unix", "/x/socket_name"},
137 }, {
138 "/x", "my-proj:my-reg:my-instance=unix:/my/custom/sql-socket",
139 instanceConfig{"my-proj:my-reg:my-instance", "unix", "/my/custom/sql-socket"},
140 }, {
141 "/x", "my-proj:my-reg:my-instance=tcp:1234",
142 instanceConfig{"my-proj:my-reg:my-instance", "tcp", anyLoopbackAddress},
143 }, {
144 "/x", "my-proj:my-reg:my-instance=tcp4:1234",
145 instanceConfig{"my-proj:my-reg:my-instance", "tcp4", "127.0.0.1:1234"},
146 }, {
147 "/x", "my-proj:my-reg:my-instance=tcp6:1234",
148 instanceConfig{"my-proj:my-reg:my-instance", "tcp6", "[::1]:1234"},
149 }, {
150 "/x", "my-proj:my-reg:my-instance=tcp:my-host:1111",
151 instanceConfig{"my-proj:my-reg:my-instance", "tcp", "my-host:1111"},
152 }, {
153 "/x", "my-proj:my-reg:my-instance=",
154 wantErr,
155 }, {
156 "/x", "my-proj:my-reg:my-instance=cool network",
157 wantErr,
158 }, {
159 "/x", "my-proj:my-reg:my-instance=cool network:1234",
160 wantErr,
161 }, {
162 "/x", "my-proj:my-reg:my-instance=oh:so:many:colons",
163 wantErr,
164 },
165 }
166
167 for _, tc := range tcs {
168 t.Run(fmt.Sprintf("parseInstanceConfig(%q, %q)", tc.dir, tc.instance), func(t *testing.T) {
169 if os.Getenv("EXPECT_IPV4_AND_IPV6") != "true" {
170
171
172 if tc.wantCfg.Network == "tcp4" || tc.wantCfg.Network == "tcp6" {
173 if !validNets[tc.wantCfg.Network] {
174 t.Skipf("%q net not supported, skipping", tc.wantCfg.Network)
175 }
176 }
177
178 if runtime.GOOS == "windows" && tc.wantCfg.Network == "unix" {
179 t.Skipf("%q net not supported on Windows, skipping", tc.wantCfg.Network)
180 }
181 }
182
183 got, err := parseInstanceConfig(tc.dir, tc.instance, mockClient)
184 if tc.wantCfg == wantErr {
185 if err != nil {
186 return
187 }
188 t.Fatalf("parseInstanceConfig(%s, %s) = %+v, wanted error", tc.dir, tc.instance, got)
189 }
190 if err != nil {
191 t.Fatalf("parseInstanceConfig(%s, %s) had unexpected error: %v", tc.dir, tc.instance, err)
192 }
193
194 if tc.wantCfg.Address == anyLoopbackAddress {
195 host, _, err := net.SplitHostPort(got.Address)
196 if err != nil {
197 t.Fatalf("net.SplitHostPort(%v): %v", got.Address, err)
198 }
199 ip := net.ParseIP(host)
200 if !ip.IsLoopback() {
201 t.Fatalf("want loopback, got addr: %v", got.Address)
202 }
203
204
205 got.Address = "<loopback>"
206 tc.wantCfg.Address = got.Address
207 }
208
209 if got != tc.wantCfg {
210 t.Errorf("parseInstanceConfig(%s, %s) = %+v, want %+v", tc.dir, tc.instance, got, tc.wantCfg)
211 }
212 })
213 }
214 }
215
View as plain text