This is an automated email from the ASF dual-hosted git repository.

leginee pushed a commit to branch bazel-migration
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit db9514d4d88722b66b4c8337b6b32ae0890a1fe4
Author: Peter Kovacs <[email protected]>
AuthorDate: Sat Aug 1 16:29:30 2026 +0200

    test(sal,shell): wire the osl/socket + shell zip suites; two reusable test 
hooks
    
    Nine more suites onto `bazel test`.  The headline is that "these need a 
CppUnit
    external dep" — carried in the frontier and main/test/readme.md for months 
— was
    simply wrong: every one of them is a plain GoogleTest suite.  Nothing 
checked so
    far actually uses CppUnit.
    
      //main/sal   osl_SocketOld, osl_Socket_tests, osl_StreamSocket,
                   osl_DatagramSocket, osl_SocketAddr, osl_Socket2,
                   osl_ConnectorSocket, osl_AcceptorSocket   (8, from
                   qa/osl/socket/makefile.mk; all they needed was ws2_32)
      //main/shell shell_qa_zip (3 cases) — zipfile reader over a real .odt.  
dmake
                   split this into exe + DLL only so the DLL could be rebuilt
                   against a different STL (NO_DEFAULT_STL); no analogue here, 
so
                   both TUs go into the one exe.
    
    Two reusable hooks fell out, both plumbed through gtest_test:
    
    * //build/testsupport:sal_process_init.  The socket suites each declare 
their
      own bare main() instead of going through SAL_IMPLEMENT_MAIN, and on 
Windows
      that macro is what calls sal_detail_initialize() -> WSAStartup (sal3.dll's
      DllMain only ever calls the matching WSACleanup, never WSAStartup).  
Without
      it Winsock is never initialised and every osl socket call returns
      WSANOTINITIALISED, so the suites collapse in ways that implicate 
everything
      except the cause — SocketAddr constructors quietly yield unusable 
addresses,
      getLocalHostname() fails.  These are testshl2-era suites; that harness 
used to
      supply main() for them.  The shim initialises from a dynamic initialiser
      (run by the CRT before main) using __argc/__argv, since osl_setCommandArgs
      asserts argc > 0.  It is migration-authored test support, not AOO source,
      hence build/ rather than main/<module>/qa/.
    
    * gtest_test's data_files.  Staging a fixture beside the exe is NOT enough:
      `bazel test` sets the working directory to the execroot, not the exe's 
dir.
      Co-located DLLs still resolve (the loader searches the exe's own path), 
which
      makes it easy to assume relative opens do too.  shell_qa_zip opens
      "simpledocument.odt" by bare name and threw file-not-found while passing 
when
      run by hand from the staged dir.  data_files stages the input AND 
switches the
      target to a .bat launcher that cd's there first, forwarding the exit code.
    
    With the shim, 4 of the 8 socket suites are fully green and the rest go from
    near-total failure to a small residual set, none of it a build problem.  The
    module's own .xsce files already excluded connect_003 and getLocalHost_001 
for
    wntmsci — our exact platform — plus ctors_family_Ipx and getHostname_002
    everywhere; the remainder need Administrator (raw sockets), use an 
unsupported
    socket option (SO_DONTROUTE), or depend on DNS.  All 8 are added to 
sal_tests
    per that suite's stated policy of running everything and treating failures 
as
    information; it is 44 targets / 34 passing, documented in 
main/test/readme.md.
    
    Also recorded there and in CLAUDE.md: writerfilter/qa/cppunittests is 
misnamed —
    only doctok is GoogleTest, the other four use the retired testshl harness, 
as
    does sal/qa/rtl_strings, which its own readme.txt marks superseded by
    qa/rtl/{ostring,oustring} (both already wired).  Dead weight, not blockers.
    
    Co-Authored-By: Claude Opus 5 <[email protected]>
---
 CLAUDE.md                              | 27 ++++++++++---
 build/rules/gtest_test.bzl             | 40 +++++++++++++++++--
 build/testsupport/BUILD.bazel          | 16 ++++++++
 build/testsupport/sal_process_init.cxx | 64 ++++++++++++++++++++++++++++++
 main/sal/BUILD.bazel                   | 53 +++++++++++++++++++++++++
 main/shell/BUILD.bazel                 | 33 ++++++++++++++++
 main/test/readme.md                    | 71 +++++++++++++++++++++++++++++++---
 7 files changed, 289 insertions(+), 15 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index 63959e4f30..1e11722886 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -49,12 +49,27 @@ test          🔨  C++ unit-test infra runnable — NOW THE 
FRONT-LINE TASK: br
                    id 1, now linked into every gtest_test exe) not just staged 
