mirror of
https://github.com/hanzoai/telemetry.git
synced 2026-10-30 20:01:49 +00:00
TestLoader_PersistToFile_MkdirAllError chmods its temp dir to 0500 and expects persistToFile to fail creating a subdirectory. Root ignores the permission bits, so the mkdir succeeds, persistToFile returns nil, and require.Error fails. The assertion is sound; the premise just does not hold for uid 0. Same shape as the mdatagen write-back test. The sibling WriteFileError test needs no guard: it writes to a path that is a directory, which fails for root too.
619 lines
21 KiB
Go
619 lines
21 KiB
Go
// Copyright The OpenTelemetry Authors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package schemagen
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestLoader_LoadFromFile_Success(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
// Create schema file - for a local ref
|
|
schemaPath := filepath.Join(tempDir, "internal/metadata")
|
|
require.NoError(t, os.MkdirAll(schemaPath, 0o750))
|
|
schemaFile := filepath.Join(schemaPath, schemaFileName)
|
|
schemaContent := `config:
|
|
title: "Test Schema"
|
|
description: "A test schema"
|
|
type: object
|
|
`
|
|
require.NoError(t, os.WriteFile(schemaFile, []byte(schemaContent), 0o600))
|
|
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
|
|
// For local refs, the loadFromFile method takes a file path
|
|
result, err := loader.loadFromFile(schemaFile)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "Test Schema", result.Title)
|
|
require.Equal(t, "A test schema", result.Description)
|
|
require.Equal(t, "object", result.Type)
|
|
}
|
|
|
|
func TestLoader_LoadFromFile_ExportedConfigsOnly(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
schemaFile := filepath.Join(tempDir, schemaFileName)
|
|
schemaContent := `exported_configs:
|
|
sample_config:
|
|
type: object
|
|
properties:
|
|
endpoint:
|
|
type: string
|
|
`
|
|
require.NoError(t, os.WriteFile(schemaFile, []byte(schemaContent), 0o600))
|
|
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
|
|
result, err := loader.loadFromFile(schemaFile)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, result)
|
|
require.Contains(t, result.Defs, "sample_config")
|
|
require.Equal(t, "object", result.Defs["sample_config"].Type)
|
|
require.Contains(t, result.Defs["sample_config"].Properties, "endpoint")
|
|
}
|
|
|
|
func TestLoader_LoadFromFile_NotFound(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
|
|
// Try to load from non-existent file
|
|
result, err := loader.loadFromFile(filepath.Join(tempDir, "nonexistent", schemaFileName))
|
|
require.ErrorIs(t, err, ErrNotFound)
|
|
require.Nil(t, result)
|
|
}
|
|
|
|
func TestLoader_LoadFromFile_ParseError(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
// Create invalid YAML file
|
|
schemaPath := filepath.Join(tempDir, "test/path")
|
|
require.NoError(t, os.MkdirAll(schemaPath, 0o750))
|
|
schemaFile := filepath.Join(schemaPath, schemaFileName)
|
|
invalidYAML := `title: "Test"
|
|
invalid: yaml: content:
|
|
`
|
|
require.NoError(t, os.WriteFile(schemaFile, []byte(invalidYAML), 0o600))
|
|
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
|
|
result, err := loader.loadFromFile(schemaFile)
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "failed to parse schema")
|
|
require.Nil(t, result)
|
|
}
|
|
|
|
func TestLoader_LoadFromHTTP_Success(t *testing.T) {
|
|
// Create test HTTP server
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write([]byte("config:\n title: \"HTTP Schema\"\n type: string\n"))
|
|
}))
|
|
defer server.Close()
|
|
|
|
// Override namespaceToURL for testing
|
|
originalURL := namespaceToURL["go.opentelemetry.io/collector"]
|
|
namespaceToURL["go.opentelemetry.io/collector"] = server.URL
|
|
defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }()
|
|
|
|
tempDir := t.TempDir()
|
|
// Use schemagenDir so resolveModuleVersion can find confmap (a direct dep) without go get.
|
|
loader := NewLoader(schemagenDir(t)).(*schemaLoader)
|
|
ref := *NewRef("go.opentelemetry.io/collector/confmap.controller_config")
|
|
|
|
result, err := loader.loadFromHTTP(ref, filepath.Join(tempDir, ".schemas"))
|
|
require.NoError(t, err)
|
|
require.Equal(t, "HTTP Schema", result.Title)
|
|
require.Equal(t, "string", result.Type)
|
|
}
|
|
|
|
func TestLoader_LoadFromHTTP_NotFound(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}))
|
|
defer server.Close()
|
|
|
|
originalURL := namespaceToURL["go.opentelemetry.io/collector"]
|
|
namespaceToURL["go.opentelemetry.io/collector"] = server.URL
|
|
defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }()
|
|
|
|
tempDir := t.TempDir()
|
|
loader := NewLoader(schemagenDir(t)).(*schemaLoader)
|
|
ref := *NewRef("go.opentelemetry.io/collector/confmap.controller_config")
|
|
|
|
result, err := loader.loadFromHTTP(ref, filepath.Join(tempDir, ".schemas"))
|
|
require.ErrorIs(t, err, ErrNotFound)
|
|
require.Nil(t, result)
|
|
}
|
|
|
|
func TestLoader_LoadFromHTTP_ServerError(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
}))
|
|
defer server.Close()
|
|
|
|
originalURL := namespaceToURL["go.opentelemetry.io/collector"]
|
|
namespaceToURL["go.opentelemetry.io/collector"] = server.URL
|
|
defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }()
|
|
|
|
tempDir := t.TempDir()
|
|
loader := NewLoader(schemagenDir(t)).(*schemaLoader)
|
|
ref := *NewRef("go.opentelemetry.io/collector/confmap.controller_config")
|
|
|
|
result, err := loader.loadFromHTTP(ref, filepath.Join(tempDir, ".schemas"))
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "HTTP 500")
|
|
require.Nil(t, result)
|
|
}
|
|
|
|
func TestLoader_TryLoad_WithVersion(t *testing.T) {
|
|
// Create test HTTP server that returns different content for different versions
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
if strings.Contains(r.URL.Path, "v1.0.0") {
|
|
_, _ = w.Write([]byte("config:\n title: \"Versioned Schema\"\n"))
|
|
} else {
|
|
_, _ = w.Write([]byte("config:\n title: \"Main Version Schema\"\n"))
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
|
|
originalURL := namespaceToURL["go.opentelemetry.io/collector"]
|
|
namespaceToURL["go.opentelemetry.io/collector"] = server.URL
|
|
defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }()
|
|
|
|
tempDir := t.TempDir()
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
ref := *NewRef("go.opentelemetry.io/collector/test/path.config")
|
|
|
|
// Try to load with version
|
|
result, err := loader.tryLoad(ref, "v1.0.0")
|
|
require.NoError(t, err)
|
|
require.Equal(t, "Versioned Schema", result.Title)
|
|
}
|
|
|
|
func TestLoader_TryLoad_ExportedConfigsOnly(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write([]byte(`exported_configs:
|
|
sample_config:
|
|
type: object
|
|
properties:
|
|
endpoint:
|
|
type: string
|
|
`))
|
|
}))
|
|
defer server.Close()
|
|
|
|
originalURL := namespaceToURL["go.opentelemetry.io/collector"]
|
|
namespaceToURL["go.opentelemetry.io/collector"] = server.URL
|
|
defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }()
|
|
|
|
loader := NewLoader(t.TempDir()).(*schemaLoader)
|
|
ref := *NewRef("go.opentelemetry.io/collector/test/path.sample_config")
|
|
|
|
result, err := loader.tryLoad(ref, "v1.0.0")
|
|
require.NoError(t, err)
|
|
require.NotNil(t, result)
|
|
require.Contains(t, result.Defs, "sample_config")
|
|
require.Equal(t, "object", result.Defs["sample_config"].Type)
|
|
require.Contains(t, result.Defs["sample_config"].Properties, "endpoint")
|
|
}
|
|
|
|
func TestLoader_PersistToFile_Success(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
|
|
metadata := &ConfigMetadata{
|
|
Title: "Persisted Schema",
|
|
Description: "Test persistence",
|
|
}
|
|
|
|
filePath := filepath.Join(tempDir, "test", "persisted.yaml")
|
|
err := loader.persistToFile(filePath, metadata)
|
|
require.NoError(t, err)
|
|
|
|
// Verify file was created and can be round-tripped via loadFromFile
|
|
require.FileExists(t, filePath)
|
|
|
|
roundTripped, err := loader.loadFromFile(filePath)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "Persisted Schema", roundTripped.Title)
|
|
require.Equal(t, "Test persistence", roundTripped.Description)
|
|
}
|
|
|
|
func TestLoader_Load_CacheInteraction(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
ref := *NewRef("go.opentelemetry.io/collector/test/path.config")
|
|
|
|
expected := &ConfigMetadata{Title: "Pre-cached Schema"}
|
|
loader.cache[ref.CacheKey()] = expected
|
|
|
|
result, err := loader.Load(ref)
|
|
require.NoError(t, err)
|
|
require.Equal(t, expected, result)
|
|
require.Same(t, expected, result)
|
|
}
|
|
|
|
func TestLoader_Integration_MemoryCachePeristence(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
loader := &schemaLoader{
|
|
cache: make(map[string]*ConfigMetadata),
|
|
cd: tempDir,
|
|
httpClient: &http.Client{Timeout: 30 * time.Second},
|
|
}
|
|
|
|
ref := *NewRef("go.opentelemetry.io/collector/test/path.config")
|
|
expected := &ConfigMetadata{Title: "Integration Test"}
|
|
|
|
loader.cache[ref.CacheKey()] = expected
|
|
|
|
result1, err := loader.Load(ref)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "Integration Test", result1.Title)
|
|
|
|
result2, err := loader.Load(ref)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "Integration Test", result2.Title)
|
|
|
|
require.Same(t, result1, result2)
|
|
}
|
|
|
|
func TestLoader_Load_CachesOnFirstLoad(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
schemaPath := filepath.Join(tempDir, "subdir")
|
|
require.NoError(t, os.MkdirAll(schemaPath, 0o750))
|
|
schemaFile := filepath.Join(schemaPath, schemaFileName)
|
|
require.NoError(t, os.WriteFile(schemaFile, []byte("config:\n title: Cached\n type: object\n"), 0o600))
|
|
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
loader.rootDir = tempDir // bypass git
|
|
|
|
ref := Ref{schemaID: "subdir", kind: Local}
|
|
|
|
result1, err := loader.Load(ref)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "Cached", result1.Title)
|
|
|
|
result2, err := loader.Load(ref)
|
|
require.NoError(t, err)
|
|
require.Same(t, result1, result2)
|
|
}
|
|
|
|
func TestLoader_Load_RepoRootError(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
|
|
ref := Ref{schemaID: "subdir", kind: Local}
|
|
_, err := loader.load(ref)
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "failed to determine repo root")
|
|
}
|
|
|
|
func TestLoader_Load_LocalAbsolutePath(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
// Create schema at <repoRoot>/somepackage/config.schema.yaml
|
|
schemaDir := filepath.Join(tempDir, "somepackage")
|
|
require.NoError(t, os.MkdirAll(schemaDir, 0o750))
|
|
require.NoError(t, os.WriteFile(filepath.Join(schemaDir, schemaFileName), []byte("config:\n title: AbsoluteLocal\n type: object\n"), 0o600))
|
|
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
loader.rootDir = tempDir // bypass git
|
|
|
|
// absolute local ref (starts with /)
|
|
ref := Ref{schemaID: "/somepackage", kind: Local}
|
|
result, err := loader.load(ref)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "AbsoluteLocal", result.Title)
|
|
}
|
|
|
|
func TestLoader_Load_LocalRelativePath(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
subDir := filepath.Join(tempDir, "subdir")
|
|
require.NoError(t, os.MkdirAll(subDir, 0o750))
|
|
require.NoError(t, os.WriteFile(filepath.Join(subDir, schemaFileName), []byte("config:\n title: RelativeLocal\n type: object\n"), 0o600))
|
|
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
loader.rootDir = tempDir // bypass git
|
|
|
|
// relative local ref (does not start with /)
|
|
ref := Ref{schemaID: "subdir", kind: Local}
|
|
result, err := loader.load(ref)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "RelativeLocal", result.Title)
|
|
}
|
|
|
|
func TestLoader_LoadFromFile_ReadError(t *testing.T) {
|
|
// Create a directory where the file is expected — os.ReadFile on a directory fails
|
|
tempDir := t.TempDir()
|
|
dirPath := filepath.Join(tempDir, schemaFileName)
|
|
require.NoError(t, os.MkdirAll(dirPath, 0o750))
|
|
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
result, err := loader.loadFromFile(dirPath)
|
|
require.Error(t, err)
|
|
require.Nil(t, result)
|
|
require.NotErrorIs(t, err, ErrNotFound)
|
|
require.Contains(t, err.Error(), "failed to read schema")
|
|
}
|
|
|
|
func TestLoader_LoadFromHTTP_FileCacheHit(t *testing.T) {
|
|
// Test that loadFromHTTP returns from the file cache when a schema is already persisted,
|
|
// without making any HTTP requests.
|
|
ref := *NewRef("go.opentelemetry.io/collector/confmap.controller_config")
|
|
|
|
// Resolve the real module version so we can place the file at the right path.
|
|
sgDir := schemagenDir(t)
|
|
helper := NewLoader(sgDir).(*schemaLoader)
|
|
version := helper.resolveModuleVersion(ref.Module())
|
|
if version == "" {
|
|
t.Skip("could not resolve module version, skipping file cache hit test")
|
|
}
|
|
|
|
tempDir := t.TempDir()
|
|
fileCacheDir := filepath.Join(tempDir, ".schemas")
|
|
filePath := filepath.Join(fileCacheDir, version, ref.SchemaID(), schemaFileName)
|
|
require.NoError(t, os.MkdirAll(filepath.Dir(filePath), 0o750))
|
|
require.NoError(t, os.WriteFile(filePath, []byte("config:\n title: FileCached\n type: object\n"), 0o600))
|
|
|
|
// Use an httpClient that always panics to confirm no HTTP call is made.
|
|
loader := &schemaLoader{
|
|
cache: make(map[string]*ConfigMetadata),
|
|
cd: sgDir,
|
|
httpClient: &http.Client{},
|
|
}
|
|
|
|
result, err := loader.loadFromHTTP(ref, fileCacheDir)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "FileCached", result.Title)
|
|
}
|
|
|
|
func TestLoader_LoadFromHTTP_PersistWarning(t *testing.T) {
|
|
// Test the warning path when persistToFile fails (non-writable dir).
|
|
// We create a read-only file cache dir so persistToFile fails.
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("file permission test not reliable on Windows")
|
|
}
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write([]byte("config:\n title: PersistFail\n type: object\n"))
|
|
}))
|
|
defer server.Close()
|
|
|
|
originalURL := namespaceToURL["go.opentelemetry.io/collector"]
|
|
namespaceToURL["go.opentelemetry.io/collector"] = server.URL
|
|
defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }()
|
|
|
|
tempDir := t.TempDir()
|
|
|
|
// Make the file cache directory read-only so persistToFile fails
|
|
cacheDir := filepath.Join(tempDir, ".schemas")
|
|
require.NoError(t, os.MkdirAll(cacheDir, 0o750))
|
|
|
|
loader := NewLoader(schemagenDir(t)).(*schemaLoader)
|
|
ref := *NewRef("go.opentelemetry.io/collector/confmap.controller_config")
|
|
|
|
// Should still return the result even though persist fails (warning only)
|
|
result, err := loader.loadFromHTTP(ref, cacheDir)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "PersistFail", result.Title)
|
|
}
|
|
|
|
func TestLoader_LoadFromHTTP_NonNotFoundFileError(t *testing.T) {
|
|
// Test the log.Printf warning path in loadFromHTTP when loadFromFile on the cached path
|
|
// fails with a non-ErrNotFound error (directory placed where file is expected).
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write([]byte("config:\n title: AfterWarning\n type: object\n"))
|
|
}))
|
|
defer server.Close()
|
|
|
|
originalURL := namespaceToURL["go.opentelemetry.io/collector"]
|
|
namespaceToURL["go.opentelemetry.io/collector"] = server.URL
|
|
defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }()
|
|
|
|
sgDir := schemagenDir(t)
|
|
ref := *NewRef("go.opentelemetry.io/collector/confmap.controller_config")
|
|
|
|
// Resolve the real version so we can poison the file cache at the correct path
|
|
helper := NewLoader(sgDir).(*schemaLoader)
|
|
version := helper.resolveModuleVersion(ref.Module())
|
|
if version == "" {
|
|
t.Skip("could not resolve module version, skipping non-ErrNotFound warning test")
|
|
}
|
|
|
|
tempDir := t.TempDir()
|
|
cacheDir := filepath.Join(tempDir, ".schemas")
|
|
filePath := filepath.Join(cacheDir, version, ref.SchemaID(), schemaFileName)
|
|
// Place a directory at the expected file path → loadFromFile returns a non-ErrNotFound error
|
|
require.NoError(t, os.MkdirAll(filePath, 0o750))
|
|
|
|
loader := &schemaLoader{
|
|
cache: make(map[string]*ConfigMetadata),
|
|
cd: sgDir,
|
|
httpClient: &http.Client{},
|
|
}
|
|
|
|
result, err := loader.loadFromHTTP(ref, cacheDir)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "AfterWarning", result.Title)
|
|
}
|
|
|
|
func TestLoader_TryLoad_URLError(t *testing.T) {
|
|
// Ref with unsupported namespace → URL() returns an error
|
|
loader := NewLoader("").(*schemaLoader)
|
|
ref := *NewRef("unknownns/path.type")
|
|
// namespace is set so Module() returns non-empty, but Namespace() returns false
|
|
// Actually NewRef sets it as external; let's manually set up a ref with no URL support
|
|
ref2 := Ref{namespace: "unsupported.example.com", schemaID: "pkg", defName: "t", kind: External}
|
|
_, err := loader.tryLoad(ref2, "v1.0.0")
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "failed to construct URL")
|
|
_ = ref
|
|
}
|
|
|
|
func TestLoader_TryLoad_HTTPError(t *testing.T) {
|
|
// Use a server that closes connections immediately to simulate a network error
|
|
// The simplest approach: use an invalid URL
|
|
loader := NewLoader("").(*schemaLoader)
|
|
|
|
ref := *NewRef("go.opentelemetry.io/collector/test/path.config")
|
|
|
|
// Override the URL to point to an invalid host
|
|
originalURL := namespaceToURL["go.opentelemetry.io/collector"]
|
|
namespaceToURL["go.opentelemetry.io/collector"] = "http://127.0.0.1:0" // port 0 → connection refused
|
|
defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }()
|
|
|
|
_, err := loader.tryLoad(ref, "v1.0.0")
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "failed to fetch schema")
|
|
}
|
|
|
|
func TestLoader_TryLoad_ParseError(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write([]byte("title: bad\n invalid: yaml: :\n"))
|
|
}))
|
|
defer server.Close()
|
|
|
|
originalURL := namespaceToURL["go.opentelemetry.io/collector"]
|
|
namespaceToURL["go.opentelemetry.io/collector"] = server.URL
|
|
defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }()
|
|
|
|
loader := NewLoader("").(*schemaLoader)
|
|
ref := *NewRef("go.opentelemetry.io/collector/test/path.config")
|
|
_, err := loader.tryLoad(ref, "v1.0.0")
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "failed to parse schema")
|
|
}
|
|
|
|
func TestLoader_RefVersion_UnknownModulePath(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
|
|
ref := Ref{namespace: "", schemaID: "pkg", defName: "t", kind: Internal}
|
|
_, err := loader.refVersion(&ref)
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "unknown module path")
|
|
}
|
|
|
|
func TestLoader_ResolveModuleVersion_NilModule(t *testing.T) {
|
|
loader := NewLoader(mdatagenDir(t)).(*schemaLoader)
|
|
|
|
version := loader.resolveModuleVersion("fmt")
|
|
require.Empty(t, version)
|
|
}
|
|
|
|
func TestLoader_ResolveModuleVersion_LoadError(t *testing.T) {
|
|
loader := NewLoader("/nonexistent/path/xyz").(*schemaLoader)
|
|
|
|
version := loader.resolveModuleVersion("somemodule/that/doesnt/exist")
|
|
require.Empty(t, version)
|
|
}
|
|
|
|
func TestLoader_RepoRoot_CachedValue(t *testing.T) {
|
|
loader := NewLoader("").(*schemaLoader)
|
|
loader.rootDir = "/cached/root"
|
|
|
|
root, err := loader.repoRoot("/any/dir")
|
|
require.NoError(t, err)
|
|
require.Equal(t, "/cached/root", root)
|
|
}
|
|
|
|
func TestLoader_RepoRoot_GitError(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
|
|
_, err := loader.repoRoot(tempDir)
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "failed to determine repo root")
|
|
}
|
|
|
|
func TestLoader_PersistToFile_MkdirAllError(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("file permission test not reliable on Windows")
|
|
}
|
|
if os.Geteuid() == 0 {
|
|
t.Skip("root bypasses file permissions, so a read-only directory cannot induce the mkdir error this test needs")
|
|
}
|
|
tempDir := t.TempDir()
|
|
t.Cleanup(func() {
|
|
_ = os.Chmod(tempDir, 0o700) // #nosec G302 -- restore so t.TempDir cleanup can remove it
|
|
})
|
|
|
|
require.NoError(t, os.Chmod(tempDir, 0o500)) // #nosec G302
|
|
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
err := loader.persistToFile(filepath.Join(tempDir, "newdir", "schema.yaml"), &ConfigMetadata{Title: "X"})
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "failed to create directory")
|
|
}
|
|
|
|
func TestLoader_PersistToFile_WriteFileError(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
filePath := filepath.Join(tempDir, "schema.yaml")
|
|
require.NoError(t, os.MkdirAll(filePath, 0o750))
|
|
|
|
loader := NewLoader(tempDir).(*schemaLoader)
|
|
err := loader.persistToFile(filePath, &ConfigMetadata{Title: "X"})
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "failed to write file")
|
|
}
|
|
|
|
func TestLoader_TryLoad_ReadBodyError(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.Header().Set("Content-Length", "1000")
|
|
w.WriteHeader(http.StatusOK)
|
|
hj, ok := w.(http.Hijacker)
|
|
if !ok {
|
|
return
|
|
}
|
|
conn, _, _ := hj.Hijack()
|
|
_ = conn.Close()
|
|
}))
|
|
defer server.Close()
|
|
|
|
originalURL := namespaceToURL["go.opentelemetry.io/collector"]
|
|
namespaceToURL["go.opentelemetry.io/collector"] = server.URL
|
|
defer func() { namespaceToURL["go.opentelemetry.io/collector"] = originalURL }()
|
|
|
|
loader := NewLoader("").(*schemaLoader)
|
|
ref := *NewRef("go.opentelemetry.io/collector/test/path.config")
|
|
_, err := loader.tryLoad(ref, "v1.0.0")
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "failed to read response body")
|
|
}
|
|
|
|
func mdatagenDir(t *testing.T) string {
|
|
t.Helper()
|
|
_, file, _, ok := runtime.Caller(0)
|
|
require.True(t, ok, "could not determine caller file")
|
|
return filepath.Join(filepath.Dir(file), "../../cmd/mdatagen")
|
|
}
|
|
|
|
// schemagenDir returns the directory of this test file (internal/schemagen).
|
|
// Use it as the loader's cwd when tests need packages.Load to resolve a module
|
|
// version without invoking go get — confmap is a direct dep here and locally replaced.
|
|
func schemagenDir(t *testing.T) string {
|
|
t.Helper()
|
|
_, file, _, ok := runtime.Caller(0)
|
|
require.True(t, ok, "could not determine caller file")
|
|
return filepath.Dir(file)
|
|
}
|