You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

345 lines
9.3 KiB
C

/*=========================================================================
Program: Visualization Toolkit
Module: vtkTesting.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/**
* @class vtkTesting
* @brief a unified VTK regression testing framework
*
*
* This is a VTK regression testing framework. Looks like this:
*
* vtkTesting* t = vtkTesting::New();
*
* Two options for setting arguments
*
* Option 1:
* for ( cc = 1; cc < argc; cc ++ )
* {
* t->AddArgument(argv[cc]);
* }
*
* Option 2:
* t->AddArgument("-D");
* t->AddArgument(my_data_dir);
* t->AddArgument("-V");
* t->AddArgument(my_valid_image);
*
* ...
*
* Two options of doing testing:
*
* Option 1:
* t->SetRenderWindow(renWin);
* int res = t->RegressionTest(threshold);
*
* Option 2:
* int res = t->RegressionTest(test_image, threshold);
*
* ...
*
* if (res == vtkTesting::PASSED)
* {
* Test passed
* }
* else
* {
* Test failed
* }
*
*/
#ifndef vtkTesting_h
#define vtkTesting_h
#include "vtkObject.h"
#include "vtkTestingRenderingModule.h" // For export macro
#include <string> // STL Header used for argv
#include <vector> // STL Header used for argv
class vtkAlgorithm;
class vtkRenderWindow;
class vtkImageData;
class vtkDataArray;
class vtkDataSet;
class vtkRenderWindowInteractor;
/**
* A unit test may return this value to tell ctest to skip the test. This can
* be used to abort a test when an unsupported runtime configuration is
* detected.
*/
const int VTK_SKIP_RETURN_CODE = 125;
class VTKTESTINGRENDERING_EXPORT vtkTesting : public vtkObject
{
public:
static vtkTesting* New();
vtkTypeMacro(vtkTesting, vtkObject);
void PrintSelf(ostream& os, vtkIndent indent) override;
enum ReturnValue
{
FAILED = 0,
PASSED = 1,
NOT_RUN = 2,
DO_INTERACTOR = 3
};
static int Test(int argc, char* argv[], vtkRenderWindow* rw, double thresh);
/**
* This method is intended to be a comprehensive, one line replacement for
* vtkRegressionTest and for the replay based testing using
* vtkInteractorEventRecorder, greatly simplifying API and code
* bloat. It scans the command line specified for the following :
* - If a "--DisableReplay" is specified, it disables the testing
* replay. This is particularly useful in enabling the user to
* exercise the widgets. Typically the widgets are defined by the
* testing replay, so the user misses out on playing around with the
* widget definition behaviour.
* - If a "--Record" is specified, it records the interactions into
* a "vtkInteractorEventRecorder.log" file. This is useful when
* creating the playback stream that is plugged into tests. The
* file can be used to create a const char * variable for playback
* or can copied into a location as a playback file.
* - If a "--PlaybackFile filename is specified,the provided file
* contains the events and is passed to the event recorder.
* Typical usage in a test for a VTK widget that needs playback
* testing / recording is :
* const char TestFooWidgetLog[] = {
* ....
* };
* int TestFooWidget( int argc, char *argv[] )
* {
* ...
* return vtkTesting::InteractorEventLoop(
* argc, argv, iren,
* TestFooWidgetLog );
* }
* In tests that playback events from a file:
* TestFooEventLog.txt stored in ../Data/Input/TestFooEventLog.txt
* The CMakeLists.txt file should contain:
* set(TestFoo_ARGS "--PlaybackFile"
* "DATA{../Data/Input/TestFooEventLog.txt}")
* and the API is
* int TestFoo( int argc, char *argv[] )
* {
* ...
* return vtkTesting::InteractorEventLoop( argc, argv, iren );
* }
* In tests where no playback is exercised, the API is simply
* int TestFoo( int argc, char *argv[] )
* {
* ...
* return vtkTesting::InteractorEventLoop( argc, argv, iren );
* }
*/
static int InteractorEventLoop(
int argc, char* argv[], vtkRenderWindowInteractor* iren, const char* stream = nullptr);
//@{
/**
* Use the front buffer first for regression test comparisons. By
* default use back buffer first, then try the front buffer if the
* test fails when comparing to the back buffer.
*/
vtkBooleanMacro(FrontBuffer, vtkTypeBool);
vtkGetMacro(FrontBuffer, vtkTypeBool);
void SetFrontBuffer(vtkTypeBool frontBuffer);
//@}
/**
* Perform the test and return the result. Delegates to
* RegressionTestAndCaptureOutput, sending the output to cout.
*/
virtual int RegressionTest(double thresh);
/**
* Perform the test and return the result. At the same time, write
* the output to the output stream os. Includes timing information
* in the output.
*/
virtual int RegressionTestAndCaptureOutput(double thresh, ostream& os);
/**
* Perform the test and return the result. At the same time, write
* the output to the output stream os. This method is nearly the
* same as RegressionTestAndCaptureOutput, but does not include
* timing information in the output.
*/
virtual int RegressionTest(double thresh, ostream& os);
//@{
/**
* Perform the test and return result. The test image will be read from the
* png file at pngFileName.
*/
virtual int RegressionTest(const std::string& pngFileName, double thresh);
virtual int RegressionTest(const std::string& pngFileName, double thresh, ostream& os);
//@}
//@{
/**
* Compare the image with the valid image.
*/
virtual int RegressionTest(vtkAlgorithm* imageSource, double thresh);
virtual int RegressionTest(vtkAlgorithm* imageSource, double thresh, ostream& os);
//@}
/**
* Compute the average L2 norm between all point data data arrays
* of types float and double present in the data sets "dsA" and "dsB"
* (this includes instances of vtkPoints) Compare the result of
* each L2 comutation to "tol".
*/
int CompareAverageOfL2Norm(vtkDataSet* pdA, vtkDataSet* pdB, double tol);
/**
* Compute the average L2 norm between two data arrays "daA" and "daB"
* and compare against "tol".
*/
int CompareAverageOfL2Norm(vtkDataArray* daA, vtkDataArray* daB, double tol);
//@{
/**
* Set and get the render window that will be used for regression testing.
*/
virtual void SetRenderWindow(vtkRenderWindow* rw);
vtkGetObjectMacro(RenderWindow, vtkRenderWindow);
//@}
//@{
/**
* Set/Get the name of the valid image file
*/
vtkSetStringMacro(ValidImageFileName);
const char* GetValidImageFileName();
//@}
//@{
/**
* Get the image difference.
*/
vtkGetMacro(ImageDifference, double);
//@}
//@{
/**
* Pass the command line arguments into this class to be processed. Many of
* the Get methods such as GetValidImage and GetBaselineRoot rely on the
* arguments to be passed in prior to retrieving these values. Just call
* AddArgument for each argument that was passed into the command line
*/
void AddArgument(const char* argv);
void AddArguments(int argc, const char** argv);
void AddArguments(int argc, char** argv);
//@}
/**
* Search for a specific argument by name and return its value
* (assumed to be the next on the command tail). Up to caller
* to delete the returned string.
*/
char* GetArgument(const char* arg);
/**
* This method delete all arguments in vtkTesting, this way you can reuse
* it in a loop where you would have multiple testing.
*/
void CleanArguments();
//@{
/**
* Get some parameters from the command line arguments, env, or defaults
*/
const char* GetDataRoot();
vtkSetStringMacro(DataRoot);
//@}
//@{
/**
* Get some parameters from the command line arguments, env, or defaults
*/
const char* GetTempDirectory();
vtkSetStringMacro(TempDirectory);
//@}
/**
* Is a valid image specified on the command line areguments?
*/
int IsValidImageSpecified();
/**
* Is the interactive mode specified?
*/
int IsInteractiveModeSpecified();
/**
* Is some arbitrary user flag ("-X", "-Z" etc) specified
*/
int IsFlagSpecified(const char* flag);
//@{
/**
* Number of pixels added as borders to avoid problems with
* window decorations added by some window managers.
*/
vtkSetMacro(BorderOffset, int);
vtkGetMacro(BorderOffset, int);
//@}
//@{
/**
* Get/Set verbosity level. A level of 0 is quiet.
*/
vtkSetMacro(Verbose, int);
vtkGetMacro(Verbose, int);
//@}
protected:
vtkTesting();
~vtkTesting() override;
static char* IncrementFileName(const char* fname, int count);
static int LookForFile(const char* newFileName);
vtkTypeBool FrontBuffer;
vtkRenderWindow* RenderWindow;
char* ValidImageFileName;
double ImageDifference;
char* TempDirectory;
int BorderOffset;
int Verbose;
std::vector<std::string> Args;
char* DataRoot;
double StartWallTime;
double StartCPUTime;
private:
vtkTesting(const vtkTesting&) = delete;
void operator=(const vtkTesting&) = delete;
};
#endif