Skip to content

Commit 69f676f

Browse files
authored
Merge pull request #1227 from ingve/unittests
test: more unit tests, add cppcheck target for os files included in unittests
2 parents f6096d2 + 2efe1f5 commit 69f676f

7 files changed

Lines changed: 293 additions & 7 deletions

File tree

src/net/buffer_store.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#if !defined(__MACH__)
2121
#include <malloc.h>
2222
#else
23+
#include <cstddef>
2324
extern void *memalign(size_t, size_t);
2425
#endif
2526
#include <net/buffer_store.hpp>

test/CMakeLists.txt

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
cmake_minimum_required(VERSION 2.8.9)
22
project(unittests C CXX)
3+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
34

45
option(COVERAGE "Build with coverage generation" OFF)
56
option(SILENT_BUILD "Build with some warnings turned off" ON)
@@ -85,6 +86,9 @@ set(TEST_SOURCES
8586
${TEST}/util/unit/percent_encoding_test.cpp
8687
${TEST}/util/unit/ringbuffer.cpp
8788
${TEST}/util/unit/statman.cpp
89+
${TEST}/util/unit/syslogd_test.cpp
90+
${TEST}/util/unit/syslog_facility_test.cpp
91+
${TEST}/util/unit/tar_test.cpp
8892
${TEST}/util/unit/uri_test.cpp
8993
)
9094

@@ -167,6 +171,10 @@ set(OS_SOURCES
167171

168172
set(MOD_OBJECTS
169173
${INCLUDEOS_ROOT}/mod/http-parser/http_parser.c
174+
${INCLUDEOS_ROOT}/mod/uzlib/src/adler32.c
175+
${INCLUDEOS_ROOT}/mod/uzlib/src/crc32.c
176+
${INCLUDEOS_ROOT}/mod/uzlib/src/tinflate.c
177+
${INCLUDEOS_ROOT}/mod/uzlib/src/tinfgzip.c
170178
)
171179

172180
if(COVERAGE)
@@ -208,9 +216,45 @@ endif("${ARCH}" STREQUAL "ARCH_ARMv7")
208216
if(SILENT_BUILD)
209217
message(STATUS "NOTE: Building with some warnings turned off")
210218
set_property(SOURCE ${SOURCES} APPEND_STRING PROPERTY COMPILE_FLAGS
211-
"-Wno-unused-variable -Wno-unused-parameter -Wno-sign-compare -Wno-format")
219+
" -Wno-unused-variable -Wno-unused-parameter -Wno-sign-compare -Wno-format")
212220
endif()
213221

