blob: d362f59f73b891f7f11e2ad02601a359c3a14a04 [file] [log] [blame]
package org.eclipse.epp.internal.logging.aeri.ide.server.mars;
import static org.eclipse.epp.logging.aeri.core.SendMode.NEVER;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
import java.io.File;
import java.io.IOException;
import org.apache.http.HttpStatus;
import org.apache.lucene.analysis.KeywordAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.epp.internal.logging.aeri.ide.server.mars.ServerProblemsHistory.RemoteProblemsHistoryFilter;
import org.eclipse.epp.internal.logging.aeri.ide.server.mars.ServerProblemsHistory.UpdateIndexJob;
import org.eclipse.epp.internal.logging.aeri.ide.utils.Zips;
import org.eclipse.epp.logging.aeri.core.ISystemSettings;
import org.eclipse.epp.logging.aeri.core.ProblemStatus;
import org.eclipse.epp.logging.aeri.core.ResetSendMode;
import org.eclipse.epp.logging.aeri.core.util.Statuses;
import org.eclipse.epp.logging.aeri.tests.util.TestStatus;
import org.eclipse.epp.logging.aeri.tests.util.TestStatuses;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
public class RemoteProblemsHistoryTest {
private ServerProblemsHistory sut;
private RemoteProblemsHistoryFilter filter;
private TestStatus status;
private RAMDirectory directory;
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Before
public void setup() {
sut = new ServerProblemsHistory(null) {
@Override
protected Directory createIndexDirectory() throws IOException {
directory = new RAMDirectory();
return directory;
}
};
filter = new RemoteProblemsHistoryFilter(sut);
status = new TestStatus();
status.setException(new RuntimeException().fillInStackTrace());
}
@Test
public void testNotRunning() {
// not started should not fail anything
assertTrue(filter.apply(status));
}
@Test
public void testEmptyProblemsDatabase() {
sut.startAsync().awaitRunning();
assertTrue(filter.apply(status));
}
@Test
public void testIndexProblemStatus() throws Exception {
sut.startAsync().awaitRunning();
Status status = TestStatuses.thirdPartyStatus();
index(status, "NEEDINFO");
assertThat(sut.seen(status).getStatus(), is(ProblemStatus.NEEDINFO));
}
@Test
public void testIndexMatchStatus() throws Exception {
sut.startAsync().awaitRunning();
Status status = TestStatuses.multiStatus();
index(status, "FIXED");
// should not match
index(TestStatuses.coreExceptionStatus(), "NONE");
assertThat(sut.seen(status).getStatus(), is(ProblemStatus.FIXED));
}
@Test
public void testUpdateLocalNotOutdated() {
IO io = mock(IO.class);
when(io.getConfiguration()).thenReturn(new ServerConfiguration());
ISystemSettings settings = mock(ISystemSettings.class);
ServerProblemsHistory history = mock(ServerProblemsHistory.class);
when(io.isProblemsDatabaseOutdated()).thenReturn(false);
UpdateIndexJob job = new UpdateIndexJob(io, settings, history);
job.run(mock(IProgressMonitor.class));
verify(io).getConfiguration();
verify(io).isProblemsDatabaseOutdated();
verifyNoMoreInteractions(io);
verifyNoMoreInteractions(settings);
verifyNoMoreInteractions(history);
}
@Test
public void testUpdateRemoteNotModified() throws IOException {
IO io = mock(IO.class);
when(io.getConfiguration()).thenReturn(new ServerConfiguration());
ISystemSettings settings = mock(ISystemSettings.class);
ServerProblemsHistory history = mock(ServerProblemsHistory.class);
when(io.isProblemsDatabaseOutdated()).thenReturn(true);
when(io.downloadDatabase(any(File.class), any(IProgressMonitor.class))).thenReturn(HttpStatus.SC_NOT_MODIFIED);
UpdateIndexJob job = new UpdateIndexJob(io, settings, history);
job.run(mock(IProgressMonitor.class));
verify(io).getConfiguration();
verify(io).isProblemsDatabaseOutdated();
verify(io).downloadDatabase(any(File.class), any(IProgressMonitor.class));
verifyNoMoreInteractions(io);
verifyNoMoreInteractions(settings);
verifyNoMoreInteractions(history);
}
@Test
public void testUpdateFromRemoteFailure() throws IOException {
IO io = mock(IO.class);
when(io.getConfiguration()).thenReturn(new ServerConfiguration());
ISystemSettings settings = mock(ISystemSettings.class);
ServerProblemsHistory history = mock(ServerProblemsHistory.class);
when(io.isProblemsDatabaseOutdated()).thenReturn(true);
when(io.downloadDatabase(any(File.class), any(IProgressMonitor.class))).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);
UpdateIndexJob job = new UpdateIndexJob(io, settings, history);
job.run(mock(IProgressMonitor.class));
verify(io).getConfiguration();
verify(io).isProblemsDatabaseOutdated();
verify(io).downloadDatabase(any(File.class), any(IProgressMonitor.class));
verifyNoMoreInteractions(io);
verify(settings).setSendMode(NEVER);
verify(settings).setResetSendMode(ResetSendMode.RESTART);
verifyNoMoreInteractions(settings);
verifyNoMoreInteractions(history);
}
@Test
public void testUpdateFromRemoteSuccess() throws IOException {
IO io = mock(IO.class);
when(io.getConfiguration()).thenReturn(new ServerConfiguration());
ISystemSettings settings = mock(ISystemSettings.class);
ServerProblemsHistory history = mock(ServerProblemsHistory.class);
when(io.isProblemsDatabaseOutdated()).thenReturn(true);
// the job will try to unzip the index for the service
when(io.downloadDatabase(any(File.class), any(IProgressMonitor.class))).then(new Answer<Integer>() {
@Override
public Integer answer(InvocationOnMock invocation) throws Throwable {
File file = (File) invocation.getArguments()[0];
createMinimalZipFile(file);
return HttpStatus.SC_OK;
}
});
UpdateIndexJob job = new UpdateIndexJob(io, settings, history);
long downloadTimestampBefore = io.getConfiguration().getProblemsZipLastDownloadTimestamp();
job.run(mock(IProgressMonitor.class));
long downloadedTimestampNow = io.getConfiguration().getProblemsZipLastDownloadTimestamp();
assertThat(downloadedTimestampNow, is(not(downloadTimestampBefore)));
verify(io, atLeastOnce()).getConfiguration();
verify(io).isProblemsDatabaseOutdated();
verify(io).downloadDatabase(any(File.class), any(IProgressMonitor.class));
verify(io).saveConfiguration();
verifyNoMoreInteractions(io);
verifyNoMoreInteractions(settings);
verify(history).replaceContent(any(File.class));
}
private void index(Status status, String problemStatus) throws CorruptIndexException, LockObtainFailedException, IOException {
IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_35, new KeywordAnalyzer());
conf.setOpenMode(OpenMode.CREATE_OR_APPEND);
try (IndexWriter writer = new IndexWriter(directory, conf)) {
Document doc = new Document();
doc.add(new Field(ServerProblemsHistory.F_FINGERPRINT, Statuses.traceIdentityHash(status), Store.NO, Index.NOT_ANALYZED));
doc.add(new Field(ServerProblemsHistory.F_ACTION, problemStatus, Store.YES, Index.NO));
writer.addDocument(doc);
writer.commit();
sut.indexChanged();
}
}
private void createMinimalZipFile(File file) throws IOException {
File folder = temporaryFolder.newFolder();
File f = new File(folder, "empty");
f.createNewFile();
Zips.zip(folder, file);
}
}