Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bcc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
bcc
Commits
b93f2c0e
Commit
b93f2c0e
authored
Apr 20, 2016
by
Vicent Marti
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cc: Add tests for the C API
parent
18ae111f
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
393 additions
and
0 deletions
+393
-0
tests/cc/CMakeLists.txt
tests/cc/CMakeLists.txt
+5
-0
tests/cc/sput.h
tests/cc/sput.h
+272
-0
tests/cc/test_c_api.c
tests/cc/test_c_api.c
+116
-0
No files found.
tests/cc/CMakeLists.txt
View file @
b93f2c0e
...
@@ -7,3 +7,8 @@ add_executable(test_static test_static.c)
...
@@ -7,3 +7,8 @@ add_executable(test_static test_static.c)
target_link_libraries
(
test_static bcc-static
)
target_link_libraries
(
test_static bcc-static
)
add_test
(
NAME c_test_static COMMAND
${
TEST_WRAPPER
}
c_test_static sudo
${
CMAKE_CURRENT_BINARY_DIR
}
/test_static
)
add_test
(
NAME c_test_static COMMAND
${
TEST_WRAPPER
}
c_test_static sudo
${
CMAKE_CURRENT_BINARY_DIR
}
/test_static
)
add_executable
(
test_c_api test_c_api.c
)
target_link_libraries
(
test_c_api bcc-shared dl
)
add_test
(
NAME test_c_api COMMAND
${
TEST_WRAPPER
}
c_test_api sudo
${
CMAKE_CURRENT_BINARY_DIR
}
/test_c_api
)
tests/cc/sput.h
0 → 100644
View file @
b93f2c0e
/*
* sput - Simple, Portable Unit Testing Framework for C/C++ v1.3.1
*
* http://www.lingua-systems.com/unit-testing/
*
*
* Copyright (c) 2011-2015 Lingua-Systems Software GmbH
*
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HAVE_SPUT_H
#define HAVE_SPUT_H
#ifdef __cplusplus
extern
"C"
{
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/* ===================================================================
* definitions
* =================================================================== */
#define SPUT_VERSION_MAJOR 1
#define SPUT_VERSION_MINOR 3
#define SPUT_VERSION_PATCH 1
#define SPUT_VERSION_STRING "1.3.1"
#define SPUT_DEFAULT_SUITE_NAME "Unlabeled Suite"
#define SPUT_DEFAULT_CHECK_NAME "Unlabeled Check"
#define SPUT_INITIALIZED 0x06
/* ACK */
/* ===================================================================
* sput global variable
* =================================================================== */
static
struct
sput
{
FILE
*
out
;
char
initialized
;
struct
sput_overall
{
unsigned
long
checks
;
unsigned
long
suites
;
unsigned
long
ok
;
unsigned
long
nok
;
}
overall
;
struct
sput_suite
{
const
char
*
name
;
unsigned
long
nr
;
unsigned
long
checks
;
unsigned
long
ok
;
unsigned
long
nok
;
}
suite
;
struct
sput_test
{
const
char
*
name
;
unsigned
long
nr
;
}
test
;
struct
sput_check
{
const
char
*
name
;
const
char
*
cond
;
const
char
*
type
;
unsigned
long
line
;
}
check
;
struct
sput_time
{
time_t
start
;
time_t
end
;
}
time
;
}
__sput
;
/* ==================================================================
* sput internal macros
* ================================================================== */
#define _sput_die_unless_initialized() \
if (__sput.initialized != SPUT_INITIALIZED) { \
fputs("sput_start_testing() omitted\n", stderr); \
exit(EXIT_FAILURE); \
}
#define _sput_die_unless_suite_set() \
if (!__sput.suite.name) { \
fputs("sput_enter_suite() omitted\n", __sput.out); \
exit(EXIT_FAILURE); \
}
#define _sput_die_unless_test_set() \
if (!__sput.test.name) { \
fputs("sput_run_test() omitted\n", __sput.out); \
exit(EXIT_FAILURE); \
}
#define _sput_check_failed() \
{ \
_sput_die_unless_initialized(); \
_sput_die_unless_suite_set(); \
__sput.suite.nok++; \
fprintf(__sput.out, \
"[%lu:%lu] %s:#%lu \"%s\" FAIL\n" \
"! Type: %s\n" \
"! Condition: %s\n" \
"! Line: %lu\n", \
__sput.suite.nr, __sput.suite.checks, __sput.test.name, \
__sput.test.nr, __sput.check.name, __sput.check.type, \
__sput.check.cond, __sput.check.line); \
}
#define _sput_check_succeeded() \
{ \
_sput_die_unless_initialized(); \
_sput_die_unless_suite_set(); \
__sput.suite.ok++; \
fprintf(__sput.out, "[%lu:%lu] %s:#%lu \"%s\" pass\n", __sput.suite.nr, \
__sput.suite.checks, __sput.test.name, __sput.test.nr, \
__sput.check.name); \
}
/* ==================================================================
* user macros
* ================================================================== */
#define sput_start_testing() \
do { \
memset(&__sput, 0, sizeof(__sput)); \
__sput.out = stdout; \
__sput.time.start = time(NULL); \
__sput.initialized = SPUT_INITIALIZED; \
} while (0)
#define sput_leave_suite() \
do { \
float failpls = 0.0f; \
_sput_die_unless_initialized(); \
_sput_die_unless_suite_set(); \
failpls = __sput.suite.checks \
? (float)((__sput.suite.nok * 100.0) / __sput.suite.checks) \
: 0.0f; \
fprintf(__sput.out, "\n--> %lu check(s), %lu ok, %lu failed (%.2f%%)\n", \
__sput.suite.checks, __sput.suite.ok, __sput.suite.nok, failpls); \
__sput.overall.checks += __sput.suite.checks; \
__sput.overall.ok += __sput.suite.ok; \
__sput.overall.nok += __sput.suite.nok; \
memset(&__sput.suite, 0, sizeof(__sput.suite)); \
} while (0)
#define sput_get_return_value() \
(__sput.overall.nok > 0 ? EXIT_FAILURE : EXIT_SUCCESS)
#define sput_enter_suite(_name) \
do { \
_sput_die_unless_initialized(); \
if (__sput.suite.name) { \
sput_leave_suite(); \
} \
__sput.suite.name = _name != NULL ? _name : SPUT_DEFAULT_SUITE_NAME; \
__sput.suite.nr = ++__sput.overall.suites; \
fprintf(__sput.out, "\n== Entering suite #%lu, \"%s\" ==\n\n", \
__sput.suite.nr, __sput.suite.name); \
} while (0)
#define sput_finish_testing() \
do { \
float failpft = 0.0f; \
_sput_die_unless_initialized(); \
if (__sput.suite.name) { \
sput_leave_suite(); \
} \
failpft = \
__sput.overall.checks \
? (float)((__sput.overall.nok * 100.0) / __sput.overall.checks) \
: 0.0f; \
__sput.time.end = time(NULL); \
fprintf( \
__sput.out, \
"\n==> %lu check(s) in %lu suite(s) finished after %.2f " \
"second(s),\n" \
" %lu succeeded, %lu failed (%.2f%%)\n" \
"\n[%s]\n", \
__sput.overall.checks, __sput.overall.suites, \
difftime(__sput.time.end, __sput.time.start), __sput.overall.ok, \
__sput.overall.nok, failpft, \
(sput_get_return_value() == EXIT_SUCCESS) ? "SUCCESS" : "FAILURE"); \
} while (0)
#define sput_set_output_stream(_fp) \
do { \
__sput.out = _fp != NULL ? _fp : stdout; \
} while (0)
#define sput_fail_if(_cond, _name) \
do { \
_sput_die_unless_initialized(); \
_sput_die_unless_suite_set(); \
_sput_die_unless_test_set(); \
__sput.check.name = _name != NULL ? _name : SPUT_DEFAULT_CHECK_NAME; \
__sput.check.line = __LINE__; \
__sput.check.cond = #_cond; \
__sput.check.type = "fail-if"; \
__sput.test.nr++; \
__sput.suite.checks++; \
if ((_cond)) { \
_sput_check_failed(); \
} else { \
_sput_check_succeeded(); \
} \
} while (0)
#define sput_fail_unless(_cond, _name) \
do { \
_sput_die_unless_initialized(); \
_sput_die_unless_suite_set(); \
_sput_die_unless_test_set(); \
__sput.check.name = _name != NULL ? _name : SPUT_DEFAULT_CHECK_NAME; \
__sput.check.line = __LINE__; \
__sput.check.cond = #_cond; \
__sput.check.type = "fail-unless"; \
__sput.test.nr++; \
__sput.suite.checks++; \
if (!(_cond)) { \
_sput_check_failed(); \
} else { \
_sput_check_succeeded(); \
} \
} while (0)
#define sput_run_test(_func) \
do { \
_sput_die_unless_initialized(); \
_sput_die_unless_suite_set(); \
memset(&__sput.test, 0, sizeof(__sput.test)); \
__sput.test.name = #_func; \
_func(); \
} while (0)
#ifdef __cplusplus
}
#endif
#endif
/* HAVE_SPUT_H */
/* vim: set ft=c sts=4 sw=4 ts=4 ai et: */
tests/cc/test_c_api.c
0 → 100644
View file @
b93f2c0e
#include <stdint.h>
#include <unistd.h>
#include <dlfcn.h>
#include "sput.h"
#include "bcc_elf.h"
#include "bcc_proc.h"
#include "bcc_syms.h"
static
void
test_procutils__which_so
(
void
)
{
const
char
*
libm
=
bcc_procutils_which_so
(
"m"
);
sput_fail_unless
(
libm
,
"find libm"
);
sput_fail_unless
(
libm
[
0
]
==
'/'
,
"resolve libm absolute path"
);
sput_fail_unless
(
strstr
(
libm
,
"libm.so"
),
"resolve libm so"
);
}
static
void
test_procutils__which
(
void
)
{
char
*
ld
=
bcc_procutils_which
(
"ld"
);
sput_fail_unless
(
ld
,
"find `ld` binary"
);
sput_fail_unless
(
ld
[
0
]
==
'/'
,
"find `ld` absolute path"
);
free
(
ld
);
}
static
void
_test_ksym
(
const
char
*
sym
,
uint64_t
addr
,
void
*
_
)
{
if
(
!
strcmp
(
sym
,
"startup_64"
))
{
sput_fail_unless
(
addr
==
0xffffffff81000000ull
,
"ksym `startup_64`"
);
}
else
if
(
!
strcmp
(
sym
,
"__per_cpu_start"
))
sput_fail_unless
(
addr
==
0x0
,
"ksym `__per_cpu_start`"
);
}
static
void
test_procutils__each_ksym
(
void
)
{
sput_fail_unless
(
geteuid
()
==
0
,
"ensure we are root"
);
bcc_procutils_each_ksym
(
_test_ksym
,
NULL
);
}
static
void
test_syms__resolve_symname
(
void
)
{
struct
bcc_symbol
sym
;
sput_fail_unless
(
bcc_resolve_symname
(
"c"
,
"malloc"
,
0x0
,
&
sym
)
==
0
,
"bcc_resolve_symname(c, malloc)"
);
sput_fail_unless
(
strstr
(
sym
.
module
,
"libc.so"
),
"resolve to module"
);
sput_fail_unless
(
sym
.
module
[
0
]
==
'/'
,
"resolve to abspath"
);
sput_fail_unless
(
sym
.
offset
!=
0
,
"resolve sym offset"
);
}
static
void
test_syms__resolver_pid
(
void
)
{
struct
bcc_symbol
sym
;
void
*
resolver
=
bcc_symcache_new
(
getpid
());
sput_fail_unless
(
resolver
,
"create a new resolver for PID"
);
sput_fail_unless
(
bcc_symcache_resolve
(
resolver
,
(
uint64_t
)
&
test_syms__resolver_pid
,
&
sym
)
==
0
,
"resolve the current function address"
);
char
*
this_exe
=
realpath
(
"/proc/self/exe"
,
NULL
);
sput_fail_unless
(
strcmp
(
this_exe
,
sym
.
module
)
==
0
,
"resolve a function to our own binary"
);
free
(
this_exe
);
sput_fail_unless
(
strcmp
(
"test_syms__resolver_pid"
,
sym
.
name
)
==
0
,
"resolve a function to its actual name"
);
void
*
libbcc
=
dlopen
(
"libbcc.so"
,
RTLD_LAZY
|
RTLD_NOLOAD
);
sput_fail_unless
(
libbcc
,
"dlopen(libbcc.so)"
);
void
*
libbcc_fptr
=
dlsym
(
libbcc
,
"bcc_resolve_symname"
);
sput_fail_unless
(
libbcc_fptr
,
"dlsym(bcc_resolve_symname)"
);
sput_fail_unless
(
bcc_symcache_resolve
(
resolver
,
(
uint64_t
)
libbcc_fptr
,
&
sym
)
==
0
,
"resolve a function in libbcc in our current process"
);
sput_fail_unless
(
strstr
(
sym
.
module
,
"libbcc.so"
),
"resolve a function to the loaded libbcc module"
);
sput_fail_unless
(
strcmp
(
"bcc_resolve_symname"
,
sym
.
name
)
==
0
,
"resolve a function in libbcc to its actual name"
);
void
*
libc_fptr
=
dlsym
(
NULL
,
"strtok"
);
sput_fail_unless
(
libc_fptr
,
"dlsym(strtok)"
);
sput_fail_unless
(
bcc_symcache_resolve
(
resolver
,
(
uint64_t
)
libc_fptr
,
&
sym
)
==
0
,
"resolve a function in libc in our current process"
);
sput_fail_unless
(
sym
.
module
&&
sym
.
module
[
0
]
==
'/'
&&
strstr
(
sym
.
module
,
"libc"
),
"resolve a function to linked libc module"
);
sput_fail_unless
(
strcmp
(
"strtok"
,
sym
.
name
)
==
0
,
"resolve a function in libc to its actual name"
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
sput_start_testing
();
sput_enter_suite
(
"procutils: which_so"
);
sput_run_test
(
test_procutils__which_so
);
sput_enter_suite
(
"procutils: which"
);
sput_run_test
(
test_procutils__which
);
sput_enter_suite
(
"procutils: each_ksym"
);
sput_run_test
(
test_procutils__each_ksym
);
sput_enter_suite
(
"syms: resolve_symname"
);
sput_run_test
(
test_syms__resolve_symname
);
sput_enter_suite
(
"syms: resolver_pid"
);
sput_run_test
(
test_syms__resolver_pid
);
sput_finish_testing
();
return
sput_get_return_value
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment