Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(2818)

Issue 6348053: state/ZooKeeper test consistency

Can't Edit
Can't Publish+Mail
Start Review
Created:
11 years, 10 months ago by fwereade
Modified:
11 years, 10 months ago
Reviewers:
mp+112721
Visibility:
Public.

Description

state/ZooKeeper test consistency OK, this is a *monster* of a change, and I'm sorry for that; but the niggling frustrations of duplicated and subtly inconsistent test code across packages, and of the poor organisation of the state tests, have become a serious mental drain. All the following changes are interrelated to a greater or lesser extent, and my judgment is that while I could express this change as a long pipeline it would in fact be counterproductive to do so; a big bang merge is actually going to save us all time. Yes, even you, dear reviewer. This will be explained shortly; in the meantime, here's a sketch of the changes in this CL: 1) ZooKeeper setup and maintenance has been consolidated Every test package that wants to use a ZooKeeper server should register its tests by calling testing.ZkTestPackage; every such test suite should embed and use testing.ZkSuite, which will clear out the server at the end of each test. See testing/zk.go. Note that this simplifies the use of the dummy environ, which now expects client test packages to use ZkTestPackage, and determines the test server by inspecting the testing package directly; it also removes boilerplate from internal state tests, and from the tests for state's subpackages. 2) State test setup and maintenance has been consolidated Every test that wishes to use a *state.State should embed and use state/testing.StateSuite, which will supply a freshly Initialized State to each test method. This simplifies the testing for container, and for several cmd subpackages, not to mention for the state package itself. 3) StateSuite has been split up into broadly logical chunks Essentially, StateSuite is for testing methods on State; it will occasionally touch instances of other types returned from State methods, but only in service of testing the State type. (oh, yeah, and testing the diff function, because I couldn't think of anywhere better to put the tests, which are certainly too small to deserve a file of their own). Tests for other types are generally in their own files, with their own suites, and include the tests for the watchers returned by that type's methods; the commonality of implementation of watchers means it's sensible to keep the implementations in the same file, but there's little justification for smooshing all the tests together when each test is far more closely connected with the type that returns it than with the general concept of "watcher". Exceptions to this rule are assign_test, which collects all the unit/machine assignment tests into one place; and relation_test, which should perhaps more properly be part of StateSuite according to the logic above, but which is in fact far more concerned with testing the details of the relations than with the fact that they happen to be created by State. In general, the type-specific tests have had common setup code moved to SetUpTest and are otherwise unmodified; in a couple of cases, factoring the common behaviour into one place led to sufficiently weird/ugly looking tests that they have been modified slightly for readability. A number of tests appears to be asserting more-or-less insane behaviour; these have been flagged with TODO BUG but I have no interest whatsoever in mixing functionality changes into this CL, on the basis that it would divert the team's precious time and creativity into groudbreaking methods of stabbing me over the intrnet. 4) state package internals have been rearranged slightly This is mainly about the internal tests -- internal_test.go has been split into topology_test.go and confignode_test.go -- but I also took the opportunity to move ConfigNode, and supporting code, into a new confignode.go file, because it was taking up the vast majority of util.go, and the ickiness was again impossible to ignore. 5) cmd/jujuc/server.UnitFixture renamed to UnitSuite For consistency's sake. 6) cmd/jujud/main_test moved into cmd/jujud And is now actually run again. 7) state/presence test stability fixes * hugely increasing pinger periods and timeouts to account for observed behaviour * adding diagnostic Debugfs that should be useful should we encounter further issues * rearranging Pinger.Stop and .Kill such that Kill can always be called safely * consequently adding defered Kills to all test Pingers, ensuring they don't live beyond their intended lifetime and cause cascading failures in other tests ~~~~~ Almost all the above changes are necesary for me to start working on state.Initialize, which is a prerequisite for correct handling of the default-series environment setting; as soon as I change its behaviour it will have far-reaching effects across the codebase, and the prospect of sorting those out without the above consolidations in place (and the prospect of the further subtle inconsistencies that would sneak in were I to attempt to do so) gives me the screaming heebie-jeebies. The changes that are not strictly necessary have been done anyway, because it's incredibly hard to achieve consistency when aiming at a moving target. By imposing them all at the same time, we actually reach a consistent state and thereby have the best chance of maintaining it for a while, and saving ourselves the subtle but debilitating low-level headaches that come from an inadequately tended source tree. I hope. ~~~~~ There are a number of additional changes I have resisted the temptation to address; most importantly, the state_test.ConnSuite is problematic, because it is the single component that splurges zookeeper dependencies across all the state tests that depend on it. Our testing of underlying zookeeper state is extremely inconsistent, and isolating it felt too much like too much more hard work; but if we *can* isolate all the tests that inspect/modify zookeeper directly, then it should become possible to use the other, non-polluted, tests to verify both state and mstate; which would be *awesome*. I also didn't hit mstate at all, because I suspect it's still in a somewhat churny situation; conversely, AFAIK, only myself and TheMue are currently touching state, and TheMue only with a single branch that's still WIP; my situation is more delicate, but I consider the slight extra hassle of resolving the conflicts to be a small price to pay for the benefits. ~~~~~ TLDR: we had to do this, and it's less complicated than it looks. https://code.launchpad.net/~fwereade/juju-core/vast-zookeeper-tests-cleanup/+merge/112721 (do not edit description out of merge proposal)

