firecracker icon indicating copy to clipboard operation
firecracker copied to clipboard

Use Python generated client in the testing framework

Open gbionescu opened this issue 5 years ago • 6 comments

We need to generate the Python API client to use inside the testing framework instead of writing our own API request classes.

This effort would help in making sure that any YAML change is reflected in the way that API requests are done and reducing framework code.

Things to keep in mind:

  • The python client would have to be generated each time the YAML file is changed. This would add a few problems since the codegen step could take a while to finish, so some investigation would initially have to be done to make sure that we don't spend a lot of time here. Some ideas to speed up things would be to check the YAML version or store a hash of the last checked YAML file.
  • The resources.py file would be replaced.
  • API requests should be timed - see decorators here.
  • The MicroVM class will suffer a lot of changes, so it would be a good opportunity to clean up some of the things there.

gbionescu avatar Nov 25 '20 10:11 gbionescu

I wouldn't mind taking a look at this. Is there a specific method we would want to use to generate the code? I assume the YAML file mentioned is the firecracker.yaml file?

EvanJP avatar Nov 28 '20 07:11 EvanJP

If there are more concrete ideas on how to approach the code generation (forgive my ignorance on how we're supposed to generate it), I would be glad to try to work on this. Is the codegen client supposed to come from swagger?

EvanJP avatar Dec 01 '20 16:12 EvanJP

Yes, use firecracker.yaml to generate client code; yes, the code-generator can come from swagger (there are possibly others out there too, haven't checked).

acatangiu avatar Dec 02 '20 10:12 acatangiu

@EvanJP I've used swagger-codegen in the past to generate the client code.

There is one thing to take care with the generated code: I didn't find a simple method of making it aware that the requests are done through a socket path, so I basically had to override the way that the swagger client classes are built. I can paste the snippet that I used, but perhaps we can look into it once you manage to generate the code and actually hit that issue.

gbionescu avatar Dec 02 '20 16:12 gbionescu

@gc-plp I've generated the python code, and I think I see what you mean by the lack of options to make it aware of a UNIX socket path. I see that the go-swagger community has implemented it, but alas that is go and not python.

Are there any files other than resources.py and microvm.py to be aware of? Also what sort of "clean-up" would be necessary for the MicroVM class?

EvanJP avatar Dec 10 '20 20:12 EvanJP

@EvanJP, the way I did it was to create a dummy class that wraps UDS calls:

import requests_unixsocket

class UDSRequests():
    """
    Dummy class that overrides the default PUT so that it works over UDS.
    """
    def __init__(self, configuration, pools_size=4, maxsize=None):
        self._configuration = configuration

    def PUT(self, url, headers=None, query_params=None, post_params=None,
            body=None, _preload_content=True, _request_timeout=None):
        session = requests_unixsocket.Session()

        # TODO check response and raise on error
        session.put("http+unix://%s" % (url),
                    headers=headers,
                    json=body)

And then kind of hacked my way through the swagger code by overriding the RESTClientObject attribute:

swagger_client.rest.RESTClientObject = uds.UDSRequests

This could probably be done in a nicer way, but didn't have the time to explore other options.

As for the cleanup logic, you'd probably have to reverse all the steps that you did to bring up a VM: stop the instance, clean up the network namespace and so on.

gbionescu avatar Dec 14 '20 12:12 gbionescu