Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UT coverage to 95%, code improve and minor fix #34

Merged
merged 3 commits into from
May 13, 2023
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
10 changes: 9 additions & 1 deletion .azure-pipelines/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ jobs:
sudo apt-get install -y dotnet-sdk-6.0
displayName: install .Net
- script: |
set -ex
sudo apt-get update
sudo apt-get install -y \
libboost-system-dev \
libboost-thread-dev \
Expand All @@ -51,7 +53,13 @@ jobs:
displayName: "Install dependencies"
- checkout: self
clean: true
submodules: true
submodules: recursive
- script: |
git submodule foreach --recursive 'git clean -xfdf || true'
git submodule foreach --recursive 'git reset --hard || true'
git submodule foreach --recursive 'git remote update || true'
git submodule update --init --recursive
displayName: 'Reset submodules'
- task: DownloadPipelineArtifact@2
inputs:
source: specific
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "gmock_global"]
path = gmock_global
url = https://github.com/apriorit/gmock-global.git
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.ONESHELL:
SHELL = /bin/bash

RM := rm -rf
BUILD_DIR := build
BUILD_TEST_DIR := build-test
Expand All @@ -12,7 +15,7 @@ override LDLIBS += -levent -lhiredis -lswsscommon -pthread -lboost_thread -lboos
override CPPFLAGS += -Wall -std=c++17 -fPIE -I/usr/include/swss
override CPPFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)"
CPPFLAGS_TEST := --coverage -fprofile-arcs -ftest-coverage -fprofile-generate -fsanitize=address
LDLIBS_TEST := --coverage -lgtest -pthread -lstdc++fs -fsanitize=address
LDLIBS_TEST := --coverage -lgtest -lgmock -pthread -lstdc++fs -fsanitize=address
PWD := $(shell pwd)

all: $(DHCP6RELAY_TARGET) $(DHCP6RELAY_TEST_TARGET)
Expand Down
2 changes: 1 addition & 1 deletion azurepipelines-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ coverage:
status: # Code coverage status will be posted to pull requests based on targets defined below.
comments: on # Off by default. When on, details about coverage for each file changed will be posted as a pull request comment.
diff: # Diff coverage is code coverage only for the lines changed in a pull request.
target: 60% # Set this to a desired percentage. Default is 70 percent
target: 90% # Set this to a desired percentage. Default is 70 percent
1 change: 1 addition & 0 deletions gmock_global
Submodule gmock_global added at 6552fa
45 changes: 13 additions & 32 deletions src/configInterface.cpp → src/config_interface.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#include <sstream>
#include <syslog.h>
#include <algorithm>
#include "configInterface.h"
#include "config_interface.h"

constexpr auto DEFAULT_TIMEOUT_MSEC = 1000;

bool pollSwssNotifcation = true;
std::shared_ptr<boost::thread> mSwssThreadPtr;
swss::Select swssSelect;

/**
Expand All @@ -29,6 +28,17 @@ void initialize_swss(std::unordered_map<std::string, relay_config> &vlans)
}
}

/**
*@code stopSwssNotificationPoll
*
*@brief stop SWSS listening thread
*
*@return none
*/
static void stopSwssNotificationPoll() {
pollSwssNotifcation = false;
};

/**
* @code void deinitialize_swss()
*
Expand All @@ -39,12 +49,8 @@ void initialize_swss(std::unordered_map<std::string, relay_config> &vlans)
void deinitialize_swss()
{
stopSwssNotificationPoll();
if (mSwssThreadPtr != nullptr) {
mSwssThreadPtr->interrupt();
}
}


/**

* @code void get_dhcp(std::unordered_map<std::string, relay_config> &vlans, swss::SubscriberStateTable *ipHelpersTable, bool dynamic)
Expand All @@ -58,6 +64,7 @@ void get_dhcp(std::unordered_map<std::string, relay_config> &vlans, swss::Subscr
int ret = swssSelect.select(&selectable, DEFAULT_TIMEOUT_MSEC);
if (ret == swss::Select::ERROR) {
syslog(LOG_WARNING, "Select: returned ERROR");
return;
} else if (ret == swss::Select::TIMEOUT) {
}
if (selectable == static_cast<swss::Selectable *> (ipHelpersTable)) {
Expand All @@ -69,21 +76,6 @@ void get_dhcp(std::unordered_map<std::string, relay_config> &vlans, swss::Subscr
}
}
}
/**
* @code void handleSwssNotification(std::vector<relay_config> *vlans)
*
* @brief main thread for handling SWSS notification
*
* @param context map of vlans/argument config that contains strings of server and option
*
* @return none
*/
void handleSwssNotification(swssNotification test)
{
while (pollSwssNotifcation) {
get_dhcp(test.vlans, test.ipHelpersTable, true);
}
}

