Skip to content

Commit

Permalink
Merge pull request #398 from coreyfarrell/test-coverage
Browse files Browse the repository at this point in the history
Improve test coverage.
  • Loading branch information
akheron committed Feb 20, 2018
2 parents 6dddf68 + 73c22de commit 2d494c1
Show file tree
Hide file tree
Showing 15 changed files with 444 additions and 14 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ if (NOT JANSSON_WITHOUT_TESTS)
set(api_tests
test_array
test_copy
test_chaos
test_dump
test_dump_callback
test_equal
Expand Down
6 changes: 2 additions & 4 deletions src/load.c
Original file line number Diff line number Diff line change
Expand Up @@ -829,10 +829,8 @@ static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
}

json = jsonp_stringn_nocheck_own(value, len);
if(json) {
lex->value.string.val = NULL;
lex->value.string.len = 0;
}
lex->value.string.val = NULL;
lex->value.string.len = 0;
break;
}

Expand Down
5 changes: 4 additions & 1 deletion src/pack_unpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,10 @@ static char *read_string(scanner_t *s, va_list *ap,
return (char *)str;
}

strbuffer_init(&strbuff);
if(strbuffer_init(&strbuff)) {
set_error(s, "<internal>", json_error_out_of_memory, "Out of memory");
s->has_error = 1;
}

