示例#1
0
// PGUrl returns a postgres connection url which connects to this server with
// the given user. Returns a connection string and a cleanup function which must
// be called after any connection created using the string has been closed.
//
// In order to connect securely using postgres, this method will create
// temporary on-disk copies of certain embedded security certificates. The
// certificates will be created as temporary files in the provided directory,
// and their filenames will have the provided prefix. The returned cleanup
// function will delete these temporary files.
func PGUrl(t util.Tester, ts *server.TestServer, user, tempDir, prefix string) (url.URL, func()) {
	host, port, err := net.SplitHostPort(ts.PGAddr())
	if err != nil {
		t.Fatal(err)
	}

	caPath := filepath.Join(security.EmbeddedCertsDir, "ca.crt")
	certPath := security.ClientCertPath(security.EmbeddedCertsDir, user)
	keyPath := security.ClientKeyPath(security.EmbeddedCertsDir, user)

	// Copy these assets to disk from embedded strings, so this test can
	// run from a standalone binary.
	tempCAPath, tempCACleanup := securitytest.TempRestrictedCopy(t, caPath, tempDir, "TestLogic_ca")
	tempCertPath, tempCertCleanup := securitytest.TempRestrictedCopy(t, certPath, tempDir, "TestLogic_cert")
	tempKeyPath, tempKeyCleanup := securitytest.TempRestrictedCopy(t, keyPath, tempDir, "TestLogic_key")

	return url.URL{
			Scheme: "postgres",
			User:   url.User(user),
			Host:   net.JoinHostPort(host, port),
			RawQuery: fmt.Sprintf("sslmode=verify-full&sslrootcert=%s&sslcert=%s&sslkey=%s",
				url.QueryEscape(tempCAPath),
				url.QueryEscape(tempCertPath),
				url.QueryEscape(tempKeyPath),
			),
		}, func() {
			tempCACleanup()
			tempCertCleanup()
			tempKeyCleanup()
		}
}
示例#2
0
// 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)
	}
}
示例#3
0
// TempRestrictedCopy creates a temporary on-disk copy of the embedded security asset
// with the provided path. The copy will be created as a temporary file in the
// provided directory; its filename will have the provided prefix. Returns the
// path of the temporary file and a cleanup function that will delete the
// temporary file.
//
// The temporary file will have restrictive file permissions (0600), making it
// appropriate for usage by libraries that require security assets to have such
// restrictive permissions.
func TempRestrictedCopy(t util.Tester, path, tempdir, prefix string) (string, func()) {
	contents, err := Asset(path)
	if err != nil {
		t.Fatal(err)
	}
	return util.CreateTempRestrictedFile(t, contents, tempdir, prefix)
}
示例#4
0
// RestrictedCopy creates an on-disk copy of the embedded security asset
// with the provided path. The copy will be created in the provided directory.
// Returns the path of the file and a cleanup function that will delete the file.
//
// The file will have restrictive file permissions (0600), making it
// appropriate for usage by libraries that require security assets to have such
// restrictive permissions.
func RestrictedCopy(t util.Tester, path, tempdir, name string) string {
	contents, err := Asset(path)
	if err != nil {
		if t == nil {
			log.Fatal(err)
		} else {
			t.Fatal(err)
		}
	}
	return util.CreateRestrictedFile(t, contents, tempdir, name)
}
示例#5
0
func makeClient(t util.Tester, str string) (*client.DB, *stop.Stopper) {
	stopper := stop.NewStopper()

	db, err := client.Open(stopper, str)

	if err != nil {
		t.Fatal(err)
	}

	return db, stopper
}
示例#6
0
// MakeClient creates a DB client for node 'i' using the cluster certs dir.
func (l *LocalCluster) MakeClient(t util.Tester, node int) (*client.DB, *stop.Stopper) {
	stopper := stop.NewStopper()

	db, err := client.Open(stopper, "rpcs://"+security.NodeUser+"@"+
		l.Nodes[node].Addr("").String()+
		"?certs="+l.CertsDir)

	if err != nil {
		t.Fatal(err)
	}

	return db, stopper
}
示例#7
0
// MakeClient returns a client which is pointing at the node with the given
// index. The given integer must be in the range [0,NumNodes()-1].
func (r *RemoteCluster) MakeClient(t util.Tester, i int) (*client.DB, *stop.Stopper) {
	stopper := stop.NewStopper()

	// TODO(tschottdorf,mberhault): TLS all the things!
	db, err := client.Open(stopper, "rpc://"+"root"+"@"+
		util.EnsureHostPort(r.nodes[i].Addr)+
		"?certs="+"certswhocares")

	if err != nil {
		t.Fatal(err)
	}

	return db, stopper
}
示例#8
0
// makeDBClientForUser creates a DB client for node 'i' and user 'user'.
func makeDBClientForUser(t util.Tester, lc *LocalCluster, user string, node int) (*client.DB, *stop.Stopper) {
	stopper := stop.NewStopper()

	// We need to run with "InsecureSkipVerify" (set when Certs="" inside the http sender).
	// This is due to the fact that we're running outside docker, so we cannot use a fixed hostname
	// to reach the cluster. This in turn means that we do not have a verified server name in the certs.
	db, err := client.Open(stopper, "rpcs://"+user+"@"+
		lc.Nodes[node].Addr("").String()+
		"?certs="+lc.CertsDir)

	if err != nil {
		t.Fatal(err)
	}

	return db, stopper
}
示例#9
0
// Assert verifies that the cluster state is as expected (i.e. no unexpected
// restarts or node deaths occurred). Tests can call this periodically to
// ascertain cluster health.
// TODO(tschottdorf): unimplemented when nodes are expected down.
func (f *Farmer) Assert(t util.Tester) {
	for _, item := range []struct {
		typ   string
		hosts []string
	}{
		{"cockroach", f.Nodes()},
		{"block_writer", f.Writers()},
	} {
		for i, host := range item.hosts {
			out, _, err := f.execSupervisor(host, "status "+item.typ)
			if err != nil {
				t.Fatal(err)
			}
			if !strings.Contains(out, "RUNNING") {
				t.Fatalf("%s %d (%s) is down:\n%s", item.typ, i, host, out)
			}
		}
	}
}
示例#10
0
// AssertAndStop performs the same test as Assert but then proceeds to
// dismantle the cluster.
func (f *Farmer) AssertAndStop(t util.Tester) {
	if err := f.Destroy(); err != nil {
		t.Fatal(err)
	}
}