1 /* 2 * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #include "precompiled.hpp" 25 #include "prims/jvm.h" 26 #include "runtime/arguments.hpp" 27 #include "unittest.hpp" 28 #include "utilities/globalDefinitions.hpp" 29 30 class ArgumentsTest : public ::testing::Test { 31 public: 32 static intx parse_xss_inner_annotated(const char* str, jint expected_err, const char* file, int line_number); 33 34 // Expose the private Arguments functions. 35 36 static Arguments::ArgsRange check_memory_size(julong size, julong min_size, julong max_size) { 37 return Arguments::check_memory_size(size, min_size, max_size); 38 } 39 40 static jint parse_xss(const JavaVMOption* option, const char* tail, intx* out_ThreadStackSize) { 41 return Arguments::parse_xss(option, tail, out_ThreadStackSize); 42 } 43 }; 44 45 TEST_F(ArgumentsTest, atojulong) { 46 char ullong_max[32]; 47 int ret = jio_snprintf(ullong_max, sizeof(ullong_max), JULONG_FORMAT, ULLONG_MAX); 48 ASSERT_NE(-1, ret); 49 50 julong value; 51 const char* invalid_strings[] = { 52 "", "-1", "-100", " 1", "2 ", "3 2", "1.0", 53 "0x4.5", "0x", "0x0x1" "0.001", "4e10", "e" 54 "K", "M", "G", "1MB", "1KM", "AA", "0B", 55 "18446744073709551615K", "17179869184G", 56 "999999999999999999999999999999" 57 }; 58 for (uint i = 0; i < ARRAY_SIZE(invalid_strings); i++) { 59 ASSERT_FALSE(Arguments::atojulong(invalid_strings[i], &value)) 60 << "Invalid string '" << invalid_strings[i] << "' parsed without error."; 61 } 62 63 struct { 64 const char* str; 65 julong expected_value; 66 } valid_strings[] = { 67 { "0", 0 }, 68 { "4711", 4711 }, 69 { "1K", 1ULL * K }, 70 { "1k", 1ULL * K }, 71 { "2M", 2ULL * M }, 72 { "2m", 2ULL * M }, 73 { "4G", 4ULL * G }, 74 { "4g", 4ULL * G }, 75 { "0K", 0 }, 76 { ullong_max, ULLONG_MAX }, 77 { "0xcafebabe", 0xcafebabe }, 78 { "0XCAFEBABE", 0xcafebabe }, 79 { "0XCAFEbabe", 0xcafebabe }, 80 { "0x10K", 0x10 * K } 81 }; 82 for (uint i = 0; i < ARRAY_SIZE(valid_strings); i++) { 83 ASSERT_TRUE(Arguments::atojulong(valid_strings[i].str, &value)) 84 << "Valid string '" << valid_strings[i].str << "' did not parse."; 85 ASSERT_EQ(valid_strings[i].expected_value, value); 86 } 87 } 88 89 TEST_F(ArgumentsTest, check_memory_size__min) { 90 EXPECT_EQ(check_memory_size(999, 1000, max_uintx), Arguments::arg_too_small); 91 EXPECT_EQ(check_memory_size(1000, 1000, max_uintx), Arguments::arg_in_range); 92 EXPECT_EQ(check_memory_size(1001, 1000, max_uintx), Arguments::arg_in_range); 93 94 EXPECT_EQ(check_memory_size(max_intx - 2, max_intx - 1, max_uintx), Arguments::arg_too_small); 95 EXPECT_EQ(check_memory_size(max_intx - 1, max_intx - 1, max_uintx), Arguments::arg_in_range); 96 EXPECT_EQ(check_memory_size(max_intx - 0, max_intx - 1, max_uintx), Arguments::arg_in_range); 97 98 EXPECT_EQ(check_memory_size(max_intx - 1, max_intx, max_uintx), Arguments::arg_too_small); 99 EXPECT_EQ(check_memory_size(max_intx , max_intx, max_uintx), Arguments::arg_in_range); 100 101 NOT_LP64( 102 EXPECT_EQ(check_memory_size((julong)max_intx + 1, max_intx, max_uintx), Arguments::arg_in_range); 103 104 EXPECT_EQ(check_memory_size( max_intx - 1, (julong)max_intx + 1, max_uintx), Arguments::arg_too_small); 105 EXPECT_EQ(check_memory_size( max_intx , (julong)max_intx + 1, max_uintx), Arguments::arg_too_small); 106 EXPECT_EQ(check_memory_size((julong)max_intx + 1, (julong)max_intx + 1, max_uintx), Arguments::arg_in_range); 107 EXPECT_EQ(check_memory_size((julong)max_intx + 2, (julong)max_intx + 1, max_uintx), Arguments::arg_in_range); 108 ); 109 110 EXPECT_EQ(check_memory_size(max_uintx - 2, max_uintx - 1, max_uintx), Arguments::arg_too_small); 111 EXPECT_EQ(check_memory_size(max_uintx - 1, max_uintx - 1, max_uintx), Arguments::arg_in_range); 112 EXPECT_EQ(check_memory_size(max_uintx , max_uintx - 1, max_uintx), Arguments::arg_in_range); 113 114 EXPECT_EQ(check_memory_size(max_uintx - 1, max_uintx, max_uintx), Arguments::arg_too_small); 115 EXPECT_EQ(check_memory_size(max_uintx , max_uintx, max_uintx), Arguments::arg_in_range); 116 } 117 118 TEST_F(ArgumentsTest, check_memory_size__max) { 119 EXPECT_EQ(check_memory_size(max_uintx - 1, 1000, max_uintx), Arguments::arg_in_range); 120 EXPECT_EQ(check_memory_size(max_uintx , 1000, max_uintx), Arguments::arg_in_range); 121 122 EXPECT_EQ(check_memory_size(max_intx - 2 , 1000, max_intx - 1), Arguments::arg_in_range); 123 EXPECT_EQ(check_memory_size(max_intx - 1 , 1000, max_intx - 1), Arguments::arg_in_range); 124 EXPECT_EQ(check_memory_size(max_intx , 1000, max_intx - 1), Arguments::arg_too_big); 125 126 EXPECT_EQ(check_memory_size(max_intx - 1 , 1000, max_intx), Arguments::arg_in_range); 127 EXPECT_EQ(check_memory_size(max_intx , 1000, max_intx), Arguments::arg_in_range); 128 129 NOT_LP64( 130 EXPECT_EQ(check_memory_size((julong)max_intx + 1 , 1000, max_intx), Arguments::arg_too_big); 131 132 EXPECT_EQ(check_memory_size( max_intx , 1000, (julong)max_intx + 1), Arguments::arg_in_range); 133 EXPECT_EQ(check_memory_size((julong)max_intx + 1 , 1000, (julong)max_intx + 1), Arguments::arg_in_range); 134 EXPECT_EQ(check_memory_size((julong)max_intx + 2 , 1000, (julong)max_intx + 1), Arguments::arg_too_big); 135 ); 136 } 137 138 // A random value - used to verify the output when parsing is expected to fail. 139 static const intx no_value = 4711; 140 141 inline intx ArgumentsTest::parse_xss_inner_annotated(const char* str, jint expected_err, const char* file, int line_number) { 142 intx value = no_value; 143 jint err = parse_xss(NULL /* Silence error messages */, str, &value); 144 EXPECT_EQ(err, expected_err) << "Failure from: " << file << ":" << line_number; 145 return value; 146 } 147 148 // Wrapper around the help function - gives file and line number when a test failure occurs. 149 #define parse_xss_inner(str, expected_err) ArgumentsTest::parse_xss_inner_annotated(str, expected_err, __FILE__, __LINE__) 150 151 static intx calc_expected(julong small_xss_input) { 152 assert(small_xss_input <= max_julong / 2, "Sanity"); 153 154 // Match code in arguments.cpp 155 julong julong_ret = align_up_(small_xss_input, K) / K; 156 assert(julong_ret <= (julong)max_intx, "Overflow: " JULONG_FORMAT, julong_ret); 157 return (intx)julong_ret; 158 } 159 160 static char buff[100]; 161 static char* to_string(julong value) { 162 jio_snprintf(buff, sizeof(buff), JULONG_FORMAT, value); 163 return buff; 164 } 165 166 TEST_VM_F(ArgumentsTest, parse_xss) { 167 // Test the maximum input value - should fail. 168 { 169 EXPECT_EQ(parse_xss_inner(to_string(max_julong), JNI_EINVAL), no_value); 170 NOT_LP64(EXPECT_EQ(parse_xss_inner(to_string(max_uintx), JNI_EINVAL), no_value)); 171 } 172 173 // Test values "far" away from the uintx boundary, 174 // but still beyond the max limit. 175 { 176 LP64_ONLY(EXPECT_EQ(parse_xss_inner(to_string(max_julong / 2), JNI_EINVAL), no_value)); 177 EXPECT_EQ(parse_xss_inner(to_string(INT_MAX), JNI_EINVAL), no_value); 178 } 179 180 // Test at and around the max limit. 181 { 182 EXPECT_EQ(parse_xss_inner(to_string(1 * M * K - 1), JNI_OK), calc_expected(1 * M * K - 1)); 183 EXPECT_EQ(parse_xss_inner(to_string(1 * M * K), JNI_OK), calc_expected(1 * M * K)); 184 EXPECT_EQ(parse_xss_inner(to_string(1 * M * K + 1), JNI_EINVAL), no_value); 185 } 186 187 // Test value aligned both to K and vm_page_size. 188 { 189 EXPECT_TRUE(is_aligned(32 * M, K)); 190 EXPECT_TRUE(is_aligned(32 * M, (size_t)os::vm_page_size())); 191 EXPECT_EQ(parse_xss_inner(to_string(32 * M), JNI_OK), (intx)(32 * M / K)); 192 } 193 194 // Test around the min limit. 195 { 196 EXPECT_EQ(parse_xss_inner(to_string(0), JNI_OK), calc_expected(0)); 197 EXPECT_EQ(parse_xss_inner(to_string(1), JNI_OK), calc_expected(1)); 198 EXPECT_EQ(parse_xss_inner(to_string(K - 1), JNI_OK), calc_expected(K - 1)); 199 EXPECT_EQ(parse_xss_inner(to_string(K), JNI_OK), calc_expected(K)); 200 EXPECT_EQ(parse_xss_inner(to_string(K + 1), JNI_OK), calc_expected(K + 1)); 201 } 202 }