Files
dolthub--doltgresql/testing/generation/function_coverage/main.go
T
2026-07-13 12:32:25 +08:00

120 lines
3.6 KiB
Go

// Copyright 2024 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"fmt"
"sort"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/functions/framework"
"github.com/dolthub/doltgresql/server/initialization"
doltgresservercfg "github.com/dolthub/doltgresql/servercfg"
"github.com/dolthub/doltgresql/testing/generation/utils"
)
// Assertion represents a single SELECT assertion.
type Assertion struct {
Stmt string
Rows []sql.Row
Error bool
}
func main() {
initialization.Initialize(nil, doltgresservercfg.DefaultServerConfig())
rootFolder, err := utils.GetRootFolder()
if err != nil {
fmt.Printf("%s\n", err.Error())
return
}
rootFolder = rootFolder.MoveRoot("testing/generation/function_coverage")
// Sort the strings for determinism, since range iteration on maps is non-deterministic
functionNames := make([]string, 0, len(framework.Catalog))
for functionName := range framework.Catalog {
functionNames = append(functionNames, functionName)
}
sort.Strings(functionNames)
for _, functionName := range functionNames {
var assertions []Assertion
utils.PrintSectionMarker(functionName, '+', 80)
FunctionLoop:
for _, function := range framework.Catalog[functionName] {
var literalGeneratorParams []utils.StatementGenerator
literalGeneratorParams = append(literalGeneratorParams, utils.Text(functionName+"("))
for i, paramType := range function.GetParameters() {
if i > 0 {
literalGeneratorParams = append(literalGeneratorParams, utils.Text(", "))
}
if generator, ok := valueMappings[paramType.ID]; ok {
literalGeneratorParams = append(literalGeneratorParams, generator)
} else {
fmt.Printf("missing support for functions with the parameter type: `%s`\n", paramType.String())
continue FunctionLoop
}
}
literalGeneratorParams = append(literalGeneratorParams, utils.Text(")"))
literalGenerator := utils.Collection(
utils.Text("SELECT"),
utils.Collection(literalGeneratorParams...),
utils.Text(";"),
)
randomInts, err := utils.GenerateRandomInts(500, literalGenerator.Permutations())
if err != nil {
fmt.Println(err.Error())
continue FunctionLoop
}
for _, randomInt := range randomInts {
literalGenerator.SetConsumeIterations(randomInt)
assertion := Assertion{
Stmt: literalGenerator.String(),
Error: false,
}
result, _, err := QueryPostgres(assertion.Stmt)
if err != nil {
assertion.Error = true
} else {
// Some tests may generate enormous strings, so we'll skip those
roughRowTotal := uint64(0)
for _, v1 := range result {
for _, v2 := range v1 {
if stringVal, ok := v2.(string); ok {
roughRowTotal += uint64(len(stringVal))
}
}
}
if roughRowTotal > 300 {
continue
}
assertion.Rows = result
}
assertions = append(assertions, assertion)
}
}
if len(assertions) > 0 {
if err := GenerateTests(rootFolder, functionName, assertions); err != nil {
fmt.Printf("%s\n", err.Error())
return
}
}
}
}