github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/service/systemd/testing/writeconf.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package testing
     5  
     6  import (
     7  	"fmt"
     8  	"sort"
     9  	"strings"
    10  
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/testing"
    15  )
    16  
    17  // WriteConfTest is used in tests to verify that the shell commands
    18  // to write a service conf to disk are correct.
    19  type WriteConfTest struct {
    20  	Service  string
    21  	DataDir  string
    22  	Expected string
    23  	Script   string
    24  }
    25  
    26  func (wct WriteConfTest) fileName() string {
    27  	return fmt.Sprintf("'%s/%s.service'", wct.DataDir, wct.Service)
    28  }
    29  
    30  func (wct WriteConfTest) scriptName() string {
    31  	return fmt.Sprintf("'%s/%s-exec-start.sh'", wct.DataDir, wct.Service)
    32  }
    33  
    34  // CheckCommands checks the given commands against the test's expectations.
    35  func (wct WriteConfTest) CheckCommands(c *gc.C, commands []string) {
    36  	if wct.Script != "" {
    37  		wct.checkWriteExecScript(c, commands[:2])
    38  		commands = commands[2:]
    39  	}
    40  	wct.checkWriteConf(c, commands)
    41  }
    42  
    43  func (wct WriteConfTest) checkWriteExecScript(c *gc.C, commands []string) {
    44  	script := "#!/usr/bin/env bash\n\n" + wct.Script
    45  	testing.CheckWriteFileCommand(c, commands[0], wct.scriptName(), script, nil)
    46  
    47  	// Check the remaining commands.
    48  	c.Check(commands[1:], jc.DeepEquals, []string{
    49  		"chmod 0755 " + wct.scriptName(),
    50  	})
    51  }
    52  
    53  func (wct WriteConfTest) checkWriteConf(c *gc.C, commands []string) {
    54  	// This check must be done without regard to map order.
    55  	parse := func(lines []string) interface{} {
    56  		return parseConfSections(lines)
    57  	}
    58  	testing.CheckWriteFileCommand(c, commands[0], wct.fileName(), wct.Expected, parse)
    59  
    60  	// Check the remaining commands.
    61  	c.Check(commands[1:], jc.DeepEquals, []string{
    62  		"/bin/systemctl link " + wct.fileName(),
    63  		"/bin/systemctl daemon-reload",
    64  		"/bin/systemctl enable " + wct.fileName(),
    65  	})
    66  }
    67  
    68  // parseConfSections is a poor man's ini parser.
    69  func parseConfSections(lines []string) map[string][]string {
    70  	sections := make(map[string][]string)
    71  
    72  	var section string
    73  	for _, line := range lines {
    74  		line = strings.TrimSpace(line)
    75  		if line == "" {
    76  			continue
    77  		}
    78  		if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
    79  			if section != "" {
    80  				sort.Strings(sections[section])
    81  			}
    82  			section = line[1 : len(line)-1]
    83  			sections[section] = nil
    84  		} else {
    85  			sections[section] = append(sections[section], line)
    86  		}
    87  	}
    88  	if section != "" {
    89  		sort.Strings(sections[section])
    90  	}
    91  
    92  	return sections
    93  }