Provides a clean, Java-friendly interface to the gopher-orch agent functionality. + * + *
Example: + * + *
{@code
+ * // Create an agent with API key
+ * GopherAgent agent = GopherAgent.create(
+ * GopherAgentConfig.builder()
+ * .provider("AnthropicProvider")
+ * .model("claude-3-haiku-20240307")
+ * .apiKey("your-api-key")
+ * .build()
+ * );
+ *
+ * // Run a query
+ * String answer = agent.run("What time is it in Tokyo?");
+ * System.out.println(answer);
+ *
+ * // Cleanup (optional - happens automatically on close)
+ * agent.dispose();
+ * }
+ *
+ * Or use try-with-resources for automatic cleanup: + * + *
{@code
+ * try (GopherAgent agent = GopherAgent.create(config)) {
+ * String answer = agent.run("What time is it in Tokyo?");
+ * System.out.println(answer);
+ * }
+ * }
+ */
+public class GopherAgent implements AutoCloseable {
+
+ private static final AtomicBoolean initialized = new AtomicBoolean(false);
+ private static final AtomicBoolean cleanupHandlerRegistered = new AtomicBoolean(false);
+
+ private final Pointer handle;
+ private final AtomicBoolean disposed = new AtomicBoolean(false);
+
+ private GopherAgent(Pointer handle) {
+ this.handle = handle;
+ }
+
+ /**
+ * Initialize the gopher-orch library.
+ *
+ * Must be called before creating any agents. Called automatically by create() if not already + * initialized. + * + * @throws AgentException if initialization fails + */ + public static synchronized void init() { + if (initialized.get()) { + return; + } + + GopherOrchLibrary lib = GopherOrchLibrary.getInstance(); + if (lib == null) { + throw new AgentException("Failed to load gopher-orch native library"); + } + + initialized.set(true); + setupCleanupHandler(); + } + + /** + * Shutdown the gopher-orch library. + * + *
Called automatically on JVM shutdown, but can be called manually.
+ */
+ public static synchronized void shutdown() {
+ initialized.set(false);
+ }
+
+ /** Check if the library is initialized. */
+ public static boolean isInitialized() {
+ return initialized.get();
+ }
+
+ /**
+ * Create a new GopherAgent instance.
+ *
+ * @param config Agent configuration
+ * @return GopherAgent instance
+ * @throws AgentException if agent creation fails
+ */
+ public static GopherAgent create(GopherAgentConfig config) {
+ if (!initialized.get()) {
+ init();
+ }
+
+ GopherOrchLibrary lib = GopherOrchLibrary.getInstance();
+ if (lib == null) {
+ throw new AgentException("Native library not available");
+ }
+
+ Pointer handle;
+ try {
+ if (config.hasApiKey()) {
+ handle =
+ lib.gopher_orch_agent_create_by_api_key(
+ config.getProvider(),
+ config.getModel(),
+ config.getApiKey().orElseThrow());
+ } else {
+ handle =
+ lib.gopher_orch_agent_create_by_json(
+ config.getProvider(),
+ config.getModel(),
+ config.getServerConfig().orElseThrow());
+ }
+ } catch (Exception e) {
+ throw new AgentException("Failed to create agent: " + e.getMessage(), e);
+ }
+
+ if (handle == null || handle == Pointer.NULL) {
+ String error = GopherOrchLibrary.getLastError();
+ lib.gopher_orch_clear_error();
+ throw new AgentException(error != null ? error : "Failed to create agent");
+ }
+
+ return new GopherAgent(handle);
+ }
+
+ /**
+ * Create a new GopherAgent with API key.
+ *
+ * @param provider Provider name (e.g., "AnthropicProvider")
+ * @param model Model name (e.g., "claude-3-haiku-20240307")
+ * @param apiKey API key for fetching remote server config
+ * @return GopherAgent instance
+ */
+ public static GopherAgent create(String provider, String model, String apiKey) {
+ return create(
+ GopherAgentConfig.builder().provider(provider).model(model).apiKey(apiKey).build());
+ }
+
+ /**
+ * Create a new GopherAgent with JSON server config.
+ *
+ * @param provider Provider name (e.g., "AnthropicProvider")
+ * @param model Model name (e.g., "claude-3-haiku-20240307")
+ * @param serverConfig JSON server configuration
+ * @return GopherAgent instance
+ */
+ public static GopherAgent createWithServerConfig(
+ String provider, String model, String serverConfig) {
+ return create(
+ GopherAgentConfig.builder()
+ .provider(provider)
+ .model(model)
+ .serverConfig(serverConfig)
+ .build());
+ }
+
+ /**
+ * Run a query against the agent.
+ *
+ * @param query The user query to process
+ * @return The agent's response
+ * @throws AgentException if the query fails
+ */
+ public String run(String query) {
+ return run(query, 60000);
+ }
+
+ /**
+ * Run a query against the agent with custom timeout.
+ *
+ * @param query The user query to process
+ * @param timeoutMs Timeout in milliseconds
+ * @return The agent's response
+ * @throws AgentException if the query fails
+ */
+ public String run(String query, long timeoutMs) {
+ ensureNotDisposed();
+
+ GopherOrchLibrary lib = GopherOrchLibrary.getInstance();
+ if (lib == null) {
+ throw new AgentException("Native library not available");
+ }
+
+ try {
+ String response = lib.gopher_orch_agent_run(handle, query, timeoutMs);
+ if (response == null) {
+ return "No response for query: \"" + query + "\"";
+ }
+ return response;
+ } catch (Exception e) {
+ throw new AgentException("Query execution failed: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Run a query with detailed result information.
+ *
+ * @param query The user query to process
+ * @return AgentResult with response and metadata
+ */
+ public AgentResult runDetailed(String query) {
+ return runDetailed(query, 60000);
+ }
+
+ /**
+ * Run a query with detailed result information and custom timeout.
+ *
+ * @param query The user query to process
+ * @param timeoutMs Timeout in milliseconds
+ * @return AgentResult with response and metadata
+ */
+ public AgentResult runDetailed(String query, long timeoutMs) {
+ try {
+ String response = run(query, timeoutMs);
+ return AgentResult.builder()
+ .response(response)
+ .status(AgentResultStatus.SUCCESS)
+ .iterationCount(1)
+ .tokensUsed(0)
+ .build();
+ } catch (TimeoutException e) {
+ return AgentResult.timeout(e.getMessage());
+ } catch (Exception e) {
+ return AgentResult.error(e.getMessage());
+ }
+ }
+
+ /** Dispose of the agent and free resources. */
+ public void dispose() {
+ if (disposed.compareAndSet(false, true)) {
+ GopherOrchLibrary lib = GopherOrchLibrary.getInstance();
+ if (lib != null && handle != null) {
+ lib.gopher_orch_agent_release(handle);
+ }
+ }
+ }
+
+ /** Check if agent is disposed. */
+ public boolean isDisposed() {
+ return disposed.get();
+ }
+
+ /** AutoCloseable implementation - calls dispose(). */
+ @Override
+ public void close() {
+ dispose();
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ dispose();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ private void ensureNotDisposed() {
+ if (disposed.get()) {
+ throw new AgentException("Agent has been disposed");
+ }
+ }
+
+ private static void setupCleanupHandler() {
+ if (cleanupHandlerRegistered.compareAndSet(false, true)) {
+ Runtime.getRuntime()
+ .addShutdownHook(
+ new Thread(
+ () -> {
+ shutdown();
+ },
+ "gopher-orch-shutdown"));
+ }
+ }
+}
diff --git a/src/main/java/com/gophersecurity/orch/GopherAgentConfig.java b/src/main/java/com/gophersecurity/orch/GopherAgentConfig.java
new file mode 100644
index 00000000..84f19ada
--- /dev/null
+++ b/src/main/java/com/gophersecurity/orch/GopherAgentConfig.java
@@ -0,0 +1,92 @@
+package com.gophersecurity.orch;
+
+import java.util.Objects;
+import java.util.Optional;
+
+/** Configuration options for creating a GopherAgent. */
+public final class GopherAgentConfig {
+
+ private final String provider;
+ private final String model;
+ private final String apiKey;
+ private final String serverConfig;
+
+ private GopherAgentConfig(Builder builder) {
+ this.provider = Objects.requireNonNull(builder.provider, "Provider is required");
+ this.model = Objects.requireNonNull(builder.model, "Model is required");
+ this.apiKey = builder.apiKey;
+ this.serverConfig = builder.serverConfig;
+
+ if (apiKey == null && serverConfig == null) {
+ throw new IllegalArgumentException("Either apiKey or serverConfig is required");
+ }
+ if (apiKey != null && serverConfig != null) {
+ throw new IllegalArgumentException("Cannot specify both apiKey and serverConfig");
+ }
+ }
+
+ public String getProvider() {
+ return provider;
+ }
+
+ public String getModel() {
+ return model;
+ }
+
+ public Optional These tests require the native library to be built and available.
+ */
+class GopherAgentIntegrationTest {
+
+ private static final String SERVER_CONFIG =
+ "{"
+ + "\"succeeded\": true,"
+ + "\"code\": 200000000,"
+ + "\"message\": \"success\","
+ + "\"data\": {"
+ + " \"servers\": ["
+ + " {"
+ + " \"version\": \"2025-01-09\","
+ + " \"serverId\": \"1\","
+ + " \"name\": \"test-server\","
+ + " \"transport\": \"http_sse\","
+ + " \"config\": {\"url\": \"http://127.0.0.1:9999/mcp\", \"headers\": {}},"
+ + " \"connectTimeout\": 5000,"
+ + " \"requestTimeout\": 30000"
+ + " }"
+ + " ]"
+ + "}"
+ + "}";
+
+ /** Check if native library is available for tests. */
+ static boolean isNativeLibraryAvailable() {
+ return GopherOrchLibrary.isAvailable();
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testInitialization() {
+ // Test that initialization works
+ GopherAgent.init();
+ assertTrue(GopherAgent.isInitialized());
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testCreateAgentWithServerConfig() {
+ // Test creating agent with server config through FFI
+ GopherAgentConfig config =
+ GopherAgentConfig.builder()
+ .provider("AnthropicProvider")
+ .model("claude-3-haiku-20240307")
+ .serverConfig(SERVER_CONFIG)
+ .build();
+
+ GopherAgent agent = null;
+ try {
+ agent = GopherAgent.create(config);
+ assertNotNull(agent, "Agent should be created");
+ assertFalse(agent.isDisposed(), "Agent should not be disposed");
+ } catch (AgentException e) {
+ // Agent creation may fail without API key - this is expected in test environment
+ Assumptions.assumeTrue(false, "Skipping test: " + e.getMessage());
+ } finally {
+ if (agent != null) {
+ agent.dispose();
+ assertTrue(agent.isDisposed(), "Agent should be disposed after dispose()");
+ }
+ }
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testCreateAgentWithHelperMethod() {
+ // Test the convenience method
+ GopherAgent agent = tryCreateAgent();
+ try {
+ assertNotNull(agent);
+ } finally {
+ if (agent != null) {
+ agent.dispose();
+ }
+ }
+ }
+
+ /**
+ * Helper method to create an agent, skipping test if creation fails. Agent creation may fail
+ * without API key or network access.
+ */
+ private GopherAgent tryCreateAgent() {
+ try {
+ return GopherAgent.createWithServerConfig(
+ "AnthropicProvider", "claude-3-haiku-20240307", SERVER_CONFIG);
+ } catch (AgentException e) {
+ Assumptions.assumeTrue(
+ false, "Skipping test - agent creation failed: " + e.getMessage());
+ return null; // Never reached
+ }
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testTryWithResources() {
+ // Test AutoCloseable implementation
+ GopherAgent capturedAgent = null;
+ try (GopherAgent agent = tryCreateAgent()) {
+ assertNotNull(agent);
+ assertFalse(agent.isDisposed());
+ capturedAgent = agent;
+ }
+ // After try-with-resources, agent should be disposed
+ assertNotNull(capturedAgent);
+ assertTrue(capturedAgent.isDisposed());
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testDisposeIdempotent() {
+ // Test that dispose can be called multiple times safely
+ GopherAgent agent = tryCreateAgent();
+
+ agent.dispose();
+ assertTrue(agent.isDisposed());
+
+ // Second dispose should not throw
+ agent.dispose();
+ assertTrue(agent.isDisposed());
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testRunAfterDisposeThrows() {
+ GopherAgent agent = tryCreateAgent();
+ agent.dispose();
+
+ // Running on disposed agent should throw
+ assertThrows(
+ AgentException.class,
+ () -> {
+ agent.run("test query");
+ });
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testRunDetailedReturnsResult() {
+ try (GopherAgent agent = tryCreateAgent()) {
+ // Run with very short timeout to get quick response (likely timeout or error)
+ AgentResult result = agent.runDetailed("test query", 100);
+
+ assertNotNull(result, "Result should not be null");
+ assertNotNull(result.getResponse(), "Response should not be null");
+ assertNotNull(result.getStatus(), "Status should not be null");
+ }
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testMultipleAgentsCanBeCreated() {
+ GopherAgent agent1 = null;
+ GopherAgent agent2 = null;
+
+ try {
+ agent1 = tryCreateAgent();
+ agent2 = tryCreateAgent();
+
+ assertNotNull(agent1);
+ assertNotNull(agent2);
+ assertNotSame(agent1, agent2, "Should be different agent instances");
+ } finally {
+ if (agent1 != null) agent1.dispose();
+ if (agent2 != null) agent2.dispose();
+ }
+ }
+
+ @Test
+ void testCreateWithoutNativeLibraryThrows() {
+ // This test verifies error handling when native library is not available
+ // Skip if library IS available (we're testing the error case)
+ if (GopherOrchLibrary.isAvailable()) {
+ // Library is available, so we can't test the "not available" case
+ // Just verify that create works (or gracefully fails without API key)
+ try {
+ GopherAgent agent =
+ GopherAgent.createWithServerConfig(
+ "AnthropicProvider", "claude-3-haiku-20240307", SERVER_CONFIG);
+ agent.dispose();
+ } catch (AgentException e) {
+ // Expected if no API key is available
+ }
+ }
+ // If library is not available, init() would throw AgentException
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testShutdownAndReinit() {
+ // Test that shutdown and re-init work correctly
+ GopherAgent.init();
+ assertTrue(GopherAgent.isInitialized());
+
+ GopherAgent.shutdown();
+ assertFalse(GopherAgent.isInitialized());
+
+ // Re-init should work
+ GopherAgent.init();
+ assertTrue(GopherAgent.isInitialized());
+ }
+}
diff --git a/src/test/java/com/gophersecurity/orch/ffi/GopherOrchLibraryTest.java b/src/test/java/com/gophersecurity/orch/ffi/GopherOrchLibraryTest.java
new file mode 100644
index 00000000..50d47a13
--- /dev/null
+++ b/src/test/java/com/gophersecurity/orch/ffi/GopherOrchLibraryTest.java
@@ -0,0 +1,202 @@
+package com.gophersecurity.orch.ffi;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIf;
+
+import com.sun.jna.Pointer;
+
+/**
+ * Tests for FFI bindings to the native gopher-orch library.
+ *
+ * These tests verify that the Java side can correctly call C++ functions through JNA FFI
+ * bindings.
+ */
+class GopherOrchLibraryTest {
+
+ /** Check if native library is available for tests. */
+ static boolean isNativeLibraryAvailable() {
+ return GopherOrchLibrary.isAvailable();
+ }
+
+ @Test
+ void testLibraryIsAvailable() {
+ // This test verifies that the native library can be loaded
+ boolean available = GopherOrchLibrary.isAvailable();
+ assertTrue(
+ available,
+ "Native library should be available. "
+ + "Make sure to run ./build.sh first to build the native library.");
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testGetInstance() {
+ GopherOrchLibrary lib = GopherOrchLibrary.getInstance();
+ assertNotNull(lib, "Library instance should not be null");
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testAgentCreateByJsonWithValidConfig() {
+ GopherOrchLibrary lib = GopherOrchLibrary.getInstance();
+ assertNotNull(lib);
+
+ // Valid server configuration JSON
+ String serverConfig =
+ "{"
+ + "\"succeeded\": true,"
+ + "\"code\": 200000000,"
+ + "\"message\": \"success\","
+ + "\"data\": {"
+ + " \"servers\": ["
+ + " {"
+ + " \"version\": \"2025-01-09\","
+ + " \"serverId\": \"1\","
+ + " \"name\": \"test-server\","
+ + " \"transport\": \"http_sse\","
+ + " \"config\": {\"url\": \"http://127.0.0.1:9999/mcp\", \"headers\": {}},"
+ + " \"connectTimeout\": 5000,"
+ + " \"requestTimeout\": 30000"
+ + " }"
+ + " ]"
+ + "}"
+ + "}";
+
+ // Call native function to create agent
+ Pointer handle =
+ lib.gopher_orch_agent_create_by_json(
+ "AnthropicProvider", "claude-3-haiku-20240307", serverConfig);
+
+ // Agent should be created (handle may be null if no API key, but function should not crash)
+ // The important thing is that the FFI call works without throwing
+ if (handle != null && handle != Pointer.NULL) {
+ // Clean up if agent was created
+ lib.gopher_orch_agent_release(handle);
+ }
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testAgentCreateByJsonWithEmptyConfig() {
+ GopherOrchLibrary lib = GopherOrchLibrary.getInstance();
+ assertNotNull(lib);
+
+ // Empty/invalid config should return null handle
+ Pointer handle =
+ lib.gopher_orch_agent_create_by_json(
+ "AnthropicProvider", "claude-3-haiku-20240307", "{}");
+
+ // Should handle gracefully (null or valid pointer, but no crash)
+ if (handle != null && handle != Pointer.NULL) {
+ lib.gopher_orch_agent_release(handle);
+ }
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testAgentCreateByApiKey() {
+ GopherOrchLibrary lib = GopherOrchLibrary.getInstance();
+ assertNotNull(lib);
+
+ // Call with a dummy API key - should not crash
+ Pointer handle =
+ lib.gopher_orch_agent_create_by_api_key(
+ "AnthropicProvider", "claude-3-haiku-20240307", "test-api-key-12345");
+
+ // May return null if API key is invalid, but should not crash
+ if (handle != null && handle != Pointer.NULL) {
+ lib.gopher_orch_agent_release(handle);
+ }
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testLastErrorAndClearError() {
+ GopherOrchLibrary lib = GopherOrchLibrary.getInstance();
+ assertNotNull(lib);
+
+ // Try to get last error (may be null if no error)
+ try {
+ GopherOrchLibrary.GopherOrchErrorInfo.ByReference errorInfo =
+ lib.gopher_orch_last_error();
+ // errorInfo may be null or have null message if no error
+ } catch (Exception e) {
+ fail("gopher_orch_last_error should not throw: " + e.getMessage());
+ }
+
+ // Clear error should not throw
+ try {
+ lib.gopher_orch_clear_error();
+ } catch (Exception e) {
+ fail("gopher_orch_clear_error should not throw: " + e.getMessage());
+ }
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testApiFetchServers() {
+ GopherOrchLibrary lib = GopherOrchLibrary.getInstance();
+ assertNotNull(lib);
+
+ // Call with dummy API key - should return JSON (possibly error response)
+ try {
+ String result = lib.gopher_orch_api_fetch_servers("test-api-key");
+ // Result may be null or contain error, but should not crash
+ } catch (Exception e) {
+ fail("gopher_orch_api_fetch_servers should not throw: " + e.getMessage());
+ }
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testAgentRunWithNullHandle() {
+ GopherOrchLibrary lib = GopherOrchLibrary.getInstance();
+ assertNotNull(lib);
+
+ // Running with null handle should be handled gracefully
+ try {
+ String result = lib.gopher_orch_agent_run(null, "test query", 1000);
+ // May return null or error message, but should not crash
+ } catch (Exception e) {
+ // Exception is acceptable for null handle
+ }
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testAgentReleaseWithNullHandle() {
+ GopherOrchLibrary lib = GopherOrchLibrary.getInstance();
+ assertNotNull(lib);
+
+ // Releasing null handle should be handled gracefully
+ try {
+ lib.gopher_orch_agent_release(null);
+ } catch (Exception e) {
+ // Exception is acceptable for null handle
+ }
+ }
+
+ @Test
+ @EnabledIf("isNativeLibraryAvailable")
+ void testFreeWithNullPointer() {
+ GopherOrchLibrary lib = GopherOrchLibrary.getInstance();
+ assertNotNull(lib);
+
+ // Free with null should be handled gracefully
+ try {
+ lib.gopher_orch_free(null);
+ } catch (Exception e) {
+ // Exception is acceptable for null pointer
+ }
+ }
+
+ @Test
+ void testGetLastErrorWhenLibraryNotLoaded() {
+ // This tests the static helper method
+ String error = GopherOrchLibrary.getLastError();
+ // Should return null gracefully, not throw
+ // (error may be null or a message depending on state)
+ }
+}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
deleted file mode 100644
index 88a9c7d4..00000000
--- a/tests/CMakeLists.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-# gopher-orch tests
-
-# Test utilities and helpers
-set(TEST_UTIL_SOURCES
- # test_utils.cpp
-)
-
-# Orch-specific core tests
-set(ORCH_CORE_TEST_SOURCES
- orch/hello_test.cpp
-)
-
-# Helper function to create orch test executables
-function(add_orch_test test_name test_sources)
- add_executable(${test_name} ${test_sources} ${TEST_UTIL_SOURCES})
- # Use static library for tests to avoid duplicate symbol issues
- if(TARGET gopher-orch-static)
- set(GOPHER_ORCH_TEST_LIB gopher-orch-static)
- else()
- set(GOPHER_ORCH_TEST_LIB gopher-orch)
- endif()
- target_link_libraries(${test_name}
- ${GOPHER_ORCH_TEST_LIB}
- ${GOPHER_MCP_LIBRARIES}
- GTest::gtest
- GTest::gtest_main
- GTest::gmock
- Threads::Threads
- )
- target_include_directories(${test_name} PRIVATE
- ${CMAKE_SOURCE_DIR}/include
- ${CMAKE_SOURCE_DIR}/tests
- ${GOPHER_MCP_INCLUDE_DIR}
- )
-
- # Add test to CTest
- gtest_discover_tests(${test_name}
- WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
- PROPERTIES LABELS ${ARGN}
- )
-endfunction()
-
-# Create individual orch test executables
-add_orch_test(hello_test "${ORCH_CORE_TEST_SOURCES}" "orch")
-
-# Create a combined orch test executable for convenience
-add_executable(gopher-orch-tests
- ${ORCH_CORE_TEST_SOURCES}
- ${TEST_UTIL_SOURCES}
-)
-
-# Use static library for tests to avoid duplicate symbol issues
-if(TARGET gopher-orch-static)
- set(GOPHER_ORCH_TEST_LIB gopher-orch-static)
-else()
- set(GOPHER_ORCH_TEST_LIB gopher-orch)
-endif()
-
-target_link_libraries(gopher-orch-tests
- ${GOPHER_ORCH_TEST_LIB}
- ${GOPHER_MCP_LIBRARIES}
- GTest::gtest
- GTest::gtest_main
- GTest::gmock
- Threads::Threads
-)
-
-target_include_directories(gopher-orch-tests PRIVATE
- ${CMAKE_SOURCE_DIR}/include
- ${CMAKE_SOURCE_DIR}/tests
- ${GOPHER_MCP_INCLUDE_DIR}
-)
-
-# Custom test targets
-add_custom_target(test-verbose
- COMMAND ${CMAKE_CTEST_COMMAND} -V
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-)
-
-add_custom_target(test-parallel
- COMMAND ${CMAKE_CTEST_COMMAND} -j${CMAKE_BUILD_PARALLEL_LEVEL}
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-)
diff --git a/tests/orch/hello_test.cpp b/tests/orch/hello_test.cpp
deleted file mode 100644
index a6672772..00000000
--- a/tests/orch/hello_test.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-#include "orch/core/hello.h"
-
-#include