1# Copyright (C) 2022 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") 16load("//build/bazel/rules/sysprop:sysprop_library.bzl", "sysprop_library") 17load("//build/bazel/rules/test_common:args.bzl", "get_arg_value") 18load( 19 "//build/bazel/rules/test_common:paths.bzl", 20 "get_output_and_package_dir_based_path", 21 "get_package_dir_based_path", 22) 23load(":cc_sysprop_library.bzl", "cc_gen_sysprop") 24 25def _provides_correct_outputs_test_impl(ctx): 26 env = analysistest.begin(ctx) 27 28 target_under_test = analysistest.target_under_test(env) 29 output_files = target_under_test[DefaultInfo].files.to_list() 30 actual_output_strings = [ 31 file.short_path 32 for file in output_files 33 ] 34 35 asserts.equals( 36 env, 37 6, 38 len(output_files), 39 "List of outputs incorrect length", 40 ) 41 for name in ["foo", "bar"]: 42 expected_cpp_path = get_package_dir_based_path( 43 env, 44 "sysprop/path/to/%s.sysprop.cpp" % (name), 45 ) 46 asserts.true( 47 env, 48 expected_cpp_path in actual_output_strings, 49 ("Generated cpp source file for %s.sysprop not present in " + 50 "output.\n" + 51 "Expected Value: %s\n" + 52 "Actual output: %s") % ( 53 name, 54 expected_cpp_path, 55 actual_output_strings, 56 ), 57 ) 58 expected_header_path = get_package_dir_based_path( 59 env, 60 "sysprop/include/path/to/%s.sysprop.h" % (name), 61 ) 62 asserts.true( 63 env, 64 expected_header_path in actual_output_strings, 65 ("Generated header source file for %s.sysprop not present in " + 66 "output.\n" + 67 "Expected Value: %s\n" + 68 "Actual output: %s") % ( 69 name, 70 expected_header_path, 71 actual_output_strings, 72 ), 73 ) 74 expected_public_header_path = get_package_dir_based_path( 75 env, 76 "sysprop/public/include/path/to/%s.sysprop.h" % (name), 77 ) 78 asserts.true( 79 env, 80 expected_public_header_path in actual_output_strings, 81 ("Generated public header source file for %s.sysprop not present " + 82 "in output.\n" + 83 "Expected Value: %s\n" + 84 "Actual output: %s") % ( 85 name, 86 expected_public_header_path, 87 actual_output_strings, 88 ), 89 ) 90 91 return analysistest.end(env) 92 93provides_correct_outputs_test = analysistest.make( 94 _provides_correct_outputs_test_impl, 95) 96 97# TODO(b/240466571): This test will be notably different after implementing 98# exported include and header selection 99def _provides_correct_ccinfo_test_impl(ctx): 100 env = analysistest.begin(ctx) 101 102 target_under_test = analysistest.target_under_test(env) 103 target_ccinfo = target_under_test[CcInfo] 104 actual_includes = target_ccinfo.compilation_context.includes.to_list() 105 actual_headers = target_ccinfo.compilation_context.headers.to_list() 106 expected_package_relative_include = get_package_dir_based_path( 107 env, 108 "sysprop/include", 109 ) 110 asserts.true( 111 env, 112 expected_package_relative_include in actual_includes, 113 ("Package relative include incorrect or not found in CcInfo.\n" + 114 "Expected value: %s\n" + 115 "Actual output: %s") % ( 116 expected_package_relative_include, 117 actual_includes, 118 ), 119 ) 120 expected_root_relative_include = get_output_and_package_dir_based_path( 121 env, 122 "sysprop/include", 123 ) 124 asserts.true( 125 env, 126 expected_root_relative_include in actual_includes, 127 ("Root relative include incorrect or not found in CcInfo.\n" + 128 "Expected value: %s\n" + 129 "Actual output: %s") % ( 130 expected_root_relative_include, 131 actual_includes, 132 ), 133 ) 134 asserts.true( 135 env, 136 len(actual_includes) == 2, 137 ("CcInfo includes should contain a package relative and a " + 138 "root-relative path and nothing else. Actual output: %s" % ( 139 actual_includes, 140 )), 141 ) 142 actual_header_strings = [ 143 header.path 144 for header in actual_headers 145 ] 146 for name in ["foo", "bar"]: 147 asserts.true( 148 env, 149 get_output_and_package_dir_based_path( 150 env, 151 "sysprop/include/path/to/%s.sysprop.h" % (name), 152 ) in actual_header_strings, 153 ("Generated header file for %s.sysprop not present in CcInfo " + 154 "headers. Actual output: %s") % (name, actual_header_strings), 155 ) 156 asserts.true( 157 env, 158 len(actual_headers) == 2, 159 ("List of generated headers in CcInfo was incorrect length. Should " + 160 "be exactly two. Actual output: %s" % actual_headers), 161 ) 162 163 return analysistest.end(env) 164 165provides_correct_ccinfo_test = analysistest.make( 166 _provides_correct_ccinfo_test_impl, 167) 168 169def _correct_args_test_impl(ctx): 170 env = analysistest.begin(ctx) 171 172 actions = analysistest.target_actions(env) 173 174 asserts.equals( 175 env, 176 2, 177 len(actions), 178 "Incorrect number of actions", 179 ) 180 names = ["foo", "bar"] 181 for i in range(2): 182 name = names[i] 183 actual_args = actions[i].argv 184 185 asserts.equals( 186 env, 187 get_output_and_package_dir_based_path(env, "sysprop/include/path/to"), 188 get_arg_value(actual_args, "--header-dir"), 189 "--header-dir argument incorrect or not found.\n", 190 ) 191 asserts.equals( 192 env, 193 get_output_and_package_dir_based_path(env, "sysprop/public/include/path/to"), 194 get_arg_value(actual_args, "--public-header-dir"), 195 "--public-header-dir argument incorrect or not found.\n", 196 ) 197 asserts.equals( 198 env, 199 get_output_and_package_dir_based_path(env, "sysprop/path/to"), 200 get_arg_value(actual_args, "--source-dir"), 201 "--source-dir argument incorrect or not found.\n", 202 ) 203 asserts.equals( 204 env, 205 "path/to/%s.sysprop.h" % name, 206 get_arg_value(actual_args, "--include-name"), 207 "--include-name argument incorrect or not found.\n", 208 ) 209 expected_input = get_package_dir_based_path( 210 env, 211 "path/to/%s.sysprop" % name, 212 ) 213 actual_cli_string = " ".join(actual_args) 214 asserts.true( 215 env, 216 expected_input in actual_cli_string, 217 ("Input argument not found.\n" + 218 "Expected Value: %s\n" + 219 "Command: %s") % (expected_input, actual_cli_string), 220 ) 221 222 return analysistest.end(env) 223 224correct_args_test = analysistest.make( 225 _correct_args_test_impl, 226) 227 228def _create_test_targets(name, rule_func): 229 wrapper_name = name + "_wrapper" 230 test_name = name + "_test" 231 sysprop_library( 232 name = wrapper_name, 233 srcs = [ 234 "path/to/foo.sysprop", 235 "path/to/bar.sysprop", 236 ], 237 tags = ["manual"], 238 ) 239 cc_gen_sysprop( 240 name = name, 241 dep = ":" + wrapper_name, 242 tags = ["manual"], 243 ) 244 rule_func( 245 name = test_name, 246 target_under_test = name, 247 ) 248 return test_name 249 250def cc_gen_sysprop_test_suite(name): 251 native.test_suite( 252 name = name, 253 tests = [ 254 _create_test_targets( 255 "provides_correct_outputs", 256 provides_correct_outputs_test, 257 ), 258 _create_test_targets( 259 "provides_correct_ccinfo", 260 provides_correct_ccinfo_test, 261 ), 262 _create_test_targets( 263 "correct_args_test", 264 correct_args_test, 265 ), 266 ], 267 ) 268