FindMatlab: added unit tests for new functionality.

Also allowing a way to select which of multiple installed MATLAB versions to use in the test.
This commit is contained in:
Cris Luengo 2018-10-22 02:19:04 -06:00
parent ee7e97a7d3
commit 160499296c
9 changed files with 191 additions and 9 deletions

View File

@ -1493,13 +1493,18 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
# Matlab module
# CMake_TEST_FindMatlab: indicates to look for Matlab (from PATH for Linux)
# CMake_TEST_FindMatlab_ROOT_DIR: indicates an optional root directory for Matlab, allows to select a version.
# CMake_TEST_FindMatlab_MCR: indicates the MCR is installed
# CMake_TEST_FindMatlab_MCR_ROOT_DIR: indicates an optional root directory for the MCR, required on Linux
if(CMake_TEST_FindMatlab OR CMake_TEST_FindMatlab_MCR OR (NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL ""))
if(CMake_TEST_FindMatlab OR (NOT "${CMake_TEST_FindMatlab_ROOT_DIR}" STREQUAL "") OR
CMake_TEST_FindMatlab_MCR OR (NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL ""))
set(FindMatlab_additional_test_options )
if(CMake_TEST_FindMatlab_MCR OR NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL "")
set(FindMatlab_additional_test_options -DIS_MCR=TRUE)
endif()
if(NOT "${CMake_TEST_FindMatlab_ROOT_DIR}" STREQUAL "")
set(FindMatlab_additional_test_options ${FindMatlab_additional_test_options} "-DMatlab_ROOT_DIR=${CMake_TEST_FindMatlab_ROOT_DIR}")
endif()
if(NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL "")
set(FindMatlab_additional_test_options ${FindMatlab_additional_test_options} "-DMCR_ROOT:FILEPATH=${CMake_TEST_FindMatlab_MCR_ROOT_DIR}")
endif()
@ -1511,6 +1516,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
ADD_TEST_MACRO(FindMatlab.components_checks ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>)
set(FindMatlab.failure_reports_BUILD_OPTIONS ${FindMatlab_additional_test_options})
ADD_TEST_MACRO(FindMatlab.failure_reports ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>)
set(FindMatlab.r2018a_check_BUILD_OPTIONS ${FindMatlab_additional_test_options})
ADD_TEST_MACRO(FindMatlab.r2018a_check ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>)
endif()
find_package(GTK2 QUIET)

View File

@ -10,11 +10,10 @@ set(MATLAB_FIND_DEBUG TRUE)
# - on 64bits builds (cmake is building with 64 bits), it looks for 64 bits Matlab
if(IS_MCR)
set(components MX_LIBRARY)
set(RUN_UNIT_TESTS FALSE)
else()
set(RUN_UNIT_TESTS TRUE)
set(components MX_LIBRARY MAIN_PROGRAM)
set(components MAIN_PROGRAM)
endif()
if(NOT "${MCR_ROOT}" STREQUAL "")
@ -34,7 +33,7 @@ matlab_add_mex(
OUTPUT_NAME cmake_matlab_mex1
SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper1.cpp
DOCUMENTATION ${CMAKE_CURRENT_SOURCE_DIR}/../help_text1.m.txt
)
)
if(RUN_UNIT_TESTS)
matlab_add_unit_test(

View File

@ -0,0 +1,28 @@
classdef cmake_matlab_unit_tests4 < matlab.unittest.TestCase
% Testing R2017b and R2018a APIs
properties
end
methods (Test)
function testR2017b(testCase)
ret = cmake_matlab_mex2a(5+6i);
testCase.verifyEqual(ret, 8);
end
function testR2018a(testCase)
ret = cmake_matlab_mex2b(5+6i);
v = version;
n = find(v=='.');
v = str2double(v(1:n(2)-1));
disp(v)
if v>= 9.4 % R2018a
testCase.verifyEqual(ret, 16);
disp('TESTING version >= 9.4')
else
testCase.verifyEqual(ret, 8);
end
end
end
end

View File

@ -0,0 +1,20 @@
classdef cmake_matlab_unit_tests5 < matlab.unittest.TestCase
% C++ API test
properties
end
methods (Test)
function testDummyCall(testCase)
% very simple call test
disp('TESTING C++')
ret = cmake_matlab_mex3(162);
testCase.verifyEqual(ret, 162);
end
function testFailTest(testCase)
testCase.verifyError(@() cmake_matlab_mex3, 'MATLAB:mex:CppMexException');
end
end
end

View File

@ -15,7 +15,7 @@ endif()
# the success of the following command is dependent on the current configuration:
# - on 32bits builds (cmake is building with 32 bits), it looks for 32 bits Matlab
# - on 64bits builds (cmake is building with 64 bits), it looks for 64 bits Matlab
find_package(Matlab REQUIRED COMPONENTS MX_LIBRARY ENG_LIBRARY MAT_LIBRARY
find_package(Matlab REQUIRED COMPONENTS ENG_LIBRARY MAT_LIBRARY
OPTIONAL_COMPONENTS MAIN_PROGRAM)
message(STATUS "FindMatlab libraries: ${Matlab_LIBRARIES}")
@ -28,4 +28,4 @@ matlab_add_mex(
SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper1.cpp
DOCUMENTATION ${CMAKE_CURRENT_SOURCE_DIR}/../help_text1.m.txt
LINK_TO ${Matlab_LIBRARIES}
)
)

View File

@ -8,11 +8,10 @@ project(failure_reports)
set(MATLAB_FIND_DEBUG TRUE)
if(IS_MCR)
set(components MX_LIBRARY)
set(RUN_UNIT_TESTS FALSE)
else()
set(RUN_UNIT_TESTS TRUE)
set(components MX_LIBRARY MAIN_PROGRAM)
set(components MAIN_PROGRAM)
endif()
if(NOT "${MCR_ROOT}" STREQUAL "")
@ -32,7 +31,7 @@ matlab_add_mex(
OUTPUT_NAME cmake_matlab_mex1
SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper1.cpp
DOCUMENTATION ${CMAKE_CURRENT_SOURCE_DIR}/../help_text1.m.txt
)
)
if(RUN_UNIT_TESTS)
# the unit test file does not exist: the failure should be properly reported

