blob: c2b16f66e58112e54d0f6b0d6101e189258f26ed [file] [log] [blame]
Paul Duffin35816122021-02-24 01:49:52 +00001// Copyright 2021 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
15package android
16
17import (
Paul Duffinbbccfcf2021-03-03 00:44:00 +000018 "fmt"
Paul Duffin80f4cea2021-03-16 14:08:00 +000019 "strings"
Paul Duffin35816122021-02-24 01:49:52 +000020 "testing"
21)
22
23// Provides support for creating test fixtures on which tests can be run. Reduces duplication
24// of test setup by allow tests to easily reuse setup code.
25//
26// Fixture
27// =======
28// These determine the environment within which a test can be run. Fixtures are mutable and are
Paul Duffin4814bb82021-03-29 01:55:10 +010029// created and mutated by FixturePreparer instances. They are created by first creating a base
30// Fixture (which is essentially empty) and then applying FixturePreparer instances to it to modify
31// the environment.
Paul Duffin35816122021-02-24 01:49:52 +000032//
33// FixturePreparer
34// ===============
35// These are responsible for modifying a Fixture in preparation for it to run a test. Preparers are
36// intended to be immutable and able to prepare multiple Fixture objects simultaneously without
37// them sharing any data.
38//
Paul Duffinff2aa692021-03-19 18:20:59 +000039// They provide the basic capabilities for running tests too.
40//
41// FixturePreparers are only ever applied once per test fixture. Prior to application the list of
Paul Duffin35816122021-02-24 01:49:52 +000042// FixturePreparers are flattened and deduped while preserving the order they first appear in the
43// list. This makes it easy to reuse, group and combine FixturePreparers together.
44//
45// Each small self contained piece of test setup should be their own FixturePreparer. e.g.
46// * A group of related modules.
47// * A group of related mutators.
48// * A combination of both.
49// * Configuration.
50//
51// They should not overlap, e.g. the same module type should not be registered by different
52// FixturePreparers as using them both would cause a build error. In that case the preparer should
53// be split into separate parts and combined together using FixturePreparers(...).
54//
55// e.g. attempting to use AllPreparers in preparing a Fixture would break as it would attempt to
56// register module bar twice:
57// var Preparer1 = FixtureRegisterWithContext(RegisterModuleFooAndBar)
58// var Preparer2 = FixtureRegisterWithContext(RegisterModuleBarAndBaz)
Paul Duffina560d5a2021-02-28 01:38:51 +000059// var AllPreparers = GroupFixturePreparers(Preparer1, Preparer2)
Paul Duffin35816122021-02-24 01:49:52 +000060//
61// However, when restructured like this it would work fine:
62// var PreparerFoo = FixtureRegisterWithContext(RegisterModuleFoo)
63// var PreparerBar = FixtureRegisterWithContext(RegisterModuleBar)
64// var PreparerBaz = FixtureRegisterWithContext(RegisterModuleBaz)
Paul Duffina560d5a2021-02-28 01:38:51 +000065// var Preparer1 = GroupFixturePreparers(RegisterModuleFoo, RegisterModuleBar)
66// var Preparer2 = GroupFixturePreparers(RegisterModuleBar, RegisterModuleBaz)
67// var AllPreparers = GroupFixturePreparers(Preparer1, Preparer2)
Paul Duffin35816122021-02-24 01:49:52 +000068//
69// As after deduping and flattening AllPreparers would result in the following preparers being
70// applied:
71// 1. PreparerFoo
72// 2. PreparerBar
73// 3. PreparerBaz
74//
75// Preparers can be used for both integration and unit tests.
76//
77// Integration tests typically use all the module types, mutators and singletons that are available
78// for that package to try and replicate the behavior of the runtime build as closely as possible.
79// However, that realism comes at a cost of increased fragility (as they can be broken by changes in
80// many different parts of the build) and also increased runtime, especially if they use lots of
81// singletons and mutators.
82//
83// Unit tests on the other hand try and minimize the amount of code being tested which makes them
84// less susceptible to changes elsewhere in the build and quick to run but at a cost of potentially
85// not testing realistic scenarios.
86//
87// Supporting unit tests effectively require that preparers are available at the lowest granularity
88// possible. Supporting integration tests effectively require that the preparers are organized into
89// groups that provide all the functionality available.
90//
91// At least in terms of tests that check the behavior of build components via processing
92// `Android.bp` there is no clear separation between a unit test and an integration test. Instead
93// they vary from one end that tests a single module (e.g. filegroup) to the other end that tests a
94// whole system of modules, mutators and singletons (e.g. apex + hiddenapi).
95//
96// TestResult
97// ==========
98// These are created by running tests in a Fixture and provide access to the Config and TestContext
99// in which the tests were run.
100//
101// Example
102// =======
103//
104// An exported preparer for use by other packages that need to use java modules.
105//
106// package java
Paul Duffina560d5a2021-02-28 01:38:51 +0000107// var PrepareForIntegrationTestWithJava = GroupFixturePreparers(
Paul Duffin35816122021-02-24 01:49:52 +0000108// android.PrepareForIntegrationTestWithAndroid,
109// FixtureRegisterWithContext(RegisterAGroupOfRelatedModulesMutatorsAndSingletons),
110// FixtureRegisterWithContext(RegisterAnotherGroupOfRelatedModulesMutatorsAndSingletons),
111// ...
112// )
113//
114// Some files to use in tests in the java package.
115//
116// var javaMockFS = android.MockFS{
Paul Duffinff2aa692021-03-19 18:20:59 +0000117// "api/current.txt": nil,
118// "api/removed.txt": nil,
Paul Duffin35816122021-02-24 01:49:52 +0000119// ...
120// }
121//
Paul Duffinff2aa692021-03-19 18:20:59 +0000122// A package private preparer for use for testing java within the java package.
Paul Duffin35816122021-02-24 01:49:52 +0000123//
Paul Duffinff2aa692021-03-19 18:20:59 +0000124// var prepareForJavaTest = android.GroupFixturePreparers(
125// PrepareForIntegrationTestWithJava,
126// FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
127// ctx.RegisterModuleType("test_module", testModule)
128// }),
129// javaMockFS.AddToFixture(),
130// ...
131// }
132//
133// func TestJavaStuff(t *testing.T) {
Paul Duffin3cb2c062021-03-22 19:24:26 +0000134// result := android.GroupFixturePreparers(
Paul Duffinff2aa692021-03-19 18:20:59 +0000135// prepareForJavaTest,
136// android.FixtureWithRootAndroidBp(`java_library {....}`),
137// android.MockFS{...}.AddToFixture(),
138// ).RunTest(t)
139// ... test result ...
140// }
141//
142// package cc
143// var PrepareForTestWithCC = android.GroupFixturePreparers(
144// android.PrepareForArchMutator,
145// android.prepareForPrebuilts,
146// FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest),
147// ...
148// )
149//
150// package apex
151//
152// var PrepareForApex = GroupFixturePreparers(
153// ...
154// )
155//
156// Use modules and mutators from java, cc and apex. Any duplicate preparers (like
157// android.PrepareForArchMutator) will be automatically deduped.
158//
159// var prepareForApexTest = android.GroupFixturePreparers(
160// PrepareForJava,
161// PrepareForCC,
162// PrepareForApex,
163// )
164//
Paul Duffin35816122021-02-24 01:49:52 +0000165
166// A set of mock files to add to the mock file system.
167type MockFS map[string][]byte
168
Paul Duffin6e9a4002021-03-11 19:01:26 +0000169// Merge adds the extra entries from the supplied map to this one.
170//
171// Fails if the supplied map files with the same paths are present in both of them.
Paul Duffin35816122021-02-24 01:49:52 +0000172func (fs MockFS) Merge(extra map[string][]byte) {
173 for p, c := range extra {
Paul Duffin80f4cea2021-03-16 14:08:00 +0000174 validateFixtureMockFSPath(p)
Paul Duffin6e9a4002021-03-11 19:01:26 +0000175 if _, ok := fs[p]; ok {
176 panic(fmt.Errorf("attempted to add file %s to the mock filesystem but it already exists", p))
177 }
Paul Duffin35816122021-02-24 01:49:52 +0000178 fs[p] = c
179 }
180}
181
Paul Duffin80f4cea2021-03-16 14:08:00 +0000182// Ensure that tests cannot add paths into the mock file system which would not be allowed in the
183// runtime, e.g. absolute paths, paths relative to the 'out/' directory.
184func validateFixtureMockFSPath(path string) {
185 // This uses validateSafePath rather than validatePath because the latter prevents adding files
186 // that include a $ but there are tests that allow files with a $ to be used, albeit only by
187 // globbing.
188 validatedPath, err := validateSafePath(path)
189 if err != nil {
190 panic(err)
191 }
192
193 // Make sure that the path is canonical.
194 if validatedPath != path {
195 panic(fmt.Errorf("path %q is not a canonical path, use %q instead", path, validatedPath))
196 }
197
198 if path == "out" || strings.HasPrefix(path, "out/") {
199 panic(fmt.Errorf("cannot add output path %q to the mock file system", path))
200 }
201}
202
Paul Duffin35816122021-02-24 01:49:52 +0000203func (fs MockFS) AddToFixture() FixturePreparer {
204 return FixtureMergeMockFs(fs)
205}
206
Paul Duffinae542a52021-03-09 03:15:28 +0000207// FixtureCustomPreparer allows for the modification of any aspect of the fixture.
208//
209// This should only be used if one of the other more specific preparers are not suitable.
210func FixtureCustomPreparer(mutator func(fixture Fixture)) FixturePreparer {
211 return newSimpleFixturePreparer(func(f *fixture) {
212 mutator(f)
213 })
214}
215
Paul Duffin4c0765a2022-10-29 17:48:00 +0100216// FixtureTestRunner determines the type of test to run.
217//
218// If no custom FixtureTestRunner is provided (using the FixtureSetTestRunner) then the default test
219// runner will run a standard Soong test that corresponds to what happens when Soong is run on the
220// command line.
221type FixtureTestRunner interface {
222 // FinalPreparer is a function that is run immediately before parsing the blueprint files. It is
223 // intended to perform the initialization needed by PostParseProcessor.
224 //
225 // It returns a CustomTestResult that is passed into PostParseProcessor and returned from
226 // FixturePreparer.RunTestWithCustomResult. If it needs to return some custom data then it must
227 // provide its own implementation of CustomTestResult and return an instance of that. Otherwise,
228 // it can just return the supplied *TestResult.
229 FinalPreparer(result *TestResult) CustomTestResult
230
231 // PostParseProcessor is called after successfully parsing the blueprint files and can do further
232 // work on the result of parsing the files.
233 //
234 // Successfully parsing simply means that no errors were encountered when parsing the blueprint
235 // files.
236 //
237 // This must collate any information useful for testing, e.g. errs, ninja deps and custom data in
238 // the supplied result.
239 PostParseProcessor(result CustomTestResult)
240}
241
242// FixtureSetTestRunner sets the FixtureTestRunner in the fixture.
243//
244// It is an error if more than one of these is applied to a single fixture. If none of these are
245// applied then the fixture will use the defaultTestRunner which will run the test as if it was
246// being run in `m <target>`.
247func FixtureSetTestRunner(testRunner FixtureTestRunner) FixturePreparer {
248 return newSimpleFixturePreparer(func(fixture *fixture) {
249 if fixture.testRunner != nil {
250 panic("fixture test runner has already been set")
251 }
252 fixture.testRunner = testRunner
253 })
254}
255
Paul Duffin35816122021-02-24 01:49:52 +0000256// Modify the config
257func FixtureModifyConfig(mutator func(config Config)) FixturePreparer {
258 return newSimpleFixturePreparer(func(f *fixture) {
259 mutator(f.config)
260 })
261}
262
263// Modify the config and context
264func FixtureModifyConfigAndContext(mutator func(config Config, ctx *TestContext)) FixturePreparer {
265 return newSimpleFixturePreparer(func(f *fixture) {
266 mutator(f.config, f.ctx)
267 })
268}
269
270// Modify the context
271func FixtureModifyContext(mutator func(ctx *TestContext)) FixturePreparer {
272 return newSimpleFixturePreparer(func(f *fixture) {
273 mutator(f.ctx)
274 })
275}
276
277func FixtureRegisterWithContext(registeringFunc func(ctx RegistrationContext)) FixturePreparer {
278 return FixtureModifyContext(func(ctx *TestContext) { registeringFunc(ctx) })
279}
280
281// Modify the mock filesystem
282func FixtureModifyMockFS(mutator func(fs MockFS)) FixturePreparer {
283 return newSimpleFixturePreparer(func(f *fixture) {
284 mutator(f.mockFS)
Paul Duffin80f4cea2021-03-16 14:08:00 +0000285
286 // Make sure that invalid paths were not added to the mock filesystem.
287 for p, _ := range f.mockFS {
288 validateFixtureMockFSPath(p)
289 }
Paul Duffin35816122021-02-24 01:49:52 +0000290 })
291}
292
293// Merge the supplied file system into the mock filesystem.
294//
295// Paths that already exist in the mock file system are overridden.
296func FixtureMergeMockFs(mockFS MockFS) FixturePreparer {
297 return FixtureModifyMockFS(func(fs MockFS) {
298 fs.Merge(mockFS)
299 })
300}
301
302// Add a file to the mock filesystem
Paul Duffin6e9a4002021-03-11 19:01:26 +0000303//
304// Fail if the filesystem already contains a file with that path, use FixtureOverrideFile instead.
Paul Duffin35816122021-02-24 01:49:52 +0000305func FixtureAddFile(path string, contents []byte) FixturePreparer {
306 return FixtureModifyMockFS(func(fs MockFS) {
Paul Duffin80f4cea2021-03-16 14:08:00 +0000307 validateFixtureMockFSPath(path)
Paul Duffin6e9a4002021-03-11 19:01:26 +0000308 if _, ok := fs[path]; ok {
309 panic(fmt.Errorf("attempted to add file %s to the mock filesystem but it already exists, use FixtureOverride*File instead", path))
310 }
Paul Duffin35816122021-02-24 01:49:52 +0000311 fs[path] = contents
312 })
313}
314
315// Add a text file to the mock filesystem
Paul Duffin6e9a4002021-03-11 19:01:26 +0000316//
317// Fail if the filesystem already contains a file with that path.
Paul Duffin35816122021-02-24 01:49:52 +0000318func FixtureAddTextFile(path string, contents string) FixturePreparer {
319 return FixtureAddFile(path, []byte(contents))
320}
321
Paul Duffin6e9a4002021-03-11 19:01:26 +0000322// Override a file in the mock filesystem
323//
324// If the file does not exist this behaves as FixtureAddFile.
325func FixtureOverrideFile(path string, contents []byte) FixturePreparer {
326 return FixtureModifyMockFS(func(fs MockFS) {
327 fs[path] = contents
328 })
329}
330
331// Override a text file in the mock filesystem
332//
333// If the file does not exist this behaves as FixtureAddTextFile.
334func FixtureOverrideTextFile(path string, contents string) FixturePreparer {
335 return FixtureOverrideFile(path, []byte(contents))
336}
337
Paul Duffin35816122021-02-24 01:49:52 +0000338// Add the root Android.bp file with the supplied contents.
339func FixtureWithRootAndroidBp(contents string) FixturePreparer {
340 return FixtureAddTextFile("Android.bp", contents)
341}
342
Paul Duffinbbccfcf2021-03-03 00:44:00 +0000343// Merge some environment variables into the fixture.
344func FixtureMergeEnv(env map[string]string) FixturePreparer {
345 return FixtureModifyConfig(func(config Config) {
346 for k, v := range env {
347 if k == "PATH" {
348 panic("Cannot set PATH environment variable")
349 }
350 config.env[k] = v
351 }
352 })
353}
354
355// Modify the env.
356//
357// Will panic if the mutator changes the PATH environment variable.
358func FixtureModifyEnv(mutator func(env map[string]string)) FixturePreparer {
359 return FixtureModifyConfig(func(config Config) {
360 oldPath := config.env["PATH"]
361 mutator(config.env)
362 newPath := config.env["PATH"]
363 if newPath != oldPath {
364 panic(fmt.Errorf("Cannot change PATH environment variable from %q to %q", oldPath, newPath))
365 }
366 })
367}
368
Paul Duffin2e0323d2021-03-04 15:11:01 +0000369// Allow access to the product variables when preparing the fixture.
370type FixtureProductVariables struct {
371 *productVariables
372}
373
374// Modify product variables.
375func FixtureModifyProductVariables(mutator func(variables FixtureProductVariables)) FixturePreparer {
376 return FixtureModifyConfig(func(config Config) {
377 productVariables := FixtureProductVariables{&config.productVariables}
378 mutator(productVariables)
379 })
380}
381
Paul Duffin64715ba2021-04-20 22:42:17 +0100382// PrepareForDebug_DO_NOT_SUBMIT puts the fixture into debug which will cause it to output its
383// state before running the test.
384//
385// This must only be added temporarily to a test for local debugging and must be removed from the
386// test before submitting.
387var PrepareForDebug_DO_NOT_SUBMIT = newSimpleFixturePreparer(func(fixture *fixture) {
388 fixture.debug = true
389})
390
Paul Duffina560d5a2021-02-28 01:38:51 +0000391// GroupFixturePreparers creates a composite FixturePreparer that is equivalent to applying each of
392// the supplied FixturePreparer instances in order.
393//
394// Before preparing the fixture the list of preparers is flattened by replacing each
395// instance of GroupFixturePreparers with its contents.
396func GroupFixturePreparers(preparers ...FixturePreparer) FixturePreparer {
Paul Duffinff2aa692021-03-19 18:20:59 +0000397 all := dedupAndFlattenPreparers(nil, preparers)
398 return newFixturePreparer(all)
Paul Duffin35816122021-02-24 01:49:52 +0000399}
400
Paul Duffin50deaae2021-03-16 17:46:12 +0000401// NullFixturePreparer is a preparer that does nothing.
402var NullFixturePreparer = GroupFixturePreparers()
403
404// OptionalFixturePreparer will return the supplied preparer if it is non-nil, otherwise it will
405// return the NullFixturePreparer
406func OptionalFixturePreparer(preparer FixturePreparer) FixturePreparer {
407 if preparer == nil {
408 return NullFixturePreparer
409 } else {
410 return preparer
411 }
412}
413
Paul Duffinff2aa692021-03-19 18:20:59 +0000414// FixturePreparer provides the ability to create, modify and then run tests within a fixture.
Paul Duffin35816122021-02-24 01:49:52 +0000415type FixturePreparer interface {
Paul Duffin4ca67522021-03-20 01:25:12 +0000416 // Return the flattened and deduped list of simpleFixturePreparer pointers.
417 list() []*simpleFixturePreparer
Paul Duffinff2aa692021-03-19 18:20:59 +0000418
Paul Duffinff2aa692021-03-19 18:20:59 +0000419 // Create a Fixture.
Paul Duffin34a7fff2021-03-30 22:11:24 +0100420 Fixture(t *testing.T) Fixture
Paul Duffinff2aa692021-03-19 18:20:59 +0000421
422 // ExtendWithErrorHandler creates a new FixturePreparer that will use the supplied error handler
423 // to check the errors (may be 0) reported by the test.
424 //
425 // The default handlers is FixtureExpectsNoErrors which will fail the go test immediately if any
426 // errors are reported.
427 ExtendWithErrorHandler(errorHandler FixtureErrorHandler) FixturePreparer
428
429 // Run the test, checking any errors reported and returning a TestResult instance.
430 //
Paul Duffin55e740e2021-03-29 02:06:19 +0100431 // Shorthand for Fixture(t).RunTest()
432 RunTest(t *testing.T) *TestResult
Paul Duffinff2aa692021-03-19 18:20:59 +0000433
Paul Duffin4c0765a2022-10-29 17:48:00 +0100434 // RunTestWithCustomResult runs the test just as RunTest(t) does but instead of returning a
435 // *TestResult it returns the CustomTestResult that was returned by the custom
436 // FixtureTestRunner.PostParseProcessor method that ran the test, or the *TestResult if that
437 // method returned nil.
438 //
439 // This method must be used when needing to access custom data collected by the
440 // FixtureTestRunner.PostParseProcessor method.
441 //
442 // e.g. something like this
443 //
444 // preparers := ...FixtureSetTestRunner(&myTestRunner)...
445 // customResult := preparers.RunTestWithCustomResult(t).(*myCustomTestResult)
446 // doSomething(customResult.data)
447 RunTestWithCustomResult(t *testing.T) CustomTestResult
448
Paul Duffinff2aa692021-03-19 18:20:59 +0000449 // Run the test with the supplied Android.bp file.
450 //
Paul Duffin55e740e2021-03-29 02:06:19 +0100451 // preparer.RunTestWithBp(t, bp) is shorthand for
452 // android.GroupFixturePreparers(preparer, android.FixtureWithRootAndroidBp(bp)).RunTest(t)
Paul Duffinff2aa692021-03-19 18:20:59 +0000453 RunTestWithBp(t *testing.T, bp string) *TestResult
454
455 // RunTestWithConfig is a temporary method added to help ease the migration of existing tests to
456 // the test fixture.
457 //
458 // In order to allow the Config object to be customized separately to the TestContext a lot of
459 // existing test code has `test...WithConfig` funcs that allow the Config object to be supplied
460 // from the test and then have the TestContext created and configured automatically. e.g.
461 // testCcWithConfig, testCcErrorWithConfig, testJavaWithConfig, etc.
462 //
463 // This method allows those methods to be migrated to use the test fixture pattern without
464 // requiring that every test that uses those methods be migrated at the same time. That allows
465 // those tests to benefit from correctness in the order of registration quickly.
466 //
467 // This method discards the config (along with its mock file system, product variables,
468 // environment, etc.) that may have been set up by FixturePreparers.
469 //
470 // deprecated
471 RunTestWithConfig(t *testing.T, config Config) *TestResult
Paul Duffin35816122021-02-24 01:49:52 +0000472}
473
474// dedupAndFlattenPreparers removes any duplicates and flattens any composite FixturePreparer
475// instances.
476//
477// base - a list of already flattened and deduped preparers that will be applied first before
Colin Crossd079e0b2022-08-16 10:27:33 -0700478//
479// the list of additional preparers. Any duplicates of these in the additional preparers
480// will be ignored.
Paul Duffin35816122021-02-24 01:49:52 +0000481//
482// preparers - a list of additional unflattened, undeduped preparers that will be applied after the
Colin Crossd079e0b2022-08-16 10:27:33 -0700483//
484// base preparers.
Paul Duffin35816122021-02-24 01:49:52 +0000485//
Paul Duffin59251822021-03-15 22:20:12 +0000486// Returns a deduped and flattened list of the preparers starting with the ones in base with any
487// additional ones from the preparers list added afterwards.
Paul Duffin4ca67522021-03-20 01:25:12 +0000488func dedupAndFlattenPreparers(base []*simpleFixturePreparer, preparers []FixturePreparer) []*simpleFixturePreparer {
Paul Duffin59251822021-03-15 22:20:12 +0000489 if len(preparers) == 0 {
490 return base
491 }
492
493 list := make([]*simpleFixturePreparer, len(base))
Paul Duffin35816122021-02-24 01:49:52 +0000494 visited := make(map[*simpleFixturePreparer]struct{})
495
496 // Mark the already flattened and deduped preparers, if any, as having been seen so that
Paul Duffin59251822021-03-15 22:20:12 +0000497 // duplicates of these in the additional preparers will be discarded. Add them to the output
498 // list.
499 for i, s := range base {
Paul Duffin35816122021-02-24 01:49:52 +0000500 visited[s] = struct{}{}
Paul Duffin59251822021-03-15 22:20:12 +0000501 list[i] = s
Paul Duffin35816122021-02-24 01:49:52 +0000502 }
503
Paul Duffin4ca67522021-03-20 01:25:12 +0000504 for _, p := range preparers {
505 for _, s := range p.list() {
506 if _, seen := visited[s]; !seen {
507 visited[s] = struct{}{}
508 list = append(list, s)
509 }
Paul Duffin35816122021-02-24 01:49:52 +0000510 }
Paul Duffin4ca67522021-03-20 01:25:12 +0000511 }
512
Paul Duffin35816122021-02-24 01:49:52 +0000513 return list
514}
515
516// compositeFixturePreparer is a FixturePreparer created from a list of fixture preparers.
517type compositeFixturePreparer struct {
Paul Duffinff2aa692021-03-19 18:20:59 +0000518 baseFixturePreparer
Paul Duffin4ca67522021-03-20 01:25:12 +0000519 // The flattened and deduped list of simpleFixturePreparer pointers encapsulated within this
520 // composite preparer.
Paul Duffin35816122021-02-24 01:49:52 +0000521 preparers []*simpleFixturePreparer
522}
523
Paul Duffin4ca67522021-03-20 01:25:12 +0000524func (c *compositeFixturePreparer) list() []*simpleFixturePreparer {
525 return c.preparers
Paul Duffin35816122021-02-24 01:49:52 +0000526}
527
Paul Duffinff2aa692021-03-19 18:20:59 +0000528func newFixturePreparer(preparers []*simpleFixturePreparer) FixturePreparer {
529 if len(preparers) == 1 {
530 return preparers[0]
531 }
532 p := &compositeFixturePreparer{
533 preparers: preparers,
534 }
535 p.initBaseFixturePreparer(p)
536 return p
537}
538
Paul Duffin35816122021-02-24 01:49:52 +0000539// simpleFixturePreparer is a FixturePreparer that applies a function to a fixture.
540type simpleFixturePreparer struct {
Paul Duffinff2aa692021-03-19 18:20:59 +0000541 baseFixturePreparer
Paul Duffin35816122021-02-24 01:49:52 +0000542 function func(fixture *fixture)
543}
544
Paul Duffin4ca67522021-03-20 01:25:12 +0000545func (s *simpleFixturePreparer) list() []*simpleFixturePreparer {
546 return []*simpleFixturePreparer{s}
Paul Duffin35816122021-02-24 01:49:52 +0000547}
548
549func newSimpleFixturePreparer(preparer func(fixture *fixture)) FixturePreparer {
Paul Duffinff2aa692021-03-19 18:20:59 +0000550 p := &simpleFixturePreparer{function: preparer}
551 p.initBaseFixturePreparer(p)
552 return p
Paul Duffin35816122021-02-24 01:49:52 +0000553}
554
Paul Duffincfd33742021-02-27 11:59:02 +0000555// FixtureErrorHandler determines how to respond to errors reported by the code under test.
556//
557// Some possible responses:
Colin Crossd079e0b2022-08-16 10:27:33 -0700558// - Fail the test if any errors are reported, see FixtureExpectsNoErrors.
559// - Fail the test if at least one error that matches a pattern is not reported see
560// FixtureExpectsAtLeastOneErrorMatchingPattern
561// - Fail the test if any unexpected errors are reported.
Paul Duffincfd33742021-02-27 11:59:02 +0000562//
563// Although at the moment all the error handlers are implemented as simply a wrapper around a
564// function this is defined as an interface to allow future enhancements, e.g. provide different
565// ways other than patterns to match an error and to combine handlers together.
566type FixtureErrorHandler interface {
567 // CheckErrors checks the errors reported.
568 //
569 // The supplied result can be used to access the state of the code under test just as the main
570 // body of the test would but if any errors other than ones expected are reported the state may
571 // be indeterminate.
Paul Duffinc81854a2021-03-12 12:22:27 +0000572 CheckErrors(t *testing.T, result *TestResult)
Paul Duffincfd33742021-02-27 11:59:02 +0000573}
574
575type simpleErrorHandler struct {
Paul Duffinc81854a2021-03-12 12:22:27 +0000576 function func(t *testing.T, result *TestResult)
Paul Duffincfd33742021-02-27 11:59:02 +0000577}
578
Paul Duffinc81854a2021-03-12 12:22:27 +0000579func (h simpleErrorHandler) CheckErrors(t *testing.T, result *TestResult) {
580 t.Helper()
581 h.function(t, result)
Paul Duffincfd33742021-02-27 11:59:02 +0000582}
583
584// The default fixture error handler.
585//
586// Will fail the test immediately if any errors are reported.
Paul Duffinea8a3862021-03-04 17:58:33 +0000587//
588// If the test fails this handler will call `result.FailNow()` which will exit the goroutine within
589// which the test is being run which means that the RunTest() method will not return.
Paul Duffincfd33742021-02-27 11:59:02 +0000590var FixtureExpectsNoErrors = FixtureCustomErrorHandler(
Paul Duffinc81854a2021-03-12 12:22:27 +0000591 func(t *testing.T, result *TestResult) {
592 t.Helper()
593 FailIfErrored(t, result.Errs)
Paul Duffincfd33742021-02-27 11:59:02 +0000594 },
595)
596
Paul Duffin85034e92021-03-17 00:20:34 +0000597// FixtureIgnoreErrors ignores any errors.
598//
599// If this is used then it is the responsibility of the test to check the TestResult.Errs does not
600// contain any unexpected errors.
601var FixtureIgnoreErrors = FixtureCustomErrorHandler(func(t *testing.T, result *TestResult) {
602 // Ignore the errors
603})
604
Paul Duffincfd33742021-02-27 11:59:02 +0000605// FixtureExpectsAtLeastOneMatchingError returns an error handler that will cause the test to fail
606// if at least one error that matches the regular expression is not found.
607//
608// The test will be failed if:
609// * No errors are reported.
610// * One or more errors are reported but none match the pattern.
611//
612// The test will not fail if:
613// * Multiple errors are reported that do not match the pattern as long as one does match.
Paul Duffinea8a3862021-03-04 17:58:33 +0000614//
615// If the test fails this handler will call `result.FailNow()` which will exit the goroutine within
616// which the test is being run which means that the RunTest() method will not return.
Paul Duffincfd33742021-02-27 11:59:02 +0000617func FixtureExpectsAtLeastOneErrorMatchingPattern(pattern string) FixtureErrorHandler {
Paul Duffinc81854a2021-03-12 12:22:27 +0000618 return FixtureCustomErrorHandler(func(t *testing.T, result *TestResult) {
619 t.Helper()
620 if !FailIfNoMatchingErrors(t, pattern, result.Errs) {
621 t.FailNow()
Paul Duffinea8a3862021-03-04 17:58:33 +0000622 }
Paul Duffincfd33742021-02-27 11:59:02 +0000623 })
624}
625
626// FixtureExpectsOneErrorToMatchPerPattern returns an error handler that will cause the test to fail
627// if there are any unexpected errors.
628//
629// The test will be failed if:
630// * The number of errors reported does not exactly match the patterns.
631// * One or more of the reported errors do not match a pattern.
632// * No patterns are provided and one or more errors are reported.
633//
634// The test will not fail if:
635// * One or more of the patterns does not match an error.
Paul Duffinea8a3862021-03-04 17:58:33 +0000636//
637// If the test fails this handler will call `result.FailNow()` which will exit the goroutine within
638// which the test is being run which means that the RunTest() method will not return.
Paul Duffincfd33742021-02-27 11:59:02 +0000639func FixtureExpectsAllErrorsToMatchAPattern(patterns []string) FixtureErrorHandler {
Paul Duffinc81854a2021-03-12 12:22:27 +0000640 return FixtureCustomErrorHandler(func(t *testing.T, result *TestResult) {
641 t.Helper()
642 CheckErrorsAgainstExpectations(t, result.Errs, patterns)
Paul Duffincfd33742021-02-27 11:59:02 +0000643 })
644}
645
Paul Duffin0fc6d322021-07-06 22:36:33 +0100646// FixtureExpectsOneErrorPattern returns an error handler that will cause the test to fail
647// if there is more than one error or the error does not match the pattern.
648//
649// If the test fails this handler will call `result.FailNow()` which will exit the goroutine within
650// which the test is being run which means that the RunTest() method will not return.
651func FixtureExpectsOneErrorPattern(pattern string) FixtureErrorHandler {
652 return FixtureCustomErrorHandler(func(t *testing.T, result *TestResult) {
653 t.Helper()
654 CheckErrorsAgainstExpectations(t, result.Errs, []string{pattern})
655 })
656}
657
Paul Duffincfd33742021-02-27 11:59:02 +0000658// FixtureCustomErrorHandler creates a custom error handler
Paul Duffinc81854a2021-03-12 12:22:27 +0000659func FixtureCustomErrorHandler(function func(t *testing.T, result *TestResult)) FixtureErrorHandler {
Paul Duffincfd33742021-02-27 11:59:02 +0000660 return simpleErrorHandler{
661 function: function,
662 }
663}
664
Paul Duffin35816122021-02-24 01:49:52 +0000665// Fixture defines the test environment.
666type Fixture interface {
Paul Duffinae542a52021-03-09 03:15:28 +0000667 // Config returns the fixture's configuration.
668 Config() Config
669
670 // Context returns the fixture's test context.
671 Context() *TestContext
672
673 // MockFS returns the fixture's mock filesystem.
674 MockFS() MockFS
675
Paul Duffincfd33742021-02-27 11:59:02 +0000676 // Run the test, checking any errors reported and returning a TestResult instance.
Paul Duffin4c0765a2022-10-29 17:48:00 +0100677 RunTest() CustomTestResult
Paul Duffin35816122021-02-24 01:49:52 +0000678}
679
Paul Duffin35816122021-02-24 01:49:52 +0000680// Struct to allow TestResult to embed a *TestContext and allow call forwarding to its methods.
681type testContext struct {
682 *TestContext
683}
684
685// The result of running a test.
686type TestResult struct {
Paul Duffin35816122021-02-24 01:49:52 +0000687 testContext
688
689 fixture *fixture
690 Config Config
Paul Duffin942481b2021-03-04 18:58:11 +0000691
692 // The errors that were reported during the test.
693 Errs []error
Paul Duffin78c36212021-03-16 23:57:12 +0000694
695 // The ninja deps is a list of the ninja files dependencies that were added by the modules and
696 // singletons via the *.AddNinjaFileDeps() methods.
697 NinjaDeps []string
Paul Duffin35816122021-02-24 01:49:52 +0000698}
699
Paul Duffin4c0765a2022-10-29 17:48:00 +0100700func (r *TestResult) testResult() *TestResult { return r }
701
702// CustomTestResult is the interface that FixtureTestRunner implementations who wish to return
703// custom data must implement. It must embed *TestResult and initialize that to the value passed
704// into the method. It is returned from the FixtureTestRunner.FinalPreparer, passed into the
705// FixtureTestRunner.PostParseProcessor and returned from FixturePreparer.RunTestWithCustomResult.
706//
707// e.g. something like this:
708//
709// type myCustomTestResult struct {
710// *android.TestResult
711// data []string
712// }
713//
714// func (r *myTestRunner) FinalPreparer(result *TestResult) CustomTestResult {
715// ... do some final test preparation ...
716// return &myCustomTestResult{TestResult: result)
717// }
718//
719// func (r *myTestRunner) PostParseProcessor(result CustomTestResult) {
720// ...
721// myData := []string {....}
722// ...
723// customResult := result.(*myCustomTestResult)
724// customResult.data = myData
725// }
726type CustomTestResult interface {
727 // testResult returns the embedded *TestResult.
728 testResult() *TestResult
729}
730
731var _ CustomTestResult = (*TestResult)(nil)
732
Sam Delmerico2351eac2022-05-24 17:10:02 +0000733type TestPathContext struct {
734 *TestResult
735}
736
737var _ PathContext = &TestPathContext{}
738
739func (t *TestPathContext) Config() Config {
740 return t.TestResult.Config
741}
742
743func (t *TestPathContext) AddNinjaFileDeps(deps ...string) {
744 panic("unimplemented")
745}
746
Paul Duffin34a7fff2021-03-30 22:11:24 +0100747func createFixture(t *testing.T, buildDir string, preparers []*simpleFixturePreparer) Fixture {
Paul Duffindff5ff02021-03-15 15:42:40 +0000748 config := TestConfig(buildDir, nil, "", nil)
Paul Duffin3f7bf9f2022-11-08 12:21:15 +0000749 ctx := newTestContextForFixture(config)
Paul Duffin35816122021-02-24 01:49:52 +0000750 fixture := &fixture{
Paul Duffin34a7fff2021-03-30 22:11:24 +0100751 preparers: preparers,
Paul Duffincff464f2021-03-19 18:13:46 +0000752 t: t,
753 config: config,
754 ctx: ctx,
755 mockFS: make(MockFS),
756 // Set the default error handler.
757 errorHandler: FixtureExpectsNoErrors,
Paul Duffin35816122021-02-24 01:49:52 +0000758 }
759
Paul Duffin34a7fff2021-03-30 22:11:24 +0100760 for _, preparer := range preparers {
Paul Duffin35816122021-02-24 01:49:52 +0000761 preparer.function(fixture)
762 }
763
764 return fixture
765}
766
Paul Duffinff2aa692021-03-19 18:20:59 +0000767type baseFixturePreparer struct {
768 self FixturePreparer
769}
770
771func (b *baseFixturePreparer) initBaseFixturePreparer(self FixturePreparer) {
772 b.self = self
773}
774
Paul Duffin34a7fff2021-03-30 22:11:24 +0100775func (b *baseFixturePreparer) Fixture(t *testing.T) Fixture {
776 return createFixture(t, t.TempDir(), b.self.list())
Paul Duffinff2aa692021-03-19 18:20:59 +0000777}
778
779func (b *baseFixturePreparer) ExtendWithErrorHandler(errorHandler FixtureErrorHandler) FixturePreparer {
Paul Duffin79abe572021-03-29 02:16:14 +0100780 return GroupFixturePreparers(b.self, newSimpleFixturePreparer(func(fixture *fixture) {
Paul Duffincff464f2021-03-19 18:13:46 +0000781 fixture.errorHandler = errorHandler
782 }))
Paul Duffincfd33742021-02-27 11:59:02 +0000783}
784
Paul Duffin55e740e2021-03-29 02:06:19 +0100785func (b *baseFixturePreparer) RunTest(t *testing.T) *TestResult {
Paul Duffin35816122021-02-24 01:49:52 +0000786 t.Helper()
Paul Duffin4c0765a2022-10-29 17:48:00 +0100787 return b.RunTestWithCustomResult(t).testResult()
788}
789
790func (b *baseFixturePreparer) RunTestWithCustomResult(t *testing.T) CustomTestResult {
791 t.Helper()
Paul Duffin55e740e2021-03-29 02:06:19 +0100792 fixture := b.self.Fixture(t)
Paul Duffin35816122021-02-24 01:49:52 +0000793 return fixture.RunTest()
794}
795
Paul Duffinff2aa692021-03-19 18:20:59 +0000796func (b *baseFixturePreparer) RunTestWithBp(t *testing.T, bp string) *TestResult {
Paul Duffin35816122021-02-24 01:49:52 +0000797 t.Helper()
Paul Duffin55e740e2021-03-29 02:06:19 +0100798 return GroupFixturePreparers(b.self, FixtureWithRootAndroidBp(bp)).RunTest(t)
Paul Duffin35816122021-02-24 01:49:52 +0000799}
800
Paul Duffinff2aa692021-03-19 18:20:59 +0000801func (b *baseFixturePreparer) RunTestWithConfig(t *testing.T, config Config) *TestResult {
Paul Duffin72018ad2021-03-04 19:36:49 +0000802 t.Helper()
803 // Create the fixture as normal.
Paul Duffinff2aa692021-03-19 18:20:59 +0000804 fixture := b.self.Fixture(t).(*fixture)
Paul Duffin72018ad2021-03-04 19:36:49 +0000805
806 // Discard the mock filesystem as otherwise that will override the one in the config.
807 fixture.mockFS = nil
808
809 // Replace the config with the supplied one in the fixture.
810 fixture.config = config
811
812 // Ditto with config derived information in the TestContext.
813 ctx := fixture.ctx
814 ctx.config = config
815 ctx.SetFs(ctx.config.fs)
816 if ctx.config.mockBpList != "" {
817 ctx.SetModuleListFile(ctx.config.mockBpList)
818 }
819
Paul Duffin4c0765a2022-10-29 17:48:00 +0100820 return fixture.RunTest().testResult()
Paul Duffin72018ad2021-03-04 19:36:49 +0000821}
822
Paul Duffin35816122021-02-24 01:49:52 +0000823type fixture struct {
Paul Duffin59251822021-03-15 22:20:12 +0000824 // The preparers used to create this fixture.
825 preparers []*simpleFixturePreparer
Paul Duffincfd33742021-02-27 11:59:02 +0000826
Paul Duffin4c0765a2022-10-29 17:48:00 +0100827 // The test runner used in this fixture, defaults to defaultTestRunner if not set.
828 testRunner FixtureTestRunner
829
Paul Duffincfd33742021-02-27 11:59:02 +0000830 // The gotest state of the go test within which this was created.
831 t *testing.T
832
833 // The configuration prepared for this fixture.
834 config Config
835
836 // The test context prepared for this fixture.
837 ctx *TestContext
838
839 // The mock filesystem prepared for this fixture.
840 mockFS MockFS
841
842 // The error handler used to check the errors, if any, that are reported.
843 errorHandler FixtureErrorHandler
Paul Duffin64715ba2021-04-20 22:42:17 +0100844
845 // Debug mode status
846 debug bool
Paul Duffin35816122021-02-24 01:49:52 +0000847}
848
Paul Duffinae542a52021-03-09 03:15:28 +0000849func (f *fixture) Config() Config {
850 return f.config
851}
852
853func (f *fixture) Context() *TestContext {
854 return f.ctx
855}
856
857func (f *fixture) MockFS() MockFS {
858 return f.mockFS
859}
860
Paul Duffin4c0765a2022-10-29 17:48:00 +0100861func (f *fixture) RunTest() CustomTestResult {
Paul Duffin35816122021-02-24 01:49:52 +0000862 f.t.Helper()
863
Paul Duffin64715ba2021-04-20 22:42:17 +0100864 // If in debug mode output the state of the fixture before running the test.
865 if f.debug {
866 f.outputDebugState()
867 }
868
Paul Duffin35816122021-02-24 01:49:52 +0000869 ctx := f.ctx
870
Paul Duffin72018ad2021-03-04 19:36:49 +0000871 // Do not use the fixture's mockFS to initialize the config's mock file system if it has been
872 // cleared by RunTestWithConfig.
873 if f.mockFS != nil {
874 // The TestConfig() method assumes that the mock filesystem is available when creating so
875 // creates the mock file system immediately. Similarly, the NewTestContext(Config) method
876 // assumes that the supplied Config's FileSystem has been properly initialized before it is
877 // called and so it takes its own reference to the filesystem. However, fixtures create the
878 // Config and TestContext early so they can be modified by preparers at which time the mockFS
879 // has not been populated (because it too is modified by preparers). So, this reinitializes the
880 // Config and TestContext's FileSystem using the now populated mockFS.
881 f.config.mockFileSystem("", f.mockFS)
882
883 ctx.SetFs(ctx.config.fs)
884 if ctx.config.mockBpList != "" {
885 ctx.SetModuleListFile(ctx.config.mockBpList)
886 }
Paul Duffin35816122021-02-24 01:49:52 +0000887 }
888
Paul Duffin3f7bf9f2022-11-08 12:21:15 +0000889 // Create and set the Context's NameInterface. It needs to be created here as it depends on the
890 // configuration that has been prepared for this fixture.
891 resolver := NewNameResolver(ctx.config)
892
893 // Set the NameInterface in the main Context.
894 ctx.SetNameInterface(resolver)
895
896 // Set the NameResolver in the TestContext.
897 ctx.NameResolver = resolver
898
Paul Duffin4c0765a2022-10-29 17:48:00 +0100899 // If test runner has not been set then use the default runner.
900 if f.testRunner == nil {
901 f.testRunner = defaultTestRunner
Paul Duffincfd33742021-02-27 11:59:02 +0000902 }
Paul Duffin35816122021-02-24 01:49:52 +0000903
Paul Duffin4c0765a2022-10-29 17:48:00 +0100904 // Create the result to collate result information.
Paul Duffin35816122021-02-24 01:49:52 +0000905 result := &TestResult{
Paul Duffin35816122021-02-24 01:49:52 +0000906 testContext: testContext{ctx},
907 fixture: f,
908 Config: f.config,
Paul Duffin4c0765a2022-10-29 17:48:00 +0100909 }
910
911 // Do any last minute preparation before parsing the blueprint files.
912 customResult := f.testRunner.FinalPreparer(result)
913
914 // Parse the blueprint files adding the information to the result.
915 extraNinjaDeps, errs := ctx.ParseBlueprintsFiles("ignored")
916 result.NinjaDeps = append(result.NinjaDeps, extraNinjaDeps...)
917 result.Errs = append(result.Errs, errs...)
918
919 if len(result.Errs) == 0 {
920 // If parsing the blueprint files was successful then perform any additional processing.
921 f.testRunner.PostParseProcessor(customResult)
Paul Duffin35816122021-02-24 01:49:52 +0000922 }
Paul Duffincfd33742021-02-27 11:59:02 +0000923
Paul Duffinc81854a2021-03-12 12:22:27 +0000924 f.errorHandler.CheckErrors(f.t, result)
Paul Duffincfd33742021-02-27 11:59:02 +0000925
Paul Duffin4c0765a2022-10-29 17:48:00 +0100926 return customResult
927}
928
929// standardTestRunner is the implementation of the default test runner
930type standardTestRunner struct{}
931
932func (s *standardTestRunner) FinalPreparer(result *TestResult) CustomTestResult {
933 // Register the hard coded mutators and singletons used by the standard Soong build as well as
934 // any additional instances that have been registered with this fixture.
935 result.TestContext.Register()
Paul Duffin35816122021-02-24 01:49:52 +0000936 return result
937}
938
Paul Duffin4c0765a2022-10-29 17:48:00 +0100939func (s *standardTestRunner) PostParseProcessor(customResult CustomTestResult) {
940 result := customResult.(*TestResult)
941 ctx := result.TestContext
942 cfg := result.Config
943 // Prepare the build actions, i.e. run all the mutators, singletons and then invoke the
944 // GenerateAndroidBuildActions methods on all the modules.
945 extraNinjaDeps, errs := ctx.PrepareBuildActions(cfg)
946 result.NinjaDeps = append(result.NinjaDeps, extraNinjaDeps...)
947 result.CollateErrs(errs)
948}
949
950var defaultTestRunner FixtureTestRunner = &standardTestRunner{}
951
Paul Duffin64715ba2021-04-20 22:42:17 +0100952func (f *fixture) outputDebugState() {
953 fmt.Printf("Begin Fixture State for %s\n", f.t.Name())
954 if len(f.config.env) == 0 {
955 fmt.Printf(" Fixture Env is empty\n")
956 } else {
957 fmt.Printf(" Begin Env\n")
958 for k, v := range f.config.env {
959 fmt.Printf(" - %s=%s\n", k, v)
960 }
961 fmt.Printf(" End Env\n")
962 }
963 if len(f.mockFS) == 0 {
964 fmt.Printf(" Mock FS is empty\n")
965 } else {
966 fmt.Printf(" Begin Mock FS Contents\n")
967 for p, c := range f.mockFS {
968 if c == nil {
969 fmt.Printf("\n - %s: nil\n", p)
970 } else {
971 contents := string(c)
972 separator := " ========================================================================"
973 fmt.Printf(" - %s\n%s\n", p, separator)
974 for i, line := range strings.Split(contents, "\n") {
975 fmt.Printf(" %6d: %s\n", i+1, line)
976 }
977 fmt.Printf("%s\n", separator)
978 }
979 }
980 fmt.Printf(" End Mock FS Contents\n")
981 }
982 fmt.Printf("End Fixture State for %s\n", f.t.Name())
983}
984
Paul Duffin35816122021-02-24 01:49:52 +0000985// NormalizePathForTesting removes the test invocation specific build directory from the supplied
986// path.
987//
988// If the path is within the build directory (e.g. an OutputPath) then this returns the relative
989// path to avoid tests having to deal with the dynamically generated build directory.
990//
991// Otherwise, this returns the supplied path as it is almost certainly a source path that is
992// relative to the root of the source tree.
993//
994// Even though some information is removed from some paths and not others it should be possible to
995// differentiate between them by the paths themselves, e.g. output paths will likely include
996// ".intermediates" but source paths won't.
997func (r *TestResult) NormalizePathForTesting(path Path) string {
998 pathContext := PathContextForTesting(r.Config)
999 pathAsString := path.String()
Lukacs T. Berki9f6c24a2021-08-26 15:07:24 +02001000 if rel, isRel := MaybeRel(pathContext, r.Config.SoongOutDir(), pathAsString); isRel {
Paul Duffin35816122021-02-24 01:49:52 +00001001 return rel
1002 }
1003 return pathAsString
1004}
1005
1006// NormalizePathsForTesting normalizes each path in the supplied list and returns their normalized
1007// forms.
1008func (r *TestResult) NormalizePathsForTesting(paths Paths) []string {
1009 var result []string
1010 for _, path := range paths {
1011 result = append(result, r.NormalizePathForTesting(path))
1012 }
1013 return result
1014}
1015
Paul Duffin59251822021-03-15 22:20:12 +00001016// Preparer will return a FixturePreparer encapsulating all the preparers used to create the fixture
1017// that produced this result.
1018//
1019// e.g. assuming that this result was created by running:
Colin Crossd079e0b2022-08-16 10:27:33 -07001020//
1021// GroupFixturePreparers(preparer1, preparer2, preparer3).RunTest(t)
Paul Duffin59251822021-03-15 22:20:12 +00001022//
1023// Then this method will be equivalent to running:
Colin Crossd079e0b2022-08-16 10:27:33 -07001024//
1025// GroupFixturePreparers(preparer1, preparer2, preparer3)
Paul Duffin59251822021-03-15 22:20:12 +00001026//
1027// This is intended for use by tests whose output is Android.bp files to verify that those files
1028// are valid, e.g. tests of the snapshots produced by the sdk module type.
1029func (r *TestResult) Preparer() FixturePreparer {
Paul Duffinff2aa692021-03-19 18:20:59 +00001030 return newFixturePreparer(r.fixture.preparers)
Paul Duffin59251822021-03-15 22:20:12 +00001031}
1032
Paul Duffin35816122021-02-24 01:49:52 +00001033// Module returns the module with the specific name and of the specified variant.
1034func (r *TestResult) Module(name string, variant string) Module {
1035 return r.ModuleForTests(name, variant).Module()
1036}
Paul Duffin4c0765a2022-10-29 17:48:00 +01001037
1038// CollateErrs adds additional errors to the result and returns true if there is more than one
1039// error in the result.
1040func (r *TestResult) CollateErrs(errs []error) bool {
1041 r.Errs = append(r.Errs, errs...)
1042 return len(r.Errs) > 0
1043}