Package com.eviware.soapui.tools

Source Code of com.eviware.soapui.tools.SoapUILoadTestRunner

/*
*  soapUI, copyright (C) 2004-2011 eviware.com
*
*  soapUI is free software; you can redistribute it and/or modify it under the
*  terms of version 2.1 of the GNU Lesser General Public License as published by
*  the Free Software Foundation.
*
*  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
*  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*  See the GNU Lesser General Public License for more details at gnu.org.
*/

package com.eviware.soapui.tools;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.cli.CommandLine;

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
import com.eviware.soapui.impl.wsdl.loadtest.data.actions.ExportLoadTestLogAction;
import com.eviware.soapui.impl.wsdl.loadtest.data.actions.ExportStatisticsAction;
import com.eviware.soapui.impl.wsdl.loadtest.log.LoadTestLog;
import com.eviware.soapui.impl.wsdl.loadtest.log.LoadTestLogEntry;
import com.eviware.soapui.model.project.ProjectFactoryRegistry;
import com.eviware.soapui.model.testsuite.LoadTestRunContext;
import com.eviware.soapui.model.testsuite.LoadTestRunListener;
import com.eviware.soapui.model.testsuite.LoadTestRunner;
import com.eviware.soapui.model.testsuite.TestCase;
import com.eviware.soapui.model.testsuite.TestCaseRunContext;
import com.eviware.soapui.model.testsuite.TestCaseRunner;
import com.eviware.soapui.model.testsuite.TestRunner.Status;
import com.eviware.soapui.model.testsuite.TestStep;
import com.eviware.soapui.model.testsuite.TestStepResult;
import com.eviware.soapui.model.testsuite.TestSuite;
import com.eviware.soapui.settings.UISettings;
import com.eviware.soapui.support.SoapUIException;
import com.eviware.soapui.support.StringUtils;

/**
* Standalone test-runner used from maven-plugin, can also be used from
* command-line (see xdocs) or directly from other classes.
* <p>
* For standalone usage, set the project file (with setProjectFile) and other
* desired properties before calling run
* </p>
*
* @author Ole.Matzura
*/

public class SoapUILoadTestRunner extends AbstractSoapUITestRunner implements LoadTestRunListener
{
  private String testSuite;
  private String testCase;
  private String loadTest;
  private boolean printReport;
  private List<LoadTestRunner> failedTests = new ArrayList<LoadTestRunner>();
  private int testCaseCount;
  private int loadTestCount;
  private int limit = -1;
  private long threadCount = -1;
  private boolean saveAfterRun;

  public static String TITLE = "soapUI " + SoapUI.SOAPUI_VERSION + " LoadTest Runner";

  /**
   * Runs the loadtests in the specified soapUI project file, see soapUI xdocs
   * for details.
   *
   * @param args
   * @throws Exception
   */

  public static void main( String[] args )
  {
    System.exit( new SoapUILoadTestRunner().runFromCommandLine( args ) );
  }

  protected boolean processCommandLine( CommandLine cmd )
  {
    String message = "";

    if( cmd.hasOption( "e" ) )
      setEndpoint( cmd.getOptionValue( "e" ) );

    if( cmd.hasOption( "s" ) )
    {
      String testSuite = getCommandLineOptionSubstSpace( cmd, "s" );
      setTestSuite( testSuite );
    }

    if( cmd.hasOption( "c" ) )
    {
      String testCase = cmd.getOptionValue( "c" );
      setTestCase( testCase );
    }

    if( cmd.hasOption( "l" ) )
      setLoadTest( cmd.getOptionValue( "l" ) );

    if( cmd.hasOption( "u" ) )
      setUsername( cmd.getOptionValue( "u" ) );

    if( cmd.hasOption( "p" ) )
      setPassword( cmd.getOptionValue( "p" ) );

    if( cmd.hasOption( "w" ) )
      setWssPasswordType( cmd.getOptionValue( "w" ) );

    if( cmd.hasOption( "d" ) )
      setDomain( cmd.getOptionValue( "d" ) );

    if( cmd.hasOption( "h" ) )
      setHost( cmd.getOptionValue( "h" ) );

    if( cmd.hasOption( "m" ) )
      setLimit( Integer.parseInt( cmd.getOptionValue( "m" ) ) );

    if( cmd.hasOption( "n" ) )
      setThreadCount( Integer.parseInt( cmd.getOptionValue( "n" ) ) );

    if( cmd.hasOption( "f" ) )
      setOutputFolder( getCommandLineOptionSubstSpace( cmd, "f" ) );

    if( cmd.hasOption( "t" ) )
      setSettingsFile( getCommandLineOptionSubstSpace( cmd, "t" ) );

    setPrintReport( cmd.hasOption( "r" ) );
    setSaveAfterRun( cmd.hasOption( "S" ) );

    if( cmd.hasOption( "x" ) )
    {
      setProjectPassword( cmd.getOptionValue( "x" ) );
    }

    if( cmd.hasOption( "v" ) )
    {
      setSoapUISettingsPassword( cmd.getOptionValue( "v" ) );
    }

    if( cmd.hasOption( "D" ) )
    {
      setSystemProperties( cmd.getOptionValues( "D" ) );
    }

    if( cmd.hasOption( "G" ) )
    {
      setGlobalProperties( cmd.getOptionValues( "G" ) );
    }

    if( cmd.hasOption( "P" ) )
    {
      setProjectProperties( cmd.getOptionValues( "P" ) );
    }

    if( message.length() > 0 )
    {
      log.error( message );
      return false;
    }

    return true;
  }

