Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Android CI

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

permissions: read-all

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
api-level: [ 26, 28, 30, 33 ]
name: Rhino Android Tests
steps:
- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
# we do not checkout test262 submodule or setup java in this build
- name: Check out Rhino
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v4.2.2
- name: Build and test for Android
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
arch: x86_64
script: |
adb logcat -c || true # try to clear logs
mkdir -p it-android/build/reports # make dir
touch it-android/build/reports/emulator.log # create log file
chmod 777 it-android/build/reports/emulator.log # allow writing to log file
adb logcat >> it-android/build/reports/emulator.log & # pipe all logcat messages into log file as a background process
./gradlew it-android:connectedCheck
- name: Upload results for Android
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: ${{ always() }}
with:
name: reports-android-sdk-${{ matrix.api-level }}
path: '*/build/reports'
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@ rhino.iws

.java-version
.kotlin

# android specific
android-sdk/
local.properties
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ The release contains the following other modules, which are used while building
testing but which are not published to Maven Central:

* **tests**: The tests that depend on all of Rhino and also the external tests, including the Mozilla legacy test scripts and the test262 tests.
* **it-android**: Integration tests for android, [see the details.](./it-android/README.md)
* **benchmarks**: Runs benchmarks using JMH.
* **examples**: Surprisingly, this contains example code.

