gitee.com/leisunstar/runtime@v0.0.0-20200521203717-5cef3e7b53f9/pkg/katatestutils/constraints_api.go (about) 1 // Copyright (c) 2019 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 6 // This file contains the public API for the test constraints facility. 7 8 package katatestutils 9 10 import ( 11 "os" 12 "strings" 13 ) 14 15 // Operator represents an operator to apply to a test constraint value. 16 type Operator int 17 18 const ( 19 eqOperator Operator = iota 20 geOperator Operator = iota 21 gtOperator Operator = iota 22 leOperator Operator = iota 23 ltOperator Operator = iota 24 neOperator Operator = iota 25 ) 26 27 // Constraints encapsulates all information about a test constraint. 28 type Constraints struct { 29 Issue string 30 31 UID int 32 33 // Not ideal: set when UID needs to be checked. This allows 34 // a test for UID 0 to be detected. 35 UIDSet bool 36 37 // DistroName is the name of a distro in all lower-case letters. 38 DistroName string 39 40 // DistroVersion is the version of the particular distro in string 41 // format. It may contain periods and dashes. 42 DistroVersion string 43 44 // KernelVersion is the version of a particular kernel. 45 KernelVersion string 46 47 // Operator is the operator to apply to one of the constraints. 48 Operator Operator 49 } 50 51 // Constraint is a function that operates on a Constraints object to set 52 // particular values. 53 type Constraint func(c *Constraints) 54 55 // TestConstraint records details about test constraints. 56 type TestConstraint struct { 57 Debug bool 58 59 // Effective user ID of running test 60 ActualEUID int 61 62 DistroName string 63 DistroVersion string 64 KernelVersion string 65 66 // Used to record all passed and failed constraints in 67 // human-readable form. 68 Passed []Result 69 Failed []Result 70 71 // Optionally used to record an issue number that relates to the 72 // constraint. 73 Issue string 74 } 75 76 // NewKataTest creates a new TestConstraint object and is the main interface 77 // to the test constraints feature. 78 func NewTestConstraint(debug bool) TestConstraint { 79 distroName, distroVersion, err := getDistroDetails() 80 if err != nil { 81 panic(err) 82 } 83 84 kernelVersion, err := getKernelVersion() 85 if err != nil { 86 panic(err) 87 } 88 89 return TestConstraint{ 90 Debug: debug, 91 92 ActualEUID: os.Geteuid(), 93 DistroName: distroName, 94 DistroVersion: distroVersion, 95 KernelVersion: kernelVersion, 96 } 97 } 98 99 // NotValid checks if the specified list of constraints are all valid, 100 // returning true if any _fail_. 101 // 102 // Notes: 103 // 104 // - Constraints are applied in the order specified. 105 // - A constraint type (user, distro) can only be specified once. 106 // - If the function fails to determine whether it can check the constraints, 107 // it will panic. Since this is facility is used for testing, this seems like 108 // the best approach as it unburdens the caller from checking for an error 109 // (which should never be ignored). 110 func (tc *TestConstraint) NotValid(constraints ...Constraint) bool { 111 if len(constraints) == 0 { 112 panic("need atleast one constraint") 113 } 114 115 // Reset in case of a previous call 116 tc.Passed = nil 117 tc.Failed = nil 118 tc.Issue = "" 119 120 for _, c := range constraints { 121 valid := tc.constraintValid(c) 122 if !valid { 123 return true 124 } 125 } 126 127 return false 128 } 129 130 // NeedUID skips the test unless running as a user with the specified user ID. 131 func NeedUID(uid int, op Operator) Constraint { 132 return func(c *Constraints) { 133 c.Operator = op 134 c.UID = uid 135 c.UIDSet = true 136 } 137 } 138 139 // NeedNonRoot skips the test unless running as root. 140 func NeedRoot() Constraint { 141 return NeedUID(0, eqOperator) 142 } 143 144 // NeedNonRoot skips the test if running as the root user. 145 func NeedNonRoot() Constraint { 146 return NeedUID(0, neOperator) 147 } 148 149 // NeedDistroWithOp skips the test unless the distro constraint specified by 150 // the arguments is true. 151 func NeedDistroWithOp(distro string, op Operator) Constraint { 152 return func(c *Constraints) { 153 c.DistroName = strings.ToLower(distro) 154 c.Operator = op 155 } 156 } 157 158 // NeedDistroEquals will skip the test unless running on the specified distro. 159 func NeedDistroEquals(distro string) Constraint { 160 return NeedDistroWithOp(distro, eqOperator) 161 } 162 163 // NeedDistroNotEquals will skip the test unless run a distro that does not 164 // match the specified name. 165 func NeedDistroNotEquals(distro string) Constraint { 166 return NeedDistroWithOp(distro, neOperator) 167 } 168 169 // NeedDistro will skip the test unless running on the specified distro. 170 func NeedDistro(distro string) Constraint { 171 return NeedDistroEquals(distro) 172 } 173 174 // NeedDistroVersionWithOp skips the test unless the distro version constraint 175 // specified by the arguments is true. 176 // 177 // Note: distro versions vary in format. 178 func NeedDistroVersionWithOp(version string, op Operator) Constraint { 179 return func(c *Constraints) { 180 c.DistroVersion = version 181 c.Operator = op 182 } 183 } 184 185 // NeedDistroVersionEquals will skip the test unless the distro version is the 186 // same as the specified version. 187 // 188 // Note: distro versions vary in format. 189 func NeedDistroVersionEquals(version string) Constraint { 190 return NeedDistroVersionWithOp(version, eqOperator) 191 } 192 193 // NeedDistroVersionNotEquals will skip the test unless the distro version is 194 // different to the specified version. 195 // 196 // Note: distro versions vary in format. 197 func NeedDistroVersionNotEquals(version string) Constraint { 198 return NeedDistroVersionWithOp(version, neOperator) 199 } 200 201 // NeedDistroVersionLE will skip the test unless the distro version is older 202 // than or the same as the specified version. 203 // 204 // Note: distro versions vary in format. 205 func NeedDistroVersionLE(version string) Constraint { 206 return NeedDistroVersionWithOp(version, leOperator) 207 } 208 209 // NeedDistroVersionLT will skip the test unless the distro version is older 210 // than the specified version. 211 // 212 // Note: distro versions vary in format. 213 func NeedDistroVersionLT(version string) Constraint { 214 return NeedDistroVersionWithOp(version, ltOperator) 215 } 216 217 // NeedDistroVersionGE will skip the test unless the distro version is newer 218 // than or the same as the specified version. 219 // 220 // Note: distro versions vary in format. 221 func NeedDistroVersionGE(version string) Constraint { 222 return NeedDistroVersionWithOp(version, geOperator) 223 } 224 225 // NeedDistroVersionGT will skip the test unless the distro version is newer 226 // than the specified version. 227 // 228 // Note: distro versions vary in format. 229 func NeedDistroVersionGT(version string) Constraint { 230 return NeedDistroVersionWithOp(version, gtOperator) 231 } 232 233 // NeedDistroVersion will skip the test unless running on the specified 234 // (exact) version of some distro. 235 // 236 // Note: distro versions vary in format. 237 func NeedDistroVersion(version string) Constraint { 238 return NeedDistroVersionEquals(version) 239 } 240 241 // NeedKernelVersionWithOp skips the test unless the distro version constraint 242 // specified by the arguments is true. 243 func NeedKernelVersionWithOp(version string, op Operator) Constraint { 244 return func(c *Constraints) { 245 c.KernelVersion = version 246 c.Operator = op 247 } 248 } 249 250 // NeedKernelVersionLT will skip the test unless the distro version is older 251 // than the specified version. 252 func NeedKernelVersionEquals(version string) Constraint { 253 return NeedKernelVersionWithOp(version, eqOperator) 254 } 255 256 // NeedKernelVersionNotEquals will skip the test unless the distro version is 257 // different to the specified version. 258 func NeedKernelVersionNotEquals(version string) Constraint { 259 return NeedKernelVersionWithOp(version, neOperator) 260 } 261 262 // NeedKernelVersionLT will skip the test unless the distro version is older 263 // than the specified version. 264 // 265 // Note: distro versions vary in format. 266 func NeedKernelVersionLT(version string) Constraint { 267 return NeedKernelVersionWithOp(version, ltOperator) 268 } 269 270 // NeedKernelVersionLE will skip the test unless the distro version is older 271 // than or the same as the specified version. 272 // 273 // Note: distro versions vary in format. 274 func NeedKernelVersionLE(version string) Constraint { 275 return NeedKernelVersionWithOp(version, leOperator) 276 } 277 278 // NeedKernelVersionGT will skip the test unless the distro version is newer 279 // than the specified version. 280 // 281 // Note: distro versions vary in format. 282 func NeedKernelVersionGT(version string) Constraint { 283 return NeedKernelVersionWithOp(version, gtOperator) 284 } 285 286 // NeedKernelVersionGE will skip the test unless the distro version is newer 287 // than or the same as the specified version. 288 // 289 // Note: distro versions vary in format. 290 func NeedKernelVersionGE(version string) Constraint { 291 return NeedKernelVersionWithOp(version, geOperator) 292 } 293 294 // NeedKernelVersion will skip the test unless running on the specified 295 // (exact) version of some distro. 296 // 297 // Note: distro versions vary in format. 298 func NeedKernelVersion(version string) Constraint { 299 return NeedKernelVersionEquals(version) 300 } 301 302 // WithIssue allows the specification of an issue URL. 303 // 304 // Note that the issue is not checked for validity. 305 func WithIssue(issue string) Constraint { 306 return func(c *Constraints) { 307 c.Issue = issue 308 } 309 }