• Stars
    star
    119
  • Rank 296,245 (Top 6 %)
  • Language
    Kotlin
  • License
    Apache License 2.0
  • Created about 5 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Adb Server for Espresso tests

CircleCI

[DEPRECATED] Autotests Adb Server

Please, use Kaspresso where AdbServer was migrated.
Detailed information is available here.

What is it?

When you are writing ui-tests you need do some actions with device sometimes. You may to execute a big part of those actions by ADB. But Espresso doesn't contain a mechanism allowing Adb commands fulfilling although Appium does.
Why? In Espresso your app and tests are in device. In Appium your tests are in Desktop or Server. So in Espresso you can't call adb because you can't call adb from inside the device.
That's why we have created Autotests Adb Server to compensate for the Espresso disadvantage.

The main idea of the tool is so similar with idea of Appium. We need an ability to include in our tests some external thing from where we would send adb-commands to a device. This external thing can be Desktop or Server.
That's why the tool is consist of two parts: Desktop and Device.
Desktop - is the server listening commands from devices to execute adb-commands.
Device - is the client sending commands to the server from your tests.

Usage

Server/Desktop

You need to start the Desktop on your host (desktop/server) before tests' start to execute.
To start the Desktop please copy built library from /artifacts/desktop.jar to convenient for you place.
The next is to execute a simple command in your host's cmd:

java -jar desktop.jar

Also, you can set additional options as it's shown in the example below:

java -jar desktop.jar emulators=emulator-5554,emulator-5556 adbServerPort=5041

where:
emulators - you set a list of emulators that can be captured by desktop.jar
adbServerPort - you set the adb server port number (the default value is 5037)

Device

  1. Add adbserver-device dependency in your project
  2. Give permissions for an access to the Internet
<uses-permission android:name="android.permission.INTERNET" />
  1. Use the class:
object AdbTerminal {

    fun connect() { }

    fun disconnect() { }

    /**
     * Please first of all call [connect] method to establish a connection
     */
    fun executeAdb(command: String): CommandResult { }

    /**
     * Please first of all call [connect] method to establish a connection
     */
    fun executeCmd(command: String): CommandResult { }

}

As you are seeing you need to establish connection by connect method calling before to execute adb or simple cmd command.
For a reminder: adb-command is also cmd command but it starts with adb key word.
After the session please close the connection by disconnect method.
executeAdb and executeCmd are synchronous methods to not reorder a line of commands because if commands were completed in incorrect order it may to lead inconsistent state of the app and the device.
Also these methods don't throw any exception. All possible results are mapping into CommandResult.
All methods of AdbTerminal may be call from any thread.
So, please observe example module.

Logs

Let's consider what the developer looks in the logs on the host and the device.

The host logs

desktop.jar is running and waiting devices. But no one device exists in the current environment.

INFO:_____tag=MAIN______________________________________message => arguments: emulators=[], adbServerPort=null
INFO:_____tag=Desktop___________________________________method=startDevicesObserving___________________message => start

There has been new emulator in the current environment - emulator-5554.
The main moment is port forwarding.
Next step is a WatchdogThread's start that is responsible to establish socket connection between the client (the host forwarded to device port) and the server (the device).

INFO:_____tag=Desktop_________________________________method=startDevicesObserving___________________message => New device has been found: emulator-5554. Initialize connection to it...
INFO:_____tag=DesktopDeviceSocketConnectionForwardImplmethod=getDesktopSocketLoad____________________message => calculated desktop client port=11866
INFO:_____tag=DesktopDeviceSocketConnectionForwardImplmethod=forwardPorts(fromPort=11866, toPort=8500)_message => started
INFO:_____tag=CommandExecutorImpl_____________________method=execute_________________________________message => adbCommand=adb -s emulator-5554 forward tcp:11866 tcp:8500
INFO:_____tag=DesktopDeviceSocketConnectionForwardImplmethod=forwardPorts(fromPort=11866, toPort=8500)_message => result=CommandResult(status=SUCCESS, description=exitCode=0, message=11866
)
INFO:_____tag=DesktopDeviceSocketConnectionForwardImplmethod=getDesktopSocketLoad____________________message => desktop client port=11866 is forwarding with device server port=8500
INFO:_____tag=DeviceMirror____________________________method=startConnectionToDevice_________________message => connect to device=emulator-5554 start
INFO:_____tag=DeviceMirror.WatchdogThread_____________method=run_____________________________________message => WatchdogThread is started from Desktop to Device=emulator-5554

