Skip to content

Commit

Permalink
Allow deleting tables before updating
Browse files Browse the repository at this point in the history
Add table_delete to mod_config in the ConfigDBPipeConnector to allow table cleanup as part of transaction

Add unittest for ConfigDBConnector
  • Loading branch information
seiferteric authored and ericseifert committed May 30, 2023
1 parent 92991f0 commit b2b16ab
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
'redis>=4.5.4;python_version >= "3.0"',
'redis>=3.5.3;python_version < "3.0"',
'redis-dump-load',
'fakeredis',
]

high_performance_deps = [
Expand Down
10 changes: 9 additions & 1 deletion src/swsssdk/configdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,19 +392,27 @@ def __mod_entry(self, pipe, table, key, data):
else:
pipe.hmset(_hash, self.typed_to_raw(data))

def mod_config(self, data):
def mod_config(self, data, table_delete=None):
"""Write multiple tables into config db.
Extra entries/fields in the db which are not in the data are kept.
Pass one or more tables in table_delete to delete tables before update.
Args:
data: config data in a dictionary form
{
'TABLE_NAME': { 'row_key': {'column_key': 'value', ...}, ...},
'MULTI_KEY_TABLE_NAME': { ('l1_key', 'l2_key', ...) : {'column_key': 'value', ...}, ...},
...
}
table_delete: Table name(s) that will be deleted first before modify
"""
client = self.get_redis_client(self.db_name)
pipe = client.pipeline()
if table_delete:
if isinstance(table_delete, list):
for t in table_delete:
self.__delete_table(client, pipe, t)
else:
self.__delete_table(client, pipe, table_delete)
for table_name in data:
table_data = data[table_name]
if table_data is None:
Expand Down
31 changes: 31 additions & 0 deletions test/test_configdb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import os
import sys

from unittest import mock

from unittest import TestCase

modules_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(modules_path, 'src'))

import swsssdk
import fakeredis


class TestConfigDB(TestCase):
def test__configdb_pipe(self):

s_db = swsssdk.ConfigDBPipeConnector()
#Use fakeredis to mock redis db
r_db = fakeredis.FakeStrictRedis(version=5)
s_db.get_redis_client = lambda db_name: r_db
s_db.db_name = "CONFIG_DB"

s_db.mod_config({'TABLE_NAME': { 'row_key': {'column_key1': 'valueA1', 'column_key2': 'valueB1'}}})
self.assertEqual(r_db.hget('TABLE_NAME|row_key', 'column_key1'), b'valueA1')
self.assertEqual(r_db.hget('TABLE_NAME|row_key', 'column_key2'), b'valueB1')
s_db.mod_config({'TABLE_NAME': { 'row_key': {'column_key1': 'valueA2'}}}, table_delete='TABLE_NAME')
self.assertEqual(r_db.hget('TABLE_NAME|row_key', 'column_key1'), b'valueA2')
self.assertEqual(r_db.hget('TABLE_NAME|row_key', 'column_key2'), None)


0 comments on commit b2b16ab

Please sign in to comment.