Getting Started

Introduction

GBA allows you to programmatically control profiling of devices. It's perfect for integrating with CI to automate performance metric collection. There are two parts to GBA:

  • The server which communicates with the devices to start sessions, etc.
  • A client which talks to the server and instructs it to perform certain actions

By separating the above, the client and server needn't be on the same host or network. Clients communicate with the server over HTTP which every programming language has libraries for. We provide higher-level libraries for Java, Python and Go.

A concrete example

The Jenkins server itself does not have any devices attached. However, there is a separate OSX machine which a collection of iOS and Android devices are connected to. The Jenkins server would make HTTP requests to the GBA server running on the OSX machine during builds, to capture performance metrics when the built app is running on the devices.

Download server

GBA server is available for OSX, Windows, Linux and Docker. Please sign in to https://portal.gamebench.net to access the downloads.

To profile iOS devices on OSX you must have XCode installed.

To profile iOS devices on Windows you must have iTunes installed.

Download client

As clients interact with the server over HTTP, you can just use curl. Alternatively, you can use:

GBA server configuration

By default, your GBA server configuration will exist in <your home directory>/GameBench/gbaconfig. If this is the first time starting GBA, you'll need to create it in that location. Alternatively, you may override this by setting the GBA_SERVER_CONFIG_PATH environment variable when running the server.

The configuration is in JSON and is an array of objects with each configuration value represented as {"key":"","value":""}.

Please ensure you have an API token created for use with GBA. If you're unsure of how to generate an API token, please see the API token documentation.

Configuration for web.gamebench.net (GameBench cloud)

Ensure your config file contains the following entries:
[
  {"key":"enterprise_login","value":false},
  {"key":"use_https","value":true},
  {"key":"apiUsername","value":"$USERNAME"},
  {"key":"apiToken","value":"$API_TOKEN"}
]

Check credentials via curl:

curl -u $USERNAME:$API_TOKEN https://web.gamebench.net/v1/users/me

Configuration for private servers

Ensure your config file contains the following entries:

[
  {"key":"enterprise_login","value":true},
  {"key":"use_https","value":true},
  {"key":"apiUsername","value":"$USERNAME"},
  {"key":"apiToken","value":"$API_TOKEN"},
  {"key":"serverHost","value":"$SERVER_HOST"},
  {"key":"serverPort","value":"$SERVER_PORT"}
]

Additional configuration for profiling iOS devices: OSX and Windows

Before you can collect data from an iOS device, you need to obtain a zip of Developer Disk Images. At the very least, it will need to include the disk image for the version of iOS that is running on your device.

Download the Developer Disk Images.

If you do wish to collect data from an iOS device, you will need to provide the path of the zip to GBA by executing the following, otherwise you may skip this step.

[
...
{"key":"imgZip","value":"/path/to/ddimg.zip"},
...
]

Start GBA server

Define the following environment variables:

GBA_SERVER_HTTP_HOST=127.0.0.1
GBA_SERVER_HTTP_PORT=8000

Alternatively, from v1.8.0, the HTTP host and port can be set via command-line options. For example: --http-host=127.0.0.1 --http-port=8000.


unzip osx.zip
java -jar -Dapple.awt.UIElement=true osx/lib.jar --start-server

Extract windows.zip

Run the command below:

win/gba.exe --start-server

unzip linux.zip
java -jar linux/lib.jar --start-server

You can retrieve your quay.io credentials from https://portal.gamebench.net.

The docker command below assumes there is a gbconfig.json file within the current directory.

docker run \
    -e GBA_SERVER_CONFIG_PATH=/var/gamebench/gbconfig.json \
    -e GBA_SERVER_HTTP_HOST \
    -e GBA_SERVER_HTTP_PORT \
    -v $(pwd):/var/gamebench \
    --rm \
    --net=host \
    quay.io/gamebench/gba-server:v1.12.2

List devices


curl http://localhost:8000/devices

./gba-client -s http://localhost:8000 device list

import com.gamebench.gbaclientlib.*;

import java.util.List;

public class GbaClientExample {
    public static void main(String[] args) {
        try {
            GbaClient gbaClient = new GbaClient("http://localhost:8000");
            List<Device> devices = gbaClient.listDevices();
            System.out.println(devices);
        } catch (GbaClientException e) {
            e.printStackTrace();
        }
    }
}

