[runtests] Exclude shared libraries from test discovery

Test: ran locally with a shared library in host_tests

Change-Id: If9a3e9d5d92232e0451d610d4c31690495bbb06c
diff --git a/system/ulib/runtests-utils/runtests-utils.cpp b/system/ulib/runtests-utils/runtests-utils.cpp
index 4c38644..3765ef6 100644
--- a/system/ulib/runtests-utils/runtests-utils.cpp
+++ b/system/ulib/runtests-utils/runtests-utils.cpp
@@ -199,6 +199,31 @@
     return 0;
 }
 
+bool IsSharedLibraryName(fbl::StringPiece filename) {
+    struct ExcludePattern {
+        fbl::StringPiece prefix;
+        fbl::StringPiece suffix;
+    };
+    static const fbl::Vector<ExcludePattern> kExcludePatterns = {
+        {"lib", ".so"},
+        {"lib", ".dylib"},
+    };
+
+    for (const auto& exclusion : kExcludePatterns) {
+        if (filename.length() < exclusion.prefix.length() + exclusion.suffix.length()) {
+            continue;
+        }
+
+        fbl::StringPiece start(filename.begin(), exclusion.prefix.length());
+        fbl::StringPiece finish(filename.end() - exclusion.suffix.length(), exclusion.suffix.length());
+        if (start == exclusion.prefix && finish == exclusion.suffix) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 int DiscoverTestsInDirGlobs(const fbl::Vector<fbl::String>& dir_globs,
                             const char* ignore_dir_name,
                             const fbl::Vector<fbl::String>& basename_whitelist,
@@ -247,12 +272,16 @@
 
         struct dirent* de;
         while ((de = readdir(dir)) != nullptr) {
-            const char* test_name = de->d_name;
+            fbl::StringPiece test_name = de->d_name;
             if (!basename_whitelist.is_empty() &&
                 !runtests::IsInWhitelist(test_name, basename_whitelist)) {
                 continue;
             }
 
+            if (IsSharedLibraryName(test_name)) {
+                continue;
+            }
+
             const fbl::String test_path = runtests::JoinPath(abs_test_dir, test_name);
             if (stat(test_path.c_str(), &st) != 0 || !S_ISREG(st.st_mode)) {
                 continue;