/************************************************************************************* * Copyright (c) 2013 Red Hat, Inc. and others. * 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: * JBoss by Red Hat - Initial implementation. ************************************************************************************/ package org.jboss.tools.foundation.core.test.ecf; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.ServerSocket; import java.net.Socket; import java.net.URL; import java.net.URLEncoder; import java.util.Random; import java.util.concurrent.Executors; import junit.framework.TestCase; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; import org.jboss.tools.foundation.core.ecf.URLTransportUtility; import org.jboss.tools.foundation.core.internal.FoundationCorePlugin; import org.jboss.tools.foundation.core.test.FoundationTestConstants; import org.jboss.tools.foundation.core.test.testutils.FakeHttpServer; import org.junit.Test; import org.osgi.framework.Bundle; public class URLTransportUtilTest extends TestCase { private void testDownload(String urlString) { testDownload(urlString, new NullProgressMonitor()); } private void testDownload(String urlString, IProgressMonitor monitor) { URLTransportUtility util = new URLTransportUtility(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); IStatus s = util.download("displayName", urlString, baos, monitor); assertTrue(s.isOK()); String stringFromDownload = baos.toString(); assertNotNull(stringFromDownload); assertNotNull(stringFromDownload); } private void testLastModified(String urlString) { // verify get last timestamp works, or at least doesn't fail with an exception URLTransportUtility util = new URLTransportUtility(); try { long l = util.getLastModified(new URL(urlString)); } catch(CoreException ce) { fail(ce.getMessage()); } catch(MalformedURLException murle) { fail(murle.getMessage()); } } @Test public void testWebDownload() { String urlString = "https://raw.github.com/jboss-jdf/jdf-stack/1.0.0.Final/stacks.yaml"; testDownload(urlString); testLastModified(urlString); } public void testLongUrl() throws CoreException { String urlString = "http://thelongestlistofthelongeststuffatthelongestdomainnameatlonglast.com/wearejustdoingthistobestupidnowsincethiscangoonforeverandeverandeverbutitstilllookskindaneatinthebrowsereventhoughitsabigwasteoftimeandenergyandhasnorealpointbutwehadtodoitanyways.html"; File file = new URLTransportUtility().getCachedFileForURL(urlString, "Long Url", URLTransportUtility.CACHE_UNTIL_EXIT, new NullProgressMonitor()); assertTrue(file.exists()); assertTrue(file.length() > 0); } protected FakeHttpServer startFakeSlowHttpServer(String statusLine) throws IOException { return startFakeHttpServer(statusLine, 45000); } protected FakeHttpServer startFakeHttpServer(String statusLine, final long delay) throws IOException { int port = new Random().nextInt(9 * 1024) + 1024; FakeHttpServer serverFake = null; String sLine = statusLine == null ? FakeHttpServer.DEFAULT_STATUSLINE : statusLine; serverFake = new FakeHttpServer(port, null, sLine) { public void start() throws IOException { executor = Executors.newFixedThreadPool(1); this.serverSocket = new ServerSocket(port); executor.submit(new ServerFakeSocket() { protected String getResponse(Socket socket) throws IOException { System.out.println("Response requested. Delaying"); try { Thread.sleep(delay); } catch(InterruptedException ie) {} System.out.println("Responding to request: Hello"); return "Hello"; } }); } }; serverFake.start(); return serverFake; } @Test public void testTimeoutWithoutCancel() { FakeHttpServer server = null; try { server = startFakeSlowHttpServer(null); } catch(IOException ioe) { fail(); } try { URL url = server.getUrl(); final IProgressMonitor monitor = new NullProgressMonitor(); URLTransportUtility util = new URLTransportUtility(); ByteArrayOutputStream os = new ByteArrayOutputStream(); long t1 = System.currentTimeMillis(); IStatus s = util.download("displayString", url.toExternalForm(), os, 500, monitor); long t2 = System.currentTimeMillis(); assertTrue(s.getSeverity() == IStatus.ERROR); assertTrue(t2 - t1 < 3000); } catch(MalformedURLException murle) { } finally { if( server != null ) server.stop(); } } @Test public void testCancelMonitor() { FakeHttpServer server = null; try { server = startFakeSlowHttpServer(null); } catch(IOException ioe) { fail(); } final Long[] times = new Long[2]; try { URL url = server.getUrl(); final IProgressMonitor monitor = new NullProgressMonitor(); new Thread() { public void run() { System.out.println("Cancel Monitor Thread Launched"); try { Thread.sleep(3000); } catch(InterruptedException ie) {} System.out.println("Canceling Monitor"); synchronized (times) { times[0] = System.currentTimeMillis(); } monitor.setCanceled(true); } }.start(); URLTransportUtility util = new URLTransportUtility(); ByteArrayOutputStream os = new ByteArrayOutputStream(); IStatus s = util.download("displayString", url.toExternalForm(), os, monitor); synchronized (times) { times[1] = System.currentTimeMillis(); } assertTrue(s.getSeverity() == IStatus.CANCEL || s.getSeverity() == IStatus.ERROR); // MUST cancel within 500 ms assertTrue(times[1] - times[0] < 500); } catch(MalformedURLException murle) { fail(murle.getMessage()); } finally { if( server != null ) server.stop(); } } @Test public void testTimeToLive1() { testTimeToLive(1000); } @Test public void testTimeToLive2() { testTimeToLive(5000); } private void testTimeToLive(long timeout) { FakeHttpServer server = null; try { server = startFakeSlowHttpServer(null); } catch(IOException ioe) { fail(); } try { URL url = server.getUrl(); long start = System.currentTimeMillis(); URLTransportUtility util = new URLTransportUtility(); File result = util.getCachedFileForURL( url.toExternalForm(), "displayName", URLTransportUtility.CACHE_UNTIL_EXIT, 20000, timeout, new NullProgressMonitor()); long finish = System.currentTimeMillis(); long duration = finish - start; assertTrue(duration > timeout); // Should be impossible to finish BEFORE the timeout assertTrue(duration < (timeout + 300)); // Add 300 ms in case of jobs taking time to phase out assertNull(result); } catch(MalformedURLException murle) { fail(murle.getMessage()); } catch(CoreException ce) { fail(ce.getMessage()); } finally { if( server != null ) server.stop(); } } @Test public void testPlatformUrl() { String urlString ="platform:/plugin/" + FoundationTestConstants.PLUGIN_ID + "/data/simpletext.txt"; testDownload(urlString); testLastModified(urlString); } @Test public void testBundleEntryUrl() { Bundle b = Platform.getBundle(FoundationTestConstants.PLUGIN_ID); URL url = b.getEntry("data/simpletext.txt"); testDownload(url.toExternalForm()); testLastModified(url.toExternalForm()); } // Test the caching preferences @Test public void testCaching() { // Simple test to verify caching is persisted IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(FoundationCorePlugin.PLUGIN_ID); String CACHE_MAP_KEY = "URLTransportCache.CacheMapKey"; // internal key, but cannot change String val = prefs.get(CACHE_MAP_KEY, ""); assertEquals(val, ""); try { String urlString = "https://raw.github.com/jboss-jdf/jdf-stack/1.0.0.Final/stacks.yaml"; boolean outdated = new URLTransportUtility().isCacheOutdated(urlString, new NullProgressMonitor()); assertTrue(outdated); File downloaded = new URLTransportUtility().getCachedFileForURL(urlString, "stuff", URLTransportUtility.CACHE_FOREVER, new NullProgressMonitor()); outdated = new URLTransportUtility().isCacheOutdated(urlString, new NullProgressMonitor()); assertTrue(outdated); // cache is outdated because github indicates remote file has timestamp of 0 assertTrue(downloaded.exists()); } catch(CoreException ce) { fail(ce.getMessage()); } catch(Exception uee) { fail(uee.getMessage()); // should never happen } } }