Example #1
0
func officialAddr(unresolvedAddr string, resolvedAddr net.Addr) (*util.UnresolvedAddr, error) {
	unresolvedHost, unresolvedPort, err := net.SplitHostPort(unresolvedAddr)
	if err != nil {
		return nil, err
	}

	resolvedHost, resolvedPort, err := net.SplitHostPort(resolvedAddr.String())
	if err != nil {
		return nil, err
	}

	var host string
	if unresolvedHost != "" {
		// A host was provided, use it.
		host = unresolvedHost
	} else {
		// A host was not provided. Ask the system, and fall back to the listener.
		if hostname, err := os.Hostname(); err == nil {
			host = hostname
		} else {
			host = resolvedHost
		}
	}

	var port string
	if unresolvedPort != "0" {
		// A port was provided, use it.
		port = unresolvedPort
	} else {
		// A port was not provided, but the system assigned one.
		port = resolvedPort
	}

	return util.NewUnresolvedAddr(resolvedAddr.Network(), net.JoinHostPort(host, port)), nil
}
Example #2
0
func (tr *testResolver) GetAddress() (net.Addr, error) {
	defer func() { tr.numTries++ }()
	if tr.numTries < tr.numFails {
		return nil, errors.New("bad address")
	}
	return util.NewUnresolvedAddr("tcp", tr.addr), nil
}
Example #3
0
func checkOfficialize(t *testing.T, network, oldAddrString, newAddrString, expAddrString string) {
	resolvedAddr := util.NewUnresolvedAddr(network, newAddrString)

	if unresolvedAddr, err := officialAddr(oldAddrString, resolvedAddr); err != nil {
		t.Fatal(err)
	} else if retAddrString := unresolvedAddr.String(); retAddrString != expAddrString {
		t.Errorf("officialAddr(%s, %s) was %s; expected %s", oldAddrString, newAddrString, retAddrString, expAddrString)
	}
}
Example #4
0
// setupSendNextTest sets up a situation in which SendNextTimeout has
// caused RPCs to be sent to all three replicas simultaneously. The
// caller may then cause those RPCs to finish by writing to one of the
// 'done' channels in the first return value; the second returned
// channel will contain the final result of the send() call.
//
// TODO(bdarnell): all the 'done' channels are currently the same.
// Either give each call its own channel, return a list of (replica
// descriptor, channel) pair, or decide we don't care about
// distinguishing them and just send a single channel.
func setupSendNextTest(t *testing.T) ([]chan<- BatchCall, chan BatchCall, *stop.Stopper) {
	stopper := stop.NewStopper()
	nodeContext := newNodeTestContext(hlc.NewClock(hlc.UnixNano, time.Nanosecond), stopper)

	addrs := []net.Addr{
		util.NewUnresolvedAddr("dummy", "1"),
		util.NewUnresolvedAddr("dummy", "2"),
		util.NewUnresolvedAddr("dummy", "3"),
	}

	doneChanChan := make(chan chan<- BatchCall, len(addrs))

	opts := SendOptions{
		ctx:             context.Background(),
		SendNextTimeout: 1 * time.Millisecond,
		transportFactory: func(_ SendOptions,
			_ *rpc.Context,
			replicas ReplicaSlice,
			_ roachpb.BatchRequest,
		) (Transport, error) {
			return &channelSaveTransport{
				ch:        doneChanChan,
				remaining: len(replicas),
			}, nil
		},
	}

	sendChan := make(chan BatchCall, 1)
	go func() {
		// Send the batch. This will block until we signal one of the done
		// channels.
		br, err := sendBatch(opts, addrs, nodeContext)
		sendChan <- BatchCall{br, err}
	}()

	doneChans := make([]chan<- BatchCall, len(addrs))
	for i := range doneChans {
		// Note that this blocks until the replica has been contacted.
		doneChans[i] = <-doneChanChan
	}
	return doneChans, sendChan, stopper
}
Example #5
0
// GetAddress returns a net.Addr or error.
func (sr *socketResolver) GetAddress() (net.Addr, error) {
	switch sr.typ {
	case "tcp":
		_, err := net.ResolveTCPAddr("tcp", sr.addr)
		if err != nil {
			return nil, err
		}
		return util.NewUnresolvedAddr("tcp", sr.addr), nil
	}
	return nil, errors.Errorf("unknown address type: %q", sr.typ)
}
Example #6
0
// TestComplexScenarios verifies various complex success/failure scenarios by
// mocking sendOne.
func TestComplexScenarios(t *testing.T) {
	defer leaktest.AfterTest(t)()

	stopper := stop.NewStopper()
	defer stopper.Stop()

	nodeContext := newNodeTestContext(hlc.NewClock(hlc.UnixNano, time.Nanosecond), stopper)

	// TODO(bdarnell): the retryable flag is no longer used for RPC errors.
	// Rework this test to incorporate application-level errors carried in
	// the BatchResponse.
	testCases := []struct {
		numServers int
		numErrors  int
		success    bool
	}{
		// --- Success scenarios ---
		{1, 0, true},
		{5, 0, true},
		// There are some errors, but enough RPCs succeed.
		{5, 1, true},
		{5, 4, true},
		{5, 2, true},

		// --- Failure scenarios ---
		// All RPCs fail.
		{5, 5, false},
	}
	for i, test := range testCases {
		var serverAddrs []net.Addr
		for j := 0; j < test.numServers; j++ {
			serverAddrs = append(serverAddrs, util.NewUnresolvedAddr("dummy",
				strconv.Itoa(j)))
		}

		opts := SendOptions{
			ctx: context.Background(),
			transportFactory: func(_ SendOptions,
				_ *rpc.Context,
				replicas ReplicaSlice,
				args roachpb.BatchRequest,
			) (Transport, error) {
				return &firstNErrorTransport{
					replicas:  replicas,
					args:      args,
					numErrors: test.numErrors,
				}, nil
			},
		}

		reply, err := sendBatch(opts, serverAddrs, nodeContext)
		if test.success {
			if err != nil {
				t.Errorf("%d: unexpected error: %s", i, err)
			}
			if reply == nil {
				t.Errorf("%d: expected reply", i)
			}
		} else {
			if err == nil {
				t.Errorf("%d: unexpected success", i)
			}
		}
	}
}