[libcxx-commits] [libcxx] 3ea9450 - [libc++] Migrate Lit platform detection to the DSL

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jun 12 11:06:02 PDT 2020


Author: Louis Dionne
Date: 2020-06-12T13:59:45-04:00
New Revision: 3ea9450bda902574426a847e290567ffaf6a6c40

URL: https://github.com/llvm/llvm-project/commit/3ea9450bda902574426a847e290567ffaf6a6c40
DIFF: https://github.com/llvm/llvm-project/commit/3ea9450bda902574426a847e290567ffaf6a6c40.diff

LOG: [libc++] Migrate Lit platform detection to the DSL

As an important fly-by fix, also make sure we set those features to their
value on the target we run on, not on the host compiling the test suite.

Added: 
    

Modified: 
    libcxx/test/libcxx/selftest/dsl/dsl.sh.py
    libcxx/utils/libcxx/test/config.py
    libcxx/utils/libcxx/test/dsl.py
    libcxx/utils/libcxx/test/features.py
    libcxx/utils/libcxx/test/target_info.py

Removed: 
    


################################################################################
diff  --git a/libcxx/test/libcxx/selftest/dsl/dsl.sh.py b/libcxx/test/libcxx/selftest/dsl/dsl.sh.py
index 5a8ae88e0531..b58524175dc7 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/config.py b/libcxx/utils/libcxx/test/config.py
index 44cb95943877..41c0b084393d 100644
--- a/libcxx/utils/libcxx/test/config.py
+++ b/libcxx/utils/libcxx/test/config.py
@@ -317,9 +317,6 @@ def configure_features(self):
             self.config.available_features.add('availability=%s' % name)
             self.config.available_features.add('availability=%s%s' % (name, version))
 
-        # Insert the platform name and version into the available features.
-        self.target_info.add_platform_features(self.config.available_features)
-
         # Simulator testing can take a really long time for some of these tests
         # so add a feature check so we can REQUIRES: long_tests in them
         self.long_tests = self.get_lit_bool('long_tests')
@@ -333,7 +330,6 @@ def configure_features(self):
             self.config.available_features.add('long_tests')
 
         if self.target_info.is_windows():
-            self.config.available_features.add('windows')
             if self.cxx_stdlib_under_test == 'libc++':
                 # LIBCXX-WINDOWS-FIXME is the feature name used to XFAIL the
                 # initial Windows failures until they can be properly diagnosed

diff  --git a/libcxx/utils/libcxx/test/dsl.py b/libcxx/utils/libcxx/test/dsl.py
index bbed2bba76c4..991e938ca197 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=''):
   """

diff  --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py
index d00866df9aaa..ecce08d377d4 100644
--- a/libcxx/utils/libcxx/test/features.py
+++ b/libcxx/utils/libcxx/test/features.py
@@ -7,6 +7,7 @@
 #===----------------------------------------------------------------------===##
 
 from libcxx.test.dsl import *
+import pipes
 import sys
 
 _isClang      = lambda cfg: '__clang__' in compilerMacros(cfg) and '__apple_build_version__' not in compilerMacros(cfg)
@@ -108,3 +109,24 @@
     Feature(name='locale.{}'.format(locale),
             when=lambda cfg: any(hasLocale(cfg, alt) for alt in alts))
   ]
+
+
+# Add a feature representing the platform name: darwin, linux, windows, etc...
+features += [
+  Feature(name=lambda cfg: programOutput(cfg, """
+    #include <cstdio>
+    int main() {
+    #if defined(__APPLE__)
+      std::printf("darwin");
+    #elif defined(_WIN32)
+      std::printf("windows");
+    #elif defined(__NetBSD__)
+      std::printf("netbsd");
+    #elif defined(__linux__)
+      std::printf("linux");
+    #else
+      std::printf("unknown-platform");
+    #endif
+    }
+  """))
+]

diff  --git a/libcxx/utils/libcxx/test/target_info.py b/libcxx/utils/libcxx/test/target_info.py
index adc704890efd..a9abb433133e 100644
--- a/libcxx/utils/libcxx/test/target_info.py
+++ b/libcxx/utils/libcxx/test/target_info.py
@@ -21,23 +21,17 @@ def __init__(self, full_config):
         self.full_config = full_config
         self.executor = None
 
-    def platform(self):
-        return sys.platform.lower().strip()
-
     def is_windows(self):
-        return self.platform() == 'win32'
+        return sys.platform.lower().strip() == 'win32'
 
     def is_darwin(self):
-        return self.platform() == 'darwin'
+        return sys.platform.lower().strip() == 'darwin'
 
     def add_cxx_compile_flags(self, flags): pass
     def add_cxx_link_flags(self, flags): pass
     def allow_cxxabi_link(self): return True
     def use_lit_shell_default(self): return False
 
-    def add_platform_features(self, features):
-        features.add(self.platform())
-
     def add_path(self, dest_env, new_path):
         if not new_path:
             return
@@ -143,44 +137,6 @@ class LinuxLocalTI(DefaultTargetInfo):
     def __init__(self, full_config):
         super(LinuxLocalTI, self).__init__(full_config)
 
-    def platform(self):
-        return 'linux'
-
-    def _distribution(self):
-        try:
-            # linux_distribution is not available since Python 3.8
-            # However, this function is only used to detect SLES 11,
-            # which is quite an old distribution that doesn't have
-            # Python 3.8.
-            return platform.linux_distribution()
-        except AttributeError:
-            return '', '', ''
-
-    def platform_name(self):
-        name, _, _ = self._distribution()
-        # Some distros have spaces, e.g. 'SUSE Linux Enterprise Server'
-        # lit features can't have spaces
-        name = name.lower().strip().replace(' ', '-')
-        return name # Permitted to be None
-
-    def platform_ver(self):
-        _, ver, _ = self._distribution()
-        ver = ver.lower().strip().replace(' ', '-')
-        return ver # Permitted to be None.
-
-    def add_platform_features(self, features):
-        super(LinuxLocalTI, self).add_platform_features(features)
-
-        # Some linux distributions have 
diff erent locale data than others.
-        # Insert the distributions name and name-version into the available
-        # features to allow tests to XFAIL on them.
-        name = self.platform_name()
-        ver = self.platform_ver()
-        if name:
-            features.add(name)
-        if name and ver:
-            features.add('%s-%s' % (name, ver))
-
     def add_cxx_compile_flags(self, flags):
         flags += ['-D__STDC_FORMAT_MACROS',
                   '-D__STDC_LIMIT_MACROS',


        


More information about the libcxx-commits mailing list