Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
mxq/test_mx_util.c
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
652 lines (510 sloc)
16.2 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _GNU_SOURCE | |
#include <assert.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include "mx_util.h" | |
#include "mx_proc.h" | |
static void test_mx_strskipwhitespaces(void) | |
{ | |
char *s; | |
assert((s = mx_strskipwhitespaces(" abc "))); | |
assert(strcmp(s, "abc ") == 0); | |
assert((s = mx_strskipwhitespaces("abc "))); | |
assert(strcmp(s, "abc ") == 0); | |
assert((s = mx_strskipwhitespaces(""))); | |
assert(strcmp(s, "") == 0); | |
} | |
static void test_mx_strtoul(void) | |
{ | |
unsigned long int l; | |
assert(mx_strtoul("123", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoul(" 123 ", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoul("0173", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoul("0x007b", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoul("0x007B", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoul("+123", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoul("-1", &l) == -ERANGE); | |
assert(mx_strtoul(" -1", &l) == -ERANGE); | |
assert(mx_strtoul("123 123", &l) == -EINVAL); | |
assert(mx_strtoul("123s", &l) == -EINVAL); | |
assert(mx_strtoul("0888", &l) == -EINVAL); | |
assert(mx_strtoul("1.2", &l) == -EINVAL); | |
assert(mx_strtoul("1,2", &l) == -EINVAL); | |
assert(mx_strtoul("test", &l) == -EINVAL); | |
} | |
static void test_mx_strtoull(void) | |
{ | |
unsigned long long int l; | |
assert(mx_strtoull("123", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoull("0173", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoull("0x007b", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoull("0x00000000000000000000000000000007b", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoull("0x007B", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoull("-127", &l) == -ERANGE); | |
assert(mx_strtoull(" -128", &l) == -ERANGE); | |
assert(mx_strtoull("0888", &l) == -EINVAL); | |
assert(mx_strtoull("1.2", &l) == -EINVAL); | |
assert(mx_strtoull("1,2", &l) == -EINVAL); | |
assert(mx_strtoull("test", &l) == -EINVAL); | |
} | |
static void test_mx_strtou8(void) | |
{ | |
uint8_t u; | |
assert(mx_strtou8("255", &u) == 0); | |
assert(u == 255); | |
assert(mx_strtou8("256", &u) == -ERANGE); | |
} | |
static void test_mx_strtoi8(void) | |
{ | |
int8_t u; | |
assert(mx_strtoi8("127", &u) == 0); | |
assert(u == 127); | |
assert(mx_strtoi8("-127", &u) == 0); | |
assert(u == -127); | |
assert(mx_strtoi8(" -128", &u) == 0); | |
assert(u == -128); | |
assert(mx_strtoi8("128", &u) == -ERANGE); | |
assert(mx_strtoi8("-129", &u) == -ERANGE); | |
} | |
static void test_mx_strbeginswith(void) | |
{ | |
char *end = NULL; | |
assert(mx_strbeginswith("blahblubb", "", NULL)); | |
assert(mx_strbeginswith("blahblubb", "", &end)); | |
assert(strcmp(end, "blahblubb") == 0); | |
assert(mx_strbeginswith("BlahBlubb", "Blah", &end)); | |
assert(strcmp(end, "Blubb") == 0); | |
assert(mx_strbeginswith("blahblubb", "blahblubb", &end)); | |
assert(*end == 0); | |
end = NULL; | |
assert(mx_strbeginswith("blahblubb", "blubb", &end) == 0); | |
assert(end == NULL); | |
assert(mx_strbeginswith("blah", "blahblubb", &end) == 0); | |
assert(end == NULL); | |
assert(mx_strbeginswith("Blahblubb", "blah", &end) == 0); | |
assert(end == NULL); | |
assert(mx_strbeginswith("", "blah", &end) == 0); | |
assert(end == NULL); | |
} | |
static void test_mx_stribeginswith(void) | |
{ | |
char *end = NULL; | |
assert(mx_stribeginswith("blahblubb", "", NULL)); | |
assert(mx_stribeginswith("blahblubb", "", &end)); | |
assert(strcmp(end, "blahblubb") == 0); | |
assert(mx_stribeginswith("BlahBlubb", "Blah", &end)); | |
assert(strcmp(end, "Blubb") == 0); | |
assert(mx_stribeginswith("BlahBlubb", "bLaH", &end)); | |
assert(strcmp(end, "Blubb") == 0); | |
assert(mx_stribeginswith("blahblubb", "BlahBluBB", &end)); | |
assert(*end == 0); | |
end = NULL; | |
assert(mx_stribeginswith("blahblubb", "blubb", &end) == 0); | |
assert(end == NULL); | |
assert(mx_stribeginswith("blah", "blahblubb", &end) == 0); | |
assert(end == NULL); | |
assert(mx_stribeginswith("", "blah", &end) == 0); | |
assert(end == NULL); | |
} | |
static void test_mx_strbeginswithany(void) | |
{ | |
char *end = NULL; | |
assert(mx_strbeginswithany("blahblubb", (char *[]){ "bla", "blah", NULL }, &end)); | |
assert(strcmp(end, "blubb") == 0); | |
assert(mx_strbeginswithany("blablubb", (char *[]){ "bla", "blah", NULL }, &end)); | |
assert(strcmp(end, "blubb") == 0); | |
end = NULL; | |
assert(mx_strbeginswithany("blubb", (char *[]){ "bla", "blah", NULL }, &end) == 0); | |
assert(end == NULL); | |
} | |
static void test_mx_strtoseconds(void) | |
{ | |
unsigned long long int l; | |
assert(mx_strtoseconds("123s", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoseconds("0123s", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoseconds("123s0s", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoseconds("2m3s", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoseconds(" 2 m 3 s ", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtoseconds("1h 2m 3s", &l) == 0); | |
assert(l == 60*60 + 2*60 + 3); | |
assert(mx_strtoseconds("2m 3s 1h", &l) == 0); | |
assert(l == 60*60 + 2*60 + 3); | |
assert(mx_strtoseconds("2m 3s 1h1y", &l) == 0); | |
assert(l == 60*60 + 2*60 + 3 + 52*7*24*60*60); | |
assert(mx_strtoseconds("2m 3s 1h1y", &l) == 0); | |
assert(l == 60*60 + 2*60 + 3 + 52*7*24*60*60); | |
assert(mx_strtoseconds("-1", &l) == -ERANGE); | |
assert(mx_strtoseconds(" -1", &l) == -ERANGE); | |
assert(mx_strtoseconds("123", &l) == -EINVAL); | |
assert(mx_strtoseconds("0123", &l) == -EINVAL); | |
assert(mx_strtoseconds("1.2", &l) == -EINVAL); | |
assert(mx_strtoseconds("1,2", &l) == -EINVAL); | |
assert(mx_strtoseconds("test", &l) == -EINVAL); | |
} | |
static void test_mx_strtominutes(void) | |
{ | |
unsigned long long int l; | |
assert(mx_strtominutes("123s", &l) == 0); | |
assert(l == 2); | |
assert(mx_strtominutes("20d", &l) == 0); | |
assert(l == 20*24*60); | |
assert(mx_strtominutes("-1", &l) == -ERANGE); | |
assert(mx_strtominutes(" -1", &l) == -ERANGE); | |
assert(mx_strtominutes("123", &l) == -EINVAL); | |
assert(mx_strtominutes("0123", &l) == -EINVAL); | |
assert(mx_strtominutes("1.2", &l) == -EINVAL); | |
assert(mx_strtominutes("1,2", &l) == -EINVAL); | |
assert(mx_strtominutes("test", &l) == -EINVAL); | |
} | |
static void test_mx_strtobytes(void) | |
{ | |
unsigned long long int l; | |
assert(mx_strtobytes("123B", &l) == 0); | |
assert(l == 123); | |
assert(mx_strtobytes("2M", &l) == 0); | |
assert(l == 2*1024*1024); | |
assert(mx_strtobytes("1M1024k", &l) == 0); | |
assert(l == 2*1024*1024); | |
assert(mx_strtobytes("1024k1024K", &l) == 0); | |
assert(l == 2*1024*1024); | |
assert(mx_strtobytes("-1", &l) == -ERANGE); | |
assert(mx_strtobytes(" -1", &l) == -ERANGE); | |
assert(mx_strtobytes("2.5M", &l) == -EINVAL); | |
assert(mx_strtobytes("123", &l) == -EINVAL); | |
assert(mx_strtobytes("0123", &l) == -EINVAL); | |
assert(mx_strtobytes("1.2", &l) == -EINVAL); | |
assert(mx_strtobytes("1,2", &l) == -EINVAL); | |
assert(mx_strtobytes("test", &l) == -EINVAL); | |
} | |
static void test_mx_read_first_line_from_file(void) | |
{ | |
char *str; | |
long long int l; | |
assert(mx_read_first_line_from_file("/proc/sys/kernel/random/boot_id", &str) == 36); | |
assert(str); | |
mx_free_null(str); | |
assert(mx_read_first_line_from_file("/proc/sys/kernel/random/uuid", &str) == 36); | |
assert(str); | |
mx_free_null(str); | |
assert(mx_read_first_line_from_file("/proc/no_such_file", &str) == -ENOENT); | |
assert(str == NULL); | |
assert(mx_read_first_line_from_file("/proc/self/stat", &str) > 0); | |
assert(str); | |
mx_strtoll(str, &l); | |
mx_free_null(str); | |
} | |
static void test_mx_strscan(void) | |
{ | |
_mx_cleanup_free_ char *s = NULL; | |
char *str; | |
unsigned long long int ull; | |
long long int ll; | |
_mx_cleanup_free_ char *line = NULL; | |
_mx_cleanup_free_ struct mx_proc_pid_stat *pps = NULL; | |
assert((s = strdup("123 456 -789 246 abc"))); | |
str = s; | |
assert(mx_strscan_ull(&str, &ull) == 0); | |
assert(ull == 123); | |
assert(mx_strscan_ull(&str, &ull) == 0); | |
assert(ull == 456); | |
assert(mx_strscan_ull(&str, &ull) == -ERANGE); | |
assert(mx_streq(str, "-789 246 abc")); | |
assert(mx_strscan_ll(&str, &ll) == 0); | |
assert(ll == -789); | |
assert(mx_streq(str, "246 abc")); | |
assert(mx_strscan_ll(&str, &ll) == 0); | |
assert(ll == 246); | |
assert(mx_streq(str, "abc")); | |
assert(mx_strscan_ull(&str, &ull) == -EINVAL); | |
assert(mx_streq(str, "abc")); | |
assert(mx_streq(s, "123 456 -789 246 abc")); | |
mx_free_null(s); | |
assert((s = strdup("123"))); | |
str = s; | |
assert(mx_strscan_ull(&str, &ull) == 0); | |
assert(ull == 123); | |
assert(mx_streq(str, "")); | |
assert(mx_streq(s, "123")); | |
assert(mx_proc_pid_stat(&pps, getpid()) == 0); | |
assert(pps->pid == getpid()); | |
assert(pps->ppid == getppid()); | |
assert(pps->state == 'R'); | |
assert(mx_streq(pps->comm, program_invocation_short_name) || mx_streq(pps->comm, "memcheck-amd64-")); | |
mx_proc_pid_stat_free_content(pps); | |
} | |
static void test_mx_strvec(void) { | |
char **strvec; | |
char *str; | |
strvec=mx_strvec_new(); | |
mx_strvec_push_str(&strvec,strdup("Hallo")); | |
mx_strvec_push_str(&strvec,strdup("Bla")); | |
mx_strvec_push_str(&strvec,strdup("lall")); | |
assert((str=mx_strvec_join("XXX",strvec))); | |
assert(strcmp(str,"HalloXXXBlaXXXlall")==0); | |
free(str); | |
assert((str=mx_strvec_join("",strvec))); | |
assert(strcmp(str,"HalloBlalall")==0); | |
free(str); | |
mx_strvec_free(strvec); | |
strvec=mx_strvec_new(); | |
assert((str=mx_strvec_join("XXX",strvec))); | |
assert(strcmp(str,"")==0); | |
free(str); | |
mx_strvec_push_str(&strvec,strdup("A")); | |
assert((str=mx_strvec_join("x",strvec))); | |
assert(strcmp(str,"A")==0); | |
free(str); | |
mx_strvec_push_str(&strvec,strdup("")); | |
assert((str=mx_strvec_join("x",strvec))); | |
assert(strcmp(str,"Ax")==0); | |
free(str); | |
mx_strvec_push_str(&strvec,strdup("B")); | |
assert((str=mx_strvec_join("x",strvec))); | |
assert(strcmp(str,"AxxB")==0); | |
free(str); | |
mx_strvec_free(strvec); | |
char *test[] = { "AAA", "", "bbb", NULL}; | |
str = mx_strvec_to_str(test); | |
assert(strcmp(str,"AAA\\0\\0bbb\\0")==0); | |
strvec = mx_strvec_from_str(str); | |
assert( strcmp(strvec[0], "AAA") == 0 ); | |
assert( strcmp(strvec[1], "") == 0 ); | |
assert( strcmp(strvec[2], "bbb") == 0 ); | |
assert( strvec[3] == NULL); | |
free(str); | |
free(strvec); | |
} | |
static void test_mx_strcat(void) { | |
char *str; | |
char *str2; | |
assert((str = mx_strconcat(NULL))); | |
assert(mx_streq(str, "")); | |
mx_free_null(str); | |
assert((str = mx_strconcat("abc", "123"))); | |
assert(mx_streq(str, "abc123")); | |
assert((str2 = mx_strconcat(str, "def", str, "456"))); | |
assert(mx_streq(str2, "abc123defabc123456")); | |
mx_free_null(str2); | |
assert((str2 = mx_strconcat(str))); | |
assert(mx_streq(str, str2)); | |
mx_free_null(str); | |
mx_free_null(str2); | |
} | |
static void test_mx_cpuset(void) | |
{ | |
cpu_set_t cpuset; | |
char *str; | |
assert(mx_str_to_cpuset(&cpuset,"1,2,3,10,11,12,100-102")==0); | |
assert((str=mx_cpuset_to_str(&cpuset))); | |
assert(strcmp(str,"1-3,10-12,100-102")==0); | |
free(str); | |
assert(mx_str_to_cpuset(&cpuset,"")==0); | |
assert((str=mx_cpuset_to_str(&cpuset))); | |
assert(strcmp(str,"")==0); | |
free(str); | |
assert(mx_str_to_cpuset(&cpuset,"bla")<0); | |
assert(mx_str_to_cpuset(&cpuset,"5-4")<0); | |
assert(mx_str_to_cpuset(&cpuset,"-4")<0); | |
assert(mx_str_to_cpuset(&cpuset,"4-")<0); | |
} | |
struct obj { | |
int i; | |
struct obj *next; | |
}; | |
int obj_compare(struct obj *o1,struct obj *o2) | |
{ | |
return | |
o1->i > o2->i ? 1 | |
: o1->i < o2->i ? -1 | |
: 0; | |
} | |
struct obj **obj_getnextptr(struct obj *o) { | |
return &o->next; | |
} | |
static void test_listsort(void) | |
{ | |
struct obj o[10]; | |
struct obj *list; | |
for (int i=0;i<10;i++) { | |
o[i].i=i; | |
o[i].next= i==9 ? NULL : &o[i+1]; | |
} | |
/* () -> () */ | |
list=NULL; | |
mx_sort_linked_list(&list,obj_compare,obj_getnextptr); | |
assert(list==NULL); | |
/* (9) -> (9) */ | |
list=&o[9]; | |
mx_sort_linked_list(&list,obj_compare,obj_getnextptr); | |
assert(list==&o[9]); | |
assert(o[9].next==NULL); | |
/* (9 8 7 6 5 4 3 2 1 0) -> (0 1 2 3 4 5 6 7 8 9) */ | |
list=&o[0]; | |
for (int i=0;i<10;i++) { | |
o[i].i = 9-i; | |
} | |
mx_sort_linked_list(&list,obj_compare,obj_getnextptr); | |
assert(list==&o[9]); | |
for (int i=0;i<10;i++) { | |
assert(o[i].next == (i==0 ? NULL : &o[i-1])); | |
} | |
/* (100 0 1 2 50 50 2 1 0 100) -> ( 0 0 1 1 2 2 50 50 100 100) stable */ | |
/* also verify stable sort */ | |
for (int i=0;i<10;i++) { | |
o[i].next= i==9 ? NULL : &o[i+1]; | |
} | |
list=&o[0]; | |
o[0].i=100; | |
o[1].i=0; | |
o[2].i=1; | |
o[3].i=2; | |
o[4].i=50; | |
o[5].i=50; | |
o[6].i=2; | |
o[7].i=1; | |
o[8].i=0; | |
o[9].i=100; | |
mx_sort_linked_list(&list,obj_compare,obj_getnextptr); | |
assert(list==&o[1]); | |
assert(o[1].next==&o[8]); | |
assert(o[8].next==&o[2]); | |
assert(o[2].next==&o[7]); | |
assert(o[7].next==&o[3]); | |
assert(o[3].next==&o[6]); | |
assert(o[6].next==&o[4]); | |
assert(o[4].next==&o[5]); | |
assert(o[5].next==&o[0]); | |
assert(o[0].next==&o[9]); | |
assert(o[9].next==NULL); | |
} | |
static void test_mx_df(void) { | |
unsigned long free; | |
unsigned long total; | |
int res = mx_fs_get_sizes("/", &free, &total); | |
assert(res == 0); | |
assert(total != 0); | |
assert(free != 0); | |
assert(total > free); | |
unsigned long free2 = mx_df("/"); | |
assert(free2 > free-1024*1024*1024 || free2 < free+1024*1024*1024); | |
free = 123; | |
total = 456; | |
res = mx_fs_get_sizes("/does_not_exist", &free, &total); | |
assert(res == -1); | |
assert(errno == ENOENT); | |
assert (free == 123); | |
assert (total == 456); | |
} | |
static void test_mx_pipe_external(void) { | |
char *line; | |
errno = 999; | |
{ | |
char *argv[] = { "/usr/bin/echo", "123", NULL }; | |
line = mx_pipe_external("/usr/bin/echo", argv); | |
assert(line && strcmp(line, "123") == 0); | |
free(line); | |
} | |
{ | |
char *argv[] = { "/usr/bin/echo", "-n", "123", NULL }; | |
line = mx_pipe_external("/usr/bin/echo", argv); | |
assert(line && strcmp(line, "123") == 0); | |
free(line); | |
} | |
{ | |
char *argv[] = { "/usr/bin/echo", "-ne", "123\n456\n\n", NULL }; | |
line = mx_pipe_external("/usr/bin/echo", argv); | |
assert(line && strcmp(line, "123\n456\n") == 0); | |
free(line); | |
} | |
{ | |
char *argv[] = { "/usr/bin/true", NULL }; | |
line = mx_pipe_external("/usr/bin/true", argv); | |
assert(line && strcmp(line, "") == 0); | |
free(line); | |
} | |
assert(errno == 999); | |
{ | |
char *argv[] = { "/usr/bin/false", NULL }; | |
line = mx_pipe_external("/usr/bin/false", argv); | |
assert(line == NULL && errno==EPROTO); | |
} | |
{ | |
char *argv[] = { "/usr/bin/cat", "/usr/bin/bash", NULL }; | |
line = mx_pipe_external("/usr/bin/cat", argv); | |
assert(line == NULL && errno==EPROTO); | |
} | |
{ | |
char *argv[] = { "/usr/bin/yes", NULL }; | |
line = mx_pipe_external("/usr/bin/yes", argv); | |
assert(line == NULL && errno==EPROTO); | |
} | |
} | |
static void test_mx_call_external(void) { | |
int sts; | |
errno = 999; | |
char *argv[] = { "", NULL }; | |
sts = mx_call_external("/usr/bin/true", argv); | |
assert(sts == 0); | |
assert(errno == 999); | |
sts = mx_call_external("/usr/bin/false", argv); | |
assert(sts == -1); | |
assert(errno == EPROTO); | |
} | |
static void test_mx_closerange(void) { | |
int res; | |
int fd1 = open("/dev/null", O_RDONLY); | |
assert (fd1 != -1); | |
int fd2 = dup2(fd1, 100); | |
assert (fd2 == 100 ); | |
res=close_range(3, ~0u, 0); | |
assert(res == 0); | |
res = close(fd1); | |
assert (res == -1 && errno == EBADF); | |
res = close(fd2); | |
assert (res == -1 && errno == EBADF); | |
} | |
int main(void) | |
{ | |
test_mx_strskipwhitespaces(); | |
test_mx_strtoul(); | |
test_mx_strtoull(); | |
test_mx_strtou8(); | |
test_mx_strtoi8(); | |
test_mx_strbeginswith(); | |
test_mx_stribeginswith(); | |
test_mx_strbeginswithany(); | |
test_mx_strtoseconds(); | |
test_mx_strtominutes(); | |
test_mx_strtobytes(); | |
test_mx_read_first_line_from_file(); | |
test_mx_strscan(); | |
test_mx_strvec(); | |
test_mx_strcat(); | |
test_mx_cpuset(); | |
test_listsort(); | |
test_mx_df(); | |
test_mx_pipe_external(); | |
test_mx_call_external(); | |
test_mx_closerange(); | |
return 0; | |
} |