updated coverage for timeout path lookup

Signed-off-by: quobix <dave@quobix.com>
This commit is contained in:
quobix
2024-01-04 16:45:00 -05:00
parent 15c53c1c2b
commit 202ae3365a
3 changed files with 114 additions and 104 deletions

View File

@@ -4,21 +4,21 @@
package base package base
import ( import (
"context" "context"
"strings" "strings"
"testing" "testing"
"github.com/pb33f/libopenapi/datamodel/low" "github.com/pb33f/libopenapi/datamodel/low"
lowbase "github.com/pb33f/libopenapi/datamodel/low/base" lowbase "github.com/pb33f/libopenapi/datamodel/low/base"
"github.com/pb33f/libopenapi/index" "github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/utils" "github.com/pb33f/libopenapi/utils"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
func TestSchemaProxy_MarshalYAML(t *testing.T) { func TestSchemaProxy_MarshalYAML(t *testing.T) {
const ymlComponents = `components: const ymlComponents = `components:
schemas: schemas:
rice: rice:
type: string type: string
@@ -31,99 +31,99 @@ func TestSchemaProxy_MarshalYAML(t *testing.T) {
rice: rice:
$ref: '#/components/schemas/rice'` $ref: '#/components/schemas/rice'`
idx := func() *index.SpecIndex { idx := func() *index.SpecIndex {
var idxNode yaml.Node var idxNode yaml.Node
err := yaml.Unmarshal([]byte(ymlComponents), &idxNode) err := yaml.Unmarshal([]byte(ymlComponents), &idxNode)
assert.NoError(t, err) assert.NoError(t, err)
return index.NewSpecIndexWithConfig(&idxNode, index.CreateOpenAPIIndexConfig()) return index.NewSpecIndexWithConfig(&idxNode, index.CreateOpenAPIIndexConfig())
}() }()
const ref = "#/components/schemas/nice" const ref = "#/components/schemas/nice"
const ymlSchema = `$ref: '` + ref + `'` const ymlSchema = `$ref: '` + ref + `'`
var node yaml.Node var node yaml.Node
_ = yaml.Unmarshal([]byte(ymlSchema), &node) _ = yaml.Unmarshal([]byte(ymlSchema), &node)
lowProxy := new(lowbase.SchemaProxy) lowProxy := new(lowbase.SchemaProxy)
err := lowProxy.Build(context.Background(), nil, node.Content[0], idx) err := lowProxy.Build(context.Background(), nil, node.Content[0], idx)
assert.NoError(t, err) assert.NoError(t, err)
lowRef := low.NodeReference[*lowbase.SchemaProxy]{ lowRef := low.NodeReference[*lowbase.SchemaProxy]{
Value: lowProxy, Value: lowProxy,
} }
sp := NewSchemaProxy(&lowRef) sp := NewSchemaProxy(&lowRef)
origin := sp.GetReferenceOrigin() origin := sp.GetReferenceOrigin()
assert.Nil(t, origin) assert.Nil(t, origin)
rend, _ := sp.Render() rend, _ := sp.Render()
assert.Equal(t, "$ref: '#/components/schemas/nice'", strings.TrimSpace(string(rend))) assert.Equal(t, "$ref: '#/components/schemas/nice'", strings.TrimSpace(string(rend)))
} }
func TestCreateSchemaProxy(t *testing.T) { func TestCreateSchemaProxy(t *testing.T) {
sp := CreateSchemaProxy(&Schema{Description: "iAmASchema"}) sp := CreateSchemaProxy(&Schema{Description: "iAmASchema"})
assert.Equal(t, "iAmASchema", sp.rendered.Description) assert.Equal(t, "iAmASchema", sp.rendered.Description)
assert.False(t, sp.IsReference()) assert.False(t, sp.IsReference())
} }
func TestCreateSchemaProxyRef(t *testing.T) { func TestCreateSchemaProxyRef(t *testing.T) {
sp := CreateSchemaProxyRef("#/components/schemas/MySchema") sp := CreateSchemaProxyRef("#/components/schemas/MySchema")
assert.Equal(t, "#/components/schemas/MySchema", sp.GetReference()) assert.Equal(t, "#/components/schemas/MySchema", sp.GetReference())
assert.True(t, sp.IsReference()) assert.True(t, sp.IsReference())
} }
func TestSchemaProxy_GetReference(t *testing.T) { func TestSchemaProxy_GetReference(t *testing.T) {
refNode := utils.CreateStringNode("#/components/schemas/MySchema") refNode := utils.CreateStringNode("#/components/schemas/MySchema")
ref := low.Reference{} ref := low.Reference{}
ref.SetReference("#/components/schemas/MySchema", refNode) ref.SetReference("#/components/schemas/MySchema", refNode)
sp := &SchemaProxy{ sp := &SchemaProxy{
schema: &low.NodeReference[*lowbase.SchemaProxy]{ schema: &low.NodeReference[*lowbase.SchemaProxy]{
Value: &lowbase.SchemaProxy{ Value: &lowbase.SchemaProxy{
Reference: ref, Reference: ref,
}, },
}, },
} }
assert.Equal(t, "#/components/schemas/MySchema", sp.GetReference()) assert.Equal(t, "#/components/schemas/MySchema", sp.GetReference())
assert.Equal(t, refNode, sp.GetReferenceNode()) assert.Equal(t, refNode, sp.GetReferenceNode())
} }
func TestSchemaProxy_IsReference_Nil(t *testing.T) { func TestSchemaProxy_IsReference_Nil(t *testing.T) {
var sp *SchemaProxy var sp *SchemaProxy
assert.False(t, sp.IsReference()) assert.False(t, sp.IsReference())
} }
func TestSchemaProxy_NoSchema_GetOrigin(t *testing.T) { func TestSchemaProxy_NoSchema_GetOrigin(t *testing.T) {
sp := &SchemaProxy{} sp := &SchemaProxy{}
assert.Nil(t, sp.GetReferenceOrigin()) assert.Nil(t, sp.GetReferenceOrigin())
} }
func TestCreateSchemaProxyRef_GetReferenceNode(t *testing.T) { func TestCreateSchemaProxyRef_GetReferenceNode(t *testing.T) {
refNode := utils.CreateRefNode("#/components/schemas/MySchema") refNode := utils.CreateRefNode("#/components/schemas/MySchema")
sp := CreateSchemaProxyRef("#/components/schemas/MySchema") sp := CreateSchemaProxyRef("#/components/schemas/MySchema")
assert.Equal(t, refNode, sp.GetReferenceNode()) assert.Equal(t, refNode, sp.GetReferenceNode())
} }
func TestCreateRefNode_MarshalYAML(t *testing.T) { func TestCreateRefNode_MarshalYAML(t *testing.T) {
ref := low.Reference{} ref := low.Reference{}
ref.SetReference("#/components/schemas/MySchema", nil) ref.SetReference("#/components/schemas/MySchema", nil)
sp := &SchemaProxy{ sp := &SchemaProxy{
schema: &low.NodeReference[*lowbase.SchemaProxy]{ schema: &low.NodeReference[*lowbase.SchemaProxy]{
Value: &lowbase.SchemaProxy{ Value: &lowbase.SchemaProxy{
Reference: ref, Reference: ref,
}, },
}, },
} }
node, err := sp.MarshalYAML() node, err := sp.MarshalYAML()
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, node, utils.CreateRefNode("#/components/schemas/MySchema")) assert.Equal(t, node, utils.CreateRefNode("#/components/schemas/MySchema"))
} }
func TestSchemaProxy_MarshalYAML_InlineCircular(t *testing.T) { func TestSchemaProxy_MarshalYAML_InlineCircular(t *testing.T) {
const ymlComponents = `openapi: 3.1 const ymlComponents = `openapi: 3.1
components: components:
schemas: schemas:
spice: spice:
@@ -135,37 +135,37 @@ components:
rice: rice:
$ref: '#/components/schemas/nice'` $ref: '#/components/schemas/nice'`
idx := func() *index.SpecIndex { idx := func() *index.SpecIndex {
var idxNode yaml.Node var idxNode yaml.Node
err := yaml.Unmarshal([]byte(ymlComponents), &idxNode) err := yaml.Unmarshal([]byte(ymlComponents), &idxNode)
assert.NoError(t, err) assert.NoError(t, err)
return index.NewSpecIndexWithConfig(&idxNode, index.CreateOpenAPIIndexConfig()) return index.NewSpecIndexWithConfig(&idxNode, index.CreateOpenAPIIndexConfig())
}() }()
resolver := index.NewResolver(idx) resolver := index.NewResolver(idx)
resolver.CheckForCircularReferences() resolver.CheckForCircularReferences()
const ymlSchema = `properties: const ymlSchema = `properties:
rice: rice:
$ref: '#/components/schemas/nice'` $ref: '#/components/schemas/nice'`
var node yaml.Node var node yaml.Node
_ = yaml.Unmarshal([]byte(ymlSchema), &node) _ = yaml.Unmarshal([]byte(ymlSchema), &node)
lowProxy := new(lowbase.SchemaProxy) lowProxy := new(lowbase.SchemaProxy)
err := lowProxy.Build(context.Background(), &node, node.Content[0], idx) err := lowProxy.Build(context.Background(), &node, node.Content[0], idx)
assert.NoError(t, err) assert.NoError(t, err)
lowRef := low.NodeReference[*lowbase.SchemaProxy]{ lowRef := low.NodeReference[*lowbase.SchemaProxy]{
Value: lowProxy, Value: lowProxy,
KeyNode: &node, KeyNode: &node,
} }
spEmpty := NewSchemaProxy(nil) spEmpty := NewSchemaProxy(nil)
assert.Nil(t, spEmpty.GetSchemaKeyNode()) assert.Nil(t, spEmpty.GetSchemaKeyNode())
sp := NewSchemaProxy(&lowRef) sp := NewSchemaProxy(&lowRef)
assert.NotNil(t, sp.GetSchemaKeyNode()) assert.NotNil(t, sp.GetSchemaKeyNode())
rend, _ := sp.MarshalYAMLInline() rend, _ := sp.MarshalYAMLInline()
assert.NotNil(t, rend) assert.NotNil(t, rend)
} }

View File

@@ -114,24 +114,17 @@ func FindNodesWithoutDeserializing(node *yaml.Node, jsonPath string) ([]*yaml.No
// this can spin out, to lets gatekeep it. // this can spin out, to lets gatekeep it.
done := make(chan bool) done := make(chan bool)
eChan := make(chan error)
var results []*yaml.Node var results []*yaml.Node
timeout, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) timeout, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel() defer cancel()
go func(d chan bool, e chan error) { go func(d chan bool) {
var er error results, _ = path.Find(node)
results, er = path.Find(node)
if er != nil {
e <- er
}
done <- true done <- true
}(done, eChan) }(done)
select { select {
case <-done: case <-done:
return results, nil return results, nil
case er := <-eChan:
return nil, er
case <-timeout.Done(): case <-timeout.Done():
return nil, fmt.Errorf("node lookup timeout exceeded") return nil, fmt.Errorf("node lookup timeout exceeded")
} }

View File

@@ -913,3 +913,20 @@ func TestDetermineJSONWhitespaceLength_None(t *testing.T) {
someBytes := []byte(`{"hello": "world"}`) someBytes := []byte(`{"hello": "world"}`)
assert.Equal(t, 0, DetermineWhitespaceLength(string(someBytes))) assert.Equal(t, 0, DetermineWhitespaceLength(string(someBytes)))
} }
func TestTimeoutFind(t *testing.T) {
a := &yaml.Node{
Value: "chicken",
}
b := &yaml.Node{
Value: "nuggets",
}
// loopy loop.
a.Content = append(a.Content, b)
b.Content = append(b.Content, a)
nodes, err := FindNodesWithoutDeserializing(a, "$..nuggets")
assert.Error(t, err)
assert.Nil(t, nodes)
}