import gba
client_factory = gba.ClientFactory()
client = client_factory.create({'baseUrl': 'http://localhost:8000')
devices = client.list_devices()
print(devices)

import "fmt"
import "github.com/GameBench/gba-client-go"

func main() {
	config := &gba.Config{BaseUrl: "http://localhost:8000"}
	client := gba.New(config)
	devices, _ := client.listDevices()
	fmt.Printf("%+v\n", devices)
}

List device's apps


curl http://localhost:8000/devices/$DEVICE_ID/apps

./gba-client -s http://localhost:8000 device list-apps $DEVICE_ID

import com.gamebench.gbaclientlib.*;

import java.util.List;

public class GbaClientExample {
    public static void main(String[] args) {
        try {
            GbaClient gbaClient = new GbaClient("http://localhost:8000");
            String deviceId = "";
            List<App> apps = gbaClient.listDeviceApps(deviceId);
            System.out.println(apps);
        } catch (GbaClientException e) {
            e.printStackTrace();
        }
    }
}

import gba
client_factory = gba.ClientFactory()
client = client_factory.create({'baseUrl': 'http://localhost:8000')
device_id = ""
apps = client.list_device_apps(device_id)

import "fmt"
import "github.com/GameBench/gba-client-go"

func main() {
	config := &gba.Config{BaseUrl: "http://localhost:8000"}
	client := gba.New(config)
	deviceId := ""
	apps, _ := client.ListDeviceApps(deviceId)
	fmt.Printf("%+v\n", apps)
}

Start session


curl -X POST http://localhost:8000/sessions -H 'Content-Type: application/json' -d '{"deviceId":"","appId":"","autoSync":true,"screenshots":true}'

./gba-client -s http://localhost:8000 session start $DEVICE_ID $APP_ID --auto-sync --screenshots

import com.gamebench.gbaclientlib.*;

import java.util.List;

public class GbaClientExample {
    public static void main(String[] args) {
        try {
            GbaClient gbaClient = new GbaClient("http://localhost:8000");
            String deviceId = "";
            String appId = "";
            StartSessionOptions options = new StartSessionOptions();
            options.setAutoSync(true);
            options.setScreenshots(true);
            Session session = gbaClient.startSession(deviceId, appId, options);
            System.out.println(session);
        } catch (GbaClientException e) {
            e.printStackTrace();
        }
    }
}

import gba
client_factory = gba.ClientFactory()
client = client_factory.create({'baseUrl': 'http://localhost:8000')
device_id = ""
app_id = ""
session = client.start_session(device_id, app_id, autoSync=True, screenshots=True)

import "fmt"
import "github.com/GameBench/gba-client-go"

func main() {
	config := &gba.Config{BaseUrl: "http://localhost:8000"}
	client := gba.New(config)
	deviceId := ""
	appId := ""
	options := &StartSessionOptions{AutoSync: true, Screenshots: true}
	session, _ := client.startSession(deviceId, appId, options)
	fmt.Printf("%+v\n", session)
}

Stop session


curl -X POST http://localhost:8000/sessions/$SESSION_ID/stop

./gba-client -s http://localhost:8000 session stop $SESSION_ID

import com.gamebench.gbaclientlib.*;

import java.util.List;

public class GbaClientExample {
    public static void main(String[] args) {
        try {
            GbaClient gbaClient = new GbaClient("http://localhost:8000");
            String sessionId = "";
            gbaClient.stopSession(sessionId);
        } catch (GbaClientException e) {
            e.printStackTrace();
        }
    }
}

import gba
client_factory = gba.ClientFactory()
client = client_factory.create({'baseUrl': 'http://localhost:8000')
device_id = ""
app_id = ""
client.stop_session(session_id)

import "fmt"
import "github.com/GameBench/gba-client-go"

func main() {
	config := &gba.Config{BaseUrl: "http://localhost:8000"}
	client := gba.New(config)
	sessionId := ""
	client.StopSession(sessionId)
}

Troubleshooting

I can't find the JSON summary file.

In some cases, sessions may end unexpectedly. This could cause the JSON summary file to not get generated. If this happens you can create your JSON file by running the following command:

 --generate-json <path_to_session_folder> <target_file>

Why am I not retrieving data for metric X?

For iOS, the collection of certain metrics depend on other metrics. For example; to collect fps, you need to enable collection for fps AND gpu. For cpu, you need to enable collection for cpu AND memory. For network, you need to enable collection for network AND power.