github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/service/service_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package service_test
     5  
     6  import (
     7  	"strings"
     8  
     9  	"github.com/juju/errors"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/service"
    14  	svctesting "github.com/juju/juju/service/common/testing"
    15  	"github.com/juju/juju/service/systemd"
    16  	"github.com/juju/juju/service/upstart"
    17  	"github.com/juju/juju/service/windows"
    18  )
    19  
    20  type serviceSuite struct {
    21  	service.BaseSuite
    22  }
    23  
    24  var _ = gc.Suite(&serviceSuite{})
    25  
    26  func (s *serviceSuite) TestNewServiceKnown(c *gc.C) {
    27  	for _, test := range []struct {
    28  		series     string
    29  		initSystem string
    30  	}{
    31  		{
    32  			series:     "vivid",
    33  			initSystem: service.InitSystemSystemd,
    34  		}, {
    35  			series:     "trusty",
    36  			initSystem: service.InitSystemUpstart,
    37  		}, {
    38  			series:     "win2012",
    39  			initSystem: service.InitSystemWindows,
    40  		},
    41  	} {
    42  		svc, err := service.NewService(s.Name, s.Conf, test.series)
    43  		if !c.Check(err, jc.ErrorIsNil) {
    44  			continue
    45  		}
    46  
    47  		switch test.initSystem {
    48  		case service.InitSystemSystemd:
    49  			c.Check(svc, gc.FitsTypeOf, &systemd.Service{})
    50  		case service.InitSystemUpstart:
    51  			c.Check(svc, gc.FitsTypeOf, &upstart.Service{})
    52  		case service.InitSystemWindows:
    53  			c.Check(svc, gc.FitsTypeOf, &windows.Service{})
    54  		}
    55  		c.Check(svc.Name(), gc.Equals, s.Name)
    56  		c.Check(svc.Conf(), jc.DeepEquals, s.Conf)
    57  	}
    58  }
    59  
    60  func (s *serviceSuite) TestNewServiceMissingName(c *gc.C) {
    61  	_, err := service.NewService("", s.Conf, service.InitSystemUpstart)
    62  
    63  	c.Check(err, gc.ErrorMatches, `.*missing name.*`)
    64  }
    65  
    66  func (s *serviceSuite) TestNewServiceUnknown(c *gc.C) {
    67  	_, err := service.NewService(s.Name, s.Conf, "<unknown>")
    68  
    69  	c.Check(err, jc.Satisfies, errors.IsNotFound)
    70  }
    71  
    72  func (s *serviceSuite) TestListServices(c *gc.C) {
    73  	_, err := service.ListServices()
    74  
    75  	c.Check(err, jc.ErrorIsNil)
    76  }
    77  
    78  func (*serviceSuite) TestListServicesScript(c *gc.C) {
    79  	script := service.ListServicesScript()
    80  
    81  	expected := strings.Split(service.DiscoverInitSystemScript(), "\n")
    82  	expected[0] = "init_system=$(" + expected[0]
    83  	expected[len(expected)-1] += ")"
    84  	expected = append(expected,
    85  		`case "$init_system" in`,
    86  		`systemd)`,
    87  		`    /bin/systemctl list-unit-files --no-legend --no-page -l -t service`+
    88  			` | grep -o -P '^\w[\S]*(?=\.service)'`,
    89  		`    ;;`,
    90  		`upstart)`,
    91  		`    sudo initctl list | awk '{print $1}' | sort | uniq`,
    92  		`    ;;`,
    93  		`*)`,
    94  		`    exit 1`,
    95  		`    ;;`,
    96  		`esac`,
    97  	)
    98  	c.Check(strings.Split(script, "\n"), jc.DeepEquals, expected)
    99  }
   100  
   101  func (s *serviceSuite) TestInstallAndStartOkay(c *gc.C) {
   102  	s.PatchAttempts(5)
   103  
   104  	err := service.InstallAndStart(s.Service)
   105  	c.Assert(err, jc.ErrorIsNil)
   106  
   107  	s.Service.CheckCallNames(c, "Install", "Stop", "Start")
   108  }
   109  
   110  func (s *serviceSuite) TestInstallAndStartRetry(c *gc.C) {
   111  	s.PatchAttempts(5)
   112  	s.Service.SetErrors(nil, s.Failure, s.Failure)
   113  
   114  	err := service.InstallAndStart(s.Service)
   115  	c.Assert(err, jc.ErrorIsNil)
   116  
   117  	s.Service.CheckCallNames(c, "Install", "Stop", "Start", "Stop", "Start")
   118  }
   119  
   120  func (s *serviceSuite) TestInstallAndStartFail(c *gc.C) {
   121  	s.PatchAttempts(3)
   122  	s.Service.SetErrors(nil, s.Failure, s.Failure, s.Failure, s.Failure, s.Failure, s.Failure)
   123  
   124  	err := service.InstallAndStart(s.Service)
   125  
   126  	s.CheckFailure(c, err)
   127  	s.Service.CheckCallNames(c, "Install", "Stop", "Start", "Stop", "Start", "Stop", "Start")
   128  }
   129  
   130  func (s *serviceSuite) TestFindUnitServiceNames(c *gc.C) {
   131  	names := []string{
   132  		"jujud-unit-ubuntu-lite-0",
   133  		"jujud-unit-wordpress-0",
   134  		"jujud-unit-wordpress-1",
   135  		"jujud-machine-0",
   136  		"not-a-juju-service",
   137  	}
   138  
   139  	expected := map[string]string{
   140  		"ubuntu-lite/0": "jujud-unit-ubuntu-lite-0",
   141  		"wordpress/0":   "jujud-unit-wordpress-0",
   142  		"wordpress/1":   "jujud-unit-wordpress-1",
   143  	}
   144  
   145  	services := service.FindUnitServiceNames(names)
   146  	c.Check(services, gc.DeepEquals, expected)
   147  }
   148  
   149  type restartSuite struct {
   150  	service.BaseSuite
   151  }
   152  
   153  var _ = gc.Suite(&restartSuite{})
   154  
   155  func (s *restartSuite) SetUpTest(c *gc.C) {
   156  	s.BaseSuite.SetUpTest(c)
   157  
   158  	s.Patched.Service = s.Service
   159  }
   160  
   161  func (s *restartSuite) TestRestartStopAndStart(c *gc.C) {
   162  	err := service.Restart(s.Name)
   163  	c.Assert(err, jc.ErrorIsNil)
   164  
   165  	s.Stub.CheckCallNames(c, "DiscoverService", "Stop", "Start")
   166  }
   167  
   168  type restartable struct {
   169  	*svctesting.FakeService
   170  }
   171  
   172  func (s *restartable) Restart() error {
   173  	s.AddCall("Restart")
   174  
   175  	return s.NextErr()
   176  }
   177  
   178  func (s *restartSuite) TestRestartRestartable(c *gc.C) {
   179  	s.Patched.Service = &restartable{s.Service}
   180  
   181  	err := service.Restart(s.Name)
   182  	c.Assert(err, jc.ErrorIsNil)
   183  
   184  	// TODO(tsm): fix service.upstart behaviour to match other implementations,
   185  	// then change the test to
   186  	// s.Stub.CheckCallNames(c, "DiscoverService", "Restart")
   187  	s.Stub.CheckCallNames(c, "DiscoverService", "Stop", "Start")
   188  }
   189  
   190  func (s *restartSuite) TestRestartFailDiscovery(c *gc.C) {
   191  	s.Stub.SetErrors(s.Failure)
   192  
   193  	err := service.Restart(s.Name)
   194  
   195  	s.CheckFailure(c, err)
   196  	s.Stub.CheckCallNames(c, "DiscoverService")
   197  }
   198  
   199  func (s *restartSuite) TestRestartFailStop(c *gc.C) {
   200  	s.Stub.SetErrors(nil, s.Failure, nil) // DiscoverService, Stop, Start
   201  
   202  	err := service.Restart(s.Name)
   203  
   204  	// s.CheckFailure(c, err)
   205  	c.Check(err, jc.ErrorIsNil)
   206  
   207  	// s.Stub.CheckCallNames(c, "DiscoverService", "Restart")
   208  	s.Stub.CheckCallNames(c, "DiscoverService", "Stop", "Start")
   209  }
   210  
   211  func (s *restartSuite) TestRestartFailStart(c *gc.C) {
   212  	s.Stub.SetErrors(nil, nil, s.Failure) // DiscoverService, Stop, Start
   213  
   214  	err := service.Restart(s.Name)
   215  
   216  	s.CheckFailure(c, err)
   217  	s.Stub.CheckCallNames(c, "DiscoverService", "Stop", "Start")
   218  }
   219  
   220  func (s *restartSuite) TestRestartFailRestart(c *gc.C) {
   221  	// TODO(tsm): fix service.upstart behaviour to match other implementations
   222  
   223  	s.Patched.Service = &restartable{s.Service}
   224  	//s.Stub.SetErrors(nil, s.Failure)  // DiscoverService, Restart
   225  	s.Stub.SetErrors(nil, nil, s.Failure) // DiscoverService, Stop, Start
   226  
   227  	err := service.Restart(s.Name)
   228  
   229  	s.CheckFailure(c, err)
   230  	// s.Stub.CheckCallNames(c, "DiscoverService", "Restart")
   231  	s.Stub.CheckCallNames(c, "DiscoverService", "Stop", "Start")
   232  }