// TestBlockProposal ensures that node will block proposal when it does not // know who is the current leader; node will accept proposal when it knows // who is the current leader. func TestBlockProposal(t *testing.T) { n := newNode() r := newRaft(1, []int64{1}, 10, 1) go n.run(r) defer n.Stop() errc := make(chan error, 1) go func() { errc <- n.Propose(context.TODO(), []byte("somedata")) }() pkg.ForceGosched() select { case err := <-errc: t.Errorf("err = %v, want blocking", err) default: } n.Campaign(context.TODO()) pkg.ForceGosched() select { case err := <-errc: if err != nil { t.Errorf("err = %v, want %v", err, nil) } default: t.Errorf("blocking proposal, want unblocking") } }
// TestCompacts ensures Node.Compact creates a correct raft snapshot and compacts // the raft log (call raft.compact) func TestCompact(t *testing.T) { ctx := context.Background() n := newNode() r := newRaft(1, []int64{1}, 0, 0) go n.run(r) n.Campaign(ctx) n.Propose(ctx, []byte("foo")) w := raftpb.Snapshot{ Term: 1, Index: 2, // one nop + one proposal Data: []byte("a snapshot"), Nodes: []int64{1}, } pkg.ForceGosched() select { case <-n.Ready(): default: t.Fatalf("unexpected proposal failure: unable to commit entry") } n.Compact(w.Data) pkg.ForceGosched() select { case rd := <-n.Ready(): if !reflect.DeepEqual(rd.Snapshot, w) { t.Errorf("snap = %+v, want %+v", rd.Snapshot, w) } default: t.Fatalf("unexpected compact failure: unable to create a snapshot") } pkg.ForceGosched() // TODO: this test the run updates the snapi correctly... should be tested // separately with other kinds of updates select { case <-n.Ready(): t.Fatalf("unexpected more ready") default: } n.Stop() if r.raftLog.offset != w.Index { t.Errorf("log.offset = %d, want %d", r.raftLog.offset, w.Index) } }