removed all references to keeper
This commit is contained in:
@@ -239,7 +239,6 @@ class Project(Group):
|
|||||||
def __init__(self, id, project_manager_id, description, member_ids):
|
def __init__(self, id, project_manager_id, description, member_ids):
|
||||||
self.project_manager_id = project_manager_id
|
self.project_manager_id = project_manager_id
|
||||||
super(Project, self).__init__(id, description, member_ids)
|
super(Project, self).__init__(id, description, member_ids)
|
||||||
self.keeper = datastore.Keeper(prefix="project-")
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def project_manager(self):
|
def project_manager(self):
|
||||||
|
|||||||
@@ -21,19 +21,10 @@
|
|||||||
"""
|
"""
|
||||||
Datastore:
|
Datastore:
|
||||||
|
|
||||||
Providers the Keeper class, a simple pseudo-dictionary that
|
|
||||||
persists on disk.
|
|
||||||
|
|
||||||
MAKE Sure that ReDIS is running, and your flags are set properly,
|
MAKE Sure that ReDIS is running, and your flags are set properly,
|
||||||
before trying to run this.
|
before trying to run this.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import sqlite3
|
|
||||||
import time
|
|
||||||
|
|
||||||
from nova import vendor
|
from nova import vendor
|
||||||
import redis
|
import redis
|
||||||
|
|
||||||
@@ -42,15 +33,11 @@ from nova import utils
|
|||||||
|
|
||||||
|
|
||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
flags.DEFINE_string('datastore_path', utils.abspath('../keeper'),
|
|
||||||
'where keys are stored on disk')
|
|
||||||
flags.DEFINE_string('redis_host', '127.0.0.1',
|
flags.DEFINE_string('redis_host', '127.0.0.1',
|
||||||
'Host that redis is running on.')
|
'Host that redis is running on.')
|
||||||
flags.DEFINE_integer('redis_port', 6379,
|
flags.DEFINE_integer('redis_port', 6379,
|
||||||
'Port that redis is running on.')
|
'Port that redis is running on.')
|
||||||
flags.DEFINE_integer('redis_db', 0, 'Multiple DB keeps tests away')
|
flags.DEFINE_integer('redis_db', 0, 'Multiple DB keeps tests away')
|
||||||
flags.DEFINE_string('keeper_backend', 'redis',
|
|
||||||
'which backend to use for keeper')
|
|
||||||
|
|
||||||
|
|
||||||
class Redis(object):
|
class Redis(object):
|
||||||
@@ -61,247 +48,9 @@ class Redis(object):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def instance(cls):
|
def instance(cls):
|
||||||
if not hasattr(cls, '_instance'):
|
if not hasattr(cls, '_instance'):
|
||||||
inst = redis.Redis(host=FLAGS.redis_host, port=FLAGS.redis_port, db=FLAGS.redis_db)
|
inst = redis.Redis(host=FLAGS.redis_host,
|
||||||
|
port=FLAGS.redis_port,
|
||||||
|
db=FLAGS.redis_db)
|
||||||
cls._instance = inst
|
cls._instance = inst
|
||||||
return cls._instance
|
return cls._instance
|
||||||
|
|
||||||
|
|
||||||
def slugify(key, prefix=None):
|
|
||||||
"""
|
|
||||||
Key has to be a valid filename. Slugify solves that.
|
|
||||||
"""
|
|
||||||
return "%s%s" % (prefix, key)
|
|
||||||
|
|
||||||
|
|
||||||
class SqliteKeeper(object):
|
|
||||||
""" Keeper implementation in SQLite, mostly for in-memory testing """
|
|
||||||
_conn = {} # class variable
|
|
||||||
|
|
||||||
def __init__(self, prefix):
|
|
||||||
self.prefix = prefix
|
|
||||||
|
|
||||||
@property
|
|
||||||
def conn(self):
|
|
||||||
if self.prefix not in self.__class__._conn:
|
|
||||||
logging.debug('no sqlite connection (%s), making new', self.prefix)
|
|
||||||
if FLAGS.datastore_path != ':memory:':
|
|
||||||
try:
|
|
||||||
os.mkdir(FLAGS.datastore_path)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
conn = sqlite3.connect(os.path.join(
|
|
||||||
FLAGS.datastore_path, '%s.sqlite' % self.prefix))
|
|
||||||
else:
|
|
||||||
conn = sqlite3.connect(':memory:')
|
|
||||||
|
|
||||||
c = conn.cursor()
|
|
||||||
try:
|
|
||||||
c.execute('''CREATE TABLE data (item text, value text)''')
|
|
||||||
conn.commit()
|
|
||||||
except Exception:
|
|
||||||
logging.exception('create table failed')
|
|
||||||
finally:
|
|
||||||
c.close()
|
|
||||||
|
|
||||||
self.__class__._conn[self.prefix] = conn
|
|
||||||
|
|
||||||
return self.__class__._conn[self.prefix]
|
|
||||||
|
|
||||||
def __delitem__(self, item):
|
|
||||||
#logging.debug('sqlite deleting %s', item)
|
|
||||||
c = self.conn.cursor()
|
|
||||||
try:
|
|
||||||
c.execute('DELETE FROM data WHERE item = ?', (item, ))
|
|
||||||
self.conn.commit()
|
|
||||||
except Exception:
|
|
||||||
logging.exception('delete failed: %s', item)
|
|
||||||
finally:
|
|
||||||
c.close()
|
|
||||||
|
|
||||||
def __getitem__(self, item):
|
|
||||||
#logging.debug('sqlite getting %s', item)
|
|
||||||
result = None
|
|
||||||
c = self.conn.cursor()
|
|
||||||
try:
|
|
||||||
c.execute('SELECT value FROM data WHERE item = ?', (item, ))
|
|
||||||
row = c.fetchone()
|
|
||||||
if row:
|
|
||||||
result = json.loads(row[0])
|
|
||||||
else:
|
|
||||||
result = None
|
|
||||||
except Exception:
|
|
||||||
logging.exception('select failed: %s', item)
|
|
||||||
finally:
|
|
||||||
c.close()
|
|
||||||
#logging.debug('sqlite got %s: %s', item, result)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def __setitem__(self, item, value):
|
|
||||||
serialized_value = json.dumps(value)
|
|
||||||
insert = True
|
|
||||||
if self[item] is not None:
|
|
||||||
insert = False
|
|
||||||
#logging.debug('sqlite insert %s: %s', item, value)
|
|
||||||
c = self.conn.cursor()
|
|
||||||
try:
|
|
||||||
if insert:
|
|
||||||
c.execute('INSERT INTO data VALUES (?, ?)',
|
|
||||||
(item, serialized_value))
|
|
||||||
else:
|
|
||||||
c.execute('UPDATE data SET item=?, value=? WHERE item = ?',
|
|
||||||
(item, serialized_value, item))
|
|
||||||
|
|
||||||
self.conn.commit()
|
|
||||||
except Exception:
|
|
||||||
logging.exception('select failed: %s', item)
|
|
||||||
finally:
|
|
||||||
c.close()
|
|
||||||
|
|
||||||
def clear(self):
|
|
||||||
if self.prefix not in self.__class__._conn:
|
|
||||||
return
|
|
||||||
self.conn.close()
|
|
||||||
if FLAGS.datastore_path != ':memory:':
|
|
||||||
os.unlink(os.path.join(FLAGS.datastore_path, '%s.sqlite' % self.prefix))
|
|
||||||
del self.__class__._conn[self.prefix]
|
|
||||||
|
|
||||||
def clear_all(self):
|
|
||||||
for k, conn in self.__class__._conn.iteritems():
|
|
||||||
conn.close()
|
|
||||||
if FLAGS.datastore_path != ':memory:':
|
|
||||||
os.unlink(os.path.join(FLAGS.datastore_path,
|
|
||||||
'%s.sqlite' % self.prefix))
|
|
||||||
self.__class__._conn = {}
|
|
||||||
|
|
||||||
|
|
||||||
def set_add(self, item, value):
|
|
||||||
group = self[item]
|
|
||||||
if not group:
|
|
||||||
group = []
|
|
||||||
group.append(value)
|
|
||||||
self[item] = group
|
|
||||||
|
|
||||||
def set_is_member(self, item, value):
|
|
||||||
group = self[item]
|
|
||||||
if not group:
|
|
||||||
return False
|
|
||||||
return value in group
|
|
||||||
|
|
||||||
def set_remove(self, item, value):
|
|
||||||
group = self[item]
|
|
||||||
if not group:
|
|
||||||
group = []
|
|
||||||
group.remove(value)
|
|
||||||
self[item] = group
|
|
||||||
|
|
||||||
def set_members(self, item):
|
|
||||||
group = self[item]
|
|
||||||
if not group:
|
|
||||||
group = []
|
|
||||||
return group
|
|
||||||
|
|
||||||
def set_fetch(self, item):
|
|
||||||
# TODO(termie): I don't really know what set_fetch is supposed to do
|
|
||||||
group = self[item]
|
|
||||||
if not group:
|
|
||||||
group = []
|
|
||||||
return iter(group)
|
|
||||||
|
|
||||||
class JsonKeeper(object):
|
|
||||||
"""
|
|
||||||
Simple dictionary class that persists using
|
|
||||||
JSON in files saved to disk.
|
|
||||||
"""
|
|
||||||
def __init__(self, prefix):
|
|
||||||
self.prefix = prefix
|
|
||||||
|
|
||||||
def __delitem__(self, item):
|
|
||||||
"""
|
|
||||||
Removing a key means deleting a file from disk.
|
|
||||||
"""
|
|
||||||
item = slugify(item, self.prefix)
|
|
||||||
path = "%s/%s" % (FLAGS.datastore_path, item)
|
|
||||||
if os.path.isfile(path):
|
|
||||||
os.remove(path)
|
|
||||||
|
|
||||||
def __getitem__(self, item):
|
|
||||||
"""
|
|
||||||
Fetch file contents and dejsonify them.
|
|
||||||
"""
|
|
||||||
item = slugify(item, self.prefix)
|
|
||||||
path = "%s/%s" % (FLAGS.datastore_path, item)
|
|
||||||
if os.path.isfile(path):
|
|
||||||
return json.load(open(path, 'r'))
|
|
||||||
return None
|
|
||||||
|
|
||||||
def __setitem__(self, item, value):
|
|
||||||
"""
|
|
||||||
JSON encode value and save to file.
|
|
||||||
"""
|
|
||||||
item = slugify(item, self.prefix)
|
|
||||||
path = "%s/%s" % (FLAGS.datastore_path, item)
|
|
||||||
with open(path, "w") as blobfile:
|
|
||||||
blobfile.write(json.dumps(value))
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
class RedisKeeper(object):
|
|
||||||
"""
|
|
||||||
Simple dictionary class that persists using
|
|
||||||
ReDIS.
|
|
||||||
"""
|
|
||||||
def __init__(self, prefix="redis-"):
|
|
||||||
self.prefix = prefix
|
|
||||||
#Redis.instance().ping()
|
|
||||||
|
|
||||||
def __setitem__(self, item, value):
|
|
||||||
"""
|
|
||||||
JSON encode value and save to file.
|
|
||||||
"""
|
|
||||||
item = slugify(item, self.prefix)
|
|
||||||
Redis.instance().set(item, json.dumps(value))
|
|
||||||
return value
|
|
||||||
|
|
||||||
def __getitem__(self, item):
|
|
||||||
item = slugify(item, self.prefix)
|
|
||||||
value = Redis.instance().get(item)
|
|
||||||
if value:
|
|
||||||
return json.loads(value)
|
|
||||||
|
|
||||||
def __delitem__(self, item):
|
|
||||||
item = slugify(item, self.prefix)
|
|
||||||
return Redis.instance().delete(item)
|
|
||||||
|
|
||||||
def clear(self):
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
def clear_all(self):
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
def set_add(self, item, value):
|
|
||||||
item = slugify(item, self.prefix)
|
|
||||||
return Redis.instance().sadd(item, json.dumps(value))
|
|
||||||
|
|
||||||
def set_is_member(self, item, value):
|
|
||||||
item = slugify(item, self.prefix)
|
|
||||||
return Redis.instance().sismember(item, json.dumps(value))
|
|
||||||
|
|
||||||
def set_remove(self, item, value):
|
|
||||||
item = slugify(item, self.prefix)
|
|
||||||
return Redis.instance().srem(item, json.dumps(value))
|
|
||||||
|
|
||||||
def set_members(self, item):
|
|
||||||
item = slugify(item, self.prefix)
|
|
||||||
return [json.loads(v) for v in Redis.instance().smembers(item)]
|
|
||||||
|
|
||||||
def set_fetch(self, item):
|
|
||||||
item = slugify(item, self.prefix)
|
|
||||||
for obj in Redis.instance().sinter([item]):
|
|
||||||
yield json.loads(obj)
|
|
||||||
|
|
||||||
|
|
||||||
def Keeper(prefix=''):
|
|
||||||
KEEPERS = {'redis': RedisKeeper,
|
|
||||||
'sqlite': SqliteKeeper}
|
|
||||||
return KEEPERS[FLAGS.keeper_backend](prefix)
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ from twisted.python import failure
|
|||||||
from twisted.trial import unittest as trial_unittest
|
from twisted.trial import unittest as trial_unittest
|
||||||
import stubout
|
import stubout
|
||||||
|
|
||||||
from nova import datastore
|
|
||||||
from nova import fakerabbit
|
from nova import fakerabbit
|
||||||
from nova import flags
|
from nova import flags
|
||||||
|
|
||||||
@@ -79,10 +78,6 @@ class TrialTestCase(trial_unittest.TestCase):
|
|||||||
if FLAGS.fake_rabbit:
|
if FLAGS.fake_rabbit:
|
||||||
fakerabbit.reset_all()
|
fakerabbit.reset_all()
|
||||||
|
|
||||||
# attempt to wipe all keepers
|
|
||||||
#keeper = datastore.Keeper()
|
|
||||||
#keeper.clear_all()
|
|
||||||
|
|
||||||
def flags(self, **kw):
|
def flags(self, **kw):
|
||||||
for k, v in kw.iteritems():
|
for k, v in kw.iteritems():
|
||||||
if k in self.flag_overrides:
|
if k in self.flag_overrides:
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2010 United States Government as represented by the
|
|
||||||
# Administrator of the National Aeronautics and Space Administration.
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Copyright 2010 Anso Labs, LLC
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
from nova import test
|
|
||||||
from nova import datastore
|
|
||||||
import random
|
|
||||||
|
|
||||||
class KeeperTestCase(test.BaseTestCase):
|
|
||||||
"""
|
|
||||||
Basic persistence tests for Keeper datastore.
|
|
||||||
Generalize, then use these to support
|
|
||||||
migration to redis / cassandra / multiple stores.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
"""
|
|
||||||
Create a new keeper instance for test keys.
|
|
||||||
"""
|
|
||||||
super(KeeperTestCase, self).__init__(*args, **kwargs)
|
|
||||||
self.keeper = datastore.Keeper('test-')
|
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
"""
|
|
||||||
Scrub out test keeper data.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_store_strings(self):
|
|
||||||
"""
|
|
||||||
Confirm that simple strings go in and come out safely.
|
|
||||||
Should also test unicode strings.
|
|
||||||
"""
|
|
||||||
randomstring = ''.join(
|
|
||||||
[random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-')
|
|
||||||
for _x in xrange(20)]
|
|
||||||
)
|
|
||||||
self.keeper['test_string'] = randomstring
|
|
||||||
self.assertEqual(randomstring, self.keeper['test_string'])
|
|
||||||
|
|
||||||
def test_store_dicts(self):
|
|
||||||
"""
|
|
||||||
Arbitrary dictionaries should be storable.
|
|
||||||
"""
|
|
||||||
test_dict = {'key_one': 'value_one'}
|
|
||||||
self.keeper['test_dict'] = test_dict
|
|
||||||
self.assertEqual(test_dict['key_one'],
|
|
||||||
self.keeper['test_dict']['key_one'])
|
|
||||||
|
|
||||||
def test_sets(self):
|
|
||||||
"""
|
|
||||||
A keeper dict should be self-serializing.
|
|
||||||
"""
|
|
||||||
self.keeper.set_add('test_set', 'foo')
|
|
||||||
test_dict = {'arbitrary': 'dict of stuff'}
|
|
||||||
self.keeper.set_add('test_set', test_dict)
|
|
||||||
self.assertTrue(self.keeper.set_is_member('test_set', 'foo'))
|
|
||||||
self.assertFalse(self.keeper.set_is_member('test_set', 'bar'))
|
|
||||||
self.keeper.set_remove('test_set', 'foo')
|
|
||||||
self.assertFalse(self.keeper.set_is_member('test_set', 'foo'))
|
|
||||||
rv = self.keeper.set_fetch('test_set')
|
|
||||||
self.assertEqual(test_dict, rv.next())
|
|
||||||
self.keeper.set_remove('test_set', test_dict)
|
|
||||||
|
|
||||||
@@ -27,6 +27,4 @@ FLAGS.fake_storage = True
|
|||||||
FLAGS.fake_rabbit = True
|
FLAGS.fake_rabbit = True
|
||||||
FLAGS.fake_network = True
|
FLAGS.fake_network = True
|
||||||
FLAGS.fake_users = True
|
FLAGS.fake_users = True
|
||||||
#FLAGS.keeper_backend = 'sqlite'
|
|
||||||
FLAGS.datastore_path = ':memory:'
|
|
||||||
FLAGS.verbose = True
|
FLAGS.verbose = True
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2010 United States Government as represented by the
|
|
||||||
# Administrator of the National Aeronautics and Space Administration.
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Copyright 2010 Anso Labs, LLC
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
# not use this file except in compliance with the License. You may obtain
|
|
||||||
# a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations
|
|
||||||
# under the License.
|
|
||||||
|
|
||||||
import random
|
|
||||||
|
|
||||||
from nova import datastore
|
|
||||||
from nova import test
|
|
||||||
|
|
||||||
class KeeperTestCase(test.TrialTestCase):
|
|
||||||
"""
|
|
||||||
Basic persistence tests for Keeper datastore.
|
|
||||||
Generalize, then use these to support
|
|
||||||
migration to redis / cassandra / multiple stores.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(KeeperTestCase, self).setUp()
|
|
||||||
self.keeper = datastore.Keeper('test')
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
super(KeeperTestCase, self).tearDown()
|
|
||||||
self.keeper.clear()
|
|
||||||
|
|
||||||
def test_store_strings(self):
|
|
||||||
"""
|
|
||||||
Confirm that simple strings go in and come out safely.
|
|
||||||
Should also test unicode strings.
|
|
||||||
"""
|
|
||||||
randomstring = ''.join(
|
|
||||||
[random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-')
|
|
||||||
for _x in xrange(20)]
|
|
||||||
)
|
|
||||||
self.keeper['test_string'] = randomstring
|
|
||||||
self.assertEqual(randomstring, self.keeper['test_string'])
|
|
||||||
|
|
||||||
def test_store_dicts(self):
|
|
||||||
"""
|
|
||||||
Arbitrary dictionaries should be storable.
|
|
||||||
"""
|
|
||||||
test_dict = {'key_one': 'value_one'}
|
|
||||||
self.keeper['test_dict'] = test_dict
|
|
||||||
self.assertEqual(test_dict['key_one'],
|
|
||||||
self.keeper['test_dict']['key_one'])
|
|
||||||
|
|
||||||
def test_sets(self):
|
|
||||||
"""
|
|
||||||
A keeper dict should be self-serializing.
|
|
||||||
"""
|
|
||||||
self.keeper.set_add('test_set', 'foo')
|
|
||||||
test_dict = {'arbitrary': 'dict of stuff'}
|
|
||||||
self.keeper.set_add('test_set', test_dict)
|
|
||||||
self.assertTrue(self.keeper.set_is_member('test_set', 'foo'))
|
|
||||||
self.assertFalse(self.keeper.set_is_member('test_set', 'bar'))
|
|
||||||
self.keeper.set_remove('test_set', 'foo')
|
|
||||||
self.assertFalse(self.keeper.set_is_member('test_set', 'foo'))
|
|
||||||
rv = self.keeper.set_fetch('test_set')
|
|
||||||
self.assertEqual(test_dict, rv.next())
|
|
||||||
self.keeper.set_remove('test_set', test_dict)
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user