@@ -22,7 +22,9 @@ import (
2222
2323 "github.com/cucumber/godog"
2424 "github.com/seldonio/seldon-core/apis/go/v2/mlops/v2_dataplane"
25+ "github.com/sirupsen/logrus"
2526 "google.golang.org/grpc/metadata"
27+ "google.golang.org/protobuf/encoding/protojson"
2628)
2729
2830type inference struct {
@@ -33,6 +35,7 @@ type inference struct {
3335 httpPort uint
3436 lastHTTPResponse * http.Response
3537 lastGRPCResponse lastGRPCResponse
38+ log logrus.FieldLogger
3639}
3740
3841func LoadInferenceSteps (scenario * godog.ScenarioContext , w * World ) {
@@ -61,6 +64,14 @@ func LoadInferenceSteps(scenario *godog.ScenarioContext, w *World) {
6164 scenario .Step (`^expect http response body to contain JSON:$` , w .infer .httpRespCheckBodyContainsJSON )
6265 scenario .Step (`^expect gRPC response body to contain JSON:$` , w .infer .gRPCRespCheckBodyContainsJSON )
6366 scenario .Step (`^expect gRPC response error to contain "([^"]+)"` , w .infer .gRPCRespContainsError )
67+ scenario .Step (`^expect gRPC response to not return an error$` , w .infer .gRPCRespContainsNoError )
68+ scenario .Step (`^expect http response body to contain valid JSON$` , func () error {
69+ testModel , ok := testModels [w .currentModel .modelType ]
70+ if ! ok {
71+ return fmt .Errorf ("model %s not found" , w .currentModel .modelType )
72+ }
73+ return w .infer .doHttpRespCheckBodyContainsJSON (testModel .ValidJSONResponse )
74+ })
6475}
6576
6677func (i * inference ) doHTTPModelInferenceRequest (ctx context.Context , modelName , body string ) error {
@@ -102,7 +113,7 @@ func (i *inference) sendHTTPModelInferenceRequestFromModel(ctx context.Context,
102113 return fmt .Errorf ("could not find test model %s" , m .model .Name )
103114 }
104115
105- return i .doHTTPModelInferenceRequest (ctx , m .modelName , testModel .ValidInferenceRequest )
116+ return i .doHTTPModelInferenceRequest (ctx , m .modelName , testModel .ValidHTTPInferenceRequest )
106117}
107118
108119func httpScheme (useSSL bool ) string {
@@ -121,7 +132,7 @@ func (i *inference) sendGRPCModelInferenceRequestFromModel(ctx context.Context,
121132 if ! ok {
122133 return fmt .Errorf ("could not find test model %s" , m .model .Name )
123134 }
124- return i .doGRPCModelInferenceRequest (ctx , m .modelName , testModel .ValidInferenceRequest )
135+ return i .doGRPCModelInferenceRequest (ctx , m .modelName , testModel .ValidGRPCInferenceRequest )
125136}
126137
127138func (i * inference ) doGRPCModelInferenceRequest (
@@ -130,15 +141,19 @@ func (i *inference) doGRPCModelInferenceRequest(
130141 payload string ,
131142) error {
132143 var req v2_dataplane.ModelInferRequest
133- if err := json .Unmarshal ([]byte (payload ), & req ); err != nil {
144+ if err := protojson .Unmarshal ([]byte (payload ), & req ); err != nil {
134145 return fmt .Errorf ("could not unmarshal gRPC json payload: %w" , err )
135146 }
136147 req .ModelName = model
137148
138149 md := metadata .Pairs ("seldon-model" , model )
139150 ctx = metadata .NewOutgoingContext (ctx , md )
140151
152+ i .log .Debugf ("sending gRPC model inference %+v" , & req )
153+
141154 resp , err := i .grpc .ModelInfer (ctx , & req )
155+ i .log .Debugf ("grpc model infer response: %+v" , resp )
156+ i .log .Debugf ("grpc model infer error: %+v" , err )
142157
143158 i .lastGRPCResponse .response = resp
144159 i .lastGRPCResponse .err = err
@@ -212,6 +227,16 @@ func jsonContainsObjectSubset(jsonStr, needleStr string) (bool, error) {
212227 return containsSubset (needle , hay ), nil
213228}
214229
230+ func (i * inference ) gRPCRespContainsNoError () error {
231+ if i .lastGRPCResponse .err != nil {
232+ return fmt .Errorf ("grpc response contains error: %w" , i .lastGRPCResponse .err )
233+ }
234+ if i .lastGRPCResponse .response == nil {
235+ return errors .New ("grpc contains no response" )
236+ }
237+ return nil
238+ }
239+
215240func (i * inference ) gRPCRespContainsError (err string ) error {
216241 if i .lastGRPCResponse .err == nil {
217242 return errors .New ("no gRPC response error found" )
@@ -226,6 +251,9 @@ func (i *inference) gRPCRespContainsError(err string) error {
226251
227252func (i * inference ) gRPCRespCheckBodyContainsJSON (expectJSON * godog.DocString ) error {
228253 if i .lastGRPCResponse .response == nil {
254+ if i .lastGRPCResponse .err != nil {
255+ return fmt .Errorf ("no gRPC response, error found: %s" , i .lastGRPCResponse .err .Error ())
256+ }
229257 return errors .New ("no gRPC response found" )
230258 }
231259
@@ -234,6 +262,7 @@ func (i *inference) gRPCRespCheckBodyContainsJSON(expectJSON *godog.DocString) e
234262 return fmt .Errorf ("could not marshal gRPC json: %w" , err )
235263 }
236264
265+ i .log .Debugf ("checking gRPC response: %s contains %s" , string (gotJson ), expectJSON .Content )
237266 ok , err := jsonContainsObjectSubset (string (gotJson ), expectJSON .Content )
238267 if err != nil {
239268 return fmt .Errorf ("could not check if json contains object: %w" , err )
@@ -247,6 +276,10 @@ func (i *inference) gRPCRespCheckBodyContainsJSON(expectJSON *godog.DocString) e
247276}
248277
249278func (i * inference ) httpRespCheckBodyContainsJSON (expectJSON * godog.DocString ) error {
279+ return i .doHttpRespCheckBodyContainsJSON (expectJSON .Content )
280+ }
281+
282+ func (i * inference ) doHttpRespCheckBodyContainsJSON (expectJSON string ) error {
250283 if i .lastHTTPResponse == nil {
251284 return errors .New ("no http response found" )
252285 }
@@ -256,7 +289,8 @@ func (i *inference) httpRespCheckBodyContainsJSON(expectJSON *godog.DocString) e
256289 return fmt .Errorf ("could not read response body: %w" , err )
257290 }
258291
259- ok , err := jsonContainsObjectSubset (string (body ), expectJSON .Content )
292+ i .log .Debugf ("checking HTTP response: %s contains %s" , string (body ), expectJSON )
293+ ok , err := jsonContainsObjectSubset (string (body ), expectJSON )
260294 if err != nil {
261295 return fmt .Errorf ("could not check if json contains object: %w" , err )
262296 }
0 commit comments