View File

@ -0,0 +1,16 @@
#include "mex.h"
// This test uses the new complex-interleaved C API (R2018a and newer)
// The input should be a complex array (scalar is OK). It returns the number of
// bytes in a matrix element. For the old (R2017b) API, this is 8. For the new
// (R2018a) API, this is 16.
void mexFunction(const int nlhs, mxArray* plhs[], const int nrhs,
const mxArray* prhs[])
{
if (nrhs != 1 || !mxIsComplex(prhs[0])) {
mexErrMsgTxt("Incorrect arguments");
}
plhs[0] = mxCreateDoubleScalar(mxGetElementSize(prhs[0]));
}

View File

@ -0,0 +1,29 @@
#include "mex.hpp"
#include "mexAdapter.hpp"
// This test uses the new C++ API (R2018a and newer)
// The input should be a scalar double array. The output is a copy of that
// array.
using namespace matlab::data;
using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function
{
public:
void operator()(ArgumentList outputs, ArgumentList inputs)
{
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
ArrayFactory factory;
if (inputs[0].getType() != ArrayType::DOUBLE ||
inputs[0].getType() == ArrayType::COMPLEX_DOUBLE ||
inputs[0].getNumberOfElements() != 1) {
matlabPtr->feval(
u"error", 0,
std::vector<Array>({ factory.createScalar("Incorrect arguments") }));
}
double a = inputs[0][0];
outputs[0] = factory.createScalar(a);
}
};

View File

@ -0,0 +1,84 @@
cmake_minimum_required (VERSION 2.8.12)
enable_testing()
project(r2018a_checks)
set(MATLAB_FIND_DEBUG TRUE)
# this test doesn't do much if MATLAB version < R2018a
if(IS_MCR)
set(RUN_UNIT_TESTS FALSE)
else()
set(RUN_UNIT_TESTS TRUE)
set(components MAIN_PROGRAM)
endif()
if(NOT "${MCR_ROOT}" STREQUAL "")
set(Matlab_ROOT_DIR "${MCR_ROOT}")
if(NOT EXISTS "${MCR_ROOT}")
message(FATAL_ERROR "MCR does not exist ${MCR_ROOT}")
endif()
endif()
find_package(Matlab REQUIRED COMPONENTS ${components})
set(IS_R2018a 1)
if(${Matlab_VERSION_STRING} VERSION_LESS "9.4")
# This is an older version of MATLAB, tests will fail
set(IS_R2018a 0)
endif()
matlab_add_mex(
# target name
NAME cmake_matlab_test_wrapper2a
# output name
OUTPUT_NAME cmake_matlab_mex2a
SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper2.cpp
R2017b
)
matlab_add_mex(
# target name
NAME cmake_matlab_test_wrapper2b
# output name
OUTPUT_NAME cmake_matlab_mex2b
SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper2.cpp
R2018a
)
if(IS_R2018a)
matlab_add_mex(
# target name
NAME cmake_matlab_test_wrapper3
# output name
OUTPUT_NAME cmake_matlab_mex3
SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper3.cpp
)
set_target_properties(
cmake_matlab_test_wrapper3
PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON
)
endif()
if(RUN_UNIT_TESTS)
# Check that the R2017b and R2018a APIs work.
matlab_add_unit_test(
NAME ${PROJECT_NAME}_matlabtest-1
TIMEOUT 300
UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests4.m
ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper2a>
)
# Check that the C++ API works (test run only on R2018a and newer)
if(IS_R2018a)
matlab_add_unit_test(
NAME ${PROJECT_NAME}_matlabtest-3
TIMEOUT 300
UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests5.m
ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper3>
)
endif()
endif()