2023-10-06 21:54:58 +02:00
// Copyright 2020 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package testing
import (
"path/filepath"
"strconv"
"android/soong/android"
"android/soong/testing/test_spec_proto"
"google.golang.org/protobuf/proto"
2023-12-13 01:39:03 +01:00
"github.com/google/blueprint"
2023-10-06 21:54:58 +02:00
)
// ErrTestModuleDataNotFound is the error message for missing test module provider data.
const 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"
func TestSpecFactory ( ) android . Module {
module := & TestSpecModule { }
android . InitAndroidModule ( module )
android . InitDefaultableModule ( module )
module . AddProperties ( & module . properties )
return module
}
type TestSpecModule struct {
android . ModuleBase
android . DefaultableModuleBase
// Properties for "test_spec"
properties struct {
// Specifies the name of the test config.
Name string
// Specifies the team ID.
TeamId string
// Specifies the list of tests covered under this module.
Tests [ ] string
}
}
type testsDepTagType struct {
blueprint . BaseDependencyTag
}
var testsDepTag = testsDepTagType { }
func ( module * TestSpecModule ) DepsMutator ( ctx android . BottomUpMutatorContext ) {
// Validate Properties
if len ( module . properties . TeamId ) == 0 {
ctx . PropertyErrorf ( "TeamId" , "Team Id not found in the test_spec module. Hint: Maybe the TeamId property hasn't been properly specified." )
}
if ! isInt ( module . properties . TeamId ) {
ctx . PropertyErrorf ( "TeamId" , "Invalid value for Team ID. The Team ID must be an integer." )
}
if len ( module . properties . Tests ) == 0 {
ctx . PropertyErrorf ( "Tests" , "Expected to attribute some test but none found. Hint: Maybe the test property hasn't been properly specified." )
}
ctx . AddDependency ( ctx . Module ( ) , testsDepTag , module . properties . Tests ... )
}
func isInt ( s string ) bool {
_ , err := strconv . Atoi ( s )
return err == nil
}
// Provider published by TestSpec
2023-11-17 13:37:41 +01:00
type TestSpecProviderData struct {
2023-10-06 21:54:58 +02:00
IntermediatePath android . WritablePath
}
2023-12-13 01:39:03 +01:00
var TestSpecProviderKey = blueprint . NewProvider [ TestSpecProviderData ] ( )
2023-10-06 21:54:58 +02:00
type TestModuleProviderData struct {
}
2023-12-13 01:39:03 +01:00
var TestModuleProviderKey = blueprint . NewProvider [ TestModuleProviderData ] ( )
2023-10-06 21:54:58 +02:00
func ( module * TestSpecModule ) GenerateAndroidBuildActions ( ctx android . ModuleContext ) {
for _ , m := range ctx . GetDirectDepsWithTag ( testsDepTag ) {
2023-12-13 22:47:44 +01:00
if _ , ok := android . OtherModuleProvider ( ctx , m , TestModuleProviderKey ) ; ! ok {
2023-10-06 21:54:58 +02:00
ctx . ModuleErrorf ( ErrTestModuleDataNotFound , m . Name ( ) )
}
}
bpFilePath := filepath . Join ( ctx . ModuleDir ( ) , ctx . BlueprintsFile ( ) )
metadataList := make (
[ ] * test_spec_proto . TestSpec_OwnershipMetadata , 0 ,
len ( module . properties . Tests ) ,
)
for _ , test := range module . properties . Tests {
targetName := test
metadata := test_spec_proto . TestSpec_OwnershipMetadata {
TrendyTeamId : & module . properties . TeamId ,
TargetName : & targetName ,
Path : & bpFilePath ,
}
metadataList = append ( metadataList , & metadata )
}
intermediatePath := android . PathForModuleOut (
ctx , "intermediateTestSpecMetadata.pb" ,
)
testSpecMetadata := test_spec_proto . TestSpec { OwnershipMetadataList : metadataList }
protoData , err := proto . Marshal ( & testSpecMetadata )
if err != nil {
ctx . ModuleErrorf ( "Error: %s" , err . Error ( ) )
}
2023-11-03 00:57:08 +01:00
android . WriteFileRuleVerbatim ( ctx , intermediatePath , string ( protoData ) )
2023-10-06 21:54:58 +02:00
2023-12-14 00:19:49 +01:00
android . SetProvider ( ctx ,
2023-11-17 13:37:41 +01:00
TestSpecProviderKey , TestSpecProviderData {
2023-10-06 21:54:58 +02:00
IntermediatePath : intermediatePath ,
} ,
)
}