[3/4] gdb/unittests: additional tests for gdb_argv class

Message ID b126a112461bac1fd34ca2827b86d94a763c987c.1707409662.git.aburgess@redhat.com
State New
Headers
Series Rewrite gdb_argv using extract_string_maybe_quoted |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Testing passed

Commit Message

Andrew Burgess Feb. 8, 2024, 4:28 p.m. UTC
  We already have some gdb_argv tests, but these only test the
gdb_argv::as_array_view member function.

This commit creates a new unittests/gdb_argv-selftests.c file and adds
a wider range of gdb_argv tests, this includes covering the existing
as_array_view tests, so the existing tests have been deleted from
gdb/utils.c.

I've also added an additional test to gdb.python/py-cmd.exp which
tests calling gdb.string_to_argv with an empty string.  The
gdb.string_to_argv function is a wrapper around gdb_argv, and I
thought the empty string case was worth covering.
---
 gdb/Makefile.in                     |   1 +
 gdb/testsuite/gdb.python/py-cmd.exp |   4 +
 gdb/unittests/gdb_argv-selftests.c  | 131 ++++++++++++++++++++++++++++
 gdb/utils.c                         |  26 ------
 4 files changed, 136 insertions(+), 26 deletions(-)
 create mode 100644 gdb/unittests/gdb_argv-selftests.c
  

Patch

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 92fe06de489..18dec570389 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -462,6 +462,7 @@  SELFTESTS_SRCS = \
 	unittests/format_pieces-selftests.c \
 	unittests/frame_info_ptr-selftests.c \
 	unittests/function-view-selftests.c \
+	unittests/gdb_argv-selftests.c \
 	unittests/gdb_tilde_expand-selftests.c \
 	unittests/gmp-utils-selftests.c \
 	unittests/intrusive_list-selftests.c \
diff --git a/gdb/testsuite/gdb.python/py-cmd.exp b/gdb/testsuite/gdb.python/py-cmd.exp
index 82cb4cb557a..01af475dded 100644
--- a/gdb/testsuite/gdb.python/py-cmd.exp
+++ b/gdb/testsuite/gdb.python/py-cmd.exp
@@ -142,6 +142,10 @@  gdb_test "python print (gdb.string_to_argv ('1\\ 2 3'))" \
   {\['1 2', '3'\]} \
     "string_to_argv ('1\\ 2 3')"
 
+gdb_test "python print (gdb.string_to_argv (''))" \
+  {\[\]} \
+    "string_to_argv ('')"
+
 # Test user-defined python commands.
 gdb_test_multiline "input simple user-defined command" \
   "python" "" \