Further, you can observer a lot of attempts to establish connection between the client and the server.
It's right behavior. Don't worry.

INFO:_____tag=DeviceMirror.WatchdogThread_____________method=run_____________________________________message => Try to connect to Device=emulator-5554...
INFO:_____tag=ConnectionServerImplBySocket____________method=tryConnect______________________________message => start
INFO:_____tag=ConnectionMaker_________________________method=connect_________________________________message => start
INFO:_____tag=ConnectionMaker_________________________method=connect_________________________________message => current state=DISCONNECTED
INFO:_____tag=DesktopDeviceSocketConnectionForwardImplmethod=getDesktopSocketLoad____________________message => started with ip=127.0.0.1, port=11866
INFO:_____tag=DesktopDeviceSocketConnectionForwardImplmethod=getDesktopSocketLoad____________________message => completed with ip=127.0.0.1, port=11866
INFO:_____tag=ConnectionMaker_________________________method=connect_________________________________message => updated state=CONNECTED
INFO:_____tag=ConnectionServerImplBySocket____________method=tryConnect______________________________message => start handleMessages
INFO:_____tag=SocketMessagesTransferring______________method=startListening__________________________message => start
ERROR:____tag=SocketMessagesTransferring______________method=startListening__________________________message => java.io.EOFException
INFO:_____tag=ConnectionServerImplBySocket____________method=tryDisconnect___________________________message => start
INFO:_____tag=ConnectionMaker_________________________method=disconnect______________________________message => start
INFO:_____tag=ConnectionMaker_________________________method=disconnect______________________________message => current state=CONNECTED
INFO:_____tag=ConnectionMaker_________________________method=disconnect______________________________message => updated state=DISCONNECTING
INFO:_____tag=ConnectionMaker_________________________method=disconnect______________________________message => updated state=DISCONNECTED
INFO:_____tag=ConnectionServerImplBySocket____________method=tryDisconnect___________________________message => attempt completed
INFO:_____tag=ConnectionServerImplBySocket____________method=tryConnect______________________________message => attempt completed
INFO:_____tag=DeviceMirror.WatchdogThread_____________method=run_____________________________________message => Try to connect to Device=emulator-5554...
INFO:_____tag=ConnectionServerImplBySocket____________method=tryConnect______________________________message => start
INFO:_____tag=ConnectionMaker_________________________method=connect_________________________________message => start
INFO:_____tag=ConnectionMaker_________________________method=connect_________________________________message => current state=DISCONNECTED
INFO:_____tag=DesktopDeviceSocketConnectionForwardImplmethod=getDesktopSocketLoad____________________message => started with ip=127.0.0.1, port=11866
INFO:_____tag=DesktopDeviceSocketConnectionForwardImplmethod=getDesktopSocketLoad____________________message => completed with ip=127.0.0.1, port=11866
INFO:_____tag=ConnectionMaker_________________________method=connect_________________________________message => updated state=CONNECTED
INFO:_____tag=ConnectionServerImplBySocket____________method=tryConnect______________________________message => start handleMessages
INFO:_____tag=SocketMessagesTransferring______________method=startListening__________________________message => start
ERROR:____tag=SocketMessagesTransferring______________method=startListening__________________________message => java.io.EOFException
INFO:_____tag=ConnectionServerImplBySocket____________method=tryDisconnect___________________________message => start
INFO:_____tag=ConnectionMaker_________________________method=disconnect______________________________message => start
INFO:_____tag=ConnectionMaker_________________________method=disconnect______________________________message => current state=CONNECTED
INFO:_____tag=ConnectionMaker_________________________method=disconnect______________________________message => updated state=DISCONNECTING
INFO:_____tag=ConnectionMaker_________________________method=disconnect______________________________message => updated state=DISCONNECTED
INFO:_____tag=ConnectionServerImplBySocket____________method=tryDisconnect___________________________message => attempt completed
INFO:_____tag=ConnectionServerImplBySocket____________method=tryConnect______________________________message => attempt completed

When a developer runs the application containing Device part of AdbServer and starts this part then the connection is successfully established.

