/*
 * Copyright 2008-2009 LinkedIn, Inc
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package voldemort.versioning;

import static voldemort.TestUtils.getClock;
import junit.framework.TestCase;
import voldemort.TestUtils;

/**
 * VectorClock tests
 * 
 * @author jay
 * 
 */
public class VectorClockTest extends TestCase {

    public void testComparisons() {
        assertTrue("The empty clock should not happen before itself.",
                   getClock().compare(getClock()) != Occured.CONCURRENTLY);
        assertTrue("A clock should not happen before an identical clock.",
                   getClock(1, 1, 2).compare(getClock(1, 1, 2)) != Occured.CONCURRENTLY);
        assertTrue(" A clock should happen before an identical clock with a single additional event.",
                   getClock(1, 1, 2).compare(getClock(1, 1, 2, 3)) == Occured.BEFORE);
        assertTrue("Clocks with different events should be concurrent.",
                   getClock(1).compare(getClock(2)) == Occured.CONCURRENTLY);
        assertTrue("Clocks with different events should be concurrent.",
                   getClock(1, 1, 2).compare(getClock(1, 1, 3)) == Occured.CONCURRENTLY);
        assertTrue(getClock(2, 2).compare(getClock(1, 2, 2, 3)) == Occured.BEFORE
                   && getClock(1, 2, 2, 3).compare(getClock(2, 2)) == Occured.AFTER);
    }

    public void testMerge() {
        // merging two clocks should create a clock contain the element-wise
        // maximums
        assertEquals("Two empty clocks merge to an empty clock.",
                     getClock().merge(getClock()),
                     getClock());
        assertEquals("Merge of a clock with itself does nothing",
                     getClock(1).merge(getClock(1)),
                     getClock(1));
        assertEquals(getClock(1).merge(getClock(2)), getClock(1, 2));
        assertEquals(getClock(1).merge(getClock(1, 2)), getClock(1, 2));
        assertEquals(getClock(1, 2).merge(getClock(1)), getClock(1, 2));
        assertEquals("Two-way merge fails.",
                     getClock(1, 1, 1, 2, 3, 5).merge(getClock(1, 2, 2, 4)),
                     getClock(1, 1, 1, 2, 2, 3, 4, 5));
        assertEquals(getClock(2, 3, 5).merge(getClock(1, 2, 2, 4, 7)),
                     getClock(1, 2, 2, 3, 4, 5, 7));
    }

    public void testSerialization() {
        assertEquals("The empty clock serializes incorrectly.",
                     getClock(),
                     new VectorClock(getClock().toBytes()));
        VectorClock clock = getClock(1, 1, 2, 3, 4, 4, 6);
        assertEquals("This clock does not serialize to itself.",
                     clock,
                     new VectorClock(clock.toBytes()));
    }

    public void testSerializationWraps() {
        VectorClock clock = getClock(1, 1, 2, 3, 3, 6);
        for(int i = 0; i < 300; i++)
            clock.incrementVersion(2, System.currentTimeMillis());
        assertEquals("Clock does not serialize to itself.", clock, new VectorClock(clock.toBytes()));
    }

    public void testIncrementOrderDoesntMatter() {
        // Clocks should have the property that no matter what order the
        // increment operations are done in the resulting clocks are equal
        int numTests = 10;
        int numNodes = 10;
        int numValues = 100;
        VectorClock[] clocks = new VectorClock[numNodes];
        for(int t = 0; t < numTests; t++) {
            int[] test = TestUtils.randomInts(numNodes, numValues);
            for(int n = 0; n < numNodes; n++)
                clocks[n] = getClock(TestUtils.shuffle(test));
            // test all are equal
            for(int n = 0; n < numNodes - 1; n++)
                assertEquals("Clock " + n + " and " + (n + 1) + " are not equal.",
                             clocks[n],
                             clocks[n + 1]);
        }
    }
}

@@ -833,16 +833,241 @@
 Case %7B%0A%0A
+    public void testEqualsAndHashcode() %7B%0A        VectorClock one = getClock(1, 2);%0A        VectorClock other = getClock(1, 2);%0A        assertEquals(one, other);%0A        assertEquals(one.hashCode(), other.hashCode());%0A    %7D%0A%0A
     publ

Add testEqualsAndHashCode.