  public void setLimit( int limit )
  {
    this.limit = limit;
  }

  public void setThreadCount( long threadCount )
  {
    this.threadCount = threadCount;
  }

  protected SoapUIOptions initCommandLineOptions()
  {
    SoapUIOptions options = new SoapUIOptions( "loadtestrunner" );
    options.addOption( "e", true, "Sets the endpoint" );
    options.addOption( "s", true, "Sets the testsuite" );
    options.addOption( "c", true, "Sets the testcase" );
    options.addOption( "l", true, "Sets the loadtest" );
    options.addOption( "u", true, "Sets the username" );
    options.addOption( "p", true, "Sets the password" );
    options.addOption( "w", true, "Sets the WSS password type, either 'Text' or 'Digest'" );
    options.addOption( "d", true, "Sets the domain" );
    options.addOption( "h", true, "Sets the host" );
    options.addOption( "m", true, "Overrides the LoadTest Limit" );
    options.addOption( "n", true, "Overrides the LoadTest ThreadCount" );
    options.addOption( "r", false, "Exports statistics and testlogs for each LoadTest run" );
    options.addOption( "f", true, "Sets the output folder to export to" );
    options.addOption( "t", true, "Sets the soapui-settings.xml file to use" );
    options.addOption( "x", true, "Sets project password for decryption if project is encrypted" );
    options.addOption( "v", true, "Sets password for soapui-settings.xml file" );
    options.addOption( "D", true, "Sets system property with name=value" );
    options.addOption( "G", true, "Sets global property with name=value" );
    options.addOption( "P", true, "Sets or overrides project property with name=value" );
    options.addOption( "S", false, "Saves the project after running the tests" );

    return options;
  }

  public SoapUILoadTestRunner()
  {
    this( TITLE );
  }

  public SoapUILoadTestRunner( String title )
  {
    super( title );
  }

  public void setLoadTest( String loadTest )
  {
    this.loadTest = loadTest;
  }

  public void setPrintReport( boolean printReport )
  {
    this.printReport = printReport;
  }

  public void setSaveAfterRun( boolean saveAfterRun )
  {
    this.saveAfterRun = saveAfterRun;
  }

  /**
   * Runs the testcases as configured with setXXX methods
   *
   * @throws Exception
   *            thrown if any tests fail
   */

