package org.graalvm.component.installer;
import org.graalvm.component.installer.remote.CatalogIterable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.graalvm.component.installer.DownloadURLIterable.DownloadURLParam;
import org.graalvm.component.installer.jar.JarArchive;
import org.graalvm.component.installer.model.CatalogContents;
import org.graalvm.component.installer.model.ComponentInfo;
import org.graalvm.component.installer.remote.FileDownloader;
import org.graalvm.component.installer.persist.MetadataLoader;
import org.graalvm.component.installer.persist.ProxyResource;
import org.graalvm.component.installer.persist.test.Handler;
import org.graalvm.component.installer.remote.RemoteCatalogDownloader;
import org.junit.After;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
public class CatalogIterableTest extends CommandTestBase {
@Rule public final ProxyResource proxyResource = new ProxyResource();
@Override
@Before
public void setUp() throws Exception {
super.setUp();
}
@After
public void tearDown() throws Exception {
if (param != null) {
param.close();
}
}
@Test
public void testRemoteNames() throws Exception {
initRemoteComponent("persist/data/truffleruby2.jar", "test://graalvm.io/download/truffleruby.zip", "testComponent", "test");
assertEquals("test", param.getSpecification());
assertEquals("testComponent", param.getDisplayName());
assertFalse(param.isComplete());
assertFalse(Handler.isVisited(url));
}
@Test
public void testCreateMetaLoader() throws Exception {
initRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", "testComponent", "test");
MetadataLoader ldr = param.createMetaLoader();
ldr.setNoVerifySymlinks(false);
ldr.loadPaths();
ldr.loadPermissions();
ldr.loadSymlinks();
ComponentInfo meta = ldr.getComponentInfo();
assertEquals("ruby", meta.getId());
assertNull(meta.getInfoPath());
assertNull(meta.getLicensePath());
assertTrue(meta.getPaths().isEmpty());
assertEquals("TruffleRuby 0.33-dev", meta.getName());
assertEquals("0.33-dev", meta.getVersionString());
assertFalse(Handler.isVisited(url));
}
@Test
public void testCreateFileLoader() throws Exception {
initRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", "testComponent", "test");
MetadataLoader ldr = param.createFileLoader();
ldr.setNoVerifySymlinks(false);
ldr.loadPaths();
ldr.loadPermissions();
ldr.loadSymlinks();
ComponentInfo meta = ldr.getComponentInfo();
assertEquals("ruby", meta.getId());
assertNull(meta.getInfoPath());
assertFalse(meta.getPaths().isEmpty());
assertEquals("TruffleRuby 0.33-dev", meta.getName());
assertEquals("0.33-dev", meta.getVersionString());
assertTrue(Handler.isVisited(url));
}
@Test
public void testVerifyRemoteJars() throws Exception {
initRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", "testComponent", "test");
info.setShaDigest(SystemUtils.toHashBytes("d3a45ea326b379cc3d543cc56130ee9bd395fd1c1d51a470e8c2c8af1129829c"));
try {
exception.expect(IOException.class);
exception.expectMessage("ERR_FileDigestError");
param.createFileLoader();
} finally {
assertTrue(Handler.isVisited(url));
}
}
void addRemoteComponent(String relative, String u, boolean addParam) throws IOException {
storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "0.33-dev");
initRemoteComponent(relative, u, null, null);
catalogStorage.installed.add(info);
if (addParam) {
components.add(param);
}
}
@Test
public void testReadComponentMetadataNoNetwork() throws Exception {
addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false);
textParams.add("ruby");
CatalogIterable cit = new CatalogIterable(this, this);
assertTrue(cit.iterator().hasNext());
for (ComponentParam p : cit) {
URL remoteU = p.createMetaLoader().getComponentInfo().getRemoteURL();
assertEquals(url, remoteU);
}
assertFalse(Handler.isVisited(url));
}
@Test
public void testUnknownComponentSpecified() throws Exception {
exception.expect(FailedOperationException.class);
exception.expectMessage("REMOTE_UnknownComponentId");
addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false);
textParams.add("r");
CatalogIterable cit = new CatalogIterable(this, this);
assertTrue(cit.iterator().hasNext());
cit.iterator().next();
}
@Test
public void testUnknownComponentButExistingFile() throws Exception {
exception.expect(FailedOperationException.class);
exception.expectMessage("REMOTE_UnknownComponentMaybeFile");
addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false);
File mistyped = folder.newFile("mistyped-component.jar");
textParams.add(mistyped.getPath());
CatalogIterable cit = new CatalogIterable(this, this);
assertTrue(cit.iterator().hasNext());
cit.iterator().next();
}
@Test
public void testMetaAccessesDirectURL() throws Exception {
addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false);
rparam = new DownloadURLParam(url, rparam.getDisplayName(), rparam.getSpecification(), this, false);
components.add(param);
URL remoteU = rparam.createMetaLoader().getComponentInfo().getRemoteURL();
assertEquals(url, remoteU);
assertTrue(Handler.isVisited(url));
assertTrue(rparam.isComplete());
}
@Test
public void testDirectURLAccessedJustOnce() throws Exception {
addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false);
rparam = new DownloadURLParam(url, rparam.getDisplayName(), rparam.getSpecification(), this, false);
components.add(param);
URL remoteU = rparam.createMetaLoader().getComponentInfo().getRemoteURL();
assertEquals(url, remoteU);
assertTrue(Handler.isVisited(url));
assertTrue(rparam.isComplete());
Handler.clearVisited();
Archive jf = rparam.getArchive();
assertNotNull(jf);
assertFalse(Handler.isVisited(url));
}
@Test
public void testDirectURLJarClosedAfterMeta() throws Exception {
addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false);
rparam = new DownloadURLParam(url, rparam.getDisplayName(), rparam.getSpecification(), this, false);
components.add(param);
URL remoteU = rparam.createMetaLoader().getComponentInfo().getRemoteURL();
assertEquals(url, remoteU);
JarArchive jf = (JarArchive) rparam.getArchive();
assertNotNull(jf.getEntry("META-INF"));
rparam.close();
exception.expect(IllegalStateException.class);
jf.getEntry("META-INF");
}
@Test
public void testDirectURLJarClosedAfterJar() throws Exception {
addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false);
rparam = new DownloadURLParam(url, rparam.getDisplayName(), rparam.getSpecification(), this, false);
components.add(param);
JarArchive jf = (JarArchive) rparam.getArchive();
assertNotNull(jf.getEntry("META-INF"));
rparam.close();
exception.expect(IllegalStateException.class);
jf.getEntry("META-INF");
}
@Test
public void testURLDoesNotExist() throws Exception {
storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "0.33-dev");
addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false);
textParams.add("ruby");
Handler.bind(url.toString(), new URLConnection(url) {
@Override
public InputStream getInputStream() throws IOException {
connect();
return clu.openStream();
}
@Override
public String (int n) {
try {
connect();
} catch (IOException ex) {
Logger.getLogger(CatalogIterableTest.class.getName()).log(Level.SEVERE, null, ex);
}
return super.getHeaderField(n);
}
@Override
public Map<String, List<String>> () {
try {
connect();
} catch (IOException ex) {
Logger.getLogger(CatalogIterableTest.class.getName()).log(Level.SEVERE, null, ex);
}
return super.getHeaderFields();
}
@Override
public void connect() throws IOException {
throw new FileNotFoundException();
}
});
CatalogIterable cit = new CatalogIterable(this, this);
ComponentParam rubyComp = cit.iterator().next();
exception.expect(FailedOperationException.class);
exception.expectMessage("REMOTE_ErrorDownloadingNotExist");
rubyComp.createFileLoader().getComponentInfo();
}
private static final String TEST_CATALOG_URL = "test://release/catalog.properties";
private RemoteCatalogDownloader downloader;
private void setupCatalog() throws Exception {
this.storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "19.3-dev");
String relSpec = "commands/cataloginstallDeps.properties";
URL u = getClass().getResource(relSpec);
Handler.bind(TEST_CATALOG_URL, u);
downloader = new RemoteCatalogDownloader(this, this, new URL(TEST_CATALOG_URL));
this.registry = new CatalogContents(this, downloader.getStorage(), getLocalRegistry());
}
@Test
public void testNoWildcards() throws Exception {
setupCatalog();
textParams.add("ruby");
CatalogIterable cit = new CatalogIterable(this, this);
Iterator<ComponentParam> comps = cit.iterator();
ComponentParam c;
c = comps.next();
assertFalse(comps.hasNext());
assertEquals("org.graalvm.ruby", c.createMetaLoader().getComponentInfo().getId());
}
@Test
public void testAllComponents() throws Exception {
setupCatalog();
textParams.add("*");
CatalogIterable cit = new CatalogIterable(this, this);
Iterator<ComponentParam> comps = cit.iterator();
List<String> fullIds = new ArrayList<>();
for (; comps.hasNext();) {
ComponentParam cp = comps.next();
fullIds.add(cp.createMetaLoader().getComponentInfo().getId());
}
assertEquals(5, fullIds.size());
}
@Test
public void testSelectSomeComponents() throws Exception {
setupCatalog();
textParams.add("*mage");
textParams.add("llvm*");
CatalogIterable cit = new CatalogIterable(this, this);
Iterator<ComponentParam> comps = cit.iterator();
List<String> fullIds = new ArrayList<>();
for (; comps.hasNext();) {
ComponentParam cp = comps.next();
fullIds.add(cp.createMetaLoader().getComponentInfo().getId());
}
assertEquals(2, fullIds.size());
}
@Test
public void testWildardSorted() throws Exception {
setupCatalog();
textParams.add("r*");
CatalogIterable cit = new CatalogIterable(this, this);
Iterator<ComponentParam> comps = cit.iterator();
List<String> fullIds = new ArrayList<>();
for (; comps.hasNext();) {
ComponentParam cp = comps.next();
fullIds.add(cp.createMetaLoader().getComponentInfo().getId());
}
assertEquals(2, fullIds.size());
assertEquals("org.graalvm.r", fullIds.get(0));
assertEquals("org.graalvm.ruby", fullIds.get(1));
}
@Test
public void testMixWildcardsAndLiterals() throws Exception {
setupCatalog();
textParams.add("r*");
textParams.add("ruby");
CatalogIterable cit = new CatalogIterable(this, this);
Iterator<ComponentParam> comps = cit.iterator();
List<String> fullIds = new ArrayList<>();
for (; comps.hasNext();) {
ComponentParam cp = comps.next();
fullIds.add(cp.createMetaLoader().getComponentInfo().getId());
}
assertEquals(3, fullIds.size());
assertEquals("org.graalvm.ruby", fullIds.get(1));
assertEquals("org.graalvm.ruby", fullIds.get(2));
}
@Override
public FileDownloader configureDownloader(ComponentInfo ci, FileDownloader dn) {
return dn;
}
}