Package com.google.enterprise.connector.instantiator

Source Code of com.google.enterprise.connector.instantiator.ChangeDetectorTest$ExceptionalChangeListener

// Copyright 2010 Google 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.google.enterprise.connector.instantiator;

import com.google.enterprise.connector.persist.MockPersistentStore;
import com.google.enterprise.connector.persist.PersistentStore;
import com.google.enterprise.connector.persist.StoreContext;
import com.google.enterprise.connector.scheduler.Schedule;

import junit.framework.TestCase;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/** Tests for {@link ChangeDetectorImpl}. */
// TODO: Change StoreContext to String (instance name).
// TODO: More tests, especially including stamps and corner cases like
// deleted and then re-added, etc.
public class ChangeDetectorTest extends TestCase {
  private PersistentStore store;
  private ExceptionalChangeListener listener;
  private ChangeDetector detector;

  private List<String> expectedChanges;

  public ChangeDetectorTest() {
  }

  @Override
  public void setUp() {
    store = new MockPersistentStore();
    listener = new ExceptionalChangeListener();
    detector = new ChangeDetectorImpl(store, listener);

    expectedChanges = new ArrayList<String>();
  }

  /** Adds an instance to the store and records the action. */
  private void addConnector(String connectorName) {
    store.storeConnectorConfiguration(
        new StoreContext(connectorName, "testType"),
        new Configuration("testType", Collections.<String, String>emptyMap(),
                          null));
    expectedChanges.add(MockChangeListener.CONNECTOR_ADDED + connectorName);
  }

  /** Updates an instance to the store and records the action. */
  private void updateConnector(String connectorName) {
    StoreContext context = new StoreContext(connectorName, "testType");
    assertNotNull(store.getConnectorConfiguration(context));
    store.storeConnectorConfiguration(context, new Configuration(
        "testType", Collections.<String, String>emptyMap(), null));
    expectedChanges.add(MockChangeListener.CONFIGURATION_CHANGED
                        + connectorName);
  }

  /** Deletes an instance from the store and records the action. */
  private void removeConnector(String connectorName) {
    store.removeConnectorConfiguration(
        new StoreContext(connectorName, "testType"));
    expectedChanges.add(MockChangeListener.CONNECTOR_REMOVED + connectorName);
  }

  /** Sets the checkpoint for a connector instance and records the action. */
  private void setCheckpoint(String connectorName) {
    store.storeConnectorState(new StoreContext(connectorName, "testType"), "");
    expectedChanges.add(MockChangeListener.CHECKPOINT_CHANGED + connectorName);
  }

  /** Sets the Schedule for a connector instance and records the action. */
  private void setSchedule(String connectorName) {
    store.storeConnectorSchedule(new StoreContext(connectorName, "testType"),
                                 new Schedule());
    expectedChanges.add(MockChangeListener.SCHEDULE_CHANGED + connectorName);
  }

  /**
   * Compares the contents of the two lists as multisets, that is,
   * considering only the members and not the ordering.  Neither of
   * the lists should be empty.
   *
   * @param expected the expected value
   * @param actual the actual value
   */
  private void assertEqualsMultiSet(List<String> expected,
      List<String> actual) {
    assertFalse(expected.isEmpty());
    assertFalse(actual.isEmpty());
    // Copy, sort, and compare.
    List<String> left = new ArrayList<String>(expected);
    List<String> right = new ArrayList<String>(actual);
    Collections.sort(left);
    Collections.sort(right);
    assertEquals(left, right);
  }

  /**
   * Assertst that expected and actual lists each have no recorded changes.
   *
   * @param expected the expected value
   * @param actual the actual value
   */
  private void assertNoChanges(List<String> expected, List<String> actual) {
    assertTrue(expected.isEmpty());
    assertTrue(actual.isEmpty());
  }

