diff options
author | Salud Lemus <saludlemus@google.com> | 2019-07-02 15:49:21 -0700 |
---|---|---|
committer | Salud Lemus <saludlemus@google.com> | 2019-07-08 21:02:23 +0000 |
commit | 7727c9fe68894c37ab14467f4d79cfc0934227ef (patch) | |
tree | 447f3c880b6b9e5c0e6058df16ca98412a3bf9bf /llvm_tools | |
parent | 6befccfc2baa5042a9a2438b2012df2fa7f788b8 (diff) | |
download | toolchain-utils-7727c9fe68894c37ab14467f4d79cfc0934227ef.tar.gz |
LLVM tools: Unittests for get_llvm_hash.py
BUG=None
TEST='./get_llvm_hash_unittest.py' passes
Change-Id: I421e58dda744c6df6ae37a2fbc6559b98bcab2a8
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/1687777
Reviewed-by: George Burgess <gbiv@chromium.org>
Reviewed-by: Manoj Gupta <manojgupta@chromium.org>
Tested-by: Salud Lemus <saludlemus@google.com>
Diffstat (limited to 'llvm_tools')
-rwxr-xr-x | llvm_tools/get_llvm_hash.py | 8 | ||||
-rwxr-xr-x | llvm_tools/get_llvm_hash_unittest.py | 361 |
2 files changed, 365 insertions, 4 deletions
diff --git a/llvm_tools/get_llvm_hash.py b/llvm_tools/get_llvm_hash.py index 98b7b749..07ea2009 100755 --- a/llvm_tools/get_llvm_hash.py +++ b/llvm_tools/get_llvm_hash.py @@ -45,7 +45,7 @@ class LLVMHash(object): ret, _, err = self._ce.RunCommandWOutput(clone_cmd, print_to_console=False) if ret: # failed to create repo - raise Exception('Failed to clone the llvm repo: %s' % err) + raise ValueError('Failed to clone the llvm repo: %s' % err) def _ParseCommitMessages(self, subdir, hash_vals, llvm_version): """Parses the hashes that match the llvm version. @@ -80,7 +80,7 @@ class LLVMHash(object): find_llvm_cmd, print_to_console=False) if ret: # failed to parse the commit message - raise Exception('Failed to parse commit message: %s' % err) + raise ValueError('Failed to parse commit message: %s' % err) # find all "llvm-svn:" instances llvm_versions = llvm_svn_pattern.findall(out) @@ -90,7 +90,7 @@ class LLVMHash(object): return cur_hash # failed to find the commit hash - raise Exception('Could not find commit hash.') + raise ValueError('Could not find commit hash.') def GetGitHashForVersion(self, llvm_git_dir, llvm_version): """Finds the commit hash(es) of the llvm version in the git log history. @@ -116,7 +116,7 @@ class LLVMHash(object): hash_cmd, print_to_console=False) if ret: # failed to find hash - raise Exception('Hash not found: %s' % err) + raise ValueError('Hash not found: %s' % err) return self._ParseCommitMessages(subdir, hash_vals, llvm_version) diff --git a/llvm_tools/get_llvm_hash_unittest.py b/llvm_tools/get_llvm_hash_unittest.py new file mode 100755 index 00000000..97dd1278 --- /dev/null +++ b/llvm_tools/get_llvm_hash_unittest.py @@ -0,0 +1,361 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- +# Copyright 2019 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Unit tests for retrieving the LLVM hash.""" + +from __future__ import print_function + +import mock +import tempfile +import unittest + +from cros_utils import command_executer +from get_google3_llvm_version import LLVMVersion +from get_llvm_hash import LLVMHash + + +class TestGetLLVMHash(unittest.TestCase): + """The LLVMHash test class.""" + + @mock.patch.object(command_executer.CommandExecuter, 'RunCommandWOutput') + def testCloneRepoSucceeds(self, mock_run_commmand_output): + # Test function to emulate RunCommandWOutput behavior in succeeds case. + def GoodCloneRepo(clone_cmd, print_to_console): + # Expected argument to RunCommandWOutput. + self.assertEqual(clone_cmd.split()[-1], '/tmp/tmpTest') + + # Returns shell error code, stdout, stderr. + return 0, None, 0 + + # Use the test function to simulate RunCommandWOutput behavior. + mock_run_commmand_output.side_effect = GoodCloneRepo + + TestLLVMHash = LLVMHash() + + # Test the call to _CloneLLVMRepo function. + TestLLVMHash._CloneLLVMRepo('/tmp/tmpTest') + + mock_run_commmand_output.assert_called_once() + + @mock.patch.object(command_executer.CommandExecuter, 'RunCommandWOutput') + def testCloneRepoFails(self, mock_run_command_output): + # Test function to simulate RunCommandWOutput behavior in a failed case. + def BadCloneRepo(clone_cmd, print_to_console): + # Make sure an invalid argument is passed in. + self.assertNotEqual(clone_cmd.split()[-1], '/tmp/tmpTest') + + # Returns shell error code, stdout, stderr. + return 1, None, 'Invalid path provided' + + # Use the test function to simulate RunCommandWOutput behavior. + mock_run_command_output.side_effect = BadCloneRepo + + TestLLVMHash = LLVMHash() + + # Verify the exception is raised when cloning the repo fails. + with self.assertRaises(ValueError) as err: + TestLLVMHash._CloneLLVMRepo('/tmp/tmp1') + + self.assertEqual(err.exception.message, 'Failed to clone the llvm repo: ' \ + 'Invalid path provided') + + mock_run_command_output.assert_called_once() + + @mock.patch.object(tempfile, 'mkdtemp') + def testCreateTempDirectory(self, mock_create_temp_dir): + # Test function to simulate mkdtemp behavior. + def FakeMakeDir(): + # Returns a directory in '/tmp/'. + return '/tmp/tmpTest' + + # Use the test function to simulate mkdtemp behavior. + mock_create_temp_dir.side_effect = FakeMakeDir + + TestLLVMHash = LLVMHash() + + self.assertEqual(TestLLVMHash._CreateTempDirectory(), '/tmp/tmpTest') + + mock_create_temp_dir.assert_called_once() + + @mock.patch.object(command_executer.CommandExecuter, 'RunCommandWOutput') + def testFailToParseCommitMessage(self, mock_commit_message): + # Test function to simulate RunCommandWOutput behavior. + def FakeCommitMessageOutput(find_llvm_cmd, print_to_console): + # Returns shell error code, stdout, stderr. + return 1, None, 'Unable to find the llvm version' + + # Use the test function to simulate RunCommandWOutput behavior. + mock_commit_message.side_effect = FakeCommitMessageOutput + + TestLLVMHash = LLVMHash() + + # Verify the exception is raised when failed to parse a commit message. + with self.assertRaises(ValueError) as err: + TestLLVMHash._ParseCommitMessages('/tmp/tmpTest', + 'a13testhash2 This is a test', 100) + + self.assertEqual(err.exception.message, 'Failed to parse commit message: ' \ + 'Unable to find the llvm version') + + mock_commit_message.assert_called_once() + + @mock.patch.object(command_executer.CommandExecuter, 'RunCommandWOutput') + def testUnableToFindCommitHash(self, mock_commit_message): + # Test function to simulate RunCommandWOutput when parsing a + # commit message body. + def CustomCommitMessage(find_llvm_cmd, print_to_console): + commit_message = ('[Test] Test sentence.\n\n' + 'A change was made.\n\n' + 'llvm-svn: 1000') + + # Returns shell error code, stdout, stderr. + return 0, commit_message, 0 + + # Use test function to simulate RunCommandWOutput behavior. + mock_commit_message.side_effect = CustomCommitMessage + + TestLLVMHash = LLVMHash() + + # Verify the exception is raised when failed to find the commit hash. + with self.assertRaises(ValueError) as err: + TestLLVMHash._ParseCommitMessages('/tmp/tmpTest', + 'a13testhash2 This is a test', 100) + + self.assertEqual(err.exception.message, 'Could not find commit hash.') + + mock_commit_message.assert_called_once() + + @mock.patch.object(command_executer.CommandExecuter, 'RunCommandWOutput') + def testFindCommitHashSuccessfully(self, mock_commit_message): + # Test function will be called 3 times, so + # 'loop_counter' determines which commit message to return + loop_counter = [0] + + # Test function to simulate RunCommandWOutput when + # returning a commit message. + def MultipleCommitMessages(find_llvm_cmd, print_to_console): + if loop_counter[0] == 0: # first iteration + commit_message_1 = ('[Test] Test sentence.\n\n' + 'A change was made.\n\n' + 'llvm-svn: 1001') + + loop_counter[0] += 1 + + # Returns shell error code, stdout, stderr. + return 0, commit_message_1, 0 + if loop_counter[0] == 1: # second iteration + # nested commit message containing two 'llvm-svn' + commit_message_2 = ('[Revert] Reverted commit.\n\n' + 'This reverts r1000:\n\n' + ' [Test2] Update.\n\n' + ' This updates stuff.\n\n' + ' llvm-svn: 1000\n\n' + 'llvm-svn: 58') + + loop_counter[0] += 1 + + # Returns shell error code, stdout, stderr. + return 0, commit_message_2, 0 + if loop_counter[0] == 2: # third iteration + # nested commit message containing two 'llvm-svn' + commit_message_3 = ('[Revert] Reverted commit.\n\n' + 'This reverts r958:\n\n' + ' [Test2] Update.\n\n' + ' This updates stuff.\n\n' + ' llvm-svn: 958\n\n' + 'llvm-svn: 1000') + + # Returns shell error code, stdout, stderr. + return 0, commit_message_3, 0 + + # Testing function was called more times than expected (3 times) + assert False, 'RunCommandWOutput was called more than 3 times.' + + # Use test function to simulate RunCommandWOutput behavior. + mock_commit_message.side_effect = MultipleCommitMessages + + TestLLVMHash = LLVMHash() + + # Test hashes used for parsing. + # + # Format: + # [Hash] [Commit Summary] + hash_vals = ('a13testhash2 [Test] Test sentence.\n' + 'a13testhash3 [Revert] Reverted commit.\n' + 'a13testhash4 [Revert] Reverted commit.') + + self.assertEqual( + TestLLVMHash._ParseCommitMessages('/tmp/tmpTest', hash_vals, 1000), + 'a13testhash4') + + self.assertEqual(mock_commit_message.call_count, 3) + + @mock.patch.object(command_executer.CommandExecuter, 'RunCommandWOutput') + def testUnableToGetGitHash(self, mock_hash_val_output): + # Test function to simulate RunCommandWOuput when unable to + # find the 'llvm-svn' passed in. + def FailedHashValOutput(hash_cmd, print_to_console): + # Returns shell error code, stdout, stderr. + return 1, None, 'Failed to find specific llvm-svn' + + # Use test function to simulate RunCommandWOutput behavior. + mock_hash_val_output.side_effect = FailedHashValOutput + + TestLLVMHash = LLVMHash() + + # Verify the exception is raised when unable to get the hash for the llvm + # version. + with self.assertRaises(ValueError) as err: + TestLLVMHash.GetGitHashForVersion('/tmp/tmpTest', 100) + + self.assertEqual(err.exception.message, + 'Hash not found: Failed to find specific llvm-svn') + + mock_hash_val_output.assert_called_once() + + @mock.patch.object(command_executer.CommandExecuter, 'RunCommandWOutput') + @mock.patch.object(LLVMHash, '_ParseCommitMessages') + def testGetGitHashSuccess(self, mock_return_hash_val, mock_hash_val_output): + # Test function to simulate RunCommandWOutput when parsing the git log + # history. + # + # Format: + # [Hash] [Commit Summary] + def CustomHashValsOutput(hash_cmd, print_to_console): + hash_val = 'a13testhash2 [Test] Test sentence.' + + # Returns shell error code, stdout, stderr. + return 0, hash_val, 0 + + # Test function to simulate _ParseCommitMessages when a commit hash is + # returned. + def CustomReturnHash(subdir, hash_vals, llvm_version): + return 'a13testhash2' + + # Use test functions to simulate behavior. + mock_hash_val_output.side_effect = CustomHashValsOutput + mock_return_hash_val.side_effect = CustomReturnHash + + TestLLVMHash = LLVMHash() + + self.assertEqual( + TestLLVMHash.GetGitHashForVersion('/tmp/tmpTest', 100), 'a13testhash2') + + mock_return_hash_val.assert_called_once_with( + '/tmp/tmpTest/llvm', 'a13testhash2 [Test] Test sentence.', 100) + mock_hash_val_output.assert_called_once() + + @mock.patch.object(LLVMHash, '_CloneLLVMRepo') + @mock.patch.object(LLVMHash, '_DeleteTempDirectory') + @mock.patch.object(LLVMHash, '_CreateTempDirectory') + def testExceptionWhenGetLLVMHash(self, mock_create_temp_dir, + mock_del_temp_dir, mock_clone_repo): + + # Test function to simulate _CloneLLVMRepo when exception is thrown. + def FailedCloneRepo(llvm_git_dir): + raise ValueError('Failed to clone LLVM repo.') + + # Test function to simulate _DeleteTempDirectory when successfully + # deleted the temp directory. + def DeletedTempDirectory(llvm_git_dir): + return True + + # Test function to simulate _CreateTempDirectory when temp directory + # is returned. + def CreatedTempDirectory(): + return '/tmp/tmpTest' + + # Use test functions to simulate the behavior. + mock_clone_repo.side_effect = FailedCloneRepo + mock_del_temp_dir.side_effect = DeletedTempDirectory + mock_create_temp_dir.side_effect = CreatedTempDirectory + + TestLLVMHash = LLVMHash() + + # Verify the exception is raised when an exception is thrown + # within the 'try' block + # + # Cloning the repo will raise the exception. + with self.assertRaises(ValueError) as err: + TestLLVMHash.GetLLVMHash(100) + + self.assertEqual(err.exception.message, 'Failed to clone LLVM repo.') + + mock_del_temp_dir.assert_called_once_with('/tmp/tmpTest') + mock_clone_repo.assert_called_once() + mock_create_temp_dir.assert_called_once() + + @mock.patch.object(LLVMHash, '_CloneLLVMRepo') + @mock.patch.object(LLVMHash, '_DeleteTempDirectory') + @mock.patch.object(LLVMHash, '_CreateTempDirectory') + @mock.patch.object(LLVMHash, 'GetGitHashForVersion') + def testReturnWhenGetLLVMHash(self, mock_get_git_hash, mock_create_temp_dir, + mock_del_temp_dir, mock_clone_repo): + + # Test function to simulate _CloneLLVMRepo when successfully cloned the + # repo. + def ClonedRepo(llvm_git_dir): + return True + + # Test function to simulate _DeleteTempDirectory when successfully + # deleted the temp directory. + def DeletedTempDirectory(llvm_git_dir): + return True + + # Test function to simulate _CreateTempDirectory when successfully + # created the temp directory. + def CreatedTempDirectory(): + return '/tmp/tmpTest' + + # Test function to simulate GetGitHashForVersion when a hash is returned + # of its llvm version. + def ReturnGitHashForVersion(llvm_git_dir, llvm_version): + return 'a13testhash2' + + # Use test functions to simulate behavior. + mock_clone_repo.side_effect = ClonedRepo + mock_del_temp_dir.side_effect = DeletedTempDirectory + mock_create_temp_dir.side_effect = CreatedTempDirectory + mock_get_git_hash.side_effect = ReturnGitHashForVersion + + TestLLVMHash = LLVMHash() + + self.assertEqual(TestLLVMHash.GetLLVMHash(100), 'a13testhash2') + + mock_create_temp_dir.assert_called_once() + mock_clone_repo.assert_called_once_with('/tmp/tmpTest') + mock_get_git_hash.assert_called_once_with('/tmp/tmpTest', 100) + mock_del_temp_dir.assert_called_once() + + @mock.patch.object(LLVMHash, 'GetLLVMHash') + @mock.patch.object(LLVMVersion, 'GetGoogle3LLVMVersion') + def testReturnGoogle3LLVMHash(self, mock_google3_llvm_version, + mock_get_llvm_hash): + + # Test function to simulate GetLLVMHash that returns + # the hash of the google3 llvm version. + def ReturnGoogle3LLVMHash(google3_llvm_version): + return 'a13testhash3' + + # Test function to simulate GetGoogle3LLVMVersion that returns + # the google3 llvm version. + def ReturnGoogle3LLVMVersion(): + return 1000 + + # Use test functions to simulate behavior. + mock_get_llvm_hash.side_effect = ReturnGoogle3LLVMHash + mock_google3_llvm_version.side_effect = ReturnGoogle3LLVMVersion + + TestLLVMHash = LLVMHash() + + self.assertEqual(TestLLVMHash.GetGoogle3LLVMHash(), 'a13testhash3') + + mock_get_llvm_hash.assert_called_once_with(1000) + mock_google3_llvm_version.assert_called_once() + + +if __name__ == '__main__': + unittest.main() |