as an
                    external <exe>.manifest, or late DLL loads fall outside the
                    activation context.  NEXT: sweep qa/ across the remaining 
migrated
-                   modules — most of what is left is NOT standalone: 
svl/qa/complex +
-                   svtools/qa/unoapi + sfx2 + writerfilter/qa/complex are 
Java/UNO,
-                   svl/qa/test_URIHelper and configmgr/qa/unit bootstrap a UNO
-                   component context, shell/qa + writerfilter/qa/cppunittests 
are
-                   cppunit.  So the front line now shifts to the two fixtures:
-                   OfficeConnection (running-soffice) and a CppUnit external 
dep.
+                   modules.  DONE since: 8 sal osl/socket suites + 
shell_qa_zip.
+                   "Needs a CppUnit external dep" was largely a MYTH — NOTHING 
checked
+                   so far actually uses cppunit.  osl/socket and shell/qa are 
plain
+                   GoogleTest (now wired); writerfilter/qa/cppunittests is 
misnamed —
+                   only doctok is GoogleTest, the other 4 
(odiapi/qname/sl/xxml) use
+                   the RETIRED testshl harness, as does rtl_strings, which is 
also
+                   superseded by qa/rtl/{ostring,oustring} — treat all of 
those as dead
+                   weight, not blockers, and do not migrate them.  Two 
reusable hooks came
+                   out of it, both in gtest_test: 
//build/testsupport:sal_process_init
+                   (suites with a bare main() skip SAL_IMPLEMENT_MAIN ⇒ no 
WSAStartup
+                   ⇒ every osl socket call is WSANOTINITIALISED) and 
data_files (a
+                   staged fixture is NOT enough — bazel test's CWD is the 
execroot, so
+                   relative opens need the cd-first .bat launcher).  NEXT: 
what is
+                   genuinely left is not standalone — svl/qa/complex + 
svtools/qa/unoapi
+                   + sfx2 + writerfilter/qa/complex are Java/UNO; 
svl/qa/test_URIHelper,
+                   configmgr/qa/unit and cppuhelper/qa/propertysetmixin 
bootstrap a UNO
+                   component context.  So the front line is now ONE fixture:
+                   OfficeConnection (running-soffice).  test.dll is built and 
its
+                   arg plumbing is rtl::Bootstrap 
"arg-soffice=path:…"/"arg-user=…",
+                   so the missing piece is a rule that points it at 
//main/staging:install
+                   and gives the test exe its own UNO bootstrap.
 testtools     ⬜  (bridgetest — pure-C++ UNO bridge round-trip; cli/pyuno/java 
variants
                    need rules_java — see Java bucket)
 qadevOOo      🔨  OOoRunner.jar built (//main/qadevOOo:OOoRunner — qadevOOo QA
diff --git a/build/rules/gtest_test.bzl b/build/rules/gtest_test.bzl
index 0cde3d9fcb..9217f857be 100644
--- a/build/rules/gtest_test.bzl
+++ b/build/rules/gtest_test.bzl
@@ -75,10 +75,33 @@ def _staged_gtest_test_impl(ctx):
     ctx.actions.symlink(output = man, target_file = ctx.file.app_manifest)
     staged.append(man)
 
+    # Co-locating a data file with the exe is not enough for a test that opens 
it
+    # by bare relative name: `bazel test` runs the executable with the working
+    # directory set to the execroot, not to the exe's directory (the loader 
finds
+    # the staged DLLs via the exe's own path, which is why those work 
regardless).
+    # When run_in_staged_dir is set, hand Bazel a .bat that cd's into the 
staged
+    # dir first and forwards the exit code, so relative paths resolve there.
+    executable = staged_exe
+    if ctx.attr.run_in_staged_dir:
+        launcher = ctx.actions.declare_file(d + "/" + ctx.label.name + 
"_run.bat")
+        ctx.actions.write(
+            output = launcher,
+            content = "\r\n".join([
+                "@echo off",
+                'cd /d "%~dp0" || exit /b 1',
+                '"%~dp0' + staged_exe.basename + '" %*',
+                "exit /b %ERRORLEVEL%",
+                "",
+            ]),
+            is_executable = True,
+        )
+        staged.append(launcher)
+        executable = launcher
+
     return [DefaultInfo(
-        executable = staged_exe,
+        executable = executable,
         runfiles = ctx.runfiles(files = staged),
-        files = depset([staged_exe]),
+        files = depset([executable]),
     )]
 
 _staged_gtest_test = rule(
@@ -89,6 +112,7 @@ _staged_gtest_test = rule(
         "runtime": attr.label_list(allow_files = True),
         "companions": attr.label_list(cfg = "target"),
         "app_manifest": attr.label(allow_single_file = True, default = 
_APP_MANIFEST),
+        "run_in_staged_dir": attr.bool(default = False),
     },
 )
 