while(1) {
str = va_arg(*ap, const char *);
Expand Down
9 changes: 1 addition & 8 deletions src/value.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,8 +652,7 @@ static json_t *string_create(const char *value, size_t len, int own)

string = jsonp_malloc(sizeof(json_string_t));
if(!string) {
if(!own)
jsonp_free(v);
jsonp_free(v);
return NULL;
}
json_init(&string->json, JSON_STRING);
Expand Down Expand Up @@ -768,9 +767,6 @@ static int json_string_equal(const json_t *string1, const json_t *string2)
{
json_string_t *s1, *s2;

if(!json_is_string(string1) || !json_is_string(string2))
return 0;

s1 = json_to_string(string1);
s2 = json_to_string(string2);
return s1->length == s2->length && !memcmp(s1->value, s2->value, s1->length);
Expand All @@ -780,9 +776,6 @@ static json_t *json_string_copy(const json_t *string)
{
json_string_t *s;

if(!json_is_string(string))
return NULL;

s = json_to_string(string);
return json_stringn_nocheck(s->value, s->length);
}
Expand Down
1 change: 1 addition & 0 deletions test/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
logs
bin/json_process
suites/api/test_array
suites/api/test_chaos
suites/api/test_copy
suites/api/test_cpp
suites/api/test_dump
Expand Down
2 changes: 2 additions & 0 deletions test/suites/api/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ EXTRA_DIST = run check-exports

check_PROGRAMS = \
test_array \
test_chaos \
test_copy \
test_dump \
test_dump_callback \
Expand All @@ -18,6 +19,7 @@ check_PROGRAMS = \
test_unpack

test_array_SOURCES = test_array.c util.h
test_chaos_SOURCES = test_chaos.c util.h
test_copy_SOURCES = test_copy.c util.h
test_dump_SOURCES = test_dump.c util.h
test_dump_callback_SOURCES = test_dump_callback.c util.h
Expand Down
73 changes: 73 additions & 0 deletions test/suites/api/test_array.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,78 @@ static void test_array_foreach()
json_decref(array2);
}

static void test_bad_args(void)
{
json_t *arr = json_array();
json_t *num = json_integer(1);

if(!arr || !num)
fail("failed to create required objects");

if(json_array_size(NULL) != 0)
fail("NULL array has nonzero size");
if(json_array_size(num) != 0)
fail("non-array has nonzero array size");

if(json_array_get(NULL, 0))
fail("json_array_get did not return NULL for non-array");
if(json_array_get(num, 0))
fail("json_array_get did not return NULL for non-array");

if(!json_array_set_new(NULL, 0, json_incref(num)))
fail("json_array_set_new did not return error for non-array");
if(!json_array_set_new(num, 0, json_incref(num)))
fail("json_array_set_new did not return error for non-array");
if(!json_array_set_new(arr, 0, NULL))
fail("json_array_set_new did not return error for NULL value");
if(!json_array_set_new(arr, 0, json_incref(arr)))
fail("json_array_set_new did not return error for value == array");

if(!json_array_remove(NULL, 0))
fail("json_array_remove did not return error for non-array");
if(!json_array_remove(num, 0))
fail("json_array_remove did not return error for non-array");

if(!json_array_clear(NULL))
fail("json_array_clear did not return error for non-array");
if(!json_array_clear(num))
fail("json_array_clear did not return error for non-array");

if(!json_array_append_new(NULL, json_incref(num)))
fail("json_array_append_new did not return error for non-array");
if(!json_array_append_new(num, json_incref(num)))
fail("json_array_append_new did not return error for non-array");
if(!json_array_append_new(arr, NULL))
fail("json_array_append_new did not return error for NULL value");
if(!json_array_append_new(arr, json_incref(arr)))
fail("json_array_append_new did not return error for value == array");

if(!json_array_insert_new(NULL, 0, json_incref(num)))
fail("json_array_insert_new did not return error for non-array");
if(!json_array_insert_new(num, 0, json_incref(num)))
fail("json_array_insert_new did not return error for non-array");
if(!json_array_insert_new(arr, 0, NULL))
fail("json_array_insert_new did not return error for NULL value");
if(!json_array_insert_new(arr, 0, json_incref(arr)))
fail("json_array_insert_new did not return error for value == array");

if(!json_array_extend(NULL, arr))
fail("json_array_extend did not return error for first argument non-array");
if(!json_array_extend(num, arr))
fail("json_array_extend did not return error for first argument non-array");
if(!json_array_extend(arr, NULL))
fail("json_array_extend did not return error for second arguemnt non-array");
if(!json_array_extend(arr, num))
fail("json_array_extend did not return error for second arguemnt non-array");

if(num->refcount != 1)
fail("unexpected reference count on num");
if(arr->refcount != 1)
fail("unexpected reference count on arr");

json_decref(num);
json_decref(arr);
}

static void run_tests()
{
Expand All @@ -429,4 +501,5 @@ static void run_tests()
test_extend();
test_circular();
test_array_foreach();
test_bad_args();
}
115 changes: 115 additions & 0 deletions test/suites/api/test_chaos.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#include <stdio.h>
#include <string.h>
#include <jansson.h>
#include "util.h"

static int chaos_pos = 0;
static int chaos_fail = 0;
#define CHAOS_MAX_FAILURE 100

void *chaos_malloc(size_t size)
{
if (chaos_pos == chaos_fail)
return NULL;

chaos_pos++;

return malloc(size);
}

void chaos_free(void *obj)
{
free(obj);
}

/* Test all potential allocation failures. */
#define chaos_loop(condition, code, cleanup) \
{ \
chaos_pos = chaos_fail = 0; \
while (condition) { \
if (chaos_fail > CHAOS_MAX_FAILURE) \
fail("too many chaos failures"); \
code \
chaos_pos = 0; \
chaos_fail++; \
} \
cleanup \
}

#define chaos_loop_new_value(json, initcall) \
chaos_loop(!json, json = initcall;, json_decref(json); json = NULL;)

static void test_chaos()
{
json_malloc_t orig_malloc;
json_free_t orig_free;
json_t *json = NULL;
json_t *obj = json_object();
json_t *arr1 = json_array();
json_t *arr2 = json_array();
json_t *txt = json_string("test");
json_t *intnum = json_integer(1);
json_t *dblnum = json_real(0.5);
int keyno;

if (!obj || !arr1 || !arr2 || !txt || !intnum || !dblnum)
fail("failed to allocate basic objects");

json_get_alloc_funcs(&orig_malloc, &orig_free);
json_set_alloc_funcs(chaos_malloc, chaos_free);

chaos_loop_new_value(json, json_pack("{s:s}", "key", "value"));
chaos_loop_new_value(json, json_pack("{s:[]}", "key"));
chaos_loop_new_value(json, json_pack("[biIf]", 1, 1, (json_int_t)1, 1.0));
chaos_loop_new_value(json, json_pack("[s*,s*]", "v1", "v2"));
chaos_loop_new_value(json, json_pack("o", json_incref(txt)));
chaos_loop_new_value(json, json_pack("O", txt));
chaos_loop_new_value(json, json_pack("s++", "a",
"long string to force realloc",
"another long string to force yet another reallocation of the string because "
"that's what we are testing."));

chaos_loop_new_value(json, json_copy(obj));
chaos_loop_new_value(json, json_deep_copy(obj));

chaos_loop_new_value(json, json_copy(arr1));
chaos_loop_new_value(json, json_deep_copy(arr1));

chaos_loop_new_value(json, json_copy(txt));
chaos_loop_new_value(json, json_copy(intnum));
chaos_loop_new_value(json, json_copy(dblnum));

chaos_loop_new_value(json, json_sprintf("%s", "string"));

for (keyno = 0; keyno < 100; ++keyno) {
#if !defined(_MSC_VER) || _MSC_VER >= 1900
/* Skip this test on old Windows compilers. */
char testkey[10];

snprintf(testkey, sizeof(testkey), "test%d", keyno);
chaos_loop(json_object_set_new_nocheck(obj, testkey, json_object()),,);
#endif
chaos_loop(json_array_append_new(arr1, json_null()),,);
chaos_loop(json_array_insert_new(arr2, 0, json_null()),,);
}

chaos_loop(json_array_extend(arr1, arr2),,);
chaos_loop(json_string_set_nocheck(txt, "test"),,);

json_set_alloc_funcs(orig_malloc, orig_free);
json_decref(obj);
json_decref(arr1);
json_decref(arr2);
json_decref(txt);
json_decref(intnum);
json_decref(dblnum);
}

static void run_tests()
{
test_chaos();
}
7 changes: 7 additions & 0 deletions test/suites/api/test_equal.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ static void test_equal_simple()
fail("unable to create an string");
if(json_equal(value1, value2))
fail("json_equal fails for two inequal strings");
json_decref(value2);

value2 = json_string("bar2");
if(!value2)
fail("unable to create an string");
if(json_equal(value1, value2))
fail("json_equal fails for two inequal length strings");

json_decref(value1);
json_decref(value2);
Expand Down
7 changes: 7 additions & 0 deletions test/suites/api/test_memory_funcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,16 @@ static void test_secure_funcs(void)
create_and_free_complex_object();
}