INFO:_____tag=DeviceMirror.WatchdogThread_____________method=run_____________________________________message => Try to connect to Device=emulator-5554...
INFO:_____tag=ConnectionServerImplBySocket____________method=tryConnect______________________________message => start
INFO:_____tag=ConnectionMaker_________________________method=connect_________________________________message => start
INFO:_____tag=ConnectionMaker_________________________method=connect_________________________________message => current state=DISCONNECTED
INFO:_____tag=DesktopDeviceSocketConnectionForwardImplmethod=getDesktopSocketLoad____________________message => started with ip=127.0.0.1, port=11866
INFO:_____tag=DesktopDeviceSocketConnectionForwardImplmethod=getDesktopSocketLoad____________________message => completed with ip=127.0.0.1, port=11866
INFO:_____tag=ConnectionMaker_________________________method=connect_________________________________message => updated state=CONNECTED
INFO:_____tag=ConnectionServerImplBySocket____________method=tryConnect______________________________message => start handleMessages
INFO:_____tag=SocketMessagesTransferring______________method=startListening__________________________message => start
INFO:_____tag=SocketMessagesTransferring______________method=startListening__________________________message => IO Streams were created
INFO:_____tag=ConnectionServerImplBySocket____________method=tryConnect______________________________message => attempt completed
INFO:_____tag=SocketMessagesTransferring.MessagesListeningThread_method=run_____________________________________message => start to work

And an example of one command execution:

INFO:_____tag=SocketMessagesTransferring.MessagesListeningThread_method=peekNextMessage_________________________message => with message=TaskMessage(command=AdbCommand(body=shell input text 1))
INFO:_____tag=ConnectionServerImplBySocket____________method=handleMessages__________________________message => received taskMessage=TaskMessage(command=AdbCommand(body=shell input text 1))
INFO:_____tag=CommandExecutorImpl_____________________method=execute_________________________________message => adbCommand=adb -s emulator-5554 shell input text 1
INFO:_____tag=ConnectionServerImplBySocket____________method=handleMessages.backgroundExecutor_______message => result of taskMessage=TaskMessage(command=AdbCommand(body=shell input text 1)) => result=CommandResult(status=SUCCESS, description=exitCode=0, message=)
INFO:_____tag=SocketMessagesTransferring______________method=sendMessage_____________________________message => where sendModel=ResultMessage(command=AdbCommand(body=shell input text 1), data=CommandResult(status=SUCCESS, description=exitCode=0, message=))

The device logs

The device with Device part is running and waiting host with working AdbServer (Desktop part). But no one host exists in the current environment.

INFO:_____tag=Device__________________________________method=start___________________________________message => start
INFO:_____tag=Device.WatchdogThread___________________method=run_____________________________________message => WatchdogThread starts from Device to Desktop
INFO:_____tag=Device.WatchdogThread___________________method=run_____________________________________message => Try to connect to Desktop...
INFO:_____tag=ConnectionClientImplBySocket____________method=tryConnect______________________________message => start
INFO:_____tag=ConnectionMaker_________________________method=connect_________________________________message => start
INFO:_____tag=ConnectionMaker_________________________method=connect_________________________________message => current state=DISCONNECTED
INFO:_____tag=DesktopDeviceSocketConnectionForwardImplmethod=getDeviceSocketLoad_____________________message => started

There has been appropriate host.

INFO:_____tag=DesktopDeviceSocketConnectionForwardImplmethod=getDeviceSocketLoad_____________________message => completed
INFO:_____tag=ConnectionMaker_________________________method=connect_________________________________message => updated state=CONNECTED
INFO:_____tag=ConnectionClientImplBySocket____________method=tryConnect______________________________message => start handleMessages
INFO:_____tag=SocketMessagesTransferring______________method=startListening__________________________message => start
INFO:_____tag=SocketMessagesTransferring______________method=startListening__________________________message => IO Streams were created
INFO:_____tag=ConnectionClientImplBySocket____________method=tryConnect______________________________message => attempt completed
INFO:_____tag=SocketMessagesTransferring.MessagesListeningThread_method=run_____________________________________message => start to work

And an example of one command execution:

INFO:_____tag=Device__________________________________method=execute_________________________________message => Start to execute the command=AdbCommand(body=shell input text 1)
INFO:_____tag=ConnectionClientImplBySocket____________method=executeAdbCommand_______________________message => started command=AdbCommand(body=shell input text 1)
INFO:_____tag=SocketMessagesTransferring______________method=sendMessage_____________________________message => where sendModel=TaskMessage(command=AdbCommand(body=shell input text 1))
INFO:_____tag=SocketMessagesTransferring.MessagesListeningThread_method=peekNextMessage_________________________message => with message=ResultMessage(command=AdbCommand(body=shell input text 1), data=CommandResult(status=SUCCESS, description=exitCode=0, message=))
INFO:_____tag=ConnectionClientImplBySocket____________method=handleMessages__________________________message => received resultMessage=ResultMessage(command=AdbCommand(body=shell input text 1), data=CommandResult(status=SUCCESS, description=exitCode=0, message=))
INFO:_____tag=ConnectionClientImplBySocket____________method=executeAdbCommand_______________________message => command=AdbCommand(body=shell input text 1) completed with commandResult=CommandResult(status=SUCCESS, description=exitCode=0, message=)
INFO:_____tag=Device__________________________________method=execute_________________________________message => The result of command=AdbCommand(body=shell input text 1) => CommandResult(status=SUCCESS, description=exitCode=0, message=)

