Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added timeout feature to prevent runaway linting #404

Merged
merged 2 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions cmd/build_results.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,25 @@ import (
"github.com/daveshanley/vacuum/rulesets"
"github.com/pterm/pterm"
"os"
"time"
)

func BuildResults(
rulesetFlag string,
specBytes []byte,
customFunctions map[string]model.RuleFunction,
base string) (*model.RuleResultSet, *motor.RuleSetExecutionResult, error) {
return BuildResultsWithDocCheckSkip(rulesetFlag, specBytes, customFunctions, base, false)
base string,
timeout time.Duration) (*model.RuleResultSet, *motor.RuleSetExecutionResult, error) {
return BuildResultsWithDocCheckSkip(rulesetFlag, specBytes, customFunctions, base, false, timeout)
}

func BuildResultsWithDocCheckSkip(
rulesetFlag string,
specBytes []byte,
customFunctions map[string]model.RuleFunction,
base string,
skipCheck bool) (*model.RuleResultSet, *motor.RuleSetExecutionResult, error) {
skipCheck bool,
timeout time.Duration) (*model.RuleResultSet, *motor.RuleSetExecutionResult, error) {

// read spec and parse
defaultRuleSets := rulesets.BuildDefaultRuleSets()
Expand Down Expand Up @@ -52,6 +55,7 @@ func BuildResultsWithDocCheckSkip(
Base: base,
SkipDocumentCheck: skipCheck,
AllowLookup: true,
Timeout: timeout,
})

resultSet := model.NewRuleResultSet(ruleset.Results)
Expand Down
4 changes: 2 additions & 2 deletions cmd/build_results_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import (
)

func TestBuildResults(t *testing.T) {
_, _, err := BuildResults("nuggets", nil, nil, "")
_, _, err := BuildResults("nuggets", nil, nil, "", 5)
assert.Error(t, err)
}

func TestBuildResults_SkipCheck(t *testing.T) {
_, _, err := BuildResultsWithDocCheckSkip("nuggets", nil, nil, "", true)
_, _, err := BuildResultsWithDocCheckSkip("nuggets", nil, nil, "", true, 5)
assert.Error(t, err)
}
4 changes: 3 additions & 1 deletion cmd/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func GetDashboardCommand() *cobra.Command {
}
baseFlag, _ := cmd.Flags().GetString("base")
skipCheckFlag, _ := cmd.Flags().GetBool("skip-check")
timeoutFlag, _ := cmd.Flags().GetInt("timeout")

