This repository has been archived by the owner on Mar 24, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #297 from alphagov/refactor-data-layer-step-1
Refactor data layer step 1
- Loading branch information
Showing
7 changed files
with
130 additions
and
10 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import os | ||
import logging | ||
import datetime | ||
from itertools import imap | ||
|
||
import pymongo | ||
from pymongo.errors import AutoReconnect | ||
from bson import Code | ||
|
||
from .. import timeutils | ||
from ... import statsd | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
__all__ = ['MongoStorageEngine'] | ||
|
||
|
||
def get_mongo_client(hosts, port): | ||
"""Return an appropriate mongo client | ||
""" | ||
client_list = ','.join(':'.join([host, str(port)]) for host in hosts) | ||
|
||
# We can't always guarantee we'll be on 'production' | ||
# so we allow jenkins to add the set as a variable | ||
# Some test environments / other envs have their own sets e.g. 'gds-ci' | ||
replica_set = os.getenv('MONGO_REPLICA_SET', 'production') | ||
|
||
if replica_set == '': | ||
return pymongo.MongoClient(client_list) | ||
else: | ||
return pymongo.MongoReplicaSetClient( | ||
client_list, replicaSet=replica_set) | ||
|
||
|
||
class MongoStorageEngine(object): | ||
@classmethod | ||
def create(cls, hosts, port, database): | ||
return cls(get_mongo_client(hosts, port), database) | ||
|
||
def __init__(self, mongo, database): | ||
self._mongo = mongo | ||
self._db = mongo[database] | ||
|
||
def alive(self): | ||
return self._mongo.alive() | ||
|
||
def dataset_exists(self, dataset_id): | ||
return dataset_id in self._db.collection_names() | ||
|
||
def create_dataset(self, dataset_id, size): | ||
if size > 0: | ||
self._db.create_collection(dataset_id, capped=True, size=size) | ||
else: | ||
self._db.create_collection(dataset_id, capped=False) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
""" | ||
Integration tests for the mongo storage engine. | ||
Unit tests are in doctest format in the module itself. | ||
""" | ||
from hamcrest import assert_that, is_, has_item, has_entries | ||
from nose.tools import assert_raises | ||
|
||
from pymongo.errors import CollectionInvalid | ||
|
||
from backdrop.core.storage.mongo import MongoStorageEngine | ||
|
||
|
||
class TestMongoStorageEngine(object): | ||
def setup(self): | ||
self.engine = MongoStorageEngine.create( | ||
['localhost'], 27017, 'backdrop_test') | ||
self.mongo = self.engine._mongo | ||
self.db = self.mongo['backdrop_test'] | ||
|
||
def teardown(self): | ||
self.mongo.drop_database('backdrop_test') | ||
|
||
# ALIVE | ||
def test_alive_returns_true_if_mongo_is_up(self): | ||
assert_that(self.engine.alive(), is_(True)) | ||
|
||
# EXISTS | ||
def test_exists_returns_false_if_data_set_does_not_exist(self): | ||
assert_that(self.engine.dataset_exists('foo_bar'), is_(False)) | ||
|
||
def test_exists_returns_true_if_data_set_exists(self): | ||
self.db.create_collection('foo_bar') | ||
|
||
assert_that(self.engine.dataset_exists('foo_bar'), is_(True)) | ||
|
||
# CREATE | ||
def test_create_a_non_capped_collection(self): | ||
self.engine.create_dataset('foo_bar', 0) | ||
|
||
assert_that(self.db.collection_names(), has_item('foo_bar')) | ||
assert_that(self.db['foo_bar'].options(), has_entries( | ||
{'capped': False})) | ||
|
||
def test_create_a_capped_collection(self): | ||
self.engine.create_dataset('foo_bar', 100) | ||
|
||
assert_that(self.db.collection_names(), has_item('foo_bar')) | ||
assert_that(self.db['foo_bar'].options(), has_entries( | ||
{'capped': True, 'size': 100})) | ||
|
||
def test_create_fails_if_collection_already_exists(self): | ||
# TODO: reraise a backdrop exception | ||
self.engine.create_dataset('foo_bar', 0) | ||
|
||
assert_raises(CollectionInvalid, | ||
self.engine.create_dataset, 'foo_bar', 0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters