< prev index next >

test/native/runtime/test_arguments.cpp

Print this page

        

*** 25,35 **** #include "prims/jvm.h" #include "runtime/arguments.hpp" #include "unittest.hpp" #include "utilities/globalDefinitions.hpp" ! TEST(arguments, atojulong) { char ullong_max[32]; int ret = jio_snprintf(ullong_max, sizeof(ullong_max), JULONG_FORMAT, ULLONG_MAX); ASSERT_NE(-1, ret); julong value; --- 25,44 ---- #include "prims/jvm.h" #include "runtime/arguments.hpp" #include "unittest.hpp" #include "utilities/globalDefinitions.hpp" ! class ArgumentsTest : public ::testing::Test { ! static intx parse_xss_inner_annotated(const char* str, jint expected_err, const char* file, int line_number); ! ! public: ! static void check_memory_size_min(); ! static void check_memory_size_max(); ! static void parse_xss(); ! }; ! ! TEST_F(ArgumentsTest, atojulong) { char ullong_max[32]; int ret = jio_snprintf(ullong_max, sizeof(ullong_max), JULONG_FORMAT, ULLONG_MAX); ASSERT_NE(-1, ret); julong value;
*** 68,72 **** --- 77,207 ---- ASSERT_TRUE(Arguments::atojulong(valid_strings[i].str, &value)) << "Valid string '" << valid_strings[i].str << "' did not parse."; ASSERT_EQ(valid_strings[i].expected_value, value); } } + + // Proxy through the TestClass test fixture, which is a friend class of the implementation. + #define FRIEND_PROXIED(TestClass, function, mode) \ + TEST ## mode (TestClass, function) { \ + TestClass::function(); \ + } \ + void TestClass::function() + + #define FRIEND_PROXIED_TEST_F( TestClass, function) FRIEND_PROXIED(TestClass, function, _F) + #define FRIEND_PROXIED_TEST_VM_F(TestClass, function) FRIEND_PROXIED(TestClass, function, _VM_F) + + FRIEND_PROXIED_TEST_F(ArgumentsTest, check_memory_size_min) { + EXPECT_EQ(Arguments::check_memory_size(999, 1000, max_uintx), Arguments::arg_too_small); + EXPECT_EQ(Arguments::check_memory_size(1000, 1000, max_uintx), Arguments::arg_in_range); + EXPECT_EQ(Arguments::check_memory_size(1001, 1000, max_uintx), Arguments::arg_in_range); + + EXPECT_EQ(Arguments::check_memory_size(max_intx - 2, max_intx - 1, max_uintx), Arguments::arg_too_small); + EXPECT_EQ(Arguments::check_memory_size(max_intx - 1, max_intx - 1, max_uintx), Arguments::arg_in_range); + EXPECT_EQ(Arguments::check_memory_size(max_intx - 0, max_intx - 1, max_uintx), Arguments::arg_in_range); + + EXPECT_EQ(Arguments::check_memory_size(max_intx - 1, max_intx, max_uintx), Arguments::arg_too_small); + EXPECT_EQ(Arguments::check_memory_size(max_intx , max_intx, max_uintx), Arguments::arg_in_range); + + NOT_LP64( + EXPECT_EQ(Arguments::check_memory_size((julong)max_intx + 1, max_intx, max_uintx), Arguments::arg_in_range); + + EXPECT_EQ(Arguments::check_memory_size( max_intx - 1, (julong)max_intx + 1, max_uintx), Arguments::arg_too_small); + EXPECT_EQ(Arguments::check_memory_size( max_intx , (julong)max_intx + 1, max_uintx), Arguments::arg_too_small); + EXPECT_EQ(Arguments::check_memory_size((julong)max_intx + 1, (julong)max_intx + 1, max_uintx), Arguments::arg_in_range); + EXPECT_EQ(Arguments::check_memory_size((julong)max_intx + 2, (julong)max_intx + 1, max_uintx), Arguments::arg_in_range); + ); + + EXPECT_EQ(Arguments::check_memory_size(max_uintx - 2, max_uintx - 1, max_uintx), Arguments::arg_too_small); + EXPECT_EQ(Arguments::check_memory_size(max_uintx - 1, max_uintx - 1, max_uintx), Arguments::arg_in_range); + EXPECT_EQ(Arguments::check_memory_size(max_uintx , max_uintx - 1, max_uintx), Arguments::arg_in_range); + + EXPECT_EQ(Arguments::check_memory_size(max_uintx - 1, max_uintx, max_uintx), Arguments::arg_too_small); + EXPECT_EQ(Arguments::check_memory_size(max_uintx , max_uintx, max_uintx), Arguments::arg_in_range); + } + + FRIEND_PROXIED_TEST_F(ArgumentsTest, check_memory_size_max) { + EXPECT_EQ(Arguments::check_memory_size(max_uintx - 1, 1000, max_uintx), Arguments::arg_in_range); + EXPECT_EQ(Arguments::check_memory_size(max_uintx , 1000, max_uintx), Arguments::arg_in_range); + + EXPECT_EQ(Arguments::check_memory_size(max_intx - 2 , 1000, max_intx - 1), Arguments::arg_in_range); + EXPECT_EQ(Arguments::check_memory_size(max_intx - 1 , 1000, max_intx - 1), Arguments::arg_in_range); + EXPECT_EQ(Arguments::check_memory_size(max_intx , 1000, max_intx - 1), Arguments::arg_too_big); + + EXPECT_EQ(Arguments::check_memory_size(max_intx - 1 , 1000, max_intx), Arguments::arg_in_range); + EXPECT_EQ(Arguments::check_memory_size(max_intx , 1000, max_intx), Arguments::arg_in_range); + + NOT_LP64( + EXPECT_EQ(Arguments::check_memory_size((julong)max_intx + 1 , 1000, max_intx), Arguments::arg_too_big); + + EXPECT_EQ(Arguments::check_memory_size( max_intx , 1000, (julong)max_intx + 1), Arguments::arg_in_range); + EXPECT_EQ(Arguments::check_memory_size((julong)max_intx + 1 , 1000, (julong)max_intx + 1), Arguments::arg_in_range); + EXPECT_EQ(Arguments::check_memory_size((julong)max_intx + 2 , 1000, (julong)max_intx + 1), Arguments::arg_too_big); + ); + } + + // A random value - used to verify the output when parsing is expected to fail. + static const intx no_value = 4711; + + inline intx ArgumentsTest::parse_xss_inner_annotated(const char* str, jint expected_err, const char* file, int line_number) { + intx value = no_value; + jint err = Arguments::parse_xss(NULL /* Silence error messages */, str, &value); + EXPECT_EQ(err, expected_err) << "Failure from: " << file << ":" << line_number; + return value; + } + + // Wrapper around the help function - gives file and line number when a test failure occurs. + #define parse_xss_inner(str, expected_err) ArgumentsTest::parse_xss_inner_annotated(str, expected_err, __FILE__, __LINE__) + + static intx calc_expected(julong small_xss_input) { + assert(small_xss_input <= max_julong / 2, "Sanity"); + + // Match code in arguments.cpp + julong julong_ret = align_size_up_(small_xss_input, K) / K; + assert(julong_ret <= (julong)max_intx, "Overflow: " JULONG_FORMAT, julong_ret); + return (intx)julong_ret; + } + + static char buff[100]; + static char* to_string(julong value) { + jio_snprintf(buff, sizeof(buff), JULONG_FORMAT, value); + return buff; + } + + FRIEND_PROXIED_TEST_VM_F(ArgumentsTest, parse_xss) { + // Test the maximum input value - should fail. + { + EXPECT_EQ(parse_xss_inner(to_string(max_julong), JNI_EINVAL), no_value); + NOT_LP64(EXPECT_EQ(parse_xss_inner(to_string(max_uintx), JNI_EINVAL), no_value)); + } + + // Test values "far" away from the uintx boundary. + { + LP64_ONLY(EXPECT_EQ(parse_xss_inner(to_string(max_julong / 2), JNI_OK), calc_expected(max_julong / 2))); + EXPECT_EQ(parse_xss_inner(to_string(INT_MAX), JNI_OK), calc_expected(INT_MAX)); + EXPECT_EQ(parse_xss_inner(to_string(INT_MAX / 2), JNI_OK), calc_expected(INT_MAX / 2)); + } + + // Test value aligned both to K and vm_page_size. + { + EXPECT_TRUE(is_size_aligned(32 * M, K)); + EXPECT_TRUE(is_size_aligned(32 * M, (size_t)os::vm_page_size())); + EXPECT_EQ(parse_xss_inner(to_string(32 * M), JNI_OK), (intx)(32 * M / K)); + } + + // Test values around the uintx boundary. + { + // Reverse calculation of ThreadStackSize in os_windows.cpp + julong page_aligned_max_uintx = align_size_down_((julong)max_uintx, (size_t)os::vm_page_size()); + julong expected_max = align_size_down_(page_aligned_max_uintx, K) / K; + ASSERT_LE(expected_max, (julong)max_intx) << "expected_max will overflow intx"; + + // Calculation used in os_windows.cpp + julong max_expanded = align_size_up_(expected_max * K, (size_t)os::vm_page_size()); + ASSERT_LE(max_expanded, (julong)max_uintx) << "max_expanded will overflow uintx"; + + // Test exact max and values around max + EXPECT_EQ(parse_xss_inner(to_string(max_expanded), JNI_OK), (intx)expected_max); + EXPECT_EQ(parse_xss_inner(to_string(max_expanded - 1), JNI_OK), (intx)expected_max); + EXPECT_EQ(parse_xss_inner(to_string(max_expanded + 1), JNI_EINVAL), no_value); + } + }
< prev index next >