mirror of
https://github.com/vxcontrol/langchaingo.git
synced 2026-07-21 08:55:25 -04:00
99951bca92
* build: add examples-updater tool and update examples to v0.1.14-pre.1 Add a new tool to automate updating langchaingo version references in example projects and use it to update all examples to v0.1.14-pre.1. The tool also removes temporary replace directives that are no longer needed. - Add update-examples Makefile target that runs the new tool - Create internal/devtools/examples-updater implementation - Update all example go.mod files to reference v0.1.14-pre.1 - Remove replace directives in googleai and vertex examples - Update dependencies in main go.mod/go.sum * httprr: improve header normalization and test container setup Add header normalization to make HTTP recordings more stable: - Add normalizeGoogleAPIClientHeader and normalizeVersionHeader functions - Normalize User-Agent, x-goog-api-client and other version headers - Remove OpenAI-Project header for consistency - Preserve body for both replay lookup and recording - Add comprehensive tests for header normalization Improve testcontainer environment detection: - Better handling of non-standard Docker socket paths - Disable Ryuk reaper by default for resource efficiency - Add verbose logging option via environment variable * httputil: add ApiKeyTransport for query parameter API keys Add a reusable ApiKeyTransport that adds API keys to URL query parameters: - Create ApiKeyTransport implementation in httputil package - Add comprehensive tests for the new transport - Refactor googleai_test.go to use the shared transport - Update chains/llm_test.go to use ApiKeyTransport with proper key scrubbing This improves how API keys are handled with client libraries that don't properly set keys when using custom HTTP clients, particularly useful with httprr for testing Google API integrations. * openai: remove duplicate MaxTokens field assignment Remove redundant assignment where both MaxTokens and MaxCompletionTokens were being set to the same value. MaxCompletionTokens is the preferred field name that reflects OpenAI's API changes, while MaxTokens was previously kept for backward compatibility. * vectorstores/maridadb: add test infrastructure for MariaDB vectorstore Add TestMain function for MariaDB vectorstore tests that ensures the proper test environment is set up using the testctr package. This enables consistent test container setup and teardown for MariaDB integration tests. * all: normalize all httprr recordings for consistency Update test recordings across all packages to use normalized headers: - Standardize User-Agent to 'langchaingo-httprr' - Normalize version information in x-goog-api-client headers - Remove OpenAI-Project headers for consistency - Fix deprecated Anthropic completion API tests - Update HuggingFace test recordings with valid responses These changes make test recordings stable across dependency updates and different environments, preventing test failures from version changes. * devtools: add utility tool for normalizing httprr test recordings Add a command-line tool that standardizes version information in httprr recordings: - Normalizes x-goog-api-client headers to use placeholder versions - Standardizes x-amz-user-agent headers for consistency - Replaces Go version strings with generic placeholders - Supports dry-run mode to preview changes without modifying files - Includes verbose output option for detailed change reporting This tool helps maintain consistent test recordings across different environments and dependency versions, preventing test failures from version changes. * llms/openai: update OpenAI embedding test to use text-embedding-3-small model Update the embedding test to use the current text-embedding-3-small model: - Change model from text-embedding-ada-002 to text-embedding-3-small - Adjust dimensions parameter from 1234 to 256 to match model capabilities - Update test recording with appropriate response data This change ensures tests remain compatible with OpenAI's current embedding models and prevents test failures from API version changes.
136 lines
4.5 KiB
Go
136 lines
4.5 KiB
Go
// Package testctr provides utilities for setting up testcontainers in tests.
|
|
//
|
|
// Usage:
|
|
//
|
|
// 1. Add a TestMain function to your test package:
|
|
//
|
|
// func TestMain(m *testing.M) {
|
|
// code := testctr.EnsureTestEnv()
|
|
// if code == 0 {
|
|
// code = m.Run()
|
|
// }
|
|
// os.Exit(code)
|
|
// }
|
|
//
|
|
// 2. In your test functions, check for Docker availability:
|
|
//
|
|
// func TestWithContainers(t *testing.T) {
|
|
// testctr.SkipIfDockerNotAvailable(t)
|
|
// // Your test code here
|
|
// }
|
|
//
|
|
// This approach ensures proper environment setup for testcontainers while
|
|
// maintaining compatibility with parallel tests.
|
|
package testctr
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// EnsureTestEnv sets up the necessary environment variables for testcontainers
|
|
// at the process level. This should be called from TestMain before running tests.
|
|
// It returns an exit code that should be passed to os.Exit.
|
|
//
|
|
// This works around a testcontainers bug where it doesn't properly detect
|
|
// the Docker socket when using Colima or other non-standard Docker setups.
|
|
//
|
|
// Example usage:
|
|
//
|
|
// func TestMain(m *testing.M) {
|
|
// code := testctr.EnsureTestEnv()
|
|
// if code == 0 {
|
|
// code = m.Run()
|
|
// }
|
|
// os.Exit(code)
|
|
// }
|
|
func EnsureTestEnv() int {
|
|
verbose := os.Getenv("TESTCONTAINERS_VERBOSE") == "true"
|
|
// Check if docker is available in PATH
|
|
_, err := exec.LookPath("docker")
|
|
if err != nil {
|
|
// If DOCKER_HOST is set, assume Docker is available remotely
|
|
if os.Getenv("DOCKER_HOST") == "" {
|
|
fmt.Fprintf(os.Stderr, "WARNING: Docker not found in PATH and DOCKER_HOST not set\n")
|
|
// Don't fail, just warn - tests will skip individually
|
|
return 0
|
|
}
|
|
// Docker CLI not found but DOCKER_HOST is set, so continue
|
|
}
|
|
|
|
// Only set environment variables if they're not already set
|
|
if os.Getenv("DOCKER_HOST") == "" && err == nil {
|
|
// Get Docker host from docker context
|
|
cmd := exec.Command("docker", "context", "inspect", "-f={{.Endpoints.docker.Host}}")
|
|
output, err := cmd.CombinedOutput()
|
|
if err == nil {
|
|
dockerHost := strings.TrimSpace(string(output))
|
|
|
|
// Set DOCKER_HOST if using non-standard Docker socket paths (Colima, Lima, etc.)
|
|
// This works around testcontainers bug where it doesn't properly detect non-standard sockets
|
|
if dockerHost != "" && (strings.Contains(dockerHost, "colima") ||
|
|
strings.Contains(dockerHost, ".lima") ||
|
|
!strings.Contains(dockerHost, "/var/run/docker.sock")) {
|
|
os.Setenv("DOCKER_HOST", dockerHost)
|
|
if verbose {
|
|
fmt.Fprintf(os.Stderr, "testctr: Set DOCKER_HOST=%s\n", dockerHost)
|
|
}
|
|
} else if verbose && dockerHost != "" {
|
|
fmt.Fprintf(os.Stderr, "testctr: Using standard Docker socket: %s\n", dockerHost)
|
|
}
|
|
}
|
|
// If docker context inspect fails, just continue without setting DOCKER_HOST
|
|
// This is common when using standard Docker Desktop
|
|
}
|
|
|
|
// Disable Ryuk reaper if not explicitly enabled to reduce resource usage
|
|
// Ryuk is used for cleanup but can cause issues with limited Docker resources
|
|
if os.Getenv("TESTCONTAINERS_RYUK_DISABLED") == "" {
|
|
os.Setenv("TESTCONTAINERS_RYUK_DISABLED", "true")
|
|
if verbose {
|
|
fmt.Fprintf(os.Stderr, "testctr: Disabled Ryuk reaper for resource efficiency\n")
|
|
}
|
|
}
|
|
|
|
// Set the testcontainers Docker socket override if not already set
|
|
// This tells testcontainers where to find the actual Docker socket
|
|
if os.Getenv("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE") == "" {
|
|
dockerSocket := "/var/run/docker.sock" // default
|
|
|
|
// For Colima and other non-standard setups, extract socket path from DOCKER_HOST
|
|
if dockerHost := os.Getenv("DOCKER_HOST"); dockerHost != "" {
|
|
if strings.HasPrefix(dockerHost, "unix://") {
|
|
dockerSocket = strings.TrimPrefix(dockerHost, "unix://")
|
|
}
|
|
}
|
|
|
|
os.Setenv("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", dockerSocket)
|
|
if verbose {
|
|
fmt.Fprintf(os.Stderr, "testctr: Set TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=%s\n", dockerSocket)
|
|
}
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
// SkipIfDockerNotAvailable checks if Docker is available and skips the test if not.
|
|
// This is safe to call from tests that use t.Parallel() as it doesn't use t.Setenv.
|
|
// You must ensure the environment variables are set before running the test (e.g., via EnsureTestEnv in TestMain).
|
|
func SkipIfDockerNotAvailable(t *testing.T) {
|
|
t.Helper()
|
|
|
|
// Check if docker is available in PATH
|
|
_, err := exec.LookPath("docker")
|
|
if err != nil {
|
|
// If DOCKER_HOST is set, assume Docker is available remotely
|
|
if os.Getenv("DOCKER_HOST") == "" {
|
|
t.Skip("Docker not found in PATH and DOCKER_HOST not set, skipping test")
|
|
return
|
|
}
|
|
// Docker CLI not found but DOCKER_HOST is set, so continue
|
|
}
|
|
}
|