/** * Replication Benchmarker * https://github.com/score-team/replication-benchmarker/ * Copyright (C) 2013 LORIA / Inria / SCORE Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package crdt.tree.orderedtree; import collect.OrderedNode; import crdt.CRDTMessage; import crdt.Factory; import crdt.PreconditionException; import crdt.set.CRDTSet; import crdt.set.NaiveSet; import crdt.set.observedremove.CommutativeOrSet; import crdt.set.observedremove.ConvergentOrSet; import crdt.simulator.CausalDispatcherSetsAndTreesTest; import crdt.simulator.IncorrectTraceException; import crdt.simulator.random.OperationProfile; import crdt.simulator.random.OrderedTreeOperationProfile; import crdt.simulator.random.StandardOrderedTreeOperationProfileWithMoveRename; import crdt.tree.fctree.FCTreeGf; import crdt.tree.fctree.FCTreeT; import crdt.tree.fctree.policy.FastCycleBreaking; import static crdt.tree.orderedtree.OrderedNodeMock.tree; import crdt.tree.wordtree.WordConnectionPolicy; import crdt.tree.wordtree.WordTree; import crdt.tree.wordtree.policy.*; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import jbenchmarker.core.MergeAlgorithm; import jbenchmarker.factories.LogootFactory; import jbenchmarker.logoot.BoundaryStrategy; import jbenchmarker.logoot.RandomLogootStrategy; import jbenchmarker.ot.ottree.OTTree; import jbenchmarker.ot.ottree.OTTreeTransformation; import jbenchmarker.ot.ottree.TreeOPT; import jbenchmarker.ot.ottree.TreeOPTTTFTranformation; import jbenchmarker.ot.soct2.SOCT2; import jbenchmarker.ot.soct2.SOCT2Log; import jbenchmarker.ot.soct2.SOCT2LogTTFOpt; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.junit.Test; /** * * @author urso */ public class OrderedTreeTest { private void assertSameTree(OrderedNode on, OrderedNode ot) { assertTrue(ot + " expected : " + on, CRDTOrderedTree.sameNode(on, ot)); } private void assertSameTree(OrderedNode on, PositionIdentifierTree ot) { assertTrue(ot.lookup() + " expected : " + on, CRDTOrderedTree.sameNode(on, ot.lookup())); } static class IntegerPos implements PositionIdentifier { int p; public IntegerPos(int p) { this.p = p; } } static List<Integer> path(int ... p) { List<Integer> l = new LinkedList<Integer>(); for (int i : p) { l.add(i); } return l; } public static PositionIdentifierTree createTree(OrderedNode root, Factory<CRDTSet> sf, Factory<WordConnectionPolicy> wcp) { WordTree wt = new WordTree(sf.create(), wcp); return new PositionIdentifierTree((PositionnedNode)root.createNode(null), wt); } Factory<MergeAlgorithm> lf = new LogootFactory(); OrderedNode testTree(PositionIdentifierTree tf) throws PreconditionException { PositionIdentifierTree ot = tf.create(), ot2 = tf.create(); ot.setReplicaNumber(1); ot2.setReplicaNumber(2); OrderedNodeMock on; CRDTMessage m1 = ot.add(path(), 0, 'x'); ot2.applyRemote(m1); on = tree(null, 'x'); assertSameTree(on, ot); assertSameTree(on, ot2); CRDTMessage m2 = ot2.add(path(), 0, 'a'), m3 = ot.add(path(), 1, 'c'); ot.applyRemote(m2); ot2.applyRemote(m3); on = tree(null, 'a', 'x', 'c'); assertSameTree(on, ot); assertSameTree(on, ot2); CRDTMessage m4 = ot.remove(path(1)), m5 = ot2.add(path(), 1, 'b'); ot2.applyRemote(m4); ot.applyRemote(m5); on = tree(null, 'a', 'b', 'c'); assertSameTree(on, ot); assertSameTree(on, ot2); CRDTMessage m6 = ot.add(path(1), 0, 'y'), m7 = ot2.add(path(1), 0, 'y'); ot2.applyRemote(m6); ot.applyRemote(m7); on = tree(null, 'a', tree('b', 'y', 'y'), 'c'); assertSameTree(on, ot); assertSameTree(on, ot2); CRDTMessage m8 = ot.remove(path(0)), m9 = ot2.add(path(0), 0, 'y'); ot2.applyRemote(m8); ot.applyRemote(m9); assertSameTree(ot.lookup(), ot2.lookup()); return (OrderedNode) ot.lookup(); } void testSkip(OrderedNode root, Factory<CRDTSet> sf) throws PreconditionException { OrderedNode r = testTree(createTree(root, sf, new WordIncrementalSkip())); OrderedNodeMock on = tree(null, tree('b', 'y', 'y'), 'c'); assertSameTree(on, r); r = testTree(createTree(root, sf, new WordIncrementalSkipOpti())); assertSameTree(on, r); // r = testLogoot(sf, new WordSkip()); // assertSameTree(on, r); } public void testSetSkips(OrderedNode root) throws PreconditionException { testSkip(root, new CommutativeOrSet()); testSkip(root, new ConvergentOrSet()); testSkip(root, new NaiveSet()); } @Test public void testFoo() throws PreconditionException { List a = new ArrayList(), b = new LinkedList(); a.add('a'); b.add('c'); b.add('a'); b.add('b'); assertEquals(a, b.subList(1, 2)); } @Test public void testLogootTree() throws PreconditionException { RandomLogootStrategy st = new BoundaryStrategy(32, 100); OrderedNode root = new LogootTreeNode(null, 0, st); testSetSkips(root); } @Test public void testLogootTreeBoundary() throws PreconditionException { RandomLogootStrategy st = new BoundaryStrategy(2, 1); OrderedNode root = new LogootTreeNode(null, 0, st); testSetSkips(root); } @Test public void testWootHTree() throws PreconditionException { OrderedNode root = new WootHashTreeNode(null, 0); testSetSkips(root); } Factory policies[] = {// new WordSkip(), new WordReappear(), new WordRoot(), new WordCompact(), new WordIncrementalSkip(), new WordIncrementalReappear(), new WordIncrementalRoot(), new WordIncrementalCompact(), new WordIncrementalSkipOpti()}; public static OperationProfile otreeop = new OrderedTreeOperationProfile(0.6, 0.7) { @Override public Object nextElement() { return (char) ('a'+(int) (Math.random() * 26)); } }; public void testRoot(Factory<CRDTOrderedTree> f) throws PreconditionException { CRDTOrderedTree<Character> t0 = f.create(), t1 = f.create(); t0.setReplicaNumber(0); t1.setReplicaNumber(1); CRDTMessage m11, m12, m01, m02, m13, m03; m11 = t1.applyLocal(new OrderedTreeOperation(path(), 0, 'r')); m12 = t1.applyLocal(new OrderedTreeOperation(path(0))); t0.applyRemote(m11); m01 = t0.applyLocal(new OrderedTreeOperation(path(), 0, 'n')); m02 = t0.applyLocal(new OrderedTreeOperation(path(1), 0, 'b')); t0.applyRemote(m12); t1.applyRemote(m01); m13 = t1.applyLocal(new OrderedTreeOperation(path(0), 0, 'y')); m03 = t0.applyLocal(new OrderedTreeOperation(path(0))); t0.applyRemote(m13); t1.applyRemote(m02); t1.applyRemote(m03); assertTrue(t0.sameLookup(t1)); } @Test public void testRunsNaiveLogootSkip() throws PreconditionException, IncorrectTraceException, IOException { CausalDispatcherSetsAndTreesTest.testRunX(createTree(new LogootTreeNode(null, 0, new BoundaryStrategy(32, 100)), new NaiveSet(), new WordIncrementalSkip()), 2000, 100, 5, otreeop); } @Test public void testRunsNaiveLogootSkipOpti() throws PreconditionException, IncorrectTraceException, IOException { CausalDispatcherSetsAndTreesTest.testRunX(createTree(new LogootTreeNode(null, 0, new BoundaryStrategy(32, 100)), new NaiveSet(), new WordIncrementalSkipOpti()), 2000, 100, 5, otreeop); } @Test public void testRunsNaiveLogootSkipUnique() throws PreconditionException, IncorrectTraceException, IOException { CausalDispatcherSetsAndTreesTest.testRunX(createTree(new LogootTreeNode(null, 0, new BoundaryStrategy(32, 100)), new NaiveSet(), new WordIncrementalSkipUnique()), 2000, 100, 5, otreeop); } @Test public void testRunsNaiveLogootReappear() throws PreconditionException, IncorrectTraceException, IOException { CausalDispatcherSetsAndTreesTest.testRunX(createTree(new LogootTreeNode(null, 0, new BoundaryStrategy(32, 100)), new NaiveSet(), new WordIncrementalReappear()), 2000, 100, 5, otreeop); } @Test public void testRunsOTTree() throws PreconditionException, IncorrectTraceException, IOException { //new OTTree(new SOCT2(0, new SOCT2Log(new OTTreeTransformation()), null)); //for(int p=0;p<20000;p++){ CausalDispatcherSetsAndTreesTest.testRunX(new OTTree(new SOCT2(0, new SOCT2Log(new OTTreeTransformation()), null)), 2000, 100, 5, otreeop); //} } @Test public void testRunsFCTreeT() throws PreconditionException, IncorrectTraceException, IOException { //new OTTree(new SOCT2(0, new SOCT2Log(new OTTreeTransformation()), null)); //for(int p=0;p<20000;p++){ CausalDispatcherSetsAndTreesTest.testRunX(new FCTreeT(), 2000, 100, 5, otreeop); //} } @Test public void testRunsFCTreeGf() throws PreconditionException, IncorrectTraceException, IOException { //new OTTree(new SOCT2(0, new SOCT2Log(new OTTreeTransformation()), null)); //for(int p=0;p<20000;p++){ CausalDispatcherSetsAndTreesTest.testRunX(new FCTreeGf(), 2000, 100, 5, otreeop); //} } @Test public void testRunsFCTreeMove() throws PreconditionException, IncorrectTraceException, IOException { //new OTTree(new SOCT2(0, new SOCT2Log(new OTTreeTransformation()), null)); //for(int p=0;p<20000;p++){ CausalDispatcherSetsAndTreesTest.testRunX(new FCTreeGf(), 2000, 100, 5, new StandardOrderedTreeOperationProfileWithMoveRename(0.4, 0.2, 0.2, 0.7)); //} } @Test public void testRunsFCTreeMoveCB() throws PreconditionException, IncorrectTraceException, IOException { //new OTTree(new SOCT2(0, new SOCT2Log(new OTTreeTransformation()), null)); //for(int p=0;p<20000;p++){ CausalDispatcherSetsAndTreesTest.testRunX(new FCTreeGf(new FastCycleBreaking("Garbage")), 2000, 100, 5, new StandardOrderedTreeOperationProfileWithMoveRename(0.4, 0.2, 0.2, 0.7)); //} } @Test public void testRunsTreeOPT() throws PreconditionException, IncorrectTraceException, IOException { //new OTTree(new SOCT2(0, new SOCT2Log(new OTTreeTransformation()), null)); //for(int p=0;p<20000;p++){ CausalDispatcherSetsAndTreesTest.testRunX(new TreeOPT(new SOCT2(0, new SOCT2Log(new TreeOPTTTFTranformation()), null)), 2000, 100, 5, otreeop); //} } @Test public void testRunsTreeOPT2() throws PreconditionException, IncorrectTraceException, IOException { //new OTTree(new SOCT2(0, new SOCT2Log(new OTTreeTransformation()), null)); //for(int p=0;p<20000;p++){ CausalDispatcherSetsAndTreesTest.testRunX(new TreeOPT(new SOCT2(0, new SOCT2LogTTFOpt(new TreeOPTTTFTranformation()), null)), 2000, 100, 5, otreeop); //} } @Test public void testRunsOTTree2() throws PreconditionException, IncorrectTraceException, IOException { //new OTTree(new SOCT2(0, new SOCT2Log(new OTTreeTransformation()), null)); //for(int p=0;p<20000;p++){ CausalDispatcherSetsAndTreesTest.testRunX(new OTTree(new SOCT2(0, new SOCT2LogTTFOpt(new OTTreeTransformation()), null)), 2000, 100, 5, otreeop); //} } }