/**
* Copyright (c) 2016 Codetrails GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andreas Sewe - initial API and implementation.
*/
package org.eclipse.recommenders.news.impl.poll;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.util.resource.PathResource;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class DefaultDownloadServiceTest {
private static Server server;
private static URI serverUri;
@ClassRule
public static TemporaryFolder serverRoot = new TemporaryFolder();
@Rule
public TemporaryFolder temp = new TemporaryFolder();
@BeforeClass
public static void setUpClass() throws Exception {
server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(0);
server.addConnector(connector);
server.setStopAtShutdown(true);
HandlerList handlerList = new HandlerList();
ResourceHandler resourceHandler = new ResourceHandler();
resourceHandler.setBaseResource(new PathResource(serverRoot.getRoot().toPath()));
ContextHandler contextHandler = new ContextHandler();
contextHandler.setHandler(resourceHandler);
contextHandler.addAliasCheck(new ContextHandler.ApproveAliases());
handlerList.addHandler(contextHandler);
handlerList.addHandler(new DefaultHandler());
server.setHandler(handlerList);
server.start();
String host = connector.getHost() == null ? "localhost" : connector.getHost();
int port = connector.getLocalPort();
serverUri = new URI(String.format("http://%s:%d/", host, port));
}
@Test
public void testDownloadPresentResource() throws Exception {
serveResource("present.txt", "content");
URI uri = serverUri.resolve("present.txt");
DefaultDownloadService sut = new DefaultDownloadService(temp.getRoot().toPath());
InputStream stream = sut.download(uri, null);
String content = IOUtils.toString(stream, StandardCharsets.UTF_8.toString());
assertThat(content, is(equalTo("content")));
}
@Test(expected = IOException.class)
public void testDownloadEmptyResource() throws Exception {
serveResource("empty.txt", "");
URI uri = serverUri.resolve("empty.txt");
DefaultDownloadService sut = new DefaultDownloadService(temp.getRoot().toPath());
sut.download(uri, null);
}
@Test(expected = IOException.class)
public void testDownloadMissingResource() throws Exception {
URI uri = serverUri.resolve("missing.txt");
DefaultDownloadService sut = new DefaultDownloadService(temp.getRoot().toPath());
sut.download(uri, null);
}
@Test
public void testReadPresentResource() throws Exception {
serveResource("present.txt", "content");
URI uri = serverUri.resolve("present.txt");
DefaultDownloadService sut = new DefaultDownloadService(temp.getRoot().toPath());
sut.download(uri, null);
InputStream stream = sut.read(uri);
String content = IOUtils.toString(stream, StandardCharsets.UTF_8.toString());
assertThat(content, is(equalTo("content")));
}
@Test
public void testReadPreviouslyPresentResource() throws Exception {
Path presentTxt = serveResource("present.txt", "content");
URI uri = serverUri.resolve("present.txt");
DefaultDownloadService sut = new DefaultDownloadService(temp.getRoot().toPath());
sut.download(uri, null);
Files.delete(presentTxt);
try {
sut.download(uri, null);
fail("IOException expected");
} catch (IOException e) {
// Ignore
}
InputStream stream = sut.read(uri);
String content = IOUtils.toString(stream, StandardCharsets.UTF_8.toString());
assertThat(content, is(equalTo("content")));
}
@Test(expected = IOException.class)
public void testReadEmptyResource() throws Exception {
serveResource("empty.txt", "");
URI uri = serverUri.resolve("empty.txt");
DefaultDownloadService sut = new DefaultDownloadService(temp.getRoot().toPath());
try {
sut.download(uri, null);
fail("IOException expected");
} catch (IOException e) {
// Ignore
}
sut.read(uri);
}
@Test(expected = IOException.class)
public void testReadMissingResource() throws Exception {
URI uri = serverUri.resolve("missing.txt");
DefaultDownloadService sut = new DefaultDownloadService(temp.getRoot().toPath());
try {
sut.download(uri, null);
fail("IOException expected");
} catch (IOException e) {
// Ignore
}
sut.read(uri);
}
@Test
public void testReadNeverDownloadedResource() throws Exception {
URI uri = serverUri.resolve("never.txt");
DefaultDownloadService sut = new DefaultDownloadService(temp.getRoot().toPath());
InputStream stream = sut.read(uri);
assertThat(stream, is(nullValue()));
}
@Test
public void testGetLastAttemptDatePresentResource() throws Exception {
serveResource("present.txt", "content");
URI uri = serverUri.resolve("present.txt");
DefaultDownloadService sut = new DefaultDownloadService(temp.getRoot().toPath());
Date beforeDownload = now(-2, SECONDS); // Adjust by 2s to account for coarse-grained file system timestamps
sut.download(uri, null);
Date afterDownload = now(+2, SECONDS); // Adjust by 2s to account for coarse-grained file system timestamps
Date lastAttemptDate = sut.getLastAttemptDate(uri);
assertThat(lastAttemptDate, is(greaterThanOrEqualTo(beforeDownload)));
assertThat(lastAttemptDate, is(lessThanOrEqualTo(afterDownload)));
}
@Test
public void testGetLastAttemptDatePreviouslyPresentResource() throws Exception {
Path presentTxt = serveResource("present.txt", "content");
URI uri = serverUri.resolve("present.txt");
DefaultDownloadService sut = new DefaultDownloadService(temp.getRoot().toPath());
sut.download(uri, null);
Date previousAttemptDate = sut.getLastAttemptDate(uri);
Files.delete(presentTxt);
Thread.sleep(SECONDS.toMillis(2)); // Account for coarse-grained file system timestamps
try {
sut.download(uri, null);
fail("IOException expected");
} catch (IOException e) {
// Ignore
}
Date lastAttemptDate = sut.getLastAttemptDate(uri);
assertThat(lastAttemptDate, is(greaterThan(previousAttemptDate)));
}
@Test
public void testGetLastAttemptDateEmptyResource() throws Exception {
serveResource("empty.txt", "");
URI uri = serverUri.resolve("empty.txt");
DefaultDownloadService sut = new DefaultDownloadService(temp.getRoot().toPath());
Date beforeDownload = now(-2, SECONDS); // Adjust by 2s to account for coarse-grained file system timestamps
try {
sut.download(uri, null);
fail("IOException expected");
} catch (IOException e) {
// Ignore
}
Date afterDownload = now(+2, SECONDS); // Adjust by 2s to account for coarse-grained file system timestamps
Date lastAttemptDate = sut.getLastAttemptDate(uri);
assertThat(lastAttemptDate, is(greaterThanOrEqualTo(beforeDownload)));
assertThat(lastAttemptDate, is(lessThanOrEqualTo(afterDownload)));
}
@Test
public void testGetLastAttemptDateMissingResource() throws Exception {
URI uri = serverUri.resolve("missing.txt");
DefaultDownloadService sut = new DefaultDownloadService(temp.getRoot().toPath());
Date beforeDownload = now(-2, SECONDS); // Adjust by 2s to account for coarse-grained file system timestamps
try {
sut.download(uri, null);
fail("IOException expected");
} catch (IOException e) {
// Ignore
}
Date afterDownload = now(+2, SECONDS); // Adjust by 2s to account for coarse-grained file system timestamps
Date lastAttemptDate = sut.getLastAttemptDate(uri);
assertThat(lastAttemptDate, is(greaterThanOrEqualTo(beforeDownload)));
assertThat(lastAttemptDate, is(lessThanOrEqualTo(afterDownload)));
}
@Test
public void testGetLastAttemptDateNeverDownloadedResource() throws Exception {
URI uri = serverUri.resolve("never.txt");
DefaultDownloadService sut = new DefaultDownloadService(temp.getRoot().toPath());
Date lastAttemptDate = sut.getLastAttemptDate(uri);
assertThat(lastAttemptDate, is(nullValue()));
}
@AfterClass
public static void tearDownClass() throws Exception {
server.stop();
}
private Path serveResource(String path, String content) throws IOException {
Path file = serverRoot.getRoot().toPath().resolve(path);
Files.newBufferedWriter(file, StandardCharsets.UTF_8).append(content).close();
return file;
}
private Date now(long delta, TimeUnit timeUnit) {
long now = System.currentTimeMillis();
return new Date(now + timeUnit.toMillis(delta));
}
}