/**
* @code void handleRelayNotification(swss::SubscriberStateTable &ipHelpersTable, std::unordered_map<std::string, relay_config> &vlans)
Expand Down Expand Up @@ -152,14 +144,3 @@ void processRelayNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries,
vlans[vlan] = intf;
}
}

/**
*@code stopSwssNotificationPoll
*
*@brief stop SWSS listening thread
*
*@return none
*/
void stopSwssNotificationPoll() {
pollSwssNotifcation = false;
};
19 changes: 0 additions & 19 deletions src/configInterface.h → src/config_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,6 @@ void deinitialize_swss();
* @return none
*/
void get_dhcp(std::unordered_map<std::string, relay_config> &vlans, swss::SubscriberStateTable *ipHelpersTable, bool dynamic);
/**
* @code void swssNotification test
*
* @brief main thread for handling SWSS notification
*
* @param test swssNotification that includes list of vlans/argument config that contains strings of server and option
*
* @return none
*/
void handleSwssNotification(swssNotification test);

/**
* @code void handleRelayNotification(swss::SubscriberStateTable &ipHelpersTable, std::unordered_map<std::string, relay_config> &vlans)
Expand All @@ -71,12 +61,3 @@ void handleRelayNotification(swss::SubscriberStateTable &ipHelpersTable, std::un
* @return none
*/
void processRelayNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries, std::unordered_map<std::string, relay_config> &vlans);

/**
*@code stopSwssNotificationPoll
*
*@brief stop SWSS listening thread
*
*@return none
*/
void stopSwssNotificationPoll();
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <stdlib.h>
#include <syslog.h>
#include <unordered_map>
#include "configInterface.h"
#include "config_interface.h"

bool dual_tor_sock = false;

Expand Down
41 changes: 27 additions & 14 deletions src/relay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "configdb.h"
#include "sonicv2connector.h"
#include "dbconnector.h"
#include "configInterface.h"
#include "config_interface.h"

