Permalink
Browse files

WIP: keep database between tests

Instead of deleting the state database between tests, keep it but clear
out the collections between tests.

Doesn't work at the moment - when trying to repopulate the model after
clearing all of the collections PopulateEmptyModel hangs at
st.runTransaction.
  • Loading branch information...
1 parent 147e87a commit aa4d79e1bb8a47ac6b558c36ac9a39378d75f56a @babbageclunk committed May 13, 2016
Showing with 73 additions and 43 deletions.
  1. +29 −12 state/internal_test.go
  2. +44 −31 state/open.go
View
@@ -8,6 +8,7 @@ import (
jujutesting "github.com/juju/testing"
jc "github.com/juju/testing/checkers"
gc "gopkg.in/check.v1"
+ "gopkg.in/mgo.v2/txn"
"github.com/juju/juju/mongo"
"github.com/juju/juju/mongo/mongotest"
@@ -24,11 +25,30 @@ type internalStateSuite struct {
testing.BaseSuite
state *State
owner names.UserTag
+ model names.ModelTag
+}
+
+func getInfo() *mongo.MongoInfo {
+ // Copied from NewMongoInfo (due to import loops).
+ return &mongo.MongoInfo{
+ Info: mongo.Info{
+ Addrs: []string{jujutesting.MgoServer.Addr()},
+ CACert: testing.CACert,
+ },
+ }
}
func (s *internalStateSuite) SetUpSuite(c *gc.C) {
+ txn.SetLogger(c)
+ txn.SetDebug(true)
+
s.MgoSuite.SetUpSuite(c)
s.BaseSuite.SetUpSuite(c)
+ s.owner = names.NewLocalUserTag("test-admin")
+ st, err := Initialize(s.owner, getInfo(), testing.ModelConfig(c), mongotest.DialOpts(), nil)
+ c.Assert(err, jc.ErrorIsNil)
+ s.model = st.modelTag
+ st.Close()
}
func (s *internalStateSuite) TearDownSuite(c *gc.C) {
@@ -39,23 +59,20 @@ func (s *internalStateSuite) TearDownSuite(c *gc.C) {
func (s *internalStateSuite) SetUpTest(c *gc.C) {
s.MgoSuite.SetUpTest(c)
s.BaseSuite.SetUpTest(c)
-
- s.owner = names.NewLocalUserTag("test-admin")
- // Copied from NewMongoInfo (due to import loops).
- info := &mongo.MongoInfo{
- Info: mongo.Info{
- Addrs: []string{jujutesting.MgoServer.Addr()},
- CACert: testing.CACert,
- },
- }
- dialopts := mongotest.DialOpts()
- st, err := Initialize(s.owner, info, testing.ModelConfig(c), dialopts, nil)
+ st, err := Open(s.model, getInfo(), mongotest.DialOpts(), nil)
c.Assert(err, jc.ErrorIsNil)
s.state = st
- s.AddCleanup(func(*gc.C) { s.state.Close() })
+ s.AddCleanup(func(c *gc.C) {
+ c.Logf("closing state")
+ s.state.Close()
+ })
}
func (s *internalStateSuite) TearDownTest(c *gc.C) {
s.BaseSuite.TearDownTest(c)
s.MgoSuite.TearDownTest(c)
+ c.Logf("repopulating model")
+ err := PopulateEmptyModel(s.state, s.owner, getInfo(), testing.ModelConfig(c))
+ c.Assert(err, jc.ErrorIsNil)
+ c.Logf("leaving internalStateSuite.TearDownTest")
}
View
@@ -103,43 +103,18 @@ func mongodbLogin(session *mgo.Session, mongoInfo *mongo.MongoInfo) error {
return nil
}
-// Initialize sets up an initial empty state and returns it.
-// This needs to be performed only once for the initial controller model.
-// It returns unauthorizedError if access is unauthorized.
-func Initialize(owner names.UserTag, info *mongo.MongoInfo, cfg *config.Config, opts mongo.DialOpts, policy Policy) (_ *State, err error) {
- uuid := cfg.UUID()
- modelTag := names.NewModelTag(uuid)
- st, err := open(modelTag, info, opts, policy)
- if err != nil {
- return nil, errors.Trace(err)
- }
- defer func() {
- if err != nil {
- if closeErr := st.Close(); closeErr != nil {
- logger.Errorf("error closing state while aborting Initialize: %v", closeErr)
- }
- }
- }()
-
- // A valid model is used as a signal that the
- // state has already been initalized. If this is the case
- // do nothing.
- if _, err := st.Model(); err == nil {
- return nil, errors.New("already initialized")
- } else if !errors.IsNotFound(err) {
- return nil, errors.Trace(err)
- }
-
+func PopulateEmptyModel(st *State, owner names.UserTag, info *mongo.MongoInfo, cfg *config.Config) error {
// When creating the controller model, the new model
// UUID is also used as the controller UUID.
+ uuid := st.modelTag.Id()
logger.Infof("initializing controller model %s", uuid)
modelOps, err := st.modelSetupOps(cfg, uuid, uuid, owner, MigrationModeActive)
if err != nil {
- return nil, errors.Trace(err)
+ return errors.Trace(err)
}
salt, err := utils.RandomSalt()
if err != nil {
- return nil, err
+ return err
}
ops := []txn.Op{
createInitialUserOp(st, owner, info.Password, salt),
@@ -172,13 +147,51 @@ func Initialize(owner names.UserTag, info *mongo.MongoInfo, cfg *config.Config,
}
ops = append(ops, modelOps...)
+ logger.Infof("before run")
if err := st.runTransaction(ops); err != nil {
+ return errors.Trace(err)
+ }
+ logger.Infof("after run")
+ return nil
+}
+
+// Initialize sets up an initial empty state and returns it.
+// This needs to be performed only once for the initial controller model.
+// It returns unauthorizedError if access is unauthorized.
+func Initialize(owner names.UserTag, info *mongo.MongoInfo, cfg *config.Config, opts mongo.DialOpts, policy Policy) (_ *State, err error) {
+ uuid := cfg.UUID()
+ modelTag := names.NewModelTag(uuid)
+ logger.Debugf("Creating model %v", modelTag)
+ st, err := open(modelTag, info, opts, policy)
+ if err != nil {
return nil, errors.Trace(err)
}
- if err := st.start(modelTag); err != nil {
+ defer func() {
+ if err != nil {
+ if closeErr := st.Close(); closeErr != nil {
+ logger.Errorf("error closing state while aborting Initialize: %v", closeErr)
+ }
+ }
+ }()
+
+ // A valid model is used as a signal that the
+ // state has already been initalized. If this is the case
+ // do nothing.
+ if _, err := st.Model(); err == nil {
+ return nil, errors.New("already initialized")
+ } else if !errors.IsNotFound(err) {
return nil, errors.Trace(err)
}
- return st, nil
+
+ err = PopulateEmptyModel(st, owner, info, cfg)
+ if err != nil {
+ return nil, errors.Trace(err)
+ }
+ if err := st.start(st.modelTag); err != nil {
+ return nil, errors.Trace(err)
+ }
+ return st, err
+
}
func (st *State) modelSetupOps(cfg *config.Config, modelUUID, serverUUID string, owner names.UserTag, mode MigrationMode) ([]txn.Op, error) {

0 comments on commit aa4d79e

Please sign in to comment.