Patch Set 1 #

Total comments: 11

Patch Set 2 : Fix state and zookeeper tests #

Patch Set 3 : state/ZooKeeper test consistency #

Patch Set 4 : state/ZooKeeper test consistency #

Total comments: 10

Patch Set 5 : state/ZooKeeper test consistency #

Total comments: 14

Patch Set 6 : state/ZooKeeper test consistency #

Unified diffs Side-by-side diffs Delta from patch set Stats (+2673 lines, -3006 lines) Patch
A [revision details] View 1 2 3 4 5 1 chunk +2 lines, -0 lines 0 comments Download
M cmd/juju/main_test.go View 1 2 3 4 5 2 chunks +2 lines, -6 lines 0 comments Download
M cmd/jujuc/server/config-get_test.go View 1 chunk +2 lines, -2 lines 0 comments Download
M cmd/jujuc/server/ports_test.go View 1 chunk +1 line, -1 line 0 comments Download
M cmd/jujuc/server/unit-get_test.go View 1 chunk +2 lines, -2 lines 0 comments Download
M cmd/jujuc/server/util_test.go View 1 2 3 4 5 2 chunks +19 lines, -54 lines 0 comments Download
M cmd/jujud/initzk_test.go View 1 chunk +3 lines, -6 lines 0 comments Download
M cmd/jujud/machine_test.go View 1 2 3 4 5 5 chunks +20 lines, -37 lines 0 comments Download
M cmd/jujud/main_test.go View 2 chunks +9 lines, -5 lines 0 comments Download
M cmd/jujud/provisioning_test.go View 1 2 3 4 5 2 chunks +1 line, -15 lines 0 comments Download
D cmd/jujud/suite_test.go View 1 chunk +0 lines, -48 lines 0 comments Download
M container/container_test.go View 1 2 3 4 5 3 chunks +7 lines, -30 lines 0 comments Download
M environs/dummy/environs.go View 4 chunks +8 lines, -25 lines 0 comments Download
M environs/dummy/environs_test.go View 2 chunks +2 lines, -6 lines 0 comments Download
M juju/conn_test.go View 2 chunks +2 lines, -6 lines 0 comments Download
M service/provisioner/provisioner_test.go View 1 2 3 4 5 22 chunks +53 lines, -50 lines 0 comments Download
D service/provisioner/suite_test.go View 1 2 3 4 5 1 chunk +0 lines, -48 lines 0 comments Download
A state/assign_test.go View 1 2 3 4 5 1 chunk +228 lines, -0 lines 0 comments Download
A state/charm_test.go View 1 2 3 4 5 1 chunk +41 lines, -0 lines 0 comments Download
A state/confignode.go View 1 1 chunk +244 lines, -0 lines 0 comments Download
A state/confignode_test.go View 1 1 chunk +325 lines, -0 lines 0 comments Download
M state/export_test.go View 1 chunk +1 line, -2 lines 0 comments Download
A state/machine_test.go View 1 2 3 4 5 1 chunk +284 lines, -0 lines 0 comments Download
M state/presence/presence.go View 1 2 3 4 5 6 chunks +85 lines, -22 lines 0 comments Download
M state/presence/presence_test.go View 1 2 3 4 5 12 chunks +58 lines, -104 lines 0 comments Download
M state/relation_internal_test.go View 3 chunks +5 lines, -19 lines 0 comments Download
A state/relation_test.go View 1 2 3 4 5 1 chunk +146 lines, -0 lines 0 comments Download
A state/service_test.go View 1 2 3 4 5 1 chunk +381 lines, -0 lines 0 comments Download
M state/ssh_test.go View 1 2 3 4 5 3 chunks +8 lines, -7 lines 0 comments Download
M state/state_test.go View 1 2 3 4 5 7 chunks +221 lines, -1227 lines 0 comments Download
A state/testing/testing.go View 1 2 3 4 5 1 chunk +48 lines, -0 lines 0 comments Download
M state/topology_test.go View 1 2 chunks +4 lines, -360 lines 0 comments Download
A state/unit_test.go View 1 2 3 4 5 1 chunk +352 lines, -0 lines 0 comments Download
M state/util.go View 1 3 chunks +15 lines, -239 lines 0 comments Download
M state/watcher.go View 1 1 chunk +0 lines, -14 lines 0 comments Download
M state/watcher/watcher_test.go View 5 chunks +12 lines, -35 lines 0 comments Download
D state/watcher_test.go View 1 1 chunk +0 lines, -605 lines 0 comments Download
M testing/zk.go View 1 2 3 4 5 3 chunks +82 lines, -31 lines 0 comments Download

