gitee.com/mysnapcore/mysnapd@v0.1.0/asserts/export_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2015-2022 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package asserts 21 22 import ( 23 "io" 24 "time" 25 26 "gitee.com/mysnapcore/mysnapd/asserts/internal" 27 ) 28 29 // expose test-only things here 30 31 var NumAssertionType int 32 33 func init() { 34 NumAssertionType = len(typeRegistry) 35 } 36 37 // v1FixedTimestamp exposed for tests 38 var V1FixedTimestamp = v1FixedTimestamp 39 40 // assembleAndSign exposed for tests 41 var AssembleAndSignInTest = assembleAndSign 42 43 // decodePrivateKey exposed for tests 44 var DecodePrivateKeyInTest = decodePrivateKey 45 46 // NewDecoderStressed makes a Decoder with a stressed setup with the given buffer and maximum sizes. 47 func NewDecoderStressed(r io.Reader, bufSize, maxHeadersSize, maxBodySize, maxSigSize int) *Decoder { 48 return (&Decoder{ 49 rd: r, 50 initialBufSize: bufSize, 51 maxHeadersSize: maxHeadersSize, 52 maxSigSize: maxSigSize, 53 defaultMaxBodySize: maxBodySize, 54 }).initBuffer() 55 } 56 57 func BootstrapAccountForTest(authorityID string) *Account { 58 return &Account{ 59 assertionBase: assertionBase{ 60 headers: map[string]interface{}{ 61 "type": "account", 62 "authority-id": authorityID, 63 "account-id": authorityID, 64 "validation": "verified", 65 }, 66 }, 67 timestamp: time.Now().UTC(), 68 } 69 } 70 71 func MakeAccountKeyForTest(authorityID string, openPGPPubKey PublicKey, since time.Time, validYears int) *AccountKey { 72 return MakeAccountKeyForTestWithUntil(authorityID, openPGPPubKey, since, since.AddDate(validYears, 0, 0), validYears) 73 } 74 75 func MakeAccountKeyForTestWithUntil(authorityID string, openPGPPubKey PublicKey, since, until time.Time, validYears int) *AccountKey { 76 return &AccountKey{ 77 assertionBase: assertionBase{ 78 headers: map[string]interface{}{ 79 "type": "account-key", 80 "authority-id": authorityID, 81 "account-id": authorityID, 82 "public-key-sha3-384": openPGPPubKey.ID(), 83 }, 84 }, 85 sinceUntil: sinceUntil{ 86 since: since.UTC(), 87 until: until.UTC(), 88 }, 89 pubKey: openPGPPubKey, 90 } 91 } 92 93 func BootstrapAccountKeyForTest(authorityID string, pubKey PublicKey) *AccountKey { 94 return MakeAccountKeyForTest(authorityID, pubKey, time.Time{}, 9999) 95 } 96 97 func ExpiredAccountKeyForTest(authorityID string, pubKey PublicKey) *AccountKey { 98 return MakeAccountKeyForTest(authorityID, pubKey, time.Time{}, 1) 99 } 100 101 func MockTimeNow(t time.Time) (restore func()) { 102 oldTimeNow := timeNow 103 timeNow = func() time.Time { 104 return t 105 } 106 return func() { 107 timeNow = oldTimeNow 108 } 109 } 110 111 // define test assertion types to use in the tests 112 113 type TestOnly struct { 114 assertionBase 115 } 116 117 func assembleTestOnly(assert assertionBase) (Assertion, error) { 118 // for testing error cases 119 if _, err := checkIntWithDefault(assert.headers, "count", 0); err != nil { 120 return nil, err 121 } 122 return &TestOnly{assert}, nil 123 } 124 125 var TestOnlyType = &AssertionType{"test-only", []string{"primary-key"}, nil, assembleTestOnly, 0} 126 127 type TestOnly2 struct { 128 assertionBase 129 } 130 131 func assembleTestOnly2(assert assertionBase) (Assertion, error) { 132 return &TestOnly2{assert}, nil 133 } 134 135 var TestOnly2Type = &AssertionType{"test-only-2", []string{"pk1", "pk2"}, nil, assembleTestOnly2, 0} 136 137 // TestOnlyDecl is a test-only assertion that mimics snap-declaration 138 // relations with other assertions. 139 type TestOnlyDecl struct { 140 assertionBase 141 } 142 143 func (dcl *TestOnlyDecl) ID() string { 144 return dcl.HeaderString("id") 145 } 146 147 func (dcl *TestOnlyDecl) DevID() string { 148 return dcl.HeaderString("dev-id") 149 } 150 151 func (dcl *TestOnlyDecl) Prerequisites() []*Ref { 152 return []*Ref{ 153 {Type: AccountType, PrimaryKey: []string{dcl.DevID()}}, 154 } 155 } 156 157 func assembleTestOnlyDecl(assert assertionBase) (Assertion, error) { 158 return &TestOnlyDecl{assert}, nil 159 } 160 161 var TestOnlyDeclType = &AssertionType{"test-only-decl", []string{"id"}, nil, assembleTestOnlyDecl, 0} 162 163 // TestOnlyRev is a test-only assertion that mimics snap-revision 164 // relations with other assertions. 165 type TestOnlyRev struct { 166 assertionBase 167 } 168 169 func (rev *TestOnlyRev) H() string { 170 return rev.HeaderString("h") 171 } 172 173 func (rev *TestOnlyRev) ID() string { 174 return rev.HeaderString("id") 175 } 176 177 func (rev *TestOnlyRev) DevID() string { 178 return rev.HeaderString("dev-id") 179 } 180 181 func (rev *TestOnlyRev) Prerequisites() []*Ref { 182 return []*Ref{ 183 {Type: TestOnlyDeclType, PrimaryKey: []string{rev.ID()}}, 184 {Type: AccountType, PrimaryKey: []string{rev.DevID()}}, 185 } 186 } 187 188 func assembleTestOnlyRev(assert assertionBase) (Assertion, error) { 189 return &TestOnlyRev{assert}, nil 190 } 191 192 var TestOnlyRevType = &AssertionType{"test-only-rev", []string{"h"}, nil, assembleTestOnlyRev, 0} 193 194 // TestOnlySeq is a test-only assertion that is sequence-forming. 195 type TestOnlySeq struct { 196 assertionBase 197 seq int 198 } 199 200 func (seq *TestOnlySeq) N() string { 201 return seq.HeaderString("n") 202 } 203 204 func (seq *TestOnlySeq) Sequence() int { 205 return seq.seq 206 } 207 208 func assembleTestOnlySeq(assert assertionBase) (Assertion, error) { 209 seq, err := checkSequence(assert.headers, "sequence") 210 if err != nil { 211 return nil, err 212 } 213 return &TestOnlySeq{ 214 assertionBase: assert, 215 seq: seq, 216 }, nil 217 } 218 219 var TestOnlySeqType = &AssertionType{"test-only-seq", []string{"n", "sequence"}, nil, assembleTestOnlySeq, sequenceForming} 220 221 type TestOnlyNoAuthority struct { 222 assertionBase 223 } 224 225 func assembleTestOnlyNoAuthority(assert assertionBase) (Assertion, error) { 226 if _, err := checkNotEmptyString(assert.headers, "hdr"); err != nil { 227 return nil, err 228 } 229 return &TestOnlyNoAuthority{assert}, nil 230 } 231 232 var TestOnlyNoAuthorityType = &AssertionType{"test-only-no-authority", nil, nil, assembleTestOnlyNoAuthority, noAuthority} 233 234 type TestOnlyNoAuthorityPK struct { 235 assertionBase 236 } 237 238 func assembleTestOnlyNoAuthorityPK(assert assertionBase) (Assertion, error) { 239 return &TestOnlyNoAuthorityPK{assert}, nil 240 } 241 242 var TestOnlyNoAuthorityPKType = &AssertionType{"test-only-no-authority-pk", []string{"pk"}, nil, assembleTestOnlyNoAuthorityPK, noAuthority} 243 244 func init() { 245 typeRegistry[TestOnlyType.Name] = TestOnlyType 246 maxSupportedFormat[TestOnlyType.Name] = 1 247 typeRegistry[TestOnly2Type.Name] = TestOnly2Type 248 typeRegistry[TestOnlyNoAuthorityType.Name] = TestOnlyNoAuthorityType 249 typeRegistry[TestOnlyNoAuthorityPKType.Name] = TestOnlyNoAuthorityPKType 250 formatAnalyzer[TestOnlyType] = func(headers map[string]interface{}, _ []byte) (int, error) { 251 if _, ok := headers["format-1-feature"]; ok { 252 return 1, nil 253 } 254 return 0, nil 255 } 256 typeRegistry[TestOnlyDeclType.Name] = TestOnlyDeclType 257 typeRegistry[TestOnlyRevType.Name] = TestOnlyRevType 258 typeRegistry[TestOnlySeqType.Name] = TestOnlySeqType 259 maxSupportedFormat[TestOnlySeqType.Name] = 2 260 } 261 262 // AccountKeyIsKeyValidAt exposes isKeyValidAt on AccountKey for tests 263 func AccountKeyIsKeyValidAt(ak *AccountKey, when time.Time) bool { 264 return ak.isValidAt(when) 265 } 266 267 type sinceUntilLike interface { 268 isValidAssumingCurTimeWithin(earliest, latest time.Time) bool 269 } 270 271 // IsValidAssumingCurTimeWithin exposes sinceUntil.isValidAssumingCurTimeWithin 272 func IsValidAssumingCurTimeWithin(su sinceUntilLike, earliest, latest time.Time) bool { 273 return su.isValidAssumingCurTimeWithin(earliest, latest) 274 } 275 276 type GPGRunner func(input []byte, args ...string) ([]byte, error) 277 278 func MockRunGPG(mock func(prev GPGRunner, input []byte, args ...string) ([]byte, error)) (restore func()) { 279 prevRunGPG := runGPG 280 runGPG = func(input []byte, args ...string) ([]byte, error) { 281 return mock(prevRunGPG, input, args...) 282 } 283 return func() { 284 runGPG = prevRunGPG 285 } 286 } 287 288 func GPGBatchYes() (restore func()) { 289 gpgBatchYes = true 290 return func() { 291 gpgBatchYes = false 292 } 293 } 294 295 // Headers helpers to test 296 var ( 297 ParseHeaders = parseHeaders 298 AppendEntry = appendEntry 299 ) 300 301 // ParametersForGenerate exposes parametersForGenerate for tests. 302 func (gkm *GPGKeypairManager) ParametersForGenerate(passphrase string, name string) string { 303 return gkm.parametersForGenerate(passphrase, name) 304 } 305 306 // constraint tests 307 308 func CompileAttrMatcher(constraints interface{}, allowedOperations []string) (func(attrs map[string]interface{}, helper AttrMatchContext) error, error) { 309 // XXX adjust 310 cc := compileContext{ 311 opts: &compileAttrMatcherOptions{ 312 allowedOperations: allowedOperations, 313 }, 314 } 315 matcher, err := compileAttrMatcher(cc, constraints) 316 if err != nil { 317 return nil, err 318 } 319 domatch := func(attrs map[string]interface{}, helper AttrMatchContext) error { 320 return matcher.match("", attrs, &attrMatchingContext{ 321 attrWord: "field", 322 helper: helper, 323 }) 324 } 325 return domatch, nil 326 } 327 328 var ( 329 CompileDeviceScopeConstraint = compileDeviceScopeConstraint 330 ) 331 332 // ifacedecls tests 333 var ( 334 CompileAttributeConstraints = compileAttributeConstraints 335 CompileNameConstraints = compileNameConstraints 336 CompilePlugRule = compilePlugRule 337 CompileSlotRule = compileSlotRule 338 ) 339 340 type featureExposer interface { 341 feature(flabel string) bool 342 } 343 344 func RuleFeature(rule featureExposer, flabel string) bool { 345 return rule.feature(flabel) 346 } 347 348 func (b *Batch) DoPrecheck(db *Database) error { 349 return b.precheck(db) 350 } 351 352 // pool tests 353 354 func MakePoolGrouping(elems ...uint16) Grouping { 355 return Grouping(internal.Serialize(elems)) 356 }