github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/overlord/configstate/configcore/picfg_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2017 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 configcore_test
    21  
    22  import (
    23  	"io/ioutil"
    24  	"os"
    25  	"path/filepath"
    26  	"strings"
    27  
    28  	. "gopkg.in/check.v1"
    29  
    30  	"github.com/snapcore/snapd/dirs"
    31  	"github.com/snapcore/snapd/overlord/configstate/configcore"
    32  	"github.com/snapcore/snapd/release"
    33  	"github.com/snapcore/snapd/testutil"
    34  )
    35  
    36  type piCfgSuite struct {
    37  	configcoreSuite
    38  
    39  	mockConfigPath string
    40  }
    41  
    42  var _ = Suite(&piCfgSuite{})
    43  
    44  var mockConfigTxt = `
    45  # For more options and information see
    46  # http://www.raspberrypi.org/documentation/configuration/config-txt.md
    47  #hdmi_group=1
    48  # uncomment this if your display has a black border of unused pixels visible
    49  # and your display can output without overscan
    50  #disable_overscan=1
    51  unrelated_options=are-kept
    52  #gpu_mem_512=true
    53  `
    54  
    55  func (s *piCfgSuite) SetUpTest(c *C) {
    56  	s.configcoreSuite.SetUpTest(c)
    57  	c.Assert(os.MkdirAll(filepath.Join(dirs.GlobalRootDir, "etc"), 0755), IsNil)
    58  
    59  	s.mockConfigPath = filepath.Join(dirs.GlobalRootDir, "/boot/uboot/config.txt")
    60  	err := os.MkdirAll(filepath.Dir(s.mockConfigPath), 0755)
    61  	c.Assert(err, IsNil)
    62  	s.mockConfig(c, mockConfigTxt)
    63  }
    64  
    65  func (s *piCfgSuite) mockConfig(c *C, txt string) {
    66  	err := ioutil.WriteFile(s.mockConfigPath, []byte(txt), 0644)
    67  	c.Assert(err, IsNil)
    68  }
    69  
    70  func (s *piCfgSuite) checkMockConfig(c *C, expected string) {
    71  	c.Check(s.mockConfigPath, testutil.FileEquals, expected)
    72  }
    73  
    74  func (s *piCfgSuite) TestConfigurePiConfigUncommentExisting(c *C) {
    75  	err := configcore.UpdatePiConfig(s.mockConfigPath, map[string]string{"disable_overscan": "1"})
    76  	c.Assert(err, IsNil)
    77  
    78  	expected := strings.Replace(mockConfigTxt, "#disable_overscan=1", "disable_overscan=1", -1)
    79  	s.checkMockConfig(c, expected)
    80  }
    81  
    82  func (s *piCfgSuite) TestConfigurePiConfigCommentExisting(c *C) {
    83  	s.mockConfig(c, mockConfigTxt+"avoid_warnings=1\n")
    84  
    85  	err := configcore.UpdatePiConfig(s.mockConfigPath, map[string]string{"avoid_warnings": ""})
    86  	c.Assert(err, IsNil)
    87  
    88  	expected := mockConfigTxt + "#avoid_warnings=1\n"
    89  	s.checkMockConfig(c, expected)
    90  }
    91  
    92  func (s *piCfgSuite) TestConfigurePiConfigAddNewOption(c *C) {
    93  	err := configcore.UpdatePiConfig(s.mockConfigPath, map[string]string{"framebuffer_depth": "16"})
    94  	c.Assert(err, IsNil)
    95  
    96  	expected := mockConfigTxt + "framebuffer_depth=16\n"
    97  	s.checkMockConfig(c, expected)
    98  
    99  	// add again, verify its not added twice but updated
   100  	err = configcore.UpdatePiConfig(s.mockConfigPath, map[string]string{"framebuffer_depth": "32"})
   101  	c.Assert(err, IsNil)
   102  	expected = mockConfigTxt + "framebuffer_depth=32\n"
   103  	s.checkMockConfig(c, expected)
   104  }
   105  
   106  func (s *piCfgSuite) TestConfigurePiConfigNoChangeUnset(c *C) {
   107  	// ensure we cannot write to the dir to test that we really
   108  	// do not update the file
   109  	err := os.Chmod(filepath.Dir(s.mockConfigPath), 0500)
   110  	c.Assert(err, IsNil)
   111  	defer os.Chmod(filepath.Dir(s.mockConfigPath), 0755)
   112  
   113  	err = configcore.UpdatePiConfig(s.mockConfigPath, map[string]string{"hdmi_group": ""})
   114  	c.Assert(err, IsNil)
   115  }
   116  
   117  func (s *piCfgSuite) TestConfigurePiConfigNoChangeSet(c *C) {
   118  	// ensure we cannot write to the dir to test that we really
   119  	// do not update the file
   120  	err := os.Chmod(filepath.Dir(s.mockConfigPath), 0500)
   121  	c.Assert(err, IsNil)
   122  	defer os.Chmod(filepath.Dir(s.mockConfigPath), 0755)
   123  
   124  	err = configcore.UpdatePiConfig(s.mockConfigPath, map[string]string{"unrelated_options": "cannot-be-set"})
   125  	c.Assert(err, ErrorMatches, `cannot set unsupported configuration value "unrelated_options"`)
   126  }
   127  
   128  func (s *piCfgSuite) TestConfigurePiConfigIntegration(c *C) {
   129  	restore := release.MockOnClassic(false)
   130  	defer restore()
   131  
   132  	err := configcore.Run(&mockConf{
   133  		state: s.state,
   134  		conf: map[string]interface{}{
   135  			"pi-config.disable-overscan": 1,
   136  		},
   137  	})
   138  	c.Assert(err, IsNil)
   139  
   140  	expected := strings.Replace(mockConfigTxt, "#disable_overscan=1", "disable_overscan=1", -1)
   141  	s.checkMockConfig(c, expected)
   142  
   143  	err = configcore.Run(&mockConf{
   144  		state: s.state,
   145  		conf: map[string]interface{}{
   146  			"pi-config.disable-overscan": "",
   147  		},
   148  	})
   149  	c.Assert(err, IsNil)
   150  
   151  	s.checkMockConfig(c, mockConfigTxt)
   152  }
   153  
   154  func (s *piCfgSuite) TestConfigurePiConfigRegression(c *C) {
   155  	restore := release.MockOnClassic(false)
   156  	defer restore()
   157  
   158  	err := configcore.Run(&mockConf{
   159  		state: s.state,
   160  		conf: map[string]interface{}{
   161  			"pi-config.gpu-mem-512": true,
   162  		},
   163  	})
   164  	c.Assert(err, IsNil)
   165  	expected := strings.Replace(mockConfigTxt, "#gpu_mem_512=true", "gpu_mem_512=true", -1)
   166  	s.checkMockConfig(c, expected)
   167  }
   168  
   169  func (s *piCfgSuite) TestFilesystemOnlyApply(c *C) {
   170  	conf := configcore.PlainCoreConfig(map[string]interface{}{
   171  		"pi-config.gpu-mem-512": true,
   172  	})
   173  
   174  	tmpDir := c.MkDir()
   175  	c.Assert(os.MkdirAll(filepath.Join(tmpDir, "/boot/uboot"), 0755), IsNil)
   176  
   177  	// write default config
   178  	piCfg := filepath.Join(tmpDir, "/boot/uboot/config.txt")
   179  	c.Assert(ioutil.WriteFile(piCfg, []byte(mockConfigTxt), 0644), IsNil)
   180  
   181  	c.Assert(configcore.FilesystemOnlyApply(tmpDir, conf, nil), IsNil)
   182  
   183  	expected := strings.Replace(mockConfigTxt, "#gpu_mem_512=true", "gpu_mem_512=true", -1)
   184  	c.Check(piCfg, testutil.FileEquals, expected)
   185  }