1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project 2*7594170eSAndroid Build Coastguard Worker# 3*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*7594170eSAndroid Build Coastguard Worker# 7*7594170eSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*7594170eSAndroid Build Coastguard Worker# 9*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*7594170eSAndroid Build Coastguard Worker# limitations under the License. 14*7594170eSAndroid Build Coastguard Worker 15*7594170eSAndroid Build Coastguard Worker"""Unit tests for difftool.py.""" 16*7594170eSAndroid Build Coastguard Worker 17*7594170eSAndroid Build Coastguard Workerimport os 18*7594170eSAndroid Build Coastguard Workerimport pathlib 19*7594170eSAndroid Build Coastguard Workerimport unittest 20*7594170eSAndroid Build Coastguard Workerimport clangcompile 21*7594170eSAndroid Build Coastguard Workerimport difftool 22*7594170eSAndroid Build Coastguard Worker 23*7594170eSAndroid Build Coastguard Worker 24*7594170eSAndroid Build Coastguard Workerdef get_path(name): 25*7594170eSAndroid Build Coastguard Worker return os.path.join(os.getenv("TEST_TMPDIR"), name) 26*7594170eSAndroid Build Coastguard Worker 27*7594170eSAndroid Build Coastguard Worker 28*7594170eSAndroid Build Coastguard Workerdef create_file(name, content): 29*7594170eSAndroid Build Coastguard Worker path = get_path(name) 30*7594170eSAndroid Build Coastguard Worker with open(path, "w") as f: 31*7594170eSAndroid Build Coastguard Worker f.write(content) 32*7594170eSAndroid Build Coastguard Worker return pathlib.Path(path) 33*7594170eSAndroid Build Coastguard Worker 34*7594170eSAndroid Build Coastguard Worker 35*7594170eSAndroid Build Coastguard Workerdef _substring_in_list(s, slist): 36*7594170eSAndroid Build Coastguard Worker for elem in slist: 37*7594170eSAndroid Build Coastguard Worker if s in elem: 38*7594170eSAndroid Build Coastguard Worker return True 39*7594170eSAndroid Build Coastguard Worker return False 40*7594170eSAndroid Build Coastguard Worker 41*7594170eSAndroid Build Coastguard Worker 42*7594170eSAndroid Build Coastguard Workerclass DifftoolTest(unittest.TestCase): 43*7594170eSAndroid Build Coastguard Worker 44*7594170eSAndroid Build Coastguard Worker def assertNotInErrors(self, expected, errorlist): 45*7594170eSAndroid Build Coastguard Worker if _substring_in_list(expected, errorlist): 46*7594170eSAndroid Build Coastguard Worker self.fail("{!r} found in errors: {!r}".format(expected, errorlist)) 47*7594170eSAndroid Build Coastguard Worker 48*7594170eSAndroid Build Coastguard Worker def assertInErrors(self, expected, errorlist): 49*7594170eSAndroid Build Coastguard Worker if not _substring_in_list(expected, errorlist): 50*7594170eSAndroid Build Coastguard Worker self.fail("{!r} not found in errors: {!r}".format(expected, errorlist)) 51*7594170eSAndroid Build Coastguard Worker 52*7594170eSAndroid Build Coastguard Worker def test_file_differences_not_exist(self): 53*7594170eSAndroid Build Coastguard Worker obj_file = create_file("foo.o", "object contents") 54*7594170eSAndroid Build Coastguard Worker 55*7594170eSAndroid Build Coastguard Worker diffs = difftool.file_differences(pathlib.Path("doesntexist.o"), 56*7594170eSAndroid Build Coastguard Worker obj_file) 57*7594170eSAndroid Build Coastguard Worker self.assertEqual(["doesntexist.o does not exist"], diffs) 58*7594170eSAndroid Build Coastguard Worker 59*7594170eSAndroid Build Coastguard Worker @unittest.skip("TODO(usta)") 60*7594170eSAndroid Build Coastguard Worker def test_file_differences_different_types(self): 61*7594170eSAndroid Build Coastguard Worker obj_file = create_file("foo.o", "object contents") 62*7594170eSAndroid Build Coastguard Worker obj_file_two = create_file("foo2.o", "object contents two") 63*7594170eSAndroid Build Coastguard Worker txt_file = create_file("foo3.txt", "other") 64*7594170eSAndroid Build Coastguard Worker so_file = create_file("bar.so", "shared lib contents") 65*7594170eSAndroid Build Coastguard Worker 66*7594170eSAndroid Build Coastguard Worker diffs = difftool.file_differences(obj_file, so_file) 67*7594170eSAndroid Build Coastguard Worker self.assertInErrors("file types differ", diffs) 68*7594170eSAndroid Build Coastguard Worker 69*7594170eSAndroid Build Coastguard Worker diffs = difftool.file_differences(obj_file, txt_file) 70*7594170eSAndroid Build Coastguard Worker self.assertInErrors("file types differ", diffs) 71*7594170eSAndroid Build Coastguard Worker 72*7594170eSAndroid Build Coastguard Worker diffs = difftool.file_differences(so_file, obj_file) 73*7594170eSAndroid Build Coastguard Worker self.assertInErrors("file types differ", diffs) 74*7594170eSAndroid Build Coastguard Worker 75*7594170eSAndroid Build Coastguard Worker diffs = difftool.file_differences(obj_file, obj_file_two) 76*7594170eSAndroid Build Coastguard Worker self.assertNotInErrors("file types differ", diffs) 77*7594170eSAndroid Build Coastguard Worker 78*7594170eSAndroid Build Coastguard Worker @unittest.skip("TODO(usta)") 79*7594170eSAndroid Build Coastguard Worker def test_object_contents_differ(self): 80*7594170eSAndroid Build Coastguard Worker obj_file = create_file("foo.o", "object contents\none\n") 81*7594170eSAndroid Build Coastguard Worker obj_file_two = create_file("foo2.o", "object contents\ntwo\n") 82*7594170eSAndroid Build Coastguard Worker 83*7594170eSAndroid Build Coastguard Worker diffs = difftool.file_differences(obj_file, obj_file_two) 84*7594170eSAndroid Build Coastguard Worker self.assertNotInErrors("object_contents", diffs) 85*7594170eSAndroid Build Coastguard Worker self.assertInErrors("one", diffs) 86*7594170eSAndroid Build Coastguard Worker self.assertInErrors("two", diffs) 87*7594170eSAndroid Build Coastguard Worker 88*7594170eSAndroid Build Coastguard Worker def test_soong_clang_compile_info(self): 89*7594170eSAndroid Build Coastguard Worker fake_cmd = ("PWD=/proc/self/cwd prebuilts/clang -c -Wall -Wno-unused " + 90*7594170eSAndroid Build Coastguard Worker "foo.cpp -Iframeworks/av/include -Dsomedefine " + 91*7594170eSAndroid Build Coastguard Worker "-misc_flag misc_arg " + 92*7594170eSAndroid Build Coastguard Worker "-o foo.o # comment") 93*7594170eSAndroid Build Coastguard Worker info = difftool.rich_command_info(fake_cmd) 94*7594170eSAndroid Build Coastguard Worker self.assertIsInstance(info, clangcompile.ClangCompileInfo) 95*7594170eSAndroid Build Coastguard Worker self.assertEqual([("I", "frameworks/av/include")], info.i_includes) 96*7594170eSAndroid Build Coastguard Worker self.assertEqual(["-Dsomedefine"], info.defines) 97*7594170eSAndroid Build Coastguard Worker self.assertEqual(["-Wall", "-Wno-unused"], info.warnings) 98*7594170eSAndroid Build Coastguard Worker self.assertEqual(["-c", ("misc_flag", "misc_arg")], info.misc_flags) 99*7594170eSAndroid Build Coastguard Worker self.assertEqual(["foo.cpp", ("o", "foo.o")], info.file_flags) 100*7594170eSAndroid Build Coastguard Worker 101*7594170eSAndroid Build Coastguard Worker def test_bazel_clang_compile_info(self): 102*7594170eSAndroid Build Coastguard Worker fake_cmd = ("cd out/bazel/execroot && rm -f foo.o && " + 103*7594170eSAndroid Build Coastguard Worker "prebuilts/clang -MD -MF bazel-out/foo.d " + 104*7594170eSAndroid Build Coastguard Worker "-iquote . -iquote bazel-out/foo/bin " + 105*7594170eSAndroid Build Coastguard Worker "-I frameworks/av/include " + 106*7594170eSAndroid Build Coastguard Worker "-I bazel-out/frameworks/av/include/bin " + 107*7594170eSAndroid Build Coastguard Worker " -Dsomedefine " + 108*7594170eSAndroid Build Coastguard Worker "-misc_flag misc_arg " + 109*7594170eSAndroid Build Coastguard Worker "-Werror=int-conversion " + 110*7594170eSAndroid Build Coastguard Worker "-Wno-reserved-id-macro " 111*7594170eSAndroid Build Coastguard Worker "-o foo.o # comment") 112*7594170eSAndroid Build Coastguard Worker info = difftool.rich_command_info(fake_cmd) 113*7594170eSAndroid Build Coastguard Worker self.assertIsInstance(info, clangcompile.ClangCompileInfo) 114*7594170eSAndroid Build Coastguard Worker self.assertEqual([("iquote", ".")], info.iquote_includes) 115*7594170eSAndroid Build Coastguard Worker self.assertEqual([("I", "frameworks/av/include")], info.i_includes) 116*7594170eSAndroid Build Coastguard Worker self.assertEqual(["-Dsomedefine"], info.defines) 117*7594170eSAndroid Build Coastguard Worker self.assertEqual(["-Werror=int-conversion", "-Wno-reserved-id-macro"], 118*7594170eSAndroid Build Coastguard Worker info.warnings) 119*7594170eSAndroid Build Coastguard Worker self.assertEqual(["-MD", ("misc_flag", "misc_arg")], info.misc_flags) 120*7594170eSAndroid Build Coastguard Worker self.assertEqual([("MF", "bazel-out/foo.d"), ("o", "foo.o")], info.file_flags) 121*7594170eSAndroid Build Coastguard Worker 122*7594170eSAndroid Build Coastguard Worker 123*7594170eSAndroid Build Coastguard Workerif __name__ == "__main__": 124*7594170eSAndroid Build Coastguard Worker unittest.main() 125