Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android testing broken since Gradle 4.2 #3006

Closed
jaredsburrows opened this issue Sep 22, 2017 · 22 comments
Closed

Android testing broken since Gradle 4.2 #3006

jaredsburrows opened this issue Sep 22, 2017 · 22 comments
Assignees
Milestone

Comments

@jaredsburrows
Copy link

Based on this reddit post: https://www.reddit.com/r/androiddev/comments/71c1sz/gradle_42_released/ and https://issuetracker.google.com/issues/65869429.

Gradle 4.2 broke espresso/instrumentation tests for Android Gradle Plugin.

Expected Behavior

The tests should run.

Current Behavior

> Task :roomDatabase:connectedDebugAndroidTest
Starting 37 tests on 5x-26(AVD) - 8.0.0


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':roomDatabase:connectedDebugAndroidTest'.
> Could not initialize class com.android.build.gradle.internal.test.report.AllTestResults

Steps to Reproduce (for bugs)

./gradlew connectedDebugAndroidTest

Your Environment

Gradle 4.2-rc-2 (happens on 4.1 as well)
Gradle Android Plugin version 3.0.0-beta6 (happened on beta2 as well)
Compile SDK version: 26
Build tools version: 26.0.1
Sdk tools version: 26.1.0

Possible solution

Could we add a single unit test and instrumentation test case for Gradle? This way we can ensure the latest Gradle releases work with existing versions of the Android Gradle plugin.

@bmuschko
Copy link
Contributor

bmuschko commented Sep 22, 2017

Might be a good enhancement to org.gradle.smoketests.AndroidPluginsSmokeTest. Would you be interested in contributing?

Is this happening with 4.2 GA as well? Would you consider this a regression in Gradle core? If yes, can you please provide a sample project?

@bmuschko bmuschko added a:chore Minor issue without significant impact from:contributor a:bug and removed a:chore Minor issue without significant impact labels Sep 22, 2017
@jaredsburrows
Copy link
Author

jaredsburrows commented Sep 22, 2017 via email

@jaredsburrows
Copy link
Author

Currently 4.1 works well, I have an example test project here: https://github.com/jaredsburrows/android-gif-example.

I am not sure whether or not to consider this apart of core or not.

I can reproduce the error in this project/branch that is apart of that repo in a PR here: jaredsburrows/android-gif-search#41.

@jaredsburrows
Copy link
Author

@bmuschko It looks like Xavier marked this issue as fixed in the Android tracker: https://issuetracker.google.com/issues/65869429. Maybe this was an AGP problem?

I still think that we should have some integration tests for this.

@oehme
Copy link
Contributor

oehme commented Sep 23, 2017

We definitely should update our tests to check against the latest agp versions.

@SteffenL
Copy link

Is Gradle 4.2 supposed to be compatible with AGP 2.3.x or only AGP 3.x?

I am asking because I got this issue with AGP 2.3.2 (also tried 2.3.3) after updating Gradle from 3.5 to 4.2.

@jaredsburrows
Copy link
Author

@bmuschko @oehme Where is the .travis.yml file? How are you all updating the SDK for tests?

@oehme oehme added this to the 4.2.1 milestone Sep 28, 2017
@oehme oehme changed the title [Test Request] - Android testing for unit/instrumentation tests Android unit testing broken since Gradle 4.2 Sep 28, 2017
@bmuschko
Copy link
Contributor

bmuschko commented Sep 28, 2017

@jaredsburrows Thanks for providing the sample project. I could reproduce the issue you reported with your sample project and an emulator.

I believe to automate an integration test, we'd have a configured emulator first. When starting the test, we'd have to bring up the emulator, run the test and then tear it down again. I am currently looking into that.

Where is the .travis.yml file?

Which Travis file are you referring to? We are running the Android smoke tests on TeamCity.

How are you all updating the SDK for tests?

I believe that is done in the infrastructure of the agents but I'd have to check.

@bmuschko
Copy link
Contributor

bmuschko commented Sep 28, 2017

This is what I believe is happening:

When running the example project I get the following stack trace:

Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.android.build.gradle.internal.test.report.AllTestResults
        at com.android.build.gradle.internal.test.report.TestReport.loadModel(TestReport.java:60)
        at com.android.build.gradle.internal.test.report.TestReport.generateReport(TestReport.java:55)
        at com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask.runTests(DeviceProviderInstrumentTestTask.java:173)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
        at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.doExecute(DefaultTaskClassInfoStore.java:142)
        at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:135)
        at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:122)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:762)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:729)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:121)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:110)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92)
        ... 29 more

