blob: 4d885c6de0ad8ab24935f8f9ef6d57135eb02df7 [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"
Aditya Choudhary9b593522023-10-06 19:54:58 +000023 "google.golang.org/protobuf/proto"
Colin Crossbc7d76c2023-12-12 16:39:03 -080024
25 "github.com/google/blueprint"
Aditya Choudhary9b593522023-10-06 19:54:58 +000026)
27
28// ErrTestModuleDataNotFound is the error message for missing test module provider data.
29const 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"
30
31func TestSpecFactory() android.Module {
32 module := &TestSpecModule{}
33
34 android.InitAndroidModule(module)
35 android.InitDefaultableModule(module)
36 module.AddProperties(&module.properties)
37
38 return module
39}
40
41type TestSpecModule struct {
42 android.ModuleBase
43 android.DefaultableModuleBase
Aditya Choudhary9b593522023-10-06 19:54:58 +000044
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
Aditya Choudharyb7b3de82023-11-17 12:37:41 +000081type TestSpecProviderData struct {
Aditya Choudhary9b593522023-10-06 19:54:58 +000082 IntermediatePath android.WritablePath
83}
84
Colin Crossbc7d76c2023-12-12 16:39:03 -080085var TestSpecProviderKey = blueprint.NewProvider[TestSpecProviderData]()
Aditya Choudhary9b593522023-10-06 19:54:58 +000086
87type TestModuleProviderData struct {
88}
89
Colin Crossbc7d76c2023-12-12 16:39:03 -080090var TestModuleProviderKey = blueprint.NewProvider[TestModuleProviderData]()
Aditya Choudhary9b593522023-10-06 19:54:58 +000091
92func (module *TestSpecModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
93 for _, m := range ctx.GetDirectDepsWithTag(testsDepTag) {
Colin Cross313aa542023-12-13 13:47:44 -080094 if _, ok := android.OtherModuleProvider(ctx, m, TestModuleProviderKey); !ok {
Aditya Choudhary9b593522023-10-06 19:54:58 +000095 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 }
Colin Cross31a67452023-11-02 16:57:08 -0700120 android.WriteFileRuleVerbatim(ctx, intermediatePath, string(protoData))
Aditya Choudhary9b593522023-10-06 19:54:58 +0000121
Colin Cross40213022023-12-13 15:19:49 -0800122 android.SetProvider(ctx,
Aditya Choudharyb7b3de82023-11-17 12:37:41 +0000123 TestSpecProviderKey, TestSpecProviderData{
Aditya Choudhary9b593522023-10-06 19:54:58 +0000124 IntermediatePath: intermediatePath,
125 },
126 )
127}