8164546: Convert DirectivesParser_test to GTest
authorppunegov
Thu, 25 Oct 2018 11:18:24 -0700
changeset 52290 db83eceba962
parent 52289 04e6910792b3
child 52291 fa61165a3f2b
8164546: Convert DirectivesParser_test to GTest Reviewed-by: kvn, iignatyev, neliasso
src/hotspot/share/compiler/directivesParser.cpp
src/hotspot/share/compiler/directivesParser.hpp
src/hotspot/share/utilities/internalVMTests.cpp
test/hotspot/gtest/compiler/test_directivesParser.cpp
--- a/src/hotspot/share/compiler/directivesParser.cpp	Thu Oct 25 10:58:59 2018 -0700
+++ b/src/hotspot/share/compiler/directivesParser.cpp	Thu Oct 25 11:18:24 2018 -0700
@@ -566,159 +566,3 @@
   }
 }
 
-#ifndef PRODUCT
-void DirectivesParser::test(const char* text, bool should_pass) {
-  DirectivesParser cd(text, tty, !VerboseInternalVMTests);
-  if (should_pass) {
-    assert(cd.valid() == true, "failed on a valid DirectivesParser string");
-    if (VerboseInternalVMTests) {
-      tty->print("-- DirectivesParser test passed as expected --\n");
-    }
-  } else {
-    assert(cd.valid() == false, "succeeded on an invalid DirectivesParser string");
-    if (VerboseInternalVMTests) {
-      tty->print("-- DirectivesParser test failed as expected --\n");
-    }
-  }
-  cd.clean_tmp();
-}
-
-void DirectivesParser::test() {
-  DirectivesParser::test("{}", false);
-  DirectivesParser::test("[]", true);
-  DirectivesParser::test("[{}]", false);
-  DirectivesParser::test("[{},{}]", false);
-  DirectivesParser::test("{},{}", false);
-
-  DirectivesParser::test(
-    "[" "\n"
-    "  {" "\n"
-    "    match: \"foo/bar.*\"," "\n"
-    "    inline : \"+java/util.*\"," "\n"
-    "    PrintAssembly: true," "\n"
-    "    BreakAtExecute: true," "\n"
-    "  }" "\n"
-    "]" "\n", true);
-
-  DirectivesParser::test(
-    "[" "\n"
-    "  [" "\n"
-    "    {" "\n"
-    "      match: \"foo/bar.*\"," "\n"
-    "      inline : \"+java/util.*\"," "\n"
-    "      PrintAssembly: true," "\n"
-    "      BreakAtExecute: true," "\n"
-    "    }" "\n"
-    "  ]" "\n"
-    "]" "\n", false);
-
-  /*DirectivesParser::test(
-    "[" "\n"
-    "  {" "\n"
-    "    match: \"foo/bar.*\"," "\n"
-    "    c1: {"
-    "      PrintIntrinsics: false," "\n"
-    "    }" "\n"
-    "  }" "\n"
-    "]" "\n", false);*/
-
-  DirectivesParser::test(
-    "[" "\n"
-    "  {" "\n"
-    "    match: \"foo/bar.*\"," "\n"
-    "    c2: {" "\n"
-    "      PrintInlining: false," "\n"
-    "    }" "\n"
-    "  }" "\n"
-    "]" "\n", true);
-
-  DirectivesParser::test(
-    "[" "\n"
-    "  {" "\n"
-    "    match: \"foo/bar.*\"," "\n"
-    "    c2: {" "\n"
-    "      VectorizeDebug: 1," "\n"
-    "      VectorizeDebug: -1," "\n"
-    "    }" "\n"
-    "  }" "\n"
-    "]" "\n", COMPILER2_PRESENT(true) NOT_COMPILER2(false));
-
-  DirectivesParser::test(
-    "[" "\n"
-    "  {" "\n"
-    "    match: \"foo/bar.*\"," "\n"
-    "    PrintInlining: [" "\n"
-    "      true," "\n"
-    "      false" "\n"
-    "    ]," "\n"
-    "  }" "\n"
-    "]" "\n", false);
-
-  DirectivesParser::test(
-    "[" "\n"
-    "  {"
-    "    // pattern to match against class+method+signature" "\n"
-    "    // leading and trailing wildcard (*) allowed" "\n"
-    "    match: \"foo/bar.*\"," "\n"
-    "" "\n"
-    "    // override defaults for specified compiler" "\n"
-    "    // we may differentiate between levels too. TBD." "\n"
-    "    c1:  {" "\n"
-    "      //override c1 presets " "\n"
-    "      DumpReplay: false," "\n"
-    "      BreakAtCompile: true," "\n"
-    "    }," "\n"
-    "" "\n"
-    "    c2: {" "\n"
-    "        // control inlining of method" "\n"
-    "        // + force inline, - dont inline" "\n"
-    "        inline : \"+java/util.*\"," "\n"
-    "        PrintInlining: true," "\n"
-    "    }," "\n"
-    "" "\n"
-    "    // directives outside a specific preset applies to all compilers" "\n"
-    "    inline : [ \"+java/util.*\", \"-com/sun.*\"]," "\n"
-    "    BreakAtExecute: true," "\n"
-    "    Log: true," "\n"
-    "  }," "\n"
-    "  {" "\n"
-    "    // matching several patterns require an array" "\n"
-    "    match: [\"baz.*\",\"frob.*\"]," "\n"
-    "" "\n"
-    "    // applies to all compilers" "\n"
-    "    // + force inline, - dont inline" "\n"
-    "    inline : [ \"+java/util.*\", \"-com/sun.*\" ]," "\n"
-    "    PrintInlining: true," "\n"
-    "" "\n"
-    "    // force matching compiles to be blocking/syncronous" "\n"
-    "    PrintNMethods: true" "\n"
-    "  }," "\n"
-    "]" "\n", true);
-
-  // Test max stack depth
-    DirectivesParser::test(
-      "[" "\n"             // depth 1: type_dir_array
-      "  {" "\n"           // depth 2: type_directives
-      "    match: \"*.*\"," // match required
-      "    c1:" "\n"       // depth 3: type_c1
-      "    {" "\n"
-      "      inline:" "\n" // depth 4: type_inline
-      "      [" "\n"       // depth 5: type_value_array
-      "        \"foo\"," "\n"
-      "        \"bar\"," "\n"
-      "      ]" "\n"       // depth 3: pop type_value_array and type_inline keys
-      "    }" "\n"         // depth 2: pop type_c1 key
-      "  }" "\n"           // depth 1: pop type_directives key
-      "]" "\n", true);     // depth 0: pop type_dir_array key
-
-    // Test max stack depth
-    DirectivesParser::test(
-      "[{c1:{c1:{c1:{c1:{c1:{c1:{c1:{}}}}}}}}]", false);
-
-}
-
-void DirectivesParser_test() {
-  DirectivesParser::test();
-}
-
-#endif
--- a/src/hotspot/share/compiler/directivesParser.hpp	Thu Oct 25 10:58:59 2018 -0700
+++ b/src/hotspot/share/compiler/directivesParser.hpp	Thu Oct 25 11:18:24 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,15 +48,18 @@
     "unknown"
 };
 
