open-traffic-generator / snappi

Open Traffic Generator SDK in Python and Go
MIT License
69 stars 7 forks source link

GoSnappi HTTP Server: Incorrect response object on client side #142

Closed rudranil-das closed 2 years ago

rudranil-das commented 2 years ago

Snappi version: This issue is observed with dev version of snappi [https://github.com/open-traffic-generator/snappi/tree/gosnappi_server_tmp/gosnappi]

Ideally the server implementation should not have any impact on the snappi client-side. But I am observing anomaly in the client-side results (python client) as mentioned below,

In python-client, we verify if the response of a snappi api has required constructs (e.g. if set_config has 200 ok response, it should have 'warnings')

res = api.set_config(cfg)
if len(res.warnings) > 0:
    print("Warnings: {}".format(res.warnings))

With snappi-version 0.6.21, this response object ('res') is as expected,

(Pdb) p type(res)
<class 'snappi.snappi.ResponseWarning'>
(Pdb) p dir(res)
['DICT', 'JSON', 'YAML', '_DEFAULTS', '_REQUIRED', '_TYPES', '__class__', '__copy__', '__deepcopy__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '_choice', '_decode', '_encode', '_get_child_class', '_get_property', '_has_choice', '_parent', '_properties', '_set_choice', '_set_property', '_validate_required', '_validate_types', 'clone', 'deserialize', 'get', 'parent', 'serialize', 'types_validation', 'validate', 'validate_binary', 'validate_bool', 'validate_float', 'validate_hex', 'validate_integer', 'validate_ipv4', 'validate_ipv6', 'validate_list', 'validate_mac', 'validate_string', 'warnings']
(Pdb) p res.warnings
[]

But with snappi version with http implementation, the response object looks incorrect

(Pdb) p type(res)
<class 'requests.models.Response'>
(Pdb) p dir(res)
['__attrs__', '__bool__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__nonzero__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_content', '_content_consumed', '_next', 'apparent_encoding', 'close', 'connection', 'content', 'cookies', 'elapsed', 'encoding', 'headers', 'history', 'is_permanent_redirect', 'is_redirect', 'iter_content', 'iter_lines', 'json', 'links', 'next', 'ok', 'raise_for_status', 'raw', 'reason', 'request', 'status_code', 'text', 'url']
(Pdb) p res.warnings
*** AttributeError: 'Response' object has no attribute 'warnings'
(Pdb) 

As a result, basic E2E test is failing.

alakendu commented 2 years ago

I think this is coming because server is sending text rather than json. This should fix if we use WriteHeader after Header

func WriteJSONResponse(w http.ResponseWriter, statuscode int, data JSONWriter) (int, error) {
    w.Header().Set("Content-Type", "application/json; charset=UTF-8")
    w.WriteHeader(statuscode)
    return w.Write([]byte(data.ToJson()))
}
alakendu commented 2 years ago

@jkristia I think this is issue in goserver generation. Probably kind of restriction in net/htp that put WriteHeader() after Hear()set(). Please review

alakendu commented 2 years ago

This should address in https://github.com/open-traffic-generator/snappi/releases/tag/v0.7.1