github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/apiserver/authentication/interactions_test.go (about)

     1  // Copyright 2016 Canonical Ltd. All rights reserved.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package authentication_test
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  	"gopkg.in/juju/names.v2"
    14  
    15  	"github.com/juju/juju/apiserver/authentication"
    16  	coretesting "github.com/juju/juju/testing"
    17  )
    18  
    19  type InteractionsSuite struct {
    20  	testing.IsolationSuite
    21  	interactions *authentication.Interactions
    22  }
    23  
    24  var _ = gc.Suite(&InteractionsSuite{})
    25  
    26  func (s *InteractionsSuite) SetUpTest(c *gc.C) {
    27  	s.IsolationSuite.SetUpTest(c)
    28  	s.interactions = authentication.NewInteractions()
    29  }
    30  
    31  func (s *InteractionsSuite) TestStart(c *gc.C) {
    32  	waitId, err := s.interactions.Start("caveat-id", time.Time{})
    33  	c.Assert(err, jc.ErrorIsNil)
    34  	c.Assert(waitId, gc.Not(gc.Equals), "")
    35  }
    36  
    37  func (s *InteractionsSuite) TestDone(c *gc.C) {
    38  	waitId := s.start(c, "caveat-id")
    39  	err := s.interactions.Done(waitId, names.NewUserTag("admin@local"), nil)
    40  	c.Assert(err, jc.ErrorIsNil)
    41  }
    42  
    43  func (s *InteractionsSuite) TestDoneNotFound(c *gc.C) {
    44  	err := s.interactions.Done("not-found", names.NewUserTag("admin@local"), nil)
    45  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
    46  	c.Assert(err, gc.ErrorMatches, `interaction "not-found" not found`)
    47  }
    48  
    49  func (s *InteractionsSuite) TestDoneTwice(c *gc.C) {
    50  	waitId := s.start(c, "caveat-id")
    51  	err := s.interactions.Done(waitId, names.NewUserTag("admin@local"), nil)
    52  	c.Assert(err, jc.ErrorIsNil)
    53  	err = s.interactions.Done(waitId, names.NewUserTag("admin@local"), nil)
    54  	c.Assert(err, gc.ErrorMatches, `interaction ".*" already done`)
    55  }
    56  
    57  func (s *InteractionsSuite) TestWait(c *gc.C) {
    58  	waitId := s.start(c, "caveat-id")
    59  	loginUser := names.NewUserTag("admin@local")
    60  	loginError := errors.New("login failed")
    61  	s.done(c, waitId, loginUser, loginError)
    62  	interaction, err := s.interactions.Wait(waitId, nil)
    63  	c.Assert(err, jc.ErrorIsNil)
    64  	c.Assert(interaction, gc.NotNil)
    65  	c.Assert(interaction, jc.DeepEquals, &authentication.Interaction{
    66  		CaveatId:   "caveat-id",
    67  		LoginUser:  loginUser,
    68  		LoginError: loginError,
    69  	})
    70  }
    71  
    72  func (s *InteractionsSuite) TestWaitNotFound(c *gc.C) {
    73  	interaction, err := s.interactions.Wait("not-found", nil)
    74  	c.Assert(err, gc.ErrorMatches, `interaction "not-found" not found`)
    75  	c.Assert(interaction, gc.IsNil)
    76  }
    77  
    78  func (s *InteractionsSuite) TestWaitTwice(c *gc.C) {
    79  	waitId := s.start(c, "caveat-id")
    80  	s.done(c, waitId, names.NewUserTag("admin@local"), nil)
    81  
    82  	_, err := s.interactions.Wait(waitId, nil)
    83  	c.Assert(err, jc.ErrorIsNil)
    84  
    85  	// The Wait call above should have removed the item.
    86  	_, err = s.interactions.Wait(waitId, nil)
    87  	c.Assert(err, gc.ErrorMatches, `interaction ".*" not found`)
    88  }
    89  
    90  func (s *InteractionsSuite) TestWaitCancellation(c *gc.C) {
    91  	waitId := s.start(c, "caveat-id")
    92  
    93  	cancel := make(chan struct{})
    94  	waitResult := make(chan error)
    95  	go func() {
    96  		_, err := s.interactions.Wait(waitId, cancel)
    97  		waitResult <- err
    98  	}()
    99  
   100  	// Wait should not pass until we've cancelled.
   101  	select {
   102  	case err := <-waitResult:
   103  		c.Fatalf("unexpected result: %v", err)
   104  	case <-time.After(coretesting.ShortWait):
   105  	}
   106  
   107  	cancel <- struct{}{}
   108  	select {
   109  	case err := <-waitResult:
   110  		c.Assert(err, gc.Equals, authentication.ErrWaitCanceled)
   111  	case <-time.After(coretesting.LongWait):
   112  		c.Fatalf("timed out waiting for Wait to return")
   113  	}
   114  }
   115  
   116  func (s *InteractionsSuite) TestWaitExpired(c *gc.C) {
   117  	t0 := time.Now()
   118  	t1 := t0.Add(time.Second)
   119  	t2 := t1.Add(time.Second)
   120  
   121  	waitId, err := s.interactions.Start("caveat-id", t2)
   122  	c.Assert(err, jc.ErrorIsNil)
   123  
   124  	type waitResult struct {
   125  		interaction *authentication.Interaction
   126  		err         error
   127  	}
   128  	waitResultC := make(chan waitResult)
   129  	go func() {
   130  		interaction, err := s.interactions.Wait(waitId, nil)
   131  		waitResultC <- waitResult{interaction, err}
   132  	}()
   133  
   134  	// This should do nothing, because there's nothing
   135  	// due to expire until t2.
   136  	s.interactions.Expire(t1)
   137  
   138  	// Wait should not pass until the interaction expires.
   139  	select {
   140  	case result := <-waitResultC:
   141  		c.Fatalf("unexpected result: %v", result)
   142  	case <-time.After(coretesting.ShortWait):
   143  	}
   144  
   145  	s.interactions.Expire(t2)
   146  	select {
   147  	case result := <-waitResultC:
   148  		c.Assert(result.err, gc.Equals, authentication.ErrExpired)
   149  		c.Assert(result.interaction, gc.IsNil)
   150  	case <-time.After(coretesting.LongWait):
   151  		c.Fatalf("timed out waiting for Wait to return")
   152  	}
   153  }
   154  
   155  func (s *InteractionsSuite) start(c *gc.C, caveatId string) string {
   156  	waitId, err := s.interactions.Start(caveatId, time.Time{})
   157  	c.Assert(err, jc.ErrorIsNil)
   158  	return waitId
   159  }
   160  
   161  func (s *InteractionsSuite) done(c *gc.C, waitId string, loginUser names.UserTag, loginError error) {
   162  	err := s.interactions.Done(waitId, loginUser, loginError)
   163  	c.Assert(err, jc.ErrorIsNil)
   164  }