blob: 58d9c234513f27873d49ead50d914e0df836d681 [file] [log] [blame]
Aditya Choudhary9b593522023-10-06 19:54:58 +00001// Copyright 2020 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 testing
16
17import (
18 "path/filepath"
19 "strconv"
20
21 "android/soong/android"
22 "android/soong/testing/test_spec_proto"
23 "github.com/google/blueprint"
24 "google.golang.org/protobuf/proto"
25)
26
27// ErrTestModuleDataNotFound is the error message for missing test module provider data.
28const ErrTestModuleDataNotFound = "The module '%s' does not provide test specification data. Hint: This issue could arise if either the module is not a valid testing module or if it lacks the required 'TestModuleProviderKey' provider.\n"
29
30func TestSpecFactory() android.Module {
31 module := &TestSpecModule{}
32
33 android.InitAndroidModule(module)
34 android.InitDefaultableModule(module)
35 module.AddProperties(&module.properties)
36
37 return module
38}
39
40type TestSpecModule struct {
41 android.ModuleBase
42 android.DefaultableModuleBase
Aditya Choudhary9b593522023-10-06 19:54:58 +000043
44 // Properties for "test_spec"
45 properties struct {
46 // Specifies the name of the test config.
47 Name string
48 // Specifies the team ID.
49 TeamId string
50 // Specifies the list of tests covered under this module.
51 Tests []string
52 }
53}
54
55type testsDepTagType struct {
56 blueprint.BaseDependencyTag
57}
58
59var testsDepTag = testsDepTagType{}
60
61func (module *TestSpecModule) DepsMutator(ctx android.BottomUpMutatorContext) {
62 // Validate Properties
63 if len(module.properties.TeamId) == 0 {
64 ctx.PropertyErrorf("TeamId", "Team Id not found in the test_spec module. Hint: Maybe the TeamId property hasn't been properly specified.")
65 }
66 if !isInt(module.properties.TeamId) {
67 ctx.PropertyErrorf("TeamId", "Invalid value for Team ID. The Team ID must be an integer.")
68 }
69 if len(module.properties.Tests) == 0 {
70 ctx.PropertyErrorf("Tests", "Expected to attribute some test but none found. Hint: Maybe the test property hasn't been properly specified.")
71 }
72 ctx.AddDependency(ctx.Module(), testsDepTag, module.properties.Tests...)
73}
74func isInt(s string) bool {
75 _, err := strconv.Atoi(s)
76 return err == nil
77}
78
79// Provider published by TestSpec
Aditya Choudharyb7b3de82023-11-17 12:37:41 +000080type TestSpecProviderData struct {
Aditya Choudhary9b593522023-10-06 19:54:58 +000081 IntermediatePath android.WritablePath
82}
83
Aditya Choudharyb7b3de82023-11-17 12:37:41 +000084var TestSpecProviderKey = blueprint.NewProvider(TestSpecProviderData{})
Aditya Choudhary9b593522023-10-06 19:54:58 +000085
86type TestModuleProviderData struct {
87}
88
89var TestModuleProviderKey = blueprint.NewProvider(TestModuleProviderData{})
90
91func (module *TestSpecModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
92 for _, m := range ctx.GetDirectDepsWithTag(testsDepTag) {
93 if !ctx.OtherModuleHasProvider(m, TestModuleProviderKey) {
94 ctx.ModuleErrorf(ErrTestModuleDataNotFound, m.Name())
95 }
96 }
97 bpFilePath := filepath.Join(ctx.ModuleDir(), ctx.BlueprintsFile())
98 metadataList := make(
99 []*test_spec_proto.TestSpec_OwnershipMetadata, 0,
100 len(module.properties.Tests),
101 )
102 for _, test := range module.properties.Tests {
103 targetName := test
104 metadata := test_spec_proto.TestSpec_OwnershipMetadata{
105 TrendyTeamId: &module.properties.TeamId,
106 TargetName: &targetName,
107 Path: &bpFilePath,
108 }
109 metadataList = append(metadataList, &metadata)
110 }
111 intermediatePath := android.PathForModuleOut(
112 ctx, "intermediateTestSpecMetadata.pb",
113 )
114 testSpecMetadata := test_spec_proto.TestSpec{OwnershipMetadataList: metadataList}
115 protoData, err := proto.Marshal(&testSpecMetadata)
116 if err != nil {
117 ctx.ModuleErrorf("Error: %s", err.Error())
118 }
119 android.WriteFileRule(ctx, intermediatePath, string(protoData))
120
121 ctx.SetProvider(
Aditya Choudharyb7b3de82023-11-17 12:37:41 +0000122 TestSpecProviderKey, TestSpecProviderData{
Aditya Choudhary9b593522023-10-06 19:54:58 +0000123 IntermediatePath: intermediatePath,
124 },
125 )
126}