gdb: make struct output_source_filename_data more C++ like
[deliverable/binutils-gdb.git] / gdb / unittests / environ-selftests.c
index 28b16f828f36a14c939e9b9aa947a85d637f9241..0ca00a88daa2b997ba3ce23d1e9b5b5f896043b6 100644 (file)
@@ -1,6 +1,6 @@
 /* Self tests for gdb_environ for GDB, the GNU debugger.
 
-   Copyright (C) 2017 Free Software Foundation, Inc.
+   Copyright (C) 2017-2021 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include "selftest.h"
-#include "common/environ.h"
-#include "common/diagnostics.h"
+#include "gdbsupport/selftest.h"
+#include "gdbsupport/environ.h"
+#include "diagnostics.h"
+
+static const char gdb_selftest_env_var[] = "GDB_SELFTEST_ENVIRON";
+
+static bool
+set_contains (const std::set<std::string> &set, std::string key)
+{
+  return set.find (key) != set.end ();
+}
 
 namespace selftests {
 namespace gdb_environ_tests {
 
+/* Test if the vector is initialized in a correct way.  */
+
 static void
-run_tests ()
+test_vector_initialization ()
 {
-  /* Set a test environment variable.  This will be unset at the end
-     of this function.  */
-  if (setenv ("GDB_SELFTEST_ENVIRON", "1", 1) != 0)
-    error (_("Could not set environment variable for testing."));
-
   gdb_environ env;
 
   /* When the vector is initialized, there should always be one NULL
      element in it.  */
   SELF_CHECK (env.envp ()[0] == NULL);
+  SELF_CHECK (env.user_set_env ().size () == 0);
+  SELF_CHECK (env.user_unset_env ().size () == 0);
 
   /* Make sure that there is no other element.  */
   SELF_CHECK (env.get ("PWD") == NULL);
+}
 
-  /* Check if unset followed by a set in an empty vector works.  */
-  env.set ("PWD", "test");
-  SELF_CHECK (strcmp (env.get ("PWD"), "test") == 0);
-  /* The second element must be NULL.  */
-  SELF_CHECK (env.envp ()[1] == NULL);
-  env.unset ("PWD");
-  SELF_CHECK (env.envp ()[0] == NULL);
+/* Test initialization using the host's environ.  */
 
+static void
+test_init_from_host_environ ()
+{
   /* Initialize the environment vector using the host's environ.  */
-  env = gdb_environ::from_host_environ ();
+  gdb_environ env = gdb_environ::from_host_environ ();
+
+  /* The user-set and user-unset lists must be empty.  */
+  SELF_CHECK (env.user_set_env ().size () == 0);
+  SELF_CHECK (env.user_unset_env ().size () == 0);
 
   /* Our test environment variable should be present at the
      vector.  */
-  SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON"), "1") == 0);
-
-  /* Set our test variable to another value.  */
-  env.set ("GDB_SELFTEST_ENVIRON", "test");
-  SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON"), "test") == 0);
-
-  /* And unset our test variable.  The variable still exists in the
-     host's environment, but doesn't exist in our vector.  */
-  env.unset ("GDB_SELFTEST_ENVIRON");
-  SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON") == NULL);
-
-  /* Re-set the test variable.  */
-  env.set ("GDB_SELFTEST_ENVIRON", "1");
-  SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON"), "1") == 0);
+  SELF_CHECK (strcmp (env.get (gdb_selftest_env_var), "1") == 0);
+}
 
-  /* When we clear our environ vector, there should be only one
-     element on it (NULL), and we shouldn't be able to get our test
-     variable.  */
-  env.clear ();
-  SELF_CHECK (env.envp ()[0] == NULL);
-  SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON") == NULL);
+/* Test reinitialization using the host's environ.  */
 
+static void
+test_reinit_from_host_environ ()
+{
   /* Reinitialize our environ vector using the host environ.  We
      should be able to see one (and only one) instance of the test
      variable.  */
+  gdb_environ env = gdb_environ::from_host_environ ();
   env = gdb_environ::from_host_environ ();
   char **envp = env.envp ();
   int num_found = 0;
@@ -88,15 +84,23 @@ run_tests ()
     if (strcmp (envp[i], "GDB_SELFTEST_ENVIRON=1") == 0)
       ++num_found;
   SELF_CHECK (num_found == 1);
+}
 