Messages

Total messages: 7
dave_cheney.net
I like this a lot. Thank you for cleaning this up. https://codereview.appspot.com/6348053/diff/1/cmd/jujuc/server/util_test.go File cmd/jujuc/server/util_test.go (right): ...
11 years, 10 months ago (2012-06-29 08:35:20 UTC) #1
fwereade
Please take a look. https://codereview.appspot.com/6348053/diff/1/cmd/jujuc/server/util_test.go File cmd/jujuc/server/util_test.go (right): https://codereview.appspot.com/6348053/diff/1/cmd/jujuc/server/util_test.go#newcode11 cmd/jujuc/server/util_test.go:11: coretesting "launchpad.net/juju-core/testing" On 2012/06/29 08:35:20, ...
11 years, 10 months ago (2012-06-29 13:22:42 UTC) #2
TheMue
Like Dave I really appreciate this change. It's a large one, yes. But the result ...
11 years, 10 months ago (2012-06-29 14:57:48 UTC) #3
TheMue
https://codereview.appspot.com/6348053/diff/8001/state/state_test.go File state/state_test.go (right): https://codereview.appspot.com/6348053/diff/8001/state/state_test.go#newcode95 state/state_test.go:95: type any map[string]interface{} Isn't related to this change, bit ...
11 years, 10 months ago (2012-06-29 14:58:08 UTC) #4
fwereade
Please take a look. https://codereview.appspot.com/6348053/diff/1/testing/zk.go File testing/zk.go (right): https://codereview.appspot.com/6348053/diff/1/testing/zk.go#newcode20 testing/zk.go:20: func FindTCPPort() int { On ...
11 years, 10 months ago (2012-06-29 15:52:15 UTC) #5
niemeyer
This is *brilliant*. Thank you so much, William. LGTM assuming that: 1) The trivials below ...
11 years, 10 months ago (2012-07-02 23:34:40 UTC) #6
fwereade
11 years, 10 months ago (2012-07-03 21:44:16 UTC) #7
*** Submitted:

state/ZooKeeper test consistency

OK, this is a *monster* of a change, and I'm sorry for that; but the
niggling frustrations of duplicated and subtly inconsistent test code
across packages, and of the poor organisation of the state tests, have
become a serious mental drain. All the following changes are interrelated
to a greater or lesser extent, and my judgment is that while I could
express this change as a long pipeline it would in fact be counterproductive
to do so; a big bang merge is actually going to save us all time.

Yes, even you, dear reviewer. This will be explained shortly; in the
meantime, here's a sketch of the changes in this CL:

1) ZooKeeper setup and maintenance has been consolidated

Every test package that wants to use a ZooKeeper server should register its
tests by calling testing.ZkTestPackage; every such test suite should embed
and use testing.ZkSuite, which will clear out the server at the end of each
test. See testing/zk.go.

