Skip to content
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
32 changes: 0 additions & 32 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -297,24 +297,8 @@ github.com/pulumi/esc v0.17.0 h1:oaVOIyFTENlYDuqc3pW75lQT9jb2cd6ie/4/Twxn66w=
github.com/pulumi/esc v0.17.0/go.mod h1:XnSxlt5NkmuAj304l/gK4pRErFbtqq6XpfX1tYT9Jbc=
github.com/pulumi/inflector v0.1.1 h1:dvlxlWtXwOJTUUtcYDvwnl6Mpg33prhK+7mzeF+SobA=
github.com/pulumi/inflector v0.1.1/go.mod h1:HUFCjcPTz96YtTuUlwG3i3EZG4WlniBvR9bd+iJxCUY=
github.com/pulumi/pulumi/pkg/v3 v3.213.0 h1:Vs7uooioUTgoe9OiusNIr3n5Emjw7gU38NCp3gGzZq0=
github.com/pulumi/pulumi/pkg/v3 v3.213.0/go.mod h1:rqMSDY7SPN6ymilqjHImS+z+TsHCs5rqcJVhDNAFvuY=
github.com/pulumi/pulumi/pkg/v3 v3.214.1 h1:cijCDh4ogkDHqaWSoqCQQyd1LV6DSQz6DCp0UtMLGHE=
github.com/pulumi/pulumi/pkg/v3 v3.214.1/go.mod h1:H4qigpfVeq6ggOAivUhdQxLkp/0upgzMKcCpK9NwatQ=
github.com/pulumi/pulumi/pkg/v3 v3.215.0 h1:/3HEWgLEa8QDqwQd6qv1A66c5+9azGaVtpCUXTkFnr0=
github.com/pulumi/pulumi/pkg/v3 v3.215.0/go.mod h1:5kx6//mZ6u6KtG3zPyvxgGnc17gZqUFQ5n+GeYY1gT8=
github.com/pulumi/pulumi/pkg/v3 v3.216.0 h1:ntOGKRwz0yjpGyVW/8sFJ/s4U+F2MGtqRNSH5KKqdf0=
github.com/pulumi/pulumi/pkg/v3 v3.216.0/go.mod h1:VnsybpTY6ZhKnkI37XO6ic3aH7XbseeSXNso0bNPpMM=
github.com/pulumi/pulumi/pkg/v3 v3.217.0 h1:GG3I8ibscYpGJAWRpDXfEDkxZ4h8pp5Y0nIedQ464yI=
github.com/pulumi/pulumi/pkg/v3 v3.217.0/go.mod h1:WyAs4mbYhnS5RZDt8ZLNtv3G71TcRk17PIFOlI/DV+Q=
github.com/pulumi/pulumi/sdk/v3 v3.213.0 h1:ICp0WJlTShaTLrx2fDI52fJ3xwCf1h8T8tVrKDRNUB4=
github.com/pulumi/pulumi/sdk/v3 v3.213.0/go.mod h1:Bn5Z9Rzp1lPqdAccaB+F2ivUBiamEl2TNR3Gg/h7iLs=
github.com/pulumi/pulumi/sdk/v3 v3.214.1 h1:mzln0QPQGUu527LxaMEx0e37V6tG48r5CPAo5mn/bAk=
github.com/pulumi/pulumi/sdk/v3 v3.214.1/go.mod h1:Bn5Z9Rzp1lPqdAccaB+F2ivUBiamEl2TNR3Gg/h7iLs=
github.com/pulumi/pulumi/sdk/v3 v3.215.0 h1:XZMiv9aSE1pD3kW4JpA53cy7mFflbJYn1fFKH1NMIAY=
github.com/pulumi/pulumi/sdk/v3 v3.215.0/go.mod h1:Bn5Z9Rzp1lPqdAccaB+F2ivUBiamEl2TNR3Gg/h7iLs=
github.com/pulumi/pulumi/sdk/v3 v3.216.0 h1:8CkcMeg/fUI+nOp0cM4XJQIn1X0Q0CeOu6ZUv9pw17A=
github.com/pulumi/pulumi/sdk/v3 v3.216.0/go.mod h1:9bgwXx4+QuVuIBgivyiVY/f4X16DgMm9gGHgAcbPxk0=
github.com/pulumi/pulumi/sdk/v3 v3.217.0 h1:S/gWOMtpgHarSkQD43gBBoEAmGLgXYJcwGHrnPRrGyY=
github.com/pulumi/pulumi/sdk/v3 v3.217.0/go.mod h1:ZOBPPC2NZOZf729AdCX+CctfNc5SN6aJh0bdqNdzQC4=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
Expand Down Expand Up @@ -408,8 +392,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
Expand All @@ -418,8 +400,6 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
Expand All @@ -428,17 +408,13 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand All @@ -457,20 +433,14 @@ golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
Expand All @@ -481,8 +451,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
187 changes: 187 additions & 0 deletions pkg/exclusion_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package pkg

