Package info.archinnov.achilles.internal.context

Source Code of info.archinnov.achilles.internal.context.BatchingFlushContextTest

/*
* Copyright (C) 2012-2014 DuyHai DOAN
*
*  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 info.archinnov.achilles.internal.context;

import static info.archinnov.achilles.type.ConsistencyLevel.EACH_QUORUM;
import static java.util.Arrays.asList;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.List;
import java.util.concurrent.ExecutorService;

import info.archinnov.achilles.async.AchillesFuture;
import info.archinnov.achilles.type.Empty;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.powermock.reflect.Whitebox;
import com.datastax.driver.core.RegularStatement;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.ListenableFuture;
import info.archinnov.achilles.interceptor.Event;
import info.archinnov.achilles.internal.async.AsyncUtils;
import info.archinnov.achilles.internal.async.EmptyFutureResultSets;
import info.archinnov.achilles.internal.context.AbstractFlushContext.FlushType;
import info.archinnov.achilles.internal.interceptor.EventHolder;
import info.archinnov.achilles.internal.metadata.holder.EntityMeta;
import info.archinnov.achilles.internal.statement.wrapper.AbstractStatementWrapper;
import info.archinnov.achilles.internal.statement.wrapper.BatchStatementWrapper;
import info.archinnov.achilles.internal.statement.wrapper.BoundStatementWrapper;
import info.archinnov.achilles.internal.statement.wrapper.RegularStatementWrapper;
import info.archinnov.achilles.listener.CASResultListener;
import info.archinnov.achilles.test.mapping.entity.CompleteBean;
import info.archinnov.achilles.type.ConsistencyLevel;

@RunWith(MockitoJUnitRunner.class)
public class BatchingFlushContextTest {

    private BatchingFlushContext context;

    @Mock
    private DaoContext daoContext;

    @Mock
    private AsyncUtils asyncUtils;

    @Mock
    private ExecutorService executorService;

    @Mock
    private BoundStatementWrapper bsWrapper;

    @Mock
    private RegularStatement query;

    @Mock
    private ListenableFuture<ResultSet> futureResultSet1;

    @Mock
    private ListenableFuture<ResultSet> futureResultSet2;

    @Mock
    private ListenableFuture<List<ResultSet>> futureAsList;

    @Mock
    private ListenableFuture<Empty> futureEmpty;

    @Mock
    private AchillesFuture<Empty> achillesEmpty;


    @Captor
    private ArgumentCaptor<AbstractStatementWrapper> statementWrapperCaptor;

    @Captor
    private ArgumentCaptor<List<ListenableFuture<ResultSet>>> futureResultSetsCaptor;

    @Captor
    private ArgumentCaptor<Function<List<ResultSet>, Empty>> applyTriggersCaptor;

    private Optional<CASResultListener> NO_LISTENER = Optional.absent();
    private static final Optional<com.datastax.driver.core.ConsistencyLevel> NO_SERIAL_CONSISTENCY = Optional.absent();

    @Before
    public void setUp() {
        context = new BatchingFlushContext(daoContext, EACH_QUORUM, NO_SERIAL_CONSISTENCY);
        context.asyncUtils = asyncUtils;
        when(daoContext.getExecutorService()).thenReturn(executorService);
    }

    @Test
    public void should_start_batch() throws Exception {
        context.startBatch();
    }

    @Test
    public void should_do_nothing_when_flush_is_called() throws Exception {
        context.statementWrappers.add(bsWrapper);

        final ListenableFuture<List<ResultSet>> actual = context.flush();

        assertThat(actual).isInstanceOf(EmptyFutureResultSets.class);
        assertThat(context.statementWrappers).containsExactly(bsWrapper);
    }

    @Test
    public void should_end_batch_with_logged_batch() throws Exception {
        //Given
        EventHolder eventHolder = mock(EventHolder.class);
        RegularStatement statement1 = QueryBuilder.select().from("table1");
        RegularStatement statement2 = QueryBuilder.select().from("table2");
        AbstractStatementWrapper wrapper1 = new RegularStatementWrapper(CompleteBean.class, statement1, null, com.datastax.driver.core.ConsistencyLevel.ONE, NO_LISTENER, NO_SERIAL_CONSISTENCY);
        AbstractStatementWrapper wrapper2 = new RegularStatementWrapper(CompleteBean.class, statement2, null, com.datastax.driver.core.ConsistencyLevel.ONE, NO_LISTENER, NO_SERIAL_CONSISTENCY);
        AbstractStatementWrapper wrapper3 = new RegularStatementWrapper(CompleteBean.class, statement2, null, com.datastax.driver.core.ConsistencyLevel.ONE, NO_LISTENER, NO_SERIAL_CONSISTENCY);
        context.eventHolders = asList(eventHolder);
        context.statementWrappers = asList(wrapper1, wrapper2);
        context.counterStatementWrappers = asList(wrapper3);
        context.consistencyLevel = ConsistencyLevel.LOCAL_QUORUM;
        context.serialConsistencyLevel = Optional.fromNullable(com.datastax.driver.core.ConsistencyLevel.LOCAL_SERIAL);

        when(daoContext.execute(statementWrapperCaptor.capture())).thenReturn(futureResultSet1, futureResultSet2);
        when(asyncUtils.mergeResultSetFutures(futureResultSetsCaptor.capture())).thenReturn(futureAsList);
        when(asyncUtils.transformFuture(eq(futureAsList), applyTriggersCaptor.capture(), eq(executorService))).thenReturn(futureEmpty);
        when(asyncUtils.buildInterruptible(futureEmpty)).thenReturn(achillesEmpty);

        //When
        final ListenableFuture<Empty> futureResultSets = context.flushBatch();

        //Then
        assertThat(futureResultSets).isSameAs(achillesEmpty);
        assertThat(futureResultSetsCaptor.getValue()).containsExactly(futureResultSet1, futureResultSet2);

        final List<AbstractStatementWrapper> wrappers = statementWrapperCaptor.getAllValues();
        BatchStatementWrapper batchWrapper = (BatchStatementWrapper) wrappers.get(0);
        assertThat(Whitebox.<List<AbstractStatementWrapper>>getInternalState(batchWrapper, "statementWrappers")).containsExactly(wrapper1, wrapper2);
        assertThat(wrappers.get(1)).isSameAs(wrapper3);

        assertThat(batchWrapper.getStatement().getConsistencyLevel()).isSameAs(com.datastax.driver.core.ConsistencyLevel.LOCAL_QUORUM);
        assertThat(batchWrapper.getStatement().getSerialConsistencyLevel()).isNull();

        final Function<List<ResultSet>, Empty> applyTriggers = applyTriggersCaptor.getValue();
        applyTriggers.apply(asList(mock(ResultSet.class)));

        verify(eventHolder).triggerInterception();
    }

    @Test
    public void should_get_type() throws Exception {
        assertThat(context.type()).isSameAs(FlushType.BATCH);
    }

    @Test
    public void should_duplicate_without_ttl() throws Exception {
        context.statementWrappers.add(bsWrapper);

        BatchingFlushContext duplicate = context.duplicate();

        assertThat(duplicate.statementWrappers).containsOnly(bsWrapper);
        assertThat(duplicate.consistencyLevel).isSameAs(EACH_QUORUM);
        assertThat(duplicate.serialConsistencyLevel.isPresent()).isFalse();
    }

    @Test
    public void should_trigger_interceptor_immediately_for_POST_LOAD_event() throws Exception {
        //Given
        EntityMeta meta = mock(EntityMeta.class, RETURNS_DEEP_STUBS);
        Object entity = new Object();

        //When
        context.triggerInterceptor(meta, entity, Event.POST_LOAD);

        //Then
        verify(meta.forInterception()).intercept(entity, Event.POST_LOAD);
    }

    @Test
    public void should_push_interceptor_to_list() throws Exception {
        //Given
        EntityMeta meta = mock(EntityMeta.class, RETURNS_DEEP_STUBS);
        Object entity = new Object();

        //When
        context.triggerInterceptor(meta, entity, Event.POST_INSERT);

        //Then
        verify(meta.forInterception(), never()).intercept(entity, Event.POST_INSERT);
        assertThat(context.eventHolders).hasSize(1);
        final EventHolder eventHolder = context.eventHolders.get(0);
        eventHolder.triggerInterception();
        verify(meta.forInterception()).intercept(entity, Event.POST_INSERT);
    }

    @Test
    public void should_duplicate_with_no_data_but_consistency() throws Exception {
        //Given
        context.statementWrappers.add(mock(AbstractStatementWrapper.class));
        context.eventHolders.add(mock(EventHolder.class));

        //When
        final BatchingFlushContext newContext = context.duplicateWithNoData(ConsistencyLevel.EACH_QUORUM);

        //Then
        assertThat(newContext.statementWrappers).isEmpty();
        assertThat(newContext.eventHolders).isEmpty();
        assertThat(newContext.consistencyLevel).isEqualTo(ConsistencyLevel.EACH_QUORUM);
    }

    @Test
    public void should_duplicate_with_no_data_vut_consistency_and_serial_consistency() throws Exception {
        //Given
        context.statementWrappers.add(mock(AbstractStatementWrapper.class));
        context.eventHolders.add(mock(EventHolder.class));

        //When
        final BatchingFlushContext newContext = context.duplicateWithNoData(ConsistencyLevel.EACH_QUORUM,
                Optional.fromNullable(com.datastax.driver.core.ConsistencyLevel.LOCAL_SERIAL));

        //Then
        assertThat(newContext.statementWrappers).isEmpty();
        assertThat(newContext.eventHolders).isEmpty();
        assertThat(newContext.consistencyLevel).isEqualTo(ConsistencyLevel.EACH_QUORUM);
        assertThat(newContext.serialConsistencyLevel.get()).isEqualTo(com.datastax.driver.core.ConsistencyLevel.LOCAL_SERIAL);
    }

}
TOP

Related Classes of info.archinnov.achilles.internal.context.BatchingFlushContextTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.