var err error
vacuumReport, specBytes, _ := vacuum_report.BuildVacuumReportFromFile(args[0])
Expand All @@ -62,7 +63,8 @@ func GetDashboardCommand() *cobra.Command {
customFunctions, _ := LoadCustomFunctions(functionsFlag)

rulesetFlag, _ := cmd.Flags().GetString("ruleset")
resultSet, ruleset, err = BuildResultsWithDocCheckSkip(rulesetFlag, specBytes, customFunctions, baseFlag, skipCheckFlag)
resultSet, ruleset, err = BuildResultsWithDocCheckSkip(rulesetFlag, specBytes, customFunctions,
baseFlag, skipCheckFlag, time.Duration(timeoutFlag)*time.Second)
if err != nil {
pterm.Error.Printf("Failed to render dashboard: %v\n\n", err)
return err
Expand Down
4 changes: 3 additions & 1 deletion cmd/html_report.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func GetHTMLReportCommand() *cobra.Command {
noStyleFlag, _ := cmd.Flags().GetBool("no-style")
baseFlag, _ := cmd.Flags().GetString("base")
skipCheckFlag, _ := cmd.Flags().GetBool("skip-check")
timeoutFlag, _ := cmd.Flags().GetInt("timeout")

// disable color and styling, for CI/CD use.
// https://github.com/daveshanley/vacuum/issues/234
Expand Down Expand Up @@ -92,7 +93,8 @@ func GetHTMLReportCommand() *cobra.Command {
customFunctions, _ := LoadCustomFunctions(functionsFlag)

rulesetFlag, _ := cmd.Flags().GetString("ruleset")
resultSet, ruleset, err = BuildResultsWithDocCheckSkip(rulesetFlag, specBytes, customFunctions, baseFlag, skipCheckFlag)
resultSet, ruleset, err = BuildResultsWithDocCheckSkip(rulesetFlag, specBytes, customFunctions,
baseFlag, skipCheckFlag, time.Duration(timeoutFlag)*time.Second)
if err != nil {
pterm.Error.Printf("Failed to generate report: %v\n\n", err)
return err
Expand Down
4 changes: 4 additions & 0 deletions cmd/lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func GetLintCommand() *cobra.Command {
noBanner, _ := cmd.Flags().GetBool("no-banner")
noMessage, _ := cmd.Flags().GetBool("no-message")
allResults, _ := cmd.Flags().GetBool("all-results")
timeoutFlag, _ := cmd.Flags().GetInt("timeout")

// disable color and styling, for CI/CD use.
// https://github.com/daveshanley/vacuum/issues/234
Expand Down Expand Up @@ -177,6 +178,7 @@ func GetLintCommand() *cobra.Command {
functions: customFunctions,
lock: &printLock,
logger: logger,
timeoutFlag: timeoutFlag,
}
fs, fp, err := lintFile(lfr)

Expand Down Expand Up @@ -266,6 +268,7 @@ type lintFileRequest struct {
errorsFlag bool
totalFiles int
fileIndex int
timeoutFlag int
defaultRuleSets rulesets.RuleSets
selectedRS *rulesets.RuleSet
functions map[string]model.RuleFunction
Expand Down Expand Up @@ -297,6 +300,7 @@ func lintFile(req lintFileRequest) (int64, int, error) {
AllowLookup: req.remote,
SkipDocumentCheck: req.skipCheckFlag,
Logger: req.logger,
Timeout: time.Duration(req.timeoutFlag) * time.Second,
})

results := result.Results
Expand Down
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func GetRootCommand() *cobra.Command {
rootCmd.PersistentFlags().BoolP("remote", "u", true, "Allow local files and remote (http) references to be looked up")
rootCmd.PersistentFlags().BoolP("skip-check", "k", false, "Skip checking for a valid OpenAPI document, useful for linting fragments or non-OpenAPI documents")
rootCmd.PersistentFlags().BoolP("debug", "w", false, "Turn on debug logging")
rootCmd.PersistentFlags().IntP("timeout", "g", 5, "Rule timeout in seconds, default is 5 seconds")

regErr := rootCmd.RegisterFlagCompletionFunc("functions", cobra.FixedCompletions(
[]string{"so"}, cobra.ShellCompDirectiveFilterFileExt,
Expand Down
2 changes: 2 additions & 0 deletions cmd/spectral_report.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func GetSpectralReportCommand() *cobra.Command {
noStyleFlag, _ := cmd.Flags().GetBool("no-style")
baseFlag, _ := cmd.Flags().GetString("base")
skipCheckFlag, _ := cmd.Flags().GetBool("skip-check")
timeoutFlag, _ := cmd.Flags().GetInt("timeout")

// disable color and styling, for CI/CD use.
// https://github.com/daveshanley/vacuum/issues/234
Expand Down Expand Up @@ -136,6 +137,7 @@ func GetSpectralReportCommand() *cobra.Command {
SilenceLogs: true,
Base: baseFlag,
SkipDocumentCheck: skipCheckFlag,
Timeout: time.Duration(timeoutFlag) * time.Second,
})

resultSet := model.NewRuleResultSet(ruleset.Results)
Expand Down
2 changes: 2 additions & 0 deletions cmd/vacuum_report.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func GetVacuumReportCommand() *cobra.Command {
baseFlag, _ := cmd.Flags().GetString("base")
junitFlag, _ := cmd.Flags().GetBool("junit")
skipCheckFlag, _ := cmd.Flags().GetBool("skip-check")
timeoutFlag, _ := cmd.Flags().GetInt("timeout")

// disable color and styling, for CI/CD use.
// https://github.com/daveshanley/vacuum/issues/234
Expand Down Expand Up @@ -138,6 +139,7 @@ func GetVacuumReportCommand() *cobra.Command {
SilenceLogs: true,
Base: baseFlag,
SkipDocumentCheck: skipCheckFlag,
Timeout: time.Duration(timeoutFlag) * time.Second,
})

resultSet := model.NewRuleResultSet(ruleset.Results)
Expand Down
3 changes: 0 additions & 3 deletions functions/openapi/oas_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ func (os OASSchema) RunRule(nodes []*yaml.Node, context model.RuleFunctionContex
// grab the original bytes and the spec info from context.
info := context.SpecInfo

// rule cannot proceed until JSON parsing is complete. Wait on channel to signal all clear.
<-info.GetJSONParsingChannel()

if info.SpecType == "" {
// spec type is un-known, there is no point in running this rule.
return results
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ require (
github.com/gizak/termui/v3 v3.1.0
github.com/json-iterator/go v1.1.12
github.com/mitchellh/mapstructure v1.5.0
github.com/pb33f/libopenapi v0.14.2
github.com/pb33f/libopenapi-validator v0.0.36
github.com/pb33f/libopenapi v0.14.4
github.com/pb33f/libopenapi-validator v0.0.37
github.com/pterm/pterm v0.12.72
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/spf13/cobra v1.8.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,10 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/pb33f/libopenapi v0.14.2 h1:FaEvmhCObhjE9olnvlYZSwgrkFuis5eviIpIqndTA1c=
github.com/pb33f/libopenapi v0.14.2/go.mod h1:m+4Pwri31UvcnZjuP8M7TlbR906DXJmMvYsbis234xg=
github.com/pb33f/libopenapi-validator v0.0.36 h1:mNCPMkxvdYljwUpLlFkSKzXXyxslNquh5JRWqrFCfEo=
github.com/pb33f/libopenapi-validator v0.0.36/go.mod h1:YaNEPkOg49iBOoj6WOyK68JmyomqTREIh0ZSgM4lqHk=
github.com/pb33f/libopenapi v0.14.4 h1:NbcYaBbG/6pnJM8lw4F6b5e54HandyKF452HUl4+9j4=
github.com/pb33f/libopenapi v0.14.4/go.mod h1:m+4Pwri31UvcnZjuP8M7TlbR906DXJmMvYsbis234xg=
github.com/pb33f/libopenapi-validator v0.0.37 h1:nD6c010yxaFs3hJC+I5esAXf0VE6QLV1iTGkpCXz7W4=
github.com/pb33f/libopenapi-validator v0.0.37/go.mod h1:nWO4jDe3dJwRskfEl2SAtV9LlCJ5ClCB+OBw2E7splo=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand Down
Loading
Loading