  /** Basic test of adding and deleting connector instances. */
  public void testAddAndRemove() {
    addConnector("c1");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    addConnector("b2");
    addConnector("b1");
    addConnector("b3");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    expectedChanges.clear();
    listener.clear();

    addConnector("c2");
    addConnector("a1");
    removeConnector("b2");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());
  }

  /** Basic test of adding, updating, and deleting connector instances. */
  public void testAddUpdateRemove() {
    addConnector("c1");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    updateConnector("c1");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    removeConnector("c1");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());
  }

  /** Test of updating schedules and checkpoints. */
  public void testCheckpointsAndSchedules() {
    addConnector("c1");
    addConnector("c2");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    setSchedule("c1");
    setSchedule("c2");
    setCheckpoint("c2");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    expectedChanges.clear();
    listener.clear();

    setSchedule("c1");
    setCheckpoint("c2");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());
  }

  /** Test detecting no changes. */
  public void testNoChanges() {
    addConnector("c1");
    addConnector("c2");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    // With no additional changes, change detector should find nothing.
    expectedChanges.clear();
    listener.clear();
    detector.detect();
    assertNoChanges(expectedChanges, listener.getChanges());

    // With no additional changes, change detector should still find nothing.
    detector.detect();
    assertNoChanges(expectedChanges, listener.getChanges());

    // Finally change something.
    updateConnector("c1");
    addConnector("b3");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());
  }

  /** Test retry connector instantiation if it fails. */
  public void testRetryInstantiationOnAdd() {
    addConnector("c1");
    addConnector("c2");
    detector.detect();
    assertFalse(listener.getChanges().isEmpty());
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    // There should be no pending changes.
    expectedChanges.clear();
    listener.clear();
    detector.detect();
    assertNoChanges(expectedChanges, listener.getChanges());

    // Force a new connector instantiation to fail.
    listener.beBad = true;
    addConnector("c3");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    // The ChangeDetector should retry this one.
    listener.clear();
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    // The ChangeDetector should retry this one, but this time let it succeed.
    listener.beBad = false;
    listener.clear();
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    // There should be no pending changes.
    expectedChanges.clear();
    listener.clear();
    detector.detect();
    assertNoChanges(expectedChanges, listener.getChanges());
  }

  /** Test retry connector instantiation if update config fails. */
  public void testRetryInstantiationOnUpdate() {
    addConnector("c1");
    addConnector("c2");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    // There should be no pending changes.
    expectedChanges.clear();
    listener.clear();
    detector.detect();
    assertNoChanges(expectedChanges, listener.getChanges());

    // Force a updated connector instantiation to fail.
    listener.beBad = true;
    updateConnector("c1");
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    // The ChangeDetector should retry this one.
    listener.clear();
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    // The ChangeDetector should retry this one, but this time let it succeed.
    listener.beBad = false;
    listener.clear();
    detector.detect();
    assertEqualsMultiSet(expectedChanges, listener.getChanges());

    // There should be no pending changes.
    expectedChanges.clear();
    listener.clear();
    detector.detect();
    assertNoChanges(expectedChanges, listener.getChanges());
  }

  /**
   * A ChangeListener that optionally throws InstantiatorException
   * for configuration changes.  Used to test instantiation retry.
   */
  private class ExceptionalChangeListener extends MockChangeListener {
    boolean beBad = false;

    @Override
    public void connectorAdded(String connectorName,
        Configuration configuration) throws InstantiatorException {
      super.connectorAdded(connectorName, configuration);
      if (beBad) {
        throw new InstantiatorException(connectorName);
      }
    }

    @Override
    public void connectorConfigurationChanged(String connectorName,
        Configuration configuration) throws InstantiatorException {
      super.connectorConfigurationChanged(connectorName, configuration);
      if (beBad) {
        throw new InstantiatorException(connectorName);
      }
    }
  }
}
TOP

Related Classes of com.google.enterprise.connector.instantiator.ChangeDetectorTest$ExceptionalChangeListener

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.