// Start starts the test cluster by bootstrapping an in-memory store // (defaults to maximum of 50M). The server is started, launching the // node RPC server and all HTTP endpoints. Use the value of // TestServer.Addr after Start() for client connections. Use Stop() // to shutdown the server after the test completes. func (ltc *LocalTestCluster) Start(t util.Tester) { ltc.Manual = hlc.NewManualClock(0) ltc.Clock = hlc.NewClock(ltc.Manual.UnixNano) ltc.Stopper = stop.NewStopper() rpcContext := rpc.NewContext(testutils.NewRootTestBaseContext(), ltc.Clock, ltc.Stopper) ltc.Gossip = gossip.New(rpcContext, gossip.TestInterval, gossip.TestBootstrap) ltc.Eng = engine.NewInMem(proto.Attributes{}, 50<<20) ltc.lSender = newRetryableLocalSender(NewLocalSender()) ltc.Sender = NewTxnCoordSender(ltc.lSender, ltc.Clock, false, nil, ltc.Stopper) var err error if ltc.DB, err = client.Open("//root@", client.SenderOpt(ltc.Sender)); err != nil { t.Fatal(err) } transport := multiraft.NewLocalRPCTransport(ltc.Stopper) ltc.Stopper.AddCloser(transport) ctx := storage.TestStoreContext ctx.Clock = ltc.Clock ctx.DB = ltc.DB ctx.Gossip = ltc.Gossip ctx.Transport = transport ltc.Store = storage.NewStore(ctx, ltc.Eng, &proto.NodeDescriptor{NodeID: 1}) if err := ltc.Store.Bootstrap(proto.StoreIdent{NodeID: 1, StoreID: 1}, ltc.Stopper); err != nil { t.Fatalf("unable to start local test cluster: %s", err) } ltc.lSender.AddStore(ltc.Store) if err := ltc.Store.BootstrapRange(nil); err != nil { t.Fatalf("unable to start local test cluster: %s", err) } if err := ltc.Store.Start(ltc.Stopper); err != nil { t.Fatalf("unable to start local test cluster: %s", err) } }
func TestSend(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() sender, err := newHTTPSender(s.ServingAddr(), testutils.NewRootTestBaseContext(), defaultRetryOptions) if err != nil { log.Fatalf("Couldn't create HTTPSender for server:(%s)", s.ServingAddr()) } testCases := []struct { req string reply string }{ {"ping", "ping"}, {"default", "default"}, } for _, test := range testCases { request := &sqlwire.Request{Sql: test.req} call := sqlwire.Call{Args: request, Reply: &sqlwire.Response{}} sender.Send(context.TODO(), call) reply := *call.Reply.Results[0].Rows[0].Values[0].StringVal if reply != test.reply { log.Fatalf("Server sent back reply: %s", reply) } } }
// TestHTTPSenderRetryHTTPSendError verifies that send is retried // on all errors sending HTTP requests. func TestHTTPSenderRetryHTTPSendError(t *testing.T) { defer leaktest.AfterTest(t) retryOptions := defaultRetryOptions retryOptions.InitialBackoff = 1 * time.Millisecond testCases := []func(*httptest.Server, http.ResponseWriter){ // Send back an unparseable response but a success code on first try. func(s *httptest.Server, w http.ResponseWriter) { fmt.Fprintf(w, "\xff\xfe\x23\x44") }, // Close the client connection. func(s *httptest.Server, w http.ResponseWriter) { s.CloseClientConnections() }, } for i, testFunc := range testCases { count := 0 var s *httptest.Server server, addr := startTestHTTPServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { count++ if count == 1 { // On first retry, invoke the error function. testFunc(s, w) return } // Success on second try. body, contentType, err := util.MarshalResponse(r, testPutResp, util.AllEncodings) if err != nil { t.Errorf("%d: failed to marshal response: %s", i, err) } w.Header().Set(util.ContentTypeHeader, contentType) w.Write(body) })) s = server sender, err := newHTTPSender(addr, testutils.NewRootTestBaseContext(), retryOptions) if err != nil { t.Fatal(err) } reply := &proto.PutResponse{} sender.Send(context.Background(), proto.Call{Args: testPutReq, Reply: reply}) if reply.GoError() != nil { t.Errorf("%d: expected success; got %s", i, reply.GoError()) } if count != 2 { t.Errorf("%d: expected retry", i) } server.Close() } }
// TestHTTPSenderSend verifies sending posts. func TestHTTPSenderSend(t *testing.T) { defer leaktest.AfterTest(t) server, addr := startTestHTTPServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { t.Errorf("expected method POST; got %s", r.Method) } if r.URL.Path != KVDBEndpoint+"Put" { t.Errorf("expected url %s; got %s", KVDBEndpoint+"Put", r.URL.Path) } // Unmarshal the request. reqBody, err := ioutil.ReadAll(r.Body) if err != nil { t.Errorf("unexpected error reading body: %s", err) } args := &proto.PutRequest{} if err := util.UnmarshalRequest(r, reqBody, args, util.AllEncodings); err != nil { t.Errorf("unexpected error unmarshalling request: %s", err) } if !args.Key.Equal(testPutReq.Key) || !args.Timestamp.Equal(testPutReq.Timestamp) { t.Errorf("expected parsed %+v to equal %+v", args, testPutReq) } body, contentType, err := util.MarshalResponse(r, testPutResp, util.AllEncodings) if err != nil { t.Errorf("failed to marshal response: %s", err) } w.Header().Set(util.ContentTypeHeader, contentType) w.Write(body) })) defer server.Close() sender, err := newHTTPSender(addr, testutils.NewRootTestBaseContext(), defaultRetryOptions) if err != nil { t.Fatal(err) } reply := &proto.PutResponse{} sender.Send(context.Background(), proto.Call{Args: testPutReq, Reply: reply}) if reply.GoError() != nil { t.Errorf("expected success; got %s", reply.GoError()) } if !reply.Timestamp.Equal(testPutResp.Timestamp) { t.Errorf("expected received %+v to equal %+v", reply, testPutResp) } }
// Example_zone shows how to use the admin client to // get/set/list/delete zone configs. func Example_zone() { s := server.StartTestServer(nil) defer s.Stop() context := testutils.NewRootTestBaseContext() client := client.NewAdminClient(context, s.ServingAddr(), client.Zone) const yamlConfig = ` replicas: - attrs: [dc1, ssd] - attrs: [dc2, ssd] - attrs: [dc3, ssd] range_min_bytes: 1048576 range_max_bytes: 67108864 ` const jsonConfig = `{ "replica_attrs": [ { "attrs": [ "dc1", "ssd" ] }, { "attrs": [ "dc2", "ssd" ] }, { "attrs": [ "dc3", "ssd" ] } ], "range_min_bytes": 1048576, "range_max_bytes": 67108864 }` testData := []struct { prefix proto.Key cfg string isJSON bool }{ {proto.KeyMin, yamlConfig, false}, {proto.Key("db1"), yamlConfig, false}, {proto.Key("db 2"), jsonConfig, true}, {proto.Key("\xfe"), jsonConfig, true}, } // Write configs. for _, test := range testData { prefix := string(test.prefix) if test.isJSON { fmt.Printf("Set JSON zone config for %q\n", prefix) if err := client.SetJSON(prefix, test.cfg); err != nil { log.Fatal(err) } } else { fmt.Printf("Set YAML zone config for %q\n", prefix) if err := client.SetYAML(prefix, test.cfg); err != nil { log.Fatal(err) } } } // Get configs in various format. body, err := client.GetJSON("db1") if err != nil { log.Fatal(err) } fmt.Printf("JSON config for \"db1\":\n%s\n", body) body, err = client.GetYAML("db 2") if err != nil { log.Fatal(err) } fmt.Printf("YAML config for \"db 2\":\n%s\n", body) // List keys. keys, err := client.List() if err != nil { log.Fatal(err) } fmt.Printf("Zone prefixes: %q\n", keys) // Remove keys: the default one cannot be removed. err = client.Delete("") if err == nil { log.Fatal("expected error") } err = client.Delete("db 2") if err != nil { log.Fatal(err) } // List keys again. keys, err = client.List() if err != nil { log.Fatal(err) } fmt.Printf("Zone prefixes: %q\n", keys) // Output: // Set YAML zone config for "" // Set YAML zone config for "db1" // Set JSON zone config for "db 2" // Set JSON zone config for "\xfe" // JSON config for "db1": // { // "replica_attrs": [ // { // "attrs": [ // "dc1", // "ssd" // ] // }, // { // "attrs": [ // "dc2", // "ssd" // ] // }, // { // "attrs": [ // "dc3", // "ssd" // ] // } // ], // "range_min_bytes": 1048576, // "range_max_bytes": 67108864 // } // YAML config for "db 2": // replicas: // - attrs: [dc1, ssd] // - attrs: [dc2, ssd] // - attrs: [dc3, ssd] // range_min_bytes: 1048576 // range_max_bytes: 67108864 // // Zone prefixes: ["" "db 2" "db1" "\xfe"] // Zone prefixes: ["" "db1" "\xfe"] }
// Example_accounting shows how to use the admin client to // get/set/list/delete accounting configs. func Example_accounting() { s := server.StartTestServer(nil) defer s.Stop() context := testutils.NewRootTestBaseContext() client := client.NewAdminClient(context, s.ServingAddr(), client.Accounting) const yamlConfig = `cluster_id: test` const jsonConfig = `{ "cluster_id": "test" }` testData := []struct { prefix proto.Key cfg string isJSON bool }{ {proto.KeyMin, yamlConfig, false}, {proto.Key("db1"), yamlConfig, false}, {proto.Key("db 2"), jsonConfig, true}, {proto.Key("\xfe"), jsonConfig, true}, } // Write configs. for _, test := range testData { prefix := string(test.prefix) if test.isJSON { fmt.Printf("Set JSON accounting config for %q\n", prefix) if err := client.SetJSON(prefix, test.cfg); err != nil { log.Fatal(err) } } else { fmt.Printf("Set YAML accounting config for %q\n", prefix) if err := client.SetYAML(prefix, test.cfg); err != nil { log.Fatal(err) } } } // Get configs in various format. body, err := client.GetJSON("db1") if err != nil { log.Fatal(err) } fmt.Printf("JSON config for \"db1\":\n%s\n", body) body, err = client.GetYAML("db 2") if err != nil { log.Fatal(err) } fmt.Printf("YAML config for \"db 2\":\n%s\n", body) // List keys. keys, err := client.List() if err != nil { log.Fatal(err) } fmt.Printf("Accounting prefixes: %q\n", keys) // Remove keys: the default one cannot be removed. err = client.Delete("") if err == nil { log.Fatal("expected error") } err = client.Delete("db 2") if err != nil { log.Fatal(err) } // List keys again. keys, err = client.List() if err != nil { log.Fatal(err) } fmt.Printf("Accounting prefixes: %q\n", keys) // Output: // Set YAML accounting config for "" // Set YAML accounting config for "db1" // Set JSON accounting config for "db 2" // Set JSON accounting config for "\xfe" // JSON config for "db1": // { // "cluster_id": "test" // } // YAML config for "db 2": // cluster_id: test // // Accounting prefixes: ["" "db 2" "db1" "\xfe"] // Accounting prefixes: ["" "db1" "\xfe"] }
// Example_user shows how to use the admin client to // get/set/list/delete user configs. func Example_user() { s := server.StartTestServer(nil) defer s.Stop() context := testutils.NewRootTestBaseContext() client := client.NewAdminClient(context, s.ServingAddr(), client.User) const yamlConfig = `hashed_password: - 10 - 20` const jsonConfig = `{ "hashed_password": "******" }` testData := []struct { prefix proto.Key cfg string isJSON bool }{ {proto.Key("db1"), yamlConfig, false}, {proto.Key("db 2"), jsonConfig, true}, {proto.Key("\xfe"), jsonConfig, true}, } // Overwriting the default entry fails. err := client.SetYAML("", yamlConfig) if err == nil { log.Fatal("expected error") } // Write configs. for _, test := range testData { prefix := string(test.prefix) if test.isJSON { fmt.Printf("Set JSON user config for %q\n", prefix) if err := client.SetJSON(prefix, test.cfg); err != nil { log.Fatal(err) } } else { fmt.Printf("Set YAML user config for %q\n", prefix) if err := client.SetYAML(prefix, test.cfg); err != nil { log.Fatal(err) } } } // Get configs in various format. body, err := client.GetJSON("db1") if err != nil { log.Fatal(err) } fmt.Printf("JSON config for \"db1\":\n%s\n", body) body, err = client.GetYAML("db 2") if err != nil { log.Fatal(err) } fmt.Printf("YAML config for \"db 2\":\n%s\n", body) // List keys. keys, err := client.List() if err != nil { log.Fatal(err) } fmt.Printf("Users: %q\n", keys) // Remove keys: the default one cannot be removed. err = client.Delete("") if err == nil { log.Fatal("expected error") } err = client.Delete("db 2") if err != nil { log.Fatal(err) } // List keys again. keys, err = client.List() if err != nil { log.Fatal(err) } fmt.Printf("Users: %q\n", keys) // Output: // Set YAML user config for "db1" // Set JSON user config for "db 2" // Set JSON user config for "\xfe" // JSON config for "db1": // { // "hashed_password": "******" // } // YAML config for "db 2": // hashed_password: // - 10 // - 20 // // Users: ["" "db 2" "db1" "\xfe"] // Users: ["" "db1" "\xfe"] }
// Example_permission shows how to use the admin client to // get/set/list/delete permission configs. func Example_permission() { s := server.StartTestServer(nil) defer s.Stop() context := testutils.NewRootTestBaseContext() client := client.NewAdminClient(context, s.ServingAddr(), client.Permission) // The test server creates a permission config entry for 'server.TestUser'. // Delete it first so it does not interfere with our configs. err := client.Delete(server.TestUser) if err != nil { log.Fatal(err) } const yamlConfig = ` read: [readonly, readwrite] write: [readwrite, writeonly] ` const jsonConfig = `{ "read": [ "readonly", "readwrite" ], "write": [ "readwrite", "writeonly" ] }` testData := []struct { prefix proto.Key cfg string isJSON bool }{ {proto.KeyMin, yamlConfig, false}, {proto.Key("db1"), yamlConfig, false}, {proto.Key("db 2"), jsonConfig, true}, {proto.Key("\xfe"), jsonConfig, true}, } // Write configs. for _, test := range testData { prefix := string(test.prefix) if test.isJSON { fmt.Printf("Set JSON permission config for %q\n", prefix) if err := client.SetJSON(prefix, test.cfg); err != nil { log.Fatal(err) } } else { fmt.Printf("Set YAML permission config for %q\n", prefix) if err := client.SetYAML(prefix, test.cfg); err != nil { log.Fatal(err) } } } // Get configs in various format. body, err := client.GetJSON("db1") if err != nil { log.Fatal(err) } fmt.Printf("JSON config for \"db1\":\n%s\n", body) body, err = client.GetYAML("db 2") if err != nil { log.Fatal(err) } fmt.Printf("YAML config for \"db 2\":\n%s\n", body) // List keys. keys, err := client.List() if err != nil { log.Fatal(err) } fmt.Printf("Permission prefixes: %q\n", keys) // Remove keys: the default one cannot be removed. err = client.Delete("") if err == nil { log.Fatal("expected error") } err = client.Delete("db 2") if err != nil { log.Fatal(err) } // List keys again. keys, err = client.List() if err != nil { log.Fatal(err) } fmt.Printf("Permission prefixes: %q\n", keys) // Output: // Set YAML permission config for "" // Set YAML permission config for "db1" // Set JSON permission config for "db 2" // Set JSON permission config for "\xfe" // JSON config for "db1": // { // "read": [ // "readonly", // "readwrite" // ], // "write": [ // "readwrite", // "writeonly" // ] // } // YAML config for "db 2": // read: // - readonly // - readwrite // write: // - readwrite // - writeonly // // Permission prefixes: ["" "db 2" "db1" "\xfe"] // Permission prefixes: ["" "db1" "\xfe"] }
"golang.org/x/net/context" snappy "github.com/cockroachdb/c-snappy" "github.com/cockroachdb/cockroach/kv" "github.com/cockroachdb/cockroach/proto" "github.com/cockroachdb/cockroach/sql/sqlwire" "github.com/cockroachdb/cockroach/storage" "github.com/cockroachdb/cockroach/storage/engine" "github.com/cockroachdb/cockroach/testutils" "github.com/cockroachdb/cockroach/util" "github.com/cockroachdb/cockroach/util/leaktest" gogoproto "github.com/gogo/protobuf/proto" ) var testContext = NewTestContext() var rootTestBaseContext = testutils.NewRootTestBaseContext() var nodeTestBaseContext = testutils.NewNodeTestBaseContext() // TestInitEngine tests whether the data directory string is parsed correctly. func TestInitEngine(t *testing.T) { defer leaktest.AfterTest(t) tmp := util.CreateNTempDirs(t, "_server_test", 5) defer util.CleanupDirs(tmp) testCases := []struct { key string // data directory expAttrs proto.Attributes // attributes for engine wantError bool // do we expect an error from this key? isMem bool // is the engine in-memory? }{ {"mem=1000", proto.Attributes{Attrs: []string{"mem"}}, false, true},
// NewRootTestContext returns a rpc.Context for testing. // It is meant to be used by clients. func NewRootTestContext(clock *hlc.Clock, stopper *stop.Stopper) *Context { if clock == nil { clock = hlc.NewClock(hlc.UnixNano) } return NewContext(testutils.NewRootTestBaseContext(), clock, stopper) }
// Verify client certificate enforcement. func TestSSLEnforcement(t *testing.T) { defer leaktest.AfterTest(t) s := StartTestServer(t) defer s.Stop() // HTTPS with client certs. certsContext := testutils.NewRootTestBaseContext() // HTTPS without client certs. noCertsContext := testutils.NewRootTestBaseContext() noCertsContext.Certs = "" // Plain http. insecureContext := testutils.NewRootTestBaseContext() insecureContext.Insecure = true testCases := []struct { method, key string ctx *base.Context success bool // request sent successfully (may be non-200) code int // http response code }{ // /ui/: basic file server: no auth. {"GET", "/index.html", certsContext, true, http.StatusOK}, {"GET", "/index.html", noCertsContext, true, http.StatusOK}, {"GET", "/index.html", insecureContext, false, -1}, // /_admin/: server.adminServer: no auth. {"GET", healthPath, certsContext, true, http.StatusOK}, {"GET", healthPath, noCertsContext, true, http.StatusOK}, {"GET", healthPath, insecureContext, false, -1}, // /debug/: server.adminServer: no auth. {"GET", debugEndpoint + "vars", certsContext, true, http.StatusOK}, {"GET", debugEndpoint + "vars", noCertsContext, true, http.StatusOK}, {"GET", debugEndpoint + "vars", insecureContext, false, -1}, // /_status/nodes: server.statusServer: no auth. {"GET", statusNodeKeyPrefix, certsContext, true, http.StatusOK}, {"GET", statusNodeKeyPrefix, noCertsContext, true, http.StatusOK}, {"GET", statusNodeKeyPrefix, insecureContext, false, -1}, // /ts/: ts.Server: no auth. {"GET", ts.URLPrefix, certsContext, true, http.StatusNotFound}, {"GET", ts.URLPrefix, noCertsContext, true, http.StatusNotFound}, {"GET", ts.URLPrefix, insecureContext, false, -1}, // /kv/db/: kv.DBServer. These are proto reqs, but we can at least get past auth. {"GET", kv.DBPrefix + "Get", certsContext, true, http.StatusBadRequest}, {"GET", kv.DBPrefix + "Get", noCertsContext, true, http.StatusUnauthorized}, {"GET", kv.DBPrefix + "Get", insecureContext, false, -1}, // /sql/: sql.Server. These are proto reqs, but we can at least get past auth. {"GET", driver.Endpoint + "Get", certsContext, true, http.StatusNotFound}, {"GET", driver.Endpoint + "Get", noCertsContext, true, http.StatusUnauthorized}, {"GET", driver.Endpoint + "Get", insecureContext, false, -1}, } for tcNum, tc := range testCases { client, err := tc.ctx.GetHTTPClient() if err != nil { t.Fatalf("[%d]: failed to get http client: %v", tcNum, err) } resp, err := doHTTPReq(t, client, tc.method, fmt.Sprintf("%s://%s%s", tc.ctx.RequestScheme(), s.ServingAddr(), tc.key)) if (err == nil) != tc.success { t.Fatalf("[%d]: expected success=%t, got err=%v", tcNum, tc.success, err) } if err != nil { continue } defer resp.Body.Close() if resp.StatusCode != tc.code { t.Errorf("[%d]: expected status code %d, got %d", tcNum, tc.code, resp.StatusCode) } } }
// TestHTTPSenderRetryResponseCodes verifies that send is retried // on some HTTP response codes but not on others. func TestHTTPSenderRetryResponseCodes(t *testing.T) { defer leaktest.AfterTest(t) retryOptions := defaultRetryOptions retryOptions.InitialBackoff = 1 * time.Millisecond testCases := []struct { code int retry bool }{ {http.StatusServiceUnavailable, true}, {http.StatusGatewayTimeout, true}, {StatusTooManyRequests, true}, {http.StatusRequestTimeout, false}, {http.StatusBadRequest, false}, {http.StatusNotFound, false}, {http.StatusUnauthorized, false}, {http.StatusForbidden, false}, {http.StatusMethodNotAllowed, false}, {http.StatusNotAcceptable, false}, {http.StatusInternalServerError, false}, {http.StatusNotImplemented, false}, } for i, test := range testCases { count := 0 server, addr := startTestHTTPServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { count++ if count == 1 { http.Error(w, "manufactured error", test.code) return } if !test.retry { t.Errorf("%d: didn't expect retry on code %d", i, test.code) } body, contentType, err := util.MarshalResponse(r, testPutResp, util.AllEncodings) if err != nil { t.Errorf("%d: failed to marshal response: %s", i, err) } w.Header().Set(util.ContentTypeHeader, contentType) w.Write(body) })) sender, err := newHTTPSender(addr, testutils.NewRootTestBaseContext(), retryOptions) if err != nil { t.Fatal(err) } reply := &proto.PutResponse{} sender.Send(context.Background(), proto.Call{Args: testPutReq, Reply: reply}) if test.retry { if count != 2 { t.Errorf("%d: expected retry", i) } if reply.GoError() != nil { t.Errorf("%d: expected success after retry; got %s", i, reply.GoError()) } } else { if count != 1 { t.Errorf("%d; expected no retry; got %d", i, count) } if reply.GoError() == nil { t.Errorf("%d: expected error", i) } } server.Close() } }
// This is a fairly high-level test of CA and node certificates. // We construct SSL server and clients and use the generated certs. func TestUseCerts(t *testing.T) { defer leaktest.AfterTest(t) // Do not mock cert access for this test. security.ResetReadFileFn() defer ResetTest() certsDir := util.CreateTempDir(t, "certs_test") defer util.CleanupDir(certsDir) err := security.RunCreateCACert(certsDir, 512) if err != nil { t.Fatalf("Expected success, got %v", err) } err = security.RunCreateNodeCert(certsDir, 512, []string{"127.0.0.1"}) if err != nil { t.Fatalf("Expected success, got %v", err) } err = security.RunCreateClientCert(certsDir, 512, security.RootUser) if err != nil { t.Fatalf("Expected success, got %v", err) } // Load TLS Configs. This is what TestServer and HTTPClient do internally. _, err = security.LoadServerTLSConfig(certsDir, "node") if err != nil { t.Fatalf("Expected success, got %v", err) } _, err = security.LoadClientTLSConfig(certsDir, security.NodeUser) if err != nil { t.Fatalf("Expected success, got %v", err) } // Start a test server and override certs. // We use a real context since we want generated certs. testCtx := server.NewContext() testCtx.Certs = certsDir testCtx.User = security.NodeUser testCtx.Addr = "127.0.0.1:0" s := &server.TestServer{Ctx: testCtx} if err := s.Start(); err != nil { t.Fatal(err) } defer s.Stop() // Insecure mode. clientContext := testutils.NewRootTestBaseContext() clientContext.Insecure = true httpClient, err := clientContext.GetHTTPClient() if err != nil { t.Fatal(err) } req, err := http.NewRequest("GET", "https://"+s.ServingAddr()+"/_admin/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err := httpClient.Do(req) if err == nil { resp.Body.Close() t.Fatalf("Expected SSL error, got success") } // Secure mode but no Certs directory: permissive config. clientContext = testutils.NewRootTestBaseContext() clientContext.Certs = "" httpClient, err = clientContext.GetHTTPClient() if err != nil { t.Fatal(err) } // Endpoint that does not enforce client auth (see: server/authentication_test.go) req, err = http.NewRequest("GET", "https://"+s.ServingAddr()+"/_admin/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err = httpClient.Do(req) if err != nil { t.Fatalf("Expected success, got %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("Expected OK, got: %d", resp.StatusCode) } // Endpoint that enforces client auth (see: server/authentication_test.go) req, err = http.NewRequest("GET", "https://"+s.ServingAddr()+kv.DBPrefix+"Get", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err = httpClient.Do(req) if err != nil { t.Fatalf("Expected success, got %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusUnauthorized { t.Fatalf("Expected status code %d, got: %d", http.StatusUnauthorized, resp.StatusCode) } // New client. With certs this time. clientContext = testutils.NewRootTestBaseContext() clientContext.Certs = certsDir httpClient, err = clientContext.GetHTTPClient() if err != nil { t.Fatalf("Expected success, got %v", err) } req, err = http.NewRequest("GET", "https://"+s.ServingAddr()+"/_admin/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err = httpClient.Do(req) if err != nil { t.Fatalf("Expected success, got %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("Expected OK, got: %d", resp.StatusCode) } }