github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/api/common/lifeflag/facade_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package lifeflag_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/names/v5"
     9  	"github.com/juju/testing"
    10  	jc "github.com/juju/testing/checkers"
    11  	"github.com/juju/worker/v3/workertest"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/api/base"
    15  	apitesting "github.com/juju/juju/api/base/testing"
    16  	"github.com/juju/juju/api/common/lifeflag"
    17  	"github.com/juju/juju/core/life"
    18  	"github.com/juju/juju/rpc/params"
    19  	"github.com/juju/juju/worker"
    20  )
    21  
    22  type FacadeSuite struct {
    23  	testing.IsolationSuite
    24  }
    25  
    26  var _ = gc.Suite(&FacadeSuite{})
    27  
    28  func (*FacadeSuite) TestLifeCall(c *gc.C) {
    29  	var called bool
    30  	caller := apiCaller(c, func(request string, args, _ interface{}) error {
    31  		called = true
    32  		c.Check(request, gc.Equals, "Life")
    33  		c.Check(args, jc.DeepEquals, params.Entities{
    34  			Entities: []params.Entity{{Tag: "application-blah"}},
    35  		})
    36  		return nil
    37  	})
    38  	facade := lifeflag.NewClient(caller, "LifeFlag")
    39  
    40  	facade.Life(names.NewApplicationTag("blah"))
    41  	c.Check(called, jc.IsTrue)
    42  }
    43  
    44  func (*FacadeSuite) TestLifeCallError(c *gc.C) {
    45  	caller := apiCaller(c, func(_ string, _, _ interface{}) error {
    46  		return errors.New("crunch belch")
    47  	})
    48  	facade := lifeflag.NewClient(caller, "LifeFlag")
    49  
    50  	result, err := facade.Life(names.NewApplicationTag("blah"))
    51  	c.Check(err, gc.ErrorMatches, "crunch belch")
    52  	c.Check(result, gc.Equals, life.Value(""))
    53  }
    54  
    55  func (*FacadeSuite) TestLifeNoResultsError(c *gc.C) {
    56  	caller := apiCaller(c, func(_ string, _, _ interface{}) error {
    57  		return nil
    58  	})
    59  	facade := lifeflag.NewClient(caller, "LifeFlag")
    60  
    61  	result, err := facade.Life(names.NewApplicationTag("blah"))
    62  	c.Check(err, gc.ErrorMatches, "expected 1 Life result, got 0")
    63  	c.Check(result, gc.Equals, life.Value(""))
    64  }
    65  
    66  func (*FacadeSuite) TestLifeExtraResultsError(c *gc.C) {
    67  	caller := apiCaller(c, func(_ string, _, results interface{}) error {
    68  		typed, ok := results.(*params.LifeResults)
    69  		c.Assert(ok, jc.IsTrue)
    70  		*typed = params.LifeResults{
    71  			Results: make([]params.LifeResult, 2),
    72  		}
    73  		return nil
    74  	})
    75  	facade := lifeflag.NewClient(caller, "LifeFlag")
    76  
    77  	result, err := facade.Life(names.NewApplicationTag("blah"))
    78  	c.Check(err, gc.ErrorMatches, "expected 1 Life result, got 2")
    79  	c.Check(result, gc.Equals, life.Value(""))
    80  }
    81  
    82  func (*FacadeSuite) TestLifeNotFoundError(c *gc.C) {
    83  	caller := apiCaller(c, func(_ string, _, results interface{}) error {
    84  		typed, ok := results.(*params.LifeResults)
    85  		c.Assert(ok, jc.IsTrue)
    86  		*typed = params.LifeResults{
    87  			Results: []params.LifeResult{{
    88  				Error: &params.Error{Code: params.CodeNotFound},
    89  			}},
    90  		}
    91  		return nil
    92  	})
    93  	facade := lifeflag.NewClient(caller, "LifeFlag")
    94  
    95  	result, err := facade.Life(names.NewApplicationTag("blah"))
    96  	c.Check(err, gc.Equals, lifeflag.ErrEntityNotFound)
    97  	c.Check(result, gc.Equals, life.Value(""))
    98  }
    99  
   100  func (*FacadeSuite) TestLifeInvalidResultError(c *gc.C) {
   101  	caller := apiCaller(c, func(_ string, _, results interface{}) error {
   102  		typed, ok := results.(*params.LifeResults)
   103  		c.Assert(ok, jc.IsTrue)
   104  		*typed = params.LifeResults{
   105  			Results: []params.LifeResult{{Life: "decomposed"}},
   106  		}
   107  		return nil
   108  	})
   109  	facade := lifeflag.NewClient(caller, "LifeFlag")
   110  
   111  	result, err := facade.Life(names.NewApplicationTag("blah"))
   112  	c.Check(err, gc.ErrorMatches, `life value "decomposed" not valid`)
   113  	c.Check(result, gc.Equals, life.Value(""))
   114  }
   115  
   116  func (*FacadeSuite) TestLifeSuccess(c *gc.C) {
   117  	caller := apiCaller(c, func(_ string, _, results interface{}) error {
   118  		typed, ok := results.(*params.LifeResults)
   119  		c.Assert(ok, jc.IsTrue)
   120  		*typed = params.LifeResults{
   121  			Results: []params.LifeResult{{Life: "dying"}},
   122  		}
   123  		return nil
   124  	})
   125  	facade := lifeflag.NewClient(caller, "LifeFlag")
   126  
   127  	result, err := facade.Life(names.NewApplicationTag("blah"))
   128  	c.Check(err, jc.ErrorIsNil)
   129  	c.Check(result, gc.Equals, life.Dying)
   130  }
   131  
   132  func (*FacadeSuite) TestWatchCall(c *gc.C) {
   133  	var called bool
   134  	caller := apiCaller(c, func(request string, args, _ interface{}) error {
   135  		called = true
   136  		c.Check(request, gc.Equals, "Watch")
   137  		c.Check(args, jc.DeepEquals, params.Entities{
   138  			Entities: []params.Entity{{Tag: "application-blah"}},
   139  		})
   140  		return nil
   141  	})
   142  	facade := lifeflag.NewClient(caller, "LifeFlag")
   143  
   144  	facade.Watch(names.NewApplicationTag("blah"))
   145  	c.Check(called, jc.IsTrue)
   146  }
   147  
   148  func (*FacadeSuite) TestWatchCallError(c *gc.C) {
   149  	caller := apiCaller(c, func(_ string, _, _ interface{}) error {
   150  		return errors.New("crunch belch")
   151  	})
   152  	facade := lifeflag.NewClient(caller, "LifeFlag")
   153  
   154  	watcher, err := facade.Watch(names.NewApplicationTag("blah"))
   155  	c.Check(err, gc.ErrorMatches, "crunch belch")
   156  	c.Check(watcher, gc.IsNil)
   157  }
   158  
   159  func (*FacadeSuite) TestWatchNoResultsError(c *gc.C) {
   160  	caller := apiCaller(c, func(_ string, _, _ interface{}) error {
   161  		return nil
   162  	})
   163  	facade := lifeflag.NewClient(caller, "LifeFlag")
   164  
   165  	watcher, err := facade.Watch(names.NewApplicationTag("blah"))
   166  	c.Check(err, gc.ErrorMatches, "expected 1 Watch result, got 0")
   167  	c.Check(watcher, gc.IsNil)
   168  }
   169  
   170  func (*FacadeSuite) TestWatchExtraResultsError(c *gc.C) {
   171  	caller := apiCaller(c, func(_ string, _, results interface{}) error {
   172  		typed, ok := results.(*params.NotifyWatchResults)
   173  		c.Assert(ok, jc.IsTrue)
   174  		*typed = params.NotifyWatchResults{
   175  			Results: make([]params.NotifyWatchResult, 2),
   176  		}
   177  		return nil
   178  	})
   179  	facade := lifeflag.NewClient(caller, "LifeFlag")
   180  
   181  	watcher, err := facade.Watch(names.NewApplicationTag("blah"))
   182  	c.Check(err, gc.ErrorMatches, "expected 1 Watch result, got 2")
   183  	c.Check(watcher, gc.IsNil)
   184  }
   185  
   186  func (*FacadeSuite) TestWatchNotFoundError(c *gc.C) {
   187  	caller := apiCaller(c, func(_ string, _, results interface{}) error {
   188  		typed, ok := results.(*params.NotifyWatchResults)
   189  		c.Assert(ok, jc.IsTrue)
   190  		*typed = params.NotifyWatchResults{
   191  			Results: []params.NotifyWatchResult{{
   192  				Error: &params.Error{Code: params.CodeNotFound},
   193  			}},
   194  		}
   195  		return nil
   196  	})
   197  	facade := lifeflag.NewClient(caller, "LifeFlag")
   198  
   199  	watcher, err := facade.Watch(names.NewApplicationTag("blah"))
   200  	c.Check(err, gc.Equals, lifeflag.ErrEntityNotFound)
   201  	c.Check(watcher, gc.IsNil)
   202  }
   203  
   204  func (*FacadeSuite) TestWatchSuccess(c *gc.C) {
   205  	caller := apitesting.APICallerFunc(func(facade string, version int, id, request string, arg, result interface{}) error {
   206  		switch facade {
   207  		case "LifeFlag":
   208  			c.Check(request, gc.Equals, "Watch")
   209  			c.Check(version, gc.Equals, 0)
   210  			c.Check(id, gc.Equals, "")
   211  			typed, ok := result.(*params.NotifyWatchResults)
   212  			c.Assert(ok, jc.IsTrue)
   213  			*typed = params.NotifyWatchResults{
   214  				Results: []params.NotifyWatchResult{{
   215  					NotifyWatcherId: "123",
   216  				}},
   217  			}
   218  			return nil
   219  		case "NotifyWatcher":
   220  			return worker.ErrKilled
   221  		default:
   222  			c.Fatalf("unknown facade %q", facade)
   223  			return nil
   224  		}
   225  	})
   226  	facade := lifeflag.NewClient(caller, "LifeFlag")
   227  	watcher, err := facade.Watch(names.NewApplicationTag("blah"))
   228  	c.Check(err, jc.ErrorIsNil)
   229  	workertest.CheckKilled(c, watcher)
   230  }
   231  
   232  func apiCaller(c *gc.C, check func(request string, arg, result interface{}) error) base.APICaller {
   233  	return apitesting.APICallerFunc(func(facade string, version int, id, request string, arg, result interface{}) error {
   234  		c.Check(facade, gc.Equals, "LifeFlag")
   235  		c.Check(version, gc.Equals, 0)
   236  		c.Check(id, gc.Equals, "")
   237  		return check(request, arg, result)
   238  	})
   239  }