Remote TestKit Thrift API
In response to our users' requests for the connectivity with CI (Continuous Integration) software, such as Jenkins, Remote TestKit has provided Thrift API, which enables to run automated test on actual remote devices. It's compatible with Java, PHP, Ruby, and Perl.
Previous Remote Testkit only allows a user to rent actual devices manually via our client software. So when the user want to connect a CI software, the user has to manually rent remote devices in advance.
Thanks to providing Remote TestKit Thrift API, a wide variety features of Remote TestKit can be automatically used by any programs without manual operation which has to be done before.
Example case 1:
Build a system to rent actual devices anytime new source code is committed, then take a result for a reference from running automated test via virtual adb/Xcode connection and recording a movie while running the test.
Example case 2:
Build a system to automatically take a screen capture for own company web site when new devices are released, then send the site images to operation team.
Structure of Remote TestKit Thrift API
Remote TestKit Thrift API is provided by using Apache Thrift framework.
Thrift was originally developed at Facebook to communicate among server programs which are developed by multiple languages. Today Evernote API, Hadoop, and other software allow users to develop a program to communicate them by Thrift.
https://en.wikipedia.org/wiki/Apache_Thrift
Apache Thrift enables developers to generate libraries for multiple program languages by only creating Thrift file as API definition. Moreover Thrift definition supports structure, enumerated type and exception, so it generate an easy-to-use library based on static type.
The following procedure is required to develop a program to use the Remote TestKit API by Thrift.
Usage flow for Remote TestKit Thrift API
Remote TestKit Thrift API is provided as a thrift file, not as a library for each programing language, such as dll or jar file. So it can be used by any languages which Thrift supports.
*If you want to use this thrift file, please download from here.
To use the API, after generating library for the language that a user wants to use for development by following procedure, the user have to run the program by launching API server.
- Compile RemoteTestKitAPI.thrift (definition file for RemoteTestKit Thrift API) to generate a library for the language which the developer want to use for development
- Download dependent library which requires when executing Thrift
- Create a program using Remote TestKit Thrift API
- Launch Remote TestKit Thrift API server on local PC
- Run the program which is created by the developer
Examples of provided Thrift API
- API for renting devices and automatically extending the rental time
- API for capturing Web pages
- API for activating virtual adb/Xcode connection
- API for screen capture and video recording
A simple example program for API usage
Introduction
This tutorial shows how to create a program for renting a device and taking a screen capture for a web page by using Remote TestKit Thrift API.
This tutorial assume the following environments. Please replace as appropriate for your environment.
- OS: Windows 7
- Java runtime environment: Java 7
- Build environment: Maven
Create an empty Maven project
In order to use the library generated by Thrift, it will require library that Thrift depends. It can also be downloaded manually from the site of the respective library, but since the time-consuming, so in this tutorial, it is automatically downloaded by creating a Maven project and setting dependent libraries in pom.xml.
Create a following Maven project.
- groupdId: nttr.rtk.example
- artifactId: rtk-example
- version: any version
Then, Set dependent library by adding libthrift to pom.xml of created Maven project. It also requires to set maven-compiler-plugin in pom.xml in order to build a program with Java 7 since Java 7 will be used to compile and run. Finally, pom.xml is as follows.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>nttr.rtk.example</groupId> <artifactId>rtk-example</artifactId> <version>1.0</version> <dependencies> <dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> <version>0.9.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> </project>
Generate library for Java using RemoteTestKitAPI.thrift
Download Thrift compiler (thrift-0.9.1.exe), which enables to generate source code for a library from thrift file, from the Web page for Apache Thrift. Then store it into the root of Maven project created earlier.
http://thrift.apache.org/download
Store thrift file for RemoteTestKit Thrift API (RemoteTestKitAPI.thrift) into the root of the Maven project, and generate a source code of a library for Java by executing following command.
Command: thrift-0.9.1.exe -out srcmainjava --gen java RemoteTestKitAPI.thrift
Create an exapmle program to use the API
Create a program to rent actual device and take a screen capture of Google mobile site.
Save the following source code as /src/main/java/example/Main.java . Before saving, change the USER_NAME and PASSWORD to the account information of your own.
package example; import java.io.File; import java.util.Arrays; import java.util.List; import javax.swing.JFileChooser; import nttr.rtk.thrift.Device; import nttr.rtk.thrift.DeviceService; import nttr.rtk.thrift.MainService; import nttr.rtk.thrift.ServicePorts; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.transport.TSocket; public class Main { public static void main(String[] args) throws Exception { String USER_NAME = "<User name>"; String PASSWORD = "<Password>"; System.out.println("Connect to main service"); TSocket mainServiceTransport = new TSocket("localhost", ServicePorts.MAIN_SERVICE_PORT.getValue()); mainServiceTransport.open(); MainService.Client mainServiceClient = new MainService.Client(new TBinaryProtocol(mainServiceTransport)); System.out.println("Login"); mainServiceClient.login(USER_NAME, PASSWORD); while (true) { System.out.println("Get device list"); List<Device> devices = mainServiceClient.getDevices(); if (devices.isEmpty()) { Thread.sleep(1000); continue; } Device device = devices.get(0); System.out.println("Connect to device service"); TSocket deviceServiceTransport = new TSocket("localhost", ServicePorts.DEVICE_SERVICE_PORT.getValue()); deviceServiceTransport.open(); System.out.println("Rent a device"); DeviceService.Client deviceServiceClient = new DeviceService.Client(new TBinaryProtocol(deviceServiceTransport)); deviceServiceClient.open(device.getDeviceId()); System.out.println("Capturing web pages"); String myDocumentDirectoryPath = new JFileChooser().getFileSystemView().getDefaultDirectory().toString(); deviceServiceClient.captureWebPages(Arrays.asList("http://www.google.co.jp"), new File(myDocumentDirectoryPath, "tmp").getAbsolutePath()); break; } } }
Launch Remote TestKit Thrift API server
When using Remote TestKit Thrift API, It requires to launch a relay server (Thrift server) between the program and Remote TestKit server. The program communicate with Remote TestKit server viaThrift server to use the API.
There are following advantages for the API by being implemented using a relay server method.
- When using an API for making a file, such as video recording, it reduces latency and network load since making a file directly on a local file system, instead of downloading a result file from the server.
- Although most Thrift-supported languages wouldn't support encryption of the communication by SSL, it enables to communicate safely with Remote TestKit server since the relay server encrypt the communication with the server.
http://wiki.apache.org/thrift/LibraryFeatures?action=show&redirect=LanguageSupport - It allows developers to use special feature, such as virtual adb
Startup method for Thrift server is different for Windows and OS X.
For Windows: Launch command prompt, then type "ThriftApiServer.exe" (In case of x64 version of Windows 7: "c:\Program Files (x86)\Remote TestKit\ThriftApiServer.exe").
Note: If you are using Remote TestKit Enterprise, please replace above "Remote TestKit" folder with "Remote TestKit Enterprise".
For OS X: Launch terminal, then type
$ cd "/Applications/Remote TestKit.app/Contents/MacOS" ; java -cp "../Java/*" -Dconf.directory.company.name=nttr nttr.rtk.MainForThriftServer
Note: If you are using Remote TestKit Enterprise, please replace above "Remote TestKit.app" with "Remote TestKit Enterprise.app"
Run the sample program
Run the main class created earlier.
Detailed description about the sample program
Thrift server is listening on two ports, one is for the main service, and the other is for device service.
The main service is providing features for general things, such as a list for device.
- Login/logout
- Get detailed information for a list of devices/each device
- Change configuration for auto rental
The device service is providing features for the followings regarding device.
- Rent device
- Get device status
- Install application
- Take a screen capture
- Video recording
- Take a screen shot for a Web page
- Turn on/off WiFi
- Screen rotation
- Establish virtual adb/Xcode connection
- Set locale
Main service and device service are listening on different ports, but Thrift connections to each port are sharing one context.
So device service should be used after login via main service.
Note that Thrift server allows a process to login by only one account.
Based on above, let's look over the earlier sample program.
First of all, connect a port for main service of Thrift server, which is launched at local.
TSocket mainServiceTransport = new TSocket("localhost", ServicePorts.MAIN_SERVICE_PORT.getValue()); mainServiceTransport.open();
After that, Connect by Thrift binary protocol and create client instance by using the class generated by thrift compiler.
(Thrift supports multiple protocol between server and client, but it only allows common binary protocol to connect Thrift server.)
MainService.Client mainServiceClient = new MainService.Client(new TBinaryProtocol(mainServiceTransport));
Log in by specifying the user name and password.
System.out.println("Login"); mainServiceClient.login(USER_NAME, PASSWORD);
After the login is complete, device list will be available.
Because the list is updated asynchronously, there can be a state where there is no device at all, depending on the timing.
So if the device list is empty, this program will wait for one second to re-get it.
while (true) { System.out.println("Get device list"); List<Device> devices = mainServiceClient.getDevices(); if (devices.isEmpty()) { Thread.sleep(1000); continue; }
If the device list is not empty, this program will get the first device on the list.
Device device = devices.get(0);
Connect device service in order to rent the first device.
System.out.println("Connect to device service"); TSocket deviceServiceTransport = new TSocket("localhost", ServicePorts.DEVICE_SERVICE_PORT.getValue()); deviceServiceTransport.open();
The device is rent by calling the open method by specifying the device ID via Thrift connection to the device service.
At the same time, this thrift connection will be the connection coupled with specified device.
System.out.println("Rent a device"); DeviceService.Client deviceServiceClient = new DeviceService.Client(new TBinaryProtocol(deviceServiceTransport)); deviceServiceClient.open(device.getDeviceId());
Specify the URL and take a screen capture for the web page, then quit the program.
System.out.println("Capturing web pages"); String myDocumentDirectoryPath = new JFileChooser().getFileSystemView().getDefaultDirectory().toString(); deviceServiceClient.captureWebPages(Arrays.asList("http://www.google.co.jp"), new File(myDocumentDirectoryPath, "tmp").getAbsolutePath()); break;
Close method is not explicitly called in the sample program, but Thrift server will automatically release the resources when it loses connection.
The status of the device, when viewed from client software of PC version, will be "Running" until close.
When the close method is called, the status will be changed to "Standby", then another program can re-call open method.
Note that if you do not close after the open, device rental time will be automatically extended.
Automatic extension will be performed for up to 3 hours, developers can specify the time for Automatic extension using setMaxRentalMinutes method of main service.
This sample only shows web page screenshot capture, but The Remote TestKit Thrift API is providing wide variety features, such as video recording, virtual adb, and so on. So please use the API depending on the application.