Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions common/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

namespace swss {

class JSon {
class JSon
{
public:
static std::string buildJson(const std::vector<FieldValueTuple> &fv);

static void readJson(const std::string &json, std::vector<FieldValueTuple> &fv);
};

Expand Down
51 changes: 46 additions & 5 deletions common/producertable.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#include "common/redisreply.h"
#include "common/producertable.h"
#include "common/json.h"
#include "common/json.hpp"
#include <stdlib.h>
#include <tuple>

using namespace std;
using json = nlohmann::json;

namespace swss {

Expand All @@ -13,6 +15,21 @@ ProducerTable::ProducerTable(DBConnector *db, string tableName) :
{
}

ProducerTable::ProducerTable(DBConnector *db, string tableName, string dumpFile) :
Table(db, tableName)
{
m_dumpFile.open(dumpFile, fstream::out | fstream::trunc);
m_dumpFile << "[" << endl;
}

ProducerTable::~ProducerTable() {
if (m_dumpFile.is_open())
{
m_dumpFile << endl << "]" << endl;
m_dumpFile.close();
}
}

void ProducerTable::enqueueDbChange(string key, string value, string op)
{
string lpush_value;
Expand Down Expand Up @@ -44,21 +61,45 @@ void ProducerTable::enqueueDbChange(string key, string value, string op)

void ProducerTable::set(string key, vector<FieldValueTuple> &values, string op)
{
multi();
if (m_dumpFile.is_open())
{
if (!m_firstItem)
m_dumpFile << "," << endl;
else
m_firstItem = false;

json j;
string json_key = getKeyName(key);
j[json_key] = json::object();
for (auto it : values)
j[json_key][fvField(it)] = fvValue(it);
j["OP"] = op;
m_dumpFile << j.dump(4);
}

multi();
enqueueDbChange(key, JSon::buildJson(values), "S" + op);
exec();
}

void ProducerTable::del(string key, string op)
{
string del("DEL ");
del += getKeyName(key);
if (m_dumpFile.is_open())
{
if (!m_firstItem)
m_dumpFile << "," << endl;
else
m_firstItem = false;

multi();
json j;
string json_key = getKeyName(key);
j[json_key] = json::object();
j["OP"] = op;
m_dumpFile << j.dump(4);
}

multi();
enqueueDbChange(key, "{}", "D" + op);

exec();
}

Expand Down
7 changes: 7 additions & 0 deletions common/producertable.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef __PRODUCERTABLE__
#define __PRODUCERTABLE__

#include <fstream>
#include <iostream>
#include <string>
#include <vector>

Expand All @@ -14,6 +16,8 @@ class ProducerTable : public Table
{
public:
ProducerTable(DBConnector *db, std::string tableName);
ProducerTable(DBConnector *db, std::string tableName, std::string dumpFile);
~ProducerTable();

/* Implements set() and del() commands using notification messages */
virtual void set(std::string key, std::vector<FieldValueTuple> &values,
Expand All @@ -25,6 +29,9 @@ class ProducerTable : public Table
ProducerTable(const ProducerTable &other);
ProducerTable & operator = (const ProducerTable &other);

std::ofstream m_dumpFile;
bool m_firstItem = true;

void enqueueDbChange(std::string key, std::string value, std::string op);
};

Expand Down
3 changes: 2 additions & 1 deletion tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ LDADD_GTEST = $(top_srcdir)/googletest/build/googlemock/gtest/libgtest_main.a \
$(top_srcdir)/googletest/build/googlemock/gtest/libgtest.a

tests_SOURCES = redis_ut.cpp \
tokenize_ut.cpp
tokenize_ut.cpp \
json_ut.cpp

tests_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_GTEST)
tests_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_GTEST)
Expand Down
71 changes: 71 additions & 0 deletions tests/json_ut.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "common/json.hpp"
#include "common/producertable.h"
#include "gtest/gtest.h"

using namespace std;
using namespace swss;
using json = nlohmann::json;

#define TEST_VIEW (7)
#define TEST_DUMP_FILE "ut_dump_file.txt"

TEST(JSON, test)
{
/* Construct the file */
DBConnector db(TEST_VIEW, "localhost", 6379, 0);
ProducerTable *p;
p = new ProducerTable(&db, "UT_REDIS", TEST_DUMP_FILE);

vector<FieldValueTuple> fvTuples;
FieldValueTuple fv1("test_field_1", "test_value_1");
fvTuples.push_back(fv1);

p->set("test_key_1", fvTuples);

FieldValueTuple fv2("test_field_2", "test_value_2");
fvTuples.push_back(fv2);

p->set("test_key_2", fvTuples);

p->del("test_key_1");

delete(p);

/* Read the file and validate the content */
fstream file(TEST_DUMP_FILE, fstream::in);
json j;
file >> j;

EXPECT_TRUE(j.is_array());
EXPECT_TRUE(j.size() == 3);

for (size_t i = 0; i < j.size(); i++)
{
auto item = j[i];
EXPECT_TRUE(item.is_object());
EXPECT_TRUE(item.size() == 2);

for (auto it = item.begin(); it != item.end(); it++)
{
if (it.key() == "OP")
EXPECT_TRUE(it.value() == "SET" || it.value() == "DEL");
else
{
EXPECT_TRUE(it.key() == "UT_REDIS:test_key_1" || it.key() == "UT_REDIS:test_key_2");
auto subitem = it.value();
EXPECT_TRUE(subitem.is_object());
if (subitem.size() > 0)
{
for (auto subit = subitem.begin(); subit != subitem.end(); subit++)
{
if (subit.key() == "test_field_1")
EXPECT_EQ(subit.value(), "test_value_1");
if (subit.key() == "test_field_2")
EXPECT_EQ(subit.value(), "test_value_2");
}
}
}
}
}
file.close();
}