@@ -106,12 +130,19 @@ def gtest_test(
         copts = [],
         defines = [],
         runtime_dlls = [],
+        data_files = [],
         companions = [],
         additional_linker_inputs = [],
         linkopts = [],
         size = "small",
         **kwargs):
-    """A GoogleTest suite that actually runs under `bazel test` on 
Windows/MD."""
+    """A GoogleTest suite that actually runs under `bazel test` on Windows/MD.
+
+    data_files: inputs the test opens by relative path (fixture documents, …).
+    They are staged beside the exe AND the test is launched with its working
+    directory set to that staged dir, which co-location alone does not give you
+    (see run_in_staged_dir in the staging rule).
+    """
     cc_binary(
         name = name + "_bin",
         srcs = srcs,
@@ -135,7 +166,8 @@ def gtest_test(
     _staged_gtest_test(
         name = name,
         binary = ":" + name + "_bin",
-        runtime = runtime_dlls + [_CRT],
+        runtime = runtime_dlls + data_files + [_CRT],
         companions = companions,
+        run_in_staged_dir = bool(data_files),
         size = size,
     )
diff --git a/build/testsupport/BUILD.bazel b/build/testsupport/BUILD.bazel
new file mode 100644
index 0000000000..5643a9325b
--- /dev/null
+++ b/build/testsupport/BUILD.bazel
@@ -0,0 +1,16 @@
+package(default_visibility = ["//visibility:public"])
+
+# Bazel migration test support — helper TUs linked into test exes.  These are
+# migration-authored (like //main/bridges:jni_test_launcher), NOT AOO product
+# source, which is why they live under build/ rather than main/<module>/qa/.
+
+# sal_process_init — runs sal_detail_initialize() from a dynamic initialiser,
+# for GoogleTest suites whose own main() skips the SAL_IMPLEMENT_MAIN
+# boilerplate.  On Windows that boilerplate is what calls WSAStartup(), so
+# without it every osl socket call fails with WSANOTINITIALISED.  See the file
+# header for the full story.
+#
+# Exported as a plain source file rather than a cc_library so it compiles with
+# the consuming test's own copts/defines (the sal/qa suites need /Zc:wchar_t-
+# and the sal_qa_test define set to agree with sal3.dll).
+exports_files(["sal_process_init.cxx"])
diff --git a/build/testsupport/sal_process_init.cxx 
b/build/testsupport/sal_process_init.cxx
new file mode 100644
index 0000000000..00a85cfdfb
--- /dev/null
+++ b/build/testsupport/sal_process_init.cxx
@@ -0,0 +1,64 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// Bazel migration test support — NOT part of the AOO product source.
+//
+// Every real AOO binary enters through SAL_IMPLEMENT_MAIN (sal/main.h), whose
+// generated main() calls sal_detail_initialize() first.  On Windows that is
+// where WSAStartup() happens (sal/osl/w32/salinit.cxx) — sal3.dll's DllMain
+// only ever calls the matching WSACleanup(), never WSAStartup().
+//
+// Several sal/qa GoogleTest suites (qa/osl/socket/*) declare a plain
+//     int main(int argc, char ** argv) { InitGoogleTest(...); 
RUN_ALL_TESTS(); }
+// which skips that boilerplate, so Winsock is never initialised and every osl
+// socket call fails with WSANOTINITIALISED — SocketAddr constructors silently
+// produce unusable addresses, getLocalHostname() fails, and the suite reports
+// dozens of unrelated-looking assertion failures.  They date from the testshl2
+// era, when the harness supplied main() (and the init) for them; testshl2 was
+// retired, and nothing took over the job.
+//
+// Fixing the suites would mean editing product-adjacent source, which is out 
of
+// scope for this migration.  Instead this TU is linked into those test exes 
and
+// does the initialisation from a dynamic initialiser, which the CRT runs 
BEFORE
+// main().  __argc/__argv are already populated at that point (the MSVC CRT 
sets
+// them during startup, ahead of dynamic initialisers), so sal sees the real
+// command line exactly as SAL_IMPLEMENT_MAIN would pass it — 
osl_setCommandArgs
+// asserts argc > 0, so passing 0/NULL is not an option.
+//
+// Deliberately NOT calling sal_detail_deinitialize(): sal3.dll's DllMain 
already
+// issues WSACleanup() on DLL_PROCESS_DETACH, and a second one would unbalance
+// the Winsock refcount.
+
+#include <stdlib.h>  // __argc / __argv
+
+#include "sal/main.h"
+
+namespace {
+
+struct SalProcessInit {
+    SalProcessInit() { sal_detail_initialize(__argc, __argv); }
+};
+
+// Dynamic initialiser: constructed before main(), like the CRT startup that
+// SAL_IMPLEMENT_MAIN would otherwise front.
+SalProcessInit theSalProcessInit;
+
+}
diff --git a/main/sal/BUILD.bazel b/main/sal/BUILD.bazel
index f471f2f380..bd001a851f 100644
--- a/main/sal/BUILD.bazel
+++ b/main/sal/BUILD.bazel
@@ -268,6 +268,51 @@ sal_qa_test(name = "osl_old_test_file", srcs = 
["qa/osl/file/osl_old_test_file.c
 # osl_Thread calls Win32 Sleep() (kernel32, default-linked): force-include 
<windows.h>.
 sal_qa_test(name = "osl_Thread", srcs = ["qa/osl/process/osl_Thread.cxx"], 
subdir = "osl/process", copts = ["/FIwindows.h"])
 
+# osl/socket — 8 apps from qa/osl/socket/makefile.mk.  These were long listed 
as
+# "blocked on a CppUnit external dep"; that was wrong — every one of them is
+# already a plain GoogleTest suite (`#include "gtest/gtest.h"`, TEST_F) with no
+# testshl2 include, so all they ever needed was ws2_32.  6 of the 8 share
+# sockethelper.cxx (ping/hostname/addr helpers).
+#
+# These bind real sockets on localhost and resolve the local hostname, so 
unlike
+# the rest of sal/qa they are environment-sensitive by nature.
+#
+# //build/testsupport:sal_process_init is REQUIRED, not incidental: each of
+# these suites declares its own bare main() that skips the SAL_IMPLEMENT_MAIN
+# boilerplate, and on Windows that boilerplate (sal_detail_initialize) is what
+# calls WSAStartup.  Without it Winsock is never initialised, every osl socket
+# call returns WSANOTINITIALISED, and the suites fail wholesale in ways that
+# point everywhere except the real cause.  They are testshl2-era suites — that
+# harness used to supply main() for them.
+_SOCKET_LINKOPTS = ["ws2_32.lib"]
+
+_SOCKET_INIT = "//build/testsupport:sal_process_init.cxx"
+
+sal_qa_test(name = "osl_SocketOld", srcs = ["qa/osl/socket/osl_Socket.cxx", 
_SOCKET_INIT], subdir = "osl/socket", linkopts = _SOCKET_LINKOPTS)
+sal_qa_test(name = "osl_Socket_tests", srcs = 
["qa/osl/socket/osl_Socket_tests.cxx", _SOCKET_INIT], subdir = "osl/socket", 
linkopts = _SOCKET_LINKOPTS)
+
+[
+    sal_qa_test(
+        name = t,
+        srcs = [
+            "qa/osl/socket/%s.cxx" % t,
+            "qa/osl/socket/sockethelper.cxx",
+            "qa/osl/socket/sockethelper.hxx",
+            _SOCKET_INIT,
+        ],
+        subdir = "osl/socket",
+        linkopts = _SOCKET_LINKOPTS,
+    )
+    for t in [
+        "osl_StreamSocket",
+        "osl_DatagramSocket",
+        "osl_SocketAddr",
+        "osl_Socket2",
+        "osl_ConnectorSocket",
+        "osl_AcceptorSocket",
+    ]
+]
+
 # systools — Win32 COM smart pointers (needs ole32 + CoInitialize).
 sal_qa_test(name = "test_comtools", srcs = ["qa/systools/test_comtools.cxx"], 
subdir = "systools", copts = ["/FIwindows.h"], linkopts = ["ole32.lib"])
 
@@ -339,6 +384,14 @@ test_suite(
         ":tcwf",
         ":osl_old_test_file",
         ":osl_Thread",
+        ":osl_SocketOld",
+        ":osl_Socket_tests",
+        ":osl_StreamSocket",
+        ":osl_DatagramSocket",
+        ":osl_SocketAddr",
+        ":osl_Socket2",
+        ":osl_ConnectorSocket",
+        ":osl_AcceptorSocket",
         ":test_comtools",
         ":testHelperFunctions",
         ":sal_ut_types",
diff --git a/main/shell/BUILD.bazel b/main/shell/BUILD.bazel
index 2c7055de0d..9bac4cd55f 100644
--- a/main/shell/BUILD.bazel
+++ b/main/shell/BUILD.bazel
@@ -2,6 +2,7 @@ package(default_visibility = ["//visibility:public"])
 
 load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
 load("//build/rules:lngconvex_rule.bzl", "lngconvex_bundle")
+load("//build/rules:gtest_test.bzl", "gtest_test")
 
 # ── Common settings ───────────────────────────────────────────────
 # Defines shared by all shlxthandler targets (XML parser + ZIP reader
@@ -438,5 +439,37 @@ cc_binary(
     visibility = ["//visibility:public"],
 )
 
+# ── qa unit test ──────────────────────────────────────────────────
+# zipfile reader round-trip over a real .odt (qa/zip).  Another suite long
+# filed as "needs CppUnit" that is in fact plain GoogleTest.
+#
+# dmake built this as an exe (ziptest.obj) linking a DLL (qa_zipimpl.dll from
+# testzipimpl.obj); that split existed only to let the DLL be rebuilt against a
+# different STL (NO_DEFAULT_STL / msvcprt.lib in testimpl/makefile.mk), which
+# has no analogue here — so both TUs go straight into the one exe.
+#
+# The test opens "simpledocument.odt" by BARE RELATIVE NAME, so it needs the
+# file resolvable from the process's working directory — which `bazel test` 
sets
+# to the execroot, not the exe's dir.  Passing it as data_files both stages it
+# beside the exe and switches the target to the cd-first .bat launcher.
+gtest_test(
+    name = "shell_qa_zip",
+    srcs = [
+        "qa/zip/ziptest.cxx",
+        "qa/zip/testimpl/testzipimpl.cxx",
+        "qa/zip/testimpl/testzipimpl.hxx",
+    ],
+    copts = _SHLXT_COPTS + ["/Imain/shell/qa/zip"],
+    defines = _SHLXT_DEFINES,
+    deps = [
+        ":zipfile",
+        "//main/sal:sal_headers",
+    ],
+    additional_linker_inputs = ["//main/sal:sal_implib"],
+    linkopts = ["$(execpath //main/sal:sal_implib)"],
+    runtime_dlls = ["//main/sal:sal3"],
+    data_files = ["qa/zip/simpledocument.odt"],
+)
+
 exports_files(glob(["**/*.component"]))
 
diff --git a/main/test/readme.md b/main/test/readme.md
index a4372343fb..7157875f45 100644
--- a/main/test/readme.md
+++ b/main/test/readme.md
@@ -28,7 +28,8 @@ holdouts).  This brings the test layer onto Bazel so suites 
run under
 | Piece | Path | Role |
 | ----- | ---- | ---- |
 | `@gtest` | `ext_libraries/modules/gtest/1.7.0/` | GoogleTest 1.7.0 bzlmod 
wrap (zip cached in `ext_sources`). Built with `/Zc:wchar_t-` so its `wchar_t` 
ABI matches `sal_Unicode` test code. |
-| `gtest_test` rule | 
[//build/rules:gtest_test.bzl](../../build/rules/gtest_test.bzl) | Reusable 
runnable-test rule. The `/MD` toolchain embeds no manifest, so a bare `cc_test` 
exe can't launch (DLLs land in runfiles subdirs; loose CRT → R6034). This 
stages the exe + runtime DLLs + VC90 CRT + an external `<exe>.manifest` into 
ONE flat dir (the test analog of `//main/idl:svidl_bundle`). |
+| `gtest_test` rule | 
[//build/rules:gtest_test.bzl](../../build/rules/gtest_test.bzl) | Reusable 
runnable-test rule. The `/MD` toolchain embeds no manifest, so a bare `cc_test` 
exe can't launch (DLLs land in runfiles subdirs; loose CRT → R6034). This 
stages the exe + runtime DLLs + VC90 CRT + an external `<exe>.manifest` into 
ONE flat dir (the test analog of `//main/idl:svidl_bundle`). Pass `data_files` 
for fixture inputs the test opens by relative path — see "working directory" 
below. |
+| `sal_process_init` | 
[//build/testsupport](../../build/testsupport/BUILD.bazel) | Migration-authored 
TU that runs `sal_detail_initialize()` from a dynamic initialiser, for suites 
whose own `main()` skips the `SAL_IMPLEMENT_MAIN` boilerplate (⇒ no 
`WSAStartup`). |
 | `libtest` | [//main/test:test](BUILD.bazel) | `test.dll` — 
`test::OfficeConnection` + arg/url helpers, for *subsequent* (UNO) tests that 
bootstrap a running soffice over URP. Built; not yet exercised. |
 | `vc90_app_manifest_res` | 
[//main/external/msvcp90](../external/msvcp90/BUILD.bazel) | The VC90-CRT 
manifest compiled to a `.res` and linked into every `gtest_test` exe at 
`RT_MANIFEST` id 1. See "the CRT activation context" below. |
 | `sal_qa_test` macro | [//main/sal:sal_qa.bzl](../sal/sal_qa.bzl) | Thin 
`gtest_test` wrapper for the sal/qa suites (common copts/deps + per-dir 
`*_Const.h` include). |
@@ -49,6 +50,9 @@ holdouts).  This brings the test layer onto Bazel so suites 
run under
      `:cppuhelper_qa_unourl`, `:cppuhelper_qa_weak`
    - `//main/binaryurp:binaryurp_tests` — `:binaryurp_qa_cache`,
      `:binaryurp_qa_unmarshal`
+   - `//main/shell:shell_qa_zip` (3) — zipfile reader over a real `.odt`
+   - `//main/sal:osl_Socket_tests`, `:osl_StreamSocket`, `:osl_DatagramSocket`,
+     `:osl_AcceptorSocket` (4 of the 8 socket suites; see the socket note 
below)
 
    **Tests with private IDL types** (cppu/qa has a `types.idl` defining
    Enum1/Struct1/Interface1/… used only by the tests): reuse the `idl_library`
@@ -109,6 +113,17 @@ holdouts).  This brings the test layer onto Bazel so 
suites run under
   (Not yet handled: under `--compilation_mode=dbg` the exes link `/MDd` but
   this `.res` still carries the *release* CRT manifest.)
 
+- **Staging a data file beside the exe is not enough — the working directory is
+  the execroot.** `bazel test` launches the test with its CWD set to the
+  execroot, *not* the exe's directory. Co-located DLLs still resolve (the 
loader
+  searches the exe's own path), which makes it easy to assume relative file
+  opens will too — they don't. A test that opens a fixture by bare relative 
name
+  (`//main/shell:shell_qa_zip` → `simpledocument.odt`) throws
+  file-not-found while passing when run by hand from the staged dir. Pass such
+  inputs as `data_files`: they are staged beside the exe *and* the target
+  switches to a `.bat` launcher that `cd`s there first and forwards the exit
+  code.
+
 - **`/Zc:wchar_t-` must be consistent across gtest and every test TU.** gtest
   declares `PrintTo(wchar_t)`; with `/Zc:wchar_t-` (`wchar_t == unsigned 
short`)
   on one side only, that mangles vs `PrintTo(unsigned short)` → `LNK2019`. 
Fixed
@@ -127,11 +142,11 @@ holdouts).  This brings the test layer onto Bazel so 
suites run under
 
 ## The sal suite is deliberately NOT a green gate
 
-`//main/sal:sal_tests` runs **every** migrated self-contained sal/qa test — 36
+`//main/sal:sal_tests` runs **every** migrated self-contained sal/qa test — 44
 targets, passing and failing alike, on the principle that failures are
 information, not something to hide (the rationale lives next to the
 `test_suite` in [main/sal/BUILD.bazel](../sal/BUILD.bazel)). So expect it to be
-red. As of 2026-08-01, 30 pass and these 6 fail, each on its **own merits** —
+red. As of 2026-08-01, 34 pass and these 10 fail, each on its **own merits** —
 none is a build or loader problem, and the source is out of scope:
 
 | Target | Failing | Why |
@@ -142,6 +157,45 @@ none is a build or loader problem, and the source is out 
of scope:
 | `rtl_logfile` | 1 | Writes/reads `c:/temp` and asserts on it — 
env/permission bound |
 | `osl_Thread` | 1 | `resume_001` is a timing race; flaky, not deterministic |
 | `rtl_OUString2` | 1 | `convertFromString` expects `\x80` to fail UTF-8 
validation — test-data drift, same class as `rtl_textcvt` |
+| `osl_SocketOld` | 10 | see socket note below |
+| `osl_SocketAddr` | 3 | see socket note below |
+| `osl_Socket2` | 7 | see socket note below |
+| `osl_ConnectorSocket` | 1 | see socket note below |
+
+### The osl/socket suites
+
+Long recorded as "blocked on a CppUnit external dep" — that was simply wrong.
+All 8 apps in `qa/osl/socket/makefile.mk` are plain GoogleTest suites with no
+testshl2 include; they only ever needed `ws2_32`.
+
+What they *did* need is `//build/testsupport:sal_process_init.cxx`. Each
+declares its own bare `main()` instead of going through `SAL_IMPLEMENT_MAIN`,
+and on Windows that macro is what calls `sal_detail_initialize()` →
+**`WSAStartup()`** (sal3.dll's `DllMain` only ever calls the matching
+`WSACleanup()`, never `WSAStartup`). Without it Winsock is never initialised,
+every osl socket call returns `WSANOTINITIALISED`, and the suites collapse in
+ways that implicate everything except the real cause — `SocketAddr`
+constructors quietly yield unusable addresses, `getLocalHostname()` fails.
+These are testshl2-era suites; that harness used to supply `main()` for them.
+The shim does the init from a dynamic initialiser (which the CRT runs before
+`main`), using `__argc`/`__argv` — `osl_setCommandArgs` asserts `argc > 0`.
+
+With it, 4 of the 8 are fully green (`osl_Socket_tests`, `osl_StreamSocket`,
+`osl_DatagramSocket`, `osl_AcceptorSocket`) and the rest go from
+near-total failure to a small residual set — none of it a build problem:
+
+- **Upstream already knew.** `connect_003` and `getLocalHost_001` are listed in
+  the module's own `.xsce` exclusion files *specifically for `wntmsci`*, our
+  exact platform; `ctors_family_Ipx` (IPX is dead on modern Windows) and
+  `getHostname_002` are excluded on every platform.
+- **Needs Administrator.** `ctors_TypeRaw` / `getType_003` create a
+  `osl_Socket_TypeRaw` socket — privileged on Windows. The test's own message
+  admits it doesn't pass on Linux/Solaris either.
+- **Unsupported socket option.** `setOption_001` / `getOption_simple_001` set
+  `SO_DONTROUTE`; the test even comments "maybe asAcceptorSocket is not right
+  initialized".
+- **DNS/host dependent.** `getHostname_001`, `getSocketAddrHandle_002`,
+  `getLocalPort_002` resolve names against whatever network the machine is on.
 
 Earlier revisions of this file listed `rtl_str`/`rtl_ustr`/`rtl_string` as
 NULL-deref crashes; those were since fixed (boundary checks in the tests plus
@@ -150,8 +204,15 @@ NULL-deref crashes; those were since fixed (boundary 
checks in the tests plus
 (`osl_Security` is not in the suite at all — it fails to *build* on testshl2,
 see the gotcha above; it is unwired entirely, not an exclusion.)
 
-Still unwired: cppunit suites (`osl/socket`, `rtl_strings`) → need a CppUnit
-external dep; child-process tests (`osl/process`, `rtl/bootstrap`,
+`rtl_strings` was also filed under "needs CppUnit". It does not: it includes
+`testshl/tresstatewrapper.hxx`, i.e. the retired **testshl** harness, and its 
own
+`readme.txt` says it is "the old test implementation of rtl::XString",
+superseded by `sal/qa/rtl/ostring` + `sal/qa/rtl/oustring` — both of which are
+already wired (`rtl_OString2`, `rtl_str`, `rtl_string`, `rtl_OUString2`,
+`rtl_ustr`). So it is **dead weight, not a blocker**; there is nothing to gain
+by migrating it.
+
+Still unwired: child-process tests (`osl/process`, `rtl/bootstrap`,
 `rtl/process`) → they resolve their helper exe via 
`getExecutablePath()`+`"/../bin"`
 (the dmake `solver/bin` layout), which flat Bazel staging can't satisfy without
 source changes — `gtest_test` has a `companions` hook ready for when that 
layout

Reply via email to