Merge branch 'dev' of ssh://box.fiane.intra/var/lib/git/libucore into dev

Conflicts:
	test/test_runner.c
This commit is contained in:
Nils O. Selåsdal
2013-07-07 03:19:12 +02:00
26 changed files with 729 additions and 49 deletions
+1 -1
View File
@@ -655,7 +655,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = src
INPUT = include
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+14
View File
@@ -36,6 +36,12 @@ AddOption('--test_xml',
help='Create a result.xml when running the testsuite'
)
AddOption('--coverage',
dest='coverage',
action='store_true',
help='Build with coverage (gcov) support'
)
AddOption('--stack-protection',
dest = 'stack_protection',
action='store_true',
@@ -59,6 +65,11 @@ def InstallPerm(env, dest, files, perm):
env = Environment(tools = ['default', 'textfile'])
#allow shell environment to override compiler
if os.environ.has_key('CC'):
env['CC'] = os.environ['CC']
env.AddMethod(InstallPerm)
Export('env', 'build_type', 'prefix', 'version_info', 'test_xml')
@@ -80,6 +91,9 @@ if GetOption('stack_protection'):
env.Append(CFLAGS = ['-fstack-protector', '--param=ssp-buffer-size=4'])
env.Append(CPPDEFINES = ['_FORTIFY_SOURCE=2'])
if GetOption('coverage'):
env.Append(CFLAGS = ['--coverage'])
env.Append(LINKFLAGS = ['--coverage'])
#put all .sconsign files in one place
env.SConsignFile()
+47
View File
@@ -0,0 +1,47 @@
#ifndef UC_ATOMIC_H_
#define UC_ATOMIC_H_
/** Atomic functions (macros). The ptr argument must be a pointer to
* an integer type.
* For gcc, see http://gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/_005f_005fsync-Builtins.html
*/
#ifdef __GNUC__
/**
* Atomically add val to *ptr
* @return *ptr before the addition
*/
#define UC_ATOMIC_ADD(ptr, val) __sync_fetch_and_add((ptr), (val))
/**
* Atomically subtract val from *ptr
* @return *ptr before the subtraction
*/
#define UC_ATOMIC_SUB(ptr, val) __sync_fetch_and_add((ptr), -(val))
/**
* Atomically decrement *ptr
* @return *ptr before the decrement
*/
#define UC_ATOMIC_DEC(ptr) UC_ATOMIC_SUB((ptr), 1)
/**
* Atomically increment *ptr
* @return *ptr before the increment
*/
#define UC_ATOMIC_INC(ptr) UC_ATOMIC_SUB((ptr), 1)
/**
* Atomic Compare-And-Swap. If *ptr is oldval, write newwal to *ptr.
* @return *ptr that was before the operation.
*/
#define UC_ATOMIC_CAS(ptr, oldval, newval) __sync_val_compare_and_swap((ptr), (oldval), (newval))
#else
#error "No atomic operations implemented for this compiler"
#endif
#endif
+9 -2
View File
@@ -1,9 +1,12 @@
#ifndef UC_BACKTRACE_H_
#define UC_BACKTRACE_H_
#define UC_BACTRACE_STDERR uc_backtrace_fd(2)
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#define UC_BACTRACE_STDERR uc_backtrace_fd(2)
/**
* Print a stacktrace to the given file descriptor.
*
@@ -21,4 +24,8 @@ void uc_backtrace_fd(int fd);
*/
void uc_backtrace_buf(char *buf, size_t len);
#ifdef __cplusplus
}
#endif
#endif
+1 -1
View File
@@ -8,7 +8,7 @@ extern "C" {
struct UCBitVec {
//storage for the bits
unsigned long *vec;
//length of the above vec. (Not the number of bits !)
//length in bytes of the above vec.
size_t vec_len;
};
+7
View File
@@ -4,6 +4,9 @@
#include <sys/time.h>
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* An abstract clock.
@@ -110,5 +113,9 @@ void uc_settable_clock_set_tv(struct UCoreSettableClock *uclock,
void uc_settable_clock_set(struct UCoreSettableClock *uclock,
time_t secs, suseconds_t usecs);
#ifdef __cplusplus
}
#endif
#endif
+25 -5
View File
@@ -3,6 +3,11 @@
#include "timers.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MUX_EV_READ (1U << 0x00)
#define MUX_EV_WRITE (1U << 0x01)
//#define MUX_EV_EXCEPT (1 << 0x02)
@@ -38,6 +43,9 @@ struct IOMuxFD {
};
/** Creates a new IOMux.
*
* @param type the underlying implementation to use @see IOMUX_TYPE
* @return Newly allocated IOMux. NULL if memory allocation fails.
*/
struct IOMux *iomux_create(enum IOMUX_TYPE type);
@@ -53,19 +61,27 @@ struct IOMux *iomux_create_ex(enum IOMUX_TYPE type, struct UCoreClock *uclock);
void iomux_delete(struct IOMux *mux);
/** Runs the event loop of the mux
* returns if the number of file descriptors and timers are 0 or
*
* @return if the number of file descriptors and timers are 0 or
* an error occurs */
int iomux_run(struct IOMux *mux);
/* Adds a file descriptor to the watch set,
* returns 0 on success, an errno value on error */
/* Adds a file descriptor to the watch set.
* The file descriptor integer value must reside in only
* one struct IOMuxFD. Adding e.g. the same file descriptor
* in 2 different struct IOMuxFD, one for read events and one for
* write events is not supported.
*
* @return 0 on success, an errno value on error
*/
int iomux_register_fd(struct IOMux *mux, struct IOMuxFD *fd);
/** Removes the file descriptor*/
int iomux_unregister_fd(struct IOMux *mux, struct IOMuxFD *fd);
/** Updates the events to watch for in fd->what
* returns 0 on success, an errno value on error */
* @return 0 on success, an errno value on error
*/
int iomux_update_events(struct IOMux *mux, struct IOMuxFD *fd);
@@ -95,10 +111,14 @@ int iomux_update_events(struct IOMux *mux, struct IOMuxFD *fd);
iomux_update_events((mux), (fd));\
})
/** Returns a UCTimer instance tied to this mux.
/** @return a UCTimer instance tied to this mux.
* Used to schedule timers within this mux.
*/
struct UCTimers *iomux_get_timers(struct IOMux *mux);
#ifdef __cplusplus
}
#endif
#endif
+4 -2
View File
@@ -71,13 +71,15 @@
extern "C" {
#endif
/** The log levels defined by ucore logging*/
/** The log levels defined by ucore logging
* UC_LL_NONE must not be used in logging statements - but
* can be used to suppress all logging for a destination or module*/
enum UC_LOG_LEVEL {
UC_LL_NONE = 0,
UC_LL_DEBUG = 1,
UC_LL_INFO = 3,
UC_LL_WARNING = 5,
UC_LL_ERROR = 7,
UC_LL_NONE = 9,
};
/** A destination for the logging messages*/
+75
View File
@@ -0,0 +1,75 @@
#ifndef UC_MBUF_H_
#define UC_MBUF_H_
#include <stdint.h>
#include <stddef.h>
#ifdef __GNUC__
# define UC_INLINE inline __attribute__((always_inline))
#else
# define UC_INLINE inline
#endif
enum UC_MBUF_FLAGS {
UC_MBUF_FL_MALLOC = 0x0001, //MBuf and MBuf->bufstart are seperatly malloc'd
UC_MBUF_FL_MALLOC_BUF = 0x0001, //MBuf is not malloc'd. MBuf->bufstart is malloc'd
UC_MBUF_FL_MALLOC_INLINE = 0x0002, //MBuf is one big malloc. Can't be resized
UC_MBUF_FL_STATIC = 0x0004, //MBuf and MBuf->bustart is user controlled. Can't be resized
};
struct MBuf {
struct MBuf *next;
uint8_t *p1;
uint8_t *p2;
uint8_t *p3;
uint8_t *p4;
void *cookie;
uint32_t flags;
uint32_t allocated;
uint8_t *bufstart;
uint8_t *head;
uint8_t *tail;
uint8_t inline_data[0];
};
/* Conventions:
* push - prepend data to the buffer (in the head room part)
* pull - remove data from the beginning of the message.
* put - Add data to the buffer.
*/
struct MBuf *uc_mbuf_new_hr(uint32_t len, uint32_t headroom);
#define uc_mbuf_new(len) uc_mbuf_new_hr((len), 0)
struct MBuf *uc_mbuf_new_inline_hr(uint32_t len, uint32_t headroom);
#define uc_mbuf_new_inline(len) uc_mbuf_new_inline_hr((len), 0)
void uc_mbuf_free(struct MBuf *mbuf);
struct MBuf *uc_mbuf_copy_data(struct MBuf *mbuf);
void uc_mbuf_init(struct MBuf *mbuf, uint8_t *buf, uint32_t len, uint32_t headroom, uint32_t flags);
void uc_mbuf_zero(struct MBuf *mbuf);
void uc_mbuf_reset(struct MBuf *mbuf);
static UC_INLINE uint32_t uc_mbuf_len(struct MBuf *mbuf)
{
return (uint32_t)(mbuf->tail - mbuf->head);
}
static UC_INLINE uint32_t uc_mbuf_tailroom(struct MBuf *mbuf)
{
return mbuf->allocated - (uint32_t)(mbuf->tail - mbuf->bufstart);
}
static inline uint32_t uc_mbuf_headroom(struct MBuf *mbuf)
{
return (uint32_t)(mbuf->head - mbuf->bufstart);
}
uint8_t *uc_mbuf_put(struct MBuf *mbuf, uint32_t size);
uint8_t *uc_mbuf_push(struct MBuf *mbuf, uint32_t size);
uint8_t *uc_mbuf_pull(struct MBuf *mbuf, uint32_t size);
#undef UC_INLINE
#endif
+7
View File
@@ -1,6 +1,9 @@
#ifndef UCORE_MERSENNE_TWISTER_H
#define UCORE_MERSENNE_TWISTER_H
#ifdef __cplusplus
extern "C" {
#endif
/** Context used for the PRNG*/
#define MT_RAND_N 624
@@ -23,5 +26,9 @@ void mtsrand(int seed, MTRand *r);
*/
unsigned int mtrand(MTRand *r);
#ifdef __cplusplus
}
#endif
#endif
+8
View File
@@ -3,6 +3,10 @@
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Read the content of a file.
* The returned char* is malloced memory and must be freed by the caller.
* The content is terminated by a nul byte, regardless of whether the content
@@ -17,4 +21,8 @@
char *
uc_read_file(const char *file_name, size_t *length, size_t max);
#ifdef __cplusplus
}
#endif
#endif
+7
View File
@@ -6,6 +6,9 @@
#include <sys/time.h>
#include "rbtree.h"
#ifdef __cplusplus
extern "C" {
#endif
struct UCTimer;
struct UCTimers;
@@ -140,4 +143,8 @@ int uc_timers_run(struct UCTimers *timers);
//uc_timers_destroy(struct UCTimers *timers) is currently missing..
#ifdef __cplusplus
}
#endif
#endif
+4 -2
View File
@@ -48,12 +48,14 @@
//struct foo *f = CONTAINER_OF(p, struct foo, zap);
#define CONTAINER_OF(ptr, type, member) ({ \
typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (unsigned char *)__mptr - offsetof(type, member) ); })
(type *)((void *)(unsigned char *)__mptr - offsetof(type, member) ); })
//the void* cast is to suppress alignment warnings
//Same as CONTAINER_OF, but for a const pointer to avoid gcc warnings..
#define CONST_CONTAINER_OF(ptr, type, member) ({ \
const typeof( ((const type *)0)->member ) *__mptr = (ptr); \
(const type *)( (const unsigned char *)__mptr - offsetof(const type, member) ); })
(const type *)((const void *)(const unsigned char *)__mptr - offsetof(const type, member) ); })
/** Align a value.
* @param val value to align
+8
View File
@@ -30,6 +30,9 @@
* </pre>
* @endhtmlonly
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Major version of the ucore library*/
extern const int ucore_version_major;
@@ -46,5 +49,10 @@ extern const char ucore_version_str[];
/** Hostname where the library was built
*/
extern const char ucore_build_host[];
#ifdef __cplusplus
}
#endif
#endif
+10 -8
View File
@@ -35,16 +35,18 @@ void uc_backtrace_buf(char *buf, size_t len)
buf[0] = 0;
lines = backtrace_symbols(buffer, ptrs);
for (i = 1; i < ptrs; i++) {
if (lines != NULL) {
for (i = 1; i < ptrs; i++) {
int rc = snprintf(buf, remaining, "%s\n", lines[i]);
if (rc <= 0 || (size_t)rc >= remaining) {
break;
int rc = snprintf(buf, remaining, "%s\n", lines[i]);
if (rc <= 0 || (size_t)rc >= remaining) {
break;
}
remaining -= rc;
buf += rc;
}
remaining -= rc;
buf += rc;
}
free(lines);
+2 -2
View File
@@ -4,7 +4,7 @@
#include <errno.h>
#include <string.h>
#include <assert.h>
#include "ucore/iomux_impl.h"
#include "iomux_impl.h"
//epoll (linux specific) IO mux.
//We stuff the struct IOMuxFD pointer in the event.data.ptr slot
@@ -183,7 +183,7 @@ again:
fd->callback(mux_, fd, events);
//be sure not to use fd after the callback, it might been removed.
mux->pending_events[i].data.ptr = NULL;
mux->pending_events[i].data.ptr = NULL; //clear from pending list
event_cnt++;
}
+1 -1
View File
@@ -2,8 +2,8 @@
#include <string.h>
#include <string.h>
#include <assert.h>
#include <ucore/iomux_impl.h>
#include "ucore/clock.h"
#include "iomux_impl.h"
//dispatchers for the IOMux implementations */
@@ -1,8 +1,8 @@
#ifndef IO_MUX_IMPL_H_
#define IO_MUX_IMPL_H_
#include "iomux.h"
#include "timers.h"
#include "ucore/iomux.h"
#include "ucore/timers.h"
/** struct for IOMux implementations */
struct IOMux {
+3 -2
View File
@@ -5,8 +5,8 @@
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#include "ucore/iomux_impl.h"
#include "ucore/utils.h"
#include "iomux_impl.h"
#define IOMUX_GROW_CHUNK (32)
@@ -168,17 +168,18 @@ again:
}
if (FD_ISSET(mux->descriptors[i]->fd, &read_set)) {
rc--;
events |= MUX_EV_READ;
}
if (FD_ISSET(mux->descriptors[i]->fd, &write_set)) {
rc--;
events |= MUX_EV_WRITE;
}
if (events) {
assert(mux->descriptors[i]->callback != NULL);
mux->descriptors[i]->callback(mux_, mux->descriptors[i], events);
rc--;
event_cnt++;
}
}
+16 -16
View File
@@ -68,17 +68,18 @@ static SLIST_HEAD(, uc_log_destination) g_destinations;
static int uc_log_reopen_file(struct uc_log_destination *dest);
//Uses enum UC_LOG_LEVEL as index
static const char *const g_log_levels[] = {
"NONE",
"UNKNOWN_0",
"DEBUG",
"UNKNOWN_2",
"INFO",
"UNKNOWN_4",
"WARNING",
"UNKNOWN_6",
"ERROR"
"ERROR",
"NONE"
};
inline const char *uc_ll_2_str(enum UC_LOG_LEVEL l)
const char *uc_ll_2_str(enum UC_LOG_LEVEL l)
{
if (l < ARRAY_SIZE(g_log_levels)) {
return g_log_levels[l];
@@ -104,7 +105,6 @@ static int uc_str_2_ll(const char *str, size_t len)
static inline int uc_ll_2_syslog(enum UC_LOG_LEVEL l)
{
switch(l) {
case UC_LL_NONE:
case UC_LL_DEBUG:
return LOG_DEBUG;
case UC_LL_INFO:
@@ -113,6 +113,9 @@ static inline int uc_ll_2_syslog(enum UC_LOG_LEVEL l)
return LOG_WARNING;
case UC_LL_ERROR:
return LOG_ERR;
case UC_LL_NONE:
return LOG_CRIT; //Fishy, but this should never happen
}
return LOG_INFO;
@@ -544,22 +547,14 @@ void uc_logf(int log_level, int module, int raw,
{
va_list ap;
struct uc_log_destination *dest;
const struct uc_log_module *log_module;
va_start(ap, fmt);
pthread_mutex_lock(&g_log_lock);
//Find the module doign the logging, or use the unknown module -
//the latter would indicate a bug somewhere in the application as it should
//always specify a known module
if (module >= 0 && module < g_modules.cnt)
log_module = &g_modules.mods[module];
else
log_module = &g_unknown_module;
//do logging for each destination
SLIST_FOREACH(dest, &g_destinations, entry) {
const struct uc_log_module *log_module;
va_list apc;
int module_log_level;
@@ -568,11 +563,16 @@ void uc_logf(int log_level, int module, int raw,
if (log_level < dest->log_level)
continue;
//individual module level
if (module >= 0 && module < g_modules.cnt)
//Find the module doing the logging, or use the unknown module -
//the latter would indicate a bug somewhere in the application as it should
//always specify a known module
if (module >= 0 && module < g_modules.cnt) {
module_log_level = dest->module_settings[module].log_level;
else //application bug. use global/unknown module
log_module = &g_modules.mods[module];
} else {
log_module = &g_unknown_module;
module_log_level = log_module->log_level;
}
if (log_level < module_log_level)
continue;
+121
View File
@@ -0,0 +1,121 @@
#include <string.h>
#include <stdlib.h>
#include "ucore/mbuf.h"
uint8_t *uc_mbuf_put(struct MBuf *mbuf, uint32_t size)
{
uint8_t *data = mbuf->tail;
if (uc_mbuf_tailroom(mbuf) < size) {
return NULL;
}
mbuf->tail += size;
return data;
}
uint8_t *uc_mbuf_push(struct MBuf *mbuf, uint32_t size)
{
if (uc_mbuf_headroom(mbuf) < size) {
return NULL;
}
mbuf->head -= size;
return mbuf->head;
}
uint8_t *uc_mbuf_pull(struct MBuf *mbuf, uint32_t size)
{
uint8_t *data = mbuf->head;
if (uc_mbuf_len(mbuf) < size) {
return NULL;
}
mbuf->head += size;
return data;
}
void uc_mbuf_init(struct MBuf *mbuf, uint8_t *buf, uint32_t len, uint32_t headroom, uint32_t flags)
{
mbuf->bufstart = buf;
mbuf->next = NULL;
mbuf->p1 = mbuf->p2 = mbuf->p3 = mbuf->p4 = NULL;
mbuf->cookie = NULL;
mbuf->flags = flags;
mbuf->allocated = len + headroom;
mbuf->head = mbuf->bufstart + headroom;
mbuf->tail = mbuf->head;
}
struct MBuf *uc_mbuf_new_hr(uint32_t len, uint32_t headroom)
{
struct MBuf *mbuf;
uint8_t *buf;
mbuf = malloc(sizeof *mbuf);
if (mbuf == NULL)
return mbuf;
buf = malloc(len + headroom);
if (buf == NULL) {
free(mbuf);
return NULL;
}
uc_mbuf_init(mbuf, buf, len, headroom, UC_MBUF_FL_MALLOC);
return mbuf;
}
struct MBuf *uc_mbuf_new_inline_hr(uint32_t len, uint32_t headroom)
{
struct MBuf *mbuf;
mbuf = malloc(sizeof *mbuf + len + headroom);
if (mbuf == NULL)
return mbuf;
uc_mbuf_init(mbuf, mbuf->inline_data, len, headroom, UC_MBUF_FL_MALLOC_INLINE);
return mbuf;
}
void uc_mbuf_free(struct MBuf *mbuf)
{
if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_BUF))
free(mbuf->bufstart);
if (mbuf->flags & (UC_MBUF_FL_MALLOC | UC_MBUF_FL_MALLOC_INLINE))
free(mbuf);
}
void uc_mbuf_zero(struct MBuf *mbuf)
{
memset(mbuf->bufstart, 0, mbuf->allocated);
}
struct MBuf *uc_mbuf_copy_data(struct MBuf *mbuf)
{
uint32_t len;
struct MBuf *copy;
uint8_t *data;
len = uc_mbuf_len(mbuf);
copy = uc_mbuf_new_hr(len, uc_mbuf_headroom(mbuf));
if (copy == NULL) {
return NULL;
}
data = uc_mbuf_put(copy, len);
memcpy(data, mbuf->head, len);
return copy;
}
#undef UC_INLINE
+9 -5
View File
@@ -6,8 +6,10 @@ uc_tvadd(struct timeval *dst, const struct timeval *a, const struct timeval *b)
dst->tv_sec = a->tv_sec + b->tv_sec;
dst->tv_usec = a->tv_usec + b->tv_usec;
if (dst->tv_usec >= 1000000)
dst->tv_sec++, dst->tv_usec -= 1000000;
if (dst->tv_usec >= 1000000) {
dst->tv_sec++;
dst->tv_usec -= 1000000;
}
return dst;
}
@@ -18,8 +20,10 @@ uc_tvsub(struct timeval *dst, const struct timeval *a, const struct timeval *b)
dst->tv_sec = a->tv_sec - b->tv_sec;
dst->tv_usec = a->tv_usec - b->tv_usec;
if (dst->tv_usec < 0)
dst->tv_sec--, dst->tv_usec += 1000000;
if (dst->tv_usec < 0) {
dst->tv_sec--;
dst->tv_usec += 1000000;
}
return dst;
}
@@ -41,7 +45,7 @@ uc_tvcmp(const struct timeval *a, const struct timeval *b)
}
struct timeval *
uc_to2tv(struct timeval *dst, unsigned long ms)
uc_ms2tv(struct timeval *dst, unsigned long long ms)
{
dst->tv_sec = ms / 1000;
dst->tv_usec = ms % 1000 * 1000;
+61
View File
@@ -410,6 +410,64 @@ START_TEST (test_logfile_dest_mask)
fail_if(st.st_size != 14*2, "was %ld\n", (long)st.st_size);
END_TEST
START_TEST (test_loglevel_module_none)
struct uc_log_module m = {
.id = 0,
.short_name = "MOD1",
.long_name = "Module 1",
.log_level = UC_LL_NONE,
};
struct uc_log_modules mods = {
.mods = &m,
.cnt = 1,
};
struct stat st;
struct uc_log_destination *dest;
int rc;
uc_log_init(&mods);
dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1);
fail_if(dest == NULL);
uc_log_add_destination(dest);
UC_LOGFR(UC_LL_ERROR, 0, "Lorum ipson %d\n", 1);
rc = stat(FILE_NAME, &st);
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size);
END_TEST
START_TEST (test_loglevel_dest_none)
struct uc_log_module m = {
.id = 0,
.short_name = "MOD1",
.long_name = "Module 1",
.log_level = UC_LL_DEBUG,
};
struct uc_log_modules mods = {
.mods = &m,
.cnt = 1,
};
struct stat st;
struct uc_log_destination *dest;
int rc;
uc_log_init(&mods);
dest = uc_log_new_file(FILE_NAME, UC_LL_NONE, 1);
fail_if(dest == NULL);
uc_log_add_destination(dest);
UC_LOGFR(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1);
rc = stat(FILE_NAME, &st);
fail_if(rc != 0, "stat failed: %s\n", strerror(errno));
fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size);
END_TEST
Suite *logging_suite(void)
{
@@ -435,6 +493,9 @@ Suite *logging_suite(void)
tcase_add_test(tc2, test_logfile_invalid_file_after_reopen);
tcase_add_test(tc1, test_logfile_raw);
tcase_add_test(tc1, test_loglevel_module_none);
tcase_add_test(tc1, test_loglevel_dest_none);
tcase_add_checked_fixture(tc1, logging_rm_files, logging_rm_files);
tcase_add_checked_fixture(tc2, logging_setup_subdir, logging_rm_subdir);
+222
View File
@@ -0,0 +1,222 @@
#include <check.h>
#include <string.h>
#include <ucore/mbuf.h>
START_TEST (test_mbuf_new)
struct MBuf *mbuf;
mbuf = uc_mbuf_new(110);
fail_if(mbuf == NULL);
fail_if(uc_mbuf_len(mbuf) != 0);
fail_if(uc_mbuf_headroom(mbuf) != 0);
fail_if(uc_mbuf_tailroom(mbuf) != 110);
fail_if(mbuf->next != NULL);
fail_if(mbuf->p1 != NULL);
fail_if(mbuf->p2 != NULL);
fail_if(mbuf->p3 != NULL);
fail_if(mbuf->p4 != NULL);
fail_if(mbuf->cookie != NULL);
fail_if(mbuf->head != mbuf->tail);
uc_mbuf_free(mbuf);
END_TEST
START_TEST (test_mbuf_new_inline)
struct MBuf *mbuf;
mbuf = uc_mbuf_new_inline(110);
fail_if(mbuf == NULL);
fail_if(uc_mbuf_len(mbuf) != 0);
fail_if(uc_mbuf_headroom(mbuf) != 0);
fail_if(uc_mbuf_tailroom(mbuf) != 110);
fail_if(mbuf->next != NULL);
fail_if(mbuf->p1 != NULL);
fail_if(mbuf->p2 != NULL);
fail_if(mbuf->p3 != NULL);
fail_if(mbuf->p4 != NULL);
fail_if(mbuf->cookie != NULL);
fail_if(mbuf->head != mbuf->tail);
uc_mbuf_free(mbuf);
END_TEST
START_TEST (test_mbuf_new_headroom)
struct MBuf *mbuf;
mbuf = uc_mbuf_new_hr(110,20);
fail_if(mbuf == NULL);
fail_if(uc_mbuf_len(mbuf) != 0);
fail_if(uc_mbuf_headroom(mbuf) != 20);
fail_if(uc_mbuf_tailroom(mbuf) != 110);
fail_if(mbuf->next != NULL);
fail_if(mbuf->p1 != NULL);
fail_if(mbuf->p2 != NULL);
fail_if(mbuf->p3 != NULL);
fail_if(mbuf->p4 != NULL);
fail_if(mbuf->cookie != NULL);
fail_if(mbuf->head != mbuf->tail);
uc_mbuf_free(mbuf);
END_TEST
START_TEST (test_mbuf_put)
struct MBuf *mbuf;
uint8_t *data;
mbuf = uc_mbuf_new_inline(111);
fail_if(mbuf == NULL);
data = uc_mbuf_put(mbuf, 111);
fail_if(data == NULL);
fail_if(uc_mbuf_len(mbuf) != 111);
fail_if(uc_mbuf_tailroom(mbuf) != 0);
memset(data, 0, 111);
uc_mbuf_free(mbuf);
END_TEST
START_TEST (test_mbuf_put_fail)
struct MBuf *mbuf;
uint8_t *data;
mbuf = uc_mbuf_new_inline(10);
fail_if(mbuf == NULL);
data = uc_mbuf_put(mbuf, 11);
fail_if(data != NULL);
uc_mbuf_free(mbuf);
END_TEST
START_TEST (test_mbuf_push)
struct MBuf *mbuf;
uint8_t *data;
mbuf = uc_mbuf_new_hr(10,1);
fail_if(mbuf == NULL);
data = uc_mbuf_push(mbuf, 1);
fail_if(data == NULL);
fail_if(uc_mbuf_len(mbuf) != 1);
fail_if(uc_mbuf_headroom(mbuf) != 0);
*data = 0;
uc_mbuf_free(mbuf);
END_TEST
START_TEST (test_mbuf_push_fail)
struct MBuf *mbuf;
uint8_t *data;
mbuf = uc_mbuf_new_hr(1,2);
fail_if(mbuf == NULL);
data = uc_mbuf_push(mbuf, 3);
fail_if(data != NULL);
uc_mbuf_free(mbuf);
END_TEST
START_TEST (test_mbuf_pull)
struct MBuf *mbuf;
uint8_t *data1;
uint8_t *data2;
mbuf = uc_mbuf_new_inline(10);
fail_if(mbuf == NULL);
data1 = uc_mbuf_put(mbuf, 10);
fail_if(data1 == NULL);
fail_if(uc_mbuf_tailroom(mbuf) != 0);
fail_if(uc_mbuf_len(mbuf) != 10);
data2 = uc_mbuf_pull(mbuf,10);
fail_if(data2 == NULL);
fail_if(data1 != data2);
fail_if(uc_mbuf_len(mbuf) != 0);
uc_mbuf_free(mbuf);
END_TEST
START_TEST (test_mbuf_pull_fail)
struct MBuf *mbuf;
uint8_t *data1;
uint8_t *data2;
mbuf = uc_mbuf_new_inline(10);
fail_if(mbuf == NULL);
data1 = uc_mbuf_put(mbuf, 10);
fail_if(data1 == NULL);
fail_if(uc_mbuf_len(mbuf) != 10);
data2 = uc_mbuf_pull(mbuf,11);
fail_if(data2 != NULL);
fail_if(uc_mbuf_len(mbuf) != 10);
uc_mbuf_free(mbuf);
END_TEST
START_TEST (test_mbuf_copy)
struct MBuf *mbuf;
uint8_t *data1;
struct MBuf *copy;
mbuf = uc_mbuf_new_inline_hr(10,5);
fail_if(mbuf == NULL);
data1 = uc_mbuf_put(mbuf, 10);
fail_if(data1 == NULL);
strcpy((char*)data1, "123456789");
copy = uc_mbuf_copy_data(mbuf);
fail_if(copy == NULL);
fail_if(uc_mbuf_len(copy) != 10);
fail_if(uc_mbuf_headroom(copy) != 5);
fail_if(memcmp(mbuf->head, copy->head, 10) != 0);
uc_mbuf_free(mbuf);
uc_mbuf_free(copy);
END_TEST
Suite *mbuf_suite(void)
{
Suite *s = suite_create("mbuf");
TCase *tc = tcase_create("mbuf tests");
tcase_add_test(tc, test_mbuf_new);
tcase_add_test(tc, test_mbuf_new_inline);
tcase_add_test(tc, test_mbuf_new_headroom);
tcase_add_test(tc, test_mbuf_put);
tcase_add_test(tc, test_mbuf_put_fail);
tcase_add_test(tc, test_mbuf_push);
tcase_add_test(tc, test_mbuf_push_fail);
tcase_add_test(tc, test_mbuf_pull);
tcase_add_test(tc, test_mbuf_pull_fail);
tcase_add_test(tc, test_mbuf_copy);
suite_add_tcase(s, tc);
return s;
}
+63
View File
@@ -91,6 +91,65 @@ START_TEST (test_read_file_boundary)
free(content);
END_TEST
START_TEST (test_read_file_devnull)
char *content;
size_t len = 123;
content = uc_read_file("/dev/null", &len, 1024);
fail_if(content == NULL);
fail_if(len != 0);
free(content);
END_TEST
START_TEST (test_read_file_too_big)
char *content;
const char *filename = "test_read_file_too_big";
size_t len;
ssize_t rc;
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);
fail_if(fd == -1);
rc = write(fd, "hello", 5);
fail_if(rc != 5, "rc was %ld", (long)rc);
close(fd);
content = uc_read_file(filename, &len, 4);
fail_if(errno != EMSGSIZE);
fail_if(content != NULL);
unlink(filename);
END_TEST
START_TEST (test_read_file_big)
char *content;
const char *filename = "test_read_file_big";
char buf[4096 * 16];
size_t len;
ssize_t rc;
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);
fail_if(fd == -1);
memset(buf, 'a', sizeof buf);
rc = write(fd, buf, sizeof buf);
fail_if(rc != sizeof buf, "rc was %ld", (long)rc);
close(fd);
content = uc_read_file(filename, &len, 4096*16);
fail_if(content == NULL);
fail_if(len != sizeof buf);
fail_if(memcmp(content, buf, sizeof buf) != 0);
free(content);
unlink(filename);
END_TEST
Suite *read_file_suite(void)
{
Suite *s = suite_create("read_file");
@@ -99,6 +158,10 @@ Suite *read_file_suite(void)
tcase_add_test(tc, test_read_file_simple);
tcase_add_test(tc, test_read_file_greater_than_max);
tcase_add_test(tc, test_read_file_boundary);
tcase_add_test(tc, test_read_file_devnull);
tcase_add_test(tc, test_read_file_too_big);
tcase_add_test(tc, test_read_file_big);
suite_add_tcase(s, tc);
+2
View File
@@ -19,6 +19,7 @@ extern Suite *clock_suite(void);
extern Suite *seq_suite(void);
extern Suite *sat_math_suite(void);
extern Suite *timers_suite(void);
extern Suite *mbuf_suite(void);
extern Suite *human_bytesz_suite(void);
static suite_func suites[] = {
@@ -35,6 +36,7 @@ static suite_func suites[] = {
seq_suite,
sat_math_suite,
timers_suite,
mbuf_suite,
human_bytesz_suite
};