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

GenerateJSONPath race condition in ApplyRulesToRuleSet #622

Open
czeslavo opened this issue Feb 14, 2025 · 0 comments
Open

GenerateJSONPath race condition in ApplyRulesToRuleSet #622

czeslavo opened this issue Feb 14, 2025 · 0 comments
Labels
bug Something isn't working

Comments

@czeslavo
Copy link
Contributor

Description

There's a data race condition in motor.ApplyRulesToRuleSet function that's triggered by concurrent read and write to a single base.Foundation instance:

=== RUN   TestMinimalRaceExample
==================
WARNING: DATA RACE
Read at 0x00c0001b0518 by goroutine 248:
  github.com/pb33f/doctor/model/high/base.(*Foundation).GenerateJSONPath()
      /Users/user/go/pkg/mod/github.com/pb33f/[email protected]/model/high/base/foundation.go:335 +0x3c
  github.com/pb33f/doctor/model/high/v3.(*Operation).GenerateJSONPath()
      <autogenerated>:1 +0x24
  github.com/daveshanley/vacuum/functions/core.(*Truthy).RunRule()
      /Users/user/go/pkg/mod/github.com/daveshanley/[email protected]/functions/core/truthy.go:102 +0x1070
  github.com/daveshanley/vacuum/motor.buildResults()
      /Users/user/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:923 +0x7e8
  github.com/daveshanley/vacuum/motor.runRule()
      /Users/user/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:837 +0xf80
  github.com/daveshanley/vacuum/motor.ApplyRulesToRuleSet.func7.gowrap1()
      /Users/user/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:693 +0x88

Previous write at 0x00c0001b0518 by goroutine 262:
  github.com/pb33f/doctor/model/high/base.(*Foundation).GenerateJSONPath()
      /Users/user/go/pkg/mod/github.com/pb33f/[email protected]/model/high/base/foundation.go:339 +0x578
  github.com/daveshanley/vacuum/functions/openapi.OperationDescription.RunRule()
      /Users/user/go/pkg/mod/github.com/daveshanley/[email protected]/functions/openapi/operation_descriptions.go:133 +0x50c
  github.com/daveshanley/vacuum/functions/openapi.(*OperationDescription).RunRule()
      <autogenerated>:1 +0xd0
  github.com/daveshanley/vacuum/motor.buildResults()
      /Users/user/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:923 +0x7e8
  github.com/daveshanley/vacuum/motor.runRule()
      /Users/user/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:837 +0xf80
  github.com/daveshanley/vacuum/motor.ApplyRulesToRuleSet.func7.gowrap1()
      /Users/user/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:693 +0x88

Goroutine 248 (running) created at:
  github.com/daveshanley/vacuum/motor.ApplyRulesToRuleSet.func7()
      /Users/user/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:693 +0x3c4
  github.com/daveshanley/vacuum/motor.ApplyRulesToRuleSet.gowrap1()
      /Users/user/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:703 +0x54

Goroutine 262 (running) created at:
  github.com/daveshanley/vacuum/motor.ApplyRulesToRuleSet.func7()
      /Users/user/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:693 +0x3c4
  github.com/daveshanley/vacuum/motor.ApplyRulesToRuleSet.gowrap1()
      /Users/user/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:703 +0x54
==================
    testing.go:1399: race detected during execution of test
--- FAIL: TestMinimalRaceExample (0.03s)

Reproduction

Run the following test with go test -race -count=10 (the race condition occurs every 3rd or 4th run).

func TestMinimalRaceExample(t *testing.T) {
	const (
		rules = `extends: [[spectral:oas, recommended]]
rules:
  x-visibility-truthy:
    description: x-visibility check
    message: "Make sure x-visibility is available for every operation"
    severity: "error"
    given: "$.paths.*.*"
    then:
      field: x-visibility
      function: truthy
`
		oapi = `openapi: 3.0.2
info:
  title: Sample API
  description: This is a sample API with internal and external routes.
  version: 1.0.0
servers:
  - url: https://internal.api.com/
  - url: https://external.api.com/
paths:
  /internalRoute:
    servers:
      - url: https://internal.api.com/
    get:
      summary: Internal route
      operationId: internalRouteOp
      responses:
        '200':
          description: Success

  /externalRoute:
    servers:
      - url: https://external.api.com/
    get:
      summary: External route
      operationId: externalRouteOp
      responses:
        '200':
          description: Success
`
	)

	customRuleSet, err := rulesets.CreateRuleSetFromData([]byte(rules))
	require.NoError(t, err)

	defaultRuleSet := rulesets.BuildDefaultRuleSets()
	customRuleSet = defaultRuleSet.GenerateRuleSetFromSuppliedRuleSet(customRuleSet)

	ruleSetResults := motor.ApplyRulesToRuleSet(&motor.RuleSetExecution{
		RuleSet:     customRuleSet,
		Spec:        []byte(oapi),
		AllowLookup: true,
	})

	require.NotNil(t, ruleSetResults)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants