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
25 changes: 25 additions & 0 deletions central/graphql/resolvers/cluster_vulnerabilities_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package resolvers

import (
"reflect"
"testing"
)

func TestClusterVulnerabilityResolverType(t *testing.T) {
// The implementation type has four more methods than the interface it implements.
//
// 17 - SnoozeExpiry
// 18 - SnoozeStart
// 19 - Snoozed
// 24 - Type
//
// This can break graphQL queries to the system until
// https://github.com/graph-gophers/graphql-go/issues/763 is fixed.
//
// TODO(ROX-35654): Unskip this tests.
t.Skip("Interface and implementation types do not have aligned method indices.")
Comment thread
rhybrillou marked this conversation as resolved.
resolverInterface := reflect.TypeOf((*ClusterVulnerabilityResolver)(nil)).Elem()
resolverImplType := reflect.TypeOf((*clusterCVEResolver)(nil))

validateAlignedMethodIndex(t, resolverInterface, resolverImplType)
}
23 changes: 23 additions & 0 deletions central/graphql/resolvers/image_components_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package resolvers

import (
"reflect"
"testing"
)

func TestImageComponentResolverType(t *testing.T) {
// The implementation type has two more methods than the interface it implements.
//
// 0 - Architecture
// 7 - ImageId
//
// This can break graphQL queries to the system until
// https://github.com/graph-gophers/graphql-go/issues/763 is fixed.
//
// TODO(ROX-35654): Unskip this tests.
t.Skip("Interface and implementation types do not have aligned method indices.")
resolverInterface := reflect.TypeOf((*ImageComponentResolver)(nil)).Elem()
resolverImplType := reflect.TypeOf((*imageComponentV2Resolver)(nil))

validateAlignedMethodIndex(t, resolverInterface, resolverImplType)
}
20 changes: 20 additions & 0 deletions central/graphql/resolvers/image_resolver_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package resolvers

import (
"reflect"
"testing"
)

func TestImageResolverType(t *testing.T) {
resolverInterface := reflect.TypeOf((*ImageResolver)(nil)).Elem()
resolverImplType := reflect.TypeOf((*imageResolver)(nil))

validateAlignedMethodIndex(t, resolverInterface, resolverImplType)
}

func TestImageV2ResolverType(t *testing.T) {
resolverInterface := reflect.TypeOf((*ImageResolver)(nil)).Elem()
resolverImplType := reflect.TypeOf((*imageV2Resolver)(nil))

validateAlignedMethodIndex(t, resolverInterface, resolverImplType)
}
26 changes: 26 additions & 0 deletions central/graphql/resolvers/image_vulnerabilities_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package resolvers

import (
"reflect"
"testing"
)

func TestImageVulnerabilityResolverType(t *testing.T) {
// The implementation type has five more methods than the interface it implements.
//
// 2 - ComponentId
// 12 - FirstImageOccurrence
// 14 - ID
// 19 - ImageId
// 32 - State
//
// This can break graphQL queries to the system until
// https://github.com/graph-gophers/graphql-go/issues/763 is fixed.
//
// TODO(ROX-35654): Unskip this tests.
t.Skip("Interface and implementation types do not have aligned method indices.")
resolverInterface := reflect.TypeOf((*ImageVulnerabilityResolver)(nil)).Elem()
resolverImplType := reflect.TypeOf((*imageCVEV2Resolver)(nil))

validateAlignedMethodIndex(t, resolverInterface, resolverImplType)
}
13 changes: 13 additions & 0 deletions central/graphql/resolvers/node_components_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package resolvers

import (
"reflect"
"testing"
)

func TestNodeComponentResolverType(t *testing.T) {
resolverInterface := reflect.TypeOf((*NodeComponentResolver)(nil)).Elem()
resolverImplType := reflect.TypeOf((*nodeComponentResolver)(nil))

validateAlignedMethodIndex(t, resolverInterface, resolverImplType)
}
27 changes: 27 additions & 0 deletions central/graphql/resolvers/node_vulnerabilities_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package resolvers

import (
"reflect"
"testing"
)

func TestNodeVulnerabilityResolverType(t *testing.T) {
// The implementation type has six more methods than the interface it implements.
//
// 6 - ID
// 18 - Orphaned
// 19 - OrphanedTime
// 23 - SnoozeExpiry
// 24 - SnoozeStart
// 25 - Snoozed
//
// This can break graphQL queries to the system until
// https://github.com/graph-gophers/graphql-go/issues/763 is fixed.
//
// TODO(ROX-35654): Unskip this tests.
t.Skip("Interface and implementation types do not have aligned method indices.")
resolverInterface := reflect.TypeOf((*NodeVulnerabilityResolver)(nil)).Elem()
resolverImplType := reflect.TypeOf((*nodeCVEResolver)(nil))

validateAlignedMethodIndex(t, resolverInterface, resolverImplType)
}
80 changes: 80 additions & 0 deletions central/graphql/resolvers/test_utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package resolvers

import (
"reflect"
"testing"

"github.com/stretchr/testify/assert"
)

func validateAlignedMethodIndex(t testing.TB, type1 reflect.Type, type2 reflect.Type) {
t.Helper()

if !assert.Equalf(t, type1.NumMethod(), type2.NumMethod(),
"Types %s and %s have should have the same number of methods",
type1.String(), type2.String(),
) {
Comment thread
rhybrillou marked this conversation as resolved.
dumpTypeMethods(t, type1, type1.String(), false)
dumpTypeMethods(t, type2, type2.String(), false)
return
}
for i := range type1.NumMethod() {
m1 := type1.Method(i)
m2 := type2.Method(i)
assert.Equal(t, m1.Name, m2.Name)
}
}

// dumpTypeMethods uses reflection to dump the index and names of methods for a given type.
// It accepts any resolver value and outputs method information to the test logger.
//
// Example usage:
//
// // After creating a resolver instance in a test:
// componentResolver, err := resolver.ImageComponent(ctx, struct{ ID *graphql.ID }{ID: &componentID})
// require.NoError(t, err)
// dumpTypeMethods(t, reflect.TypeOf(componentResolver), "imageComponentV2Resolver")
//
// Output includes:
// - Index of each method (0-based)
// - Method name
// - Full method signature
// - Input parameter types
// - Output parameter types
func dumpTypeMethods(t testing.TB, typ reflect.Type, typeName string, verbose bool) {
t.Logf("\n=== Methods of %s ===", typeName)
t.Logf("Type: %s", typ.String())
t.Logf("Kind: %s", typ.Kind())
t.Logf("Number of methods: %d\n", typ.NumMethod())

for i := 0; i < typ.NumMethod(); i++ {
method := typ.Method(i)
t.Logf("[%d] %s", i, method.Name)

if verbose {
// Also log the method signature
methodType := method.Type
t.Logf(" Signature: %s", methodType.String())

// Log input parameters
numIn := methodType.NumIn()
if numIn > 0 {
t.Logf(" Inputs (%d):", numIn)
for j := 0; j < numIn; j++ {
t.Logf(" [%d] %s", j, methodType.In(j).String())
}
}

// Log return parameters
numOut := methodType.NumOut()
if numOut > 0 {
t.Logf(" Outputs (%d):", numOut)
for j := 0; j < numOut; j++ {
t.Logf(" [%d] %s", j, methodType.Out(j).String())
}
}
t.Logf("")
}
}
t.Logf("=== End of methods for %s ===\n", typeName)
}
Loading