Path: blob/master/test/hotspot/gtest/utilities/test_json.cpp
41145 views
/*1* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#include "precompiled.hpp"24#include "jvm.h"25#include "memory/resourceArea.hpp"26#include "utilities/json.hpp"27#include "unittest.hpp"2829class JSON_GTest : public JSON {30public:31static void test(const char* json, bool valid);32char* get_output();3334private:35JSON_GTest(const char* text);36stringStream output;3738void log(uint level, const char* format, ...) ATTRIBUTE_PRINTF(3, 4);3940bool callback(JSON_TYPE t, JSON_VAL* v, uint level);41JSON_TYPE prev;42};4344char* JSON_GTest::get_output() {45return output.as_string();46}4748void JSON_GTest::test(const char* text, bool should_pass) {49ResourceMark rm;50JSON_GTest json(text);51if (should_pass) {52ASSERT_TRUE(json.valid()) << "failed on a valid json string"53<< std::endl << "debug output:" << std::endl << json.get_output();54} else {55ASSERT_FALSE(json.valid()) << "succeeded on an invalid json string"56<< std::endl << "debug output:" << std::endl << json.get_output();57}58}5960JSON_GTest::JSON_GTest(const char* text) : JSON(text, false, &output) {61prev = JSON_NONE;62parse();63}6465TEST_VM(utilities, json_curly_braces) {66JSON_GTest::test("{}", true);67}6869TEST_VM(utilities, json_brackets) {70JSON_GTest::test("[]", true);71}7273TEST_VM(utilities, json_space_braces) {74JSON_GTest::test(" { } ", true);75}7677TEST_VM(utilities, json_space_bracketes) {78JSON_GTest::test(" [ ] ", true);79}8081TEST_VM(utilities, json_quoted_error) {82JSON_GTest::test("\"error\"", false);83}8485TEST_VM(utilities, json_error_string) {86JSON_GTest::test("error", false);87}8889TEST_VM(utilities, json_simple_integer) {90JSON_GTest::test("1", false);91}9293TEST_VM(utilities, json_siple_float) {94JSON_GTest::test("1.2", false);95}9697TEST_VM(utilities, json_simple_boolean_true) {98JSON_GTest::test("true", false);99}100101TEST_VM(utilities, json_simple_boolean_false) {102JSON_GTest::test("false", false);103}104105TEST_VM(utilities, json_simple_null) {106JSON_GTest::test("null", false);107}108109TEST_VM(utilities, json_one_element_int_array) {110JSON_GTest::test("[ 1 ]", true);111}112113TEST_VM(utilities, json_int_array) {114JSON_GTest::test("[ 1, ]", true);115}116117TEST_VM(utilities, json_one_element_bool_array) {118JSON_GTest::test("[ true ]", true);119}120121TEST_VM(utilities, json_bool_array) {122JSON_GTest::test("[ true, ]", true);123}124125TEST_VM(utilities, json_one_element_false_array) {126JSON_GTest::test("[ false ]", true);127}128129TEST_VM(utilities, json_false_bool_array) {130JSON_GTest::test("[ false, ]", true);131}132133TEST_VM(utilities, json_one_null_array) {134JSON_GTest::test("[ null ]", true);135}136137TEST_VM(utilities, json_null_array) {138JSON_GTest::test("[ null, ]", true);139}140141TEST_VM(utilities, json_one_empty_string_array) {142JSON_GTest::test("[ \"\" ]", true);143}144145TEST_VM(utilities, json_empty_string_array) {146JSON_GTest::test("[ \"\", ]", true);147}148149TEST_VM(utilities, json_single_string_array) {150JSON_GTest::test("[ \"elem1\" ]", true);151}152153TEST_VM(utilities, json_string_comma_arrray) {154JSON_GTest::test("[ \"elem1\", ]", true);155}156157TEST_VM(utilities, json_two_strings_array) {158JSON_GTest::test("[ \"elem1\", \"elem2\" ]", true);159}160161TEST_VM(utilities, json_two_strings_comma_array) {162JSON_GTest::test("[ \"elem1\", \"elem2\", ]", true);163}164165TEST_VM(utilities, json_curly_braces_outside) {166JSON_GTest::test("[ \"elem1\" ] { }", false);167}168169TEST_VM(utilities, json_element_in_array) {170JSON_GTest::test("[ elem1, \"elem2\" ]", false);171}172173TEST_VM(utilities, json_incorrect_end_array) {174JSON_GTest::test("[ \"elem1\"", false);175}176177TEST_VM(utilities, json_incorrect_string_end) {178JSON_GTest::test("[ \"elem1 ]", false);179}180181TEST_VM(utilities, json_incorrect_end_of_two_elements_array) {182JSON_GTest::test("[ \"elem1\", \"elem2\"", false);183}184185TEST_VM(utilities, json_incorrect_bool_true_array) {186JSON_GTest::test("[ truefoo ]", false);187}188189TEST_VM(utilities, json_incorrect_bool_false_array) {190JSON_GTest::test("[ falsefoo ]", false);191}192193TEST_VM(utilities, json_incorrect_null_array) {194JSON_GTest::test("[ nullfoo ]", false);195}196197TEST_VM(utilities, json_key_pair) {198JSON_GTest::test("{ key : 1 }", true);199}200201TEST_VM(utilities, json_key_pair_comma) {202JSON_GTest::test("{ key : 1, }", true);203}204205TEST_VM(utilities, json_bool_true_key) {206JSON_GTest::test("{ key : true }", true);207}208209TEST_VM(utilities, json_bool_true_key_comma) {210JSON_GTest::test("{ key : true, }", true);211}212213TEST_VM(utilities, json_bool_false_key) {214JSON_GTest::test("{ key : false }", true);215}216217TEST_VM(utilities, json_bool_false_key_comma) {218JSON_GTest::test("{ key : false, }", true);219}220221TEST_VM(utilities, json_null_key) {222JSON_GTest::test("{ key : null }", true);223}224225TEST_VM(utilities, json_null_key_comma) {226JSON_GTest::test("{ key : null, }", true);227}228229TEST_VM(utilities, json_pair_of_empty_strings) {230JSON_GTest::test("{ \"\" : \"\" }", true);231}232233TEST_VM(utilities, json_pair_of_empty_strings_comma) {234JSON_GTest::test("{ \"\" : \"\", }", true);235}236237TEST_VM(utilities, json_pair_of_strings) {238JSON_GTest::test("{ \"key1\" : \"val1\" }", true);239}240241TEST_VM(utilities, json_pair_of_strings_comma) {242JSON_GTest::test("{ \"key1\" : \"val1\", }", true);243}244245TEST_VM(utilities, json_two_pairs_of_strings) {246JSON_GTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\" }", true);247}248249TEST_VM(utilities, json_two_pairs_of_strings_comma) {250JSON_GTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\", }", true);251}252253TEST_VM(utilities, json_array_outside) {254JSON_GTest::test("{ \"key\" : \"val\" } [ \"error\" ]", false);255}256257TEST_VM(utilities, json_incorrect_object_end) {258JSON_GTest::test("{ \"key\" : \"val\" ", false);259}260261TEST_VM(utilities, json_empty_comment) {262JSON_GTest::test("/**/ { }", true);263}264265TEST_VM(utilities, json_space_comment) {266JSON_GTest::test("/* */ { }", true);267}268269TEST_VM(utilities, json_comment) {270JSON_GTest::test("/*foo*/ { }", true);271}272273TEST_VM(utilities, json_star_comment) {274JSON_GTest::test("/* *foo */ { }", true);275}276277TEST_VM(utilities, json_stars_comment) {278JSON_GTest::test("/* *foo* */ { }", true);279}280281TEST_VM(utilities, json_special_comment) {282JSON_GTest::test("/* /*foo */ { }", true);283}284285TEST_VM(utilities, json_comment_after) {286JSON_GTest::test("{ } /* foo */", true);287}288289TEST_VM(utilities, json_comment_after_and_space) {290JSON_GTest::test("{ } /* foo */ ", true);291}292293TEST_VM(utilities, json_one_line_empty_comment_after) {294JSON_GTest::test("{ } //", true);295}296297TEST_VM(utilities, json_one_line_space_comment_after) {298JSON_GTest::test("{ } // ", true);299}300301TEST_VM(utilities, json_one_line_comment_after) {302JSON_GTest::test("{ } // foo", true);303}304305TEST_VM(utilities, json_incorrect_multiline_comment) {306JSON_GTest::test("/* * / { }", false);307}308309TEST_VM(utilities, json_incorrect_multiline_comment_begin) {310JSON_GTest::test("/ * */ { }", false);311}312313TEST_VM(utilities, json_oneline_comment_only) {314JSON_GTest::test("// { }", false);315}316317TEST_VM(utilities, json_multiline_comment_only) {318JSON_GTest::test("/* { } */", false);319}320321TEST_VM(utilities, json_multiline_comment_2) {322JSON_GTest::test("/* { } */ ", false);323}324325TEST_VM(utilities, json_incorrectly_commented_object) {326JSON_GTest::test("/* { } ", false);327}328329TEST_VM(utilities, json_missing_multiline_end) {330JSON_GTest::test("{ } /* ", false);331}332333TEST_VM(utilities, json_missing_multiline_slash) {334JSON_GTest::test("/* { } *", false);335}336337TEST_VM(utilities, json_commented_object_end) {338JSON_GTest::test("{ /* } */", false);339}340341TEST_VM(utilities, json_commented_array_end) {342JSON_GTest::test("[ /* ] */", false);343}344345TEST_VM(utilities, json_missing_object_end) {346JSON_GTest::test("{ key : \"val\", /* } */", false);347}348349TEST_VM(utilities, json_missing_array_end) {350JSON_GTest::test("[ \"val\", /* ] */", false);351}352353TEST_VM(utilities, json_key_values_1) {354JSON_GTest::test("/* comment */{ key1 : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\","355"{ \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\""356" : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true);357}358359TEST_VM(utilities, json_key_values_2) {360JSON_GTest::test("/* comment */ { \"key1\" : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\","361"{ \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\""362" : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true);363}364365TEST_VM(utilities, json_quoted_symbols) {366JSON_GTest::test("/*comment*/{\"ff1 fsd\":{\"☃\":{\"☃\":[\"☃\",\"☃\"]},"367"\"☃\":true},\"☃\":[\"☃\"],\"foo\":\"☃\",}", true);368}369370TEST_VM(utilities, json_incorrect_key) {371JSON_GTest::test("/* comment */ { key1 error : { \"☃\" : { \"☃\" : [ \"☃\","372" \"☃\" ] }, \"☃\" : true }, \"baz\" : [ \"☃\" ], foo : \"☃\",}",373false); // first key needs to be quoted since it contains a space374}375376TEST_VM(utilities, json_array_with_newline) {377JSON_GTest::test("[\n]", true);378}379380TEST_VM(utilities, json_directives_file) {381JSON_GTest::test(382"[" "\n"383" {"384" // pattern to match against class+method+signature" "\n"385" // leading and trailing wildcard (*) allowed" "\n"386" match: \"foo.bar.*\"," "\n"387" " "\n"388" // override defaults for specified compiler" "\n"389" // we may differentiate between levels too. TBD." "\n"390" c1: {" "\n"391" //override c1 presets " "\n"392" array_bounds_check_removal: false" "\n"393" }," "\n"394"" "\n"395" c2: {" "\n"396" // control inlining of method" "\n"397" // + force inline, - dont inline" "\n"398" inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n"399" }," "\n"400"" "\n"401" // directives outside a specific preset applies to all compilers" "\n"402" inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n"403" print_assembly: true," "\n"404" verify_oopmaps: true," "\n"405" max_loop_unrolling: 5" "\n"406" }," "\n"407" {" "\n"408" // matching several patterns require an array" "\n"409" match: [\"baz.*\",\"frob*\"]," "\n"410"" "\n"411" // only enable c1 for this directive" "\n"412" // all enabled by default. Command disables all not listed" "\n"413" enable: \"c1\"," "\n"414"" "\n"415" // applies to all compilers" "\n"416" // + force inline, - dont inline" "\n"417" inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n"418" print_inlining: true," "\n"419"" "\n"420" // force matching compiles to be blocking/syncronous" "\n"421" blocking_compile: true" "\n"422" }," "\n"423"]" "\n", true);424}425426void JSON_GTest::log(uint indent, const char* format, ...) {427if (prev != JSON_KEY) {428for (uint i = 0; i < indent; i++) {429_st->print(" ");430}431}432va_list args;433va_start(args, format);434_st->vprint(format, args);435va_end(args);436}437438bool JSON_GTest::callback(JSON_TYPE t, JSON_VAL* v, uint rlevel) {439switch (t) {440case JSON_OBJECT_BEGIN:441log(rlevel, "{\n");442prev = JSON_NONE; // Only care about JSON_KEY, to indent correctly443return true;444445case JSON_OBJECT_END:446log(rlevel, "},\n");447prev = JSON_NONE;448return true;449450case JSON_ARRAY_BEGIN:451log(rlevel, "[\n");452prev = JSON_NONE;453return true;454455case JSON_ARRAY_END:456log(rlevel, "],\n");457prev = JSON_NONE;458return true;459460case JSON_KEY:461for (uint i = 0; i < rlevel; i++) {462_st->print(" ");463}464_st->print("<key>");465for (size_t i = 0; i < v->str.length; i++) {466u_char c = v->str.start[i];467if (c == 0) {468return false;469}470_st->print("%c", c);471}472_st->print(" : ");473prev = JSON_KEY;474return true;475476case JSON_STRING:477if (prev != JSON_KEY) {478for (uint i = 0; i < rlevel; i++) {479_st->print(" ");480}481}482_st->print("<str>");483for (size_t i = 0; i < v->str.length; i++) {484u_char c = v->str.start[i];485if (c == 0) {486return false;487}488_st->print("%c", c);489}490_st->print(",\n");491prev = JSON_NONE;492return true;493494case JSON_NUMBER_INT:495log(rlevel, "<int>%" PRId64 ",\n", v->int_value);496prev = JSON_NONE;497return true;498499case JSON_NUMBER_FLOAT:500log(rlevel, "<double>%lf,\n", v->double_value);501prev = JSON_NONE;502return true;503504case JSON_TRUE:505log(rlevel, "<true>,\n");506prev = JSON_NONE;507return true;508509case JSON_FALSE:510log(rlevel, "<false>,\n");511prev = JSON_NONE;512return true;513514case JSON_NULL:515log(rlevel, "<null>,\n");516prev = JSON_NONE;517return true;518519default:520error(INTERNAL_ERROR, "unknown JSON type");521return false;522}523}524525526