Skip to content

Commit 6e8f7f3

Browse files
authored
Decouple MATLAB Functions Test from Controller.def (#6752)
* test matlab functions against controller headers * fix MATLAB capitalization * fix typo * print stderr on subprocess failure
1 parent 78755a4 commit 6e8f7f3

File tree

2 files changed

+63
-29
lines changed

2 files changed

+63
-29
lines changed

include/controller/c/webots/supervisor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,10 @@ void wb_supervisor_simulation_revert() WB_DEPRECATED; // please us
224224
void wb_supervisor_load_world(const char *filename) WB_DEPRECATED; // please use wb_supervisor_world_load() instead
225225
bool wb_supervisor_save_world(const char *filename) WB_DEPRECATED; // please use wb_supervisor_world_save() instead
226226

227-
// deprecated since Webots 8.6.0, plesae use wb_supervisor_field_remove_mf_item() instead
227+
// deprecated since Webots 8.6.0, please use wb_supervisor_field_remove_mf() instead
228228
void wb_supervisor_field_remove_mf_node(WbFieldRef field, int position) WB_DEPRECATED;
229229

230-
// deprecated since Webots 8.0.0, plesae use wb_supervisor_simulation_reset_physics() instead
230+
// deprecated since Webots 8.0.0, please use wb_supervisor_simulation_reset_physics() instead
231231
void wb_supervisor_simulation_physics_reset() WB_DEPRECATED;
232232

233233
// deprecated since Webots 8.4.0 please use wb_supervisor_movie_is_ready and wb_supervisor_movie_failed

tests/sources/test_matlab_functions.py

100755100644
Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,54 +14,88 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
"""Test that all the required Matlab functions are defined."""
17+
"""Test that all the required MATLAB functions are defined."""
1818
import unittest
19+
import glob
1920
import os
21+
import re
22+
import subprocess
2023
import sys
24+
2125
WEBOTS_HOME = os.path.normpath(os.environ['WEBOTS_HOME'])
2226
sys.path.append(os.path.join(WEBOTS_HOME, 'src', 'controller', 'matlab'))
2327
import mgenerate # noqa: E402
2428

2529

2630
class TestMatlabFunctions(unittest.TestCase):
27-
"""Unit test for checking that all the required Matlab functions are defined."""
31+
"""Unit test for checking that all the required MATLAB functions are defined."""
2832

2933
def setUp(self):
3034
if sys.version_info[0] >= 3:
3135
mgenerate.UPDATE = False
3236
mgenerate.main()
33-
"""Get all the required function."""
37+
"""Get all the required functions."""
3438
skippedLines = [
35-
'wbr',
36-
'microphone',
37-
'remote_control',
38-
'robot',
39-
'wb_device_get_type',
40-
'wb_node_get_name',
41-
'wbu_string',
42-
'lookup_table_size',
43-
'EXPORTS'
39+
# Patterns
40+
'.*_H', # Header Guards
41+
'.*_', # Some comments use the ..._* pattern to refer to a group of functions ;
42+
# grep will filter the *, but no function should end with _
43+
'wb_camera_image_get_.*', # The MATLAB API exposes the image data as a multidimensional array,
44+
# so these functions are not needed
45+
'wb_(microphone|radio)_.*', # Experimental Node Types
46+
'wb_remote_control_.*', 'wbr_.*', # Remote Control Plugin
47+
'wb_robot_.*', # Many robot functions are used internally by the C API (e.x. wb_robot_mutex_*)
48+
'.*_lookup_table_size', # MATLAB lets you get the size of an array, so these functions are not needed
49+
'wbu_string_.*', # String manipulation functions are not needed
50+
51+
# Specific Functions
52+
53+
# Non-Function Macros
54+
'WB_ALLOW_MIXING_C_AND_CPP_API',
55+
'WB_DEPRECATED',
56+
'WB_MATLAB_LOADLIBRARY',
57+
'WB_USING_C(PP)?_API',
58+
59+
# These functions are used internally by the MATLAB API
60+
'wb_camera_recognition_get_object',
61+
'wb_lidar_get_point',
62+
'wb_mouse_get_state_pointer',
63+
'wb_radar_get_target',
64+
65+
'wb_device_get_type', # Deprecated since 8.0.0
66+
'wb_node_get_name', # C API Only
67+
68+
# Not Yet Implemented
69+
'wbu_system_tmpdir',
70+
'wbu_system_webots_instance_path',
4471
]
4572
self.functions = []
46-
filename = os.path.join(WEBOTS_HOME, 'src', 'controller', 'c', 'Controller.def')
47-
self.assertTrue(
48-
os.path.isfile(filename),
49-
msg='Missing "%s" file.' % filename
50-
)
51-
with open(filename) as file:
52-
for line in file:
53-
if not any(skippedLine in line for skippedLine in skippedLines) and not line[3:].isupper():
54-
self.functions.append(line.replace('\n', ''))
73+
74+
symbolSearch = subprocess.run([
75+
# Search for webots definitions
76+
'grep', '-Ehio', r'\bwb_\w+\b',
77+
# In the controller headers
78+
*glob.glob(os.path.join(WEBOTS_HOME, 'include', 'controller', 'c', 'webots', '*.h')),
79+
*glob.glob(os.path.join(WEBOTS_HOME, 'include', 'controller', 'c', 'webots', 'utils', '*.h'))
80+
], capture_output=True, text=True)
81+
if symbolSearch.returncode != 0:
82+
self.fail(f'Failed to generate function list:\n{symbolSearch.stdout}\n{symbolSearch.stderr}')
83+
84+
for line in symbolSearch.stdout.splitlines():
85+
if not any(re.match(f'^{skippedLine}$', line) for skippedLine in skippedLines) and line not in self.functions:
86+
self.functions.append(line)
5587

5688
@unittest.skipIf(sys.version_info[0] < 3, "not supported by Python 2.7")
5789
def test_matlab_function_exists(self):
5890
"""Test that the function file exists."""
59-
for function in self.functions:
60-
filename = os.path.join(WEBOTS_HOME, 'lib', 'controller', 'matlab', function + '.m')
61-
self.assertTrue(
62-
os.path.isfile(filename),
63-
msg='Missing "%s" file.' % filename
64-
)
91+
expectedFiles = (os.path.join(WEBOTS_HOME, 'lib', 'controller', 'matlab', function + '.m')
92+
for function in self.functions)
93+
missingFiles = [file for file in expectedFiles if not os.path.isfile(file)]
94+
95+
self.assertTrue(
96+
not missingFiles,
97+
msg='Missing files: %s' % ', '.join(missingFiles)
98+
)
6599

66100

67101
if __name__ == '__main__':

0 commit comments

Comments
 (0)