214222
add_executable(unittests ${SOURCES})
215223
install(TARGETS unittests DESTINATION ${TEST})
216224
install(DIRECTORY lest/include/lest DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
225+
226+
add_custom_command(
227+
TARGET unittests PRE_BUILD
228+
COMMAND ${CMAKE_COMMAND} -E tar cf ${CMAKE_CURRENT_BINARY_DIR}/test-single.tar ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
229+
COMMAND ${CMAKE_COMMAND} -E tar cf ${CMAKE_CURRENT_BINARY_DIR}/test-multiple.tar ${CMAKE_CURRENT_SOURCE_DIR}/*.py
230+
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_BINARY_DIR}/test-invalid.tar
231+
COMMAND ${CMAKE_COMMAND} -E tar czf ${CMAKE_CURRENT_BINARY_DIR}/test.tar.gz ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
232+
COMMAND ${CMAKE_COMMAND} -E tar czf ${CMAKE_CURRENT_BINARY_DIR}/test-corrupt.gz ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
233+
COMMAND bash ${TEST}/util/unit/corrupt-tar-gz.sh ${CMAKE_CURRENT_BINARY_DIR}/test.tar.gz ${CMAKE_CURRENT_BINARY_DIR}/test-corrupt.gz
234+
COMMAND ${CMAKE_COMMAND} -E tar cf ${CMAKE_CURRENT_BINARY_DIR}/test-tar-gz-inside.tar ${CMAKE_CURRENT_BINARY_DIR}/test.tar.gz
235+
)
236+
237+
add_custom_target(
238+
cppcheck
239+
COMMAND cppcheck
240+
--enable=warning,style,performance,portability
241+
--force
242+
--platform=unix32
243+
--std=c++11
244+
--verbose
245+
--quiet
246+
-I ${INCLUDEOS_ROOT}/api
247+
-I ${INCLUDEOS_ROOT}/src/include
248+
-I ${INCLUDEOS_ROOT}/mod/
249+
-I ${INCLUDEOS_ROOT}/mod/GSL
250+
-I ${INCLUDEOS_ROOT}/mod/uzlib/src
251+
${OS_SOURCES}
252+
)
253+
254+
add_custom_target(
255+
clang-tidy
256+
COMMAND clang-tidy-3.8
257+
-checks=clang-analyzer-core.*,clang-analyzer-cplusplus.*,clang-analyzer-deadcode.*,clang-analyzer-nullability,cppcoreguidelines*,modernize*,performance*,misc*,-misc-virtual-near-miss
258+
-p=compile_commands.json
259+
${OS_SOURCES}
260+
)

test/fs/unit/path_test.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ CASE("Path can be constructed with initializer list")
4242
EXPECT(path.to_string() == "/Users/Bjarne/Documents/");
4343
}
4444

45+
CASE("Path by default is constructed as \"/\"")
46+
{
47+
fs::Path path;
48+
EXPECT(path.to_string() == "/");
49+
EXPECT(path.empty() == true);
50+
EXPECT(path.size() == 0u);
51+
}
52+
4553
CASE("Paths can be checked for equality")
4654
{
4755
fs::Path src_path {"/etc"};
@@ -68,12 +76,6 @@ CASE("Path can return specific component")
6876
EXPECT(path[2] == "Documents");
6977
}
7078

71-
CASE("Path can return specific component")
72-
{
73-
fs::Path path {"/Users/Bjarne/Documents"};
74-
EXPECT(path[2] == "Documents");
75-
}
76-
7779
CASE("Path does not segfault when requested component is out of range")
7880
{
7981
fs::Path path {"/Users/Bjarne/Documents"};

test/util/unit/corrupt-tar-gz.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
INFILE="$1"
3+
OUTFILE="$2"
4+
5+
printf '\x0a\x0f\x0a\x0f\x0a\x0f\x0a\x0f' | dd conv=notrunc bs=1 of=$OUTFILE seek=$((`ls -nl $INFILE | awk '{print $5}'` - 8))
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// This file is a part of the IncludeOS unikernel - www.includeos.org
2+
//
3+
// Copyright 2015-2017 Oslo and Akershus University College of Applied Sciences
4+
// and Alfred Bratterud
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
#include <common.cxx>
19+
#include <util/syslog_facility.hpp>
20+
21+
CASE("facility-related functions get/set facility, facility_name() returns facility name as string")
22+
{
23+
Syslog_facility sf;
24+
// default created with LOG_USER
25+
EXPECT(sf.facility_name() == "USER");
26+
sf.set_facility(LOG_MAIL);
27+
EXPECT(sf.facility_name() == "MAIL");
28+
EXPECT(sf.facility() == LOG_MAIL);
29+
}
30+
31+
CASE("ident-related functions get/set ident, returns whether ident is set")
32+
{
33+
Syslog_facility sf;
34+
EXPECT(sf.ident_is_set() == false);
35+
sf.set_ident("foo");
36+
EXPECT(sf.ident_is_set() == true);
37+
EXPECT(sf.ident() == "foo");
38+
}
39+
40+
CASE("priority-related functions get/set priority")
41+
{
42+
Syslog_facility sf;
43+
sf.set_priority(LOG_CRIT);
44+
EXPECT_NOT(sf.priority() == LOG_INFO);
45+
EXPECT(sf.priority() == LOG_CRIT);
46+
EXPECT(sf.priority_name() == "CRIT");
47+
}
48+
49+
CASE("logopt-related functions get/set logopt")
50+
{
51+
Syslog_facility sf("bar", LOG_INTERNAL);
52+
sf.set_logopt(LOG_NOWAIT);
53+
EXPECT_NOT(sf.logopt() == LOG_USER);
54+
EXPECT(sf.logopt() == (LOG_NOWAIT));
55+
}

test/util/unit/syslogd_test.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// This file is a part of the IncludeOS unikernel - www.includeos.org
2+
//
3+
// Copyright 2015-2017 Oslo and Akershus University College of Applied Sciences
4+
// and Alfred Bratterud
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
#include <common.cxx>
19+
#include <syslog.h>
20+
#include <util/syslogd.hpp>
21+
22+
CASE("valid_priority() returns whether supplied priority is valid")
23+
{
24+
EXPECT(Syslog::valid_priority(LOG_EMERG) == true);
25+
EXPECT(Syslog::valid_priority(LOG_DEBUG) == true);
26+
EXPECT_NOT(Syslog::valid_priority(8192007) == true);
27+
}
28+
29+
CASE("valid_logopt() returns whether supplied logopt is valid")
30+
{
31+
EXPECT(Syslog::valid_logopt(LOG_PID || LOG_NOWAIT) == true);
32+
}
33+
34+
CASE("valid_facility() returns whether supplied facility is valid")
35+
{
36+
EXPECT(Syslog::valid_facility(LOG_USER) == true);
37+
}
38+
39+
CASE("ip() returns destination IP address")
40+
{
41+
auto s = Syslog::ip().to_string();
42+
size_t dots = std::count(s.begin(), s.end(), '.');
43+
EXPECT(dots == 3);
44+
}
45+
46+
CASE("port() returns destination port")
47+
{
48+
int port = Syslog::port();
49+
EXPECT(port > -1);
50+
EXPECT(port < 65536);
51+
}

test/util/unit/tar_test.cpp

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// This file is a part of the IncludeOS unikernel - www.includeos.org
2+
//
3+
// Copyright 2015-2017 Oslo and Akershus University College of Applied Sciences
4+
// and Alfred Bratterud
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
#include <common.cxx>
19+
#include <tar>
20+
#include <sys/mman.h>
21+
#include <sys/stat.h>
22+
#include <fcntl.h>
23+
#include <unistd.h>
24+
25+
CASE("Reading single entry tar file")
26+
{
27+
tar::Reader r;
28+
struct stat st;
29+
int res = stat("test-single.tar", &st);
30+
EXPECT(res != -1);
31+
size_t size = st.st_size;
32+
int fd = open("test-single.tar", O_RDONLY);
33+
EXPECT_NOT(fd == -1);
34+
const uint8_t *mem = (const uint8_t *)mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
35+
tar::Tar tar = r.read_uncompressed(mem, size);
36+
EXPECT(tar.num_elements() == 1);
37+
auto names = tar.element_names();
38+
EXPECT(names.size() == 1);
39+
const auto& elements = tar.elements();
40+
EXPECT(elements.size() == 1);
41+
const auto& e = elements.at(0);
42+
EXPECT_NOT(e.is_dir());
43+
EXPECT(e.typeflag_is_set());
44+
EXPECT(e.typeflag() == REGTYPE); // regular file
45+
EXPECT_NOT(e.is_empty());
46+
EXPECT(e.is_ustar());
47+
EXPECT_NOT(e.is_tar_gz());
48+
EXPECT(e.num_content_blocks() > 0);
49+
EXPECT(e.size() > 0);
50+
const auto& name = e.name();
51+
EXPECT(name.find("CMakeLists.txt") != std::string::npos);
52+
EXPECT_NO_THROW(auto& only_element = tar.element("../CMakeLists.txt"));
53+
EXPECT_THROWS_AS(auto& missing_element = tar.element("not_there.txt"), tar::Tar_exception);
54+
55+
// try to decompress a non-tar.gz element
56+
EXPECT_THROWS_AS(tar::Tar inner_tar = r.decompress(e), tar::Tar_exception);
57+
close(fd);
58+
}
59+
60+
CASE("Reading multiple entry tar file")
61+
{
62+
tar::Reader r;
63+
struct stat st;
64+
int res = stat("test-multiple.tar", &st);
65+
EXPECT(res != -1);
66+
size_t size = st.st_size;
67+
int fd = open("test-multiple.tar", O_RDONLY);
68+
EXPECT_NOT(fd == -1);
69+
const uint8_t *mem = (const uint8_t *)mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
70+
tar::Tar tar = r.read_uncompressed(mem, size);
71+
auto names = tar.element_names();
72+
EXPECT(names.size() > 1);
73+
const auto& elements = tar.elements();
74+
EXPECT(elements.size() > 1);
75+
const auto& e = elements.at(elements.size() - 1);
76+
EXPECT(e.name().find(".py") != std::string::npos);
77+
close(fd);
78+
}
79+
80+
CASE("Reading invalid tar file")
81+
{
82+
tar::Reader r;
83+
struct stat st;
84+
int res = stat("test-invalid.tar", &st);
85+
EXPECT(res != -1);
86+
size_t size = st.st_size;
87+
int fd = open("test-invalid.tar", O_RDONLY);
88+
EXPECT_NOT(fd == -1);
89+
const uint8_t *mem = (const uint8_t *)mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
90+
EXPECT_THROWS_AS(tar::Tar tar = r.read_uncompressed(mem, size), tar::Tar_exception);
91+
close(fd);
92+
}
93+
94+
CASE("Reading corrupt tar.gz file")
95+
{
96+
tar::Reader r;
97+
struct stat st;
98+
int res = stat("test-corrupt.gz", &st);
99+
EXPECT(res != -1);
100+
size_t size = st.st_size;
101+
int fd = open("test-corrupt.gz", O_RDONLY);
102+
EXPECT_NOT(fd == -1);
103+
const uint8_t *mem = (const uint8_t *)mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
104+
EXPECT_THROWS_AS(tar::Tar tar = r.decompress(mem, size), tar::Tar_exception);
105+
close(fd);
106+
}
107+
108+
CASE("Reading tar.gz inside tar file")
109+
{
110+
tar::Reader r;
111+
struct stat st;
112+
int res = stat("test-tar-gz-inside.tar", &st);
113+
EXPECT(res != -1);
114+
size_t size = st.st_size;
115+
int fd = open("test-tar-gz-inside.tar", O_RDONLY);
116+
EXPECT_NOT(fd == -1);
117+
const uint8_t *mem = (const uint8_t *)mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
118+
tar::Tar tar = r.read_uncompressed(mem, size);
119+
EXPECT(tar.num_elements() == 1);
120+
const auto& e = tar.elements().at(0);
121+
EXPECT(e.is_tar_gz());
122+
EXPECT(e.name().find(".tar.gz") != std::string::npos);
123+
tar::Tar inner_tar = r.decompress(e);
124+
EXPECT(inner_tar.num_elements() == 1);
125+
const auto& inner_e = inner_tar.elements().at(0);
126+
EXPECT(inner_e.name().find(".tar.gz") == std::string::npos);
127+
close(fd);
128+
}

0 commit comments

Comments
 (0)