github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/asserts/headers_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2015 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_test
    21  
    22  import (
    23  	"bytes"
    24  
    25  	. "gopkg.in/check.v1"
    26  
    27  	"github.com/snapcore/snapd/asserts"
    28  )
    29  
    30  type headersSuite struct{}
    31  
    32  var _ = Suite(&headersSuite{})
    33  
    34  func (s *headersSuite) TestParseHeadersSimple(c *C) {
    35  	m, err := asserts.ParseHeaders([]byte(`foo: 1
    36  bar: baz`))
    37  	c.Assert(err, IsNil)
    38  	c.Check(m, DeepEquals, map[string]interface{}{
    39  		"foo": "1",
    40  		"bar": "baz",
    41  	})
    42  }
    43  
    44  func (s *headersSuite) TestParseHeadersMultiline(c *C) {
    45  	m, err := asserts.ParseHeaders([]byte(`foo:
    46      abc
    47      
    48  bar: baz`))
    49  	c.Assert(err, IsNil)
    50  	c.Check(m, DeepEquals, map[string]interface{}{
    51  		"foo": "abc\n",
    52  		"bar": "baz",
    53  	})
    54  
    55  	m, err = asserts.ParseHeaders([]byte(`foo: 1
    56  bar:
    57      baz`))
    58  	c.Assert(err, IsNil)
    59  	c.Check(m, DeepEquals, map[string]interface{}{
    60  		"foo": "1",
    61  		"bar": "baz",
    62  	})
    63  
    64  	m, err = asserts.ParseHeaders([]byte(`foo: 1
    65  bar:
    66      baz
    67      `))
    68  	c.Assert(err, IsNil)
    69  	c.Check(m, DeepEquals, map[string]interface{}{
    70  		"foo": "1",
    71  		"bar": "baz\n",
    72  	})
    73  
    74  	m, err = asserts.ParseHeaders([]byte(`foo: 1
    75  bar:
    76      baz
    77      
    78      baz2`))
    79  	c.Assert(err, IsNil)
    80  	c.Check(m, DeepEquals, map[string]interface{}{
    81  		"foo": "1",
    82  		"bar": "baz\n\nbaz2",
    83  	})
    84  }
    85  
    86  func (s *headersSuite) TestParseHeadersSimpleList(c *C) {
    87  	m, err := asserts.ParseHeaders([]byte(`foo:
    88    - x
    89    - y
    90    - z
    91  bar: baz`))
    92  	c.Assert(err, IsNil)
    93  	c.Check(m, DeepEquals, map[string]interface{}{
    94  		"foo": []interface{}{"x", "y", "z"},
    95  		"bar": "baz",
    96  	})
    97  }
    98  
    99  func (s *headersSuite) TestParseHeadersListNestedMultiline(c *C) {
   100  	m, err := asserts.ParseHeaders([]byte(`foo:
   101    - x
   102    -
   103        y1
   104        y2
   105        
   106    - z
   107  bar: baz`))
   108  	c.Assert(err, IsNil)
   109  	c.Check(m, DeepEquals, map[string]interface{}{
   110  		"foo": []interface{}{"x", "y1\ny2\n", "z"},
   111  		"bar": "baz",
   112  	})
   113  
   114  	m, err = asserts.ParseHeaders([]byte(`bar: baz
   115  foo:
   116    -
   117      - u1
   118      - u2
   119    -
   120        y1
   121        y2
   122        `))
   123  	c.Assert(err, IsNil)
   124  	c.Check(m, DeepEquals, map[string]interface{}{
   125  		"foo": []interface{}{[]interface{}{"u1", "u2"}, "y1\ny2\n"},
   126  		"bar": "baz",
   127  	})
   128  }
   129  
   130  func (s *headersSuite) TestParseHeadersSimpleMap(c *C) {
   131  	m, err := asserts.ParseHeaders([]byte(`foo:
   132    x: X
   133    yy: YY
   134    z5: 
   135  bar: baz`))
   136  	c.Assert(err, IsNil)
   137  	c.Check(m, DeepEquals, map[string]interface{}{
   138  		"foo": map[string]interface{}{
   139  			"x":  "X",
   140  			"yy": "YY",
   141  			"z5": "",
   142  		},
   143  		"bar": "baz",
   144  	})
   145  }
   146  
   147  func (s *headersSuite) TestParseHeadersMapNestedMultiline(c *C) {
   148  	m, err := asserts.ParseHeaders([]byte(`foo:
   149    x: X
   150    yy:
   151        YY1
   152        YY2
   153    u:
   154      - u1
   155      - u2
   156  bar: baz`))
   157  	c.Assert(err, IsNil)
   158  	c.Check(m, DeepEquals, map[string]interface{}{
   159  		"foo": map[string]interface{}{
   160  			"x":  "X",
   161  			"yy": "YY1\nYY2",
   162  			"u":  []interface{}{"u1", "u2"},
   163  		},
   164  		"bar": "baz",
   165  	})
   166  
   167  	m, err = asserts.ParseHeaders([]byte(`one:
   168    two:
   169      three: `))
   170  	c.Assert(err, IsNil)
   171  	c.Check(m, DeepEquals, map[string]interface{}{
   172  		"one": map[string]interface{}{
   173  			"two": map[string]interface{}{
   174  				"three": "",
   175  			},
   176  		},
   177  	})
   178  
   179  	m, err = asserts.ParseHeaders([]byte(`one:
   180    two:
   181        three`))
   182  	c.Assert(err, IsNil)
   183  	c.Check(m, DeepEquals, map[string]interface{}{
   184  		"one": map[string]interface{}{
   185  			"two": "three",
   186  		},
   187  	})
   188  
   189  	m, err = asserts.ParseHeaders([]byte(`map-within-map:
   190    lev1:
   191      lev2: x`))
   192  	c.Assert(err, IsNil)
   193  	c.Check(m, DeepEquals, map[string]interface{}{
   194  		"map-within-map": map[string]interface{}{
   195  			"lev1": map[string]interface{}{
   196  				"lev2": "x",
   197  			},
   198  		},
   199  	})
   200  
   201  	m, err = asserts.ParseHeaders([]byte(`list-of-maps:
   202    -
   203      entry: foo
   204      bar: baz
   205    -
   206      entry: bar`))
   207  	c.Assert(err, IsNil)
   208  	c.Check(m, DeepEquals, map[string]interface{}{
   209  		"list-of-maps": []interface{}{
   210  			map[string]interface{}{
   211  				"entry": "foo",
   212  				"bar":   "baz",
   213  			},
   214  			map[string]interface{}{
   215  				"entry": "bar",
   216  			},
   217  		},
   218  	})
   219  }
   220  
   221  func (s *headersSuite) TestParseHeadersMapErrors(c *C) {
   222  	_, err := asserts.ParseHeaders([]byte(`foo:
   223    x X
   224  bar: baz`))
   225  	c.Check(err, ErrorMatches, `map entry missing ':' separator: "x X"`)
   226  
   227  	_, err = asserts.ParseHeaders([]byte(`foo:
   228    0x: X
   229  bar: baz`))
   230  	c.Check(err, ErrorMatches, `invalid map entry key: "0x"`)
   231  
   232  	_, err = asserts.ParseHeaders([]byte(`foo:
   233    a: a
   234    a: b`))
   235  	c.Check(err, ErrorMatches, `repeated map entry: "a"`)
   236  }
   237  
   238  func (s *headersSuite) TestParseHeadersErrors(c *C) {
   239  	_, err := asserts.ParseHeaders([]byte(`foo: 1
   240  bar:baz`))
   241  	c.Check(err, ErrorMatches, `header entry should have a space or newline \(for multiline\) before value: "bar:baz"`)
   242  
   243  	_, err = asserts.ParseHeaders([]byte(`foo:
   244   - x
   245    - y
   246    - z
   247  bar: baz`))
   248  	c.Check(err, ErrorMatches, `expected 4 chars nesting prefix after multiline introduction "foo:": " - x"`)
   249  
   250  	_, err = asserts.ParseHeaders([]byte(`foo:
   251    - x
   252    - y
   253    - z
   254  bar:`))
   255  	c.Check(err, ErrorMatches, `expected 4 chars nesting prefix after multiline introduction "bar:": EOF`)
   256  }
   257  
   258  func (s *headersSuite) TestAppendEntrySimple(c *C) {
   259  	buf := bytes.NewBufferString("start: .")
   260  
   261  	asserts.AppendEntry(buf, "bar:", "baz", 0)
   262  
   263  	m, err := asserts.ParseHeaders(buf.Bytes())
   264  	c.Assert(err, IsNil)
   265  	c.Check(m, DeepEquals, map[string]interface{}{
   266  		"start": ".",
   267  		"bar":   "baz",
   268  	})
   269  }
   270  
   271  func (s *headersSuite) TestAppendEntryMultiline(c *C) {
   272  	multilines := []string{
   273  		"a\n",
   274  		"a\nb",
   275  		"baz\n baz1\nbaz2",
   276  		"baz\n baz1\nbaz2\n",
   277  		"baz\n baz1\nbaz2\n\n",
   278  	}
   279  
   280  	for _, multiline := range multilines {
   281  		buf := bytes.NewBufferString("start: .")
   282  
   283  		asserts.AppendEntry(buf, "bar:", multiline, 0)
   284  
   285  		m, err := asserts.ParseHeaders(buf.Bytes())
   286  		c.Assert(err, IsNil)
   287  		c.Check(m, DeepEquals, map[string]interface{}{
   288  			"start": ".",
   289  			"bar":   multiline,
   290  		})
   291  	}
   292  }
   293  
   294  func (s *headersSuite) TestAppendEntrySimpleList(c *C) {
   295  	lst := []interface{}{"x", "y", "z"}
   296  
   297  	buf := bytes.NewBufferString("start: .")
   298  
   299  	asserts.AppendEntry(buf, "bar:", lst, 0)
   300  
   301  	m, err := asserts.ParseHeaders(buf.Bytes())
   302  	c.Assert(err, IsNil)
   303  	c.Check(m, DeepEquals, map[string]interface{}{
   304  		"start": ".",
   305  		"bar":   lst,
   306  	})
   307  }
   308  
   309  func (s *headersSuite) TestAppendEntryListNested(c *C) {
   310  	lst := []interface{}{"x", "a\nb\n", "", []interface{}{"u1", []interface{}{"w1", "w2"}}}
   311  
   312  	buf := bytes.NewBufferString("start: .")
   313  
   314  	asserts.AppendEntry(buf, "bar:", lst, 0)
   315  
   316  	m, err := asserts.ParseHeaders(buf.Bytes())
   317  	c.Assert(err, IsNil)
   318  	c.Check(m, DeepEquals, map[string]interface{}{
   319  		"start": ".",
   320  		"bar":   lst,
   321  	})
   322  }
   323  
   324  func (s *headersSuite) TestAppendEntrySimpleMap(c *C) {
   325  	mp := map[string]interface{}{
   326  		"x":  "X",
   327  		"yy": "YY",
   328  		"z5": "",
   329  	}
   330  
   331  	buf := bytes.NewBufferString("start: .")
   332  
   333  	asserts.AppendEntry(buf, "bar:", mp, 0)
   334  
   335  	m, err := asserts.ParseHeaders(buf.Bytes())
   336  	c.Assert(err, IsNil)
   337  	c.Check(m, DeepEquals, map[string]interface{}{
   338  		"start": ".",
   339  		"bar":   mp,
   340  	})
   341  }
   342  
   343  func (s *headersSuite) TestAppendEntryNestedMap(c *C) {
   344  	mp := map[string]interface{}{
   345  		"x":  "X",
   346  		"u":  []interface{}{"u1", "u2"},
   347  		"yy": "YY1\nYY2",
   348  		"m":  map[string]interface{}{"a": "A", "b": map[string]interface{}{"x": "X", "y": "Y"}},
   349  	}
   350  
   351  	buf := bytes.NewBufferString("start: .")
   352  
   353  	asserts.AppendEntry(buf, "bar:", mp, 0)
   354  
   355  	m, err := asserts.ParseHeaders(buf.Bytes())
   356  	c.Assert(err, IsNil)
   357  	c.Check(m, DeepEquals, map[string]interface{}{
   358  		"start": ".",
   359  		"bar":   mp,
   360  	})
   361  }
   362  
   363  func (s *headersSuite) TestAppendEntryOmitting(c *C) {
   364  	buf := bytes.NewBufferString("start: .")
   365  
   366  	asserts.AppendEntry(buf, "bar:", []interface{}{}, 0)
   367  
   368  	m, err := asserts.ParseHeaders(buf.Bytes())
   369  	c.Assert(err, IsNil)
   370  	c.Check(m, DeepEquals, map[string]interface{}{
   371  		"start": ".",
   372  	})
   373  
   374  	lst := []interface{}{nil, []interface{}{}, "z"}
   375  
   376  	buf = bytes.NewBufferString("start: .")
   377  
   378  	asserts.AppendEntry(buf, "bar:", lst, 0)
   379  
   380  	m, err = asserts.ParseHeaders(buf.Bytes())
   381  	c.Assert(err, IsNil)
   382  	c.Check(m, DeepEquals, map[string]interface{}{
   383  		"start": ".",
   384  		"bar":   []interface{}{"z"},
   385  	})
   386  
   387  	buf = bytes.NewBufferString("start: .")
   388  
   389  	asserts.AppendEntry(buf, "bar:", map[string]interface{}{}, 0)
   390  
   391  	m, err = asserts.ParseHeaders(buf.Bytes())
   392  	c.Assert(err, IsNil)
   393  	c.Check(m, DeepEquals, map[string]interface{}{
   394  		"start": ".",
   395  	})
   396  }