Skip to content

Commit

Permalink
Don't automatically configure instrumentationApk when roboScript is s…
Browse files Browse the repository at this point in the history
…et. (#132)

If roboscript is set in the fladle exention, we shouldn't try to also automatically configure
the instrumentationApk as this will lead to a confusing failure.

This also adds an integration test (finally) for the fladle plugin in an android project.
  • Loading branch information
runningcode authored May 23, 2020
1 parent fa84821 commit 1b102e6
Show file tree
Hide file tree
Showing 27 changed files with 388 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
# fallback to using the latest cache if no exact match is found
- v1-dependencies-

- run: ./gradlew assembleDebug assembleDebugAndroidTest printYml
- run: ./gradlew -I gradle/buildScanInit.gradle assembleDebug assembleDebugAndroidTest printYml

- run:
name: Save test results
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ flank-gradle-*.json

# Mkdocs generated
site

# Pyhon Environment
lib
bin
19 changes: 18 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ allprojects {
google()
mavenCentral()
// jcenter is required for "org.jetbrains.trove4j:trove4j:20160824."
jcenter()
jcenter() {
content {
includeVersion 'org.jetbrains.trove4j', 'trove4j', '20160824'
}
}
}
}

Expand All @@ -44,3 +48,16 @@ wrapper {
distributionType = Wrapper.DistributionType.ALL
gradleVersion = '6.4.1'
}

def isNonStable = { String version ->
def stableKeyword = ['RELEASE', 'FINAL', 'GA'].any { it -> version.toUpperCase().contains(it) }
def regex = /^[0-9,.v-]+(-r)?$/
return !stableKeyword && !(version ==~ regex)
}

dependencyUpdates {
// Example 1: reject all non stable versions
rejectVersionIf {
isNonStable(it.candidate.version)
}
}
8 changes: 8 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.gradle.api.tasks.testing.logging.TestLogEvent

group = "com.osacky.flank.gradle"
version = "0.10.1-SNAPSHOT"
description = "Easily Scale your Android Instrumentation Tests with Firebase Test Lab with Flank"
Expand Down Expand Up @@ -145,3 +147,9 @@ fun org.gradle.api.publish.maven.MavenPom.configureForFladle(pluginName: String)
url.set("https://github.com/runningcode/fladle")
}
}

