[libcxx-commits] [libcxx] 96e48e9 - [libc++] Add the ability to run arbitrary programs using the DSL

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jun 15 12:00:06 PDT 2020


Author: Louis Dionne
Date: 2020-06-15T14:59:53-04:00
New Revision: 96e48e9a61ad4b5992457169685c5c69e20889b5

URL: https://github.com/llvm/llvm-project/commit/96e48e9a61ad4b5992457169685c5c69e20889b5
DIFF: https://github.com/llvm/llvm-project/commit/96e48e9a61ad4b5992457169685c5c69e20889b5.diff

LOG: [libc++] Add the ability to run arbitrary programs using the DSL

This is useful for checking runtime properties of the target system.
This is a partial re-application of 3ea9450bda90. This part was tested
to work on a Windows host with a SSH executor.

Added: 
    

Modified: 
    libcxx/test/libcxx/selftest/dsl/dsl.sh.py
    libcxx/utils/libcxx/test/dsl.py

Removed: 
    


################################################################################
diff  --git a/libcxx/test/libcxx/selftest/dsl/dsl.sh.py b/libcxx/test/libcxx/selftest/dsl/dsl.sh.py
index b9437d6ca053..7205f35e7dc5 100644
--- a/libcxx/test/libcxx/selftest/dsl/dsl.sh.py
+++ b/libcxx/test/libcxx/selftest/dsl/dsl.sh.py
@@ -114,6 +114,56 @@ def test_link_error_fails(self):
                     int main(int, char**) { this_isnt_defined_anywhere(); }"""
         self.assertFalse(dsl.sourceBuilds(self.config, source))
 
+class TestProgramOutput(SetupConfigs):
+    """
+    Tests for libcxx.test.dsl.programOutput
+    """
+    def test_valid_program_returns_output(self):
+        source = """
+        #include <cstdio>
+        int main(int, char**) { std::printf("FOOBAR"); }
+        """
+        self.assertEqual(dsl.programOutput(self.config, source), "FOOBAR")
+
+    def test_valid_program_returns_output_newline_handling(self):
+        source = """
+        #include <cstdio>
+        int main(int, char**) { std::printf("FOOBAR\\n"); }
+        """
+        self.assertEqual(dsl.programOutput(self.config, source), "FOOBAR\n")
+
+    def test_valid_program_returns_no_output(self):
+        source = """
+        int main(int, char**) { }
+        """
+        self.assertEqual(dsl.programOutput(self.config, source), "")
+
+    def test_invalid_program_returns_None_1(self):
+        # The program compiles, but exits with an error
+        source = """
+        int main(int, char**) { return 1; }
+        """
+        self.assertEqual(dsl.programOutput(self.config, source), None)
+
+    def test_invalid_program_returns_None_2(self):
+        # The program doesn't compile
+        source = """
+        int main(int, char**) { this doesnt compile }
+        """
+        self.assertEqual(dsl.programOutput(self.config, source), None)
+
+    def test_pass_arguments_to_program(self):
+        source = """
+        #include <cassert>
+        #include <string>
+        int main(int argc, char** argv) {
+            assert(argc == 3);
+            assert(argv[1] == std::string("first-argument"));
+            assert(argv[2] == std::string("second-argument"));
+        }
+        """
+        args = ["first-argument", "second-argument"]
+        self.assertEqual(dsl.programOutput(self.config, source, args=args), "")
 
 class TestHasLocale(SetupConfigs):
     """

diff  --git a/libcxx/utils/libcxx/test/dsl.py b/libcxx/utils/libcxx/test/dsl.py
index 3e2d0ed8ee33..475e19eae231 100644
--- a/libcxx/utils/libcxx/test/dsl.py
+++ b/libcxx/utils/libcxx/test/dsl.py
@@ -12,6 +12,7 @@
 import os
 import pipes
 import platform
+import re
 import tempfile
 
 def _memoize(f):
@@ -75,6 +76,39 @@ def sourceBuilds(config, source):
     _executeScriptInternal(test, ['rm %t.exe'])
     return exitCode == 0
 
+def programOutput(config, program, args=[]):
+  """
+  Compiles a program for the test target, run it on the test target and return
+  the output.
+
+  If the program fails to compile or run, None is returned instead. Note that
+  execution of the program is done through the %{exec} substitution, which means
+  that the program may be run on a remote host depending on what %{exec} does.
+  """
+  with _makeConfigTest(config) as test:
+    with open(test.getSourcePath(), 'w') as source:
+      source.write(program)
+    try:
+      _, _, exitCode, _ = _executeScriptInternal(test, [
+        "mkdir -p %T",
+        "%{cxx} %s %{flags} %{compile_flags} %{link_flags} -o %t.exe",
+      ])
+      if exitCode != 0:
+        return None
+
+      out, err, exitCode, _ = _executeScriptInternal(test, [
+        "%{{exec}} %t.exe {}".format(' '.join(args))
+      ])
+      if exitCode != 0:
+        return None
+
+      actualOut = re.search("command output:\n(.+)\n$", out, flags=re.DOTALL)
+      actualOut = actualOut.group(1) if actualOut else ""
+      return actualOut
+
+    finally:
+      _executeScriptInternal(test, ['rm %t.exe'])
+
 def hasCompileFlag(config, flag):
   """
   Return whether the compiler in the configuration supports a given compiler flag.
@@ -96,22 +130,14 @@ def hasLocale(config, locale):
   %{exec} -- this means that the command may be executed on a remote host
   depending on the %{exec} substitution.
   """
-  with _makeConfigTest(config) as test:
-    with open(test.getSourcePath(), 'w') as source:
-      source.write("""
-      #include <locale.h>
-      int main(int, char** argv) {
-        if (::setlocale(LC_ALL, argv[1]) != NULL) return 0;
-        else                                      return 1;
-      }
-      """)
-    out, err, exitCode, timeoutInfo = _executeScriptInternal(test, [
-      "mkdir -p %T",
-      "%{cxx} %s %{flags} %{compile_flags} %{link_flags} -o %t.exe",
-      "%{{exec}} %t.exe {}".format(pipes.quote(locale)),
-    ])
-    _executeScriptInternal(test, ['rm %t.exe'])
-    return exitCode == 0
+  program = """
+    #include <locale.h>
+    int main(int, char** argv) {
+      if (::setlocale(LC_ALL, argv[1]) != NULL) return 0;
+      else                                      return 1;
+    }
+  """
+  return programOutput(config, program, args=[pipes.quote(locale)]) != None
 
 def compilerMacros(config, flags=''):
   """


        


More information about the libcxx-commits mailing list