Project

Profile

Help

Refactor #131

closed

Move pulp.server.db.connection.initialize() calls exclusively to entry points

Added by bmbouter almost 10 years ago. Updated over 5 years ago.

Status:
CLOSED - CURRENTRELEASE
Priority:
High
Assignee:
Category:
-
Sprint/Milestone:
-
Start date:
Due date:
% Done:

100%

Estimated time:
Platform Release:
2.8.0
Groomed:
Yes
Sprint Candidate:
Yes
Tags:
Pulp 2
Sprint:
March 2015
Quarter:

Description

The Problem
Throughout the production and test code for Pulp and its plugins there are many calls to pulp.server.db.connection.initialize(). Starting with Pulp 2.6.0, mongoengine caches the last initialized connection as the connection all database interaction will use. At test run-time can cause the testing database to mistakenly attach to the production database through liberal calls to connection.initialize() that occur without the server.conf being mocked. This causes horrible things to occur to Pulp development environments. Also, its sloppy to not have a structured way to connect to the database.

This also leads to a second problem which is that many of these calls to pulp.server.db.connection.initialize() are at the module level which means that simply by importing that code you are connecting to the database! A very unexpected side-effect that makes the above test-environment database switching occur depending on what you import. Ouch!

The goal
Move all of the pulp.server.db.connection.initialize() calls to the required entry point for all Pulp components to run. Each component that starts shall make exactly one call to pulp.server.db.connection.initialize() as part of the entry startup.

The Entry Points
We need to consider entry points for both the development and production uses where Pulp code will be run that need the database connection to already be initialized.

Steps
1. Each one of the entry point components above need to have exactly one call to pulp.server.db.connection.initialize()

2. All other calls to pulp.server.db.connection.initialize() needs to be removed. This includes all platform and all plugins. Search and destroy!

3. Rework pulp.server.db.connection.PulpCollectionFailure to be PulpDatabaseFailure instead.

4. pulp.server.db.connection.initialize() needs to have a behavior added that raises an Exception if it has already been called. This should enforce that a second call to initialize() will fail hard. Maybe have the exception live in the db.connection similar to PulpDatabaseFailure from step (3).

5. Add a behavior to get_collection() get_database() and get_connection() whereby if the database has not been initialized successfully a PulpDatabaseFailure (step 3) is raised. This will ensure that when the database is to be used initialize has been called at least 1 time.

6. Add test coverage for changes 2-5.

7. Fix up all unit tests likely by having them inherit from a new base class that will initialize the database as part of its setup. Many many unit tests will need to use this so that they receive a valid connection to the test database. A single call cannot be added to ./run-tests.py or pulp.devel.test_runner because the call to subprocess which actually runs the tests will not contain the database state.

Testing Concerns
Any testing code should rely on the testing entry point to provide the call to connection.initialize(). A base class approach should be used so that tests can continue to be run using nosetests directly.

  • The WSGI scripts are so simple they likely don't need to be tested at all.
  • The celery worker entry point is also very simple and can likely not be tested.
  • The celerybeat entry point can be tested because it is guarded by scheduler.setup_schedules method. We can mock the connection.initialize() before we call setup_schedules().

Related issues

Related to Pulp - Task #989: Stop pulp from handing out uninitialized database connectionsCLOSED - WONTFIX

Actions
Actions #1

Updated by bmbouter almost 10 years ago

  • Description updated (diff)
Actions #2

Updated by rbarlow almost 10 years ago

On 01/22/2015 03:31 PM, Brian Bouterse wrote:

  • The test runner used by platform and all plugins
    pulp.devel.test_runner.run_tests

<https://github.com/pulp/pulp/blob/master/devel/pulp/devel/test_runner.py#L13>

Since the test runner is not the same process as the tests, it cannot
make the call to initialize().

Actions #3

Updated by bmbouter almost 10 years ago

  • Description updated (diff)

@rbarlow, you are right about this. Because subprocess is used any pre-fork call to db.initialize() will not be kept around when the tests are run in a subprocess. I removed the step indicating that the test_runner should have the call to db.initialize(), and am instead suggesting that a base class be used by any test that needs the DB.

Actions #4

Updated by bmbouter almost 10 years ago

  • Tags Sprint Candidate added
Actions #5

Updated by mhrivnak almost 10 years ago

  • Priority changed from Normal to High
Actions #6

