[JENKINS-16215] Avoiding unnecessary downloads in FilePath.installIfNecessaryFrom.

The updated version uses the locally cached timestamp, '.timestamp', to set the
'If-Modified-Since' header. 304 Not Modified responses are dealt with by
aborting the installation.
This commit is contained in:
Lars Hvile committed 2012-12-28 14:43:41 +01:00
1 parent d43b978f92
commit 35f7653b7b
2 files changed
+86 -1

No files matched your search

@@ -23,6 +23,7 @@
*/
package hudson;
import static org.mockito.Mockito.*;
import hudson.FilePath.TarCompression;
import hudson.model.TaskListener;
import hudson.remoting.LocalChannel;
@@ -30,10 +31,17 @@ import hudson.remoting.VirtualChannel;
import hudson.util.IOException2;
import hudson.util.NullStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@@ -43,6 +51,8 @@ import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.output.NullOutputStream;
@@ -502,4 +512,69 @@ public class FilePathTest extends ChannelTestCase {
Util.deleteRecursive(tmp);
}
}
@Bug(16215)
public void testInstallIfNecessaryAvoidsExcessiveDownloadsByUsingIfModifiedSince() throws Exception {
final File tmp = Util.createTempDir();
try {
final FilePath d = new FilePath(tmp);
d.child(".timestamp").touch(123000);
final HttpURLConnection con = mock(HttpURLConnection.class);
final URL url = someUrlToZipFile(con);
when(con.getResponseCode())
.thenReturn(HttpURLConnection.HTTP_NOT_MODIFIED);
assertFalse(d.installIfNecessaryFrom(url, null, null));
verify(con).setIfModifiedSince(123000);
} finally {
Util.deleteRecursive(tmp);
}
}
@Bug(16215)
public void testInstallIfNecessaryPerformsInstallation() throws Exception {
final File tmp = Util.createTempDir();
try {
final FilePath d = new FilePath(tmp);
final HttpURLConnection con = mock(HttpURLConnection.class);
final URL url = someUrlToZipFile(con);
when(con.getResponseCode())
.thenReturn(HttpURLConnection.HTTP_OK);
when(con.getInputStream())
.thenReturn(someZippedContent());
assertTrue(d.installIfNecessaryFrom(url, null, null));
} finally {
Util.deleteRecursive(tmp);
}
}
private URL someUrlToZipFile(final URLConnection con) throws IOException {
final URLStreamHandler urlHandler = new URLStreamHandler() {
@Override protected URLConnection openConnection(URL u) throws IOException {
return con;
}
};
return new URL("http", "some-host", 0, "/some-path.zip", urlHandler);
}
private InputStream someZippedContent() throws IOException {
final ByteArrayOutputStream buf = new ByteArrayOutputStream();
final ZipOutputStream zip = new ZipOutputStream(buf);
zip.putNextEntry(new ZipEntry("abc"));
zip.write("abc".getBytes());
zip.close();
return new ByteArrayInputStream(buf.toByteArray());
}
}