mirror of
https://github.com/falk-werner/webfused
synced 2026-03-02 04:09:19 +00:00
increased test coverage
This commit is contained in:
27
test/mock_libconfig.cc
Normal file
27
test/mock_libconfig.cc
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "mock_libconfig.hpp"
|
||||
#include "wrap_utils.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
static webfused_test::ILibConfig * wfd_MockLibConfig = nullptr;
|
||||
|
||||
WFD_WRAP_FUNC2(wfd_MockLibConfig, config_setting_t *, config_setting_get_elem,
|
||||
config_setting_t const *, unsigned int);
|
||||
|
||||
}
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
MockLibConfig::MockLibConfig()
|
||||
{
|
||||
wfd_MockLibConfig = this;
|
||||
}
|
||||
|
||||
MockLibConfig::~MockLibConfig()
|
||||
{
|
||||
wfd_MockLibConfig = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
32
test/mock_libconfig.hpp
Normal file
32
test/mock_libconfig.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef WFD_MOCK_LIBCONFIG_HPP
|
||||
#define WFD_MOCK_LIBCONFIG_HPP
|
||||
|
||||
#include <libconfig.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
class ILibConfig
|
||||
{
|
||||
public:
|
||||
virtual ~ILibConfig() = default;
|
||||
virtual config_setting_t * config_setting_get_elem(
|
||||
config_setting_t const * setting,
|
||||
unsigned int i) = 0;
|
||||
};
|
||||
|
||||
class MockLibConfig: public ILibConfig
|
||||
{
|
||||
public:
|
||||
MockLibConfig();
|
||||
~MockLibConfig() override;
|
||||
MOCK_METHOD2(config_setting_get_elem, config_setting_t * (
|
||||
config_setting_t const * setting,
|
||||
unsigned int i));
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
31
test/mock_linux.cc
Normal file
31
test/mock_linux.cc
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "mock_linux.hpp"
|
||||
#include "wrap_utils.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
static webfused_test::ILinux * wfd_MockLinux = nullptr;
|
||||
|
||||
WFD_WRAP_FUNC0( wfd_MockLinux, uid_t, getuid);
|
||||
WFD_WRAP_FUNC1( wfd_MockLinux, struct group *, getgrnam, char const *);
|
||||
WFD_WRAP_FUNC1( wfd_MockLinux, int, setgid, gid_t);
|
||||
WFD_WRAP_FUNC2( wfd_MockLinux, int, setgroups, int, gid_t *);
|
||||
WFD_WRAP_FUNC1( wfd_MockLinux, struct passwd *, getpwnam, char const *);
|
||||
WFD_WRAP_FUNC1( wfd_MockLinux, int, setuid, uid_t);
|
||||
|
||||
}
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
MockLinux::MockLinux()
|
||||
{
|
||||
wfd_MockLinux = this;
|
||||
}
|
||||
|
||||
MockLinux::~MockLinux()
|
||||
{
|
||||
wfd_MockLinux = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
41
test/mock_linux.hpp
Normal file
41
test/mock_linux.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef WFD_MOCK_LINUX_HPP
|
||||
#define WFD_MOCK_LINUX_HPP
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
class ILinux
|
||||
{
|
||||
public:
|
||||
virtual ~ILinux() = default;
|
||||
virtual uid_t getuid() = 0;
|
||||
virtual struct group * getgrnam(char const * name) = 0;
|
||||
virtual int setgid(gid_t gid) = 0;
|
||||
virtual int setgroups(int size, gid_t * list) = 0;
|
||||
virtual struct passwd * getpwnam(char const * name) = 0;
|
||||
virtual int setuid(uid_t uid) = 0;
|
||||
};
|
||||
|
||||
class MockLinux: public ILinux
|
||||
{
|
||||
public:
|
||||
MockLinux();
|
||||
~MockLinux();
|
||||
MOCK_METHOD0(getuid, uid_t());
|
||||
MOCK_METHOD1(getgrnam, struct group * (char const * name));
|
||||
MOCK_METHOD1(setgid, int (gid_t gid));
|
||||
MOCK_METHOD2(setgroups, int (int size, gid_t * list));
|
||||
MOCK_METHOD1(getpwnam, struct passwd * (char const * name));
|
||||
MOCK_METHOD1(setuid, int (uid_t uid));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
154
test/test_change_user.cc
Normal file
154
test/test_change_user.cc
Normal file
@@ -0,0 +1,154 @@
|
||||
#include "webfused/change_user.h"
|
||||
#include "mock_linux.hpp"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using ::webfused_test::MockLinux;
|
||||
using ::testing::StrictMock;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrEq;
|
||||
|
||||
TEST(change_user, nop_id_not_root)
|
||||
{
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(42));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_TRUE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, change_successfully)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 23;
|
||||
|
||||
struct passwd userinfo;
|
||||
userinfo.pw_uid = 42;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
EXPECT_CALL(sys, setgid(23)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, setgroups(0, nullptr)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getpwnam("webfused")).Times(1).WillOnce(Return(&userinfo));
|
||||
EXPECT_CALL(sys, setuid(42)).Times(1).WillOnce(Return(0));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_TRUE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_no_username_or_password)
|
||||
{
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).WillRepeatedly(Return(0));
|
||||
|
||||
ASSERT_FALSE(wfd_change_user(nullptr, "daemons"));
|
||||
ASSERT_FALSE(wfd_change_user("webfused", nullptr));
|
||||
ASSERT_FALSE(wfd_change_user(nullptr, nullptr));
|
||||
}
|
||||
|
||||
TEST(change_user, fail_setuid)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 23;
|
||||
|
||||
struct passwd userinfo;
|
||||
userinfo.pw_uid = 42;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
EXPECT_CALL(sys, setgid(23)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, setgroups(0, nullptr)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getpwnam("webfused")).Times(1).WillOnce(Return(&userinfo));
|
||||
EXPECT_CALL(sys, setuid(42)).Times(1).WillOnce(Return(-1));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_getpwnam)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 23;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
EXPECT_CALL(sys, setgid(23)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, setgroups(0, nullptr)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getpwnam("webfused")).Times(1).WillOnce(Return(nullptr));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_setgroups)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 23;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
EXPECT_CALL(sys, setgid(23)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, setgroups(0, nullptr)).Times(1).WillOnce(Return(-1));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_setgid)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 23;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
EXPECT_CALL(sys, setgid(23)).Times(1).WillOnce(Return(-1));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_getgrpnam)
|
||||
{
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(nullptr));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_switch_to_root)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 23;
|
||||
|
||||
struct passwd userinfo;
|
||||
userinfo.pw_uid = 0;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
EXPECT_CALL(sys, setgid(23)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, setgroups(0, nullptr)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getpwnam("webfused")).Times(1).WillOnce(Return(&userinfo));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_switch_to_root_group)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 0;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "webfused/log/log.h"
|
||||
#include "mock_logger.hpp"
|
||||
#include "mock_config_builder.hpp"
|
||||
|
||||
#include "mock_libconfig.hpp"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
@@ -13,6 +13,7 @@ using ::testing::StrictMock;
|
||||
using ::testing::StrEq;
|
||||
using ::webfused_test::MockLogger;
|
||||
using ::webfused_test::MockConfigBuilder;
|
||||
using ::webfused_test::MockLibConfig;
|
||||
|
||||
TEST(config, is_loadable)
|
||||
{
|
||||
@@ -372,6 +373,33 @@ TEST(config, failed_missing_auth_settings)
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(config, failed_auth_settings_get_elem)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, dispose(_)).Times(1);
|
||||
|
||||
MockLibConfig libconfig;
|
||||
EXPECT_CALL(libconfig, config_setting_get_elem(_,_)).Times(1).WillOnce(Return(nullptr));
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = 1, minor = 0 }\n"
|
||||
"authentication:\n"
|
||||
"(\n"
|
||||
" {\n"
|
||||
" provider = \"test\"\n"
|
||||
" settings: { }\n"
|
||||
" }\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(config, filesystems)
|
||||
{
|
||||
MockLogger logger;
|
||||
@@ -479,6 +507,31 @@ TEST(config, filesystems_failed_missing_mountpoint)
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(config, filesystems_failed_missing_elem)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, dispose(_)).Times(1);
|
||||
EXPECT_CALL(builder, addFilesystem(_, _)).Times(0);
|
||||
|
||||
MockLibConfig libconfig;
|
||||
EXPECT_CALL(libconfig, config_setting_get_elem(_,_)).Times(1).WillOnce(Return(nullptr));
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = 1, minor = 0 }\n"
|
||||
"filesystems:\n"
|
||||
"(\n"
|
||||
" {name = \"foo\", mount_point = \"/tmp/test\" }\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(config, log)
|
||||
{
|
||||
MockLogger logger;
|
||||
|
||||
46
test/wrap_utils.hpp
Normal file
46
test/wrap_utils.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef WFD_WRAP_UTILS_HPP
|
||||
#define WFD_WRAP_UTILS_HPP
|
||||
|
||||
#define WFD_WRAP_FUNC0( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME ) \
|
||||
extern RETURN_TYPE __real_ ## FUNC_NAME (); \
|
||||
RETURN_TYPE __wrap_ ## FUNC_NAME () \
|
||||
{ \
|
||||
if (nullptr == GLOBAL_VAR ) \
|
||||
{ \
|
||||
return __real_ ## FUNC_NAME (); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
return GLOBAL_VAR -> FUNC_NAME(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WFD_WRAP_FUNC1( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME, ARG1_TYPE ) \
|
||||
extern RETURN_TYPE __real_ ## FUNC_NAME (ARG1_TYPE); \
|
||||
RETURN_TYPE __wrap_ ## FUNC_NAME (ARG1_TYPE arg1) \
|
||||
{ \
|
||||
if (nullptr == GLOBAL_VAR ) \
|
||||
{ \
|
||||
return __real_ ## FUNC_NAME (arg1); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
return GLOBAL_VAR -> FUNC_NAME(arg1); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WFD_WRAP_FUNC2( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME, ARG1_TYPE, ARG2_TYPE ) \
|
||||
extern RETURN_TYPE __real_ ## FUNC_NAME (ARG1_TYPE, ARG2_TYPE); \
|
||||
RETURN_TYPE __wrap_ ## FUNC_NAME (ARG1_TYPE arg1, ARG2_TYPE arg2) \
|
||||
{ \
|
||||
if (nullptr == GLOBAL_VAR ) \
|
||||
{ \
|
||||
return __real_ ## FUNC_NAME (arg1, arg2); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
return GLOBAL_VAR -> FUNC_NAME(arg1, arg2); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user