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 }