github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/apiserver/common/getstatus_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common_test
     5  
     6  import (
     7  	"fmt"
     8  	"time"
     9  
    10  	"github.com/juju/names"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/apiserver/common"
    15  	"github.com/juju/juju/apiserver/params"
    16  	apiservertesting "github.com/juju/juju/apiserver/testing"
    17  	"github.com/juju/juju/state"
    18  )
    19  
    20  type statusGetterSuite struct{}
    21  
    22  var _ = gc.Suite(&statusGetterSuite{})
    23  
    24  var _ state.StatusGetter = new(fakeStatus)
    25  
    26  func fakeServiceFromUnitTag(st state.EntityFinder, unitTag string) (common.StatusService, error) {
    27  	tag, err := names.ParseUnitTag(unitTag)
    28  	if err != nil {
    29  		return nil, err
    30  	}
    31  	entity, err := st.FindEntity(tag)
    32  	service, ok := entity.(*fakeService)
    33  	if !ok {
    34  		return nil, err
    35  	}
    36  	return service, nil
    37  }
    38  
    39  func fakeIsLeaderCheck(_ state.EntityFinder, _ string) (bool, error) {
    40  	return true, nil
    41  }
    42  
    43  type fakeService struct {
    44  	tag         names.Tag
    45  	status      state.StatusInfo
    46  	statusError error
    47  
    48  	unitsStatus      map[string]state.StatusInfo
    49  	unitsStatusError error
    50  	serviceStatus    state.StatusInfo
    51  	err              error
    52  	fetchError
    53  }
    54  
    55  func (s *fakeService) Status() (state.StatusInfo, error) {
    56  	return s.status, s.statusError
    57  }
    58  
    59  func (s *fakeService) ServiceAndUnitsStatus() (state.StatusInfo, map[string]state.StatusInfo, error) {
    60  	return s.status, s.unitsStatus, s.unitsStatusError
    61  }
    62  
    63  func (s *fakeService) Tag() names.Tag {
    64  	return s.tag
    65  }
    66  
    67  func (s *fakeService) SetStatus(status state.Status, info string, data map[string]interface{}) error {
    68  	s.serviceStatus.Status = status
    69  	s.serviceStatus.Message = info
    70  	s.serviceStatus.Data = data
    71  	updated := time.Now()
    72  	s.serviceStatus.Since = &updated
    73  	return s.err
    74  }
    75  
    76  func (*statusGetterSuite) TestServiceStatus(c *gc.C) {
    77  	now := time.Now()
    78  	st := &fakeState{
    79  		entities: map[names.Tag]entityWithError{
    80  			u("x/1"): &fakeService{
    81  				tag: serviceTag("wordpress-1"),
    82  				status: state.StatusInfo{
    83  					Status:  state.StatusActive,
    84  					Message: "foo service",
    85  					Since:   &now,
    86  				},
    87  				statusError: nil,
    88  				unitsStatus: map[string]state.StatusInfo{
    89  					"unit-x-1": state.StatusInfo{
    90  						Status:  state.StatusActive,
    91  						Message: "foo",
    92  						Since:   &now,
    93  					},
    94  					"unit-x-2": state.StatusInfo{
    95  						Status:  state.StatusActive,
    96  						Message: "foo 2",
    97  						Since:   &now,
    98  					},
    99  				},
   100  				unitsStatusError: nil,
   101  			},
   102  		},
   103  	}
   104  
   105  	expected := params.ServiceStatusResults{
   106  		Results: []params.ServiceStatusResult{
   107  			params.ServiceStatusResult{
   108  				Service: params.StatusResult{
   109  					Error:  nil,
   110  					Id:     "",
   111  					Life:   "",
   112  					Status: "active",
   113  					Info:   "foo service",
   114  					Data:   nil,
   115  					Since:  &now,
   116  				},
   117  				Units: map[string]params.StatusResult{
   118  					"unit-x-1": params.StatusResult{
   119  						Error:  nil,
   120  						Id:     "",
   121  						Life:   "",
   122  						Status: "active",
   123  						Info:   "foo",
   124  						Data:   nil,
   125  						Since:  &now,
   126  					},
   127  					"unit-x-2": params.StatusResult{
   128  						Error:  nil,
   129  						Id:     "",
   130  						Life:   "",
   131  						Status: "active",
   132  						Info:   "foo 2",
   133  						Data:   nil,
   134  						Since:  &now,
   135  					},
   136  				},
   137  				Error: nil},
   138  		},
   139  	}
   140  	getCanAccess := func() (common.AuthFunc, error) {
   141  		return func(tag names.Tag) bool { return true }, nil
   142  	}
   143  
   144  	args := params.Entities{
   145  		Entities: []params.Entity{
   146  			params.Entity{
   147  				Tag: "unit-x-1",
   148  			},
   149  		},
   150  	}
   151  
   152  	sg := common.NewServiceStatusGetter(st, getCanAccess)
   153  	result, err := common.ServiceStatus(sg, args, fakeServiceFromUnitTag, fakeIsLeaderCheck)
   154  	c.Assert(err, jc.ErrorIsNil)
   155  	c.Assert(result, gc.DeepEquals, expected)
   156  }
   157  
   158  func (*statusGetterSuite) TestServiceStatusNotLeader(c *gc.C) {
   159  	now := time.Now()
   160  	leaderCheck := func(_ state.EntityFinder, tag string) (bool, error) {
   161  		return false, nil
   162  	}
   163  
   164  	getCanAccess := func() (common.AuthFunc, error) {
   165  		return func(tag names.Tag) bool { return true }, nil
   166  	}
   167  
   168  	st := &fakeState{
   169  		entities: map[names.Tag]entityWithError{
   170  			u("x/1"): &fakeService{
   171  				tag: serviceTag("wordpress-1"),
   172  				status: state.StatusInfo{
   173  					Status:  state.StatusActive,
   174  					Message: "foo service",
   175  					Since:   &now,
   176  				},
   177  				statusError: nil,
   178  				unitsStatus: map[string]state.StatusInfo{
   179  					"unit-x-1": state.StatusInfo{
   180  						Status:  state.StatusActive,
   181  						Message: "foo",
   182  						Since:   &now,
   183  					},
   184  					"unit-x-2": state.StatusInfo{
   185  						Status:  state.StatusActive,
   186  						Message: "foo 2",
   187  						Since:   &now,
   188  					},
   189  				},
   190  				unitsStatusError: nil,
   191  			},
   192  		},
   193  	}
   194  
   195  	expected := params.ServiceStatusResults{
   196  		Results: []params.ServiceStatusResult{
   197  			{
   198  				Service: params.StatusResult{
   199  					Error:  nil,
   200  					Id:     "",
   201  					Life:   "",
   202  					Status: "",
   203  					Info:   "",
   204  					Data:   nil,
   205  					Since:  nil},
   206  				Units: map[string]params.StatusResult(nil),
   207  				Error: &params.Error{"this unit is not the leader", ""},
   208  			},
   209  		},
   210  	}
   211  	args := params.Entities{
   212  		Entities: []params.Entity{
   213  			params.Entity{
   214  				Tag: "unit-x-1",
   215  			},
   216  		},
   217  	}
   218  
   219  	sg := common.NewServiceStatusGetter(st, getCanAccess)
   220  	result, err := common.ServiceStatus(sg, args, fakeServiceFromUnitTag, leaderCheck)
   221  	c.Assert(err, jc.ErrorIsNil)
   222  	c.Assert(result, gc.DeepEquals, expected)
   223  
   224  }
   225  
   226  func (*statusGetterSuite) TestStatus(c *gc.C) {
   227  	st := &fakeState{
   228  		entities: map[names.Tag]entityWithError{
   229  			u("x/0"): &fakeStatus{status: state.StatusAllocating, info: "blah", err: fmt.Errorf("x0 fails")},
   230  			u("x/1"): &fakeStatus{status: state.StatusInstalling, info: "blah"},
   231  			u("x/2"): &fakeStatus{status: state.StatusActive, info: "foo"},
   232  			u("x/3"): &fakeStatus{status: state.StatusError, info: "some info", data: map[string]interface{}{"foo": "bar"}},
   233  			u("x/4"): &fakeStatus{fetchError: "x3 error"},
   234  			u("x/5"): &fakeStatus{status: state.StatusStopping, info: "blah"},
   235  		},
   236  	}
   237  	getCanAccess := func() (common.AuthFunc, error) {
   238  		x0 := u("x/0")
   239  		x1 := u("x/1")
   240  		x2 := u("x/2")
   241  		x3 := u("x/3")
   242  		x4 := u("x/4")
   243  		x5 := u("x/5")
   244  		return func(tag names.Tag) bool {
   245  			return tag == x0 || tag == x1 || tag == x2 || tag == x3 || tag == x4 || tag == x5
   246  		}, nil
   247  	}
   248  	s := common.NewStatusGetter(st, getCanAccess)
   249  	args := params.Entities{
   250  		Entities: []params.Entity{
   251  			{"unit-x-0"},
   252  			{"unit-x-1"},
   253  			{"unit-x-2"},
   254  			{"unit-x-3"},
   255  			{"unit-x-4"},
   256  			{"unit-x-5"},
   257  			{"unit-x-6"},
   258  			{"unit-x-7"},
   259  			{"machine-1"},
   260  			{"invalid"},
   261  		},
   262  	}
   263  	result, err := s.Status(args)
   264  	c.Assert(err, jc.ErrorIsNil)
   265  	// Zero out the updated timestamps so we can easily check the results.
   266  	for i, statusResult := range result.Results {
   267  		r := statusResult
   268  		if r.Status != "" {
   269  			c.Assert(r.Since, gc.NotNil)
   270  		}
   271  		r.Since = nil
   272  		result.Results[i] = r
   273  	}
   274  	c.Assert(result, gc.DeepEquals, params.StatusResults{
   275  		Results: []params.StatusResult{
   276  			{Status: "allocating", Info: "blah", Error: &params.Error{Message: "x0 fails"}},
   277  			{Status: "installing", Info: "blah"},
   278  			{Status: "active", Info: "foo"},
   279  			{Status: "error", Info: "some info", Data: map[string]interface{}{"foo": "bar"}},
   280  			{Error: &params.Error{Message: "x3 error"}},
   281  			{Status: "stopping", Info: "blah"},
   282  			{Error: apiservertesting.ErrUnauthorized},
   283  			{Error: apiservertesting.ErrUnauthorized},
   284  			{Error: apiservertesting.ErrUnauthorized},
   285  			{Error: apiservertesting.ServerError(`"invalid" is not a valid tag`)},
   286  		},
   287  	})
   288  }
   289  
   290  func (*statusGetterSuite) TestStatusError(c *gc.C) {
   291  	getCanAccess := func() (common.AuthFunc, error) {
   292  		return nil, fmt.Errorf("pow")
   293  	}
   294  	s := common.NewStatusGetter(&fakeState{}, getCanAccess)
   295  	args := params.Entities{
   296  		Entities: []params.Entity{{"x0"}},
   297  	}
   298  	_, err := s.Status(args)
   299  	c.Assert(err, gc.ErrorMatches, "pow")
   300  }