Additional info

[RU] Дмитрий Мовчан, Евгений Мацюк — Как начать писать автотесты и не сойти с ума
[RU] Егор Курников — Единственное, что вам нужно для UI-тестирования

Integration

To use AdbServer device library, include the jcenter repository to your root build.gradle file (if it does not exist already):

allprojects {
    repositories {
        jcenter()
    }
}

And then add dependency to your module build.gradle:

androidTestImplementation 'com.kaspersky.android-components:adbserver-device:1.0.0'

Support

Russian support in telegram - t.me/kaspresso

Contribution Policy

AdbServer is an open source project, and depends on its users to improve it. We are more than happy to find you interested in taking the project forward.
Kindly refer to the Contribution Guidelines for detailed information.

License

AdbServer is open source and available under the Apache License, Version 2.0.

More Repositories

1

TinyCheck

TinyCheck allows you to easily capture network communications from a smartphone or any device which can be associated to a Wi-Fi access point in order to quickly analyze them. This can be used to check if any suspect or malicious communication is outgoing from a smartphone, by using heuristics or specific Indicators of Compromise (IoCs). In order to make it working, you need a computer with a Debian-like operating system and two Wi-Fi interfaces. The best choice is to use a Raspberry Pi (2+) a Wi-Fi dongle and a small touch screen. This tiny configuration (for less than $50) allows you to tap any Wi-Fi device, anywhere.
Python
3,077
star
2

Kaspresso

Android UI test framework
Kotlin
1,784
star
3

klara

Kaspersky's GReAT KLara
PHP
689
star
4

triangle_check

Python
509
star
5

iShutdown

Python
389
star
6

ForensicsTools

Tools for DFIR
C++
117
star
7

VBscriptInternals

Scripts for disassembling VBScript p-code in the memory to aid in exploits analysis
Python
84
star
8

Apihashes

IDA Pro plugin for recognizing known hashes of API function names
Python
81
star
9

hrtng

C++
71
star
10

ActionScript3

Tools for static and dynamic analysis of ActionScript3 SWF files.
Python
45
star
11

uif

Integration Platform to build UI and Web Services
TypeScript
33
star
12

WinDbg-JS-Scripts

JavaScript
32
star
13

BuildMigrator

C
32
star
14

xtraining-re101

Code snippets for Reverse engineering training for xtraining platform
C
30
star
15

bitscout

Shell
20
star
16

OpenTIP-scanner

Open-source file scanner that sends requests and optionally uploads files to OpenTIP.kaspersky.com.
Python
17
star
17

Articles

C++
16
star
18

SafeBoard

Repository for general info and code samples for test tasks used in SafeBoard Hackatons in Kaspersky Lab.
C++
15
star
19

klogga

Opinionated logging-audit-tracing library. Data collected via klogga can be configured to be exported to different sources, including traditional text logs, but with emphasis on structured storages, primarily time-series databases and Open Telemetry.
Go
12
star
20

hb_dec

C
11
star
21

threat-intelligence

A repository dedicated to deliver a comprehensive set of tools for integration and convenient use of Kaspersky Threat Intelligence services
Python
9
star
22

grpc-kos

Shared C [core library], C++, Ruby, Python, PHP, C# (core library based), Objective-C
C++
4
star
23

RAM

Framework to manage the product state and configuration
Python
4
star
24

protobuf-kos

Protocol Buffers (a.k.a., protobuf) are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data.
C++
3
star
25

abseil-cpp-kos

Abseil is an open source collection of C++ libraries drawn from the most fundamental pieces of Google’s internal codebase.
C++
2
star
26

c-ares-kos

c-ares is a C library for asynchronous DNS requests (including name resolves)
C++
1
star
27

boringssl-kos

BoringSSL is a fork of OpenSSL that is designed to meet Google's needs.
C++
1
star