The stack trace indicates that the class AllTestResults cannot be initialized. I couldn't find the Android source code online so I had to download the sources from the repository:

repositories {
    google()
    jcenter()
}

configurations {
    android
}

dependencies {
    android group: 'com.android.tools.build', name: 'gradle-core', version: '3.0.0-beta6', classifier: 'sources'
}

task copy(type: Copy) {
    from configurations.android
    into "$buildDir/libs"
}

The line 60 in TestReport creates a new instance of AllTestResults:

AllTestResults model = new AllTestResults();

We can find the following hierarchy of parent classes for AllTestResults:

AllTestResults extends CompositeTestResults extends TestResultModel.

The class TestResultModel instantiates a field of the Gradle core internal type DurationFormatter:

public static final DurationFormatter DURATION_FORMATTER = new DurationFormatter();
  • In Gradle 4.1 the class DurationFormatter lived in package org.gradle.reporting.
  • In Gradle 4.2 the class was moved to the package org.gradle.internal.logging.format and became an interface. The actual implementation is now TersePrettyDurationFormatter.

The change between 4.1 and 4.2 was a breaking change even though it was an internal API. Given that the class also became an interface I don't think we can just move back the class. I'd suggest that the Android plugin implements its own time formatting along the lines of org.gradle.internal.time.TimeFormatting instead of relying on an internal API that could easily be implemented in the plugin as well. The logic isn't really that complicated. In the long run we could think about exposing a public API for (test) report generation. That would also align we some of the goals we discussed before for plugin developers.

Apparently the Android team already fixed the issue though I do not know with what version and how. I left a comment in the bug report.

@oehme
Copy link
Contributor

oehme commented Sep 29, 2017

The Android team fixed it for 3.0, but 2.3 remains broken. I suggest we restore the old DurationFormatter class, add @Deprecated and remove it in Gradle 5.0. This would be a cheap fix and would allow Android 2.3 users (the vast majority) to enjoy Gradle 4.2.

@oehme
Copy link
Contributor

oehme commented Sep 29, 2017

@bmuschko I'll take this one over so you'll have more time for #2832 and #2837

@oehme oehme assigned oehme and unassigned bmuschko Sep 29, 2017
@bmuschko
Copy link
Contributor

bmuschko commented Sep 29, 2017

@oehme I already started to refactor existing Android smoke tests and set up unit/instrumented tests in this branch bm/android-smoke-tests. You can continue to commit to that branch.

@oehme oehme changed the title Android unit testing broken since Gradle 4.2 Android testing broken since Gradle 4.2 Sep 29, 2017
@jaredsburrows
Copy link
Author

Is there a way to reproduce the issue without having to connect an Android device?

Sadly "android tests" and not "unit tests" have to run on a device or an emulator.

Which Travis file are you referring to?

Sorry, I just assumed Travis.

I believe that is done in the infrastructure of the agents but I'd have to check.

If I update the build tools/sdk, will it break your current build? I just want to make sure if we upgrade to the latest release, the build server is ready.

@jaredsburrows
Copy link
Author

Awesome. Just now catching up on this thread, it looks like @bmuschko is going to go ahead and update the existing smoke tests?

@oehme
Copy link
Contributor

oehme commented Sep 29, 2017

Yes, the tests have been adjusted together with the fix, see the linked Pull Request.

@bmuschko
Copy link
Contributor

@jaredsburrows I think there's more we can do to cover unit and instrumented testing. Feel free to have a look at my branch and create a PR to improve even more.

@jaredsburrows
Copy link
Author

Thanks @oehme and @bmuschko.

If I were to add on to @bmuschko's branch, should I wait for both of your PRs to be merged in to master first?

@bmuschko
Copy link
Contributor

@jaredsburrows I'd wait for @oehme's PR to be merged. After that you can create a new PR. I'd just copy/paste the changes you think are useful from my branch.

@jaredsburrows
Copy link
Author

Sounds great, thanks!

@oehme
Copy link
Contributor

oehme commented Sep 29, 2017

The fix has been merged into release.

@oehme oehme closed this as completed Sep 29, 2017
@IgorGanapolsky
Copy link

This issue seems to be resolved in Gradle 4.3-rc-1.

@jaredsburrows
Copy link
Author

jaredsburrows commented Oct 13, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants