org.alfresco.solr.tracker.AclTrackerTest.java Source code

Java tutorial

Introduction

Here is the source code for org.alfresco.solr.tracker.AclTrackerTest.java

Source

/*
 * #%L
 * Alfresco Solr 4
 * %%
 * Copyright (C) 2005 - 2016 Alfresco Software Limited
 * %%
 * This file is part of the Alfresco software. 
 * If the software was purchased under a paid Alfresco license, the terms of 
 * the paid license agreement will prevail.  Otherwise, the software is 
 * provided under the following open source license terms:
 * 
 * Alfresco is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Alfresco 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 Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 * #L%
 */
package org.alfresco.solr.tracker;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.alfresco.solr.IndexTrackingShutdownException;
import org.alfresco.solr.InformationServer;
import org.alfresco.solr.TrackerState;
import org.alfresco.solr.client.AclChangeSet;
import org.alfresco.solr.client.AclChangeSets;
import org.alfresco.solr.client.SOLRAPIClient;
import org.apache.commons.lang.reflect.FieldUtils;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

/**
 * Unit tests for the {@link AclTracker} class.
 * 
 * @author Matt Ward
 */
@RunWith(MockitoJUnitRunner.class)
public class AclTrackerTest {
    private static final Object CUSTOM_ALFRESCO_VERSION = "99.9.9";
    // The class under test
    private AclTracker tracker;
    private @Mock SOLRAPIClient client;
    private @Mock InformationServer informationServer;
    private TrackerState trackerState;

    @Before
    public void setUp() throws Exception {
        trackerState = new TrackerState();
        trackerState.setRunning(false); // Nothing would happen if it were already running.
        Properties props = createProperties();
        // Spy in order to stub some methods and verify others. Note: non-stubbed methods go to the real class.
        tracker = spy(new AclTracker(props, client, "core-name", informationServer));
    }

    private Properties createProperties() {
        Properties props = new Properties();
        props.put("alfresco.stores", "workspace://SpacesStore");
        props.put("alfresco.version", CUSTOM_ALFRESCO_VERSION);
        return props;
    }

    protected void testTrackChangesRan() {
        when(tracker.getTrackerState()).thenReturn(trackerState);

        tracker.track();

        assertFalse(trackerState.isRunning());
        assertFalse(trackerState.isCheck());
    }

    // High level test of doTrack() workflow.
    @Test
    public void checkTrackingOperaionsPerformed() throws Throwable {
        testTrackChangesRan();

        verify(tracker).purgeAclChangeSets();
        verify(tracker).purgeAcls();

        verify(tracker).reindexAclChangeSets();
        verify(tracker).reindexAcls();

        verify(tracker).indexAclChangeSets();
        verify(tracker).indexAcls();

        verify(tracker).trackRepository();
    }

    // Tests the purgeAclChangeSets() call made in AclTracker.doTrack()
    // TODO: the other operations in doTrack().
    @Test
    public void checkTrackingWhenAclChangeSetsToPurge() throws IllegalAccessException, IOException {
        @SuppressWarnings("unchecked")
        ConcurrentLinkedQueue<Long> aclChangeSetsToPurge = (ConcurrentLinkedQueue<Long>) FieldUtils
                .readField(tracker, "aclChangeSetsToPurge", true);
        aclChangeSetsToPurge.add(101L);
        aclChangeSetsToPurge.add(102L);
        aclChangeSetsToPurge.add(103L);

        // Invoke the behaviour we're testing
        testTrackChangesRan();

        // aclChangeSetsToPurge
        verify(informationServer).deleteByAclChangeSetId(101L);
        verify(informationServer).deleteByAclChangeSetId(102L);
        verify(informationServer).deleteByAclChangeSetId(103L);

        // TODO: verify checkShutdown
        verify(informationServer).commit();
    }

    @Test
    public void checkTrackingWhenAclsToPurge() throws IllegalAccessException, IOException {
        @SuppressWarnings("unchecked")
        ConcurrentLinkedQueue<Long> aclsToPurge = (ConcurrentLinkedQueue<Long>) FieldUtils.readField(tracker,
                "aclsToPurge", true);
        aclsToPurge.add(201L);
        aclsToPurge.add(202L);
        aclsToPurge.add(203L);

        // Invoke the behaviour we're testing
        testTrackChangesRan();

        // aclsToPurge
        verify(informationServer).deleteByAclId(201L);
        verify(informationServer).deleteByAclId(202L);
        verify(informationServer).deleteByAclId(203L);

        // TODO: verify checkShutdown
        verify(informationServer).commit();
    }

    // TODO: Commented out, approach not working
    // Rethink or finish later.
    /*@Test
    public void checkTrackingWhenAclChangeSetsToReindex() throws IllegalAccessException, IOException, AuthenticationException, JSONException
    {
    @SuppressWarnings("unchecked")
    ConcurrentLinkedQueue<Long> aclChangeSetsToReindex = (ConcurrentLinkedQueue<Long>)
    FieldUtils.readField(tracker, "aclChangeSetsToReindex", true);
    aclChangeSetsToReindex.add(301L);
    aclChangeSetsToReindex.add(302L);
    aclChangeSetsToReindex.add(303L);
        
    // tracker will loop through list of ACLs to reindex, and get changesets for each changeset ID.
    when(client.getAclChangeSets(null, 201L, null, 202L, 1)).thenReturn(mockChangeSets(201L));
    when(client.getAclChangeSets(null, 202L, null, 203L, 1)).thenReturn(mockChangeSets(202L));
    when(client.getAclChangeSets(null, 203L, null, 204L, 1)).thenReturn(mockChangeSets(203L));
        
    when(client.getAcls(Collections.singletonList(new AclChangeSet(201L, 0L, 1)), null, Integer.MAX_VALUE)).thenReturn(Collections.singletonList(new Acl(201L, 0L)));
    when(client.getAcls(Collections.singletonList(new AclChangeSet(202L, 0L, 1)), null, Integer.MAX_VALUE)).thenReturn(Collections.singletonList(new Acl(202L, 0L)));
    when(client.getAcls(Collections.singletonList(new AclChangeSet(203L, 0L, 1)), null, Integer.MAX_VALUE)).thenReturn(Collections.singletonList(new Acl(203L, 0L)));
        
    // TODO: ...more...
        
    // Invoke the behaviour we're testing
    testTrackChangesRan();
        
    verify(informationServer).deleteByAclChangeSetId(301L);
    verify(informationServer).deleteByAclChangeSetId(302L);
    verify(informationServer).deleteByAclChangeSetId(303L);
        
    // TODO: verify checkShutdown
    verify(informationServer).commit();
    }*/

    private AclChangeSets mockChangeSets(long id) {
        List<AclChangeSet> changeSets = Collections.singletonList(new AclChangeSet(id, 0L, 1));
        AclChangeSets acs = mock(AclChangeSets.class);
        when(acs.getAclChangeSets()).thenReturn(changeSets);
        return acs;
    }

    @Test
    public void trackingAbortsWhenAlreadyRunning() throws Throwable {
        trackerState.setRunning(true);
        // Prove running state, before attempt to track()
        assertTrue(trackerState.isRunning());

        FieldUtils.writeField(tracker, "state", trackerState, true);
        tracker.track();

        // Still running - these values are unaffected.
        assertTrue(trackerState.isRunning());
        assertFalse(trackerState.isCheck());

        // Prove doTrack() was not called
        verify(tracker, never()).doTrack();
    }

    @Test
    public void willRollbackOnThrowableDuringTracking() throws Throwable {
        doThrow(new RuntimeException("Simulated problem during tracking")).when(tracker).doTrack();

        testTrackChangesRan();

        verify(informationServer).rollback();
    }

    @Test
    public void willRollbackOnIndexTrackingShutdownException() throws Throwable {
        doThrow(new IndexTrackingShutdownException()).when(tracker).doTrack();

        testTrackChangesRan();

        verify(informationServer).rollback();
    }

    @Ignore("Not yet implemented.")
    @Test
    public void canCheckIndex() {
        // TODO
        //        tracker.checkIndex(fromTx, toTx, fromAclTx, toAclTx, fromTime, toTime);
    }

    @Test
    public void canGetAlfrescoVersion() {
        // Check we're testing something useful
        assertNotNull(CUSTOM_ALFRESCO_VERSION);
        // Check alfresco version retrieved from properties
        assertEquals(CUSTOM_ALFRESCO_VERSION, tracker.getAlfrescoVersion());
    }

    @Test
    public void canClose() throws IllegalAccessException {
        ThreadHandler threadHandler = (ThreadHandler) FieldUtils.readField(tracker, "threadHandler", true);
        threadHandler = spy(threadHandler);
        FieldUtils.writeField(tracker, "threadHandler", threadHandler, true);

        tracker.close();

        // AclTracker specific
        verify(threadHandler).shutDownThreadPool();

        // Applicable to all AbstractAclTracker
        verify(client).close();
    }
}