+class DirectivesParserTest;
+
 class DirectivesParser : public JSON {
-public:
+ friend class DirectivesParserTest;
+ public:
   static bool has_file();
   static bool parse_from_flag();
   static bool parse_from_file(const char* filename, outputStream* st);
   static int  parse_string(const char* string, outputStream* st);
   int install_directives();
 
-private:
+ private:
   DirectivesParser(const char* text, outputStream* st, bool silent);
   ~DirectivesParser();
 
@@ -134,12 +137,6 @@
   int _tmp_depth;               // Number of directives that has been parsed but not installed.
 
   static uint mask(keytype kt);
-
-#ifndef PRODUCT
-  static void test(const char* json, bool valid);
-public:
-  static void test();
-#endif
 };
 
 #endif // SHARE_VM_COMPILER_DIRECTIVESPARSER_HPP
--- a/src/hotspot/share/utilities/internalVMTests.cpp	Thu Oct 25 10:58:59 2018 -0700
+++ b/src/hotspot/share/utilities/internalVMTests.cpp	Thu Oct 25 11:18:24 2018 -0700
@@ -45,11 +45,6 @@
   run_unit_test(TestReserveMemorySpecial_test);
   run_unit_test(TestMetaspaceUtils_test);
   run_unit_test(GCTimer_test);
