# -*- Autotest -*-
AT_BANNER([problem report])
## ------- ##
## summary ##
## ------- ##
AT_TESTFUN([summary],
[[
#include "problem_report.h"
#include "internal_libreport.h"
#include <assert.h>
int main(int argc, char **argv)
{
const char *const test_format_result[][2] = {
{
"%summary:: [abrt] trivial string",
"[abrt] trivial string"
},
{
"%summary:: [abrt] %package%",
"[abrt] libreport"
},
{
"%summary:: [abrt] %package%[[ : %crash_function%()]][[ : %does_not_exist%]][[ : %reason%]][[ TAINTED: %taint_flags%]]",
"[abrt] libreport : run_event() : Killed by SIGSEGV"
},
{
"%summary:: [abrt] %package%[[ : %crash_function%[[ : %does_not_exist%]]()]][[ : %reason%]]",
"[abrt] libreport : run_event() : Killed by SIGSEGV"
},
{
"%summary:: [abrt] %package%[[ : %does_not_exist%[[ : %crash_function%()]]]][[ : %reason%]]",
"[abrt] libreport : Killed by SIGSEGV"
},
{
"%summary:: [[%does_not_exist%]][[%once_more%]][abrt] %package%",
"[abrt] libreport"
},
{
"",
"Killed by SIGSEGV"
},
};
g_verbose = 3;
problem_data_t *data = problem_data_new();
problem_data_add_text_noteditable(data, "package", "libreport");
problem_data_add_text_noteditable(data, "crash_function", "run_event");
problem_data_add_text_noteditable(data, "reason", "Killed by SIGSEGV");
for (size_t i = 0; i < sizeof(test_format_result)/sizeof(*test_format_result); ++i) {
problem_formatter_t *pf = problem_formatter_new();
assert(!problem_formatter_load_string(pf, test_format_result[i][0]));
problem_report_t *pr = NULL;
assert(!problem_formatter_generate_report(pf, data, &pr));
assert(pr != NULL);
const char *summary = problem_report_get_summary(pr);
assert(summary != NULL);
fprintf(stderr, "expected: '%s'\n", test_format_result[i][1]);
fprintf(stderr, "result : '%s'\n", summary);
assert(strcmp(test_format_result[i][1], summary) == 0);
problem_report_free(pr);
problem_formatter_free(pf);
}
problem_data_free(data);
return 0;
}
]])
## ---------- ##
## desciption ##
## ---------- ##
AT_TESTFUN([description],
[[
#include "problem_report.h"
#include "internal_libreport.h"
#include <assert.h>
#include "testsuite.h"
int main(int argc, char **argv)
{
const char *const test_format_result[][2] = {
{
"\n"\
"\n"\
"\n"\
"Single line\n"
"\n"\
"\n"\
"\n",
"Single line\n"
},
{
"\n"\
"\n"\
"\n"\
"Comment:: %bare_comment"
"\n"\
"\n"\
"\n"\
"Ad-hoc line\n"
"\n"\
"\n"\
"\n"\
"Additional:: package,\\\n"
"uuid,cwd\\\\"
",user_name"
"\n"\
"\n",
"Comment:\n" \
"Hello, world!\n"
"\n"\
"\n"\
"Ad-hoc line\n"
"\n"\
"\n"\
"\n"\
"Additional:\n"\
"package: libreport\n"\
"uuid: 123456789ABCDEF\n"\
"user_name: abrt\n",
},
{
":: %bare_description",
"I run will_segfault and\n"\
"it crashed as expected\n"
},
{
"User:: %bare_user_name,uid\n"\
"Additional info:: -uuid,%oneline,-comment,-package",
"User:\n"\
"abrt\n"\
"uid: 69\n"\
"Additional info:\n"\
"analyzer: CCpp\n"\
"root: /var/run/mock/abrt\n"\
"type: CCpp\n"
},
{
":: %reporter",
NULL /* do no check results*/
},
{
"Truncated backtrace:: %bare_%short_backtrace",
"Truncated backtrace:\n"
"Thread no. 0 (7 frames)\n"
" #1 crash at will_segfault.c:19\n"
" #2 varargs at will_segfault.c:31\n"
" #3 inlined at will_segfault.c:40\n"
" #4 f at will_segfault.c:45\n"
" #5 callback at will_segfault.c:50\n"
" #6 call_me_back at libwillcrash.c:8\n"
" #7 recursive at will_segfault.c:59\n"
},
};
g_verbose = 3;
problem_data_t *data = problem_data_new();
problem_data_add_text_noteditable(data, "package", "libreport");
problem_data_add_text_noteditable(data, "analyzer", "CCpp");
problem_data_add_text_noteditable(data, "type", "CCpp");
problem_data_add_text_noteditable(data, "comment", "Hello, world!");
problem_data_add_text_noteditable(data, "uuid", "123456789ABCDEF");
problem_data_add_text_noteditable(data, "uid", "69");
problem_data_add_text_noteditable(data, "user_name", "abrt");
problem_data_add_text_noteditable(data, "root", "/var/run/mock/abrt");
problem_data_add_text_noteditable(data, "description", "I run will_segfault and\nit crashed as expected\n");
problem_data_add_text_noteditable(data, "backtrace",
"Thread 1 (LWP 11865):\n"\
"#0 printf (__fmt=0x400acf \"Result: %d\\n\") at /usr/include/bits/stdio2.h:104\n"\
"No locals.\n"\
"#1 crash (p=p@entry=0x0) at will_segfault.c:19\n"\
"i = <error reading variable i (Cannot access memory at address 0x0)>\n"\
"#2 0x0000000000400964 in varargs (num_args=1, num_args@entry=2) at will_segfault.c:31\n"\
"p = <optimized out>\n"\
"ap = {{gp_offset = 24, fp_offset = 32767, overflow_arg_area = 0x7fff4fc8a0c0, reg_save_area = 0x7fff4fc8a080}}\n"\
"#3 0x00000000004009be in inlined (p=0x0) at will_segfault.c:40\n"\
"num = 42\n"\
"#4 f (p=p@entry=0x0) at will_segfault.c:45\n"\
"No locals.\n"\
"#5 0x00000000004009e9 in callback (data=data@entry=0x0) at will_segfault.c:50\n"\
"No locals.\n"\
"#6 0x00000032f76006f9 in call_me_back (cb=cb@entry=0x4009e0 <callback>, data=data@entry=0x0) at libwillcrash.c:8\n"\
"res = <optimized out>\n"\
"#7 0x0000000000400a14 in recursive (i=i@entry=0) at will_segfault.c:59\n"\
"p = <optimized out>\n"\
"#8 0x0000000000400a00 in recursive (i=i@entry=1) at will_segfault.c:66\n"\
"No locals.\n"\
"#9 0x0000000000400a00 in recursive (i=i@entry=2) at will_segfault.c:66\n"\
"No locals.\n"\
"#10 0x0000000000400775 in main (argc=<optimized out>, argv=<optimized out>) at will_segfault.c:83\n"\
"No locals.\n"\
"From To Syms Read Shared Object Library\n"\
"0x00000032f76005f0 0x00000032f7600712 Yes /lib64/libwillcrash.so.0\n"\
"0x0000003245c1f4f0 0x0000003245d6aca4 Yes /lib64/libc.so.6\n"\
"0x0000003245800b10 0x000000324581b6d0 Yes /lib64/ld-linux-x86-64.so.2\n"\
"$1 = 0x0\n"
"No symbol \"__glib_assert_msg\" in current context.\n"\
"rax 0xf 15\n"\
"rbx 0x0 0\n"\
"rcx 0x7ff96f752000 140709293531136\n"\
"rdx 0x3245fb9a40 215922481728\n"\
"rsi 0x7ff96f752000 140709293531136\n"\
"rdi 0x1 1\n"\
"rbp 0x400a30 0x400a30 <__libc_csu_init>\n"\
"rsp 0x7fff4fc8a050 0x7fff4fc8a050\n"\
"r8 0xffffffff 4294967295\n"\
"r9 0x0 0\n"\
"r10 0x22 34\n"\
"r11 0x246 582\n"\
"r12 0x40079f 4196255\n"\
"r13 0x7fff4fc8a210 140734531936784\n"\
"r14 0x0 0\n"\
"r15 0x0 0\n"\
"rip 0x4008ae 0x4008ae <crash+14>\n"\
"eflags 0x10246 [ PF ZF IF RF ]\n"\
"cs 0x33 51\n"\
"ss 0x2b 43\n"\
"ds 0x0 0\n"\
"es 0x0 0\n"\
"fs 0x0 0\n"\
"gs 0x0 0\n"\
"st0 0 (raw 0x00000000000000000000)\n"\
"st1 0 (raw 0x00000000000000000000)\n"\
"st2 0 (raw 0x00000000000000000000)\n"\
"st3 0 (raw 0x00000000000000000000)\n"\
"st4 0 (raw 0x00000000000000000000)\n"\
"st5 0 (raw 0x00000000000000000000)\n"\
"st6 0 (raw 0x00000000000000000000)\n"\
"st7 0 (raw 0x00000000000000000000)\n"\
"fctrl 0x37f 895\n"\
"fstat 0x0 0\n"\
"ftag 0xffff 65535\n"\
"fiseg 0x0 0\n"\
"fioff 0x0 0\n"\
"foseg 0x0 0\n"\
"fooff 0x0 0\n"\
"fop 0x0 0\n"\
"xmm0 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm1 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x2f <repeats 16 times>}, v8_int16 = {0x2f2f, 0x2f2f, 0x2f2f, 0x2f2f, 0x2f2f, 0x2f2f, 0x2f2f, 0x2f2f}, v4_int32 = {0x2f2f2f2f, 0x2f2f2f2f, 0x2f2f2f2f, 0x2f2f2f2f}, v2_int64 = {0x2f2f2f2f2f2f2f2f, 0x2f2f2f2f2f2f2f2f}, uint128 = 0x2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f}\n"\
"xmm2 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm3 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 13 times>, 0xff, 0x0, 0x0}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff00, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0xff00}, v2_int64 = {0x0, 0xff0000000000}, uint128 = 0x0000ff00000000000000000000000000}\n"\
"xmm4 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0xff0000, 0x0}, v2_int64 = {0x0, 0xff0000}, uint128 = 0x0000000000ff00000000000000000000}\n"\
"xmm5 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm6 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm7 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm8 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm9 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm10 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm11 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm12 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 14 times>, 0xff, 0x0}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff}, v4_int32 = {0x0, 0x0, 0x0, 0xff0000}, v2_int64 = {0x0, 0xff000000000000}, uint128 = 0x00ff0000000000000000000000000000}\n"\
"xmm13 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm14 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm15 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"mxcsr 0x1f80 [ IM DM ZM OM UM PM ]\n"\
"Dump of assembler code for function crash:\n"\
" 0x00000000004008a0 <+0>: push %rbx\n"\
" 0x00000000004008a1 <+1>: mov %rdi,%rbx\n"\
" 0x00000000004008a4 <+4>: mov $0x400ac0,%edi\n"\
" 0x00000000004008a9 <+9>: callq 0x4006f0 <puts@plt>\n"\
" => 0x00000000004008ae <+14>: mov (%rbx),%edx\n"\
" 0x00000000004008b0 <+16>: mov $0x400acf,%esi\n"\
" 0x00000000004008b5 <+21>: mov $0x1,%edi\n"\
" 0x00000000004008ba <+26>: xor %eax,%eax\n"\
" 0x00000000004008bc <+28>: callq 0x400740 <__printf_chk@plt>\n"\
" 0x00000000004008c1 <+33>: pop %rbx\n"\
" 0x00000000004008c2 <+34>: retq\n"\
"End of assembler dump.\n"
);
for (size_t i = 0; i < sizeof(test_format_result)/sizeof(*test_format_result); ++i) {
problem_formatter_t *pf = problem_formatter_new();
assert(!problem_formatter_load_string(pf, test_format_result[i][0]));
problem_report_t *pr = NULL;
assert(!problem_formatter_generate_report(pf, data, &pr));
assert(pr != NULL);
const char *summary = problem_report_get_description(pr);
assert(summary != NULL);
if (test_format_result[i][1] != NULL) {
fprintf(stderr, "####\n");
fprintf(stderr, "expected: '%s'\n", test_format_result[i][1]);
fprintf(stderr, "====\n");
fprintf(stderr, "result : '%s'\n", summary);
fprintf(stderr, "####\n");
TS_ASSERT_STRING_EQ(summary, test_format_result[i][1], "Correct summary");
}
problem_report_free(pr);
problem_formatter_free(pf);
}
problem_data_free(data);
return 0;
}
]])
## --------------- ##
## short_backtrace ##
## --------------- ##
AT_TESTFUN([short_backtrace],
[[
#include "problem_report.h"
#include "internal_libreport.h"
#include <assert.h>
#define BACKTRACE_CONTENT \
"Thread 1 (LWP 11865):\n"\
"#0 printf (__fmt=0x400acf \"Result: %d\\n\") at /usr/include/bits/stdio2.h:104\n"\
"No locals.\n"\
"#1 crash (p=p@entry=0x0) at will_segfault.c:19\n"\
"i = <error reading variable i (Cannot access memory at address 0x0)>\n"\
"#2 0x0000000000400964 in varargs (num_args=1, num_args@entry=2) at will_segfault.c:31\n"\
"p = <optimized out>\n"\
"ap = {{gp_offset = 24, fp_offset = 32767, overflow_arg_area = 0x7fff4fc8a0c0, reg_save_area = 0x7fff4fc8a080}}\n"\
"#3 0x00000000004009be in inlined (p=0x0) at will_segfault.c:40\n"\
"num = 42\n"\
"#4 f (p=p@entry=0x0) at will_segfault.c:45\n"\
"No locals.\n"\
"#5 0x00000000004009e9 in callback (data=data@entry=0x0) at will_segfault.c:50\n"\
"No locals.\n"\
"#6 0x00000032f76006f9 in call_me_back (cb=cb@entry=0x4009e0 <callback>, data=data@entry=0x0) at libwillcrash.c:8\n"\
"res = <optimized out>\n"\
"#7 0x0000000000400a14 in recursive (i=i@entry=0) at will_segfault.c:59\n"\
"p = <optimized out>\n"\
"#8 0x0000000000400a00 in recursive (i=i@entry=1) at will_segfault.c:66\n"\
"No locals.\n"\
"#9 0x0000000000400a00 in recursive (i=i@entry=2) at will_segfault.c:66\n"\
"No locals.\n"\
"#10 0x0000000000400775 in main (argc=<optimized out>, argv=<optimized out>) at will_segfault.c:83\n"\
"No locals.\n"\
"From To Syms Read Shared Object Library\n"\
"0x00000032f76005f0 0x00000032f7600712 Yes /lib64/libwillcrash.so.0\n"\
"0x0000003245c1f4f0 0x0000003245d6aca4 Yes /lib64/libc.so.6\n"\
"0x0000003245800b10 0x000000324581b6d0 Yes /lib64/ld-linux-x86-64.so.2\n"\
"$1 = 0x0\n"\
"No symbol \"__glib_assert_msg\" in current context.\n"\
"rax 0xf 15\n"\
"rbx 0x0 0\n"\
"rcx 0x7ff96f752000 140709293531136\n"\
"rdx 0x3245fb9a40 215922481728\n"\
"rsi 0x7ff96f752000 140709293531136\n"\
"rdi 0x1 1\n"\
"rbp 0x400a30 0x400a30 <__libc_csu_init>\n"\
"rsp 0x7fff4fc8a050 0x7fff4fc8a050\n"\
"r8 0xffffffff 4294967295\n"\
"r9 0x0 0\n"\
"r10 0x22 34\n"\
"r11 0x246 582\n"\
"r12 0x40079f 4196255\n"\
"r13 0x7fff4fc8a210 140734531936784\n"\
"r14 0x0 0\n"\
"r15 0x0 0\n"\
"rip 0x4008ae 0x4008ae <crash+14>\n"\
"eflags 0x10246 [ PF ZF IF RF ]\n"\
"cs 0x33 51\n"\
"ss 0x2b 43\n"\
"ds 0x0 0\n"\
"es 0x0 0\n"\
"fs 0x0 0\n"\
"gs 0x0 0\n"\
"st0 0 (raw 0x00000000000000000000)\n"\
"st1 0 (raw 0x00000000000000000000)\n"\
"st2 0 (raw 0x00000000000000000000)\n"\
"st3 0 (raw 0x00000000000000000000)\n"\
"st4 0 (raw 0x00000000000000000000)\n"\
"st5 0 (raw 0x00000000000000000000)\n"\
"st6 0 (raw 0x00000000000000000000)\n"\
"st7 0 (raw 0x00000000000000000000)\n"\
"fctrl 0x37f 895\n"\
"fstat 0x0 0\n"\
"ftag 0xffff 65535\n"\
"fiseg 0x0 0\n"\
"fioff 0x0 0\n"\
"foseg 0x0 0\n"\
"fooff 0x0 0\n"\
"fop 0x0 0\n"\
"xmm0 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm1 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x2f <repeats 16 times>}, v8_int16 = {0x2f2f, 0x2f2f, 0x2f2f, 0x2f2f, 0x2f2f, 0x2f2f, 0x2f2f, 0x2f2f}, v4_int32 = {0x2f2f2f2f, 0x2f2f2f2f, 0x2f2f2f2f, 0x2f2f2f2f}, v2_int64 = {0x2f2f2f2f2f2f2f2f, 0x2f2f2f2f2f2f2f2f}, uint128 = 0x2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f}\n"\
"xmm2 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm3 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 13 times>, 0xff, 0x0, 0x0}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff00, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0xff00}, v2_int64 = {0x0, 0xff0000000000}, uint128 = 0x0000ff00000000000000000000000000}\n"\
"xmm4 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0xff0000, 0x0}, v2_int64 = {0x0, 0xff0000}, uint128 = 0x0000000000ff00000000000000000000}\n"\
"xmm5 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm6 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm7 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm8 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm9 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm10 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm11 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm12 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 14 times>, 0xff, 0x0}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff}, v4_int32 = {0x0, 0x0, 0x0, 0xff0000}, v2_int64 = {0x0, 0xff000000000000}, uint128 = 0x00ff0000000000000000000000000000}\n"\
"xmm13 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm14 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"xmm15 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}\n"\
"mxcsr 0x1f80 [ IM DM ZM OM UM PM ]\n"\
"Dump of assembler code for function crash:\n"\
" 0x00000000004008a0 <+0>: push %rbx\n"\
" 0x00000000004008a1 <+1>: mov %rdi,%rbx\n"\
" 0x00000000004008a4 <+4>: mov $0x400ac0,%edi\n"\
" 0x00000000004008a9 <+9>: callq 0x4006f0 <puts@plt>\n"\
" => 0x00000000004008ae <+14>: mov (%rbx),%edx\n"\
" 0x00000000004008b0 <+16>: mov $0x400acf,%esi\n"\
" 0x00000000004008b5 <+21>: mov $0x1,%edi\n"\
" 0x00000000004008ba <+26>: xor %eax,%eax\n"\
" 0x00000000004008bc <+28>: callq 0x400740 <__printf_chk@plt>\n"\
" 0x00000000004008c1 <+33>: pop %rbx\n"\
" 0x00000000004008c2 <+34>: retq\n"\
"End of assembler dump.\n"
#define CORE_BACKTRACE_CONTENT \
"{ \"signal\": 11\n"\
", \"only_crash_thread\": true\n"\
", \"stacktrace\":\n"\
" [ { \"crash_thread\": true\n"\
" , \"frames\":\n"\
" [ { \"address\": 93894060571040\n"\
" , \"build_id\": \"a4711308c3fe2f0699ea740b0fc13370629f52f2\"\n"\
" , \"build_id_offset\": 2464\n"\
" , \"function_name\": \"crash\"\n"\
" , \"file_name\": \"/usr/bin/will_segfault\"\n"\
" }\n"\
" , { \"address\": 93894060571239\n"\
" , \"build_id\": \"a4711308c3fe2f0699ea740b0fc13370629f52f2\"\n"\
" , \"build_id_offset\": 2663\n"\
" , \"function_name\": \"varargs\"\n"\
" , \"file_name\": \"/usr/bin/will_segfault\"\n"\
" }\n"\
" , { \"address\": 93894060571294\n"\
" , \"build_id\": \"a4711308c3fe2f0699ea740b0fc13370629f52f2\"\n"\
" , \"build_id_offset\": 2718\n"\
" , \"function_name\": \"f\"\n"\
" , \"file_name\": \"/usr/bin/will_segfault\"\n"\
" }\n"\
" , { \"address\": 93894060571337\n"\
" , \"build_id\": \"a4711308c3fe2f0699ea740b0fc13370629f52f2\"\n"\
" , \"build_id_offset\": 2761\n"\
" , \"function_name\": \"callback\"\n"\
" , \"file_name\": \"/usr/bin/will_segfault\"\n"\
" }\n"\
" , { \"address\": 140458064176825\n"\
" , \"build_id\": \"61ee70f1ceca4897eadb680f1afaa669782c53cf\"\n"\
" , \"build_id_offset\": 1721\n"\
" , \"function_name\": \"call_me_back\"\n"\
" , \"file_name\": \"/usr/lib64/libwillcrash.so.0.0.0\"\n"\
" }\n"\
" , { \"address\": 93894060571382\n"\
" , \"build_id\": \"a4711308c3fe2f0699ea740b0fc13370629f52f2\"\n"\
" , \"build_id_offset\": 2806\n"\
" , \"function_name\": \"recursive\"\n"\
" , \"file_name\": \"/usr/bin/will_segfault\"\n"\
" }\n"\
" , { \"address\": 93894060571360\n"\
" , \"build_id\": \"a4711308c3fe2f0699ea740b0fc13370629f52f2\"\n"\
" , \"build_id_offset\": 2784\n"\
" , \"function_name\": \"recursive\"\n"\
" , \"file_name\": \"/usr/bin/will_segfault\"\n"\
" }\n"\
" , { \"address\": 93894060571360\n"\
" , \"build_id\": \"a4711308c3fe2f0699ea740b0fc13370629f52f2\"\n"\
" , \"build_id_offset\": 2784\n"\
" , \"function_name\": \"recursive\"\n"\
" , \"file_name\": \"/usr/bin/will_segfault\"\n"\
" }\n"\
" , { \"address\": 93894060570663\n"\
" , \"build_id\": \"a4711308c3fe2f0699ea740b0fc13370629f52f2\"\n"\
" , \"build_id_offset\": 2087\n"\
" , \"function_name\": \"main\"\n"\
" , \"file_name\": \"/usr/bin/will_segfault\"\n"\
" } ]\n"\
" } ]\n"\
"}\n"
typedef struct backtrace_result {
const char *format;
const char *result;
int max_text_size;
int max_frames;
} backtrace_result_t;
void check(problem_data_t *data, backtrace_result_t br)
{
problem_formatter_t *pf = problem_formatter_new();
assert(!problem_formatter_load_string(pf, br.format));
problem_report_t *pr = NULL;
problem_report_settings_t report_settings = problem_formatter_get_settings(pf);
if (br.max_frames >= 0)
report_settings.prs_shortbt_max_frames = br.max_frames;
if (br.max_text_size >= 0)
report_settings.prs_shortbt_max_text_size = br.max_text_size; /* always short bt */
problem_formatter_set_settings(pf, report_settings);
assert(!problem_formatter_generate_report(pf, data, &pr));
assert(pr != NULL);
const char *summary = problem_report_get_description(pr);
assert(summary != NULL);
if (br.result != NULL) {
fprintf(stderr, "####\n");
fprintf(stderr, "# max_text_size %d, max_frames %d\n", br.max_text_size, br.max_frames);
fprintf(stderr, "expected: '%s'\n", br.result);
fprintf(stderr, "====\n");
fprintf(stderr, "result : '%s'\n", summary);
fprintf(stderr, "####\n");
assert(strcmp(br.result, summary) == 0);
}
problem_report_free(pr);
problem_formatter_free(pf);
}
int main(int argc, char **argv)
{
g_verbose = 3;
problem_data_t *data = problem_data_new();
problem_data_add_text_noteditable(data, "package", "libreport");
problem_data_add_text_noteditable(data, "analyzer", "CCpp");
problem_data_add_text_noteditable(data, "type", "CCpp");
problem_data_add_text_noteditable(data, "comment", "Hello, world!");
problem_data_add_text_noteditable(data, "uuid", "123456789ABCDEF");
problem_data_add_text_noteditable(data, "uid", "69");
problem_data_add_text_noteditable(data, "user_name", "abrt");
problem_data_add_text_noteditable(data, "root", "/var/run/mock/abrt");
problem_data_add_text_noteditable(data, "description", "I run will_segfault and\nit crashed as expected\n");
problem_data_add_text_noteditable(data, "core_backtrace", CORE_BACKTRACE_CONTENT);
backtrace_result_t core_backtrace_result[] = {
{
.format = "Truncated backtrace:: %bare_%short_backtrace",
.result = "Truncated backtrace:\n"
"#1 crash in /usr/bin/will_segfault\n"
"#2 varargs in /usr/bin/will_segfault\n"
"#3 f in /usr/bin/will_segfault\n"
"#4 callback in /usr/bin/will_segfault\n"
"#5 call_me_back in /usr/lib64/libwillcrash.so.0.0.0\n"
"#6 recursive in /usr/bin/will_segfault\n"
"#7 main in /usr/bin/will_segfault\n",
.max_text_size = -1,
.max_frames = -1
},
{
.format = "Truncated backtrace:: %bare_%short_backtrace",
.result = "Truncated backtrace:\n"
"#1 crash in /usr/bin/will_segfault\n"
"#2 varargs in /usr/bin/will_segfault\n"
"#3 f in /usr/bin/will_segfault\n"
"#4 callback in /usr/bin/will_segfault\n"
"#5 call_me_back in /usr/lib64/libwillcrash.so.0.0.0\n",
.max_text_size = -1,
.max_frames = 5
},
{
.format = "Truncated backtrace:: %bare_%short_backtrace",
.result = "Truncated backtrace:\n"
"#1 crash in /usr/bin/will_segfault\n",
.max_text_size = -1,
.max_frames = 1
},
{
.format = "Truncated backtrace:: %bare_%short_backtrace",
.result = "Truncated backtrace:\n"
"#1 crash in /usr/bin/will_segfault\n",
.max_text_size = 0,
.max_frames = 1
},
/* core_backtrase is always truncated */
{
.format = "Truncated backtrace:: %bare_%short_backtrace",
.result = "Truncated backtrace:\n"
"#1 crash in /usr/bin/will_segfault\n",
.max_text_size = strlen(CORE_BACKTRACE_CONTENT) + 1,
.max_frames = 1
},
};
/* if only core_backtrace exist, use it */
for (size_t i = 0; i < sizeof(core_backtrace_result)/sizeof(*core_backtrace_result); ++i) {
check(data, core_backtrace_result[i]);
}
/* use backtrace, if core_backtrace and backtrace exist */
problem_data_add_text_noteditable(data, "backtrace", BACKTRACE_CONTENT);
backtrace_result_t backtrace_result[] = {
{
.format = "Truncated backtrace:: %bare_%short_backtrace",
.result = "Truncated backtrace:\n"
"Thread no. 0 (7 frames)\n"
" #1 crash at will_segfault.c:19\n"
" #2 varargs at will_segfault.c:31\n"
" #3 inlined at will_segfault.c:40\n"
" #4 f at will_segfault.c:45\n"
" #5 callback at will_segfault.c:50\n"
" #6 call_me_back at libwillcrash.c:8\n"
" #7 recursive at will_segfault.c:59\n",
.max_text_size = -1,
.max_frames = -1
},
{
.format = "Truncated backtrace:: %bare_%short_backtrace",
.result = "Truncated backtrace:\n"
"Thread no. 0 (5 frames)\n"
" #1 crash at will_segfault.c:19\n"
" #2 varargs at will_segfault.c:31\n"
" #3 inlined at will_segfault.c:40\n"
" #4 f at will_segfault.c:45\n"
" #5 callback at will_segfault.c:50\n",
.max_text_size = -1,
.max_frames = 5
},
{
.format = "Truncated backtrace:: %bare_%short_backtrace",
.result = "Truncated backtrace:\n"
"Thread no. 0 (1 frames)\n"
" #1 crash at will_segfault.c:19\n",
.max_text_size = -1,
.max_frames = 1
},
{
.format = "Truncated backtrace:: %bare_%short_backtrace",
.result = "Truncated backtrace:\n"
"Thread no. 0 (1 frames)\n"
" #1 crash at will_segfault.c:19\n",
.max_text_size = 0,
.max_frames = 1
},
{
.format = "Truncated backtrace:: %bare_%short_backtrace",
.result = "Truncated backtrace:\n"BACKTRACE_CONTENT,
.max_text_size = strlen(BACKTRACE_CONTENT) + 1,
.max_frames = 1
},
};
for (size_t i = 0; i < sizeof(backtrace_result)/sizeof(*backtrace_result); ++i) {
check(data, backtrace_result[i]);
}
problem_data_free(data);
return 0;
}
]])
## ------ ##
## attach ##
## ------ ##
AT_TESTFUN([attach],
[[
#include "problem_report.h"
#include "internal_libreport.h"
#include <assert.h>
int main(int argc, char **argv)
{
g_verbose = 3;
const char *fst[] = { "backtrace", "screenshot", "description", NULL };
struct test_case {
const char *format;
const char *const *files;
} cases [] = {
{
.format = "%attach:: %multiline,%binary,-coredump",
.files = fst,
}
};
problem_data_t *data = problem_data_new();
problem_data_add_text_noteditable(data, "package", "libreport");
problem_data_add_text_noteditable(data, "analyzer", "CCpp");
problem_data_add_text_noteditable(data, "type", "CCpp");
problem_data_add_text_noteditable(data, "comment", "Hello, world!");
problem_data_add_text_noteditable(data, "uuid", "123456789ABCDEF");
problem_data_add_text_noteditable(data, "uid", "69");
problem_data_add_text_noteditable(data, "user_name", "abrt");
problem_data_add_text_noteditable(data, "root", "/var/run/mock/abrt");
problem_data_add_text_noteditable(data, "description", "I run will_segfault and\nit crashed as expected\n");
problem_data_add_file(data, "coredump", "/what/ever/path/to/coredump");
problem_data_add_file(data, "screenshot", "/what/ever/path/to/screenshot");
problem_data_add_text_noteditable(data, "backtrace",
"Thread 1 (LWP 11865):\n"\
"#0 printf (__fmt=0x400acf \"Result: %d\\n\") at /usr/include/bits/stdio2.h:104\n"\
"No locals.\n"\
"#1 crash (p=p@entry=0x0) at will_segfault.c:19\n"\
"i = <error reading variable i (Cannot access memory at address 0x0)>\n"\
"#2 0x0000000000400964 in varargs (num_args=1, num_args@entry=2) at will_segfault.c:31\n"\
"p = <optimized out>\n"\
"ap = {{gp_offset = 24, fp_offset = 32767, overflow_arg_area = 0x7fff4fc8a0c0, reg_save_area = 0x7fff4fc8a080}}\n"\
"#3 0x00000000004009be in inlined (p=0x0) at will_segfault.c:40\n"\
"num = 42\n"\
"#4 f (p=p@entry=0x0) at will_segfault.c:45\n"\
"No locals.\n"\
"#5 0x00000000004009e9 in callback (data=data@entry=0x0) at will_segfault.c:50\n"\
"No locals.\n"\
"#6 0x00000032f76006f9 in call_me_back (cb=cb@entry=0x4009e0 <callback>, data=data@entry=0x0) at libwillcrash.c:8\n"\
"res = <optimized out>\n"\
"#7 0x0000000000400a14 in recursive (i=i@entry=0) at will_segfault.c:59\n"\
"p = <optimized out>\n"\
"#8 0x0000000000400a00 in recursive (i=i@entry=1) at will_segfault.c:66\n"\
"No locals.\n"\
"#9 0x0000000000400a00 in recursive (i=i@entry=2) at will_segfault.c:66\n"\
"No locals.\n"\
"#10 0x0000000000400775 in main (argc=<optimized out>, argv=<optimized out>) at will_segfault.c:83\n"\
"No locals.\n");
for (size_t i = 0; i < sizeof(cases)/sizeof(*cases); ++i) {
fprintf(stderr, "%s", cases[i].format);
problem_formatter_t *pf = problem_formatter_new();
assert(!problem_formatter_load_string(pf, cases[i].format));
problem_report_t *pr = NULL;
assert(!problem_formatter_generate_report(pf, data, &pr));
assert(pr != NULL);
const char *const *iter = cases[i].files;
if (*iter != NULL) {
assert(problem_report_get_attachments(pr));
}
GList *clone = g_list_copy_deep(problem_report_get_attachments(pr), (GCopyFunc)xstrdup, NULL);
while (*iter) {
GList *item = g_list_find_custom(clone, *iter, (GCompareFunc)strcmp);
if (item == NULL) {
fprintf(stderr, "format: '%s'\n", cases[i].format);
fprintf(stderr, "missing file: '%s'\n", *iter);
abort();
}
else {
free(item->data);
clone = g_list_delete_link(clone, item);
}
++iter;
}
if (clone != NULL) {
for (GList *iter = clone; iter; iter = g_list_next(iter)) {
fprintf(stderr, "extra : '%s'\n", (const char *)iter->data);
}
abort();
}
problem_report_free(pr);
problem_formatter_free(pf);
}
problem_data_free(data);
return 0;
}
]])
## -------------- ##
## custom_section ##
## -------------- ##
AT_TESTFUN([custom_section],
[[
#include "problem_report.h"
#include "internal_libreport.h"
#include <assert.h>
int main(int argc, char **argv)
{
g_verbose = 3;
struct test_case;
struct test_case {
const char *section_name;
int section_flags;
int retval_load;
int retval_generate;
const char *format;
const char *output;
} cases [] = {
{ .section_name = NULL,
.section_flags = 0,
.retval_load = 1,
.retval_generate = 0,
.format =
"%additional_info::\n"
":: package,\\\n"
"uuid,cwd\\\\"
",user_name"
,
.output = NULL,
},
{ .section_name = "additional_info",
.section_flags = 0,
.retval_load = 0,
.retval_generate = 0,
.format =
"%additional_info::\n"
":: package,\\\n"
"uuid,cwd\\\\"
",user_name"
,
.output =
"package: libreport\n"
"uuid: 0123456789ABCDEF\n"
"user_name: abrt\n"
,
},
{ .section_name = "additional_info",
.section_flags = PFFF_REQUIRED,
.retval_load = 1,
.retval_generate = 0,
.format = "%summary:: [abrt] %package%\n:: %reporter\n",
.output = NULL,
},
{ .section_name = "additional_info",
.section_flags = 0,
.retval_load = 0,
.retval_generate = 0,
.format = "%summary:: [abrt] %package%\n:: %reporter\n",
.output = "",
},
{ .section_name = "additional_info",
.section_flags = 0,
.retval_load = 0,
.retval_generate = 0,
.format =
"%additional_info:: root\n"
"Info:: package,\\\n"
"uuid,cwd\\\\"
",user_name"
,
.output =
"Info:\n"
"package: libreport\n"
"uuid: 0123456789ABCDEF\n"
"user_name: abrt\n"
,
},
};
problem_data_t *data = problem_data_new();
problem_data_add_text_noteditable(data, "package", "libreport");
problem_data_add_text_noteditable(data, "crash_function", "run_event");
problem_data_add_text_noteditable(data, "reason", "Killed by SIGSEGV");
problem_data_add_text_noteditable(data, "uuid", "0123456789ABCDEF");
problem_data_add_text_noteditable(data, "user_name", "abrt");
for (size_t i = 0; i < sizeof(cases)/sizeof(*cases); ++i) {
fprintf(stderr, "#### Test case %zd ####\n", i + 1);
struct test_case *tcase = cases + i;
problem_formatter_t *pf = problem_formatter_new();
if (tcase->section_name != NULL) {
problem_formatter_add_section(pf, tcase->section_name, tcase->section_flags);
}
int r = problem_formatter_load_string(pf, tcase->format);
if (r != tcase->retval_load) {
fprintf(stderr, "Load : expected : %d , got : %d\n", tcase->retval_load, r);
abort();
}
if (tcase->retval_load != 0) {
goto next_test_case;
}
problem_report_t *pr = NULL;
r = problem_formatter_generate_report(pf, data, &pr);
if (r != tcase->retval_generate) {
fprintf(stderr, "Generaet : expected : %d , got : %d\n", tcase->retval_generate, r);
abort();
}
if (tcase->retval_generate != 0) {
goto next_test_case;
}
const char *output = problem_report_get_section(pr, tcase->section_name);
assert(output);
if (strcmp(output, tcase->output) != 0) {
fprintf(stderr, "expected:\n'%s'\n", tcase->output);
fprintf(stderr, "result :\n'%s'\n", output);
abort();
}
problem_report_free(pr);
next_test_case:
problem_formatter_free(pf);
fprintf(stderr, "#### Finished - Test case %zd ####\n", i + 1);
}
problem_data_free(data);
return 0;
}
]])
## ------ ##
## sanity ##
## ------ ##
AT_TESTFUN([sanity],
[[
#include "problem_report.h"
#include "internal_libreport.h"
#include <errno.h>
#include <assert.h>
void assert_equal_strings(const char *res, const char *exp)
{
if ( (res == NULL && exp != NULL)
|| (res != NULL && exp == NULL)
|| ((res != NULL && exp != NULL) && strcmp(res, exp) != 0)
) {
fprintf(stderr, "expected : '%s'\n", exp);
fprintf(stderr, "result : '%s'\n", res);
abort();
}
}
int main(int argc, char **argv)
{
g_verbose = 3;
problem_formatter_t *pf = problem_formatter_new();
assert(problem_formatter_add_section(pf, "summary", 0) == -EEXIST);
assert(problem_formatter_add_section(pf, "description", 0) == -EEXIST);
assert(problem_formatter_add_section(pf, "attach", 0) == -EEXIST);
assert(problem_formatter_add_section(pf, "additional_info", 0) == 0);
assert(problem_formatter_add_section(pf, "additional_info", 0) == -EEXIST);
problem_data_t *data = problem_data_new();
problem_data_add_text_noteditable(data, "package", "libreport");
problem_data_add_text_noteditable(data, "crash_function", "run_event");
problem_data_add_text_noteditable(data, "reason", "Killed by SIGSEGV");
problem_data_add_text_noteditable(data, "comment", "Hello, world!");
problem_data_add_text_noteditable(data, "root", "/var/run/mock/abrt");
problem_data_add_text_noteditable(data, "user_name", "abrt");
problem_data_add_file(data, "screenshot", "/what/ever/path/to/screenshot");
problem_formatter_load_string(pf,
"%summary:: [abrt] %package% : %reason%\n\n"
"Description:: %bare_comment\n\n"
"%attach:: screenshot\n\n"
"%additional_info::\n\n"
"User:: root,user_name,uid\n\n\n"
);
problem_report_t *pr = NULL;
problem_formatter_generate_report(pf, data, &pr);
assert_equal_strings(problem_report_get_summary(pr),
"[abrt] libreport : Killed by SIGSEGV");
problem_report_buffer_printf(problem_report_get_buffer(pr, PR_SEC_SUMMARY), " - test");
assert_equal_strings(problem_report_get_summary(pr),
"[abrt] libreport : Killed by SIGSEGV - test");
assert_equal_strings(problem_report_get_description(pr),
"Description:\nHello, world!\n");
problem_report_buffer_printf(problem_report_get_buffer(pr, PR_SEC_DESCRIPTION), "Test line\n");
assert_equal_strings(problem_report_get_description(pr),
"Description:\nHello, world!\nTest line\n");
assert_equal_strings(problem_report_get_section(pr, "additional_info"),
"User:\n"
"root: /var/run/mock/abrt\n"
"user_name: abrt\n"
);
problem_report_buffer_printf(problem_report_get_buffer(pr, "additional_info"), "uid: 42\n");
assert_equal_strings(problem_report_get_section(pr, "additional_info"),
"User:\n"
"root: /var/run/mock/abrt\n"
"user_name: abrt\n"
"uid: 42\n"
);
problem_report_free(pr);
problem_data_free(data);
problem_formatter_free(pf);
return 0;
}
]])