  public boolean runRunner() throws Exception
  {
    if( SoapUI.getSettings().getBoolean( UISettings.DONT_DISABLE_GROOVY_LOG ) )
    {
      initGroovyLog();
    }

    String projectFile = getProjectFile();

    // WsdlProject project = new WsdlProject( projectFile,
    // getProjectPassword() );
    WsdlProject project = ( WsdlProject )ProjectFactoryRegistry.getProjectFactory( "wsdl" ).createNew( projectFile,
        getProjectPassword() );

    if( project.isDisabled() )
      throw new Exception( "Failed to load soapUI project file [" + projectFile + "]" );

    initProjectProperties( project );

    int suiteCount = 0;

    if( testSuite != null && project.getTestSuiteByName( testSuite ) == null )
      throw new Exception( "Missing TestSuite named [" + testSuite + "]" );

    for( int c = 0; c < project.getTestSuiteCount(); c++ )
    {
      if( testSuite == null || project.getTestSuiteAt( c ).getName().equalsIgnoreCase( testSuite ) )
      {
        runSuite( project.getTestSuiteAt( c ) );
        suiteCount++ ;
      }
    }

    if( suiteCount == 0 )
    {
      log.warn( "No test-suites matched argument [" + testSuite + "]" );
    }
    else if( testCaseCount == 0 )
    {
      log.warn( "No test-cases matched argument [" + testCase + "]" );
    }
    else if( loadTestCount == 0 )
    {
      log.warn( "No load-tests matched argument [" + loadTest + "]" );
    }
    else
    {
      if( saveAfterRun && !project.isRemote() )
      {
        try
        {
          project.save();
        }
        catch( Throwable t )
        {
          log.error( "Failed to save project", t );
        }
      }

      if( !failedTests.isEmpty() )
      {
        log.info( failedTests.size() + " load tests failed:" );
        for( LoadTestRunner loadTestRunner : failedTests )
        {
          log.info( loadTestRunner.getLoadTest().getName() + ": " + loadTestRunner.getReason() );
        }

        throw new SoapUIException( "LoadTests failed" );
      }
    }

    return true;
  }

  /**
   * Run tests in the specified TestSuite
   *
   * @param suite
   *           the TestSuite to run
   */

  public void runSuite( TestSuite suite )
  {
    if( testCase != null && suite.getTestCaseByName( testCase ) == null )
    {
      return;
    }

    long start = System.currentTimeMillis();
    for( int c = 0; c < suite.getTestCaseCount(); c++ )
    {
      String name = suite.getTestCaseAt( c ).getName();
      if( testCase == null || name.equalsIgnoreCase( testCase ) )
      {
        runTestCase( suite.getTestCaseAt( c ) );
        testCaseCount++ ;
      }
      else
        log.info( "Skipping testcase [" + name + "], filter is [" + testCase + "]" );
    }
    log.info( "soapUI suite [" + suite.getName() + "] finished in " + ( System.currentTimeMillis() - start ) + "ms" );
  }

  /**
   * Runs the specified TestCase
   *
   * @param testCase
   *           the testcase to run
   */

  private void runTestCase( TestCase testCase )
  {
    if( loadTest != null && testCase.getLoadTestByName( loadTest ) == null )
    {
      return;
    }

    for( int c = 0; c < testCase.getLoadTestCount(); c++ )
    {
      String name = testCase.getLoadTestAt( c ).getName();
      if( loadTest == null || loadTest.equalsIgnoreCase( name ) )
      {
        runWsdlLoadTest( ( WsdlLoadTest )testCase.getLoadTestAt( c ) );
        loadTestCount++ ;
      }
    }
  }

  /**
   * Runs the specified LoadTest
   *
   * @param loadTest
   *           the loadTest to run
   */

  protected void runWsdlLoadTest( WsdlLoadTest loadTest )
  {
    try
    {
      log.info( "Running LoadTest [" + loadTest.getName() + "]" );
      if( limit >= 0 )
      {
        log.info( "Overriding limit [" + loadTest.getTestLimit() + "] with specified [" + limit + "]" );
        loadTest.setTestLimit( limit );
      }

      if( threadCount >= 0 )
      {
        log.info( "Overriding threadCount [" + loadTest.getThreadCount() + "] with specified [" + threadCount + "]" );
        loadTest.setThreadCount( threadCount );
      }

      loadTest.addLoadTestRunListener( this );
      LoadTestRunner runner = loadTest.run();

      // wait for test to finish
      while( !runner.hasStopped() )
      {
        if( runner.getStatus() == Status.RUNNING )
        {
          log.info( "LoadTest [" + loadTest.getName() + "] progress: " + runner.getProgress() + ", "
              + runner.getRunningThreadCount() );
        }
        Thread.sleep( 1000 );
      }

      log.info( "LoadTest [" + loadTest.getName() + "] finished with status " + runner.getStatus().toString() );

      if( printReport )
      {
        log.info( "Exporting log and statistics for LoadTest [" + loadTest.getName() + "]" );

        loadTest.getStatisticsModel().finish();

        exportLog( loadTest );
        exportStatistics( loadTest );
      }
    }
    catch( Exception e )
    {
      SoapUI.logError( e );
      log.error( e );
    }
  }

