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 "jvm.h" 26 #include "unittest.hpp" 27 #include "runtime/arguments.hpp" 28 #include "utilities/align.hpp" 29 #include "utilities/globalDefinitions.hpp" 30 31 class ArgumentsTest : public ::testing::Test { 32 public: 33 static intx parse_xss_inner_annotated(const char* str, jint expected_err, const char* file, int line_number); 34 35 // Expose the private Arguments functions. 36 37 static Arguments::ArgsRange check_memory_size(julong size, julong min_size, julong max_size) { 38 return Arguments::check_memory_size(size, min_size, max_size); 39 } 40 41 static jint parse_xss(const JavaVMOption* option, const char* tail, intx* out_ThreadStackSize) { 42 return Arguments::parse_xss(option, tail, out_ThreadStackSize); 43 } 44 }; 45 46 TEST_F(ArgumentsTest, atojulong) { 47 char ullong_max[32]; 48 int ret = jio_snprintf(ullong_max, sizeof(ullong_max), JULONG_FORMAT, ULLONG_MAX); 49 ASSERT_NE(-1, ret); 50 51 julong value; 52 const char* invalid_strings[] = { 53 "", "-1", "-100", " 1", "2 ", "3 2", "1.0", 54 "0x4.5", "0x", "0x0x1" "0.001", "4e10", "e" 55 "K", "M", "G", "1MB", "1KM", "AA", "0B", 56 "18446744073709551615K", "17179869184G", 57 "999999999999999999999999999999" 58 }; 59 for (uint i = 0; i < ARRAY_SIZE(invalid_strings); i++) { 60 ASSERT_FALSE(Arguments::atojulong(invalid_strings[i], &value)) 61 << "Invalid string '" << invalid_strings[i] << "' parsed without error."; 62 } 63 64 struct { 65 const char* str; 66 julong expected_value; 67 } valid_strings[] = { 68 { "0", 0 }, 69 { "4711", 4711 }, 70 { "1K", 1ULL * K }, 71 { "1k", 1ULL * K }, 72 { "2M", 2ULL * M }, 73 { "2m", 2ULL * M }, 74 { "4G", 4ULL * G }, 75 { "4g", 4ULL * G }, 76 { "0K", 0 }, 77 { ullong_max, ULLONG_MAX }, 78 { "0xcafebabe", 0xcafebabe }, 79 { "0XCAFEBABE", 0xcafebabe }, 80 { "0XCAFEbabe", 0xcafebabe }, 81 { "0x10K", 0x10 * K } 82 }; 83 for (uint i = 0; i < ARRAY_SIZE(valid_strings); i++) { 84 ASSERT_TRUE(Arguments::atojulong(valid_strings[i].str, &value)) 85 << "Valid string '" << valid_strings[i].str << "' did not parse."; 86 ASSERT_EQ(valid_strings[i].expected_value, value); 87 } 88 } 89 90 TEST_F(ArgumentsTest, check_memory_size__min) { 91 EXPECT_EQ(check_memory_size(999, 1000, max_uintx), Arguments::arg_too_small); 92 EXPECT_EQ(check_memory_size(1000, 1000, max_uintx), Arguments::arg_in_range); 93 EXPECT_EQ(check_memory_size(1001, 1000, max_uintx), Arguments::arg_in_range); 94 95 EXPECT_EQ(check_memory_size(max_intx - 2, max_intx - 1, max_uintx), Arguments::arg_too_small); 96 EXPECT_EQ(check_memory_size(max_intx - 1, max_intx - 1, max_uintx), Arguments::arg_in_range); 97 EXPECT_EQ(check_memory_size(max_intx - 0, max_intx - 1, max_uintx), Arguments::arg_in_range); 98 99 EXPECT_EQ(check_memory_size(max_intx - 1, max_intx, max_uintx), Arguments::arg_too_small); 100 EXPECT_EQ(check_memory_size(max_intx , max_intx, max_uintx), Arguments::arg_in_range); 101 102 NOT_LP64( 103 EXPECT_EQ(check_memory_size((julong)max_intx + 1, max_intx, max_uintx), Arguments::arg_in_range); 104 105 EXPECT_EQ(check_memory_size( max_intx - 1, (julong)max_intx + 1, max_uintx), Arguments::arg_too_small); 106 EXPECT_EQ(check_memory_size( max_intx , (julong)max_intx + 1, max_uintx), Arguments::arg_too_small); 107 EXPECT_EQ(check_memory_size((julong)max_intx + 1, (julong)max_intx + 1, max_uintx), Arguments::arg_in_range); 108 EXPECT_EQ(check_memory_size((julong)max_intx + 2, (julong)max_intx + 1, max_uintx), Arguments::arg_in_range); 109 ); 110 111 EXPECT_EQ(check_memory_size(max_uintx - 2, max_uintx - 1, max_uintx), Arguments::arg_too_small); 112 EXPECT_EQ(check_memory_size(max_uintx - 1, max_uintx - 1, max_uintx), Arguments::arg_in_range); 113 EXPECT_EQ(check_memory_size(max_uintx , max_uintx - 1, max_uintx), Arguments::arg_in_range); 114 115 EXPECT_EQ(check_memory_size(max_uintx - 1, max_uintx, max_uintx), Arguments::arg_too_small); 116 EXPECT_EQ(check_memory_size(max_uintx , max_uintx, max_uintx), Arguments::arg_in_range); 117 } 118 119 TEST_F(ArgumentsTest, check_memory_size__max) { 120 EXPECT_EQ(check_memory_size(max_uintx - 1, 1000, max_uintx), Arguments::arg_in_range); 121 EXPECT_EQ(check_memory_size(max_uintx , 1000, max_uintx), Arguments::arg_in_range); 122 123 EXPECT_EQ(check_memory_size(max_intx - 2 , 1000, max_intx - 1), Arguments::arg_in_range); 124 EXPECT_EQ(check_memory_size(max_intx - 1 , 1000, max_intx - 1), Arguments::arg_in_range); 125 EXPECT_EQ(check_memory_size(max_intx , 1000, max_intx - 1), Arguments::arg_too_big); 126 127 EXPECT_EQ(check_memory_size(max_intx - 1 , 1000, max_intx), Arguments::arg_in_range); 128 EXPECT_EQ(check_memory_size(max_intx , 1000, max_intx), Arguments::arg_in_range); 129 130 NOT_LP64( 131 EXPECT_EQ(check_memory_size((julong)max_intx + 1 , 1000, max_intx), Arguments::arg_too_big); 132 133 EXPECT_EQ(check_memory_size( max_intx , 1000, (julong)max_intx + 1), Arguments::arg_in_range); 134 EXPECT_EQ(check_memory_size((julong)max_intx + 1 , 1000, (julong)max_intx + 1), Arguments::arg_in_range); 135 EXPECT_EQ(check_memory_size((julong)max_intx + 2 , 1000, (julong)max_intx + 1), Arguments::arg_too_big); 136 ); 137 } 138 139 // A random value - used to verify the output when parsing is expected to fail. 140 static const intx no_value = 4711; 141 142 inline intx ArgumentsTest::parse_xss_inner_annotated(const char* str, jint expected_err, const char* file, int line_number) { 143 intx value = no_value; 144 jint err = parse_xss(NULL /* Silence error messages */, str, &value); 145 EXPECT_EQ(err, expected_err) << "Failure from: " << file << ":" << line_number; 146 return value; 147 } 148 149 // Wrapper around the help function - gives file and line number when a test failure occurs. 150 #define parse_xss_inner(str, expected_err) ArgumentsTest::parse_xss_inner_annotated(str, expected_err, __FILE__, __LINE__) 151 152 static intx calc_expected(julong small_xss_input) { 153 assert(small_xss_input <= max_julong / 2, "Sanity"); 154 155 // Match code in arguments.cpp 156 julong julong_ret = align_up_(small_xss_input, K) / K; 157 assert(julong_ret <= (julong)max_intx, "Overflow: " JULONG_FORMAT, julong_ret); 158 return (intx)julong_ret; 159 } 160 161 static char buff[100]; 162 static char* to_string(julong value) { 163 jio_snprintf(buff, sizeof(buff), JULONG_FORMAT, value); 164 return buff; 165 } 166 167 TEST_VM_F(ArgumentsTest, parse_xss) { 168 // Test the maximum input value - should fail. 169 { 170 EXPECT_EQ(parse_xss_inner(to_string(max_julong), JNI_EINVAL), no_value); 171 NOT_LP64(EXPECT_EQ(parse_xss_inner(to_string(max_uintx), JNI_EINVAL), no_value)); 172 } 173 174 // Test values "far" away from the uintx boundary, 175 // but still beyond the max limit. 176 { 177 LP64_ONLY(EXPECT_EQ(parse_xss_inner(to_string(max_julong / 2), JNI_EINVAL), no_value)); 178 EXPECT_EQ(parse_xss_inner(to_string(INT_MAX), JNI_EINVAL), no_value); 179 } 180 181 // Test at and around the max limit. 182 { 183 EXPECT_EQ(parse_xss_inner(to_string(1 * M * K - 1), JNI_OK), calc_expected(1 * M * K - 1)); 184 EXPECT_EQ(parse_xss_inner(to_string(1 * M * K), JNI_OK), calc_expected(1 * M * K)); 185 EXPECT_EQ(parse_xss_inner(to_string(1 * M * K + 1), JNI_EINVAL), no_value); 186 } 187 188 // Test value aligned both to K and vm_page_size. 189 { 190 EXPECT_TRUE(is_aligned(32 * M, K)); 191 EXPECT_TRUE(is_aligned(32 * M, (size_t)os::vm_page_size())); 192 EXPECT_EQ(parse_xss_inner(to_string(32 * M), JNI_OK), (intx)(32 * M / K)); 193 } 194 195 // Test around the min limit. 196 { 197 EXPECT_EQ(parse_xss_inner(to_string(0), JNI_OK), calc_expected(0)); 198 EXPECT_EQ(parse_xss_inner(to_string(1), JNI_OK), calc_expected(1)); 199 EXPECT_EQ(parse_xss_inner(to_string(K - 1), JNI_OK), calc_expected(K - 1)); 200 EXPECT_EQ(parse_xss_inner(to_string(K), JNI_OK), calc_expected(K)); 201 EXPECT_EQ(parse_xss_inner(to_string(K + 1), JNI_OK), calc_expected(K + 1)); 202 } 203 }