static void test_bad_args(void)
{
/* The result of this test is not crashing. */
json_get_alloc_funcs(NULL, NULL);
}

static void run_tests()
{
test_simple();
test_secure_funcs();
test_oom();
test_bad_args();
}
36 changes: 36 additions & 0 deletions test/suites/api/test_number.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,41 @@ static void test_inifity()
}
#endif // INFINITY

static void test_bad_args(void)
{
json_t *txt = json_string("test");

if(json_integer_value(NULL) != 0)
fail("json_integer_value did not return 0 for non-integer");
if(json_integer_value(txt) != 0)
fail("json_integer_value did not return 0 for non-integer");

if(!json_integer_set(NULL, 0))
fail("json_integer_set did not return error for non-integer");
if(!json_integer_set(txt, 0))
fail("json_integer_set did not return error for non-integer");

if(json_real_value(NULL) != 0.0)
fail("json_real_value did not return 0.0 for non-real");
if(json_real_value(txt) != 0.0)
fail("json_real_value did not return 0.0 for non-real");

if(!json_real_set(NULL, 0.0))
fail("json_real_set did not return error for non-real");
if(!json_real_set(txt, 0.0))
fail("json_real_set did not return error for non-real");

if(json_number_value(NULL) != 0.0)
fail("json_number_value did not return 0.0 for non-numeric");
if(json_number_value(txt) != 0.0)
fail("json_number_value did not return 0.0 for non-numeric");

if (txt->refcount != 1)
fail("unexpected reference count for txt");

json_decref(txt);
}

static void run_tests()
{
json_t *integer, *real;
Expand Down Expand Up @@ -87,4 +122,5 @@ static void run_tests()
#ifdef INFINITY
test_inifity();
#endif
test_bad_args();
}
Loading

0 comments on commit 2d494c1

Please sign in to comment.