/*
 * Copyright (c) 2013-2016 Cinchapi 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 com.cinchapi.concourse.server.storage.temp;

import java.util.Iterator;
import java.util.List;

import org.junit.Assert;
import org.junit.Test;

import com.cinchapi.concourse.server.storage.StoreTest;
import com.cinchapi.concourse.server.storage.temp.Limbo;
import com.cinchapi.concourse.server.storage.temp.Write;
import com.cinchapi.concourse.thrift.TObject;
import com.cinchapi.concourse.util.TestData;
import com.google.common.collect.Lists;

/**
 * Base unit tests for {@link Limbo} services.
 * 
 * @author Jeff Nelson
 */
public abstract class LimboTest extends StoreTest {

    @Test
    public void testIterator() {
        List<Write> writes = getWrites();
        for (Write write : writes) {
            add(write.getKey().toString(), write.getValue().getTObject(), write
                    .getRecord().longValue());
        }
        Iterator<Write> it0 = ((Limbo) store).iterator();
        Iterator<Write> it1 = writes.iterator();
        while (it1.hasNext()) {
            Assert.assertTrue(it0.hasNext());
            Write w0 = it0.next();
            Write w1 = it1.next();
            Assert.assertEquals(w0, w1);
        }
        Assert.assertFalse(it0.hasNext());
    }

    @Override
    protected abstract Limbo getStore();

    protected List<Write> getWrites() {
        List<Write> writes = Lists.newArrayList();
        for (int i = 0; i < (TestData.getScaleCount() * 50); i++) {
            writes.add(TestData.getWriteNotStorable());
        }
        return writes;
    }

    @Override
    protected void add(String key, TObject value, long record) {
        if (!store.verify(key, value, record)) {
            ((Limbo) store).insert(Write.add(key, value, record));
        }
    }

    @Override
    protected void remove(String key, TObject value, long record) {
        if (store.verify(key, value, record)) {
            ((Limbo) store).insert(Write.remove(key, value, record));
        }
    }

}

@@ -746,24 +746,77 @@
 unit.Test;%0A%0A
+import com.cinchapi.concourse.server.storage.Action;%0A
 import com.c
@@ -1019,16 +1019,57 @@
 Object;%0A
+import com.cinchapi.concourse.time.Time;%0A
 import c
@@ -1890,24 +1890,530 @@
 xt());%0A    %7D
+%0A    %0A    @Test%0A    public void testGetLastWriteActionWithTimestamp() %7B%0A        String key = TestData.getSimpleString();%0A        TObject value = TestData.getTObject();%0A        long record = TestData.getLong();%0A        add(key, value, record);%0A        long timestamp = Time.now();%0A        remove(key, value, record);%0A        Assert.assertEquals(%0A                Action.ADD,%0A                ((Limbo) store).getLastWriteAction(%0A                        Write.notStorable(key, value, record), timestamp));%0A    %7D
 %0A%0A    @Overr

add unit test reproducing bug