/******************************************************************************* * Copyright (c) 2016 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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 * * Contributor: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.examples.ui.bot.test.integration; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import org.jboss.ide.eclipse.as.reddeer.server.view.JBossServerModule; import org.jboss.ide.eclipse.as.reddeer.server.view.JBossServerView; import org.jboss.reddeer.common.condition.AbstractWaitCondition; import org.jboss.reddeer.common.exception.RedDeerException; import org.jboss.reddeer.common.exception.WaitTimeoutExpiredException; import org.jboss.reddeer.common.logging.Logger; import org.jboss.reddeer.common.matcher.RegexMatcher; import org.jboss.reddeer.common.wait.TimePeriod; import org.jboss.reddeer.common.wait.WaitUntil; import org.jboss.reddeer.common.wait.WaitWhile; import org.jboss.reddeer.core.condition.JobIsRunning; import org.jboss.reddeer.core.exception.CoreLayerException; import org.jboss.reddeer.core.handler.ShellHandler; import org.jboss.reddeer.core.util.FileUtil; import org.jboss.reddeer.eclipse.condition.ConsoleHasNoChange; import org.jboss.reddeer.eclipse.core.resources.Project; import org.jboss.reddeer.eclipse.jdt.ui.ProjectExplorer; import org.jboss.reddeer.eclipse.m2e.core.ui.preferences.MavenSettingsPreferencePage; import org.jboss.reddeer.eclipse.ui.browser.BrowserEditor; import org.jboss.reddeer.eclipse.ui.console.ConsoleView; import org.jboss.reddeer.eclipse.ui.views.log.LogMessage; import org.jboss.reddeer.eclipse.ui.views.log.LogView; import org.jboss.reddeer.eclipse.utils.DeleteUtils; import org.jboss.reddeer.eclipse.wst.server.ui.view.ModuleLabel; import org.jboss.reddeer.eclipse.wst.server.ui.view.Server; import org.jboss.reddeer.eclipse.wst.server.ui.view.ServerModule; import org.jboss.reddeer.eclipse.wst.server.ui.view.ServersView; import org.jboss.reddeer.eclipse.wst.server.ui.view.ServersViewEnums.ServerState; import org.jboss.reddeer.jface.wizard.WizardDialog; import org.jboss.reddeer.swt.impl.button.OkButton; import org.jboss.reddeer.swt.impl.button.PushButton; import org.jboss.reddeer.swt.impl.menu.ContextMenu; import org.jboss.reddeer.swt.impl.shell.DefaultShell; import org.jboss.reddeer.workbench.impl.editor.DefaultEditor; import org.jboss.reddeer.workbench.ui.dialogs.WorkbenchPreferenceDialog; import org.jboss.tools.central.reddeer.api.ExamplesOperator; import org.jboss.tools.maven.reddeer.wizards.MavenImportWizard; import org.jboss.tools.maven.reddeer.wizards.MavenImportWizard.MavenImportWizardException; import org.jboss.tools.maven.reddeer.wizards.MavenImportWizardFirstPage; import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; /** * This testsuite consist of one test. It imports all examples (location of * examples is defined by system property "examplesLocation") and checks for * errors and warnings. * * @author rhopp, jkopriva * */ public abstract class AbstractImportQuickstartsTest { protected static String SERVER_NAME = ""; protected QuickstartsReporter reporter = QuickstartsReporter.getInstance(); protected String blacklistFileContents = ""; protected static LogView errorLogView; private static final Logger log = Logger.getLogger(AbstractImportQuickstartsTest.class); @BeforeClass public static void setup() { setupLog(); } @After public void cleanup() { clearWorkspace(); } @AfterClass public static void teardown() { createReports(); } protected static void setServerName(String serverName) { SERVER_NAME = serverName; } protected void checkServerStatus() { ServersView serversView = new ServersView(); serversView.open(); Server server = serversView.getServer(getServerFullName(serversView.getServers(), SERVER_NAME)); assertTrue("Server has not been started!", server.getLabel().getState() == ServerState.STARTED); // assertTrue("Server has not been // synchronized!",server.getLabel().getPublishState() == // ServerPublishState.SYNCHRONIZED); } /* * Deploy and undeploy quickstart on running server */ protected void deployUndeployQuickstart(Quickstart qstart, String serverName) { new ConsoleView().clearConsole(); ProjectExplorer explorer = new ProjectExplorer(); findDeployableProjects(qstart, explorer); ServersView serversView = new ServersView(); serversView.open(); String fullServerName = getServerFullName(serversView.getServers(), serverName); Server server = serversView.getServer(fullServerName); for (String deployableProjectName : qstart.getDeployableProjectNames()) { try { // deploy deployProject(deployableProjectName, explorer); // check deploy status checkDeployedProject(qstart, fullServerName); // undeploy unDeployModule(qstart.getName().equals("template") ? "QUICKSTART_NAME" : qstart.getName(), server); } catch (CoreLayerException ex) { new DefaultShell("Server Error"); new OkButton().click(); } } } private void unDeployModule(String moduleName, Server server) { log.info("UNDEPLOYING MODULE" + moduleName + " ON SERVER " + server.getLabel()); ServerModule serverModule = server.getModule(new RegexMatcher(".*" + moduleName + ".*")); serverModule.remove(); new WaitWhile(new JobIsRunning(), TimePeriod.VERY_LONG); } private void findDeployableProjects(Quickstart qstart, ProjectExplorer explorer) { explorer.activate(); for (Project project : explorer.getProjects()) { explorer.getProject(project.getName()).select(); try { if (new ContextMenu("Run As", "1 Run on Server").isEnabled()) { qstart.addDeployableProjectName(project.getName()); } new WizardDialog().finish(); } catch (CoreLayerException ex) { continue;// non deployable project } } } private void deployProject(String deployableProject, ProjectExplorer explorer) { log.info("DEPLOYING " + deployableProject); explorer.activate(); Project project = explorer.getProject(deployableProject); project.select(); new ContextMenu("Run As", "1 Run on Server").select(); new WizardDialog().finish(); } private String getServerFullName(List<Server> servers, String partOfName) { for (Server srv : servers) { if (srv.getLabel().getName().contains(partOfName)) { return srv.getLabel().getName(); } } return null; } protected String getDeployableProjectName(List<Project> projects, String quickstartName) { for (Project prj : projects) { if (prj.getName().contains(quickstartName)) { return prj.getName(); } } return null; } protected static Collection<Quickstart> createQuickstartsList() { ArrayList<Quickstart> resultList = new ArrayList<Quickstart>(); ArrayList<String> specificQuickstarts = new ArrayList<String>(); if (System.getProperty("specificQuickstarts") != null && !System.getProperty("specificQuickstarts").trim().equals("${specificQuickstarts}")) { specificQuickstarts = new ArrayList<String>( Arrays.asList(System.getProperty("specificQuickstarts").trim().split(","))); } File file = new File(System.getProperty("examplesLocation")); FileFilter directoryFilter = new FileFilter() { @Override public boolean accept(File arg0) { return arg0.isDirectory(); } }; for (File f : file.listFiles(directoryFilter)) { if (!f.getPath().contains("/.")) { if (specificQuickstarts.size() == 0 || specificQuickstarts.contains(f.getName())) { log.info("PROCESSING " + f.getAbsolutePath()); Quickstart qstart = new Quickstart(f.getName(), f.getAbsolutePath()); resultList.add(qstart); } } } return resultList; } protected static void setupLog() { errorLogView = new LogView(); errorLogView.open(); errorLogView.deleteLog(); } protected static void clearWorkspace() { cleanupShells(); deleteAllProjects(); closeBrowser(); new ConsoleView().clearConsole(); } protected void runQuickstarts(Quickstart qstart, String serverName, String blacklistFile) { loadBlacklistFile(blacklistFile); if (!blacklistFileContents.contains(qstart.getName())) { try { importQuickstart(qstart); importTestUtilsIfNeeded(qstart); if (!isError() && System.getProperty("deployOnServer") != null && System.getProperty("deployOnServer").equals("true")) { checkServerStatus(); deployUndeployQuickstart(qstart, SERVER_NAME); } } catch (NoProjectException ex) { // there was no project in this directory. Pass the test. return; } checkForWarnings(qstart); checkForErrors(qstart); checkErrorLog(qstart); } } private void loadBlacklistFile(String blacklistFile) { String pathToFile = ""; try { pathToFile = new File(blacklistFile).getCanonicalPath(); blacklistFileContents = FileUtil.readFile(pathToFile); } catch (IOException ex) { fail("Blacklist file not found! Path is: " + pathToFile); } } protected static void createReports() { QuickstartsReporter.getInstance().generateReport(); QuickstartsReporter.getInstance().generateErrorFilesForEachProject(new File("target/reports/")); QuickstartsReporter.getInstance().generateAllErrorsFile(new File("target/reports/allErrors.txt")); } protected void checkErrorLog(Quickstart qstart) { List<LogMessage> allErrors = new ArrayList<LogMessage>(); List<LogMessage> errors = errorLogView.getErrorMessages(); String errorMessages = ""; for (LogMessage message : errors) { if (!message.getMessage().contains("Unable to delete") && !message.getMessage().contains("Could not delete")) { reporter.addError(qstart, "ERROR IN ERROR LOG: " + message.getMessage()); errorMessages += "\t" + message.getMessage() + "\n"; } } errorLogView.deleteLog(); if (!allErrors.isEmpty()) { fail("There are errors in error log:\n" + errorMessages); } } private void restartServer() { ServersView serversView = new ServersView(); serversView.open(); Server server = serversView.getServer(getServerFullName(serversView.getServers(), SERVER_NAME)); server.clean(); server.restart(); } protected void checkForWarnings(Quickstart q) { for (String warning : ExamplesOperator.getInstance().getAllWarnings()) { reporter.addWarning(q, warning); } } protected void checkForErrors(Quickstart q) { updateProjectsIfNeeded(); String errorMessages = ""; List<String> allErrors = new ArrayList<String>(); List<String> errors = ExamplesOperator.getInstance().getAllErrors(); for (String error : errors) { if (!error.contains("Unable to delete") && !error.contains("Could not delete")) { reporter.addError(q, "ERROR IN PROJECT: " + error); errorMessages += "\t" + error + "\n"; allErrors.add(error); } } if (!allErrors.isEmpty()) { fail("There are errors in imported project:\n" + errorMessages); } } protected boolean isError() { updateProjectsIfNeeded(); if (!ExamplesOperator.getInstance().getAllErrors().isEmpty()) { return true; } return false; } protected void updateProjectsIfNeeded() { for (String string : ExamplesOperator.getInstance().getAllErrors()) { if (string.contains("not up-to-date with pom.xml")) { // maven // update is // needed // sometimes. runUpdate(); } } } private void runUpdate() { new ProjectExplorer().getProjects().get(0).select(); new ContextMenu("Maven", "Update Project...").select(); new DefaultShell("Update Maven Project"); new PushButton("Select All").click(); new PushButton("OK").click(); new WaitWhile(new JobIsRunning(), TimePeriod.VERY_LONG); } protected static void deleteAllProjects() { ProjectExplorer projectExplorer = new ProjectExplorer(); projectExplorer.open(); List<Project> projects = projectExplorer.getProjects(); for (Project p : projects) { DeleteUtils.forceProjectDeletion(p, false); } } protected static void cleanupShells() { ShellHandler.getInstance().closeAllNonWorbenchShells(); } protected void importQuickstart(Quickstart quickstart) throws NoProjectException { ExtendedMavenImportWizard mavenImportWizard = new ExtendedMavenImportWizard(); mavenImportWizard.open(); MavenImportWizardFirstPage wizPage = new MavenImportWizardFirstPage(); try { wizPage.setRootDirectory(quickstart.getPath().getAbsolutePath()); } catch (WaitTimeoutExpiredException e) { cleanupShells(); throw new NoProjectException(); } try { mavenImportWizard.finish(); } catch (MavenImportWizardException e) { for (String error : e.getErrors()) { reporter.addError(quickstart, error); } } } private void importTestUtilsIfNeeded(Quickstart qstart) { for (String error : ExamplesOperator.getInstance().getAllErrors()) { if (error.contains("Missing artifact org.javaee7:test-utils")) { Quickstart testUtils = new Quickstart("test-utils", qstart.getPath().getAbsolutePath().replace(qstart.getName(), "test-utils")); importQuickstart(testUtils); break; } if (error.contains("Missing artifact org.javaee7:util")) { Quickstart testUtils = new Quickstart("util", qstart.getPath().getAbsolutePath().replace(qstart.getName(), "test-utils")); importQuickstart(testUtils); break; } } } protected static void closeBrowser() { try { BrowserEditor browser = new BrowserEditor(new RegexMatcher(".*")); while (browser != null) { browser.close(); try { browser = new BrowserEditor(new RegexMatcher(".*")); } catch (CoreLayerException ex) { browser = null; } } } catch (CoreLayerException ex) { return; } } private static void setupMavenRepo() { String mvnConfigFileName = new File("target/classes/settings.xml").getAbsolutePath(); WorkbenchPreferenceDialog preferenceDialog = new WorkbenchPreferenceDialog(); preferenceDialog.open(); MavenSettingsPreferencePage prefPage = new MavenSettingsPreferencePage(); preferenceDialog.select(prefPage); prefPage.setUserSettingsLocation(mvnConfigFileName); preferenceDialog.ok(); new WaitUntil(new JobIsRunning()); } /** * Extended maven import wizard. When super.finsh() fails, waits another 15 * minutes. * * @author rhopp * */ private class ExtendedMavenImportWizard extends MavenImportWizard { @Override public void finish() { try { super.finish(); } catch (WaitTimeoutExpiredException ex) { new WaitWhile(new JobIsRunning(), TimePeriod.getCustom(60 * 15)); } } } class NoProjectException extends RedDeerException { public NoProjectException() { super("There is no project in this directory"); } } /** * Checks whether is project deployed properly. * * @param projectName * @param serverNameLabel */ public void checkDeployedProject(Quickstart qstart, String serverNameLabel) { if (!qstart.getName().contains("ejb-timer") && !qstart.getName().contains("cluster-ha-singleton")) { new WaitWhile(new JobIsRunning()); new WaitUntil(new ConsoleHasNoChange(TimePeriod.LONG), TimePeriod.VERY_LONG); } JBossServerView serversView = new JBossServerView(); serversView.open(); String moduleName = qstart.getName().equals("template") ? "QUICKSTART_NAME" : qstart.getName(); JBossServerModule module = (JBossServerModule) serversView.getServer(serverNameLabel) .getModule(new RegexMatcher(".*" + moduleName + ".*")); // cannot // be // used // projectName // - // issues // with // parent // projects if (new ContextMenu("Show In", "Web Browser").isEnabled()) { module.openWebPage(); final BrowserEditor browser = new BrowserEditor(new RegexMatcher(".*")); try { new WaitUntil(new BrowserIsnotEmpty(browser)); } catch (WaitTimeoutExpiredException e) { // try to refresh browser and wait one more time. browser.refreshPage(); new WaitUntil(new BrowserIsnotEmpty(browser)); } // Now the browser should not be empty. Let's check for error // messages // (strings like "404") checkBrowserForErrorPage(browser); assertNotEquals("", browser.getText()); new DefaultEditor().close(); } checkConsoleForException(); checkServerViewForStatus(moduleName, serverNameLabel); } protected void checkServerViewForStatus(String projectName, String serverNameLabel) { ServersView serversView = new ServersView(); serversView.open(); Server server = serversView.getServer(serverNameLabel); ServerModule serverModule = server.getModule(new RegexMatcher(".*" + projectName + ".*")); ModuleLabel moduleLabel = serverModule.getLabel(); ServerState moduleState = moduleLabel.getState(); org.junit.Assert.assertTrue("Module has not been started!", moduleState == ServerState.STARTED); } protected void checkConsoleForException() { ConsoleView consoleView = new ConsoleView(); consoleView.open(); assertFalse("Console contains text 'Operation (\"deploy\") failed':\n" + consoleView.getConsoleText(), consoleView.getConsoleText().contains("Operation (\"deploy\") failed")); } protected void checkBrowserForErrorPage(BrowserEditor browser) { ConsoleView consoleView = new ConsoleView(); consoleView.open(); assertFalse("Browser contains text 'Status 404'\n Console output:\n" + consoleView.getConsoleText(), browser.getText().contains("Status 404") || browser.getText().contains("404 - Not Found")); assertFalse( "Browser contains text 'Error processing request'\n Console output:\n" + consoleView.getConsoleText(), browser.getText().contains("Error processing request")); } class BrowserIsnotEmpty extends AbstractWaitCondition { BrowserEditor browser; public BrowserIsnotEmpty(BrowserEditor browser) { this.browser = browser; } public boolean test() { return !browser.getText().equals(""); } public String description() { return "Browser is empty!"; } } class ModuleStarted extends AbstractWaitCondition { String projectName; String serverNameLabel; public ModuleStarted(String projectName, String serverNameLabel) { this.projectName = projectName; this.serverNameLabel = serverNameLabel; } public boolean test() { ServersView serversView = new ServersView(); serversView.open(); Server server = serversView.getServer(serverNameLabel); ServerModule serverModule = server.getModule(new RegexMatcher(".*" + projectName + ".*")); ModuleLabel moduleLabel = serverModule.getLabel(); ServerState moduleState = moduleLabel.getState(); return moduleState == ServerState.STARTED; } public String description() { return "Module has not started!"; } } }