Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge 2.6 Into Develop #10367

Merged
merged 29 commits into from
Jun 22, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
fb3ded8
Tie the watcher lifecycle to the catacomb
SimonRichardson Jun 18, 2019
f60a226
Merge pull request #10341 from SimonRichardson/1833155-watcher-leak
jujubot Jun 19, 2019
bc4821b
Improve error checks to cater for 'not found' provider errors that do…
anastasiamac Jun 20, 2019
93a5dbe
add provider level IsNotFound-equivalent methods to providers that ar…
anastasiamac Jun 20, 2019
3d6378c
add provider level IsNotFound-equivalent methods to providers that ar…
anastasiamac Jun 20, 2019
0b44fac
Rename commit command to branch. Enhance renamed branch command to
hmlanigan Jun 18, 2019
9d0975f
Add Created, CreatedBy, and CompletedBy to a Branch in the model cache,
hmlanigan Jun 20, 2019
12d2082
Merge pull request #10359 from hmlanigan/createdtomodelcache
jujubot Jun 20, 2019
208f334
Merge pull request #10346 from hmlanigan/branch
jujubot Jun 20, 2019
4023a75
diversify handling of operational compute errors.
anastasiamac Jun 20, 2019
b1d584c
Use waiterror.
anastasiamac Jun 20, 2019
9a1a7a2
Only inspect errors after all attempts to run an operation have been …
anastasiamac Jun 20, 2019
ef3098c
adjust tests
anastasiamac Jun 21, 2019
16155dd
adjust tests
anastasiamac Jun 21, 2019
25ab285
Merge pull request #10354 from anastasiamac/provider-not-found-errors-25
jujubot Jun 21, 2019
5fd7824
Merge branch '2.5' into merge-25-26-2106
anastasiamac Jun 21, 2019
501494a
Merge branch '2.5' into merge-25-26-2106
anastasiamac Jun 21, 2019
a6d900b
Merge pull request #10362 from anastasiamac/merge-25-26-2106
jujubot Jun 21, 2019
c2391c8
Fixes case where watcher for unit not tracking any branch starts trac…
manadart Jun 21, 2019
56d6c10
Merge pull request #10364 from manadart/2.6-config-watch-branch-deter…
jujubot Jun 21, 2019
d9d191f
Relocates uniter access control method generation to a new module for…
manadart Jun 20, 2019
ee944e0
Moves event matchers from the modelcache_test package to core/cache/c…
manadart Jun 21, 2019
b78e03e
Adds new testing infrastructure for filling a cache with objects from…
manadart Jun 21, 2019
b345347
Internalises events notification channel in testing cache controller.
manadart Jun 21, 2019
32e0618
Makes cachetest event matchers into function declarations instead of …
manadart Jun 21, 2019
f402984
Adds copyright header to new cachetest matchers module.
manadart Jun 21, 2019
7671273
Merge pull request #10366 from manadart/2.6-cache-testing-infrastructure
jujubot Jun 21, 2019
fec148b
Merge branch 'upstream/2.6' into 2.6-into-develop
manadart Jun 21, 2019
e89fa76
Removes call to deprecated WantsVote method in cachetest package.
manadart Jun 21, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Adds new testing infrastructure for filling a cache with objects from…
… state directly.

Recruits new test controller in logging config API server tests.
  • Loading branch information
manadart committed Jun 21, 2019
commit b78e03ec8649c40f36fa7f09b1bfd6ed41715b83
71 changes: 19 additions & 52 deletions apiserver/facades/agent/logger/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
package logger_test

