Skip to content
Open
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: 32 additions & 0 deletions conformance/tests/inferencepool_controllername.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package tests

import (
"testing"

"sigs.k8s.io/gateway-api/conformance/utils/suite"
"sigs.k8s.io/gateway-api/pkg/features"

"sigs.k8s.io/gateway-api-inference-extension/conformance/resources"
k8sutils "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/kubernetes"
)

func init() {
ConformanceTests = append(ConformanceTests, InferencePoolControllerName)
}

var InferencePoolControllerName = suite.ConformanceTest{
ShortName: "InferencePoolControllerName",
Description: "InferencePool status parents should include controllerName",
Manifests: []string{"tests/inferencepool_accepted.yaml"},
Features: []features.FeatureName{
features.FeatureName("SupportInferencePool"),
features.SupportGateway,
},
Test: func(t *testing.T, s *suite.ConformanceTestSuite) {
poolNN := resources.PrimaryInferencePoolNN

t.Run("InferencePool parent status reports controllerName", func(t *testing.T) {
k8sutils.InferencePoolMustHaveControllerName(t, s.Client, poolNN)
})
},
}
29 changes: 29 additions & 0 deletions conformance/utils/kubernetes/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,35 @@ func InferencePoolMustHaveNoParents(t *testing.T, c client.Reader, poolNN types.
t.Logf("Successfully verified that InferencePool %s has no parent statuses.", poolNN.String())
}

func InferencePoolMustHaveControllerName(
t *testing.T,
client client.Client,
poolNN types.NamespacedName,
) {
t.Helper()

var pool inferenceapi.InferencePool

require.Eventually(t, func() bool {
err := client.Get(context.Background(), poolNN, &pool)
if err != nil {
return false
}

if len(pool.Status.Parents) == 0 {
return false
}

for _, parent := range pool.Status.Parents {
if parent.ControllerName == "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reading the API here, I'm not sure we want to enforce the controllerName to be populated. It only says "MAY populate". @robscott @danehans

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, we're following RFC-2119 terminology here, so this is currently optional.

With that said, if we do a survey of implementations and find that most/all are already populating this, I think it would make sense to turn MAY into MUST to make this a requirement. I just don't want the conformance test to get ahead of the API spec here. Since the API is already GA, we'll have to be very careful about tightening requirements and ensure that all implementations (or at least as many as we can reach out to) are onboard with this change.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for calling that out.

I see the concern with line 247 enforcing controllerName, since the API currently marks it as a MAY field per RFC-2119. I don’t want to tighten conformance beyond what the spec guarantees.

Would you recommend removing this check entirely for now, or is there an alternative pattern you’d prefer ?

return false
}
}

return true
}, time.Minute, time.Second)
}

// HTTPRouteMustBeAcceptedAndResolved waits for the specified HTTPRoute
// to be Accepted and have its references resolved by the specified Gateway.
// It uses the upstream Gateway API's HTTPRouteMustHaveCondition helper.
Expand Down