github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/service/windows/service_windows_test.go (about)

     1  // Copyright 2015 Cloudbase Solutions
     2  // Copyright 2015 Canonical Ltd.
     3  // Licensed under the AGPLv3, see LICENCE file for details.
     4  
     5  // +build !linux windows
     6  
     7  package windows_test
     8  
     9  import (
    10  	"syscall"
    11  
    12  	win "github.com/gabriel-samfira/sys/windows"
    13  	"github.com/gabriel-samfira/sys/windows/svc"
    14  	"github.com/juju/errors"
    15  	"github.com/juju/testing"
    16  	jc "github.com/juju/testing/checkers"
    17  	gc "gopkg.in/check.v1"
    18  
    19  	"github.com/juju/juju/service/common"
    20  	"github.com/juju/juju/service/windows"
    21  	coretesting "github.com/juju/juju/testing"
    22  )
    23  
    24  type serviceManagerSuite struct {
    25  	coretesting.BaseSuite
    26  
    27  	stub       *testing.Stub
    28  	passwdStub *testing.Stub
    29  	conn       *windows.StubMgr
    30  	getPasswd  *windows.StubGetPassword
    31  
    32  	name string
    33  	conf common.Conf
    34  
    35  	mgr windows.ServiceManager
    36  
    37  	execPath string
    38  }
    39  
    40  var _ = gc.Suite(&serviceManagerSuite{})
    41  
    42  func (s *serviceManagerSuite) SetUpTest(c *gc.C) {
    43  	s.BaseSuite.SetUpTest(c)
    44  	var err error
    45  	s.execPath = `C:\juju\bin\jujud.exe`
    46  	s.stub = &testing.Stub{}
    47  	s.passwdStub = &testing.Stub{}
    48  	s.conn = windows.PatchMgrConnect(s, s.stub)
    49  	s.getPasswd = windows.PatchGetPassword(s, s.passwdStub)
    50  	s.PatchValue(&windows.WinChangeServiceConfig2, func(win.Handle, uint32, *byte) error {
    51  		return nil
    52  	})
    53  
    54  	// Set up the service.
    55  	s.name = "machine-1"
    56  	s.conf = common.Conf{
    57  		Desc:      "service for " + s.name,
    58  		ExecStart: s.execPath + " " + s.name,
    59  	}
    60  
    61  	s.mgr, err = windows.NewServiceManager()
    62  	c.Assert(err, gc.IsNil)
    63  
    64  	// Clear services
    65  	s.conn.Clear()
    66  }
    67  
    68  func (s *serviceManagerSuite) TestCreate(c *gc.C) {
    69  	s.getPasswd.SetPasswd("fake")
    70  	err := s.mgr.Create(s.name, s.conf)
    71  	c.Assert(err, gc.IsNil)
    72  
    73  	c.Assert(s.getPasswd.Calls(), gc.HasLen, 1)
    74  
    75  	exists := s.conn.Exists(s.name)
    76  	c.Assert(exists, jc.IsTrue)
    77  
    78  	svcs := s.conn.List()
    79  	c.Assert(svcs, gc.HasLen, 1)
    80  
    81  	m, ok := s.mgr.(*windows.SvcManager)
    82  	c.Assert(ok, jc.IsTrue)
    83  
    84  	cfg, err := m.Config(s.name)
    85  	c.Assert(err, gc.IsNil)
    86  	c.Assert(cfg.ServiceStartName, gc.Equals, windows.JujudUser)
    87  
    88  	running, err := s.mgr.Running(s.name)
    89  	c.Assert(err, gc.IsNil)
    90  	c.Assert(running, jc.IsFalse)
    91  }
    92  
    93  func (s *serviceManagerSuite) TestCreateInvalidPassword(c *gc.C) {
    94  	passwdError := errors.New("Failed to get password")
    95  	s.passwdStub.SetErrors(passwdError)
    96  
    97  	err := s.mgr.Create(s.name, s.conf)
    98  	c.Assert(errors.Cause(err), gc.Equals, passwdError)
    99  
   100  	c.Assert(s.getPasswd.Calls(), gc.HasLen, 1)
   101  
   102  	exists := s.conn.Exists(s.name)
   103  	c.Assert(exists, jc.IsFalse)
   104  }
   105  
   106  func (s *serviceManagerSuite) TestCreateInvalidUser(c *gc.C) {
   107  	s.getPasswd.SetPasswd("fake")
   108  
   109  	err := s.mgr.Create(s.name, s.conf)
   110  	c.Assert(err, gc.IsNil)
   111  
   112  	c.Assert(s.getPasswd.Calls(), gc.HasLen, 1)
   113  
   114  	m, ok := s.mgr.(*windows.SvcManager)
   115  	c.Assert(ok, jc.IsTrue)
   116  
   117  	cfg, err := m.Config(s.name)
   118  
   119  	c.Assert(err, gc.IsNil)
   120  	c.Assert(cfg.ServiceStartName, gc.Equals, windows.JujudUser)
   121  }
   122  
   123  func (s *serviceManagerSuite) TestCreateAlreadyExists(c *gc.C) {
   124  	err := s.mgr.Create(s.name, s.conf)
   125  	c.Assert(err, gc.IsNil)
   126  	exists := s.conn.Exists(s.name)
   127  	c.Assert(exists, jc.IsTrue)
   128  	err = s.mgr.Create(s.name, s.conf)
   129  	c.Assert(errors.Cause(err), gc.Equals, windows.ERROR_SERVICE_EXISTS)
   130  }
   131  
   132  func (s *serviceManagerSuite) TestCreateMultipleServices(c *gc.C) {
   133  	err := s.mgr.Create("test-service", common.Conf{})
   134  	c.Assert(err, gc.IsNil)
   135  	exists := s.conn.Exists("test-service")
   136  	c.Assert(exists, jc.IsTrue)
   137  
   138  	err = s.mgr.Create("another-test-service", common.Conf{})
   139  	c.Assert(err, gc.IsNil)
   140  	exists = s.conn.Exists("another-test-service")
   141  	c.Assert(exists, jc.IsTrue)
   142  
   143  	svcs := s.conn.List()
   144  	c.Assert(svcs, gc.HasLen, 2)
   145  }
   146  
   147  func (s *serviceManagerSuite) TestStart(c *gc.C) {
   148  	windows.AddService(s.name, s.execPath, s.stub, svc.Status{State: svc.Stopped})
   149  
   150  	err := s.mgr.Start(s.name)
   151  	c.Assert(err, gc.IsNil)
   152  
   153  	running, err := s.mgr.Running(s.name)
   154  	c.Assert(err, gc.IsNil)
   155  	c.Assert(running, jc.IsTrue)
   156  }
   157  
   158  func (s *serviceManagerSuite) TestStartTwice(c *gc.C) {
   159  	windows.AddService(s.name, s.execPath, s.stub, svc.Status{State: svc.Stopped})
   160  
   161  	err := s.mgr.Start(s.name)
   162  	c.Assert(err, gc.IsNil)
   163  
   164  	err = s.mgr.Start(s.name)
   165  	c.Assert(err, gc.IsNil)
   166  
   167  	running, err := s.mgr.Running(s.name)
   168  	c.Assert(err, gc.IsNil)
   169  	c.Assert(running, jc.IsTrue)
   170  }
   171  
   172  func (s *serviceManagerSuite) TestStartStop(c *gc.C) {
   173  	windows.AddService(s.name, s.execPath, s.stub, svc.Status{State: svc.Stopped})
   174  
   175  	err := s.mgr.Start(s.name)
   176  	c.Assert(err, gc.IsNil)
   177  
   178  	running, err := s.mgr.Running(s.name)
   179  	c.Assert(err, gc.IsNil)
   180  	c.Assert(running, jc.IsTrue)
   181  
   182  	err = s.mgr.Stop(s.name)
   183  	c.Assert(err, gc.IsNil)
   184  
   185  	running, err = s.mgr.Running(s.name)
   186  	c.Assert(err, gc.IsNil)
   187  	c.Assert(running, jc.IsFalse)
   188  }
   189  
   190  func (s *serviceManagerSuite) TestStop(c *gc.C) {
   191  	windows.AddService(s.name, s.execPath, s.stub, svc.Status{State: svc.Running})
   192  
   193  	running, err := s.mgr.Running(s.name)
   194  	c.Assert(err, gc.IsNil)
   195  	c.Assert(running, jc.IsTrue)
   196  
   197  	err = s.mgr.Stop(s.name)
   198  	c.Assert(err, gc.IsNil)
   199  
   200  	running, err = s.mgr.Running(s.name)
   201  	c.Assert(err, gc.IsNil)
   202  	c.Assert(running, jc.IsFalse)
   203  }
   204  
   205  func (s *serviceManagerSuite) TestChangePassword(c *gc.C) {
   206  	s.getPasswd.SetPasswd("fake")
   207  	err := s.mgr.Create(s.name, s.conf)
   208  	c.Assert(err, gc.IsNil)
   209  	c.Assert(s.getPasswd.Calls(), gc.HasLen, 1)
   210  
   211  	exists := s.conn.Exists(s.name)
   212  	c.Assert(exists, jc.IsTrue)
   213  
   214  	m, ok := s.mgr.(*windows.SvcManager)
   215  	c.Assert(ok, jc.IsTrue)
   216  
   217  	cfg, err := m.Config(s.name)
   218  	c.Assert(err, gc.IsNil)
   219  	c.Assert(cfg.Password, gc.Equals, "fake")
   220  
   221  	err = s.mgr.ChangeServicePassword(s.name, "obviously-better-password")
   222  	c.Assert(err, gc.IsNil)
   223  
   224  	cfg, err = m.Config(s.name)
   225  	c.Assert(err, gc.IsNil)
   226  	c.Assert(cfg.Password, gc.Equals, "obviously-better-password")
   227  
   228  }
   229  
   230  func (s *serviceManagerSuite) TestChangePasswordAccessDenied(c *gc.C) {
   231  	s.getPasswd.SetPasswd("fake")
   232  	err := s.mgr.Create(s.name, s.conf)
   233  	c.Assert(err, gc.IsNil)
   234  	c.Assert(s.getPasswd.Calls(), gc.HasLen, 1)
   235  
   236  	m, ok := s.mgr.(*windows.SvcManager)
   237  	c.Assert(ok, jc.IsTrue)
   238  
   239  	cfg, err := m.Config(s.name)
   240  	c.Assert(err, gc.IsNil)
   241  	c.Assert(cfg.Password, gc.Equals, "fake")
   242  
   243  	s.stub.SetErrors(syscall.ERROR_ACCESS_DENIED)
   244  
   245  	err = s.mgr.ChangeServicePassword(s.name, "obviously-better-password")
   246  	c.Assert(err, gc.IsNil)
   247  
   248  	cfg, err = m.Config(s.name)
   249  	c.Assert(err, gc.IsNil)
   250  	c.Assert(cfg.Password, gc.Equals, "fake")
   251  
   252  }
   253  
   254  func (s *serviceManagerSuite) TestChangePasswordErrorOut(c *gc.C) {
   255  	s.getPasswd.SetPasswd("fake")
   256  	err := s.mgr.Create(s.name, s.conf)
   257  	c.Assert(err, gc.IsNil)
   258  	c.Assert(s.getPasswd.Calls(), gc.HasLen, 1)
   259  
   260  	m, ok := s.mgr.(*windows.SvcManager)
   261  	c.Assert(ok, jc.IsTrue)
   262  
   263  	cfg, err := m.Config(s.name)
   264  	c.Assert(err, gc.IsNil)
   265  	c.Assert(cfg.Password, gc.Equals, "fake")
   266  
   267  	s.stub.SetErrors(errors.New("poof"))
   268  
   269  	err = s.mgr.ChangeServicePassword(s.name, "obviously-better-password")
   270  	c.Assert(err, gc.ErrorMatches, "poof")
   271  
   272  	cfg, err = m.Config(s.name)
   273  	c.Assert(err, gc.IsNil)
   274  	c.Assert(cfg.Password, gc.Equals, "fake")
   275  
   276  }
   277  
   278  func (s *serviceManagerSuite) TestDelete(c *gc.C) {
   279  	windows.AddService(s.name, s.execPath, s.stub, svc.Status{State: svc.Running})
   280  
   281  	err := s.mgr.Delete(s.name)
   282  	c.Assert(err, gc.IsNil)
   283  	exists := s.conn.Exists(s.name)
   284  	c.Assert(exists, jc.IsFalse)
   285  }
   286  
   287  func (s *serviceManagerSuite) TestDeleteInexistent(c *gc.C) {
   288  	exists := s.conn.Exists(s.name)
   289  	c.Assert(exists, jc.IsFalse)
   290  
   291  	err := s.mgr.Delete(s.name)
   292  	c.Assert(errors.Cause(err), gc.Equals, windows.ERROR_SERVICE_DOES_NOT_EXIST)
   293  }
   294  
   295  func (s *serviceManagerSuite) TestCloseCalled(c *gc.C) {
   296  	err := s.mgr.Create(s.name, s.conf)
   297  	c.Assert(err, gc.IsNil)
   298  	s.stub.CheckCallNames(c, "CreateService", "GetHandle", "CloseHandle", "Close")
   299  	s.stub.ResetCalls()
   300  
   301  	_, err = s.mgr.Running(s.name)
   302  	c.Assert(err, gc.IsNil)
   303  	s.stub.CheckCallNames(c, "OpenService", "Query", "Close")
   304  	s.stub.ResetCalls()
   305  
   306  	err = s.mgr.Start(s.name)
   307  	c.Assert(err, gc.IsNil)
   308  	s.stub.CheckCallNames(c, "OpenService", "Query", "Close", "OpenService", "Start", "Close")
   309  	s.stub.ResetCalls()
   310  
   311  	err = s.mgr.Stop(s.name)
   312  	c.Assert(err, gc.IsNil)
   313  	s.stub.CheckCallNames(c, "OpenService", "Query", "Close", "OpenService", "Control", "Close")
   314  	s.stub.ResetCalls()
   315  
   316  	err = s.mgr.Delete(s.name)
   317  	c.Assert(err, gc.IsNil)
   318  	s.stub.CheckCallNames(c, "OpenService", "Close", "OpenService", "Control", "Close")
   319  	s.stub.ResetCalls()
   320  
   321  }