func TestFigure12(t *testing.T) { a_dx := clock.Create(10, 1) a_dy := clock.Create(10, 1) a_d := &clock.Clock{} b_dx := &clock.Clock{} b_dy := &clock.Clock{} b_d := &clock.Clock{} b_dx.ResolveTheirs(a_dx) b_d.UpdateFromChild(b_dx) b_dx.UpdateSync(11, 3) b_dy.UpdateSync(11, 3) b_dx.UpdateFromParent(b_d) b_dy.UpdateFromParent(b_d) c_dx := &clock.Clock{} c_dy := &clock.Clock{} c_d := &clock.Clock{} c_dy.ResolveTheirs(a_dy) c_d.UpdateFromChild(c_dy) c_dx.UpdateSync(12, 3) c_dy.UpdateSync(12, 3) c_dx.UpdateFromParent(c_d) c_dy.UpdateFromParent(c_d) if g, e := b_dx.String(), `{sync{10:1 11:3} mod{10:1} create{10:1}}`; g != e { t.Errorf("bad state B d/x: %v != %v", g, e) } if g, e := b_dy.String(), `{sync{11:3} mod{} create{}}`; g != e { t.Errorf("bad state B d/y: %v != %v", g, e) } if g, e := b_d.String(), `{sync{} mod{10:1} create{}}`; g != e { t.Errorf("bad state B d: %v != %v", g, e) } if g, e := c_dx.String(), `{sync{12:3} mod{} create{}}`; g != e { t.Errorf("bad state C d/x: %v != %v", g, e) } if g, e := c_dy.String(), `{sync{10:1 12:3} mod{10:1} create{10:1}}`; g != e { t.Errorf("bad state C d/y: %v != %v", g, e) } if g, e := c_d.String(), `{sync{} mod{10:1} create{}}`; g != e { t.Errorf("bad state C d: %v != %v", g, e) } a_dx.ValidateFile(a_d) a_dy.ValidateFile(a_d) b_dx.ValidateFile(b_d) b_dy.ValidateFile(b_d) c_dx.ValidateFile(c_d) c_dy.ValidateFile(c_d) }
func TestFigure5C(t *testing.T) { a := clock.Create(10, 1) a.Update(10, 2) // delete b := clock.Create(11, 4) if g, e := clock.SyncToMissing(b, a), clock.Copy; g != e { t.Errorf("bad sync decision: %v is to %v -> %v != %v", a, b, g, e) } a.ResolveTheirs(b) a.ValidateFile(&clock.Clock{ /* dummy parent */ }) b.ValidateFile(&clock.Clock{ /* dummy parent */ }) }
func TestUpdateFromChildReturn(t *testing.T) { a_dx := clock.Create(10, 1) a_dy := clock.Create(10, 1) a_d := &clock.Clock{} a_d.UpdateSync(10, 1) if g, e := a_d.UpdateFromChild(a_dx), true; g != e { t.Errorf("UpdateFromChild return %v != %v", g, e) } if g, e := a_d.UpdateFromChild(a_dy), false; g != e { t.Errorf("UpdateFromChild return %v != %v", g, e) } }
func (vc *VolumeClock) UpdateOrCreate(parentInode uint64, name string, now clock.Epoch) (c *clock.Clock, changed bool, err error) { key := vc.pathToKey(parentInode, name) val := vc.b.Get(key) if val == nil { c = clock.Create(0, now) changed = true } else { c = &clock.Clock{} if err := c.UnmarshalBinary(val); err != nil { return nil, false, err } c.Update(0, now) // TODO make clock.UpdateOrCreate return changed bool changed = true } if !changed { return nil, false, nil } buf, err := c.MarshalBinary() if err != nil { return nil, true, err } if err := vc.b.Put(key, buf); err != nil { return nil, true, err } return c, true, nil }
func TestMarshalBinarySimple(t *testing.T) { v := clock.Create(10, 3) v.Update(11, 2) got, err := v.MarshalBinary() if err != nil { t.Fatalf("unexpected error: %v", err) } want := []byte{ // syncLen 2, // sync 10, 3, 11, 2, // modLen 1, // mod 11, 2, // createLen 1, // create 10, 3, } if !bytes.Equal(got, want) { t.Errorf("bad marshal: % x != % x", got, want) } }
func TestFigure8(t *testing.T) { a := clock.Create(10, 1) a.UpdateSync(10, 2) b := &clock.Clock{} b.ResolveTheirs(a) // Figure 8 does not contain the compressed modtime optimization. b.UpdateParent(11, 4) c := &clock.Clock{} if g, e := clock.Sync(b, c), clock.Copy; g != e { t.Errorf("bad sync decision: %v is to %v -> %v != %v", a, b, g, e) } c.ResolveTheirs(b) c.UpdateSync(12, 5) if g, e := c.String(), `{sync{10:2 11:4 12:5} mod{10:1 11:4} create{10:1}}`; g != e { t.Errorf("bad state C: %v != %v", g, e) } a.ValidateFile(&clock.Clock{ /* dummy parent */ }) b.ValidateFile(&clock.Clock{ /* dummy parent */ }) c.ValidateFile(&clock.Clock{ /* dummy parent */ }) }
func TestRewritePeersBadPeer(t *testing.T) { c := clock.Create(10, 1) m := map[clock.Peer]clock.Peer{ 42: 13, } if g, e := c.RewritePeers(m), clock.ErrRewritePeerNotMapped; g != e { t.Errorf("wrong error: %v != %v", g, e) } }
func TestSection3_3_2(t *testing.T) { a := clock.Create(10, 1) a.Update(11, 2) a.UpdateSync(11, 3) a.Tombstone() if g, e := a.String(), `{sync{10:1 11:3} mod{} create{}}`; g != e { t.Errorf("bad state for tombstone: %v != %v", g, e) } }
func (vc *VolumeClock) Create(parentInode uint64, name string, now clock.Epoch) (*clock.Clock, error) { c := clock.Create(0, now) buf, err := c.MarshalBinary() if err != nil { return nil, err } key := vc.pathToKey(parentInode, name) if err := vc.b.Put(key, buf); err != nil { return nil, err } return c, nil }
func TestRewritePeersSimple(t *testing.T) { c := clock.Create(10, 1) c.UpdateSync(11, 2) c.Update(12, 3) if g, e := c.String(), `{sync{10:1 11:2 12:3} mod{12:3} create{10:1}}`; g != e { t.Errorf("bad initial state: %v != %v", g, e) } m := map[clock.Peer]clock.Peer{ 10: 20, 11: 12, 12: 10, } if err := c.RewritePeers(m); err != nil { t.Fatalf("rewrite error: %v", err) } if g, e := c.String(), `{sync{20:1 12:2 10:3} mod{10:3} create{20:1}}`; g != e { t.Errorf("bad state: %v != %v", g, e) } }
func TestFigure2C(t *testing.T) { var b clock.Clock a := clock.Create(10, 1) if g, e := clock.Sync(a, &b), clock.Copy; g != e { t.Errorf("bad sync decision: %v is to %v -> %v != %v", a, b, g, e) } b.ResolveTheirs(a) a.Update(10, 3) b.Update(11, 3) if g, e := clock.Sync(&b, a), clock.Conflict; g != e { t.Errorf("bad sync decision: %v is to %v -> %v != %v", a, b, g, e) } if g, e := a.String(), `{sync{10:3} mod{10:3} create{10:1}}`; g != e { t.Errorf("bad state A: %v != %v", g, e) } if g, e := b.String(), `{sync{10:1 11:3} mod{11:3} create{10:1}}`; g != e { t.Errorf("bad state B: %v != %v", g, e) } a.ValidateFile(&clock.Clock{ /* dummy parent */ }) b.ValidateFile(&clock.Clock{ /* dummy parent */ }) }
// what would happen after paper figure 12, if the whole dir was // synced A->B func TestFigure12Continuation(t *testing.T) { a_dx := clock.Create(10, 1) a_dy := clock.Create(10, 1) a_d := &clock.Clock{} // new: no longer a partial sync a_d.UpdateSync(10, 1) a_d.UpdateFromChild(a_dx) a_d.UpdateFromChild(a_dy) a_dx.UpdateFromParent(a_d) a_dy.UpdateFromParent(a_d) if g, e := a_dx.String(), `{sync{} mod{10:1} create{10:1}}`; g != e { t.Errorf("bad state A d/x: %v != %v", g, e) } if g, e := a_dy.String(), `{sync{} mod{10:1} create{10:1}}`; g != e { t.Errorf("bad state A d/y: %v != %v", g, e) } if g, e := a_d.String(), `{sync{10:1} mod{10:1} create{}}`; g != e { t.Errorf("bad state A d: %v != %v", g, e) } b_dx := &clock.Clock{} b_dy := &clock.Clock{} b_d := &clock.Clock{} b_dx.ResolveTheirs(a_dx) b_d.UpdateFromChild(b_dx) b_dx.UpdateSync(11, 3) b_dy.UpdateSync(11, 3) // new: no longer a partial sync b_d.UpdateSync(11, 3) b_dx.UpdateFromParent(b_d) b_dy.UpdateFromParent(b_d) c_dx := &clock.Clock{} c_dy := &clock.Clock{} c_d := &clock.Clock{} c_dy.ResolveTheirs(a_dy) c_d.UpdateFromChild(c_dy) c_dx.UpdateSync(12, 3) c_dy.UpdateSync(12, 3) // new: no longer a partial sync c_d.UpdateSync(12, 3) c_dx.UpdateFromParent(c_d) c_dy.UpdateFromParent(c_d) // new things b_dy.ResolveTheirs(a_dy) b_d.ResolveOurs(a_d) b_d.UpdateFromChild(b_dy) b_dx.UpdateFromParent(b_d) b_dy.UpdateFromParent(b_d) c_dx.ResolveTheirs(a_dx) c_d.ResolveOurs(a_d) c_d.UpdateFromChild(c_dx) c_dx.UpdateFromParent(c_d) c_dy.UpdateFromParent(c_d) if g, e := b_dx.String(), `{sync{} mod{10:1} create{10:1}}`; g != e { t.Errorf("bad state B d/x: %v != %v", g, e) } if g, e := b_dy.String(), `{sync{} mod{10:1} create{10:1}}`; g != e { t.Errorf("bad state B d/y: %v != %v", g, e) } if g, e := b_d.String(), `{sync{10:1 11:3} mod{10:1} create{}}`; g != e { t.Errorf("bad state B d: %v != %v", g, e) } if g, e := c_dx.String(), `{sync{} mod{10:1} create{10:1}}`; g != e { t.Errorf("bad state C d/x: %v != %v", g, e) } if g, e := c_dy.String(), `{sync{} mod{10:1} create{10:1}}`; g != e { t.Errorf("bad state C d/y: %v != %v", g, e) } if g, e := c_d.String(), `{sync{10:1 12:3} mod{10:1} create{}}`; g != e { t.Errorf("bad state C d: %v != %v", g, e) } a_dx.ValidateFile(a_d) a_dy.ValidateFile(a_d) b_dx.ValidateFile(b_d) b_dy.ValidateFile(b_d) c_dx.ValidateFile(c_d) c_dy.ValidateFile(c_d) }