/*========================================================================= 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 // STL Header used for argv #include // 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 Args; char* DataRoot; double StartWallTime; double StartCPUTime; private: vtkTesting(const vtkTesting&) = delete; void operator=(const vtkTesting&) = delete; }; #endif