Skip to content

Commit

Permalink
refactor(e2e): add docker helper class
Browse files Browse the repository at this point in the history
Signed-off-by: Roberto Scolaro <[email protected]>
  • Loading branch information
therealbobo authored and poiana committed Mar 13, 2024
1 parent be0958a commit 5fbb799
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 60 deletions.
69 changes: 44 additions & 25 deletions test/libsinsp_e2e/container/container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ limitations under the License.
#include <gtest/gtest.h>

#include <libsinsp/sinsp_cgroup.h>
#include <string>

using namespace std;

Expand Down Expand Up @@ -637,6 +638,9 @@ static void update_container_state(sinsp* inspector,
static void healthcheck_helper(
const char* dockerfile,
bool expect_healthcheck,
const char* build_extra_args,
const char* run_extra_args,
std::vector<std::string>& labels,
sinsp_threadinfo::command_category expected_cat = sinsp_threadinfo::CAT_HEALTHCHECK)
{
container_state cstate;
Expand All @@ -650,13 +654,10 @@ static void healthcheck_helper(

dutils_kill_container("cont_health_ut");
dutils_kill_image("cont_health_ut_img");
std::string docker_res(LIBSINSP_TEST_RESOURCES_PATH "/docker/");
docker_helper dhelper(docker_res + dockerfile, "cont_health_ut_img", labels, build_extra_args, run_extra_args);

std::string build_cmdline = string("cd "
LIBSINSP_TEST_RESOURCES_PATH
"/docker/health_dockerfiles && docker build -t cont_health_ut_img -f ") +
dockerfile + " . > /dev/null 2>&1";

ASSERT_TRUE(system(build_cmdline.c_str()) == 0);
ASSERT_TRUE(dhelper.build_image() == 0);

event_filter_t filter = [&](sinsp_evt* evt)
{
Expand All @@ -676,10 +677,7 @@ static void healthcheck_helper(
inspector_handle->start_dropping_mode(1);
}

// --network=none speeds up the container setup a bit.
int rc = system(
"docker run --rm --network=none --name cont_health_ut cont_health_ut_img /bin/sh -c "
"'/bin/sleep 10' > /dev/null 2>&1");
int rc = dhelper.run_container("cont_health_ut", "/bin/sh -c '/bin/sleep 10'");

ASSERT_TRUE(exited_early || (rc == 0));
};
Expand Down Expand Up @@ -717,14 +715,16 @@ static void healthcheck_helper(
// or a second process spawned after as a health check process.
TEST_F(sys_call_test, docker_container_no_healthcheck)
{
healthcheck_helper("Dockerfile.no_healthcheck", false);
std::vector<std::string> labels{};
healthcheck_helper("Dockerfile.no_healthcheck", false, "", "", labels);
}

// A container with HEALTHCHECK=none should behave identically to one
// without any container at all.
TEST_F(sys_call_test, docker_container_none_healthcheck)
{
healthcheck_helper("Dockerfile.none_healthcheck", false);
std::vector<std::string> labels{};
healthcheck_helper("Dockerfile.none_healthcheck", false, "", "", labels);
}

// Run container w/ health check. Should find health check for
Expand All @@ -733,36 +733,49 @@ TEST_F(sys_call_test, docker_container_none_healthcheck)
// check executed for container.
TEST_F(sys_call_test, docker_container_healthcheck)
{
healthcheck_helper("Dockerfile.healthcheck", true);
std::vector<std::string> labels{};
healthcheck_helper("Dockerfile", true, "", "", labels);
}

// Run container w/ health check and entrypoint having identical
// cmdlines. Should identify healthcheck but not entrypoint as a
// health check process.
TEST_F(sys_call_test, docker_container_healthcheck_cmd_overlap)
{
healthcheck_helper("Dockerfile.healthcheck_cmd_overlap", true);
std::vector<std::string> labels{};
healthcheck_helper("Dockerfile", true, "", "", labels);
}

// A health check using shell exec instead of direct exec.
TEST_F(sys_call_test, docker_container_healthcheck_shell)
{
healthcheck_helper("Dockerfile.healthcheck_shell", true);
std::vector<std::string> labels{};
healthcheck_helper("Dockerfile", true, "", "--health-cmd 'sh -c \"/bin/ut-health-check\"' --health-interval 0.5s", labels);
}

// A health check where the container has docker labels that make it
// look like it was started in k8s.
TEST_F(sys_call_test, docker_container_liveness_probe)
{
healthcheck_helper("Dockerfile.healthcheck_liveness",
const char* label= R""""(annotation.kubectl.kubernetes.io/last-applied-configuration="{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"mysql-app\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"env\":[{\"name\":\"MYSQL_ROOT_PASSWORD\",\"value\":\"no\"}],\"image\":\"user/mysql:healthcheck\",\"livenessProbe\":{\"exec\":{\"command\":[\"/bin/ut-health-check\"]},\"initialDelaySeconds\":5,\"periodSeconds\":5},\"name\":\"mysql\"}]}}\n")"""";
std::vector<std::string> labels{std::string(label)};
healthcheck_helper("Dockerfile",
true,
"",
"",
labels,
sinsp_threadinfo::CAT_LIVENESS_PROBE);
}

TEST_F(sys_call_test, docker_container_readiness_probe)
{
healthcheck_helper("Dockerfile.healthcheck_readiness",
const char* label = R""""(annotation.kubectl.kubernetes.io/last-applied-configuration="{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"mysql-app\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"env\":[{\"name\":\"MYSQL_ROOT_PASSWORD\",\"value\":\"no\"}],\"image\":\"user/mysql:healthcheck\",\"readinessProbe\":{\"exec\":{\"command\":[\"/bin/ut-health-check\"]},\"initialDelaySeconds\":5,\"periodSeconds\":5},\"name\":\"mysql\"}]}}\n")"""";
std::vector<std::string> labels{std::string(label)};
healthcheck_helper("Dockerfile",
true,
"",
"",
labels,
sinsp_threadinfo::CAT_READINESS_PROBE);
}

Expand All @@ -775,13 +788,22 @@ TEST_F(sys_call_test, docker_container_large_json)
return;
}

std::string repeated_string = std::string(4096,'a');

std::vector<std::string> labels;
labels.emplace_back("url2=" + repeated_string);
labels.emplace_back("summary2=" + repeated_string);
labels.emplace_back("vcs-type2=" + repeated_string);
labels.emplace_back("vcs-ref2=" + repeated_string);
labels.emplace_back("description2=" + repeated_string);
labels.emplace_back("io.k8s.description2=" + repeated_string);

dutils_kill_container("large_container_ut");
dutils_kill_image("large_container_ut_img");
std::string docker_res(LIBSINSP_TEST_RESOURCES_PATH "/docker/");
docker_helper dhelper(docker_res + "Dockerfile", "large_container_ut_img", labels, "", "");

ASSERT_TRUE(system("cd "
LIBSINSP_TEST_RESOURCES_PATH
"/docker/large_container_dockerfiles && docker build -t "
"large_container_ut_img -f Dockerfile.long_labels . > /dev/null") == 0);
ASSERT_TRUE(dhelper.build_image() == 0);

event_filter_t filter = [&](sinsp_evt* evt) {
return evt->get_type() == PPME_CONTAINER_JSON_E ||
Expand All @@ -795,10 +817,7 @@ TEST_F(sys_call_test, docker_container_large_json)
std::scoped_lock inspector_handle_lock(inspector_handle);
inspector_handle->set_container_labels_max_len(60000);
}
// --network=none speeds up the container setup a bit.
int rc = system(
"docker run --rm --network=none --name large_container_ut large_container_ut_img "
"/bin/sh -c '/bin/sleep 3' > /dev/null 2>&1");
int rc = dhelper.run_container("large_container_ut", "/bin/sh -c '/bin/sleep 3'");

ASSERT_TRUE(rc == 0);
};
Expand Down
34 changes: 34 additions & 0 deletions test/libsinsp_e2e/container/docker_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,37 @@ void dutils_kill_image(const char* image)

EXPECT_EQ(system(rmi_cmd.c_str()), 0);
}

docker_helper::docker_helper(const std::string& dockerfile_path, const std::string& tagname,
const std::vector<std::string>& labels, const std::string& build_extra_args,
const std::string& run_extra_args, const bool& verbose):
m_dockerfile_path(dockerfile_path),
m_tagname(tagname),
m_labels(labels),
m_build_extra_args(build_extra_args),
m_run_extra_args(run_extra_args),
m_verbose(verbose) {}

int docker_helper::build_image() {
std::string label_options;
for (const auto& label : m_labels) {
label_options += " --label " + label;
}
std::string command = "docker build " + m_build_extra_args + label_options + " -t " + m_tagname + " -f " + m_dockerfile_path + " .";
if(!m_verbose)
{
command += " > /dev/null 2>&1";

}
return system(command.c_str());
}

int docker_helper::run_container(const std::string& container_name, const std::string& cmd, const std::string& additional_options) {
std::string command = "docker run " + additional_options + " " + m_run_extra_args + " --name " + container_name + " " + m_tagname + " " + cmd;
if(!m_verbose)
{
command += " > /dev/null 2>&1";

}
return system(command.c_str());
}
21 changes: 21 additions & 0 deletions test/libsinsp_e2e/container/docker_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,29 @@ limitations under the License.

#pragma once

#include <string>
#include <vector>

bool dutils_check_docker();
void dutils_create_tag(const char* tag, const char* image);
void dutils_kill_container(const char* name);
void dutils_kill_container_if_exists(const char* name);
void dutils_kill_image(const char* image);

class docker_helper {
public:
docker_helper(const std::string& dockerfile_path, const std::string& tagname,
const std::vector<std::string>& labels, const std::string& build_extra_args,
const std::string& run_extra_args, const bool& verbose = false);
int build_image();
int run_container(const std::string& containerName, const std::string& cmd, const std::string& additional_options = "--rm --network=none");

private:
std::string m_dockerfile_path;
std::string m_tagname;
std::vector<std::string> m_labels;
std::string m_build_extra_args;
std::string m_run_extra_args;
bool m_verbose;

};

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 5fbb799

Please sign in to comment.