/* * Copyright 2005-2010 Ignis Software Tools Ltd. All rights reserved. */ package jsystem.framework.scenario; import java.io.File; import java.util.HashSet; import java.util.Iterator; import java.util.Properties; import java.util.Set; import jsystem.framework.FrameworkOptions; import jsystem.framework.JSystemProperties; import jsystem.framework.distributedexecution.DistributedExecutionPlugin; import jsystem.framework.distributedexecution.DistributedRunExecutor; import jsystem.framework.scenario.Parameter.ParameterType; import jsystem.utils.StringUtils; /** * Used by the platform to manage and perform distributed execution. * @author goland */ public class DistributedExecutionHelper { /** * Distributed execution section. */ public final static String SCENARIO_HOSTS_PARAMETERS_SECTION = "JSystem Agents"; /** * Name of mandatory parameter. */ public static final String AGENTS = "Agents"; /** * Instance of the mandatory parameter {@link #AGENTS}. should be cloned by the * plug-in. */ public static final DistributedExecutionParameter AGENTS_SELECT = new DistributedExecutionParameter(AGENTS,ParameterType.STRING,""); /** * Returns the current DistributedExecutionPlugin. */ public static DistributedExecutionPlugin getPlugin() throws Exception{ String pluginClass = JSystemProperties.getInstance().getPreference(FrameworkOptions.DISTRIBUTED_EXECUTION_PLUGIN); if (StringUtils.isEmpty(pluginClass)){ return (DistributedExecutionPlugin)Class.forName("jsystem.runner.agent.clients.DefaultDistributedExecutionPlugin").newInstance(); } return (DistributedExecutionPlugin)Class.forName(pluginClass).newInstance(); } /** * Given a {@link JTest} returns an array of @{link {@link DistributedExecutionParameter} * that should be presented for this test. * If the system find values for these parameters, the returned parameters are * populated with the values, otherwise, the parameters are returned with default values. */ static DistributedExecutionParameter[] getHostsParameters(JTest test) throws Exception { String rootScenario = ScenariosManager.getInstance().getCurrentScenario().getName(); return getHostParametersForUniqueId(rootScenario,test.getFullUUID()); } /** * Given a test unique id and root scenario of the test, * returns an array of @{link {@link DistributedExecutionParameter} * that should be presented for this test. * If the system find values for these parameters, the returned parameters are * populated with the values, otherwise, the parameters are returned with default values. */ public static DistributedExecutionParameter[] getHostParametersForUniqueId(String rootScenarioName,String uniqueId) throws Exception { String fileName = ScenarioHelpers.getScenarioPropertiesFile(rootScenarioName); Properties prop = new Properties(); if ((new File(fileName).exists())){ prop = ScenarioHelpers.getScenarioProperties(rootScenarioName); } String uuidString = (StringUtils.isEmpty(uniqueId))? "" : uniqueId+"."; DistributedExecutionParameter[] hostsParameters = getPlugin().getDistributedExecutionParameters(); for (DistributedExecutionParameter param:hostsParameters){ if (prop.getProperty(uuidString+param.getName())!= null){ param.setValue(prop.getProperty(uuidString+param.getName())); } } return hostsParameters; } /** * Updates root scenario properties file with parameters values. */ static void setHostsParameters(JTest test,DistributedExecutionParameter[] params) throws Exception { String rootScenario = ScenariosManager.getInstance().getCurrentScenario().getName(); Properties prop = ScenarioHelpers.getRootProperties(); String uuid = test.getFullUUID(); String uuidString = (StringUtils.isEmpty(uuid))? "" : uuid+"."; for (Parameter p : params){ prop.setProperty(uuidString+p.getName(), p.getValue() == null ? "" :p.getValue().toString()); } if (prop.size() == 0){ // no scenario parameters return; } ScenarioHelpers.saveScenarioPropertiesToSrcAndClass(prop, rootScenario,true); } /** * Returns true if the array of parameters includes the #AGENTS parameters and if * it has a value. */ public static boolean isAssigned(DistributedExecutionParameter[] parameters) { for (DistributedExecutionParameter p:parameters){ if (p.getName().equals(AGENTS) && !StringUtils.isEmpty((String)p.getValue())){ return true; } } return false; } /** * Returns true if test parameters includes the #AGENTS parameters and if * it has a value. */ public static boolean isAssigned(JTest test) throws Exception{ return isAssigned(test.getDistributedExecutionParameters()); } /** * Finds the {@link #AGENTS} parameter, if it is not empty, splits * the value to array of urls. */ public static String[] getUrls(DistributedExecutionParameter[] parameters) { for (DistributedExecutionParameter p:parameters){ if (p.getName().equals(AGENTS) && !StringUtils.isEmpty((String)p.getValue())){ return StringUtils.split((String)p.getValue(),";"); } } return new String[0]; } /** * Returns to if <code>t</code> has an ancestor which is associated * with agents to be executed on. */ public static boolean ancestorIsAssignedWithHosts(JTest t) throws Exception{ while (t.getParent()!=null ){ t = t.getParent(); if (DistributedExecutionHelper.isAssigned(t.getDistributedExecutionParameters())){ return true; } } return false; } /** * Gathers all the agents URLs which are associated * with current scenario.<br> */ public static String[] getParticipatingHosts() throws Exception { Properties props = ScenarioHelpers.getRootProperties(); Set<String> results = new HashSet<String>(); gatherHosts(ScenariosManager.getInstance().getCurrentScenario(), props, results); return results.toArray(new String[0]); } /** * */ private static void gatherHosts(JTestContainer s,Properties props, Set<String> results) throws Exception { Iterator<JTest> iter = s.getRootTests().iterator(); while (iter.hasNext()){ JTest t = iter.next(); String uuid = t.getFullUUID(); String hosts = props.getProperty(uuid+"."+AGENTS); if (!StringUtils.isEmpty(hosts)){ String[] splitedHosts = StringUtils.split(hosts,";"); for (String h:splitedHosts){ results.add(h); } }else { if (t instanceof JTestContainer) { gatherHosts((JTestContainer)t, props, results); } } } } /** * Invoked in the test jvm side. * Returns true if the {@value RunningProperties.JSYSTEM_AGENT} is set to * true. * * The {@value RunningProperties.JSYSTEM_AGENT} is passed to the test jvm execution command line. * */ public static boolean isAgent(){ String invokeRemoteAgent = System.getProperty(RunningProperties.JSYSTEM_AGENT); if ("true".equals(invokeRemoteAgent)){ return true; } return false; } /** * Returns true if the {@value FrameworkOptions.IGNORE_DISTRIBUTED_EXECUTION} is set to * true.<br> * Invoked in the test jvm side.<br> * The {@value FrameworkOptions.IGNORE_DISTRIBUTED_EXECUTION} is a jsystem property, it can be * set to true by the user.<br> * The purpose of the property is to enable the user to execute scenario locally while * planing/developing, once the scenario is ready to be executed in a distributed manner, * the flag can be set to false. */ public static boolean ignoreDistributedExecution(){ String ignore = JSystemProperties.getInstance().getPreference(FrameworkOptions.IGNORE_DISTRIBUTED_EXECUTION); if ("true".equals(ignore)){ return true; } return false; } /** * Returns true if test with <code>uuid</code> is associated with remote * execution parameters.<br> * The method is invoked in test jvm side. * Root scenario name is fetched from a system property named {@value RunningProperties.CURRENT_SCENARIO_NAME} * The value is passed to the test execution jvm by the runner. */ public static boolean hasRemoteExecutionProperties(String uuid) throws Exception { String rootScenarioName = System.getProperty(RunningProperties.CURRENT_SCENARIO_NAME); DistributedExecutionParameter[] parameters = DistributedExecutionHelper.getHostParametersForUniqueId(rootScenarioName,uuid); if (DistributedExecutionHelper.isAssigned(parameters)){ return true; } return false; } /** * Returns a fully populated {@link DistributedRunExecutor}.<br> * Invoked in test execution jvm.<br> * Executor instance is created by the plug-in, and populated from * root scenario properties. */ public static DistributedRunExecutor getPopulatedExecutor(String uuidToExecute) throws Exception{ String rootScenarioName = System.getProperty(RunningProperties.CURRENT_SCENARIO_NAME); DistributedExecutionPlugin plugin = DistributedExecutionHelper.getPlugin(); DistributedRunExecutor executor = plugin.getDistributedRunExecutor(); DistributedExecutionParameter[] parameters = DistributedExecutionHelper.getHostParametersForUniqueId(rootScenarioName,uuidToExecute); executor.setHostsParameters(parameters); Scenario s = ScenariosManager.getInstance().getScenario(rootScenarioName); s.loadParametersAndValues(); JTest t = ScenarioHelpers.getTestById(s,uuidToExecute); executor.setTestToExecute(t); return executor; } /** * Return true if test/scenario with id <code>uuid</code> should * be executed remotely. */ public static boolean doRemoteExecution(String uuid) throws Exception { return !isAgent()&& hasRemoteExecutionProperties(uuid) && !ignoreDistributedExecution(); } }