import (
"time"

jc "github.com/juju/testing/checkers"
gc "gopkg.in/check.v1"
"gopkg.in/juju/names.v2"
Expand All @@ -21,7 +19,6 @@ import (
"github.com/juju/juju/core/cache/cachetest"
"github.com/juju/juju/state"
statetesting "github.com/juju/juju/state/testing"
"github.com/juju/juju/testing"
)

type loggerSuite struct {
Expand All @@ -34,11 +31,10 @@ type loggerSuite struct {
resources *common.Resources
authorizer apiservertesting.FakeAuthorizer

change cache.ModelChange
changes chan interface{}
controller *cache.Controller
events chan interface{}
capture func(change interface{})
change cache.ModelChange
ctrl *cachetest.TestController
events <-chan interface{}
capture func(change interface{})
}

var _ = gc.Suite(&loggerSuite{})
Expand All @@ -58,52 +54,26 @@ func (s *loggerSuite) SetUpTest(c *gc.C) {
Tag: s.rawMachine.Tag(),
}

s.events = make(chan interface{})
notify := func(change interface{}) {
send := false
switch change.(type) {
case cache.ModelChange:
send = true
case cache.RemoveModel:
send = true
default:
// no-op
}
if send {
c.Logf("sending %#v", change)
select {
case s.events <- change:
case <-time.After(testing.LongWait):
c.Fatalf("change not processed by test")
}
}
}
s.ctrl = cachetest.NewTestController(cachetest.ModelEvents)
s.events = s.ctrl.Init(c)

s.changes = make(chan interface{})
controller, err := cache.NewController(cache.ControllerConfig{
Changes: s.changes,
Notify: notify,
})
c.Assert(err, jc.ErrorIsNil)
s.controller = controller
s.AddCleanup(func(c *gc.C) { workertest.CleanKill(c, s.controller) })
// Add the current model to the controller.
s.change = cachetest.ModelChangeFromState(c, s.State)
s.changes <- s.change
// Ensure it is processed before we create the logger api.
select {
case <-s.events:
case <-time.After(testing.LongWait):
c.Fatalf("change not processed by test")
}
m := cachetest.ModelChangeFromState(c, s.State)
s.ctrl.SendChange(m)

// Ensure it is processed before we create the logger API.
s.ctrl.NextChange(c, s.events)

s.AddCleanup(func(c *gc.C) { workertest.CleanKill(c, s.ctrl.Controller) })

s.logger, err = s.makeLoggerAPI(s.authorizer)
c.Assert(err, jc.ErrorIsNil)
}

func (s *loggerSuite) makeLoggerAPI(auth facade.Authorizer) (*logger.LoggerAPI, error) {
ctx := facadetest.Context{
Auth_: auth,
Controller_: s.controller,
Controller_: s.ctrl.Controller,
Resources_: s.resources,
State_: s.State,
}
Expand Down Expand Up @@ -143,13 +113,10 @@ func (s *loggerSuite) TestWatchLoggingConfigNothing(c *gc.C) {
}

func (s *loggerSuite) setLoggingConfig(c *gc.C, loggingConfig string) {
s.change.Config["logging-config"] = loggingConfig
s.changes <- s.change
select {
case <-s.events:
case <-time.After(testing.LongWait):
c.Fatalf("change not processed by test")
}
m := cachetest.ModelChangeFromState(c, s.State)
m.Config["logging-config"] = loggingConfig
s.ctrl.SendChange(m)
s.ctrl.NextChange(c, s.events)
}

func (s *loggerSuite) TestWatchLoggingConfig(c *gc.C) {
Expand Down
114 changes: 114 additions & 0 deletions core/cache/cachetest/controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright 2019 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package cachetest

import (
"time"

jc "github.com/juju/testing/checkers"
gc "gopkg.in/check.v1"

"github.com/juju/juju/core/cache"
"github.com/juju/juju/state"
"github.com/juju/juju/testing"
)

// TestController wraps a cache controller for testing.
// It allows synchronisation of state objects with the cache
// without the need for a multi-watcher and cache worker.
type TestController struct {
*cache.Controller

matchers []func(interface{}) bool
changes chan interface{}
}

// NewTestController returns creates and returns a new test controller
// with an initial set of matchers for receiving cache event notifications.
// The controller can be instantiated like this in suite/test setups in order
// to retain a common set of matchers, but `Init` should be called in each
// test (see below).
func NewTestController(matchers ...func(interface{}) bool) *TestController {
return &TestController{
matchers: matchers,
}
}

// Init instantiates the inner cache controller and returns a channel for
// synchronising tests. Based on the input matchers, cache events for those
// types will be sent on the channel when the cache processes them.
//
// NOTE: It is recommended to perform this initialisation in the actual test
// method rather than `SetupSuite` or `SetupTest` as different gc.C references
// are supplied to each of those methods.
func (tc *TestController) Init(c *gc.C, matchers ...func(interface{}) bool) <-chan interface{} {
events := make(chan interface{})
matchers = append(tc.matchers, matchers...)

notify := func(change interface{}) {
send := false
for _, m := range matchers {
if m(change) {
send = true
break
}
}

if send {
c.Logf("sending %#v", change)
select {
case events <- change:
case <-time.After(testing.LongWait):
c.Fatalf("change not processed by test")
}
}
}

tc.changes = make(chan interface{})
cc, err := cache.NewController(cache.ControllerConfig{
Changes: tc.changes,
Notify: notify,
})
c.Assert(err, jc.ErrorIsNil)
tc.Controller = cc

return events
}

// UpdateModel updates the current model for the input state in the cache.
func (tc *TestController) UpdateModel(c *gc.C, m *state.Model) {
tc.SendChange(ModelChange(c, m))
}

// UpdateCharm updates the input state charm in the cache.
func (tc *TestController) UpdateCharm(modelUUID string, ch *state.Charm) {
tc.SendChange(CharmChange(modelUUID, ch))
}

// UpdateApplication updates the input state application in the cache.
func (tc *TestController) UpdateApplication(c *gc.C, modelUUID string, app *state.Application) {
tc.SendChange(ApplicationChange(c, modelUUID, app))
}

// UpdateMachine updates the input state machine in the cache.
func (tc *TestController) UpdateMachine(c *gc.C, modelUUID string, machine *state.Machine) {
tc.SendChange(MachineChange(c, modelUUID, machine))
}

func (tc *TestController) SendChange(change interface{}) {
tc.changes <- change
}

// NextChange returns the next change processed by the cache that satisfies a
// matcher, or fails the test with a time-out.
// This method should receive the channel returned by a call to `Init`.
func (tc *TestController) NextChange(c *gc.C, changes <-chan interface{}) interface{} {
var obtained interface{}
select {
case obtained = <-changes:
case <-time.After(testing.LongWait):
c.Fatalf("change not processed by test")
}
return obtained
}
Loading