1 /* 2 * Copyright (c) 2015, 2016, 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 "gc/g1/workerDataArray.inline.hpp" 26 #include "utilities/ostream.hpp" 27 #include "memory/resourceArea.hpp" 28 #include "unittest.hpp" 29 30 static ::testing::AssertionResult verify_string(const char* expected_string, const char* actual_string) { 31 const size_t expected_len = strlen(expected_string); 32 const size_t actual_len = strlen(actual_string); 33 34 if (expected_len != actual_len) { 35 return ::testing::AssertionFailure() << "Wrong string length " << actual_len << ", expected " << expected_len; 36 } 37 38 // Can't use strncmp here because floating point values use different decimal points for different locales. 39 // Allow strings to differ in "." vs. "," only. This should still catch most errors. 40 for (size_t i = 0; i < expected_len; i++) { 41 char e = expected_string[i]; 42 char a = actual_string[i]; 43 if (e != a) { 44 if ((e == '.' || e == ',') && (a == '.' || a == ',')) { 45 // Most likely just a difference in locale 46 } else { 47 return ::testing::AssertionFailure() << 48 "Actual string \"" << actual_string << 49 "\" is not equal to expected \"" << expected_string << "\""; 50 } 51 } 52 } 53 54 return ::testing::AssertionSuccess(); 55 } 56 57 template<typename T> 58 static void print_summary_on(const WorkerDataArray<T>& array, stringStream* out) { 59 array.print_summary_on(out); 60 } 61 62 template<typename T> 63 static void print_details_on(const WorkerDataArray<T>& array, stringStream* out) { 64 array.print_details_on(out); 65 } 66 67 template<typename T> 68 static ::testing::AssertionResult verify_method(void (*method)(const WorkerDataArray<T>&, stringStream*), 69 const char* expected_string, 70 const WorkerDataArray<T>& array) { 71 ResourceMark rm; 72 stringStream out; 73 method(array, &out); 74 return verify_string(expected_string, out.as_string()); 75 } 76 77 class WorkerDataArrayTest : public ::testing::Test { 78 protected: 79 WorkerDataArrayTest() : 80 basic_array(3, "Test array"), 81 add_array(3, "Test array"), 82 with_uninitialized_array(3, "Test array"), 83 uninitialized_array(3, "Test array"), 84 double_with_uninitialized_array(3, "Test array") { 85 86 setup_basic_array(&basic_array); 87 setup_add_array(&add_array); 88 setup_with_uninitialized_array(&with_uninitialized_array); 89 setup_uninitialized_array(&uninitialized_array); 90 setup_double_with_uninitialized_array(&double_with_uninitialized_array); 91 } 92 93 static const double epsilon; 94 95 WorkerDataArray<size_t> basic_array; 96 WorkerDataArray<size_t> add_array; 97 WorkerDataArray<size_t> with_uninitialized_array; 98 WorkerDataArray<size_t> uninitialized_array; 99 WorkerDataArray<double> double_with_uninitialized_array; 100 101 private: 102 static void setup_basic_array(WorkerDataArray<size_t>* array) { 103 array->set(0, 5); 104 array->set(1, 3); 105 array->set(2, 7); 106 } 107 108 static void setup_add_array(WorkerDataArray<size_t>* array) { 109 array->set(0, 5); 110 array->set(1, 3); 111 array->set(2, 7); 112 113 for (uint i = 0; i < 3; i++) { 114 array->add(i, 1); 115 } 116 } 117 118 static void setup_with_uninitialized_array(WorkerDataArray<size_t>* array) { 119 array->set(0, 5); 120 array->set(1, WorkerDataArray<size_t>::uninitialized()); 121 array->set(2, 7); 122 } 123 124 static void setup_uninitialized_array(WorkerDataArray<size_t>* array) { 125 array->set(0, WorkerDataArray<size_t>::uninitialized()); 126 array->set(1, WorkerDataArray<size_t>::uninitialized()); 127 array->set(2, WorkerDataArray<size_t>::uninitialized()); 128 } 129 130 static void setup_double_with_uninitialized_array(WorkerDataArray<double>* array) { 131 array->set(0, 5.1 / MILLIUNITS); 132 array->set(1, WorkerDataArray<double>::uninitialized()); 133 array->set(2, 7.2 / MILLIUNITS); 134 } 135 }; 136 137 const double WorkerDataArrayTest::epsilon = 0.0001; 138 139 TEST_F(WorkerDataArrayTest, sum) { 140 ASSERT_EQ(15u, basic_array.sum()); 141 ASSERT_EQ(18u, add_array.sum()); 142 ASSERT_EQ(12u, with_uninitialized_array.sum()); 143 ASSERT_EQ(0u, uninitialized_array.sum()); 144 ASSERT_NEAR(12.3 / MILLIUNITS, double_with_uninitialized_array.sum(), epsilon); 145 } 146 147 TEST_F(WorkerDataArrayTest, average) { 148 ASSERT_NEAR(5.0, basic_array.average(), epsilon); 149 ASSERT_NEAR(6.0, add_array.average(), epsilon); 150 ASSERT_NEAR(6.0, with_uninitialized_array.average(), epsilon); 151 ASSERT_NEAR(0.0, uninitialized_array.average(), epsilon); 152 ASSERT_NEAR(6.15 / MILLIUNITS, double_with_uninitialized_array.average(), epsilon); 153 } 154 155 TEST_F(WorkerDataArrayTest, print_summary_on) { 156 // use explicit template parameter to workaround old bug of Solaris Studio C++ compiler 157 ASSERT_TRUE(verify_method<size_t>(print_summary_on, 158 "Test array Min: 3, Avg: 5.0, Max: 7, Diff: 4, Sum: 15, Workers: 3\n", basic_array)); 159 ASSERT_TRUE(verify_method<size_t>(print_summary_on, 160 "Test array Min: 4, Avg: 6.0, Max: 8, Diff: 4, Sum: 18, Workers: 3\n", add_array)); 161 ASSERT_TRUE(verify_method<size_t>(print_summary_on, 162 "Test array Min: 5, Avg: 6.0, Max: 7, Diff: 2, Sum: 12, Workers: 2\n", with_uninitialized_array)); 163 ASSERT_TRUE(verify_method<size_t>(print_summary_on, 164 "Test array skipped\n", uninitialized_array)); 165 ASSERT_TRUE(verify_method<double>(print_summary_on, 166 "Test array Min: 5.1, Avg: 6.1, Max: 7.2, Diff: 2.1, Sum: 12.3, Workers: 2\n", double_with_uninitialized_array)); 167 } 168 169 TEST_F(WorkerDataArrayTest, print_details_on) { 170 ASSERT_TRUE(verify_method<size_t>(print_details_on, " 5 3 7\n", basic_array)); 171 ASSERT_TRUE(verify_method<size_t>(print_details_on, " 6 4 8\n", add_array)); 172 ASSERT_TRUE(verify_method<size_t>(print_details_on, " 5 - 7\n", with_uninitialized_array)); 173 ASSERT_TRUE(verify_method<size_t>(print_details_on, " - - -\n", uninitialized_array)); 174 ASSERT_TRUE(verify_method<double>(print_details_on, " 5.1 - 7.2\n", double_with_uninitialized_array)); 175 }