Testing any piece of software requires writing another software to test it. Apart from writing automated tests, developers would just like to examine how do some functionalities behave. If the specification changes frequently or the software is deployed in many environments, an easy-access tool will save lots of time - instead of preparing disposable testing scripts. In case of webservices, such tool would be extremely useful.
I found an interesting jquery plugin, jquery terminal (available on github) developed by Jakub Jankiewicz. It provides a browser terminal emulator communicating with a server-side script. This enables to provide any server-side functionalities inside any browser! And you don't have to worry about the security - you can add authentication which works similarly as just submitting a login form (http or https via POST method).
As I was developing a thrift backend service, where commands changed dynamically, I decided to provide a console tool to display results of all thrift commands from browser level. I've combined the jquery terminal with symfony2 and a thrift backend service. The result is fantastic!
implementation
The jquery terminal is accessible inside a symfony2 application. It is supposed to emulate thrift communication and let the developer examine how does a backend service behave for any command you choose.
The terminal code (jquery plugin with all js/css assets) reside in a symfony bundle, which uses configuration specific for the backend service (connection parameters, etc). There is a Terminal class which provides business logic for the terminal service (just like the Demo class in the example provided by the author).
The javascript layer of the terminal handles the command line buffer, which - after enter key is pressed - sends a POST request to a URL specified in the jquery terminal definition. Now - the server-side can be in fact any platform - in this case it was PHP. To be precise, the request goes to the URL of a custom controller action defined in symfony's routing.yml file.
The controller creates the Terminal instance using symfony's Dependency Injection. This class will handle the request, which is available in the $HTTP_RAW_POST_DATA. In the end of the controller, exit; command shall be added to ensure that symfony2 won't output HTML error response to the console (when a controller doesn't return any value, a sf2 exception is raised and returned as HTML to the requester, which in this case is the terminal).
To run a specific thrift command, provide one generic terminal command per backend service (e.g. execute) and pass the thrift command name as the terminal command parameter. For example, if your thrift command is get_users, then your terminal command could be execute get_users. In such case, the Terminal class must implement public execute command accepting at least one parameter - the thrift command name:
public function execute($command)
By default, the plugin provides basic built-in security mechanism which accepts $token parameter as the service class first parameter (for all methods), so it makes our command look like:
public function execute($token, $command)Additionally, if the
get_users thrift command accepts any parameters, provide additional parameter for the, which is null by default. The easiest solution is to use JSON format in the terminal, e.g.
execute get_users {"country_name":"Poland"}
which will return all users from Poland. Finally, our Terminal command will have the following header:
public function execute($token, $command, $json_params = null)The only thing you should impement here is to cast JSON to thrift parameters (but it depends mostly on your thrift service commands structure).
In the end, you may disable xdebug in the symfony controller code to make sure that no xdebug output will be displayed on the terminal (in case the PHP server configuration has xdebug installed).
customization
You can provide your custom public methods for the terminal in theTerminal class. These methods are automatically displayed in the built-in help command. For example, define a terminal command that lists all commands available in the thrift service. Such method may use reflection to list all available methods and display them on the screen (kinda help command). Thanks to it - each time when thrift communication layer is updated, the terminal tool will return current state of the communication (in other words - once you installed the terminal, you may modify thrift and the terminal will catch up with the changes).
all is a good read but you don't show your actual implementation, it would actually be more useful. Also you say that this is a useful tool many times but you don't explain or convey how is it useful and in which ways. Or at least i don't get that part clear. Please provide repo and elaborate further on the idea.
ReplyDelete@Luis, thanks for your comment. I agree that the implementation would be of much use. I couldn't post my exact implementation due to the NDA ;), that's why I tried to describe overall solution. but I'll try to find time to provide example implementation.
DeletePS the main usefullness of this feature is that you have a direct behavior testing tool. You don't have to write any tests to check the return result structure. Without such thing developers (working with services or webservices) have to write dozens of disposable (one-time-use) script or compilable tests to check behavior of each command. And it takes time.
Delete