Documentation
¶
Overview ¶
Package testutil provides common test utilities for lineage analysis tests.
Index ¶
- func BenchCaseName(s string) string
- func BenchmarkCaseAnalysis(b *testing.B, dir string, analyze AnalyzeFunc)
- func BenchmarkCaseParse(b *testing.B, dir string, parse func(string) error)
- func BenchmarkCorpusAnalysis(b *testing.B, dir string, analyze AnalyzeFunc)
- func BenchmarkShapes(b *testing.B, analyze AnalyzeFunc)
- func BenchmarkWildcardCatalog(b *testing.B, analyze AnalyzeFunc)
- func BuildDeepSubquery(n int) string
- func BuildManyJoins(n int) string
- func BuildWideSelect(n int) string
- func EdgeMatches(rel model.ColumnRelation, exp ExpectedEdge) bool
- func FindLineageTestSuites(dir string) ([]string, error)
- func FormatRelations(relations []model.ColumnRelation) string
- func IsPartialAnalysis(err error) bool
- func RequireFullEdgeAnnotations(t *testing.T, dir string)
- func RunLineageTest(t *testing.T, tc LineageTestCase, analyzeFn AnalyzeFunc)
- func RunLineageTestSuitesFromYAMLDir(t *testing.T, dir string, analyzeFn AnalyzeFunc)
- func RunLineageTestSuitesFromYAMLDirSkipping(t *testing.T, dir string, analyzeFn AnalyzeFunc, skip map[string]bool)
- func RunLineageTests(t *testing.T, testCases []LineageTestCase, analyzeFn AnalyzeFunc)
- func TransformationMatches(transform model.Transformation, exp ExpectedTransformation) bool
- func ValidateExactEdges(t testingT, relations []model.ColumnRelation, expected []ExpectedEdge)
- func ValidateExpectedEdges(t testingT, relations []model.ColumnRelation, expected []ExpectedEdge)
- type AnalyzeFunc
- type BenchCase
- type ExpectedEdge
- type ExpectedTransformation
- type FailingCatalogProvide
- type LineageTestCase
- type LineageTestSuite
- type MemoryCatalogProvide
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BenchCaseName ¶
BenchCaseName turns a corpus case name into a benchmark sub-name.
func BenchmarkCaseAnalysis ¶
func BenchmarkCaseAnalysis(b *testing.B, dir string, analyze AnalyzeFunc)
BenchmarkCaseAnalysis measures each corpus statement separately so the slow shapes are visible.
func BenchmarkCaseParse ¶
BenchmarkCaseParse isolates the parse cost from the lineage walk, so the analyzer's own overhead is the difference between the two.
func BenchmarkCorpusAnalysis ¶
func BenchmarkCorpusAnalysis(b *testing.B, dir string, analyze AnalyzeFunc)
BenchmarkCorpusAnalysis measures end-to-end analysis over a whole corpus in one operation, giving a single throughput number for the analyzer.
func BenchmarkShapes ¶
func BenchmarkShapes(b *testing.B, analyze AnalyzeFunc)
BenchmarkShapes measures synthetic statements that scale a single dimension (column count, nesting depth, join count) to show how analysis cost grows.
func BenchmarkWildcardCatalog ¶
func BenchmarkWildcardCatalog(b *testing.B, analyze AnalyzeFunc)
BenchmarkWildcardCatalog measures SELECT * expansion against a 100-column catalog, the production path where the metadata store is consulted.
func BuildDeepSubquery ¶
BuildDeepSubquery builds n nested derived tables.
func BuildManyJoins ¶
BuildManyJoins builds a join chain over n tables.
func BuildWideSelect ¶
BuildWideSelect builds a select of n projected columns.
func EdgeMatches ¶
func EdgeMatches(rel model.ColumnRelation, exp ExpectedEdge) bool
EdgeMatches checks if a relation matches the expected edge pattern. Empty strings in the expected edge are treated as wildcards that match anything.
func FindLineageTestSuites ¶
FindLineageTestSuites returns the YAML suite paths in a directory, sorted.
func FormatRelations ¶
func FormatRelations(relations []model.ColumnRelation) string
FormatRelations formats relations for error messages.
func IsPartialAnalysis ¶
IsPartialAnalysis reports whether an error is the one a partial analysis returns: the analyzer kept the edges it found and reported what it could not represent. A benchmark runs corpus cases that expect an error beside their edges, so it treats that error as the case's documented outcome while any other error still fails it.
func RequireFullEdgeAnnotations ¶
RequireFullEdgeAnnotations fails when an expectation leaves a user-visible relation field unasserted. An omitted field in an expectation is a wildcard, so a case widens instead of narrows when it leaves fields out; this keeps every case pinning what a consumer reads: the relation type, whether the target is a real table, and the operation of every transformation on the edge.
It is a check over the YAML alone and needs no analyzer.
func RunLineageTest ¶
func RunLineageTest(t *testing.T, tc LineageTestCase, analyzeFn AnalyzeFunc)
RunLineageTest executes a single lineage test case using the provided analyze function.
func RunLineageTestSuitesFromYAMLDir ¶
func RunLineageTestSuitesFromYAMLDir(t *testing.T, dir string, analyzeFn AnalyzeFunc)
RunLineageTestSuitesFromYAMLDir executes every YAML suite in a directory.
func RunLineageTestSuitesFromYAMLDirSkipping ¶
func RunLineageTestSuitesFromYAMLDirSkipping(t *testing.T, dir string, analyzeFn AnalyzeFunc, skip map[string]bool)
RunLineageTestSuitesFromYAMLDirSkipping is RunLineageTestSuitesFromYAMLDir with the named cases omitted. A dialect uses it to record, explicitly, statements its parser cannot handle yet rather than silently narrowing the shared corpus.
func RunLineageTests ¶
func RunLineageTests(t *testing.T, testCases []LineageTestCase, analyzeFn AnalyzeFunc)
RunLineageTests executes a slice of lineage test cases using the provided analyze function.
func TransformationMatches ¶
func TransformationMatches(transform model.Transformation, exp ExpectedTransformation) bool
TransformationMatches checks a transformation against the fields an expected transformation sets.
func ValidateExactEdges ¶
func ValidateExactEdges(t testingT, relations []model.ColumnRelation, expected []ExpectedEdge)
ValidateExactEdges checks that the produced edges are exactly the expected ones: every expectation matches a distinct produced edge and no produced edge is left unmatched.
func ValidateExpectedEdges ¶
func ValidateExpectedEdges(t testingT, relations []model.ColumnRelation, expected []ExpectedEdge)
ValidateExpectedEdges checks that all expected edges are found in the results.
Types ¶
type AnalyzeFunc ¶
AnalyzeFunc is the function signature for analyzing SQL and returning relations.
type BenchCase ¶
BenchCase is one statement a benchmark measures.
func LoadCorpusBenchCases ¶
LoadCorpusBenchCases reads every statement in the YAML suites under dir that is expected to analyze successfully, so the same corpus that guards correctness also measures cost. An error case never reaches the walk a benchmark measures: it stops at the statement the analyzer rejects.
type ExpectedEdge ¶
type ExpectedEdge struct {
// Source column information
FromDatabase string
FromSchema string
FromTable string
FromField string
FromFieldSet bool
// Target column information
ToDatabase string
ToSchema string
ToTable string
ToField string
ToFieldSet bool
// Optional: expected relation type (nil = not checked)
RelationType *model.RelationType
// Optional: whether transformation is expected (nil = not checked)
HasTransform *bool
// Optional: whether target is temporary (nil = not checked)
IsTemp *bool
// Optional: expected transformations. Compared exactly — same count, each
// entry matching a distinct produced transformation — unless the case sets
// Subset, in which case each entry only has to match some transformation.
Transformations []ExpectedTransformation
// SubsetTransformations relaxes the transformation comparison to "each
// expected entry matches some produced transformation". It is derived from
// the case-level Subset flag.
SubsetTransformations bool
}
ExpectedEdge defines the expected lineage edge for testing. This structure allows for flexible matching - unset fields are not validated. FieldSet records that a column name was written, so `to_field:` with an empty value can assert "this edge has no target column" (a row-level influence) instead of meaning "any target column".
type ExpectedTransformation ¶
type ExpectedTransformation struct {
Operation string
FunctionName string
Expression string
OpType string
Condition string
Arguments []string
GroupKeys []string
GroupKeysSet bool
PartitionBy []string
OrderBy []string
All bool
AllSet bool
}
ExpectedTransformation matches a transformation on the fields it sets. A field left out of the YAML is not asserted at all; GroupKeysSet records that `group_keys:` was written, so `group_keys: []` can assert "this transformation carries none" instead of meaning "do not check".
type FailingCatalogProvide ¶
type FailingCatalogProvide struct {
// contains filtered or unexported fields
}
FailingCatalogProvide fails every lookup, so a test can exercise the path where an analysis degrades because the catalog could not answer.
func NewFailingCatalogProvide ¶
func NewFailingCatalogProvide(err error) *FailingCatalogProvide
NewFailingCatalogProvide returns a provider whose every lookup fails.
func (*FailingCatalogProvide) GetTable ¶
func (p *FailingCatalogProvide) GetTable(_ context.Context, _ model.ObjectIdentifier) (*catalog.TableMeta, error)
type LineageTestCase ¶
type LineageTestCase struct {
// Name of the test case
Name string
// SQL query to analyze
SQL string
// Optional catalog provider
Catalog catalog.Provide
// Expected edges. When nil, only checks that analysis succeeds without error.
// When an empty (non-nil) slice, expects no edges at all. They are compared
// exactly by default: every produced edge must match a distinct expected edge,
// so an unexpected extra edge fails.
ExpectedEdges []ExpectedEdge
// Subset declares the case deliberately partial: expectations are matched as
// subsets instead, and transformation expectations only have to be contained.
// It is the escape hatch for a case that asserts part of a large result.
Subset bool
// ExpectError expects the analysis to report an error. Together with a nil
// ExpectedEdges it asserts a hard failure — nothing usable came back. Together
// with edges it asserts a *partial* analysis: the analyzer reported what it
// could not represent and still produced these edges, which is the contract
// UnsupportedStatementError carries.
ExpectError bool
// ErrorContains, when set, must appear in the reported error. A partial
// analysis is only useful if it says what it dropped, so the cases that pin
// one assert the message and not merely that some error occurred.
ErrorContains string
}
LineageTestCase defines a test case for lineage analysis.
type LineageTestSuite ¶
type LineageTestSuite struct {
Name string
Cases []LineageTestCase
}
LineageTestSuite defines a named group of lineage test cases loaded from YAML.
func LoadLineageTestSuiteFromYAML ¶
func LoadLineageTestSuiteFromYAML(path string) (LineageTestSuite, error)
LoadLineageTestSuiteFromYAML loads a lineage test suite definition from a YAML file.
type MemoryCatalogProvide ¶
type MemoryCatalogProvide struct {
// contains filtered or unexported fields
}
MemoryCatalogProvide is an in-memory catalog.Provide used by the lineage test harness. It lives here rather than in the catalog package because a normal source file beside the real provider is compiled into the server binary: only test files import testutil, so this one is not.
func NewMemoryCatalogProvide ¶
func NewMemoryCatalogProvide() *MemoryCatalogProvide
NewMemoryCatalogProvide creates an empty in-memory catalog.
func (*MemoryCatalogProvide) AddTable ¶
func (p *MemoryCatalogProvide) AddTable(table *catalog.TableMeta)
AddTable registers a table's metadata.
func (*MemoryCatalogProvide) Calls ¶
func (p *MemoryCatalogProvide) Calls() int
Calls returns how many lookups reached the catalog, which lets a test pin that one analysis reads a relation once however many times it is named.
func (*MemoryCatalogProvide) GetTable ¶
func (p *MemoryCatalogProvide) GetTable(_ context.Context, id model.ObjectIdentifier) (*catalog.TableMeta, error)