github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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) dirname() string {
    27  	return fmt.Sprintf("'%s/init/%s'", wct.DataDir, wct.Service)
    28  }
    29  
    30  func (wct WriteConfTest) filename() string {
    31  	return fmt.Sprintf("'%[1]s/init/%[2]s/%[2]s.service'", wct.DataDir, wct.Service)
    32  }
    33  
    34  func (wct WriteConfTest) scriptname() string {
    35  	return fmt.Sprintf("'%s/init/%s/exec-start.sh'", wct.DataDir, wct.Service)
    36  }
    37  
    38  func (wct WriteConfTest) servicename() string {
    39  	return fmt.Sprintf("%s.service", wct.Service)
    40  }
    41  
    42  // CheckCommands checks the given commands against the test's expectations.
    43  func (wct WriteConfTest) CheckCommands(c *gc.C, commands []string) {
    44  	c.Check(commands[0], gc.Equals, "mkdir -p "+wct.dirname())
    45  	commands = commands[1:]
    46  	if wct.Script != "" {
    47  		wct.checkWriteExecScript(c, commands[:2])
    48  		commands = commands[2:]
    49  	}
    50  	wct.checkWriteConf(c, commands)
    51  }
    52  
    53  func (wct WriteConfTest) CheckInstallAndStartCommands(c *gc.C, commands []string) {
    54  	wct.CheckCommands(c, commands[:len(commands)-1])
    55  	c.Check(commands[len(commands)-1], gc.Equals, "/bin/systemctl start "+wct.servicename())
    56  }
    57  
    58  func (wct WriteConfTest) checkWriteExecScript(c *gc.C, commands []string) {
    59  	script := "#!/usr/bin/env bash\n\n" + wct.Script
    60  	testing.CheckWriteFileCommand(c, commands[0], wct.scriptname(), script, nil)
    61  
    62  	// Check the remaining commands.
    63  	c.Check(commands[1:], jc.DeepEquals, []string{
    64  		"chmod 0755 " + wct.scriptname(),
    65  	})
    66  }
    67  
    68  func (wct WriteConfTest) checkWriteConf(c *gc.C, commands []string) {
    69  	// This check must be done without regard to map order.
    70  	parse := func(lines []string) interface{} {
    71  		return parseConfSections(lines)
    72  	}
    73  	testing.CheckWriteFileCommand(c, commands[0], wct.filename(), wct.Expected, parse)
    74  
    75  	// Check the remaining commands.
    76  	c.Check(commands[1:], jc.DeepEquals, []string{
    77  		"/bin/systemctl link " + wct.filename(),
    78  		"/bin/systemctl daemon-reload",
    79  		"/bin/systemctl enable " + wct.filename(),
    80  	})
    81  }
    82  
    83  // parseConfSections is a poor man's ini parser.
    84  func parseConfSections(lines []string) map[string][]string {
    85  	sections := make(map[string][]string)
    86  
    87  	var section string
    88  	for _, line := range lines {
    89  		line = strings.TrimSpace(line)
    90  		if line == "" {
    91  			continue
    92  		}
    93  		if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
    94  			if section != "" {
    95  				sort.Strings(sections[section])
    96  			}
    97  			section = line[1 : len(line)-1]
    98  			sections[section] = nil
    99  		} else {
   100  			sections[section] = append(sections[section], line)
   101  		}
   102  	}
   103  	if section != "" {
   104  		sort.Strings(sections[section])
   105  	}
   106  
   107  	return sections
   108  }