-
Notifications
You must be signed in to change notification settings - Fork 238
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automated gtest formatting checks #3370
base: develop
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just double checking - does the script detects missed INSTANTIATE_TEST_SUITE_P
for TEST_P
?
|
Will be adding some additional logic to the bash script to ensure better error messages |
VALID_HW_TYPES = {"CPU", "GPU"} | ||
VALID_DATATYPES = {"FP8", "FP16", "FP32", "FP64", "BFP16", "BFP8", "I64", "I32", "I16", "I8", "NONE"} | ||
TESTSUITE_REGEX = re.compile( | ||
r"^(CPU|GPU)_[A-Za-z0-9]+(?:_[A-Za-z0-9]+)*_(" + "|".join(VALID_DATATYPES) + r")$" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't it duplicate #3218 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one extends on it + CI integration that runs upon adding new gtest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need separate python scripts?
Seems like we might be able to unify these.
Jenkinsfile
Outdated
when { | ||
changeset "**/test/utils/**" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this only run if changes happened inside test/utils?
I think we would want this to run if changes happened in changeset "**/test/gtest/**"
Also, did we run it generally on the latest changes to ensure everything is now passing?
test/utils/gtest_formating_checks.py
Outdated
if not TESTSUITE_REGEX.match(suite): | ||
errors.append(f"{file_path}: Invalid TESTSUITE_NAME '{suite}' in TEST_P.") | ||
|
||
if suite not in instantiated_suites: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's nice to catch these before runtime! It does need to be aware of GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST though, and it also gives false failures when macros are used, e.g. layout_transpose.cpp. I don't think we should discard that flexibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implement GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST, and look into running files through the preprocessor prior to running this script.
"../../test/gtest/binary_tensor_ops.cpp", | ||
"../../test/gtest/layout_transpose.cpp", | ||
"../../test/gtest/graphapi_conv_bias_res_add_activ_fwd.cpp", | ||
"../../test/gtest/unary_tensor_ops.cpp", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it excluded? It's not an UNINSTANTIATED_PARAMETERIZED_TEST
- it is perfectly instantiated.
I guess the problem is in the parsing, since you have to run preprocessor prior to get proper code, but preproceesor will eliminate all INSTANTIATE_TEST_SUITE_P
macros.
I would suggest keeping "hard to parse" cases separated from "UNINSTANTIATED_PARAMETERIZED_TEST" cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests have formatting names that aren't to standard for gtest folder - some are in the macro section, there are regexes like ##SRC_TYPE## in the tests name:
We can either accommodate them or modify them with the standard in different PR:
ERROR: The following issues were found:
ERROR: ../../test/gtest/graphapi_operation_rng.cpp: INSTANTIATE_TEST_SUITE_P references non-existent TESTSUITE_NAME 'GraphApiOperationRng'.
ERROR: ../../test/gtest/graphapi_operation_rng.cpp: Invalid TEST_TYPE 'InvalidAtLeastSeeds' in INSTANTIATE_TEST_SUITE_P.
ERROR: ../../test/gtest/graphapi_conv_bias_res_add_activ_fwd.cpp: Invalid TESTSUITE_NAME 'GPU_ConvBiasResAddActivation_##dir##_##type' in TEST_P.
ERROR: ../../test/gtest/graphapi_conv_bias_res_add_activ_fwd.cpp: Test 'GPU_ConvBiasResAddActivation_##dir##_##type.Test' does not have a matching INSTANTIATE_TEST_SUITE_P or GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST.
ERROR: ../../test/gtest/binary_tensor_ops.cpp: Invalid TESTSUITE_NAME 'GPU_binaryTensorOps_cast_##SRC_TYPE##_##TEST_TYPE' in TEST_P.
ERROR: ../../test/gtest/binary_tensor_ops.cpp: Test 'GPU_binaryTensorOps_cast_##SRC_TYPE##_##TEST_TYPE.\
X_CONCAT_FIRST_SECOND_(__VA_ARGS__, TestTensorCast' does not have a matching INSTANTIATE_TEST_SUITE_P or GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST.
ERROR: ../../test/gtest/binary_tensor_ops.cpp: Invalid TESTSUITE_NAME 'GPU_binaryTensorOps_copy_##TEST_TYPE' in TEST_P.
ERROR: ../../test/gtest/binary_tensor_ops.cpp: Test 'GPU_binaryTensorOps_copy_##TEST_TYPE.TestTensorCopy' does not have a matching INSTANTIATE_TEST_SUITE_P or GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST.
ERROR: ../../test/gtest/unary_tensor_ops.cpp: Invalid TESTSUITE_NAME 'GPU_unaryTensorOps_##TEST_TYPE' in TEST_P.
ERROR: ../../test/gtest/unary_tensor_ops.cpp: Test 'GPU_unaryTensorOps_##TEST_TYPE.TestTensorSet' does not have a matching INSTANTIATE_TEST_SUITE_P or GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST.
ERROR: ../../test/gtest/layout_transpose.cpp: Invalid TESTSUITE_NAME 'GPU_LayoutTransposeTest_2D_##sol##_##naming_type' in TEST_P.
ERROR: ../../test/gtest/layout_transpose.cpp: Test 'GPU_LayoutTransposeTest_2D_##sol##_##naming_type.\
LayoutTransposeTest_2D_##sol##_##type##_P' does not have a matching INSTANTIATE_TEST_SUITE_P or GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST.
ERROR: ../../test/gtest/layout_transpose.cpp: Invalid TESTSUITE_NAME 'GPU_LayoutTransposeTest_3D_##sol##_##naming_type' in TEST_P.
ERROR: ../../test/gtest/layout_transpose.cpp: Test 'GPU_LayoutTransposeTest_3D_##sol##_##naming_type.\
LayoutTransposeTest_3D_##sol##_##type##_P' does not have a matching INSTANTIATE_TEST_SUITE_P or GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had some spare cycles so I addressed most of the tests that were being skipped: #3452
I thought I could bypass automatic CI by making a new branch and merging into yours. It didn't work--the CI launched anyway. Well, maybe it'll be useful. Feel free to merge my PR, or merge the branch directly and close it.
After having used the script though, I really wish it emitted line numbers. It would also be nice if it detected and ignored commented code. Is it reasonable to add those features into this PR? I'd also be satisfied with this, and adding those into the next version.
Yes, that a good point... I will add these features here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
word boundary checks
test/utils/gtest_formating_checks.py
Outdated
TESTSUITE_REGEX = re.compile( | ||
r"^(CPU|GPU)_[A-Za-z0-9]+(?:_[A-Za-z0-9]+)*_(" + "|".join(VALID_DATATYPES) + r")$" | ||
) | ||
TEST_P_REGEX = re.compile(r"TEST_P\(([^,]+),\s*([^)]+)\)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the word boundary check to these regexes--it should only be checking valid macro invocations.
TEST_P_REGEX = re.compile(r"\bTEST_P\(([^,]+),\s*([^)]+)\)")
INSTANTIATE_TEST_REGEX = re.compile(r"\bINSTANTIATE_TEST_SUITE_P\(\s*([^\n,]+),\s*([^\n,]+),")
ALLOW_UNINSTANTIATED_REGEX = re.compile(r"\bGTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST\(\s*([^\)]+)\)")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- line numbers are off
- duplicate TEST_P issue
- missing comma issue
instantiate_matches = [(m.start(), m.groups()) for m in INSTANTIATE_TEST_REGEX.finditer(content)] | ||
allow_uninstantiated_matches = [(m.start(), m.group(1)) for m in ALLOW_UNINSTANTIATED_REGEX.finditer(content)] | ||
|
||
# Map line numbers to errors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line numbers, nice! They aren't quite right though. In all the instances I've seen, they are too small by 1. I also injected an error on line 1 and it printed as line 0, which suggests a counting or indexing issue.
The image also shows another problem I found--if a line is an exact copy of a previous line, one of them is ignored. In this example, line 86 was copied and pasted at line 91 and line 86 was missed. I've also seen cases when 91 was the missing one. You'll probably need to do something along the lines of generating a hash and use that for the key for each line instead of the text itself.
If a comma is missed, the regex consumes everything until the next comma is hit--including CR's. See the error prints for line 88 (printed as line 87). This needs to be fixed in this PR.
This also demonstrates other checks we should add in the future:
- TEST: matches our name formatting rules only
- TEST_F: matches name format and has a matching TestFixtureName
- When a duplicate TEST_P occurs, it should be detected and an error thrown.
- Multiple INSTANTIATE_TEST_SUITE_P are allowed for a given TestFixtureName. The INSTANTIATION_NAME (first macro argument) must be unique. Check for this.
- Multiple TEST_F are allowed per TestFixtureName. The TestName must be unique. Check for this.
Checks for formatting rules in link upon push or changes in gtest directory.