neverallow_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. // Copyright 2018 Google Inc. All rights reserved.
  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. package android
  15. import (
  16. "testing"
  17. "github.com/google/blueprint"
  18. )
  19. var neverallowTests = []struct {
  20. // The name of the test.
  21. name string
  22. // Optional test specific rules. If specified then they are used instead of the default rules.
  23. rules []Rule
  24. // Additional contents to add to the virtual filesystem used by the tests.
  25. fs map[string][]byte
  26. // The expected error patterns. If empty then no errors are expected, otherwise each error
  27. // reported must be matched by at least one of these patterns. A pattern matches if the error
  28. // message contains the pattern. A pattern does not have to match the whole error message.
  29. expectedErrors []string
  30. }{
  31. // Test General Functionality
  32. // in direct deps tests
  33. {
  34. name: "not_allowed_in_direct_deps",
  35. rules: []Rule{
  36. NeverAllow().InDirectDeps("not_allowed_in_direct_deps"),
  37. },
  38. fs: map[string][]byte{
  39. "top/Android.bp": []byte(`
  40. cc_library {
  41. name: "not_allowed_in_direct_deps",
  42. }`),
  43. "other/Android.bp": []byte(`
  44. cc_library {
  45. name: "libother",
  46. static_libs: ["not_allowed_in_direct_deps"],
  47. }`),
  48. },
  49. expectedErrors: []string{
  50. `module "libother": violates neverallow deps:not_allowed_in_direct_deps`,
  51. },
  52. },
  53. // Test android specific rules
  54. // include_dir rule tests
  55. {
  56. name: "include_dir not allowed to reference art",
  57. fs: map[string][]byte{
  58. "other/Android.bp": []byte(`
  59. cc_library {
  60. name: "libother",
  61. include_dirs: ["art/libdexfile/include"],
  62. }`),
  63. },
  64. expectedErrors: []string{
  65. "all usages of 'art' have been migrated",
  66. },
  67. },
  68. {
  69. name: "include_dir can reference another location",
  70. fs: map[string][]byte{
  71. "other/Android.bp": []byte(`
  72. cc_library {
  73. name: "libother",
  74. include_dirs: ["another/include"],
  75. }`),
  76. },
  77. },
  78. // Treble rule tests
  79. {
  80. name: "no vndk.enabled under vendor directory",
  81. fs: map[string][]byte{
  82. "vendor/Android.bp": []byte(`
  83. cc_library {
  84. name: "libvndk",
  85. vendor_available: true,
  86. vndk: {
  87. enabled: true,
  88. },
  89. }`),
  90. },
  91. expectedErrors: []string{
  92. "VNDK can never contain a library that is device dependent",
  93. },
  94. },
  95. {
  96. name: "no vndk.enabled under device directory",
  97. fs: map[string][]byte{
  98. "device/Android.bp": []byte(`
  99. cc_library {
  100. name: "libvndk",
  101. vendor_available: true,
  102. vndk: {
  103. enabled: true,
  104. },
  105. }`),
  106. },
  107. expectedErrors: []string{
  108. "VNDK can never contain a library that is device dependent",
  109. },
  110. },
  111. {
  112. name: "vndk-ext under vendor or device directory",
  113. fs: map[string][]byte{
  114. "device/Android.bp": []byte(`
  115. cc_library {
  116. name: "libvndk1_ext",
  117. vendor: true,
  118. vndk: {
  119. enabled: true,
  120. },
  121. }`),
  122. "vendor/Android.bp": []byte(`
  123. cc_library {
  124. name: "libvndk2_ext",
  125. vendor: true,
  126. vndk: {
  127. enabled: true,
  128. },
  129. }`),
  130. },
  131. },
  132. {
  133. name: "no enforce_vintf_manifest.cflags",
  134. fs: map[string][]byte{
  135. "Android.bp": []byte(`
  136. cc_library {
  137. name: "libexample",
  138. product_variables: {
  139. enforce_vintf_manifest: {
  140. cflags: ["-DSHOULD_NOT_EXIST"],
  141. },
  142. },
  143. }`),
  144. },
  145. expectedErrors: []string{
  146. "manifest enforcement should be independent",
  147. },
  148. },
  149. {
  150. name: "no treble_linker_namespaces.cflags",
  151. fs: map[string][]byte{
  152. "Android.bp": []byte(`
  153. cc_library {
  154. name: "libexample",
  155. product_variables: {
  156. treble_linker_namespaces: {
  157. cflags: ["-DSHOULD_NOT_EXIST"],
  158. },
  159. },
  160. }`),
  161. },
  162. expectedErrors: []string{
  163. "nothing should care if linker namespaces are enabled or not",
  164. },
  165. },
  166. {
  167. name: "libc_bionic_ndk treble_linker_namespaces.cflags",
  168. fs: map[string][]byte{
  169. "Android.bp": []byte(`
  170. cc_library {
  171. name: "libc_bionic_ndk",
  172. product_variables: {
  173. treble_linker_namespaces: {
  174. cflags: ["-DSHOULD_NOT_EXIST"],
  175. },
  176. },
  177. }`),
  178. },
  179. },
  180. {
  181. name: "dependency on updatable-media",
  182. fs: map[string][]byte{
  183. "Android.bp": []byte(`
  184. java_library {
  185. name: "needs_updatable_media",
  186. libs: ["updatable-media"],
  187. }`),
  188. },
  189. expectedErrors: []string{
  190. "updatable-media includes private APIs. Use updatable_media_stubs instead.",
  191. },
  192. },
  193. {
  194. name: "java_device_for_host",
  195. fs: map[string][]byte{
  196. "Android.bp": []byte(`
  197. java_device_for_host {
  198. name: "device_for_host",
  199. libs: ["core-libart"],
  200. }`),
  201. },
  202. expectedErrors: []string{
  203. "java_device_for_host can only be used in allowed projects",
  204. },
  205. },
  206. // Libcore rule tests
  207. {
  208. name: "sdk_version: \"none\" inside core libraries",
  209. fs: map[string][]byte{
  210. "libcore/Android.bp": []byte(`
  211. java_library {
  212. name: "inside_core_libraries",
  213. sdk_version: "none",
  214. }`),
  215. },
  216. },
  217. {
  218. name: "sdk_version: \"none\" on android_*stubs_current stub",
  219. fs: map[string][]byte{
  220. "frameworks/base/Android.bp": []byte(`
  221. java_library {
  222. name: "android_stubs_current",
  223. sdk_version: "none",
  224. }`),
  225. },
  226. },
  227. {
  228. name: "sdk_version: \"none\" outside core libraries",
  229. fs: map[string][]byte{
  230. "Android.bp": []byte(`
  231. java_library {
  232. name: "outside_core_libraries",
  233. sdk_version: "none",
  234. }`),
  235. },
  236. expectedErrors: []string{
  237. "module \"outside_core_libraries\": violates neverallow",
  238. },
  239. },
  240. {
  241. name: "sdk_version: \"current\"",
  242. fs: map[string][]byte{
  243. "Android.bp": []byte(`
  244. java_library {
  245. name: "outside_core_libraries",
  246. sdk_version: "current",
  247. }`),
  248. },
  249. },
  250. // CC sdk rule tests
  251. {
  252. name: `"sdk_variant_only" outside allowed list`,
  253. fs: map[string][]byte{
  254. "Android.bp": []byte(`
  255. cc_library {
  256. name: "outside_allowed_list",
  257. sdk_version: "current",
  258. sdk_variant_only: true,
  259. }`),
  260. },
  261. expectedErrors: []string{
  262. `module "outside_allowed_list": violates neverallow`,
  263. },
  264. },
  265. {
  266. name: `"sdk_variant_only: false" outside allowed list`,
  267. fs: map[string][]byte{
  268. "Android.bp": []byte(`
  269. cc_library {
  270. name: "outside_allowed_list",
  271. sdk_version: "current",
  272. sdk_variant_only: false,
  273. }`),
  274. },
  275. expectedErrors: []string{
  276. `module "outside_allowed_list": violates neverallow`,
  277. },
  278. },
  279. {
  280. name: `"platform" outside allowed list`,
  281. fs: map[string][]byte{
  282. "Android.bp": []byte(`
  283. cc_library {
  284. name: "outside_allowed_list",
  285. platform: {
  286. shared_libs: ["libfoo"],
  287. },
  288. }`),
  289. },
  290. expectedErrors: []string{
  291. `module "outside_allowed_list": violates neverallow`,
  292. },
  293. },
  294. {
  295. name: "uncompress_dex inside art",
  296. fs: map[string][]byte{
  297. "art/Android.bp": []byte(`
  298. java_library {
  299. name: "inside_art_libraries",
  300. uncompress_dex: true,
  301. }`),
  302. },
  303. },
  304. {
  305. name: "uncompress_dex outside art",
  306. fs: map[string][]byte{
  307. "other/Android.bp": []byte(`
  308. java_library {
  309. name: "outside_art_libraries",
  310. uncompress_dex: true,
  311. }`),
  312. },
  313. expectedErrors: []string{
  314. "module \"outside_art_libraries\": violates neverallow",
  315. },
  316. },
  317. {
  318. name: "disallowed makefile_goal",
  319. fs: map[string][]byte{
  320. "Android.bp": []byte(`
  321. makefile_goal {
  322. name: "foo",
  323. product_out_path: "boot/trap.img"
  324. }
  325. `),
  326. },
  327. expectedErrors: []string{
  328. "Only boot images may be imported as a makefile goal.",
  329. },
  330. },
  331. }
  332. func TestNeverallow(t *testing.T) {
  333. for _, test := range neverallowTests {
  334. // Create a test per config to allow for test specific config, e.g. test rules.
  335. config := TestConfig(buildDir, nil, "", test.fs)
  336. t.Run(test.name, func(t *testing.T) {
  337. // If the test has its own rules then use them instead of the default ones.
  338. if test.rules != nil {
  339. SetTestNeverallowRules(config, test.rules)
  340. }
  341. _, errs := testNeverallow(config)
  342. CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
  343. })
  344. }
  345. }
  346. func testNeverallow(config Config) (*TestContext, []error) {
  347. ctx := NewTestContext()
  348. ctx.RegisterModuleType("cc_library", newMockCcLibraryModule)
  349. ctx.RegisterModuleType("java_library", newMockJavaLibraryModule)
  350. ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
  351. ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
  352. ctx.RegisterModuleType("makefile_goal", newMockMakefileGoalModule)
  353. ctx.PostDepsMutators(RegisterNeverallowMutator)
  354. ctx.Register(config)
  355. _, errs := ctx.ParseBlueprintsFiles("Android.bp")
  356. if len(errs) > 0 {
  357. return ctx, errs
  358. }
  359. _, errs = ctx.PrepareBuildActions(config)
  360. return ctx, errs
  361. }
  362. type mockCcLibraryProperties struct {
  363. Include_dirs []string
  364. Vendor_available *bool
  365. Static_libs []string
  366. Sdk_version *string
  367. Sdk_variant_only *bool
  368. Vndk struct {
  369. Enabled *bool
  370. Support_system_process *bool
  371. Extends *string
  372. }
  373. Product_variables struct {
  374. Enforce_vintf_manifest struct {
  375. Cflags []string
  376. }
  377. Treble_linker_namespaces struct {
  378. Cflags []string
  379. }
  380. }
  381. Platform struct {
  382. Shared_libs []string
  383. }
  384. }
  385. type mockCcLibraryModule struct {
  386. ModuleBase
  387. properties mockCcLibraryProperties
  388. }
  389. func newMockCcLibraryModule() Module {
  390. m := &mockCcLibraryModule{}
  391. m.AddProperties(&m.properties)
  392. InitAndroidModule(m)
  393. return m
  394. }
  395. type neverallowTestDependencyTag struct {
  396. blueprint.BaseDependencyTag
  397. name string
  398. }
  399. var staticDepTag = neverallowTestDependencyTag{name: "static"}
  400. func (c *mockCcLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
  401. for _, lib := range c.properties.Static_libs {
  402. ctx.AddDependency(ctx.Module(), staticDepTag, lib)
  403. }
  404. }
  405. func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
  406. }
  407. type mockJavaLibraryProperties struct {
  408. Libs []string
  409. Sdk_version *string
  410. Uncompress_dex *bool
  411. }
  412. type mockJavaLibraryModule struct {
  413. ModuleBase
  414. properties mockJavaLibraryProperties
  415. }
  416. func newMockJavaLibraryModule() Module {
  417. m := &mockJavaLibraryModule{}
  418. m.AddProperties(&m.properties)
  419. InitAndroidModule(m)
  420. return m
  421. }
  422. func (p *mockJavaLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
  423. }
  424. type mockMakefileGoalProperties struct {
  425. Product_out_path *string
  426. }
  427. type mockMakefileGoalModule struct {
  428. ModuleBase
  429. properties mockMakefileGoalProperties
  430. }
  431. func newMockMakefileGoalModule() Module {
  432. m := &mockMakefileGoalModule{}
  433. m.AddProperties(&m.properties)
  434. InitAndroidModule(m)
  435. return m
  436. }
  437. func (p *mockMakefileGoalModule) GenerateAndroidBuildActions(ModuleContext) {
  438. }