Add CRC validator (#5857)
* Adds crc validation checks Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Fixes invalid CRCs Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Changes test to smoke suite Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * excludes some test data from the validator Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * uses pathlib instead of os.path Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * fixes wrong path to test scripts Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Escape not needed Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
@@ -181,4 +181,6 @@ EXCLUDED_VALIDATION_PATTERNS = [
|
||||
'restricted/*/Tools/*RemoteControl',
|
||||
'*/user/Cache/*',
|
||||
'*/user/log/*',
|
||||
'*/user/log_test_1/*',
|
||||
'*/user/log_test_2/*',
|
||||
]
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
|
||||
import unittest
|
||||
from unittest.mock import patch, mock_open
|
||||
|
||||
from commit_validation.tests.mocks.mock_commit import MockCommit
|
||||
from commit_validation.validators.crc_validator import CrcValidator
|
||||
|
||||
|
||||
class CrcValidatorTests(unittest.TestCase):
|
||||
|
||||
@patch('builtins.open', mock_open(read_data='This file does not contain an AZ_CRC macro'))
|
||||
def test_fileWithNoCrc_passes(self):
|
||||
commit = MockCommit(files=['/someCppFile.cpp'])
|
||||
error_list = []
|
||||
self.assertTrue(CrcValidator().run(commit, error_list))
|
||||
self.assertEqual(len(error_list), 0, f"Unexpected errors: {error_list}")
|
||||
|
||||
@patch('builtins.open', mock_open(read_data='This file contains an invalid CRC macro AZ_CRC("My string", 0xabcdef00)'))
|
||||
def test_fileWithInvalidCrc_fails(self):
|
||||
commit = MockCommit(files=['/someCppFile.cpp'])
|
||||
error_list = []
|
||||
self.assertFalse(CrcValidator().run(commit, error_list))
|
||||
self.assertNotEqual(len(error_list), 0, f"Errors were expected but none were returned.")
|
||||
|
||||
@patch('builtins.open', mock_open(read_data='This file contains a valid CRC macro AZ_CRC("My string", 0x18fbd270)'))
|
||||
def test_fileWithValidCrc_fails(self):
|
||||
commit = MockCommit(files=['/someCppFile.cpp'])
|
||||
error_list = []
|
||||
self.assertTrue(CrcValidator().run(commit, error_list))
|
||||
self.assertEqual(len(error_list), 0, f"Unexpected errors: {error_list}")
|
||||
|
||||
@patch('builtins.open', mock_open(read_data='This file contains an invalid CRC macro AZ_CRC("My string", 0xabcdef00)'))
|
||||
def test_fileExtensionIgnored_passes(self):
|
||||
commit = MockCommit(files=['/someCppFile.somerandomextension'])
|
||||
error_list = []
|
||||
self.assertTrue(CrcValidator().run(commit, error_list))
|
||||
self.assertEqual(len(error_list), 0, f"Unexpected errors: {error_list}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,48 @@
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
|
||||
import binascii
|
||||
import fnmatch
|
||||
import pathlib
|
||||
import re
|
||||
from typing import Type, List
|
||||
|
||||
from commit_validation.commit_validation import Commit, CommitValidator, SOURCE_FILE_EXTENSIONS, EXCLUDED_VALIDATION_PATTERNS, VERBOSE
|
||||
|
||||
class CrcValidator(CommitValidator):
|
||||
"""A file-level validator that makes sure a file does not contain an invalid CRC"""
|
||||
|
||||
def run(self, commit: Commit, errors: List[str]) -> bool:
|
||||
for file_name in commit.get_files():
|
||||
for pattern in EXCLUDED_VALIDATION_PATTERNS:
|
||||
if fnmatch.fnmatch(file_name, pattern):
|
||||
if VERBOSE: print(f'{file_name}::{self.__class__.__name__} SKIPPED - Validation pattern excluded on path.')
|
||||
break
|
||||
else:
|
||||
if pathlib.Path(file_name).suffix.lower() not in SOURCE_FILE_EXTENSIONS:
|
||||
if VERBOSE: print(f'{file_name}::{self.__class__.__name__} SKIPPED - File excluded based on extension.')
|
||||
continue
|
||||
|
||||
with open(file_name, mode='r', encoding='utf8') as fh:
|
||||
fileContents = fh.read()
|
||||
matchesFound = re.findall(r'AZ_CRC\("([^"]+)",([^)]*)\)', fileContents)
|
||||
for element in matchesFound:
|
||||
stringInCode = element[0]
|
||||
valueInCode = element[1].strip()
|
||||
expectedValue = "{0:#0{1}x}".format(binascii.crc32(stringInCode.lower().encode('utf8')), 10)
|
||||
if expectedValue != valueInCode:
|
||||
error_message = str(f'{file_name}::{self.__class__.__name__} FAILED - Source file contains a CRC mismatch!\n'
|
||||
f' AZ_CRC("{stringInCode}", {valueInCode}), expected value {expectedValue}')
|
||||
if VERBOSE: print(error_message)
|
||||
errors.append(error_message)
|
||||
return (not errors)
|
||||
|
||||
|
||||
def get_validator() -> Type[CrcValidator]:
|
||||
"""Returns the validator class for this module"""
|
||||
return CrcValidator
|
||||
Reference in New Issue
Block a user