aboutsummaryrefslogtreecommitdiff
path: root/llvm_tools
diff options
context:
space:
mode:
authorSalud Lemus <saludlemus@google.com>2019-07-02 15:49:21 -0700
committerSalud Lemus <saludlemus@google.com>2019-07-08 21:02:23 +0000
commit7727c9fe68894c37ab14467f4d79cfc0934227ef (patch)
tree447f3c880b6b9e5c0e6058df16ca98412a3bf9bf /llvm_tools
parent6befccfc2baa5042a9a2438b2012df2fa7f788b8 (diff)
downloadtoolchain-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-xllvm_tools/get_llvm_hash.py8
-rwxr-xr-xllvm_tools/get_llvm_hash_unittest.py361
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()