  private void exportStatistics( WsdlLoadTest loadTest ) throws IOException
  {
    ExportStatisticsAction exportStatisticsAction = new ExportStatisticsAction( loadTest.getStatisticsModel() );
    String statisticsFileName = StringUtils.createFileName( loadTest.getName(), '_' ) + "-statistics.txt";
    if( getOutputFolder() != null )
    {
      ensureOutputFolder( loadTest );
      statisticsFileName = getAbsoluteOutputFolder( loadTest ) + File.separator + statisticsFileName;
    }

    int cnt = exportStatisticsAction.exportToFile( new File( statisticsFileName ) );
    log.info( "Exported " + cnt + " statistics to [" + statisticsFileName + "]" );
  }

  private void exportLog( WsdlLoadTest loadTest ) throws IOException
  {
    // export log first
    LoadTestLog loadTestLog = loadTest.getLoadTestLog();
    ExportLoadTestLogAction exportLoadTestLogAction = new ExportLoadTestLogAction( loadTestLog, null );
    String logFileName = StringUtils.createFileName( loadTest.getName(), '_' ) + "-log.txt";
    if( getOutputFolder() != null )
    {
      ensureOutputFolder( loadTest );
      logFileName = getAbsoluteOutputFolder( loadTest ) + File.separator + logFileName;
    }

    int cnt = exportLoadTestLogAction.exportToFile( new File( logFileName ) );
    log.info( "Exported " + cnt + " log items to [" + logFileName + "]" );

    int errorCnt = 0;
    for( int c = 0; c < loadTestLog.getSize(); c++ )
    {
      LoadTestLogEntry entry = ( LoadTestLogEntry )loadTestLog.getElementAt( c );

      if( entry != null && entry.isError() )
      {
        String entryFileName = StringUtils.createFileName( loadTest.getName(), '_' ) + "-error-" + errorCnt++
            + "-entry.txt";
        if( getOutputFolder() != null )
        {
          ensureOutputFolder( loadTest );
          entryFileName = getAbsoluteOutputFolder( loadTest ) + File.separator + entryFileName;
        }

        try
        {
          entry.exportToFile( entryFileName );
        }
        catch( Exception e )
        {
          SoapUI.logError( e );
        }
      }
    }
    log.info( "Exported " + errorCnt + " error results" );
  }

  /**
   * Sets the testcase to run
   *
   * @param testCase
   *           the testcase to run
   */

  public void setTestCase( String testCase )
  {
    this.testCase = testCase;
  }

  /**
   * Sets the TestSuite to run. If not set all TestSuites in the specified
   * project file are run
   *
   * @param testSuite
   *           the testSuite to run.
   */

  public void setTestSuite( String testSuite )
  {
    this.testSuite = testSuite;
  }

  public void afterLoadTest( LoadTestRunner loadTestRunner, LoadTestRunContext context )
  {
    if( loadTestRunner.getStatus() == LoadTestRunner.Status.FAILED )
    {
      failedTests.add( loadTestRunner );
    }
  }

  public void afterTestCase( LoadTestRunner loadTestRunner, LoadTestRunContext context, TestCaseRunner testRunner,
      TestCaseRunContext runContext )
  {
  }

  public void afterTestStep( LoadTestRunner loadTestRunner, LoadTestRunContext context, TestCaseRunner testRunner,
      TestCaseRunContext runContext, TestStepResult testStepResult )
  {
    super.afterStep( testRunner, runContext, testStepResult );
  }

  public void beforeLoadTest( LoadTestRunner loadTestRunner, LoadTestRunContext context )
  {
  }

  public void beforeTestCase( LoadTestRunner loadTestRunner, LoadTestRunContext context, TestCaseRunner testRunner,
      TestCaseRunContext runContext )
  {
  }

  public void beforeTestStep( LoadTestRunner loadTestRunner, LoadTestRunContext context, TestCaseRunner testRunner,
      TestCaseRunContext runContext, TestStep testStep )
  {
    super.beforeStep( testRunner, runContext, testStep );
  }

  public void loadTestStarted( LoadTestRunner loadTestRunner, LoadTestRunContext context )
  {
  }

  public void loadTestStopped( LoadTestRunner loadTestRunner, LoadTestRunContext context )
  {
  }
}
TOP

Related Classes of com.eviware.soapui.tools.SoapUILoadTestRunner

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.