212 lines
5 KiB
Go
212 lines
5 KiB
Go
package modules
|
|
|
|
import (
|
|
_ "embed"
|
|
"fmt"
|
|
"os"
|
|
"sort"
|
|
"strings"
|
|
|
|
"git.frostfs.info/TrueCloudLab/s3-tests-parser/internal/parser"
|
|
"git.frostfs.info/TrueCloudLab/s3-tests-parser/internal/s3"
|
|
"git.frostfs.info/TrueCloudLab/s3-tests-parser/internal/templates"
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
var compatibilityCmd = &cobra.Command{
|
|
Use: "compatibility",
|
|
Short: "Shows compatibility results",
|
|
Long: "Form compatibility table based on passed s3 tests",
|
|
Example: `s3-tests-parser compatibility suite.csv
|
|
s3-tests-parser compatibility suite.json --format json
|
|
s3-tests-parser compatibility suite.json --format json --output-format md
|
|
s3-tests-parser compatibility suite.json --format json --output-format md --output result.md
|
|
s3-tests-parser compatibility suite.json --format json --output-format txt --output result.txt --verbose`,
|
|
RunE: runCompatibilityCmd,
|
|
}
|
|
|
|
type (
|
|
Results struct {
|
|
Verbose bool
|
|
Legend []Status
|
|
TagGroups []TagGroup
|
|
}
|
|
|
|
TagGroup struct {
|
|
Name string
|
|
Tests []TestResult
|
|
}
|
|
|
|
Status struct {
|
|
Color string
|
|
Description string
|
|
}
|
|
|
|
TestResult struct {
|
|
Color string
|
|
Name string
|
|
Comment string
|
|
Passed int
|
|
Total int
|
|
FailedTests []string
|
|
PassedTests []string
|
|
}
|
|
)
|
|
|
|
const (
|
|
formatFlag = "format"
|
|
outputFlag = "output"
|
|
outputFormatFlag = "output-format"
|
|
verboseFlag = "verbose"
|
|
)
|
|
|
|
func initCompatibilityCmd() {
|
|
compatibilityCmd.Flags().String(formatFlag, "csv", "format of input test suite file")
|
|
compatibilityCmd.Flags().String(outputFlag, "", "file to write output, if missed the stdout is used")
|
|
compatibilityCmd.Flags().String(outputFormatFlag, "txt", "format of output")
|
|
compatibilityCmd.Flags().Bool(verboseFlag, false, "produce additional info")
|
|
}
|
|
|
|
func runCompatibilityCmd(cmd *cobra.Command, args []string) error {
|
|
if len(args) != 1 {
|
|
return fmt.Errorf("expected exactly one arg, got: %v", args)
|
|
}
|
|
|
|
testStruct, err := s3.ParseTestsStruct()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
testsMap, err := parser.ParseSuite(args[0], viper.GetString(formatFlag))
|
|
if err != nil {
|
|
return fmt.Errorf("parse tests: %w", err)
|
|
}
|
|
|
|
res := formResults(testStruct, testsMap)
|
|
res.Verbose = viper.GetBool(verboseFlag)
|
|
return printResults(cmd, res)
|
|
}
|
|
|
|
var legend = []Status{
|
|
{
|
|
Color: templates.GreenColor,
|
|
Description: "Supported",
|
|
},
|
|
{
|
|
Color: templates.YellowColor,
|
|
Description: "Partially supported",
|
|
},
|
|
{
|
|
Color: templates.RedColor,
|
|
Description: "Badly supported",
|
|
},
|
|
{
|
|
Color: templates.BlueColor,
|
|
Description: "Not supported",
|
|
},
|
|
{
|
|
Color: templates.BlackColor,
|
|
Description: "Not applicable or will never be supported",
|
|
},
|
|
}
|
|
|
|
func formResults(testStruct s3.TestsStructure, testsMap map[string]bool) Results {
|
|
tagGroups := make(map[string]TagGroup)
|
|
groupTests := make(map[string][]string)
|
|
for _, group := range testStruct.Groups {
|
|
groupTests[group.Name] = group.Tests
|
|
}
|
|
|
|
for _, group := range testStruct.Groups {
|
|
tagGroup, ok := tagGroups[group.Tag]
|
|
if !ok {
|
|
tagGroup.Name = group.Tag
|
|
}
|
|
|
|
for _, n := range group.Include {
|
|
group.Tests = append(group.Tests, groupTests[n]...)
|
|
}
|
|
|
|
tagGroup.Tests = append(tagGroup.Tests, formTestResult(group, testsMap))
|
|
tagGroups[group.Tag] = tagGroup
|
|
}
|
|
|
|
res := Results{Legend: legend}
|
|
for _, group := range tagGroups {
|
|
res.TagGroups = append(res.TagGroups, group)
|
|
}
|
|
|
|
sort.Slice(res.TagGroups, func(i, j int) bool {
|
|
return res.TagGroups[i].Name < res.TagGroups[j].Name
|
|
})
|
|
|
|
return res
|
|
}
|
|
|
|
func formTestResult(group s3.Group, testsMap map[string]bool) TestResult {
|
|
ln := len(group.Tests)
|
|
|
|
var failed []string
|
|
var passed []string
|
|
for _, test := range group.Tests {
|
|
split := strings.Split(test, "::") // to trim test path
|
|
if len(split) != 2 {
|
|
continue
|
|
}
|
|
testName := split[1]
|
|
if testsMap[testName] {
|
|
passed = append(passed, testName)
|
|
} else {
|
|
failed = append(failed, testName)
|
|
}
|
|
}
|
|
|
|
var color string
|
|
if strings.Contains(group.Comment, "Not supported") {
|
|
color = templates.BlueColor
|
|
} else if strings.Contains(group.Comment, "Not applicable") {
|
|
color = templates.BlackColor
|
|
} else if ln == 0 && !group.Skip {
|
|
color = templates.GreenColor
|
|
}
|
|
|
|
if color == "" {
|
|
color = templates.RedColor
|
|
rate := float64(len(passed)) / float64(ln)
|
|
if rate > 0.9 {
|
|
color = templates.GreenColor
|
|
} else if rate > 0.5 {
|
|
color = templates.YellowColor
|
|
}
|
|
}
|
|
|
|
return TestResult{
|
|
Color: color,
|
|
Name: group.Name,
|
|
Comment: group.Comment,
|
|
Passed: len(passed),
|
|
Total: ln,
|
|
FailedTests: failed,
|
|
PassedTests: passed,
|
|
}
|
|
}
|
|
|
|
func printResults(cmd *cobra.Command, res Results) error {
|
|
w := cmd.OutOrStdout()
|
|
if outFile := viper.GetString(outputFlag); outFile != "" {
|
|
f, err := os.Create(outFile)
|
|
if err != nil {
|
|
return fmt.Errorf("create out file: %w", err)
|
|
}
|
|
w = f
|
|
defer f.Close()
|
|
}
|
|
|
|
outTemplate, err := templates.GetTemplate(viper.GetString(outputFormatFlag))
|
|
if err != nil {
|
|
return fmt.Errorf("form out template: %w", err)
|
|
}
|
|
|
|
return outTemplate.Execute(w, res)
|
|
}
|