// Copyright 2011 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.manager;
import com.google.enterprise.connector.common.PropertiesUtils;
import com.google.enterprise.connector.common.StringUtils;
import com.google.enterprise.connector.instantiator.Configuration;
import com.google.enterprise.connector.instantiator.MockInstantiator;
import com.google.enterprise.connector.instantiator.ThreadPool;
import com.google.enterprise.connector.persist.ConnectorNotFoundException;
import com.google.enterprise.connector.pusher.MockFeedConnection;
import com.google.enterprise.connector.scheduler.Schedule;
import com.google.enterprise.connector.spi.AuthenticationIdentity;
import com.google.enterprise.connector.spi.AuthenticationManager;
import com.google.enterprise.connector.spi.AuthenticationResponse;
import com.google.enterprise.connector.spi.AuthorizationManager;
import com.google.enterprise.connector.spi.AuthorizationResponse;
import com.google.enterprise.connector.spi.ConfigureResponse;
import com.google.enterprise.connector.spi.ConnectorType;
import com.google.enterprise.connector.spi.Document;
import com.google.enterprise.connector.spi.MockConnector;
import com.google.enterprise.connector.spi.MockRetriever;
import com.google.enterprise.connector.spi.RepositoryDocumentException;
import com.google.enterprise.connector.spi.RepositoryException;
import com.google.enterprise.connector.spi.RepositoryLoginException;
import com.google.enterprise.connector.spi.SimpleAuthenticationIdentity;
import com.google.enterprise.connector.spi.SpiConstants;
import com.google.enterprise.connector.spi.Value;
import com.google.enterprise.connector.traversal.TraversalStateStore;
import com.google.enterprise.connector.util.SystemClock;
import junit.framework.TestCase;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/** Tests for {@link ProductionManager}. */
public class ProductionManagerTest extends TestCase {
ProductionManager manager;
MockInstantiator instantiator;
AuthenticationIdentity identity;
String connectorName;
protected void setUp() throws Exception {
ThreadPool threadPool = new ThreadPool(5, new SystemClock());
instantiator = new MockInstantiator(threadPool);
instantiator.setupTestTraversers();
manager = new ProductionManager();
manager.setInstantiator(instantiator);
manager.setFeedConnection(new MockFeedConnection());
connectorName = MockInstantiator.TRAVERSER_NAME1;
identity = new SimpleAuthenticationIdentity("bar");
}
/** Test authenticate() with no AuthenticationManager. */
public void testAuthenticateNoAuthenticationManger() throws Exception {
instantiator.addConnector(connectorName,
new MockConnector(null, null, null, null, null));
AuthenticationResponse response =
manager.authenticate(connectorName, identity);
assertNotNull(response);
assertFalse(response.isValid());
assertNull(response.getData());
assertNull(response.getGroups());
}
/** Test authenticate() with success response. */
public void testAuthenticateSuccess() throws Exception {
instantiator.addConnector(connectorName, new MockConnector(null,
new AuthenticatingAuthenticationManager(), null, null, null));
AuthenticationResponse response =
manager.authenticate(connectorName, identity);
assertNotNull(response);
assertTrue(response.isValid());
assertEquals("bar", response.getData());
}
/** Test authenticate() ConnectorNotFoundException. */
public void testAuthenticateConnectorNotFoundException() throws Exception {
instantiator.addConnector(connectorName, new MockConnector(null,
new AuthenticatingAuthenticationManager(), null, null, null));
AuthenticationResponse response =
manager.authenticate("nonexistent", identity);
assertNotNull(response);
assertFalse(response.isValid());
assertNull(response.getData());
assertNull(response.getGroups());
}
/** Test authenticate() throws RepositoryException. */
public void testAuthenticateRepositoryException() throws Exception {
instantiator.addConnector(connectorName, new MockConnector(null,
new ExceptionalAuthenticationManager(new RepositoryException()),
null, null, null));
AuthenticationResponse response =
manager.authenticate(connectorName, identity);
assertNotNull(response);
assertFalse(response.isValid());
assertNull(response.getData());
assertNull(response.getGroups());
}
/** Test authenticate() throws RepositoryLoginException. */
public void testAuthenticateRepositoryLoginException() throws Exception {
instantiator.addConnector(connectorName, new MockConnector(null,
new ExceptionalAuthenticationManager(new RepositoryLoginException()),
null, null, null));
AuthenticationResponse response =
manager.authenticate(connectorName, identity);
assertNotNull(response);
assertFalse(response.isValid());
assertNull(response.getData());
assertNull(response.getGroups());
}
/** Test authenticate() throws RuntimeException. */
public void testAuthenticateRuntimeException() throws Exception {
instantiator.addConnector(connectorName, new MockConnector(null,
new ExceptionalAuthenticationManager(null), null, null, null));
AuthenticationResponse response = manager.authenticate(
connectorName, identity);
assertNotNull(response);
assertFalse(response.isValid());
assertNull(response.getData());
assertNull(response.getGroups());
}
/** AuthenticationManager that authenticates anybody. */
private static class AuthenticatingAuthenticationManager
implements AuthenticationManager {
public AuthenticationResponse authenticate(AuthenticationIdentity id) {
return new AuthenticationResponse(true, id.getUsername());
}
}
/** AuthenticationManager that throws the given exception. */
private static class ExceptionalAuthenticationManager
implements AuthenticationManager {
RepositoryException re;
public ExceptionalAuthenticationManager(RepositoryException re) {
this.re = re;
}
public AuthenticationResponse authenticate(AuthenticationIdentity id)
throws RepositoryException {
if (re == null) {
throw new RuntimeException("testing");
}
throw re;
}
}
/** Test authorizeDocids with no AuthorizationManager. */
public void testAuthorizeDocidsNoAuthorizationManager() throws Exception {
instantiator.addConnector(connectorName,
new MockConnector(null, null, null, null, null));
List<String> docids = Arrays.asList(new String[] { "foo", "bar", "baz" });
assertNull(manager.authorizeDocids(connectorName, docids, identity));
}
/** Test authorizeDocids with Exception throwing AuthorizationManager. */
public void testAuthorizeDocidsExceptionalAuthorizationManager()
throws Exception {
instantiator.addConnector(connectorName, new MockConnector(null, null,
new ExceptionalAuthorizationManager(), null, null));
List<String> docids = Arrays.asList(new String[] { "foo", "bar", "baz" });
assertNull(manager.authorizeDocids(connectorName, docids, identity));
}
/** Test authorizeDocids with ConnectorNotFound. */
public void testAuthorizeDocidsConnectorNotFound() throws Exception {
List<String> docids = Arrays.asList(new String[] { "foo", "bar", "baz" });
assertNull(manager.authorizeDocids("nonexistent", docids, identity));
}
/** Test authorizeDocids. */
public void testAuthorizeDocids() throws Exception {
instantiator.addConnector(connectorName, new MockConnector(null, null,
new AuthorizeAllAuthorizationManager(), null, null));
List<String> docids = Arrays.asList(new String[] { "foo", "bar", "baz" });
Collection<AuthorizationResponse> authorized =
manager.authorizeDocids(connectorName, docids, identity);
assertNotNull(authorized);
assertFalse(authorized.isEmpty());
for (String docid : docids) {
checkContainsDocid(authorized, docid);
}
}
/** Check if the Collection of AuthorizationResponses contains a response
* for docid.
*/
private boolean checkContainsDocid(
Collection<AuthorizationResponse> authorized, String docid) {
for (AuthorizationResponse response : authorized) {
if (response.getDocid().equals(docid)) {
return true;
}
}
return false;
}
/** AuthorizationManager that authorizes all docs. */
private static class AuthorizeAllAuthorizationManager
implements AuthorizationManager {
public Collection<AuthorizationResponse> authorizeDocids(
Collection<String> docids, AuthenticationIdentity identity) {
HashSet<AuthorizationResponse> response =
new HashSet<AuthorizationResponse>();
for (String docid : docids) {
response.add(new AuthorizationResponse(true, docid));
}
return response;
}
}
/** AuthorizationManager that throws RepositoryException. */
private static class ExceptionalAuthorizationManager
implements AuthorizationManager {
public Collection<AuthorizationResponse> authorizeDocids(
Collection<String> docids, AuthenticationIdentity identity)
throws RepositoryException {
throw new RepositoryException();
}
}
/** Test getDocumentContent with ConnectorNotFound. */
public void testGetDocumentContentConnectorNotFound() throws Exception {
try {
manager.getDocumentContent("nonexistent", "docid");
fail("Expected ConnectorNotFoundException");
} catch (ConnectorNotFoundException expected) {
// Expected.
}
}
/** Test getDocumentContent with no Retriever. */
public void testGetDocumentContentNoRetriever() throws Exception {
instantiator.addConnector(connectorName,
new MockConnector(null, null, null, null, null));
assertNull(manager.getDocumentContent(connectorName, "docid"));
}
/** Test getDocumentContent with Document NotFound. */
public void testGetDocumentContentDocumentNotFound() throws Exception {
instantiator.addConnector(connectorName,
new MockConnector(null, null, null, new MockRetriever(), null));
try {
manager.getDocumentContent(connectorName, MockRetriever.DOCID_NOT_FOUND);
fail("Expected RepositoryDocumentException");
} catch (RepositoryDocumentException expected) {
// Expected.
}
}
/** Test getDocumentContent with RepositoryException. */
public void testGetDocumentContentRepositoryException() throws Exception {
instantiator.addConnector(connectorName,
new MockConnector(null, null, null, new MockRetriever(), null));
try {
manager.getDocumentContent(connectorName,
MockRetriever.DOCID_REPOSITORY_EXCEPTION);
fail("Expected RepositoryException");
} catch (RepositoryException expected) {
// Expected.
}
}
/** Test getDocumentContent where document has no content. */
public void testGetDocumentContentNoContent() throws Exception {
instantiator.addConnector(connectorName,
new MockConnector(null, null, null, new MockRetriever(), null));
InputStream in = manager.getDocumentContent(connectorName,
MockRetriever.DOCID_NO_CONTENT);
// GSA still doesn't handle docs with no content, so the
// Production Manager substitutes a single space.
assertNotNull(in);
assertEquals(" ", StringUtils.streamToString(in));
}
/** Test getDocumentContent where document has empty content. */
public void testGetDocumentContentEmptyContent() throws Exception {
instantiator.addConnector(connectorName,
new MockConnector(null, null, null, new MockRetriever(), null));
InputStream in = manager.getDocumentContent(connectorName,
MockRetriever.DOCID_NO_CONTENT);
// GSA still doesn't handle docs with no content, so the
// Production Manager substitutes a single space.
assertNotNull(in);
assertEquals(" ", StringUtils.streamToString(in));
}
/** Test getDocumentContent. */
public void testGetDocumentContent() throws Exception {
instantiator.addConnector(connectorName,
new MockConnector(null, null, null, new MockRetriever(), null));
InputStream in = manager.getDocumentContent(connectorName, "docid");
assertNotNull(in);
assertEquals("docid", StringUtils.streamToString(in));
}
/** Test getDocumentMetaData with ConnectorNotFound. */
public void testGetDocumentMetaDataConnectorNotFound() throws Exception {
try {
manager.getDocumentMetaData("nonexistent", "docid");
fail("Expected ConnectorNotFoundException");
} catch (ConnectorNotFoundException expected) {
// Expected.
}
}
/** Test getDocumentMetaData with no Retriever. */
public void testGetDocumentMetaDataNoRetriever() throws Exception {
instantiator.addConnector(connectorName,
new MockConnector(null, null, null, null, null));
assertNull(manager.getDocumentMetaData(connectorName, "docid"));
}
/** Test getDocumentMetaData with Document NotFound. */
public void testGetDocumentMetaDataDocumentNotFound() throws Exception {
instantiator.addConnector(connectorName,
new MockConnector(null, null, null, new MockRetriever(), null));
try {
manager.getDocumentMetaData(connectorName, MockRetriever.DOCID_NOT_FOUND);
fail("Expected RepositoryDocumentException");
} catch (RepositoryDocumentException expected) {
// Expected.
}
}
/** Test getDocumentMetaData with RepositoryException. */
public void testGetDocumentMetaDataRepositoryException() throws Exception {
instantiator.addConnector(connectorName,
new MockConnector(null, null, null, new MockRetriever(), null));
try {
manager.getDocumentMetaData(connectorName,
MockRetriever.DOCID_REPOSITORY_EXCEPTION);
fail("Expected RepositoryException");
} catch (RepositoryException expected) {
// Expected.
}
}
/** Test getDocumentMetaData. */
public void testGetDocumentMetaData() throws Exception {
instantiator.addConnector(connectorName,
new MockConnector(null, null, null, new MockRetriever(), null));
Document document = manager.getDocumentMetaData(connectorName, "docid");
assertNotNull(document);
assertEquals("docid",
Value.getSingleValueString(document, SpiConstants.PROPNAME_DOCID));
}
/** Test getConnectorStatus. */
public void testGetConnectorStatus() throws Exception {
ConnectorStatus status = manager.getConnectorStatus(connectorName);
assertNotNull(status);
assertEquals(connectorName, status.getName());
assertEquals(0, status.getStatus());
assertEquals(instantiator.getConnectorTypeName(connectorName),
status.getType());
assertNotNull(status.getSchedule());
assertTrue(status.getSchedule().startsWith("#"));
Schedule sched = new Schedule(connectorName, false, 200, 1000, "1-2");
String schedStr = sched.toString();
manager.setSchedule(connectorName, schedStr);
status = manager.getConnectorStatus(connectorName);
assertNotNull(status);
assertEquals(schedStr, status.getSchedule());
try {
status = manager.getConnectorStatus("nonexistent");
fail("Expected ConnectorNotFoundException");
} catch (ConnectorNotFoundException expected) {
// Expected
}
}
/** Test getConnectorStatuses. */
public void testGetConnectorStatuses() throws Exception {
List<ConnectorStatus> statuses = manager.getConnectorStatuses();
assertNotNull(statuses);
assertFalse(statuses.isEmpty());
}
/** Test getConnectorTypeNames. */
public void testGetConnectorTypeNames() throws Exception {
Set<String> typeNames = manager.getConnectorTypeNames();
assertNotNull(typeNames);
assertFalse(typeNames.isEmpty());
assertEquals(instantiator.getConnectorTypeNames(), typeNames);
}
/** Test getConnectorType. */
public void testGetConnectorType() throws Exception {
String typeName = instantiator.getConnectorTypeName(connectorName);
ConnectorType type = manager.getConnectorType(typeName);
assertNotNull(type);
assertEquals(instantiator.getConnectorType(connectorName), type);
}
/** Test getConfigForm. */
public void testGetConfigForm() throws Exception {
String typeName = instantiator.getConnectorTypeName(connectorName);
ConfigureResponse response = manager.getConfigForm(typeName, "en");
assertNotNull(response);
assertTrue(response.getMessage().contains(typeName));
}
/** Test getConfigFormForConnector. */
public void testGetConfigFormForConnector() throws Exception {
ConfigureResponse response =
manager.getConfigFormForConnector(connectorName, "en");
assertNotNull(response);
}
/** Test setConnectorConfiguration and getConnctorConfiguration. */
public void testSetAndGetConnectorConfiguration() throws Exception {
String typeName = instantiator.getConnectorTypeName(connectorName);
Map<String, String> config = new HashMap<String, String>();
config.put(PropertiesUtils.GOOGLE_CONNECTOR_NAME, connectorName);
Configuration configuration = new Configuration(typeName, config, null);
ConfigureResponse response = manager.setConnectorConfiguration(
connectorName, configuration, "en", true);
assertNull(response);
assertEquals(instantiator.getConnectorConfiguration(connectorName),
manager.getConnectorConfiguration(connectorName));
}
/** Test setConnectorSchedule and getConnectorSchedule. */
public void testSetAndGetConnectorSchedule() throws Exception {
Schedule sched = new Schedule(connectorName, false, 200, 1000, "1-2");
assertFalse(sched.equals(instantiator.getConnectorSchedule(connectorName)));
manager.setSchedule(connectorName, sched.toString());
assertEquals(sched, instantiator.getConnectorSchedule(connectorName));
manager.setSchedule(connectorName, null);
assertNull(instantiator.getConnectorSchedule(connectorName));
}
/** Test restartConnectorTraversal. */
public void testRestartTraversal() throws Exception {
TraversalStateStore store =
instantiator.getTraversalStateStore(connectorName);
store.storeTraversalState("checkpoint");
assertEquals("checkpoint", store.getTraversalState());
manager.restartConnectorTraversal(connectorName);
assertNull(store.getTraversalState());
}
/** Test removeConnector. */
public void testRemoveConnector() throws Exception {
String typeName = instantiator.getConnectorTypeName(connectorName);
Map<String, String> config = new HashMap<String, String>();
config.put(PropertiesUtils.GOOGLE_CONNECTOR_NAME, connectorName);
Configuration configuration = new Configuration(typeName, config, null);
ConfigureResponse response = manager.setConnectorConfiguration(
connectorName, configuration, "en", true);
assertNull(response);
manager.getConnectorConfiguration(connectorName);
assertEquals(instantiator.getConnectorConfiguration(connectorName),
configuration);
manager.removeConnector(connectorName);
try {
manager.getConnectorConfiguration(connectorName);
fail("Expected ConnectorNotFoundException");
} catch (ConnectorNotFoundException expected) {
// Expected.
}
}
}