github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/asserts/snapasserts/validation_sets_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2020 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 snapasserts_test
    21  
    22  import (
    23  	"fmt"
    24  
    25  	. "gopkg.in/check.v1"
    26  
    27  	"github.com/snapcore/snapd/asserts"
    28  	"github.com/snapcore/snapd/asserts/assertstest"
    29  	"github.com/snapcore/snapd/asserts/snapasserts"
    30  )
    31  
    32  type validationSetsSuite struct{}
    33  
    34  var _ = Suite(&validationSetsSuite{})
    35  
    36  func (s *validationSetsSuite) TestAddFromSameSequence(c *C) {
    37  	mySnapAt7Valset := assertstest.FakeAssertion(map[string]interface{}{
    38  		"type":         "validation-set",
    39  		"authority-id": "account-id",
    40  		"series":       "16",
    41  		"account-id":   "account-id",
    42  		"name":         "my-snap-ctl",
    43  		"sequence":     "1",
    44  		"snaps": []interface{}{
    45  			map[string]interface{}{
    46  				"name":     "my-snap",
    47  				"id":       "mysnapididididididididididididid",
    48  				"presence": "required",
    49  				"revision": "7",
    50  			},
    51  		},
    52  	}).(*asserts.ValidationSet)
    53  
    54  	mySnapAt8Valset := assertstest.FakeAssertion(map[string]interface{}{
    55  		"type":         "validation-set",
    56  		"authority-id": "account-id",
    57  		"series":       "16",
    58  		"account-id":   "account-id",
    59  		"name":         "my-snap-ctl",
    60  		"sequence":     "2",
    61  		"snaps": []interface{}{
    62  			map[string]interface{}{
    63  				"name":     "my-snap",
    64  				"id":       "mysnapididididididididididididid",
    65  				"presence": "required",
    66  				"revision": "8",
    67  			},
    68  		},
    69  	}).(*asserts.ValidationSet)
    70  
    71  	valsets := snapasserts.NewValidationSets()
    72  	err := valsets.Add(mySnapAt7Valset)
    73  	c.Assert(err, IsNil)
    74  	err = valsets.Add(mySnapAt8Valset)
    75  	c.Check(err, ErrorMatches, `cannot add a second validation-set under "account-id/my-snap-ctl"`)
    76  }
    77  
    78  func (s *validationSetsSuite) TestIntersections(c *C) {
    79  	mySnapAt7Valset := assertstest.FakeAssertion(map[string]interface{}{
    80  		"type":         "validation-set",
    81  		"authority-id": "account-id",
    82  		"series":       "16",
    83  		"account-id":   "account-id",
    84  		"name":         "my-snap-ctl",
    85  		"sequence":     "1",
    86  		"snaps": []interface{}{
    87  			map[string]interface{}{
    88  				"name":     "my-snap",
    89  				"id":       "mysnapididididididididididididid",
    90  				"presence": "required",
    91  				"revision": "7",
    92  			},
    93  		},
    94  	}).(*asserts.ValidationSet)
    95  
    96  	mySnapAt7Valset2 := assertstest.FakeAssertion(map[string]interface{}{
    97  		"type":         "validation-set",
    98  		"authority-id": "account-id",
    99  		"series":       "16",
   100  		"account-id":   "account-id",
   101  		"name":         "my-snap-ctl2",
   102  		"sequence":     "2",
   103  		"snaps": []interface{}{
   104  			map[string]interface{}{
   105  				"name":     "my-snap",
   106  				"id":       "mysnapididididididididididididid",
   107  				"presence": "required",
   108  				"revision": "7",
   109  			},
   110  		},
   111  	}).(*asserts.ValidationSet)
   112  
   113  	mySnapAt8Valset := assertstest.FakeAssertion(map[string]interface{}{
   114  		"type":         "validation-set",
   115  		"authority-id": "account-id",
   116  		"series":       "16",
   117  		"account-id":   "account-id",
   118  		"name":         "my-snap-ctl-other",
   119  		"sequence":     "1",
   120  		"snaps": []interface{}{
   121  			map[string]interface{}{
   122  				"name":     "my-snap",
   123  				"id":       "mysnapididididididididididididid",
   124  				"presence": "required",
   125  				"revision": "8",
   126  			},
   127  		},
   128  	}).(*asserts.ValidationSet)
   129  
   130  	mySnapAt8OptValset := assertstest.FakeAssertion(map[string]interface{}{
   131  		"type":         "validation-set",
   132  		"authority-id": "account-id",
   133  		"series":       "16",
   134  		"account-id":   "account-id",
   135  		"name":         "my-snap-ctl-opt",
   136  		"sequence":     "1",
   137  		"snaps": []interface{}{
   138  			map[string]interface{}{
   139  				"name":     "my-snap",
   140  				"id":       "mysnapididididididididididididid",
   141  				"presence": "optional",
   142  				"revision": "8",
   143  			},
   144  		},
   145  	}).(*asserts.ValidationSet)
   146  
   147  	mySnapInvalidValset := assertstest.FakeAssertion(map[string]interface{}{
   148  		"type":         "validation-set",
   149  		"authority-id": "account-id",
   150  		"series":       "16",
   151  		"account-id":   "account-id",
   152  		"name":         "my-snap-ctl-inv",
   153  		"sequence":     "1",
   154  		"snaps": []interface{}{
   155  			map[string]interface{}{
   156  				"name":     "my-snap",
   157  				"id":       "mysnapididididididididididididid",
   158  				"presence": "invalid",
   159  			},
   160  		},
   161  	}).(*asserts.ValidationSet)
   162  
   163  	mySnapAt7OptValset := assertstest.FakeAssertion(map[string]interface{}{
   164  		"type":         "validation-set",
   165  		"authority-id": "account-id",
   166  		"series":       "16",
   167  		"account-id":   "account-id",
   168  		"name":         "my-snap-ctl-opt2",
   169  		"sequence":     "1",
   170  		"snaps": []interface{}{
   171  			map[string]interface{}{
   172  				"name":     "my-snap",
   173  				"id":       "mysnapididididididididididididid",
   174  				"presence": "optional",
   175  				"revision": "7",
   176  			},
   177  		},
   178  	}).(*asserts.ValidationSet)
   179  
   180  	mySnapReqValset := assertstest.FakeAssertion(map[string]interface{}{
   181  		"type":         "validation-set",
   182  		"authority-id": "account-id",
   183  		"series":       "16",
   184  		"account-id":   "account-id",
   185  		"name":         "my-snap-ctl-req-only",
   186  		"sequence":     "1",
   187  		"snaps": []interface{}{
   188  			map[string]interface{}{
   189  				"name":     "my-snap",
   190  				"id":       "mysnapididididididididididididid",
   191  				"presence": "required",
   192  			},
   193  		},
   194  	}).(*asserts.ValidationSet)
   195  
   196  	mySnapOptValset := assertstest.FakeAssertion(map[string]interface{}{
   197  		"type":         "validation-set",
   198  		"authority-id": "account-id",
   199  		"series":       "16",
   200  		"account-id":   "account-id",
   201  		"name":         "my-snap-ctl-opt-only",
   202  		"sequence":     "1",
   203  		"snaps": []interface{}{
   204  			map[string]interface{}{
   205  				"name":     "my-snap",
   206  				"id":       "mysnapididididididididididididid",
   207  				"presence": "optional",
   208  			},
   209  		},
   210  	}).(*asserts.ValidationSet)
   211  
   212  	tests := []struct {
   213  		sets        []*asserts.ValidationSet
   214  		conflictErr string
   215  	}{
   216  		{[]*asserts.ValidationSet{mySnapAt7Valset}, ""},
   217  		{[]*asserts.ValidationSet{mySnapAt7Valset, mySnapAt7Valset2}, ""},
   218  		{[]*asserts.ValidationSet{mySnapAt7Valset, mySnapAt8Valset}, `(?ms)validation sets are in conflict:.*cannot constrain snap "my-snap" at different revisions 7 \(account-id/my-snap-ctl\), 8 \(account-id/my-snap-ctl-other\)`},
   219  		{[]*asserts.ValidationSet{mySnapAt8Valset, mySnapAt8OptValset}, ""},
   220  		{[]*asserts.ValidationSet{mySnapAt7Valset, mySnapAt8OptValset}, `(?ms)validation sets are in conflict:.*cannot constrain snap "my-snap" at different revisions 7 \(account-id/my-snap-ctl\), 8 \(account-id/my-snap-ctl-opt\)`},
   221  		{[]*asserts.ValidationSet{mySnapAt7Valset, mySnapInvalidValset}, `(?ms)validation sets are in conflict:.*cannot constrain snap "my-snap" as both invalid \(account-id/my-snap-ctl-inv\) and required at revision 7 \(account-id/my-snap-ctl\)`},
   222  		{[]*asserts.ValidationSet{mySnapInvalidValset, mySnapAt7Valset}, `(?ms)validation sets are in conflict:.*cannot constrain snap "my-snap" as both invalid \(account-id/my-snap-ctl-inv\) and required at revision 7 \(account-id/my-snap-ctl\)`},
   223  		{[]*asserts.ValidationSet{mySnapAt8OptValset, mySnapInvalidValset}, ""},
   224  		{[]*asserts.ValidationSet{mySnapInvalidValset, mySnapAt8OptValset}, ""},
   225  		{[]*asserts.ValidationSet{mySnapAt7OptValset, mySnapAt8OptValset}, ""}, // no conflict but interpreted as invalid
   226  		{[]*asserts.ValidationSet{mySnapAt7OptValset, mySnapAt8OptValset, mySnapAt7Valset}, `(?ms)validation sets are in conflict:.*cannot constrain snap "my-snap" at different revisions 7 \(account-id/my-snap-ctl,account-id/my-snap-ctl-opt2\), 8 \(account-id/my-snap-ctl-opt\)`},
   227  		{[]*asserts.ValidationSet{mySnapAt8OptValset, mySnapInvalidValset, mySnapAt7Valset}, `(?ms)validation sets are in conflict:.*cannot constrain snap "my-snap" as both invalid \(account-id/my-snap-ctl-inv\) and required at different revisions 7 \(account-id/my-snap-ctl\), 8 \(account-id/my-snap-ctl-opt\)`},
   228  		{[]*asserts.ValidationSet{mySnapAt7Valset, mySnapReqValset}, ""},
   229  		{[]*asserts.ValidationSet{mySnapReqValset, mySnapAt7Valset}, ""},
   230  		{[]*asserts.ValidationSet{mySnapAt8OptValset, mySnapReqValset}, ""},
   231  		{[]*asserts.ValidationSet{mySnapAt8OptValset, mySnapReqValset, mySnapAt7OptValset}, `(?ms)validation sets are in conflict:.*cannot constrain snap "my-snap" at different revisions 7 \(account-id/my-snap-ctl-opt2\), 8 \(account-id/my-snap-ctl-opt\) or required at any revision \(account-id/my-snap-ctl-req-only\)`},
   232  		{[]*asserts.ValidationSet{mySnapAt8OptValset, mySnapAt7OptValset, mySnapReqValset}, `(?ms)validation sets are in conflict:.*cannot constrain snap "my-snap" at different revisions 7 \(account-id/my-snap-ctl-opt2\), 8 \(account-id/my-snap-ctl-opt\) or required at any revision \(account-id/my-snap-ctl-req-only\)`},
   233  		{[]*asserts.ValidationSet{mySnapReqValset, mySnapInvalidValset}, `(?ms)validation sets are in conflict:.*cannot constrain snap "my-snap" as both invalid \(account-id/my-snap-ctl-inv\) and required at any revision \(account-id/my-snap-ctl-req-only\)`},
   234  		{[]*asserts.ValidationSet{mySnapInvalidValset, mySnapReqValset}, `(?ms)validation sets are in conflict:.*cannot constrain snap "my-snap" as both invalid \(account-id/my-snap-ctl-inv\) and required at any revision \(account-id/my-snap-ctl-req-only\)`},
   235  		{[]*asserts.ValidationSet{mySnapAt7Valset, mySnapAt8Valset, mySnapOptValset}, `(?ms)validation sets are in conflict:.*cannot constrain snap "my-snap" at different revisions 7 \(account-id/my-snap-ctl\), 8 \(account-id/my-snap-ctl-other\)`},
   236  		{[]*asserts.ValidationSet{mySnapAt7Valset, mySnapOptValset}, ""},
   237  		{[]*asserts.ValidationSet{mySnapOptValset, mySnapAt7Valset}, ""},
   238  		{[]*asserts.ValidationSet{mySnapAt8OptValset, mySnapOptValset}, ""},
   239  		{[]*asserts.ValidationSet{mySnapAt8OptValset, mySnapOptValset, mySnapAt7OptValset}, ""}, // no conflict but interpreted as invalid
   240  		{[]*asserts.ValidationSet{mySnapInvalidValset, mySnapOptValset}, ""},
   241  		{[]*asserts.ValidationSet{mySnapOptValset, mySnapInvalidValset}, ""},
   242  		{[]*asserts.ValidationSet{mySnapAt7Valset, mySnapAt8Valset, mySnapReqValset, mySnapInvalidValset}, `(?ms)validation sets are in conflict:.*cannot constrain snap "my-snap" as both invalid \(account-id/my-snap-ctl-inv\) and required at different revisions 7 \(account-id/my-snap-ctl\), 8 \(account-id/my-snap-ctl-other\) or at any revision \(account-id/my-snap-ctl-req-only\)`},
   243  	}
   244  
   245  	for _, t := range tests {
   246  		valsets := snapasserts.NewValidationSets()
   247  		cSets := make(map[string]*asserts.ValidationSet)
   248  		for _, valset := range t.sets {
   249  			err := valsets.Add(valset)
   250  			c.Assert(err, IsNil)
   251  			// mySnapOptValset never influcens an outcome
   252  			if valset != mySnapOptValset {
   253  				cSets[fmt.Sprintf("%s/%s", valset.AccountID(), valset.Name())] = valset
   254  			}
   255  		}
   256  		err := valsets.Conflict()
   257  		if t.conflictErr == "" {
   258  			c.Check(err, IsNil)
   259  		} else {
   260  			c.Check(err, ErrorMatches, t.conflictErr)
   261  			ce := err.(*snapasserts.ValidationSetsConflictError)
   262  			c.Check(ce.Sets, DeepEquals, cSets)
   263  		}
   264  	}
   265  }