-  // These tests require the "C" locale to correctly parse decimal values
-  const char* orig_locale = setlocale(LC_NUMERIC, NULL);
-  setlocale(LC_NUMERIC, "C");
-  run_unit_test(DirectivesParser_test);
-  setlocale(LC_NUMERIC, orig_locale);
   tty->print_cr("All internal VM tests passed");
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/compiler/test_directivesParser.cpp	Thu Oct 25 11:18:24 2018 -0700
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+
+#include <locale.h>
+
+#include "compiler/directivesParser.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+#include "runtime/thread.hpp"
+#include "unittest.hpp"
+
+class DirectivesParserTest : public ::testing::Test{
+ protected:
+  const char* const _locale;
+  ResourceMark rm;
+  stringStream stream;
+  // These tests require the "C" locale to correctly parse decimal values
+  DirectivesParserTest() : _locale(setlocale(LC_NUMERIC, NULL)) {
+    setlocale(LC_NUMERIC, "C");
+  }
+  ~DirectivesParserTest() {
+    setlocale(LC_NUMERIC, _locale);
+  }
+
+  void test_negative(const char* text) {
+    JavaThread* THREAD = JavaThread::current();
+    ThreadInVMfromNative ThreadInVMfromNative(THREAD);
+    DirectivesParser cd(text, &stream, false);
+    cd.clean_tmp();
+    EXPECT_FALSE(cd.valid()) << "text: " << std::endl << text << std::endl << stream.as_string();
+  }
+
+  void test_positive(const char* text) {
+    JavaThread* THREAD = JavaThread::current();
+    ThreadInVMfromNative ThreadInVMfromNative(THREAD);
+    DirectivesParser cd(text, &stream, false);
+    cd.clean_tmp();
+    EXPECT_TRUE(cd.valid()) << "text: " << std::endl << text << std::endl << stream.as_string();
+  }
+};
+
+TEST_VM_F(DirectivesParserTest, empty_object) {
+  test_negative("{}");
+}
+
+TEST_VM_F(DirectivesParserTest, empty_array) {
+  test_positive("[]");
+}
+
+TEST_VM_F(DirectivesParserTest, empty_object_in_array) {
+  test_negative("[{}]");
+}
+
+TEST_VM_F(DirectivesParserTest, empty_objects_in_array) {
+  test_negative("[{},{}]");
+}
+
+TEST_VM_F(DirectivesParserTest, empty_objects) {
+  test_negative("{},{}");
+}
+
+TEST_VM_F(DirectivesParserTest, simple_match) {
+  test_positive(
+      "[" "\n"
+      "  {" "\n"
+      "    match: \"foo/bar.*\"," "\n"
+      "    inline : \"+java/util.*\"," "\n"
+      "    PrintAssembly: true," "\n"
+      "    BreakAtExecute: true," "\n"
+      "  }" "\n"
+      "]" "\n");
+
+}
+
+TEST_VM_F(DirectivesParserTest, nesting_arrays) {
+  test_negative(
+      "[" "\n"
+      "  [" "\n"
+      "    {" "\n"
+      "      match: \"foo/bar.*\"," "\n"
+      "      inline : \"+java/util.*\"," "\n"
+      "      PrintAssembly: true," "\n"
+      "      BreakAtExecute: true," "\n"
+      "    }" "\n"
+      "  ]" "\n"
+      "]" "\n");
+}
+
+TEST_VM_F(DirectivesParserTest, c1_block) {
+  test_positive(
+    "[" "\n"
+    "  {" "\n"
+    "    match: \"foo/bar.*\"," "\n"
+    "    c1: {"
+    "      PrintInlining: false," "\n"
+    "    }" "\n"
+    "  }" "\n"
+    "]" "\n");
+}
+
+TEST_VM_F(DirectivesParserTest, c2_block) {
+  test_positive(
+      "[" "\n"
+      "  {" "\n"
+      "    match: \"foo/bar.*\"," "\n"
+      "    c2: {" "\n"
+      "      PrintInlining: false," "\n"
+      "    }" "\n"
+      "  }" "\n"
+      "]" "\n");
+}
+
+TEST_VM_F(DirectivesParserTest, boolean_array) {
+  test_negative(
+      "[" "\n"
+      "  {" "\n"
+      "    match: \"foo/bar.*\"," "\n"
+      "    PrintInlining: [" "\n"
+      "      true," "\n"
+      "      false" "\n"
+      "    ]," "\n"
+      "  }" "\n"
+      "]" "\n");
+}
+
+TEST_VM_F(DirectivesParserTest, multiple_objects) {
+  test_positive(
+      "[" "\n"
+      "  {"
+      "    // pattern to match against class+method+signature" "\n"
+      "    // leading and trailing wildcard (*) allowed" "\n"
+      "    match: \"foo/bar.*\"," "\n"
+      "" "\n"
+      "    // override defaults for specified compiler" "\n"
+      "    // we may differentiate between levels too. TBD." "\n"
+      "    c1:  {" "\n"
+      "      //override c1 presets " "\n"
+      "      DumpReplay: false," "\n"
+      "      BreakAtCompile: true," "\n"
+      "    }," "\n"
+      "" "\n"
+      "    c2: {" "\n"
+      "        // control inlining of method" "\n"
+      "        // + force inline, - dont inline" "\n"
+      "        inline : \"+java/util.*\"," "\n"
+      "        PrintInlining: true," "\n"
+      "    }," "\n"
+      "" "\n"
+      "    // directives outside a specific preset applies to all compilers" "\n"
+      "    inline : [ \"+java/util.*\", \"-com/sun.*\"]," "\n"
+      "    BreakAtExecute: true," "\n"
+      "    Log: true," "\n"
+      "  }," "\n"
+      "  {" "\n"
+      "    // matching several patterns require an array" "\n"
+      "    match: [\"baz.*\",\"frob.*\"]," "\n"
+      "" "\n"
+      "    // applies to all compilers" "\n"
+      "    // + force inline, - dont inline" "\n"
+      "    inline : [ \"+java/util.*\", \"-com/sun.*\" ]," "\n"
+      "    PrintInlining: true," "\n"
+      "" "\n"
+      "    // force matching compiles to be blocking/syncronous" "\n"
+      "    PrintNMethods: true" "\n"
+      "  }," "\n"
+      "]" "\n");
+}
+
+// Test max stack depth
+TEST_VM_F(DirectivesParserTest, correct_max_stack_depth) {
+  test_positive(
+      "[" "\n"              // depth 1: type_dir_array
+      "  {" "\n"            // depth 2: type_directives
+      "    match: \"*.*\"," // match required
+      "    c1:" "\n"        // depth 3: type_c1
+      "    {" "\n"
+      "      inline:" "\n"  // depth 4: type_inline
+      "      [" "\n"        // depth 5: type_value_array
+      "        \"foo\"," "\n"
+      "        \"bar\"," "\n"
+      "      ]" "\n"        // depth 3: pop type_value_array and type_inline keys
+      "    }" "\n"          // depth 2: pop type_c1 key
+      "  }" "\n"            // depth 1: pop type_directives key
+      "]" "\n");            // depth 0: pop type_dir_array key
+}
+
+// Test max stack depth
+TEST_VM_F(DirectivesParserTest, incorrect_max_stack_depth) {
+  test_negative("[{c1:{c1:{c1:{c1:{c1:{c1:{c1:{}}}}}}}}]");
+}