diff --git a/gdb/unittests/gdb_argv-selftests.c b/gdb/unittests/gdb_argv-selftests.c
new file mode 100644
index 00000000000..b6a87254c93
--- /dev/null
+++ b/gdb/unittests/gdb_argv-selftests.c
@@ -0,0 +1,131 @@ 
+/* Self tests for the gdb_argv class from gdbsupport.
+
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program 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 for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "gdbsupport/selftest.h"
+#include "gdbsupport/buildargv.h"
+
+namespace selftests {
+namespace gdb_argv_tests {
+
+static extract_string_ctrl shell_extract_string_ctrl
+  (nullptr, "", "\"$`\\", "\n", "", "\n");
+
+struct test_def
+{
+  /* INPUT is the string to pass to the gdb_argv constructor.  OUTPUT is
+     the vector of arguments that gdb_argv should split INPUT into.  */
+
+  test_def (const char *input,
+	    std::vector<const char *> output)
+    : m_input (input),
+      m_output (output)
+  { /* Nothing.  */ }
+
+  /* Run this test and check the results.  Throws an exception if the test
+     fails.  */
+
+  void run () const
+  {
+    gdb_argv argv (m_input);
+    int count = argv.count ();
+
+    if (run_verbose ())
+      {
+	debug_printf ("Input: %s\n", m_input);
+	debug_printf ("Output [Count]: %d\n", count);
+      }
+
+    SELF_CHECK (count == m_output.size ());
+
+    gdb::array_view<char *> view = argv.as_array_view ();
+    SELF_CHECK (view.size () == count);
+
+    const char *const *data = argv.get ();
+    for (int i = 0; i < count; ++i)
+      {
+	const char *a = argv[i];
+	SELF_CHECK (view[i] == a);
+	SELF_CHECK (strcmp (a, m_output[i]) == 0);
+	SELF_CHECK (a == *data);
+	++data;
+      }
+
+    SELF_CHECK (*data == nullptr);
+  }
+
+private:
+  /* What to pass to gdb_argv constructor.  */
+
+  const char *m_input;
+
+  /* The expected contents of gdb_argv after construction.  */
+
+  std::vector<const char *> m_output;
+};
+
+/* The array of all tests.  */
+
+test_def tests[] = {
+  { "abc def", {"abc", "def"} },
+  { "one two 3", {"one", "two", "3"} },
+  { "one two\\ three", {"one", "two three"} },
+  { "one\\ two three", {"one two", "three"} },
+  { "'one two' three", {"one two", "three"} },
+  { "one \"two three\"", {"one", "two three"} },
+  { "'\"' \"''\"", {"\"", "''"} },
+};
+
+/* Test the creation of an empty gdb_argv object.  */
+
+static void
+empty_argv_tests ()
+{
+  {
+    gdb_argv argv;
+
+    SELF_CHECK (argv.get () == nullptr);
+    SELF_CHECK (argv.count () == 0);
+
+    gdb::array_view<char *> view = argv.as_array_view ();
+
+    SELF_CHECK (view.data () == nullptr);
+    SELF_CHECK (view.size () == 0);
+  }
+}
+
+static void
+run_tests ()
+{
+  empty_argv_tests ();
+
+  for (const auto &test : tests)
+    test.run ();
+}
+
+} /* namespace gdb_argv_tests */
+} /* namespace selftests */
+
+void _initialize_gdb_argv_selftest ();
+void
+_initialize_gdb_argv_selftest ()
+{
+  selftests::register_test ("gdb_argv",
+			    selftests::gdb_argv_tests::run_tests);
+}
diff --git a/gdb/utils.c b/gdb/utils.c
index 702c3f15826..05fbbdc2b63 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -3294,31 +3294,6 @@  gdb_realpath_tests ()
   gdb_realpath_check_trailer ("", "");
 }
 
-/* Test the gdb_argv::as_array_view method.  */
-
-static void
-gdb_argv_as_array_view_test ()
-{
-  {
-    gdb_argv argv;
-
-    gdb::array_view<char *> view = argv.as_array_view ();
-
-    SELF_CHECK (view.data () == nullptr);
-    SELF_CHECK (view.size () == 0);
-  }
-  {
-    gdb_argv argv ("une bonne 50");
-
-    gdb::array_view<char *> view = argv.as_array_view ();
-
-    SELF_CHECK (view.size () == 3);
-    SELF_CHECK (strcmp (view[0], "une") == 0);
-    SELF_CHECK (strcmp (view[1], "bonne") == 0);
-    SELF_CHECK (strcmp (view[2], "50") == 0);
-  }
-}
-
 #endif /* GDB_SELF_TEST */
 
 /* Simple, portable version of dirname that does not modify its
@@ -3794,7 +3769,6 @@  When set, debugging messages will be marked with seconds and microseconds."),
 
 #if GDB_SELF_TEST
   selftests::register_test ("gdb_realpath", gdb_realpath_tests);
-  selftests::register_test ("gdb_argv_array_view", gdb_argv_as_array_view_test);
   selftests::register_test ("strncmp_iw_with_mode",
 			    strncmp_iw_with_mode_tests);
   selftests::register_test ("pager", test_pager);