struct event *listen_event;
struct event *server_listen_event;
Expand Down Expand Up @@ -163,6 +163,12 @@ uint8_t *RelayMsg::MarshalBinary(uint16_t &len) {

auto opt = m_option_list.MarshalBinary();
if (opt && !opt->empty()) {
if (opt->size() + sizeof(dhcpv6_relay_msg) > BUFFER_SIZE) {
syslog(LOG_WARNING, "Failed to marshal relay msg, packet size %lu over limit\n",
opt->size() + sizeof(dhcpv6_relay_msg));
len = 0;
return nullptr;
}
std::memcpy(ptr + sizeof(dhcpv6_relay_msg), opt->data(), opt->size());
len += opt->size();
}
Expand Down Expand Up @@ -210,6 +216,12 @@ uint8_t *DHCPv6Msg::MarshalBinary(uint16_t &len) {

auto opt = m_option_list.MarshalBinary();
if (opt && !opt->empty()) {
if (opt->size() + sizeof(dhcpv6_msg) > BUFFER_SIZE) {
syslog(LOG_WARNING, "Failed to marshal dhcpv6 msg, packet size %lu over limit\n",
opt->size() + sizeof(dhcpv6_msg));
len = 0;
return nullptr;
}
std::memcpy(ptr + sizeof(dhcpv6_msg), opt->data(), opt->size());
len += opt->size();
}
Expand Down Expand Up @@ -637,7 +649,7 @@ void relay_client(int sock, const uint8_t *msg, uint16_t len, const ip6_hdr *ip_

uint16_t relay_pkt_len = 0;
auto relay_pkt = relay.MarshalBinary(relay_pkt_len);
if (!relay_pkt_len) {
if (!relay_pkt_len || !relay_pkt) {
char addr_str[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &ip_hdr->ip6_src, addr_str, INET6_ADDRSTRLEN);
syslog(LOG_ERR, "Relay-forward marshal error, client dhcpv6 from %s", addr_str);
Expand Down Expand Up @@ -683,10 +695,10 @@ void relay_relay_forw(int sock, const uint8_t *msg, int32_t len, const ip6_hdr *

/* add relay-msg option */
relay.m_option_list.Add(OPTION_RELAY_MSG, msg, len);

uint16_t send_buffer_len = 0;
auto send_buffer = relay.MarshalBinary(send_buffer_len);
if (!send_buffer_len) {
if (!send_buffer_len || !send_buffer) {
char addr_str[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &ip_hdr->ip6_src, addr_str, INET6_ADDRSTRLEN);
syslog(LOG_ERR, "Marshal relay-forward message from %s error", addr_str);
Expand Down Expand Up @@ -929,7 +941,7 @@ void server_callback(evutil_socket_t fd, short event, void *arg) {
}

if (buffer_sz < (int32_t)sizeof(struct dhcpv6_msg)) {
syslog(LOG_WARNING, "Invalid DHCPv6 packet length %ld, no space for dhcpv6 msg header\n", buffer_sz);
syslog(LOG_WARNING, "Invalid DHCPv6 packet length %zd, no space for dhcpv6 msg header\n", buffer_sz);
continue;
}

Expand All @@ -955,7 +967,7 @@ void server_callback(evutil_socket_t fd, short event, void *arg) {
*/
int signal_init() {
int rv = -1;
do {
do {
ev_sigint = evsignal_new(base, SIGINT, signal_callback, base);
if (ev_sigint == NULL) {
syslog(LOG_ERR, "Could not create SIGINT libevent signal\n");
Expand Down Expand Up @@ -1043,13 +1055,14 @@ void loop_relay(std::unordered_map<std::string, relay_config> &vlans) {
base = event_base_new();
if(base == NULL) {
syslog(LOG_ERR, "libevent: Failed to create base\n");
exit(EXIT_FAILURE);
}

std::shared_ptr<swss::DBConnector> state_db = std::make_shared<swss::DBConnector> ("STATE_DB", 0);
std::shared_ptr<swss::DBConnector> config_db = std::make_shared<swss::DBConnector> ("CONFIG_DB", 0);
std::shared_ptr<swss::Table> mStateDbMuxTablePtr = std::make_shared<swss::Table> (
state_db.get(), "HW_MUX_CABLE_TABLE"
);
state_db.get(), "HW_MUX_CABLE_TABLE"
);

auto filter = sock_open(&ether_relay_fprog);
if (filter != -1) {
Expand Down Expand Up @@ -1102,23 +1115,23 @@ void loop_relay(std::unordered_map<std::string, relay_config> &vlans) {
syslog(LOG_INFO, "libevent: Add server listen socket for %s\n", vlan.first.c_str());
}

if((signal_init() == 0) && signal_start() == 0) {
shutdown();
for(std::size_t i = 0; i<sockets.size(); i++) {
if(signal_init() == 0 && signal_start() == 0) {
shutdown_relay();
for(std::size_t i = 0; i < sockets.size(); i++) {
close(sockets.at(i));
}
}
}

/**
* @code shutdown();
* @code shutdown_relay();
*
* @brief free signals and terminate threads
*/
void shutdown() {
void shutdown_relay() {
event_del(ev_sigint);
event_del(ev_sigterm);
event_free(ev_sigint);
event_free(ev_sigint);
event_free(ev_sigterm);
event_base_free(base);
deinitialize_swss();
Expand Down
2 changes: 1 addition & 1 deletion src/relay.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ void signal_callback(evutil_socket_t fd, short event, void *arg);
*
* @brief free signals and terminate threads
*/
void shutdown();
void shutdown_relay();

/**
* @code void initialize_counter(std::shared_ptr<swss::Table> state_db, std::string counterVlan);
Expand Down
2 changes: 1 addition & 1 deletion src/subdir.mk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
SRCS += \
src/sender.cpp \
src/relay.cpp \
src/configInterface.cpp \
src/config_interface.cpp \
src/main.cpp
3 changes: 0 additions & 3 deletions test/MockRelay.h

This file was deleted.

67 changes: 67 additions & 0 deletions test/mock_config_interface.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "mock_config_interface.h"

using namespace ::testing;

TEST(configInterface, initialize_swss) {
std::shared_ptr<swss::DBConnector> config_db = std::make_shared<swss::DBConnector> ("CONFIG_DB", 0);
config_db->hset("DHCP_RELAY|Vlan1000", "dhcpv6_servers@", "fc02:2000::1,fc02:2000::2,fc02:2000::3,fc02:2000::4");
config_db->hset("DHCP_RELAY|Vlan1000", "dhcpv6_option|rfc6939_support", "false");
config_db->hset("DHCP_RELAY|Vlan1000", "dhcpv6_option|interface_id", "true");
std::unordered_map<std::string, relay_config> vlans;
ASSERT_NO_THROW(initialize_swss(vlans));
EXPECT_EQ(vlans.size(), 1);
}

TEST(configInterface, deinitialize_swss) {
ASSERT_NO_THROW(deinitialize_swss());
}

TEST(configInterface, get_dhcp) {
std::shared_ptr<swss::DBConnector> config_db = std::make_shared<swss::DBConnector> ("CONFIG_DB", 0);
config_db->hset("DHCP_RELAY|Vlan1000", "dhcpv6_servers@", "fc02:2000::1,fc02:2000::2,fc02:2000::3,fc02:2000::4");
config_db->hset("DHCP_RELAY|Vlan1000", "dhcpv6_option|rfc6939_support", "false");
config_db->hset("DHCP_RELAY|Vlan1000", "dhcpv6_option|interface_id", "true");
swss::SubscriberStateTable ipHelpersTable(config_db.get(), "DHCP_RELAY");
std::unordered_map<std::string, relay_config> vlans;

ASSERT_NO_THROW(get_dhcp(vlans, &ipHelpersTable, false));
EXPECT_EQ(vlans.size(), 0);

swssSelect.addSelectable(&ipHelpersTable);

ASSERT_NO_THROW(get_dhcp(vlans, &ipHelpersTable, false));
EXPECT_EQ(vlans.size(), 1);
}

TEST(configInterface, handleRelayNotification) {
std::shared_ptr<swss::DBConnector> cfg_db = std::make_shared<swss::DBConnector> ("CONFIG_DB", 0);
swss::SubscriberStateTable ipHelpersTable(cfg_db.get(), "DHCP_RELAY");
std::unordered_map<std::string, relay_config> vlans;
handleRelayNotification(ipHelpersTable, vlans);
}

TEST(configInterface, processRelayNotification) {
std::shared_ptr<swss::DBConnector> config_db = std::make_shared<swss::DBConnector> ("CONFIG_DB", 0);
config_db->hset("DHCP_RELAY|Vlan1000", "dhcpv6_servers@", "fc02:2000::1,fc02:2000::2,fc02:2000::3,fc02:2000::4");
config_db->hset("DHCP_RELAY|Vlan1000", "dhcpv6_option|rfc6939_support", "false");
config_db->hset("DHCP_RELAY|Vlan1000", "dhcpv6_option|interface_id", "true");
swss::SubscriberStateTable ipHelpersTable(config_db.get(), "DHCP_RELAY");
swssSelect.addSelectable(&ipHelpersTable);
std::deque<swss::KeyOpFieldsValuesTuple> entries;
ipHelpersTable.pops(entries);
std::unordered_map<std::string, relay_config> vlans;

processRelayNotification(entries, vlans);

EXPECT_EQ(vlans.size(), 1);
EXPECT_FALSE(vlans["Vlan1000"].is_option_79);
EXPECT_TRUE(vlans["Vlan1000"].is_interface_id);
EXPECT_FALSE(vlans["Vlan1000"].state_db);
}

MOCK_GLOBAL_FUNC0(stopSwssNotificationPoll, void(void));

TEST(configInterface, stopSwssNotificationPoll) {
EXPECT_GLOBAL_CALL(stopSwssNotificationPoll, stopSwssNotificationPoll()).Times(1);
ASSERT_NO_THROW(stopSwssNotificationPoll());
}
Loading