-  /* Get rid of our test variable.  */
-  unsetenv ("GDB_SELFTEST_ENVIRON");
+/* Test the case when we set a variable A, then set a variable B,
+   then unset A, and make sure that we cannot find A in the environ
+   vector, but can still find B.  */
+
+static void
+test_set_A_unset_B_unset_A_cannot_find_A_can_find_B ()
+{
+  gdb_environ env;
 
-  /* Test the case when we set a variable A, then set a variable B,
-     then unset A, and make sure that we cannot find A in the environ
-     vector, but can still find B.  */
   env.set ("GDB_SELFTEST_ENVIRON_1", "aaa");
   SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON_1"), "aaa") == 0);
+  /* User-set environ var list must contain one element.  */
+  SELF_CHECK (env.user_set_env ().size () == 1);
+  SELF_CHECK (set_contains (env.user_set_env (),
+                           std::string ("GDB_SELFTEST_ENVIRON_1=aaa")));
 
   env.set ("GDB_SELFTEST_ENVIRON_2", "bbb");
   SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON_2"), "bbb") == 0);
@@ -105,38 +109,117 @@ run_tests ()
   SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON_1") == NULL);
   SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON_2"), "bbb") == 0);
 
+  /* The user-set environ var list must contain only one element
+     now.  */
+  SELF_CHECK (set_contains (env.user_set_env (),
+                           std::string ("GDB_SELFTEST_ENVIRON_2=bbb")));
+  SELF_CHECK (env.user_set_env ().size () == 1);
+}
+
+/* Check if unset followed by a set in an empty vector works.  */
+
+static void
+test_unset_set_empty_vector ()
+{
+  gdb_environ env;
+
+  env.set ("PWD", "test");
+  SELF_CHECK (strcmp (env.get ("PWD"), "test") == 0);
+  SELF_CHECK (set_contains (env.user_set_env (), std::string ("PWD=test")));
+  SELF_CHECK (env.user_unset_env ().size () == 0);
+  /* The second element must be NULL.  */
+  SELF_CHECK (env.envp ()[1] == NULL);
+  SELF_CHECK (env.user_set_env ().size () == 1);
+  env.unset ("PWD");
+  SELF_CHECK (env.envp ()[0] == NULL);
+  SELF_CHECK (env.user_set_env ().size () == 0);
+  SELF_CHECK (env.user_unset_env ().size () == 1);
+  SELF_CHECK (set_contains (env.user_unset_env (), std::string ("PWD")));
+}
+
+/* When we clear our environ vector, there should be only one
+   element on it (NULL), and we shouldn't be able to get our test
+   variable.  */
+
+static void
+test_vector_clear ()
+{
+  gdb_environ env;
+
+  env.set (gdb_selftest_env_var, "1");
+
   env.clear ();
+  SELF_CHECK (env.envp ()[0] == NULL);
+  SELF_CHECK (env.user_set_env ().size () == 0);
+  SELF_CHECK (env.user_unset_env ().size () == 0);
+  SELF_CHECK (env.get (gdb_selftest_env_var) == NULL);
+}
+
+/* Test that after a std::move the moved-from object is left at a
+   valid state (i.e., its only element is NULL).  */
+
+static void
+test_std_move ()
+{
+  gdb_environ env;
+  gdb_environ env2;
 
-  /* Test that after a std::move the moved-from object is left at a
-     valid state (i.e., its only element is NULL).  */
   env.set ("A", "1");
   SELF_CHECK (strcmp (env.get ("A"), "1") == 0);
-  gdb_environ env2;
+  SELF_CHECK (set_contains (env.user_set_env (), std::string ("A=1")));
+  SELF_CHECK (env.user_set_env ().size () == 1);
+
   env2 = std::move (env);
   SELF_CHECK (env.envp ()[0] == NULL);
   SELF_CHECK (strcmp (env2.get ("A"), "1") == 0);
   SELF_CHECK (env2.envp ()[1] == NULL);
+  SELF_CHECK (env.user_set_env ().size () == 0);
+  SELF_CHECK (set_contains (env2.user_set_env (), std::string ("A=1")));
+  SELF_CHECK (env2.user_set_env ().size () == 1);
   env.set ("B", "2");
   SELF_CHECK (strcmp (env.get ("B"), "2") == 0);
   SELF_CHECK (env.envp ()[1] == NULL);
+}
+
+/* Test that the move constructor leaves everything at a valid
+   state.  */
+
+static void
+test_move_constructor ()
+{
+  gdb_environ env;
 
-  /* Test that the move constructor leaves everything at a valid
-     state.  */
-  env.clear ();
   env.set ("A", "1");
   SELF_CHECK (strcmp (env.get ("A"), "1") == 0);
-  gdb_environ env3 = std::move (env);
+  SELF_CHECK (set_contains (env.user_set_env (), std::string ("A=1")));
+
+  gdb_environ env2 = std::move (env);
   SELF_CHECK (env.envp ()[0] == NULL);
-  SELF_CHECK (strcmp (env3.get ("A"), "1") == 0);
-  SELF_CHECK (env3.envp ()[1] == NULL);
+  SELF_CHECK (env.user_set_env ().size () == 0);
+  SELF_CHECK (strcmp (env2.get ("A"), "1") == 0);
+  SELF_CHECK (env2.envp ()[1] == NULL);
+  SELF_CHECK (set_contains (env2.user_set_env (), std::string ("A=1")));
+  SELF_CHECK (env2.user_set_env ().size () == 1);
+
   env.set ("B", "2");
   SELF_CHECK (strcmp (env.get ("B"), "2") == 0);
   SELF_CHECK (env.envp ()[1] == NULL);
+  SELF_CHECK (set_contains (env.user_set_env (), std::string ("B=2")));
+  SELF_CHECK (env.user_set_env ().size () == 1);
+}
+
+/* Test that self-moving works.  */
+
+static void
+test_self_move ()
+{
+  gdb_environ env;
 
   /* Test self-move.  */
-  env.clear ();
   env.set ("A", "1");
   SELF_CHECK (strcmp (env.get ("A"), "1") == 0);
+  SELF_CHECK (set_contains (env.user_set_env (), std::string ("A=1")));
+  SELF_CHECK (env.user_set_env ().size () == 1);
 
   /* Some compilers warn about moving to self, but that's precisely what we want
      to test here, so turn this warning off.  */
@@ -148,12 +231,77 @@ run_tests ()
   SELF_CHECK (strcmp (env.get ("A"), "1") == 0);
   SELF_CHECK (strcmp (env.envp ()[0], "A=1") == 0);
   SELF_CHECK (env.envp ()[1] == NULL);
+  SELF_CHECK (set_contains (env.user_set_env (), std::string ("A=1")));
+  SELF_CHECK (env.user_set_env ().size () == 1);
+}
+
+/* Test if set/unset/reset works.  */
+
+static void
+test_set_unset_reset ()
+{
+  gdb_environ env = gdb_environ::from_host_environ ();
+
+  /* Our test variable should already be present in the host's environment.  */
+  SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON") != NULL);
+
+  /* Set our test variable to another value.  */
+  env.set ("GDB_SELFTEST_ENVIRON", "test");
+  SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON"), "test") == 0);
+  SELF_CHECK (env.user_set_env ().size () == 1);
+  SELF_CHECK (env.user_unset_env ().size () == 0);
+
+  /* And unset our test variable.  The variable still exists in the
+     host's environment, but doesn't exist in our vector.  */
+  env.unset ("GDB_SELFTEST_ENVIRON");
+  SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON") == NULL);
+  SELF_CHECK (env.user_set_env ().size () == 0);
+  SELF_CHECK (env.user_unset_env ().size () == 1);
+  SELF_CHECK (set_contains (env.user_unset_env (),
+                           std::string ("GDB_SELFTEST_ENVIRON")));
+
+  /* Re-set the test variable.  */
+  env.set ("GDB_SELFTEST_ENVIRON", "1");
+  SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON"), "1") == 0);
+}
+
+static void
+run_tests ()
+{
+  /* Set a test environment variable.  */
+  if (setenv ("GDB_SELFTEST_ENVIRON", "1", 1) != 0)
+    error (_("Could not set environment variable for testing."));
+
+  test_vector_initialization ();
+
+  test_unset_set_empty_vector ();
+
+  test_init_from_host_environ ();
+
+  test_set_unset_reset ();
+
+  test_vector_clear ();
+
+  test_reinit_from_host_environ ();
+
+  /* Get rid of our test variable.  We won't need it anymore.  */
+  unsetenv ("GDB_SELFTEST_ENVIRON");
+
+  test_set_A_unset_B_unset_A_cannot_find_A_can_find_B ();
+
+  test_std_move ();
+
+  test_move_constructor ();
+
+  test_self_move ();
 }
 } /* namespace gdb_environ */
 } /* namespace selftests */
 
+void _initialize_environ_selftests ();
 void
 _initialize_environ_selftests ()
 {
-  register_self_test (selftests::gdb_environ_tests::run_tests);
+  selftests::register_test ("gdb_environ",
+                           selftests::gdb_environ_tests::run_tests);
 }
This page took 0.03482 seconds and 4 git commands to generate.