/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.openejb.maven.plugin.customizer.monkey;
import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
import org.apache.commons.compress.archivers.jar.JarArchiveOutputStream;
import org.apache.openejb.loader.IO;
import org.apache.openejb.maven.plugin.customizer.monkey.classloader.ClassLoaderFactory;
import org.codehaus.plexus.util.FileUtils;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class MonkeyTest {
private final ClassLoaderFactory loaderFactory = new ClassLoaderFactory();
@Test
public void run() throws Exception {
final File tomee = prepareProject();
try {
invoke(tomee); // invalid, should fail
} catch (final ClassFormatError cfe) {
// ok, we created an invalid jar
}
new Monkey(tomee).run();
final File[] libs = new File(tomee, "lib").listFiles(new FilenameFilter() {
@Override
public boolean accept(final File dir, final String name) {
return name.endsWith(".jar");
}
});
assertEquals(1, libs.length);
final File jar = libs[0];
assertTrue(jar.getName().contains("tomee-monkey-"));
assertEquals(2, invoke(tomee));
FileUtils.deleteDirectory(tomee.getParentFile().getParentFile());
}
private Object invoke(final File tomee) throws MalformedURLException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException {
final ClassLoader loader = loaderFactory.create(new File(tomee, "lib"));
try {
return loader.loadClass("test.patch.MyMain").getMethod("test").invoke(null);
} finally {
loaderFactory.release(loader);
}
}
private File prepareProject() throws IOException {
final File target = new File("target/MonkeyTest_run" + System.currentTimeMillis() + "/mvn/target");
target.mkdirs();
final File classes = new File(target, "classes");
classes.mkdirs();
writeBinary(classes, "target/test-classes/test/patch/MyMain.class", "test/patch/MyMain.class");
writeBinary(classes, "target/test-classes/test/patch/foo/Another.class", "test/patch/foo/Another.class");
final File tomee = new File(target, "tomee");
final File lib = new File(tomee, "lib");
lib.mkdirs();
// create the jar to patch, it is invalid but when patched it should work
JarArchiveOutputStream stream = null;
try {
stream = new JarArchiveOutputStream(new FileOutputStream(new File(lib, "t.jar")));
stream.putArchiveEntry(new JarArchiveEntry("test/patch/MyMain.class"));
stream.write("invalid".getBytes());
stream.closeArchiveEntry();
stream.putArchiveEntry(new JarArchiveEntry("test/patch/foo/Another.class"));
stream.write("invalid-too".getBytes());
stream.closeArchiveEntry();
} catch (final IOException e) {
throw new IllegalArgumentException(e);
} finally {
IO.close(stream);
}
return tomee;
}
private void writeBinary(final File root, final String location, final String jarPath) throws IOException {
final FileInputStream in = new FileInputStream(location);
final File outFile = new File(root, jarPath);
outFile.getParentFile().mkdirs();
final FileOutputStream out = new FileOutputStream(outFile);
IO.copy(in, out);
IO.close(in);
IO.close(out);
}
}