1
0
Fork 0
telegraf/testutil/file.go
Daniel Baumann 4978089aab
Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-05-24 07:26:29 +02:00

139 lines
3.3 KiB
Go

package testutil
import (
"bufio"
"errors"
"fmt"
"os"
"strings"
"github.com/influxdata/telegraf"
)
type LineParser interface {
ParseLine(line string) (telegraf.Metric, error)
}
// ParseRawLinesFrom returns the raw lines between the given header and a trailing blank line
func ParseRawLinesFrom(lines []string, header string) ([]string, error) {
if len(lines) < 2 {
// We need a line for HEADER and EMPTY TRAILING LINE
return nil, errors.New("expected at least two lines to parse from")
}
start := -1
for i := range lines {
if strings.TrimLeft(lines[i], "# ") == header {
start = i + 1
break
}
}
if start < 0 {
return nil, fmt.Errorf("header %q does not exist", header)
}
output := make([]string, 0)
for _, line := range lines[start:] {
if !strings.HasPrefix(strings.TrimLeft(line, "\t "), "#") {
return nil, errors.New("section does not end with trailing empty line")
}
// Stop at empty line
content := strings.TrimLeft(line, "# \t")
if content == "" || content == "'''" {
break
}
output = append(output, content)
}
return output, nil
}
// ParseMetricsFrom parses metrics from the given lines in line-protocol following a header, with a trailing blank line
func ParseMetricsFrom(lines []string, header string, parser LineParser) ([]telegraf.Metric, error) {
if len(lines) < 2 {
// We need a line for HEADER and EMPTY TRAILING LINE
return nil, errors.New("expected at least two lines to parse from")
}
start := -1
for i := range lines {
if strings.TrimLeft(lines[i], "# ") == header {
start = i + 1
break
}
}
if start < 0 {
return nil, fmt.Errorf("header %q does not exist", header)
}
metrics := make([]telegraf.Metric, 0)
for _, line := range lines[start:] {
if !strings.HasPrefix(strings.TrimLeft(line, "\t "), "#") {
return nil, errors.New("section does not end with trailing empty line")
}
// Stop at empty line
content := strings.TrimLeft(line, "# \t")
if content == "" || content == "'''" {
break
}
m, err := parser.ParseLine(content)
if err != nil {
return nil, fmt.Errorf("unable to parse metric in %q failed: %w", content, err)
}
metrics = append(metrics, m)
}
return metrics, nil
}
// ParseMetricsFromFile parses metrics from the given file in line-protocol
func ParseMetricsFromFile(filename string, parser telegraf.Parser) ([]telegraf.Metric, error) {
var metrics []telegraf.Metric
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Bytes()
if len(line) == 0 || strings.HasPrefix(string(line), "#") {
continue
}
nonutc, err := parser.Parse(line)
if err != nil {
return nil, fmt.Errorf("unable to parse metric in %q failed: %w", line, err)
}
for _, m := range nonutc {
// The timezone needs to be UTC to match the timestamp test results
m.SetTime(m.Time().UTC())
metrics = append(metrics, m)
}
}
return metrics, nil
}
// ParseLinesFromFile returns the lines of the file as strings
func ParseLinesFromFile(filename string) ([]string, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
var lines []string
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
if len(line) == 0 || strings.HasPrefix(line, "#") {
continue
}
lines = append(lines, line)
}
return lines, nil
}