Expand Down Expand Up @@ -130,6 +131,10 @@ this using the command:
Not all installers seem to put JDKs in the places where Gradle can find them. When in doubt,
installatioons from [Adoptium](https://adoptium.net) seem to work on most platforms.

### Testing on Android

[see here](./it-android/README.md)

### Code Coverage

The "Jacoco" coverage is enabled by default for the main published modules as well as the special
Expand Down
Empty file added build.gradle
Empty file.
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ githubPackagesRepo=https://maven.pkg.github.com/mozilla/rhino
org.gradle.caching=true
org.gradle.parallel=true
org.gradle.configuration-cache=true
android.useAndroidX=true
15 changes: 15 additions & 0 deletions install-android-sdk.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#/usr/bin/env bash
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please move this file to the "it-android" directory so that the root directory doesn't get too full?

Could you also make it executable (might need to mess around with Git -- usually if you "chmod a+x" the file Git will figure it out when you first add it).

# SDK downloader for android integration tests
export ANDROID_HOME=$PWD/android-sdk
mkdir -p $ANDROID_HOME/cmdline-tools

# Download and install command line tools
wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip -O tools.zip
unzip tools.zip -d $ANDROID_HOME/cmdline-tools
mv $ANDROID_HOME/cmdline-tools/cmdline-tools $ANDROID_HOME/cmdline-tools/latest

# Install SDK components
yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses
yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager "platform-tools" "platforms;android-34" "build-tools;34.0.0"
# set in local properties
echo sdk.dir=./android-sdk >> local.properties
74 changes: 74 additions & 0 deletions it-android/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Android integration tests

Rhino runs with some restrictions on android platform. This project builds a very minimalistic app/testframework to run
android tests either in an emulator or directly on your phone

## Restrictions

### Rhino runtime
-

- minSdk is 26 (see #1785 for background)
- runs only in intermreted mode
- not all features may be available (JavaAdapter, ...)

### Emulator

- runs in emulated mode and may behave different, than a real android-device (JIT etc.)

## Testing

### Tests

Write your tests in `src/main/assets/tests` in the same style as MozillaTestSuite

These are simple javascript tests.
(To write java-tests it is recommended to use android-studio.)

### Running tests on github

This is done automatically on each PR (maybe changed as manual action, if it consumes too much resources)

### Running tests locally

You need an Android SDK installed

- Either install Android-Studio with SDK https://developer.android.com/about/versions/14/setup-sdk

make sure that your `ANDROID_HOME` enviroment is set up properly
- Or use the provided script in `<RHINO_ROOT>/install-android-sdk`

This will install the SDK in `<RHINO_ROOT>/android-sdk` and register it in the `local.properties` for this gradle
build only. (This is the best option, if you do not want to mess up your system)

<b>Note:</b> The script will automatically accept all license terms!

Use `<RHINO_ROOT>/run-android-tests-locally.sh` to start an emulator in docker/podman, run the tests and install the
APK.

This will download an emulator based on https://github.com/budtmo/docker-android and you can access the emulated phone
on http://localhost:6080

<b>Note:</b> The emulator will not terminate automatically. You will need to remove it from your docker/podman manually

### Debugging and troubleshooting

- `./gradlew it-android:connectedAndroidTest` will try to run the tests automatically on the connected android device
- `./android-sdk/platform-tools/adb logcat` get logs from the device
- `./android-sdk/platform-tools/adb devices` list devices
- `./android-sdk/platform-tools/adb disconnect` disconnect devices
- `./android-sdk/platform-tools/adb connect localhost:5555` reconnect to emulator
- `docker rm -f android-container` or `podman rm -f android-container` remove the container

### Running tests on your phone

You need an Android SDK and an Android phone of course. (iPhone will not work here)

- open your settings and enable `wireless debugging`
- select `pari device with pariing code`
- run `./android-sdk/platform-tools/adb pair HOST:PORT PAIRING_CODE`
- run `./android-sdk/platform-tools/adb connect HOST:PORT` (Note: The port is different from the pairing port)
- check `./android-sdk/platform-tools/adb devices`, if your device is connected
- run `./gradlew it-android:connectedAndroidTest` to run your tests
- or run `./gradlew it-android:installDebug` to deploy the app on your phone

71 changes: 71 additions & 0 deletions it-android/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
buildscript {
repositories {
gradlePluginPortal()
google()
mavenCentral()
mavenLocal()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.9.3'
}
}

plugins {
id 'rhino.spotless-conventions'
}

repositories {
google()
mavenCentral()
}

spotless {
java {
target "src/*/java/**/*.java"
}
}


// read the (android specific) local.properties file
def localPropertiesFile = rootProject.file("local.properties");
Properties localProperties = new Properties()
if (localPropertiesFile.exists()) {
localProperties.load(localPropertiesFile.newDataInputStream())
}

if (!System.getenv("ANDROID_HOME") && !localProperties.get("sdk.dir")) {
System.out.println("No Android SDK found. Skipping build")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skip android build for users, that do not have a SDK installed

} else {
apply plugin: 'com.android.application'

android {
namespace = "org.mozilla.javascript.android"

compileSdkVersion 33
defaultConfig {
minSdk = 26
targetSdk = 33
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
}

dependencies {
// To test against other versions, replace the dependencies by
implementation 'org.mozilla:rhino:1.7.15'
//implementation project(':rhino')

/*implementation project(':examples')
implementation project(':rhino-engine')
implementation project(':rhino-tools')
implementation project(':rhino-xml')*/

testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test:runner:1.7.0'
androidTestImplementation 'androidx.test.ext:junit:1.3.0'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.mozilla.javascript.android.test;

import static org.junit.Assert.assertTrue;

import android.content.Context;
import android.util.Log;
import androidx.test.platform.app.InstrumentationRegistry;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mozilla.javascript.android.TestCase;

/**
* Simple testcase runner, that runs all Testcases provided by estCase.getTestCases.
*
* @author Roland Praml
*/
@RunWith(Parameterized.class)
public class RhinoTest {

@Parameterized.Parameter(value = 0)
public TestCase testCase;

@Test
public void test() {
String s = testCase.run();
Log.i(testCase.toString(), s);
assertTrue(s.contains("success"));
}

@Parameterized.Parameters(name = "{index}, js={0}")
public static Collection<Object[]> suiteValues() throws IOException {
List<Object[]> result = new ArrayList<Object[]>();
Context androidContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
for (TestCase testCase : TestCase.getTestCases(androidContext)) {
result.add(new Object[] {testCase});
}
return result;
}
}
11 changes: 11 additions & 0 deletions it-android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:label="Rhino-Test">
<activity android:name="MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Loading
Loading