[#11] Add describe flag to tests subcommand
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
c53f3fa5d0
commit
1440cebda1
4 changed files with 84 additions and 32 deletions
|
@ -1,27 +1,41 @@
|
||||||
package modules
|
package modules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmp"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"slices"
|
"slices"
|
||||||
"sort"
|
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/s3-tests-parser/internal/s3"
|
"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/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testsCmd = &cobra.Command{
|
var testsCmd = &cobra.Command{
|
||||||
Use: "tests",
|
Use: "tests",
|
||||||
Short: "Print tests to check",
|
Short: "Print tests info",
|
||||||
Long: "Print all tests that will be checked by 'compatibility' command",
|
Long: "Print all handled tests",
|
||||||
Example: `s3-tests-parser tests
|
Example: `s3-tests-parser tests
|
||||||
s3-tests-parser tests --output tests.txt`,
|
s3-tests-parser tests --output tests.txt`,
|
||||||
RunE: runTestsCmd,
|
RunE: runTestsCmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
describeFlag = "describe"
|
||||||
|
)
|
||||||
|
|
||||||
func initTestsCmd() {
|
func initTestsCmd() {
|
||||||
testsCmd.Flags().String(outputFlag, "", "file to write output, if missed the stdout is used")
|
testsCmd.Flags().String(outputFlag, "", "file to write output, if missed the stdout is used")
|
||||||
|
testsCmd.Flags().Bool(allFlag, false, "include all tests")
|
||||||
|
testsCmd.Flags().Bool(describeFlag, false, "describe test (its group, skip status, reason etc.)")
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribedTest struct {
|
||||||
|
Name string
|
||||||
|
Group string
|
||||||
|
Skip bool
|
||||||
|
Comment string
|
||||||
}
|
}
|
||||||
|
|
||||||
func runTestsCmd(cmd *cobra.Command, _ []string) error {
|
func runTestsCmd(cmd *cobra.Command, _ []string) error {
|
||||||
|
@ -30,34 +44,40 @@ func runTestsCmd(cmd *cobra.Command, _ []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tests []string
|
includeAll := viper.GetBool(allFlag)
|
||||||
|
|
||||||
groupTests := make(map[string][]string)
|
var tests []DescribedTest
|
||||||
for _, group := range testStruct.Groups {
|
|
||||||
if group.Skip {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
groupTests[group.Name] = group.Tests
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, group := range testStruct.Groups {
|
for _, group := range testStruct.Groups {
|
||||||
if group.Skip {
|
if group.Skip && !includeAll {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
tests = append(tests, group.Tests...)
|
for _, test := range group.Tests {
|
||||||
for _, include := range group.Include {
|
tests = append(tests, DescribedTest{
|
||||||
tests = append(tests, groupTests[include]...)
|
Name: test,
|
||||||
|
Group: group.Name,
|
||||||
|
Skip: group.Skip,
|
||||||
|
Comment: group.Comment,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(tests)
|
slices.SortFunc(tests, func(a, b DescribedTest) int {
|
||||||
tests = slices.Compact(tests)
|
return cmp.Compare(a.Name, b.Name)
|
||||||
|
})
|
||||||
|
tests = slices.CompactFunc(tests, func(a DescribedTest, b DescribedTest) bool {
|
||||||
|
return a.Name == b.Name
|
||||||
|
})
|
||||||
|
|
||||||
|
if viper.GetBool(describeFlag) {
|
||||||
|
return describeTests(cmd, tests)
|
||||||
|
}
|
||||||
|
|
||||||
return printTests(cmd, tests)
|
return printTests(cmd, tests)
|
||||||
}
|
}
|
||||||
|
|
||||||
func printTests(cmd *cobra.Command, res []string) error {
|
func printTests(cmd *cobra.Command, res []DescribedTest) error {
|
||||||
w := cmd.OutOrStdout()
|
w := cmd.OutOrStdout()
|
||||||
if outFile := viper.GetString(outputFlag); outFile != "" {
|
if outFile := viper.GetString(outputFlag); outFile != "" {
|
||||||
f, err := os.Create(outFile)
|
f, err := os.Create(outFile)
|
||||||
|
@ -69,10 +89,29 @@ func printTests(cmd *cobra.Command, res []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range res {
|
for i := range res {
|
||||||
if _, err := fmt.Fprintln(w, res[i]); err != nil {
|
if _, err := fmt.Fprintln(w, res[i].Name); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func describeTests(cmd *cobra.Command, res []DescribedTest) 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.GetDescribeTemplate()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("form describe template: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return outTemplate.Execute(w, res)
|
||||||
|
}
|
||||||
|
|
|
@ -342,7 +342,7 @@
|
||||||
"tests": [],
|
"tests": [],
|
||||||
"include": [],
|
"include": [],
|
||||||
"skip": true,
|
"skip": true,
|
||||||
"comment": "Not supported. This method is deprecated by AWS. Use GetBucketLifecycleConfiguration"
|
"comment": "Not supported <br>This method is deprecated by AWS, use GetBucketLifecycleConfiguration"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "GetBucketLifecycleConfiguration",
|
"name": "GetBucketLifecycleConfiguration",
|
||||||
|
@ -829,7 +829,7 @@
|
||||||
"tests": [],
|
"tests": [],
|
||||||
"include": [],
|
"include": [],
|
||||||
"skip": true,
|
"skip": true,
|
||||||
"comment": "Not supported. This method is deprecated by AWS. Use PutBucketLifecycleConfiguration"
|
"comment": "Not supported <br>This method is deprecated by AWS, use PutBucketLifecycleConfiguration"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PutBucketLifecycleConfiguration",
|
"name": "PutBucketLifecycleConfiguration",
|
||||||
|
@ -1219,7 +1219,7 @@
|
||||||
"s3tests_boto3/functional/test_s3.py::test_bucket_concurrent_set_canned_acl"
|
"s3tests_boto3/functional/test_s3.py::test_bucket_concurrent_set_canned_acl"
|
||||||
],
|
],
|
||||||
"skip": false,
|
"skip": false,
|
||||||
"comment": "Partly supported. Only restricted canned acl can be applied"
|
"comment": "Partly supported <br>Only restricted canned acl can be applied"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "BucketVersioning",
|
"name": "BucketVersioning",
|
||||||
|
@ -1249,7 +1249,7 @@
|
||||||
"s3tests_boto3/functional/test_s3.py::test_versioning_concurrent_multi_object_delete"
|
"s3tests_boto3/functional/test_s3.py::test_versioning_concurrent_multi_object_delete"
|
||||||
],
|
],
|
||||||
"skip": false,
|
"skip": false,
|
||||||
"comment": "Limitations: \n1. Don't create delete marker for non-existing objects"
|
"comment": "Limitations: <br>1. Don't create delete marker for non-existing objects"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "MultipartUpload",
|
"name": "MultipartUpload",
|
||||||
|
@ -1379,7 +1379,7 @@
|
||||||
"s3tests_boto3/functional/test_s3.py::test_post_object_wrong_bucket"
|
"s3tests_boto3/functional/test_s3.py::test_post_object_wrong_bucket"
|
||||||
],
|
],
|
||||||
"skip": true,
|
"skip": true,
|
||||||
"comment": "Not supported. AWS v2 signature is deprecated."
|
"comment": "Not supported <br>AWS v2 signature is deprecated"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Locking",
|
"name": "Locking",
|
||||||
|
@ -1526,7 +1526,7 @@
|
||||||
"s3tests_boto3/functional/test_s3.py::test_bucket_acl_default"
|
"s3tests_boto3/functional/test_s3.py::test_bucket_acl_default"
|
||||||
],
|
],
|
||||||
"skip": true,
|
"skip": true,
|
||||||
"comment": "Not supported, Full Control to bucket owner is required"
|
"comment": "Not supported <br>Full Control to bucket owner is required"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Bucket ACL, using payload",
|
"name": "Bucket ACL, using payload",
|
||||||
|
@ -1541,7 +1541,7 @@
|
||||||
"s3tests_boto3/functional/test_s3.py::test_bucket_header_acl_grants"
|
"s3tests_boto3/functional/test_s3.py::test_bucket_header_acl_grants"
|
||||||
],
|
],
|
||||||
"skip": true,
|
"skip": true,
|
||||||
"comment": "Not supported, Full Control to bucket owner is required"
|
"comment": "Not supported <br>Full Control to bucket owner is required"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Email checking",
|
"name": "Email checking",
|
||||||
|
@ -1551,7 +1551,7 @@
|
||||||
"s3tests_boto3/functional/test_s3.py::test_bucket_acl_grant_email_not_exist"
|
"s3tests_boto3/functional/test_s3.py::test_bucket_acl_grant_email_not_exist"
|
||||||
],
|
],
|
||||||
"skip": true,
|
"skip": true,
|
||||||
"comment": "Not supported, email checking"
|
"comment": "Not supported <br>Email checking"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Authorization header manipulating",
|
"name": "Authorization header manipulating",
|
||||||
|
@ -1561,7 +1561,7 @@
|
||||||
"s3tests_boto3/functional/test_headers.py::test_bucket_create_bad_authorization_none"
|
"s3tests_boto3/functional/test_headers.py::test_bucket_create_bad_authorization_none"
|
||||||
],
|
],
|
||||||
"skip": true,
|
"skip": true,
|
||||||
"comment": "Bad test, railed_on_rwg, # TODO: remove 'fails_on_rgw' and once we have learned how to manipulate the authorization header"
|
"comment": "Bad test <br>failed_on_rwg <br># TODO: remove 'fails_on_rgw' and once we have learned how to manipulate the authorization header"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "test_bucket_create_bad_expect_mismatch",
|
"name": "test_bucket_create_bad_expect_mismatch",
|
||||||
|
@ -1579,7 +1579,7 @@
|
||||||
"s3tests_boto3/functional/test_s3.py::test_bucket_create_exists"
|
"s3tests_boto3/functional/test_s3.py::test_bucket_create_exists"
|
||||||
],
|
],
|
||||||
"skip": true,
|
"skip": true,
|
||||||
"comment": "Bad test. Incorrect asserting response error"
|
"comment": "Bad test <br>Incorrect asserting response error"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Checking object owner",
|
"name": "Checking object owner",
|
||||||
|
@ -1669,7 +1669,7 @@
|
||||||
"s3tests_boto3/functional/test_s3.py::test_sse_s3_encrypted_upload_8mb"
|
"s3tests_boto3/functional/test_s3.py::test_sse_s3_encrypted_upload_8mb"
|
||||||
],
|
],
|
||||||
"skip": true,
|
"skip": true,
|
||||||
"comment": "sse_s3 not supported"
|
"comment": "SSE-S3 not supported"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "alternative client in different account",
|
"name": "alternative client in different account",
|
||||||
|
@ -1716,7 +1716,7 @@
|
||||||
"s3tests_boto3/functional/test_s3.py::test_lifecycle_expiration_header_tags_head"
|
"s3tests_boto3/functional/test_s3.py::test_lifecycle_expiration_header_tags_head"
|
||||||
],
|
],
|
||||||
"skip": true,
|
"skip": true,
|
||||||
"comment": "Probably bad test, AWS fails, https://git.frostfs.info/TrueCloudLab/frostfs-s3-gw/issues/545"
|
"comment": "Probably bad test <br>AWS fails <br>https://git.frostfs.info/TrueCloudLab/frostfs-s3-gw/issues/545"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "get bucket policy status",
|
"name": "get bucket policy status",
|
||||||
|
@ -1729,7 +1729,7 @@
|
||||||
"s3tests_boto3/functional/test_s3.py::test_get_nonpublicpolicy_acl_bucket_policy_status"
|
"s3tests_boto3/functional/test_s3.py::test_get_nonpublicpolicy_acl_bucket_policy_status"
|
||||||
],
|
],
|
||||||
"skip": true,
|
"skip": true,
|
||||||
"comment": "Not supported, S3 gate computes status based on policy, not on canned acl. AWS also fails"
|
"comment": "Not supported <br>S3 gate computes status based on policy, not on canned acl <br>AWS also fails"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Lifecycle transition",
|
"name": "Lifecycle transition",
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# S3 Tests
|
||||||
|
|
||||||
|
Commit: [7aae6ce2ca48ccd0ac35100af074281c7c88a210](https://git.frostfs.info/TrueCloudLab/s3-tests/commit/7aae6ce2ca48ccd0ac35100af074281c7c88a210)
|
||||||
|
|
||||||
|
| Test | Group | Skip | Comment |
|
||||||
|
|------|-------|------|---------|{{range .}}
|
||||||
|
| {{.Name}} | {{.Group}} | {{.Skip}} | {{.Comment}} |{{end}}
|
|
@ -35,6 +35,8 @@ var (
|
||||||
txtTemplate []byte
|
txtTemplate []byte
|
||||||
//go:embed resources/md-template.gotmpl
|
//go:embed resources/md-template.gotmpl
|
||||||
mdTemplate []byte
|
mdTemplate []byte
|
||||||
|
//go:embed resources/tests-describe-template.gotmpl
|
||||||
|
describeTemplate []byte
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetTemplate(outFormat string) (*template.Template, error) {
|
func GetTemplate(outFormat string) (*template.Template, error) {
|
||||||
|
@ -84,3 +86,7 @@ func ColorToTerminal(color string) string {
|
||||||
return blackTerminal
|
return blackTerminal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetDescribeTemplate() (*template.Template, error) {
|
||||||
|
return template.New("describe-tests").Parse(string(describeTemplate))
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue