blob: 1ad276875dc78e4afdf470c92ba737cafec4940a [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
43 android.BazelModuleBase
44
45 // Properties for "test_spec"
46 properties struct {
47 // Specifies the name of the test config.
48 Name string
49 // Specifies the team ID.
50 TeamId string
51 // Specifies the list of tests covered under this module.
52 Tests []string
53 }
54}
55
56type testsDepTagType struct {
57 blueprint.BaseDependencyTag
58}
59
60var testsDepTag = testsDepTagType{}
61
62func (module *TestSpecModule) DepsMutator(ctx android.BottomUpMutatorContext) {
63 // Validate Properties
64 if len(module.properties.TeamId) == 0 {
65 ctx.PropertyErrorf("TeamId", "Team Id not found in the test_spec module. Hint: Maybe the TeamId property hasn't been properly specified.")
66 }
67 if !isInt(module.properties.TeamId) {
68 ctx.PropertyErrorf("TeamId", "Invalid value for Team ID. The Team ID must be an integer.")
69 }
70 if len(module.properties.Tests) == 0 {
71 ctx.PropertyErrorf("Tests", "Expected to attribute some test but none found. Hint: Maybe the test property hasn't been properly specified.")
72 }
73 ctx.AddDependency(ctx.Module(), testsDepTag, module.properties.Tests...)
74}
75func isInt(s string) bool {
76 _, err := strconv.Atoi(s)
77 return err == nil
78}
79
80// Provider published by TestSpec
81type testSpecProviderData struct {
82 IntermediatePath android.WritablePath
83}
84
85var testSpecProviderKey = blueprint.NewProvider(testSpecProviderData{})
86
87type TestModuleProviderData struct {
88}
89
90var TestModuleProviderKey = blueprint.NewProvider(TestModuleProviderData{})
91
92func (module *TestSpecModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
93 for _, m := range ctx.GetDirectDepsWithTag(testsDepTag) {
94 if !ctx.OtherModuleHasProvider(m, TestModuleProviderKey) {
95 ctx.ModuleErrorf(ErrTestModuleDataNotFound, m.Name())
96 }
97 }
98 bpFilePath := filepath.Join(ctx.ModuleDir(), ctx.BlueprintsFile())
99 metadataList := make(
100 []*test_spec_proto.TestSpec_OwnershipMetadata, 0,
101 len(module.properties.Tests),
102 )
103 for _, test := range module.properties.Tests {
104 targetName := test
105 metadata := test_spec_proto.TestSpec_OwnershipMetadata{
106 TrendyTeamId: &module.properties.TeamId,
107 TargetName: &targetName,
108 Path: &bpFilePath,
109 }
110 metadataList = append(metadataList, &metadata)
111 }
112 intermediatePath := android.PathForModuleOut(
113 ctx, "intermediateTestSpecMetadata.pb",
114 )
115 testSpecMetadata := test_spec_proto.TestSpec{OwnershipMetadataList: metadataList}
116 protoData, err := proto.Marshal(&testSpecMetadata)
117 if err != nil {
118 ctx.ModuleErrorf("Error: %s", err.Error())
119 }
120 android.WriteFileRule(ctx, intermediatePath, string(protoData))
121
122 ctx.SetProvider(
123 testSpecProviderKey, testSpecProviderData{
124 IntermediatePath: intermediatePath,
125 },
126 )
127}