示例#1
0
// NewRealTimeCluster a new cluster with n logs.
// All logs use a real-time clock instead of a test clock.
func NewRealTimeCluster(logN int, fsmFn func() raft.FSM) *Cluster {
	c := &Cluster{}
	t := NewTransport()

	for i := 0; i < logN; i++ {
		l := NewLog(&url.URL{Host: fmt.Sprintf("log%d", i)})
		l.Log.FSM = fsmFn()
		l.Clock = nil
		l.Log.Clock = raft.NewClock()
		l.Transport = t
		c.Logs = append(c.Logs, l)
		t.register(l.Log)
		warnf("Log %s: %p", l.URL.String(), l.Log)
	}
	warn("")

	// Initialize leader.
	c.Logs[0].MustOpen()
	c.Logs[0].MustInitialize()

	// Join remaining nodes.
	for i := 1; i < logN; i++ {
		c.Logs[i].MustOpen()
		c.Logs[i].MustJoin(c.Logs[0].URL)
	}

	// Ensure nodes are ready.
	index, _ := c.Logs[0].LastLogIndexTerm()
	for i := 0; i < logN; i++ {
		c.Logs[i].MustWait(index)
	}

	return c
}
示例#2
0
// Ensure the AfterReconnectTimeout returns a channel that fires after the clock's reconnect interval.
func TestClock_AfterReconnectTimeout(t *testing.T) {
	c := raft.NewClock()
	c.ReconnectTimeout = 10 * time.Millisecond
	t0 := time.Now()
	<-c.AfterReconnectTimeout()
	if d := time.Since(t0); d < c.ReconnectTimeout {
		t.Fatalf("channel fired too soon: %v", d)
	}
}
示例#3
0
// Ensure the AfterHeartbeatInterval returns a channel that fires after the clock's heartbeat interval.
func TestClock_AfterHeartbeatInterval(t *testing.T) {
	c := raft.NewClock()
	c.HeartbeatInterval = 10 * time.Millisecond
	t0 := time.Now()
	<-c.AfterHeartbeatInterval()
	if d := time.Since(t0); d < c.HeartbeatInterval {
		t.Fatalf("channel fired too soon: %v", d)
	}
}
示例#4
0
// Ensure the clock can return the current time.
func TestClock_Now(t *testing.T) {
	now := raft.NewClock().Now()
	if exp := time.Now(); exp.Sub(now) > 1*time.Second {
		t.Fatalf("clock time is different than wall time: exp=%v, got=%v", exp, now)
	}
}