Updated by cduryee almost 10 years ago

  • Blocks deleted (Refactor #132: Ensure all tests can be run independantly)
Actions #7

Updated by bmbouter almost 10 years ago

  • Tags Groomed added
  • Tags deleted (Sprint Candidate)
Actions #8

Updated by bmbouter almost 10 years ago

  • Tags Sprint Candidate added
Actions #9

Updated by rbarlow over 9 years ago

  • Assignee set to rbarlow
  • Sprint/Milestone set to 14
  • Platform Release set to master
Actions #10

Updated by rbarlow over 9 years ago

  • Status changed from NEW to ASSIGNED
Actions #11

Updated by rbarlow over 9 years ago

  • Platform Release changed from master to 2.7.0
Actions #12

Updated by rbarlow over 9 years ago

  • Description updated (diff)
  • Platform Release changed from 2.7.0 to master
Actions #13

Updated by bmbouter over 9 years ago

  • Groomed set to Yes
  • Tags deleted (Groomed)
Actions #14

Updated by bmbouter over 9 years ago

  • Sprint Candidate set to Yes
  • Tags deleted (Sprint Candidate)
Actions #15

Updated by rbarlow over 9 years ago

This pull request is going to be huge. Steps 3 and 5 are not really related to the Subject of this ticket. I don't disagree with making those changes, but I believe we should do them as a separate effort to reduce the complexity of what is happening already. Separating concerns would benefit us here!

Actions #16

Updated by rbarlow over 9 years ago

I have submitted the platform PR for this[0], and now I will move on to testing the plugins against it to determine what else must be done.

[0] https://github.com/pulp/pulp/pull/1844

Actions #17

Updated by rbarlow over 9 years ago

The following plugins' tests pass with these changes in platform:
pulp_docker
pulp_openstack
pulp_ostree
pulp_puppet
pulp_python

It seems that pulp_rpm is the only plugin that will need to be adjusted for the change in platform!

Actions #18

Updated by bmbouter over 9 years ago

rbarlow wrote:

This pull request is going to be huge. Steps 3 and 5 are not really related to the Subject of this ticket. I don't disagree with making those changes, but I believe we should do them as a separate effort to reduce the complexity of what is happening already. Separating concerns would benefit us here!

@rbarlow Having a separation of concerns sounds good. Can new/tasks stories be made to track the work that isn't done with this issue?

Actions #19

Updated by rbarlow over 9 years ago

This is the change for pulp_rpm:

https://github.com/pulp/pulp_rpm/pull/682

It will fail until the platform one is merged, but merging the platform one will also break pulp_rpm's current master. Therefore, there is no way to have the Jenkins tests pass on pulp_rpm without merging the platform code, which will in turn break pulp_rpm. Chicken and egg, etc.

Actions #20

Updated by rbarlow over 9 years ago

On 05/05/2015 04:45 PM, Pulp wrote:

@rbarlow Having a separation of concerns sounds good. Can new/tasks
stories be made to track the work that isn't done with this issue?

They can be, but I'm not sure what the motivation for that change is as
it's not documented in this ticket. Perhaps it would be best if you
filed that ticket?

--
Randy Barlow

Added by rbarlow over 9 years ago

Revision d17e9e5c | View on GitHub

Ensure that tests share a single DB conenction.

Many of our tests independently connected to the database, and they did not always ensure that they were connecting to the test database. This commit fixes the tests so they all use the test database.

Additionally, this commit refactors all of the entry points such that the connection is no longer started as a side effect of importing a module. Most of our code already worked this way, but this commit refactors the Celery workers to start the database connection using a signal instead of through an import.

This commit also makes it an error for the connection to be initialized more than once.

https://pulp.plan.io/issues/131 https://pulp.plan.io/issues/460

fixes #131 fixes #460

Added by rbarlow over 9 years ago

Revision d17e9e5c | View on GitHub

Ensure that tests share a single DB conenction.

Many of our tests independently connected to the database, and they did not always ensure that they were connecting to the test database. This commit fixes the tests so they all use the test database.

Additionally, this commit refactors all of the entry points such that the connection is no longer started as a side effect of importing a module. Most of our code already worked this way, but this commit refactors the Celery workers to start the database connection using a signal instead of through an import.

This commit also makes it an error for the connection to be initialized more than once.

https://pulp.plan.io/issues/131 https://pulp.plan.io/issues/460

fixes #131 fixes #460

Actions #21

Updated by rbarlow over 9 years ago

  • Status changed from ASSIGNED to POST
Actions #22

Updated by rbarlow over 9 years ago

  • Status changed from POST to MODIFIED
  • % Done changed from 0 to 100

Added by rbarlow over 9 years ago

Revision 39da8a91 | View on GitHub

Initialize the DB connection in the test package.

Use the test package to start the database connection, rather than relying on test superclasses to do it. This way, only one database connection will happen during the unit tests rather than one per test class.

Additionally, mock all instances of alterations to the server config during testing.

https://pulp.plan.io/issues/131

re #131 re #940

Actions #23

Updated by bmbouter over 9 years ago

  • Related to Task #989: Stop pulp from handing out uninitialized database connections added
Actions #24

Updated by rbarlow about 9 years ago

  • Platform Release changed from master to 2.8.0
Actions #25

Updated by dkliban@redhat.com almost 9 years ago

  • Status changed from MODIFIED to 5
Actions #26

Updated by dkliban@redhat.com over 8 years ago

  • Status changed from 5 to CLOSED - CURRENTRELEASE
Actions #27

Updated by bmbouter almost 7 years ago

  • Sprint set to March 2015
Actions #28

Updated by bmbouter almost 7 years ago

  • Sprint/Milestone deleted (14)
Actions #29

Updated by bmbouter over 5 years ago

  • Tags Pulp 2 added

Also available in: Atom PDF