import (
"testing"

"github.com/cloudy-sky-software/pulschema/pkg/exclusions"
"github.com/stretchr/testify/assert"
)

// TestExclusionIntegration tests the new exclusion feature with OpenAPIContext
func TestExclusionIntegration(t *testing.T) {
// Test 1: Backward compatibility with ExcludedPaths
t.Run("BackwardCompatibility", func(t *testing.T) {
ctx := &OpenAPIContext{
ExcludedPaths: []string{"/health", "/metrics"},
}

// Simulate what GatherResourcesFromAPI would do
evaluator, err := exclusions.NewExclusionEvaluator(ctx.Exclusions, ctx.ExcludedPaths)
assert.NoError(t, err)
assert.NotNil(t, evaluator)

// Test exclusions
assert.True(t, evaluator.ShouldExclude("GET", "/health"))
assert.True(t, evaluator.ShouldExclude("POST", "/health"))
assert.True(t, evaluator.ShouldExclude("GET", "/metrics"))
assert.False(t, evaluator.ShouldExclude("GET", "/api/users"))
})

// Test 2: New wildcard exclusions
t.Run("WildcardExclusions", func(t *testing.T) {
ctx := &OpenAPIContext{
Exclusions: []exclusions.Exclusion{
{
PathPattern: "/internal/*",
PatternType: exclusions.PatternTypeWildcard,
},
},
}

evaluator, err := exclusions.NewExclusionEvaluator(ctx.Exclusions, nil)
assert.NoError(t, err)

assert.True(t, evaluator.ShouldExclude("GET", "/internal/debug"))
assert.True(t, evaluator.ShouldExclude("POST", "/internal/debug"))
assert.False(t, evaluator.ShouldExclude("GET", "/internal/debug/deep"))
assert.False(t, evaluator.ShouldExclude("GET", "/api/users"))
})

// Test 3: Method-specific exclusions
t.Run("MethodSpecificExclusions", func(t *testing.T) {
ctx := &OpenAPIContext{
Exclusions: []exclusions.Exclusion{
{
Method: "GET",
PathPattern: "/debug/*",
PatternType: exclusions.PatternTypeWildcard,
},
},
}

evaluator, err := exclusions.NewExclusionEvaluator(ctx.Exclusions, nil)
assert.NoError(t, err)

assert.True(t, evaluator.ShouldExclude("GET", "/debug/metrics"))
assert.False(t, evaluator.ShouldExclude("POST", "/debug/metrics"))
assert.False(t, evaluator.ShouldExclude("GET", "/api/debug"))
})

// Test 4: Regex exclusions
t.Run("RegexExclusions", func(t *testing.T) {
ctx := &OpenAPIContext{
Exclusions: []exclusions.Exclusion{
{
PathPattern: "^/api/v[0-9]+/test/.*",
PatternType: exclusions.PatternTypeRegex,
},
},
}

evaluator, err := exclusions.NewExclusionEvaluator(ctx.Exclusions, nil)
assert.NoError(t, err)

assert.True(t, evaluator.ShouldExclude("GET", "/api/v1/test/endpoint"))
assert.True(t, evaluator.ShouldExclude("POST", "/api/v2/test/resource"))
assert.False(t, evaluator.ShouldExclude("GET", "/api/vX/test/endpoint"))
assert.False(t, evaluator.ShouldExclude("GET", "/api/v1/prod/endpoint"))
})

// Test 5: Mixed configuration
t.Run("MixedConfiguration", func(t *testing.T) {
ctx := &OpenAPIContext{
ExcludedPaths: []string{"/health"},
Exclusions: []exclusions.Exclusion{
{
Method: "GET",
PathPattern: "/debug/*",
PatternType: exclusions.PatternTypeWildcard,
},
{
PathPattern: "/internal/**",
PatternType: exclusions.PatternTypeWildcard,
},
},
}

evaluator, err := exclusions.NewExclusionEvaluator(ctx.Exclusions, ctx.ExcludedPaths)
assert.NoError(t, err)

// Legacy exclusion
assert.True(t, evaluator.ShouldExclude("GET", "/health"))
assert.True(t, evaluator.ShouldExclude("POST", "/health"))

// Method-specific exclusion
assert.True(t, evaluator.ShouldExclude("GET", "/debug/metrics"))
assert.False(t, evaluator.ShouldExclude("POST", "/debug/metrics"))

// Wildcard exclusion (all methods)
assert.True(t, evaluator.ShouldExclude("GET", "/internal/a/b/c"))
assert.True(t, evaluator.ShouldExclude("DELETE", "/internal/x/y/z"))
})

// Test 6: Invalid configuration error handling
t.Run("InvalidConfiguration", func(t *testing.T) {
ctx := &OpenAPIContext{
Exclusions: []exclusions.Exclusion{
{
PathPattern: "", // Empty pattern - should fail
},
},
}

evaluator, err := exclusions.NewExclusionEvaluator(ctx.Exclusions, nil)
assert.Error(t, err)
assert.Nil(t, evaluator)
})

// Test 7: Complex real-world scenario
t.Run("RealWorldScenario", func(t *testing.T) {
ctx := &OpenAPIContext{
Exclusions: []exclusions.Exclusion{
// Exclude all internal paths
{
PathPattern: "/internal/**",
PatternType: exclusions.PatternTypeWildcard,
},
// Exclude GET requests to debug endpoints
{
Method: "GET",
PathPattern: "/debug/*",
PatternType: exclusions.PatternTypeWildcard,
},
// Exclude versioned test endpoints using regex
{
PathPattern: "^/api/v[0-9]+/test/.*",
PatternType: exclusions.PatternTypeRegex,
},
// Exclude specific admin operations
{
Method: "POST",
PathPattern: "/admin/users",
PatternType: exclusions.PatternTypeExact,
},
{
Method: "DELETE",
PathPattern: "/admin/users",
PatternType: exclusions.PatternTypeExact,
},
},
}

evaluator, err := exclusions.NewExclusionEvaluator(ctx.Exclusions, nil)
assert.NoError(t, err)
assert.Equal(t, 5, evaluator.Count())

// Test each exclusion
assert.True(t, evaluator.ShouldExclude("GET", "/internal/secret"))
assert.True(t, evaluator.ShouldExclude("GET", "/debug/metrics"))
assert.False(t, evaluator.ShouldExclude("POST", "/debug/metrics"))
assert.True(t, evaluator.ShouldExclude("GET", "/api/v1/test/foo"))
assert.False(t, evaluator.ShouldExclude("GET", "/api/v1/prod/foo"))
assert.True(t, evaluator.ShouldExclude("POST", "/admin/users"))
assert.True(t, evaluator.ShouldExclude("DELETE", "/admin/users"))
assert.False(t, evaluator.ShouldExclude("GET", "/admin/users"))
assert.False(t, evaluator.ShouldExclude("PATCH", "/admin/users"))
})
}
Loading