Note that this simplifies the use of the dummy environ, which now expects
client test packages to use ZkTestPackage, and determines the test server
by inspecting the testing package directly; it also removes boilerplate from
internal state tests, and from the tests for state's subpackages.

2) State test setup and maintenance has been consolidated

Every test that wishes to use a *state.State should embed and use
state/testing.StateSuite, which will supply a freshly Initialized State to
each test method.

This simplifies the testing for container, and for several cmd subpackages,
not to mention for the state package itself.

3) StateSuite has been split up into broadly logical chunks

Essentially, StateSuite is for testing methods on State; it will
occasionally touch instances of other types returned from State methods, but
only in service of testing the State type. (oh, yeah, and testing the diff
function, because I couldn't think of anywhere better to put the tests,
which are certainly too small to deserve a file of their own).

Tests for other types are generally in their own files, with their own
suites, and include the tests for the watchers returned by that type's
methods; the commonality of implementation of watchers means it's sensible
to keep the implementations in the same file, but there's little
justification for smooshing all the tests together when each test is far
more closely connected with the type that returns it than with the general
concept of "watcher".

Exceptions to this rule are assign_test, which collects all the unit/machine
assignment tests into one place; and relation_test, which should perhaps
more properly be part of StateSuite according to the logic above, but which
is in fact far more concerned with testing the details of the relations than
with the fact that they happen to be created by State.

In general, the type-specific tests have had common setup code moved to
SetUpTest and are otherwise unmodified; in a couple of cases, factoring the
common behaviour into one place led to sufficiently weird/ugly looking tests
that they have been modified slightly for readability.

A number of tests appears to be asserting more-or-less insane behaviour;
these have been flagged with TODO BUG but I have no interest whatsoever in
mixing functionality changes into this CL, on the basis that it would divert
the team's precious time and creativity into groudbreaking methods of
stabbing me over the intrnet.

4) state package internals have been rearranged slightly

This is mainly about the internal tests -- internal_test.go has been split
into topology_test.go and confignode_test.go -- but I also took the
opportunity to move ConfigNode, and supporting code, into a new
confignode.go file, because it was taking up the vast majority of util.go,
and the ickiness was again impossible to ignore.

5) cmd/jujuc/server.UnitFixture renamed to UnitSuite

For consistency's sake.

6) cmd/jujud/main_test moved into cmd/jujud

And is now actually run again.

7) state/presence test stability fixes

* hugely increasing pinger periods and timeouts to account for observed
  behaviour
* adding diagnostic Debugfs that should be useful should we encounter
  further issues
* rearranging Pinger.Stop and .Kill such that Kill can always be called
  safely
* consequently adding defered Kills to all test Pingers, ensuring they don't
  live beyond their intended lifetime and cause cascading failures in other
  tests

~~~~~

Almost all the above changes are necesary for me to start working on
state.Initialize, which is a prerequisite for correct handling of the
default-series environment setting; as soon as I change its behaviour it
will have far-reaching effects across the codebase, and the prospect of
sorting those out without the above consolidations in place (and the
prospect of the further subtle inconsistencies that would sneak in were I to
attempt to do so) gives me the screaming heebie-jeebies.

The changes that are not strictly necessary have been done anyway, because
it's incredibly hard to achieve consistency when aiming at a moving target.
By imposing them all at the same time, we actually reach a consistent state
and thereby have the best chance of maintaining it for a while, and saving
ourselves the subtle but debilitating low-level headaches that come from an
inadequately tended source tree. I hope.

~~~~~

There are a number of additional changes I have resisted the temptation to
address; most importantly, the state_test.ConnSuite is problematic, because
it is the single component that splurges zookeeper dependencies across all
the state tests that depend on it. Our testing of underlying zookeeper state
is extremely inconsistent, and isolating it felt too much like too much more
hard work; but if we *can* isolate all the tests that inspect/modify
zookeeper directly, then it should become possible to use the other,
non-polluted, tests to verify both state and mstate; which would be
*awesome*.

I also didn't hit mstate at all, because I suspect it's still in a somewhat
churny situation; conversely, AFAIK, only myself and TheMue are currently
touching state, and TheMue only with a single branch that's still WIP; my
situation is more delicate, but I consider the slight extra hassle of
resolving the conflicts to be a small price to pay for the benefits.