tasks.withType(Test::class.java).configureEach {
testLogging {
events = setOf(TestLogEvent.SKIPPED, TestLogEvent.FAILED, TestLogEvent.PASSED)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,11 @@ class FladlePluginDelegate {
appVariant.outputs.configureEach app@{
if (!extension.variant.isPresent || (extension.variant.isPresent && extension.variant.get() == appVariant.name)) {
project.log("Configuring fladle.debugApk from variant ${this@app.name}")
project.log("Configuring fladle.instrumentationApk from variant ${this@test.name}")
extension.debugApk.set(this@app.outputFile.absolutePath)
extension.instrumentationApk.set(this@test.outputFile.absolutePath)
if (extension.roboScript == null) {
project.log("Configuring fladle.instrumentationApk from variant ${this@test.name}")
extension.instrumentationApk.set(this@test.outputFile.absolutePath)
}
}
}
}
Expand All @@ -141,7 +143,7 @@ class FladlePluginDelegate {
get() = configurations.getByName(FLADLE_CONFIG)

companion object {
val GRADLE_MIN_VERSION: GradleVersion = GradleVersion.version("5.4")
val GRADLE_MIN_VERSION: GradleVersion = GradleVersion.version("5.5")
const val TASK_GROUP = "fladle"
const val FLADLE_CONFIG = "fladle"
fun Project.log(message: String) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.osacky.flank.gradle.integration

/*
* Copyright (C) 2016 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.File
import java.util.Properties

internal fun androidHome(): String {
val env = System.getenv("ANDROID_HOME")
if (env != null) {
return env.withInvariantPathSeparators()
}
val localProp = File(File(System.getProperty("user.dir")).parentFile, "local.properties")
if (localProp.exists()) {
val prop = Properties()
localProp.inputStream().use {
prop.load(it)
}
val sdkHome = prop.getProperty("sdk.dir")
if (sdkHome != null) {
return sdkHome.withInvariantPathSeparators()
}
}
throw IllegalStateException(
"Missing 'ANDROID_HOME' environment variable or local.properties with 'sdk.dir'")
}

internal fun String.withInvariantPathSeparators() = replace("\\", "/")
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.osacky.flank.gradle.integration

import com.google.common.truth.Truth.assertThat
import org.gradle.testkit.runner.GradleRunner
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder

class AutoConfigureFladleTest {

@get:Rule
var testProjectRoot = TemporaryFolder()
fun writeBuildGradle(build: String) {
val file = testProjectRoot.newFile("build.gradle")
file.writeText(build)
}

@Test
fun testAndroidProject() {
val fixtureName = "android-project"
testProjectRoot.newFile("local.properties").writeText("sdk.dir=${androidHome()}\n")
testProjectRoot.newFile("gradle.properties").writeText("android.useAndroidX=true")
writeBuildGradle(
"""
allprojects {
repositories {
google()
mavenCentral()
jcenter()
}
}
""".trimIndent()
)
testProjectRoot.newFile("settings.gradle").writeText("""
pluginManagement {
repositories {
gradlePluginPortal()
// google()
}
}
include '$fixtureName'
""".trimIndent())

testProjectRoot.setupFixture(fixtureName)
testProjectRoot.root.walk().forEach {
println(it)
}

val result = GradleRunner.create()
.withProjectDir(testProjectRoot.root)
.withPluginClasspath()
.withArguments("assembleDebug", "assembleDebugAndroidTest", "printYml", "--stacktrace")
.build()

assertThat(result.output).contains("BUILD SUCCESSFUL")
assertThat(result.output).containsMatch("""
> Task :android-project:printYml
gcloud:
app: [0-9a-zA-Z\/]*/android-project/build/outputs/apk/debug/android-project-debug.apk
test: [0-9a-zA-Z\/]*/android-project/build/outputs/apk/androidTest/debug/android-project-debug-androidTest.apk
device:
- model: Pixel2
version: 26
- model: Nexus5
version: 23
use-orchestrator: true
auto-google-login: false
record-video: true
performance-metrics: true
timeout: 15m
environment-variables:
clearPackageData: true
test-targets:
- class com.osacky.flank.gradle.sample.ExampleInstrumentedTest#seeView
num-flaky-test-attempts: 0
flank:
smart-flank-gcs-path: gs://test-lab-yr9w6qsdvy45q-iurp80dm95h8a/flank/test_app_android.xml
keep-file-path: false
ignore-failed-tests: false
disable-sharding: false
smart-flank-disable-upload: false
""".trimIndent())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class FlankGradlePluginIntegrationTest {
.withPluginClasspath()
.withGradleVersion(oldVersion)
.buildAndFail()
assertThat(result.output).contains("Fladle requires at minimum version Gradle 5.4. Detected version Gradle 5.3.1")
assertThat(result.output).contains("Fladle requires at minimum version Gradle 5.5. Detected version Gradle 5.3.1")
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.osacky.flank.gradle.integration

import java.io.File
import org.junit.rules.TemporaryFolder

fun TemporaryFolder.setupFixture(fixtureName: String) {
File(this::class.java.classLoader.getResource(fixtureName)!!.file).copyRecursively(newFile(fixtureName), true)
}
55 changes: 55 additions & 0 deletions buildSrc/src/test/resources/android-project/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
plugins {
id 'com.android.application'
id 'com.osacky.fladle'
}

android {
compileSdkVersion 28
defaultConfig {
applicationId "com.osacky.flank.gradle.sample"
minSdkVersion 23
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
testOptions {
execution 'ANDROIDX_TEST_ORCHESTRATOR'
}
}

fladle {
serviceAccountCredentials = project.layout.projectDirectory.file("flank-gradle-5cf02dc90531.json")
useOrchestrator = true
environmentVariables = [
"clearPackageData": "true"
]
testTargets = [
"class com.osacky.flank.gradle.sample.ExampleInstrumentedTest#seeView"
]
devices = [
[ "model": "Pixel2", "version": "26" ],
[ "model": "Nexus5", "version": "23" ]
]
smartFlankGcsPath = "gs://test-lab-yr9w6qsdvy45q-iurp80dm95h8a/flank/test_app_android.xml"
configs {
oranges {
useOrchestrator = false
testTargets = [
"class com.osacky.flank.gradle.sample.ExampleInstrumentedTest#runAndFail"
]
flakyTestAttempts = 3
}
}
}

dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation("androidx.navigation:navigation-fragment-ktx:2.2.2")
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.osacky.flank.gradle.sample;


import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import androidx.test.rule.ActivityTestRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.action.ViewActions.typeText;
import java.lang.RuntimeException;

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {

@Rule
private final ActivityTestRule testRule = new ActivityTestRule(MainActivity.class);

@Test
public void seeView() {
onView(withId(R.id.text_view_hello)).check(matches(isDisplayed()));
}

@Test
public void runAndFail() {
throw new RuntimeException("Test failed");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.osacky.flank.gradle.sample"
xmlns:android="http://schemas.android.com/apk/res/android">

<application
android:label="@string/app_name"
>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.osacky.flank.gradle.sample;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<TextView
android:id="@+id/text_view_hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">Flank Gradle Plugin Sample</string>
</resources>
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ org.gradle.jvmargs=-Xmx1536m
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
android.enableJetifier=false
Loading

0 comments on commit 1b102e6

Please sign in to comment.