github.com/nya3jp/tast@v0.0.0-20230601000426-85c8e4d83a9b/src/go.chromium.org/tast/core/internal/testing/test.go (about) 1 // Copyright 2020 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package testing 6 7 import ( 8 "context" 9 "fmt" 10 "reflect" 11 "time" 12 13 "go.chromium.org/tast/core/internal/protocol" 14 "go.chromium.org/tast/core/testing/hwdep" 15 ) 16 17 const ( 18 // ExternalLinkSuffix is a file name suffix for external data link files. 19 // These are JSON files that can be unmarshaled into the externalLink struct. 20 ExternalLinkSuffix = ".external" 21 22 // ExternalErrorSuffix is a file name suffix for external data download error files. 23 // An error message is written to the file when we encounter an error downloading 24 // the corresponding external data file. This mechanism is used to pass errors from 25 // the test runner (which downloads the files) to the test bundle so the bundle 26 // can include them in the test's output. 27 ExternalErrorSuffix = ".external-error" 28 29 // ExternalURLSuffix is a file name suffix to store external data file's source url. 30 // It is used to perform staleness check for external files. If this file is present 31 // tast first refer this file to see if it has previously downloaded file from the 32 // url. If so then file is not downloaded again. This is useful in case when 33 // the artifact name in External data files does not change, however the 34 // buildartifactsurl cli flag changed, resulting in different source url. 35 ExternalURLSuffix = ".external-url" 36 ) 37 38 // TestFunc is the code associated with a test. 39 type TestFunc func(context.Context, *State) 40 41 // Test describes a registration of one or more test instances. 42 // 43 // Test can be passed to testing.AddTest to actually register test instances 44 // to the framework. 45 // 46 // In the most basic form where Params field is empty, Test describes exactly 47 // one test instance. If Params is not empty, multiple test instances are 48 // generated on registration by merging each testing.Param to the base Test. 49 type Test struct { 50 // Func is the function to be executed to perform the test. 51 Func TestFunc 52 53 // Desc is a short one-line description of the test. 54 Desc string 55 56 // Contacts is a list of email addresses of persons and groups who are familiar with the test. 57 // At least one personal email address of an active committer should be specified so that we can 58 // file bugs or ask for code reviews. 59 Contacts []string 60 61 // Attr contains freeform text attributes describing the test. 62 // See https://chromium.googlesource.com/chromiumos/platform/tast/+/HEAD/docs/test_attributes.md 63 // for commonly-used attributes. 64 Attr []string 65 66 // PrivateAttr contains freeform text private attributes describing the test. 67 // This should not be used other than Tast and tests. 68 // Note: this info is not retrievable in test results. 69 PrivateAttr []string 70 71 // SearchFlags contains key-value pairs describing the test. 72 // This information will be available in the test results, and can be used 73 // for custom test results filtering or any other mapping. 74 SearchFlags []*protocol.StringPair 75 76 // Data contains paths of data files needed by the test, relative to a "data" subdirectory within the 77 // directory in which Func is located. 78 Data []string 79 80 // Vars contains the names of runtime variables used to pass out-of-band data to tests. 81 // Values are supplied using "tast run -var=name=value", and tests can access values via State.Var. 82 Vars []string 83 84 // VarDeps serves similar purpose as Vars but lists runtime variables that 85 // are required to run the test. 86 // Whether test fails or skipped when runtime variables in VarDeps is 87 // missing is controlled by the flag -maybemissingvars for the Tast CLI. 88 // 89 // Tests should access runtime variables in VarDeps via State.RequiredVar. 90 VarDeps []string 91 92 // SoftwareDeps lists software features that are required to run the test. 93 // If any dependencies are not satisfied by the DUT, the test will be skipped. 94 // See https://chromium.googlesource.com/chromiumos/platform/tast/+/HEAD/docs/test_dependencies.md 95 // for more information about dependencies. 96 SoftwareDeps []string 97 98 // HardwareDeps describes hardware features and setup that are required to run the test. 99 HardwareDeps hwdep.Deps 100 101 // Pre contains a precondition that must be met before the test is run. 102 Pre Precondition 103 104 // Fixture is the name of the fixture the test depends on. 105 Fixture string 106 107 // Timeout contains the maximum duration for which Func may run before the test is aborted. 108 // This should almost always be set. If not specified, a reasonable default will be used, 109 // but tests should not depend on it. 110 // This field is serialized as an integer nanosecond count. 111 Timeout time.Duration 112 113 // Params lists the Param structs for parameterized tests. 114 Params []Param 115 116 // ServiceDeps contains a list of RPC service names in local test bundles that this remote test 117 // will access. This field is valid only for remote tests. 118 ServiceDeps []string 119 120 // LacrosStatus indicates whether lacros variants have been considered for this test or not. 121 LacrosStatus LacrosMetadata 122 123 // SoftwareDepsForAll lists software features of all DUTs that 124 // are required to run the test. 125 // It is a map of companion roles and software features. 126 // The role for primary DUT should be "". 127 // The primary DUT software dependency will be the union of 128 // SoftwareDeps and SoftwareDepsForAll[""]. 129 // If any dependencies are not satisfied, the test will be skipped. 130 SoftwareDepsForAll map[string][]string 131 132 // HardwareDepsForAll describes hardware features and setup of all 133 // DUTs that are required to run the test. 134 // It is a map of companion roles and hardware features. 135 // The role for primary DUT should be "". 136 // The primary DUT hardware dependency will be the union of 137 // HardwareDeps and HardwareDepsForAll[""]. 138 // If any dependencies are not satisfied, the test will be skipped. 139 HardwareDepsForAll map[string]hwdep.Deps 140 141 // Fields after this line are used for automation purposes only, tests should not use 142 // these fields. 143 144 // TestBedDeps are used for defining test bed dependencies only, i.e., 'carrier:verizon'. 145 // These are not used by tests themselves, but added to test metadata definitions used by 146 // infra services. 147 TestBedDeps []string 148 149 // Requirements are used for linking test cases to requirements. These are not used by 150 // tests themselves, but added to test metadata definitions used by infra services. 151 Requirements []string 152 153 // Bug component id for filing bugs against this test, i.e. 'b:1234'. This field is not 154 // to be used by tests themselves, but added to test metadata definitions used by infra services. 155 BugComponent string 156 } 157 158 // LacrosMetadata indicates whether lacros variants have been considered for this test or not. 159 type LacrosMetadata int 160 161 const ( 162 // LacrosVariantUnknown indicates that this test has not yet been checked as to whether it requires a lacros variant. 163 // New tests should not use this value, i.e. new tests should always consider lacros. 164 LacrosVariantUnknown = iota 165 // LacrosVariantNeeded indicates that a lacros variant for this is needed but hasn't been created yet. 166 LacrosVariantNeeded 167 // LacrosVariantExists indicates that all required lacros variants for this test have been created. 168 LacrosVariantExists 169 // LacrosVariantUnneeded indicates that lacros variants for this test are not needed. 170 LacrosVariantUnneeded 171 ) 172 173 func (m LacrosMetadata) String() string { 174 switch m { 175 case LacrosVariantUnknown: 176 return "unknown" 177 case LacrosVariantNeeded: 178 return "needed" 179 case LacrosVariantExists: 180 return "exists" 181 case LacrosVariantUnneeded: 182 return "unneeded" 183 default: 184 return fmt.Sprintf("unexpected value (%d)", int(m)) 185 } 186 } 187 188 // Param defines parameters for a parameterized test case. 189 // See also https://chromium.googlesource.com/chromiumos/platform/tast/+/HEAD/docs/writing_tests.md#Parameterized-tests 190 type Param struct { 191 // Name is the name of this parameterized test. 192 // Full name of the test case will be category.TestFuncName.param_name, 193 // or category.TestFuncName if Name is empty. 194 // Name should match with [a-z0-9_]*. 195 Name string 196 197 // ExtraAttr contains freeform text attributes describing the test, 198 // in addition to Attr declared in the enclosing Test. 199 ExtraAttr []string 200 201 // ExtraPrivateAttr contains freeform text private attributes describing the test, 202 // in addition to PrivateAttr declared in the enclosing Test. 203 ExtraPrivateAttr []string 204 205 // ExtraSearchFlags contains name-value pairs describing the test, 206 // in addition to SearchFlags declared in the enclosing Test. 207 ExtraSearchFlags []*protocol.StringPair 208 209 // ExtraData contains paths of data files needed by the test case of this 210 // param in addition to Data declared in the enclosing Test. 211 ExtraData []string 212 213 // ExtraSoftwareDeps lists software features that are required to run the test case for this param, 214 // in addition to SoftwareDeps in the enclosing Test. 215 ExtraSoftwareDeps []string 216 217 // ExtraHardwareDeps describes hardware features and setup that are required to run the test for this 218 // param, in addition to HardwareDeps in the enclosing Test. 219 ExtraHardwareDeps hwdep.Deps 220 221 // ExtraRequirements are used for linking test cases to requirements. These are not used by 222 // tests themselves, but added to test metadata definitions used by infra services. This slice is 223 // appended to an Requirements declared by the test. 224 ExtraRequirements []string 225 226 // Pre contains a precondition that must be met before the test is run. 227 // Can only be set if the enclosing test doesn't have one already set. 228 Pre Precondition 229 230 // Fixture is the name of the fixture the test depends on. 231 // Can only be set if the enclosing test doesn't have one already set. 232 Fixture string 233 234 // Timeout contains the maximum duration for which Func may run before the test is aborted. 235 // Can only be set if the enclosing test doesn't have one already set. 236 Timeout time.Duration 237 238 // Val is the value which can be retrieved from testing.State.Param() method. 239 Val interface{} 240 241 // ExtraSoftwareDepsForAll lists software features of all DUTs 242 // that are required to run the test case for this param, 243 // in addition to SoftwareDepsForAll in the enclosing Test. 244 // The primary DUT software dependency will be the union of 245 // SoftwareDeps, SoftwareDepsForAll[""], ExtraSoftwareDeps and 246 // ExtraSoftwareDepsForAll[""]. 247 // It is a map of companion roles and software features. 248 ExtraSoftwareDepsForAll map[string][]string 249 250 // ExtraHardwareDepsForAll describes hardware features and setup 251 // companion DUTs that are required to run the test case for this param, 252 // in addition to HardwareDepsForAll in the enclosing Test. 253 // It is a map of companion roles and hardware features. 254 // The role for primary DUT should be "" 255 // The primary DUT hardware dependency will be the union of 256 // HardwareDeps, HardwareDepsForAll[""], ExtraHardwareDeps and 257 // ExtraHardwareDep and ExtraHardwareDepsForAll[""]. 258 ExtraHardwareDepsForAll map[string]hwdep.Deps 259 260 // BugComponent overrides BugComponent defined in the test. 261 // This field is for infra/external use only and should not be used 262 // or referenced within the test code.. 263 BugComponent string 264 } 265 266 // validate performs initial validations of Test. 267 // Most validations are done while constructing TestInstance from a combination 268 // of Test and Param in newTestInstance, not in this method, so that we can 269 // validate fields of the final products. However some validations can be done 270 // only in this method, e.g. checking consistencies among multiple parameters. 271 func (t *Test) validate() error { 272 if err := validateParams(t.Params); err != nil { 273 return err 274 } 275 return nil 276 } 277 278 func validateParams(params []Param) error { 279 if len(params) == 0 { 280 return nil 281 } 282 283 // Ensure unique param name. 284 seen := make(map[string]struct{}) 285 for _, p := range params { 286 name := p.Name 287 if _, ok := seen[name]; ok { 288 return fmt.Errorf("duplicate param name is found: %s", name) 289 } 290 seen[name] = struct{}{} 291 } 292 293 // Ensure all value assigned to Val should have the same type. 294 typ0 := reflect.TypeOf(params[0].Val) 295 for _, p := range params { 296 typ := reflect.TypeOf(p.Val) 297 if typ != typ0 { 298 return fmt.Errorf("unmatched Val type: got %v; want %v", typ, typ0) 299 } 300 } 301 302 return nil 303 }