/*
* Copyright © 2015 Cask Data, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package co.cask.cdap.internal.app.runtime.artifact;
import co.cask.cdap.api.artifact.ApplicationClass;
import co.cask.cdap.api.artifact.ArtifactClasses;
import co.cask.cdap.api.plugin.PluginClass;
import co.cask.cdap.api.plugin.PluginPropertyField;
import co.cask.cdap.app.program.ManifestFields;
import co.cask.cdap.app.runtime.DummyProgramRunnerFactory;
import co.cask.cdap.common.InvalidArtifactException;
import co.cask.cdap.common.conf.CConfiguration;
import co.cask.cdap.common.conf.Constants;
import co.cask.cdap.common.io.Locations;
import co.cask.cdap.common.utils.DirUtils;
import co.cask.cdap.internal.app.runtime.artifact.app.InvalidConfigApp;
import co.cask.cdap.internal.app.runtime.artifact.app.inspection.InspectionApp;
import co.cask.cdap.internal.io.ReflectionSchemaGenerator;
import co.cask.cdap.internal.test.AppJarHelper;
import co.cask.cdap.proto.Id;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.Files;
import org.apache.twill.filesystem.LocalLocationFactory;
import org.apache.twill.filesystem.Location;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
import java.util.Set;
import java.util.jar.Manifest;
/**
*/
public class ArtifactInspectorTest {
@ClassRule
public static final TemporaryFolder TMP_FOLDER = new TemporaryFolder();
private static ArtifactClassLoaderFactory classLoaderFactory;
private static ArtifactInspector artifactInspector;
@BeforeClass
public static void setup() throws Exception {
CConfiguration cConf = CConfiguration.create();
cConf.set(Constants.CFG_LOCAL_DATA_DIR, TMP_FOLDER.newFolder().getAbsolutePath());
classLoaderFactory = new ArtifactClassLoaderFactory(cConf, new DummyProgramRunnerFactory());
artifactInspector = new ArtifactInspector(cConf, classLoaderFactory);
}
@Test(expected = InvalidArtifactException.class)
public void testInvalidConfigApp() throws Exception {
Manifest manifest = new Manifest();
File appFile =
createJar(InvalidConfigApp.class, new File(TMP_FOLDER.newFolder(), "InvalidConfigApp-1.0.0.jar"), manifest);
Id.Artifact artifactId = Id.Artifact.from(Id.Namespace.DEFAULT, "InvalidConfigApp", "1.0.0");
Location artifactLocation = Locations.toLocation(appFile);
try (CloseableClassLoader artifactClassLoader = classLoaderFactory.createClassLoader(artifactLocation)) {
artifactInspector.inspectArtifact(artifactId, appFile, artifactClassLoader);
}
}
@Test
public void inspectAppsAndPlugins() throws Exception {
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(ManifestFields.EXPORT_PACKAGE, InspectionApp.class.getPackage().getName());
File appFile =
createJar(InspectionApp.class, new File(TMP_FOLDER.newFolder(), "InspectionApp-1.0.0.jar"), manifest);
Id.Artifact artifactId = Id.Artifact.from(Id.Namespace.DEFAULT, "InspectionApp", "1.0.0");
Location artifactLocation = Locations.toLocation(appFile);
try (CloseableClassLoader artifactClassLoader = classLoaderFactory.createClassLoader(artifactLocation)) {
ArtifactClasses classes = artifactInspector.inspectArtifact(artifactId, appFile, artifactClassLoader);
// check app classes
Set<ApplicationClass> expectedApps = ImmutableSet.of(new ApplicationClass(
InspectionApp.class.getName(), "", new ReflectionSchemaGenerator(false).generate(InspectionApp.AConfig.class)));
Assert.assertEquals(expectedApps, classes.getApps());
// check plugin classes
PluginClass expectedPlugin = new PluginClass(
InspectionApp.PLUGIN_TYPE, InspectionApp.PLUGIN_NAME, InspectionApp.PLUGIN_DESCRIPTION,
InspectionApp.AppPlugin.class.getName(), "pluginConf",
ImmutableMap.of(
"y", new PluginPropertyField("y", "", "double", true),
"isSomething", new PluginPropertyField("isSomething", "", "boolean", true)));
Assert.assertEquals(ImmutableSet.of(expectedPlugin), classes.getPlugins());
}
}
private static File createJar(Class<?> cls, File destFile, Manifest manifest) throws IOException {
Location deploymentJar = AppJarHelper.createDeploymentJar(new LocalLocationFactory(TMP_FOLDER.newFolder()),
cls, manifest);
DirUtils.mkdirs(destFile.getParentFile());
Files.copy(Locations.newInputSupplier(deploymentJar), destFile);
return destFile;
}
}