Fix assertions that NDEBUG deleted, and match OBS's real macOS SDK regex
test_core.cpp used bare assert(). CI builds Release, Release defines NDEBUG, and NDEBUG compiles assert() out entirely -- so that suite had been passing unconditionally, checking nothing. It now uses the same always-live ST_ASSERT harness as the other suites and reports a count (10 checks), and additionally asserts that core_version() really is the version CMake injected rather than a stale literal. macOS SDK, third iteration. The previous fix assumed OBS only wanted a version-carrying SDK filename. Reading OBS 30.0.2's cmake/macos/compilerconfig.cmake shows the actual pattern is stricter: ".+/MacOSX.platform/Developer/SDKs/MacOSX([0-9]+\.[0-9])+\.sdk$" which only ever matches a full-Xcode SDK path. A Command-Line-Tools-only install keeps its SDK at /Library/Developer/CommandLineTools/SDKs/MacOSX<ver>.sdk, with no MacOSX.platform/Developer/SDKs segment at all, so it can never match however it is named -- which is why the second attempt got past the "REGEX needs at least 5 arguments" error and still landed on "Your macOS SDK version () is too low", with the version still empty. _resolve_versioned_macos_sdk now builds a symlink tree under .deps/ whose shape matches that pattern and which points at exactly the same SDK, and uses the toolchain's own path untouched when it already matches (i.e. when real Xcode is installed). Nothing about the compilation changes -- only the spelling of the path, which is all OBS's check reads. Also refreshes the scaffold-era comments in core.h and core_c.h, which still described this library as a placeholder that would one day talk to livekit-ffi. Linux CI is green on the previous commit: real libobs adapter linked (ldd shows libobs.so.0 plus liblivekit/liblivekit_ffi resolving from the staged package directory), obs_module_load exported, ctest 6/6, artifact uploaded. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
This commit is contained in:
@@ -20,32 +20,23 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
|
||||
#include <string>
|
||||
|
||||
// C++ API for the core library. Per the design doc
|
||||
// (docs/superpowers/specs/2026-09-06-obs-camera-plugin-design.md in the
|
||||
// streamer-tools repo), this library will eventually own: streamer-tools
|
||||
// API auth, LiveKit FFI session management (connect, subscribe, decode,
|
||||
// reconnect), and frame callbacks -- all with zero OBS dependency, so it
|
||||
// can be built and tested headlessly.
|
||||
//
|
||||
// THIS IS SCAFFOLDING. Nothing below talks to a real server or to
|
||||
// livekit-ffi yet. It exists to prove the core-library/OBS-adapter split
|
||||
// builds, links, and is unit-testable, ahead of a later phase that
|
||||
// implements the real logic.
|
||||
// The small shared pieces of the core library: its version string, and the
|
||||
// streamer-tools connection settings that both the API client and the OBS
|
||||
// adapter pass around. Everything substantial lives in its own header --
|
||||
// api_client.h, session.h, http.h, json.h -- and none of it depends on OBS,
|
||||
// so the whole library builds and tests headlessly on all three platforms.
|
||||
|
||||
namespace stplugin {
|
||||
|
||||
// Returns the core library's version string. Placeholder for a real
|
||||
// version scheme once the library does something.
|
||||
// The core library's version string, injected by CMake from the top-level
|
||||
// project() version, so what OBS logs on load is the actual build.
|
||||
const char *core_version();
|
||||
|
||||
// Minimal connection configuration the future core library will use to
|
||||
// authenticate against the streamer-tools API
|
||||
// (see apps/server/src/rooms/join.routes.ts and
|
||||
// apps/server/src/livekit/tokens.ts in the streamer-tools repo for the
|
||||
// existing read-key-authed token pattern this will follow) and mint a
|
||||
// scoped LiveKit subscriber token. Validation here is intentionally
|
||||
// trivial -- it exists to prove the core library is unit-testable
|
||||
// headlessly, not to implement the real API client.
|
||||
// What an operator types into the source's properties, and what ApiClient
|
||||
// needs to reach the two read-key-scoped endpoints in
|
||||
// apps/server/src/obs/plugin.routes.ts (streamer-tools repo). The read key is
|
||||
// a credential: it is masked in the properties UI and never logged (see
|
||||
// ApiClient::redactedUrl).
|
||||
struct ConnectionConfig {
|
||||
std::string server_url;
|
||||
std::string room_slug;
|
||||
|
||||
@@ -18,15 +18,13 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
|
||||
#pragma once
|
||||
|
||||
// Minimal C ABI surface of the core library, for the OBS adapter (plain
|
||||
// C, per the obs-plugintemplate convention) to call into the core
|
||||
// library (C++) without needing a C++ compiler in that translation unit.
|
||||
// A minimal C ABI over the core library's version string.
|
||||
//
|
||||
// This mirrors the boundary the real integration will cross in the
|
||||
// other direction: livekit-ffi is a Rust library exposing a C ABI that
|
||||
// the C++ core library will link against. Proving a small, deliberate
|
||||
// C ABI seam works cleanly here is part of what this scaffold is for.
|
||||
|
||||
// The OBS adapter is C++ and calls stplugin::core_version() directly, so
|
||||
// nothing in this repository needs this header today. It is kept because it
|
||||
// is the seam a plain-C consumer would use, and because the unit tests assert
|
||||
// the two entry points agree -- which is a cheap check that the C++ library
|
||||
// really is linkable from a C translation unit.
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,9 @@ function(stplugin_add_test name)
|
||||
endfunction()
|
||||
|
||||
stplugin_add_test(test_core)
|
||||
target_compile_definitions(test_core PRIVATE
|
||||
STPLUGIN_EXPECTED_CORE_VERSION="${PROJECT_VERSION}"
|
||||
)
|
||||
stplugin_add_test(test_json)
|
||||
stplugin_add_test(test_api_client)
|
||||
stplugin_add_test(test_session)
|
||||
|
||||
+31
-27
@@ -16,44 +16,48 @@ You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
// Deliberately dependency-free (no gtest/catch2 etc.) so this test target
|
||||
// has no network fetch or package-manager step in CI -- proving the
|
||||
// "core library builds and tests headlessly, no OBS required" claim
|
||||
// without adding another moving part to this scaffolding pass.
|
||||
// NOTE on why this file uses ST_ASSERT and not assert(): CI builds Release,
|
||||
// which defines NDEBUG, which compiles every bare assert() out entirely. This
|
||||
// suite previously passed unconditionally for exactly that reason. The
|
||||
// ST_ASSERT macros in test_util.h are always live and report a pass/fail
|
||||
// count.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include "stplugin/core.h"
|
||||
#include "stplugin/core_c.h"
|
||||
#include "test_util.h"
|
||||
|
||||
int main() {
|
||||
// core_version() should return a non-empty string, via both the
|
||||
// C++ API and the C ABI wrapper the OBS adapter will actually call.
|
||||
int main()
|
||||
{
|
||||
// The version string comes through both the C++ API and the C ABI
|
||||
// wrapper, and the two must agree.
|
||||
const char *cpp_version = stplugin::core_version();
|
||||
assert(cpp_version != nullptr);
|
||||
assert(std::strlen(cpp_version) > 0);
|
||||
ST_ASSERT(cpp_version != nullptr);
|
||||
ST_ASSERT(cpp_version != nullptr && std::strlen(cpp_version) > 0);
|
||||
|
||||
const char *c_version = stplugin_core_version();
|
||||
assert(c_version != nullptr);
|
||||
assert(std::strcmp(cpp_version, c_version) == 0);
|
||||
ST_ASSERT(c_version != nullptr);
|
||||
ST_ASSERT_EQ(std::string(cpp_version ? cpp_version : ""), std::string(c_version ? c_version : ""));
|
||||
|
||||
// ConnectionConfig::is_valid() -- trivial non-empty checks, but
|
||||
// exercised through all four combinations to prove the core library
|
||||
// is genuinely testable in isolation.
|
||||
stplugin::ConnectionConfig valid{"https://streamers.example.com", "main-room", "readkey123"};
|
||||
assert(valid.is_valid());
|
||||
// It is the version CMake injected, not a hand-maintained literal.
|
||||
ST_ASSERT_EQ(std::string(cpp_version ? cpp_version : ""), std::string(STPLUGIN_EXPECTED_CORE_VERSION));
|
||||
|
||||
stplugin::ConnectionConfig missing_url{"", "main-room", "readkey123"};
|
||||
assert(!missing_url.is_valid());
|
||||
// ConnectionConfig::is_valid(): all three fields are required. Named
|
||||
// locals rather than braced temporaries inline, because the commas inside
|
||||
// a braced initialiser would be read as macro argument separators.
|
||||
const stplugin::ConnectionConfig complete{"https://streamers.example.com", "main-room", "readkey123"};
|
||||
const stplugin::ConnectionConfig no_url{"", "main-room", "readkey123"};
|
||||
const stplugin::ConnectionConfig no_slug{"https://streamers.example.com", "", "readkey123"};
|
||||
const stplugin::ConnectionConfig no_key{"https://streamers.example.com", "main-room", ""};
|
||||
const stplugin::ConnectionConfig empty;
|
||||
|
||||
stplugin::ConnectionConfig missing_slug{"https://streamers.example.com", "", "readkey123"};
|
||||
assert(!missing_slug.is_valid());
|
||||
ST_ASSERT(complete.is_valid());
|
||||
ST_ASSERT(!no_url.is_valid());
|
||||
ST_ASSERT(!no_slug.is_valid());
|
||||
ST_ASSERT(!no_key.is_valid());
|
||||
ST_ASSERT(!empty.is_valid());
|
||||
|
||||
stplugin::ConnectionConfig missing_key{"https://streamers.example.com", "main-room", ""};
|
||||
assert(!missing_key.is_valid());
|
||||
|
||||
std::printf("core: all tests passed\n");
|
||||
return 0;
|
||||
return st_test_report("core");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user