blob: 2dcb2490eb1244242cbc51fb4b5b2282f19160c9 [file] [log] [blame]
// Copyright 2011 Google Inc. All Rights Reserved.
//
// 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.adaptor;
import static org.junit.Assert.*;
import org.junit.*;
import org.junit.rules.ExpectedException;
import java.io.IOException;
import java.util.*;
/**
* Test cases for {@link DocIdSender}.
*/
public class DocIdSenderTest {
private MockGsaFeedFileMaker fileMaker = new MockGsaFeedFileMaker();
private MockGsaFeedFileSender fileSender = new MockGsaFeedFileSender();
private Journal journal = new Journal(new MockTimeProvider());
private Config config = new Config();
private DocIdsMockAdaptor adaptor = new DocIdsMockAdaptor();
private DocIdSender docIdSender
= new DocIdSender(fileMaker, fileSender, journal, config, adaptor);
private GetDocIdsErrorHandler runtimeExceptionHandler
= new RuntimeExceptionGetDocIdsErrorHandler();
@Rule
public ExpectedException thrown = ExpectedException.none();
@Before
public void setup() {
config.setValue("gsa.hostname", "localhost");
}
@Test
public void testPushDocIdsFromAdaptorNormal() throws Exception {
adaptor.pushItems = new ArrayList<List<DocIdPusher.Record>>();
DocIdPusher.Record[] records = new DocIdPusher.Record[6];
for (int i = 0; i < records.length; i++) {
DocId id = new DocId("test" + i);
records[i] = new DocIdPusher.Record.Builder(id).build();
}
List<DocIdPusher.Record> infos = new ArrayList<DocIdPusher.Record>();
infos.add(records[0]);
infos.add(records[1]);
infos.add(records[2]);
infos.add(records[3]);
infos.add(records[4]);
adaptor.pushItems.add(infos);
infos = new ArrayList<DocIdPusher.Record>();
infos.add(records[5]);
adaptor.pushItems.add(infos);
config.setValue("feed.maxUrls", "2");
config.setValue("feed.name", "testing");
docIdSender.pushFullDocIdsFromAdaptor(runtimeExceptionHandler);
assertEquals(4, fileMaker.i);
assertEquals(Arrays.asList(new String[] {
"testing", "testing", "testing", "testing",
}), fileMaker.names);
assertEquals(Arrays.asList(new List[] {
Arrays.asList(new DocIdPusher.Record[] {records[0], records[1]}),
Arrays.asList(new DocIdPusher.Record[] {records[2], records[3]}),
Arrays.asList(new DocIdPusher.Record[] {records[4]}),
Arrays.asList(new DocIdPusher.Record[] {records[5]}),
}), fileMaker.recordses);
assertEquals(Arrays.asList(new String[] {
"localhost", "localhost", "localhost", "localhost",
}), fileSender.hosts);
assertEquals(Arrays.asList(new String[] {
"testing", "testing", "testing", "testing",
}), fileSender.datasources);
assertEquals(Arrays.asList(new String[] {
"0", "1", "2", "3",
}), fileSender.xmlStrings);
}
@Test
public void testPushDocIdsNoHandler() throws Exception {
// Don't send anything.
adaptor.pushItems = new ArrayList<List<DocIdPusher.Record>>();
thrown.expect(NullPointerException.class);
docIdSender.pushFullDocIdsFromAdaptor(null);
}
@Test
public void testPushDocIdsIterrupted() throws Exception {
MockAdaptor adaptor = new MockAdaptor() {
@Override
public void getDocIds(DocIdPusher pusher) throws InterruptedException {
throw new InterruptedException();
}
};
docIdSender = new DocIdSender(fileMaker, fileSender, journal, config,
adaptor);
thrown.expect(InterruptedException.class);
docIdSender.pushFullDocIdsFromAdaptor(runtimeExceptionHandler);
}
@Test
public void testPushDocIdsFailure() throws Exception {
class FailureAdaptor extends MockAdaptor {
private int times;
@Override
public void getDocIds(DocIdPusher pusher) throws IOException {
times++;
throw new IOException();
}
}
class TryTwiceGetDocIdsErrorHandler implements GetDocIdsErrorHandler {
@Override
public boolean handleFailedToGetDocIds(Exception ex, int ntries) {
return ntries < 2;
}
}
FailureAdaptor adaptor = new FailureAdaptor();
GetDocIdsErrorHandler errorHandler = new TryTwiceGetDocIdsErrorHandler();
docIdSender = new DocIdSender(fileMaker, fileSender, journal, config,
adaptor);
docIdSender.pushFullDocIdsFromAdaptor(errorHandler);
assertEquals(2, adaptor.times);
}
@Test
public void testPushSizedBatchFailedToConnect() throws Exception {
fileSender = new MockGsaFeedFileSender() {
@Override
public void sendMetadataAndUrl(String host, String datasource,
String xmlString, boolean useCompression)
throws FailedToConnect {
throw new FailedToConnect(new IOException());
}
};
docIdSender = new DocIdSender(fileMaker, fileSender, journal, config,
adaptor);
List<DocId> ids = Arrays.asList(new DocId[] {new DocId("test")});
NeverRetryPushErrorHandler errorHandler = new NeverRetryPushErrorHandler();
docIdSender.pushDocIds(ids, errorHandler);
assertEquals(1, errorHandler.failedToConnect);
}
@Test
public void testPushSizedBatchFailedWriting() throws Exception {
fileSender = new MockGsaFeedFileSender() {
@Override
public void sendMetadataAndUrl(String host, String datasource,
String xmlString, boolean useCompression)
throws FailedWriting {
throw new FailedWriting(new IOException());
}
};
docIdSender = new DocIdSender(fileMaker, fileSender, journal, config,
adaptor);
List<DocId> ids = Arrays.asList(new DocId[] {new DocId("test")});
NeverRetryPushErrorHandler errorHandler = new NeverRetryPushErrorHandler();
docIdSender.pushDocIds(ids, errorHandler);
assertEquals(1, errorHandler.failedWriting);
}
@Test
public void testPushSizedBatchRetrying() throws Exception {
fileSender = new MockGsaFeedFileSender() {
@Override
public void sendMetadataAndUrl(String host, String datasource,
String xmlString, boolean useCompression)
throws FailedWriting {
throw new FailedWriting(new IOException());
}
};
docIdSender = new DocIdSender(fileMaker, fileSender, journal, config,
adaptor);
List<DocId> ids = Arrays.asList(new DocId[] {new DocId("test")});
NeverRetryPushErrorHandler errorHandler = new NeverRetryPushErrorHandler() {
@Override
public boolean handleFailedWriting(Exception ex, int ntries) {
super.handleFailedWriting(ex, ntries);
return ntries < 2;
}
};
docIdSender.pushDocIds(ids, errorHandler);
assertEquals(2, errorHandler.failedWriting);
}
@Test
public void testPushSizedBatchFailedReadingReply() throws Exception {
fileSender = new MockGsaFeedFileSender() {
@Override
public void sendMetadataAndUrl(String host, String datasource,
String xmlString, boolean useCompression)
throws FailedReadingReply {
throw new FailedReadingReply(new IOException());
}
};
docIdSender = new DocIdSender(fileMaker, fileSender, journal, config,
adaptor);
List<DocId> ids = Arrays.asList(new DocId[] {new DocId("test")});
NeverRetryPushErrorHandler errorHandler = new NeverRetryPushErrorHandler();
docIdSender.pushDocIds(ids, errorHandler);
assertEquals(1, errorHandler.failedReadingReply);
}
@Test
public void testNamedResources() throws Exception {
config.setValue("feed.name", "testing");
assertNull(docIdSender.pushNamedResources(
Collections.singletonMap(new DocId("test"), Acl.EMPTY),
new NeverRetryPushErrorHandler()));
assertEquals(1, fileSender.hosts.size());
}
@Test
public void testNamedResourcesFailed() throws Exception {
fileSender = new MockGsaFeedFileSender() {
@Override
public void sendMetadataAndUrl(String host, String datasource,
String xmlString, boolean useCompression)
throws FailedReadingReply {
throw new FailedReadingReply(new IOException());
}
};
docIdSender = new DocIdSender(fileMaker, fileSender, journal, config,
adaptor);
Map<DocId, Acl> resources = new TreeMap<DocId, Acl>();
resources.put(new DocId("aaa"), Acl.EMPTY);
resources.put(new DocId("bbb"), Acl.EMPTY);
assertEquals(new DocId("aaa"), docIdSender.pushNamedResources(resources,
new NeverRetryPushErrorHandler()));
}
@Test
public void testNullNamedResource() throws Exception {
thrown.expect(NullPointerException.class);
docIdSender.pushNamedResources(
Collections.singletonMap(new DocId("test"), (Acl) null));
}
@Test
public void testNullNamedResourceAcl() throws Exception {
thrown.expect(NullPointerException.class);
docIdSender.pushNamedResources(
Collections.singletonMap((DocId) null, Acl.EMPTY));
}
private static class MockGsaFeedFileMaker extends GsaFeedFileMaker {
List<String> names = new ArrayList<String>();
List<List<? extends DocIdSender.Item>> recordses
= new ArrayList<List<? extends DocIdSender.Item>>();
int i;
public MockGsaFeedFileMaker() {
super(null);
}
@Override
public String makeMetadataAndUrlXml(String name,
List<? extends DocIdSender.Item> items) {
names.add(name);
recordses.add(items);
return "" + i++;
}
}
private static class MockGsaFeedFileSender extends GsaFeedFileSender {
List<String> hosts = new ArrayList<String>();
List<String> datasources = new ArrayList<String>();
List<String> xmlStrings = new ArrayList<String>();
public MockGsaFeedFileSender() {
super(new Config());
}
@Override
public void sendMetadataAndUrl(String host, String datasource,
String xmlString, boolean useCompression)
throws FailedToConnect, FailedWriting, FailedReadingReply {
hosts.add(host);
datasources.add(datasource);
xmlStrings.add(xmlString);
}
}
private static class RuntimeExceptionGetDocIdsErrorHandler
implements GetDocIdsErrorHandler {
@Override
public boolean handleFailedToGetDocIds(Exception ex, int ntries) {
throw new TriggeredException(ex);
}
public static class TriggeredException extends RuntimeException {
public TriggeredException(Throwable cause) {
super(cause);
}
}
}
private static class NeverRetryPushErrorHandler implements PushErrorHandler {
private int failedToConnect;
private int failedWriting;
private int failedReadingReply;
@Override
public boolean handleFailedToConnect(Exception ex, int ntries) {
failedToConnect++;
return false;
}
@Override
public boolean handleFailedWriting(Exception ex, int ntries) {
failedWriting++;
return false;
}
@Override
public boolean handleFailedReadingReply(Exception ex, int ntries) {
failedReadingReply++;
return false;
}
}
private static class DocIdsMockAdaptor extends MockAdaptor {
public List<List<DocIdPusher.Record>> pushItems;
public int timesGetDocIdsCalled;
/**
* Throws a {@link NullPointerException} unless {@link #pushItems} has been
* set.
*/
@Override
public void getDocIds(DocIdPusher pusher) throws InterruptedException,
IOException {
timesGetDocIdsCalled++;
for (List<DocIdPusher.Record> infos : pushItems) {
pusher.pushRecords(infos);
}
}
}
}