package org.jboss.resteasy.utils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jboss.resteasy.api.validation.ResteasyViolationException; import org.jboss.resteasy.api.validation.ViolationReport; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ArchivePath; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.exporter.ZipExporter; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.wildfly.extras.creaper.core.ManagementClient; import org.wildfly.extras.creaper.core.online.ModelNodeResult; import org.wildfly.extras.creaper.core.online.OnlineManagementClient; import org.wildfly.extras.creaper.core.online.OnlineOptions; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.MalformedInputException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Set; /** * Base util class for RESTEasy testing. */ public class TestUtil { protected static Logger logger; private static String baseResourcePath = new StringBuilder() .append("src").append(File.separator) .append("test").append(File.separator) .append("resources").append(File.separator).toString(); /** * Try to initialize logger. This is unsuccessful on EAP deployment, because EAP do not contain log4j. * Logger is not necessary for this class. Some methods could be used without it. */ static { try { logger = LogManager.getLogger(TestUtil.class.getName()); } catch (NoClassDefFoundError e) { // unable to initialize logger, finishContainerPrepare method could not be used } } /** * Initialize deployment. * * @return Deployment. */ public static WebArchive prepareArchive(String deploymentName) { WebArchive war = ShrinkWrap.create(WebArchive.class, deploymentName + ".war"); war.addClass(TestApplication.class); return war; } /** * Finish preparing war deployment and deploy it. * * Add classes in @resources to deployment. Also all sub-classes of classes in @resources are added to deployment. * But only classes in @resources (not sub-classes of classes in @resources) can be used as resources * (getClasses function of TestApplication class return only classes in @resources). * * @param resources classes used in deployment as resources */ public static Archive<?> finishContainerPrepare(WebArchive war, Map<String, String> contextParams, final Class<?>... resources) { return finishContainerPrepare(war, contextParams, null, resources); } /** * Finish preparing war deployment and deploy it. * * Add classes in @resources to deployment. Also all sub-classes of classes in @resources are added to deployment. * But only classes in @resources (not sub-classes of classes in @resources) can be used as resources * (getClasses function of TestApplication class return only classes in @resources). * * @param singletons classes used in deployment as singletons * @param resources classes used in deployment as resources */ public static Archive<?> finishContainerPrepare(WebArchive war, Map<String, String> contextParams, List<Class<?>> singletons, final Class<?>... resources) { if (contextParams == null) { contextParams = new Hashtable<>(); } Set<String> classNamesInDeployment = new HashSet<>(); Set<String> singletonsNamesInDeployment = new HashSet<>(); if (resources != null) { for (final Class<?> clazz : resources) { war.addClass(clazz); classNamesInDeployment.add(clazz.getTypeName()); } } if (singletons != null) { for (Class<?> singleton : singletons) { war.addClass(singleton); singletonsNamesInDeployment.add(singleton.getTypeName()); } } if (contextParams != null && contextParams.size() > 0 && !war.contains("WEB-INF/web.xml")) { StringBuilder webXml = new StringBuilder(); webXml.append("<web-app version=\"3.0\" xmlns=\"http://java.sun.com/xml/ns/javaee\" \n"); webXml.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n"); webXml.append(" xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\"> \n"); for (Map.Entry<String, String> entry : contextParams.entrySet()) { String paramName = entry.getKey(); String paramValue = entry.getValue(); logger.info("Context param " + paramName + " value " + paramValue); webXml.append("<context-param>\n"); webXml.append("<param-name>" + paramName + "</param-name>\n"); webXml.append("<param-value>" + paramValue + "</param-value>\n"); webXml.append("</context-param>\n"); } webXml.append("</web-app>\n"); Asset resource = new StringAsset(webXml.toString()); war.addAsWebInfResource(resource, "web.xml"); } // prepare class list for getClasses function of TestApplication class StringBuilder classes = new StringBuilder(); boolean start = true; for (String clazz : classNamesInDeployment) { if (start) { start = false; } else { classes.append(","); } classes.append(clazz); } war.addAsResource(new StringAsset(classes.toString()), "classes.txt"); // prepare singleton list for getSingletons function of TestApplication class StringBuilder singletonBuilder = new StringBuilder(); start = true; for (String clazz : singletonsNamesInDeployment) { if (start) { start = false; } else { singletonBuilder.append(","); } singletonBuilder.append(clazz); } war.addAsResource(new StringAsset(singletonBuilder.toString()), "singletons.txt"); if (System.getProperty("STORE_WAR") != null) { war.as(ZipExporter.class).exportTo(new File("target", war.getName()), true); } return war; } public static OnlineManagementClient clientInit() throws IOException { OnlineOptions onlineOptions = OnlineOptions .standalone() .hostAndPort(PortProviderUtil.getHost(), 9990) // 9990 is default port for EAP 7 .connectionTimeout(120000) .build(); return ManagementClient.online(onlineOptions); } public static ModelNodeResult runCmd(OnlineManagementClient client, String cmd) throws Exception { ModelNodeResult result = client.execute(cmd); logger.info("CLI command: " + cmd); logger.info("Result: " + result.toString()); return result; } /** * Add package info to deployment. * * @param clazz Package info is for package of this class. */ protected WebArchive addPackageInfo(WebArchive war, final Class<?> clazz) { return war.addPackages(false, new org.jboss.shrinkwrap.api.Filter<org.jboss.shrinkwrap.api.ArchivePath>() { @Override public boolean include(final ArchivePath path) { return path.get().endsWith("package-info.class"); } }, clazz.getPackage()); } /** * Convert input stream to String. * * @param in Input stream * @return Converted string */ public static String readString(final InputStream in) throws IOException { char[] buffer = new char[1024]; StringBuilder builder = new StringBuilder(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); int wasRead = 0; do { wasRead = reader.read(buffer, 0, 1024); if (wasRead > 0) { builder.append(buffer, 0, wasRead); } } while (wasRead > -1); return builder.toString(); } public static String getErrorMessageForKnownIssue(String jira, String message) { StringBuilder s = new StringBuilder(); s.append("https://issues.jboss.org/browse/"); s.append(jira); s.append(" - "); s.append(message); return s.toString(); } public static String getErrorMessageForKnownIssue(String jira) { return getErrorMessageForKnownIssue(jira, "known issue"); } public static String getJbossHome() { return System.getProperty("jboss.home"); } public static String getJbossHome(boolean onServer) { if (onServer == false) { return getJbossHome(); } return System.getProperty("jboss.home.dir", ""); } public static boolean isOpenJDK() { return System.getProperty("java.runtime.name").toLowerCase().contains("openjdk"); } public static boolean isWildFly9x() { final String sv = System.getProperty("server.version"); return ("9.0.2.Final".equals(sv) || "9.0.1.Final".equals(sv) || "9.0.0.Final".equals(sv)); } public static boolean isOracleJDK() { if (isOpenJDK()) { return false; } String vendor = System.getProperty("java.vendor").toLowerCase(); return vendor.contains("sun") || vendor.contains("oracle"); } public static boolean isIbmJdk() { return System.getProperty("java.vendor").toLowerCase().contains("ibm"); } /** * Get resource in test scope for some class. * Example: class org.test.MyTest and name "my_resource.txt" returns "src/test/resource/org/test/my_resource.txt" */ public static String getResourcePath(Class<?> c, String name) { return new StringBuilder() .append(baseResourcePath) .append(c.getPackage().getName().replace('.', File.separatorChar)) .append(File.separator).append(name) .toString(); } /** * Read server log file from standalone/log/server.log */ public static List<String> readServerLogLines() { return readServerLogLines(false); } public static List<String> readServerLogLines(boolean onServer) { String jbossHome = TestUtil.getJbossHome(onServer); String logPath = String.format("%s%sstandalone%slog%sserver.log", jbossHome, (jbossHome.endsWith(File.separator) || jbossHome.endsWith("/")) ? "" : File.separator, File.separator, File.separator); logPath = logPath.replace('/', File.separatorChar); try { return Files.readAllLines(Paths.get(logPath)); // UTF8 is used by default } catch (MalformedInputException e1) { // some windows machines could accept only StandardCharsets.ISO_8859_1 encoding try { return Files.readAllLines(Paths.get(logPath), StandardCharsets.ISO_8859_1); } catch (IOException e4) { throw new RuntimeException("Server logs has not standard Charsets (UTF8 or ISO_8859_1)"); } } catch (IOException e) { // server.log file is not created, it is the same as server.log is empty } return new ArrayList<>(); } /** * Get count of lines with specific string in log */ public static int getWarningCount(String findedString, boolean onServer) { int count = 0; List<String> lines = TestUtil.readServerLogLines(onServer); for (String line : lines) { if (line.contains(findedString)) { count++; } } return count; } /** * Check count of violations in ResteasyViolationException. */ public static void countViolations(ResteasyViolationException e, int totalCount, int fieldCount, int propertyCount, int classCount, int parameterCount, int returnValueCount) { Assert.assertEquals("Different total count of violations expected", totalCount, e.getViolations().size()); Assert.assertEquals("Different count of field violations expected", fieldCount, e.getFieldViolations().size()); Assert.assertEquals("Different count of property violations expected", propertyCount, e.getPropertyViolations().size()); Assert.assertEquals("Different count of class violations expected", classCount, e.getClassViolations().size()); Assert.assertEquals("Different count of parameter violations expected", parameterCount, e.getParameterViolations().size()); Assert.assertEquals("Different count of return value violations expected", returnValueCount, e.getReturnValueViolations().size()); } public static void countViolations(ViolationReport e, int fieldCount, int propertyCount, int classCount, int parameterCount, int returnValueCount) { Assert.assertEquals("Different count of field violations expected", fieldCount, e.getFieldViolations().size()); Assert.assertEquals("Different count of property violations expected", propertyCount, e.getPropertyViolations().size()); Assert.assertEquals("Different count of class violations expected", classCount, e.getClassViolations().size()); Assert.assertEquals(parameterCount, e.getParameterViolations().size()); Assert.assertEquals(returnValueCount, e.getReturnValueViolations().size()); } }