~~~~~

TLDR: we had to do this, and it's less complicated than it looks.

R=dfc, TheMue, niemeyer
CC=
https://codereview.appspot.com/6348053

https://codereview.appspot.com/6348053/diff/8001/state/testing/testing.go
File state/testing/testing.go (right):

https://codereview.appspot.com/6348053/diff/8001/state/testing/testing.go#new...
state/testing/testing.go:15: St *state.State
On 2012/07/02 23:34:40, niemeyer wrote:
> On 2012/06/29 15:52:16, fwereade wrote:
> > On 2012/06/29 14:58:08, TheMue wrote:
> > > Would like to name this State. The usage with s.St.DoSomething() reads
> somehow
> > > strange.
> > 
> > I'm -1 on this; I've got very used to the .st (or I guess .St) usage.
Further
> > opinions, anyone?
> 
> Although I do agree that st is a great variable name to use all around when
> referring to the state, I'm with Dave on this one in that such a public field
> would be more typically named as State. We can easily shorthand it with st :=
> s.State and have an even more convenient name when it does make a difference.

SGTM. Done.

https://codereview.appspot.com/6348053/diff/1030/state/service_test.go
File state/service_test.go (right):

https://codereview.appspot.com/6348053/diff/1030/state/service_test.go#newcode33
state/service_test.go:33: // to a known charm??
On 2012/07/02 23:34:41, niemeyer wrote:
> Yes. In fact, we shouldn't even allow changing the URL like that. This method
> should really take a *state.Charm instead.
> 
> Can you please link to this bug from the comment:
> 
> https://bugs.launchpad.net/juju-core/+bug/1020318

Done.

https://codereview.appspot.com/6348053/diff/1030/state/service_test.go#newcode71
state/service_test.go:71: // TODO BUG this doesn't appear to be sane.
On 2012/07/02 23:34:41, niemeyer wrote:
> Yes, can you please just drop this test entirely?

Done.

https://codereview.appspot.com/6348053/diff/1030/state/service_test.go#newcod...
state/service_test.go:181: // TODO BUG is this sane?
On 2012/07/02 23:34:41, niemeyer wrote:
> Hmmm.. this seems mostly alright. The message is confusing, though. It should
> just say "unit not found" or similar.

Added bug link.

https://codereview.appspot.com/6348053/diff/1030/state/service_test.go#newcod...
state/service_test.go:192: c.Assert(err, ErrorMatches, `can't get unit
"wordpress/0": can't get service "wordpress": service with name "wordpress" not
found`)
On 2012/07/02 23:34:41, niemeyer wrote:
> Unrelated, but this error message isn't great. Filed a bug.

Noted.

https://codereview.appspot.com/6348053/diff/1030/state/ssh_test.go
File state/ssh_test.go (right):

https://codereview.appspot.com/6348053/diff/1030/state/ssh_test.go#newcode254
state/ssh_test.go:254: //  error starting ssh (sshd not up)
On 2012/07/02 23:34:41, niemeyer wrote:
> I don't mind removing the alignment with TODO, but let's please remove all
> indentation then, otherwise we're not here nor there.

Done.

https://codereview.appspot.com/6348053/diff/1030/state/state_test.go
File state/state_test.go (right):

https://codereview.appspot.com/6348053/diff/1030/state/state_test.go#newcode26
state/state_test.go:26: // eventually have a single set of tests that work
against both state and
On 2012/07/02 23:34:41, niemeyer wrote:
> We should really only be doing this if there's an advantage in doing that by
> itself, out of the sharing aspect. The plan isn't to maintain those two
packages
> in parallel, but rather to kill the losing one as soon as we can make a
> decision.

Understood, but reducing direct ZK dependencies in the existing tests is
worthwhile all the same :).

https://codereview.appspot.com/6348053/diff/1030/state/state_test.go#newcode275
state/state_test.go:275: func (s *StateSuite) TestWatchMachines(c *C) {
On 2012/07/02 23:34:41, niemeyer wrote:
> This looks more suitable for machine_test.go.

I *think* this is the right place... we're tweaking a State to induce changes in
a watcher taken directly from that State. By contrast, the MachineSuite is more
concerned with tests of the actual behaviour of Machine instances themselves.
Sign in to reply to this message.

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b