leancodepl / patrol

Flutter-first UI testing framework. Ready for action!
https://patrol.leancode.co
Apache License 2.0
898 stars 134 forks source link

Out of memory error during some patrol builds on Codemagic device #2384

Open martin1080p opened 1 week ago

martin1080p commented 1 week ago

Steps to reproduce

  1. Set up a Codemagic workflow configured to run on a macOS environment (specifically, a Mac Mini M2).
  2. In the workflow, use the following build commands:
    dart pub global activate patrol_cli
    flutter build apk --config-only -t lib/$RUN_FILE --flavor $FLAVOR
    patrol build android -t integration_test --verbose
  3. Trigger the workflow to build and run patrol tests. Ensure all necessary environment variables ($RUN_FILE, $FLAVOR, etc.) are properly configured.
  4. Observe the results of the build, noting any inconsistencies in the success or failure of the patrol test build step.

Actual results

Expected Outcome: The workflow completes successfully, with the patrol tests built and executed without errors.

Intermittent Issue: Occasionally, the patrol test build step fails with an "Out of memory" error.

Current Configuration: The org.gradle.jvmargs setting in gradle.properties is set to -Xmx8g.

Observation: Despite the 8 GB memory allocation, the build inconsistently fails due to memory constraints—sometimes succeeding and sometimes failing without any changes to the code or configuration.

Is there a way to correctly test whether gradle has correctly alocated 8 GB in memore?

Logs

Logs of FAILED build ``` : > Task :permission_handler_android:copyDebugJniLibsProjectOnly : > Task :share_plus:mergeDebugJniLibFolders : > Task :share_plus:mergeDebugNativeLibs NO-SOURCE : > Task :share_plus:copyDebugJniLibsProjectOnly : > Task :shared_preferences_android:mergeDebugJniLibFolders : > Task :shared_preferences_android:mergeDebugNativeLibs NO-SOURCE : > Task :shared_preferences_android:copyDebugJniLibsProjectOnly : > Task :sqflite:mergeDebugJniLibFolders : > Task :sqflite:mergeDebugNativeLibs NO-SOURCE : > Task :sqflite:copyDebugJniLibsProjectOnly : > Task :sqlcipher_flutter_libs:mergeDebugJniLibFolders : > Task :sqlcipher_flutter_libs:mergeDebugNativeLibs NO-SOURCE : > Task :sqlcipher_flutter_libs:copyDebugJniLibsProjectOnly : > Task :url_launcher_android:mergeDebugJniLibFolders : > Task :url_launcher_android:mergeDebugNativeLibs NO-SOURCE : > Task :url_launcher_android:copyDebugJniLibsProjectOnly : > Task :video_player_android:mergeDebugJniLibFolders : > Task :video_player_android:mergeDebugNativeLibs NO-SOURCE : > Task :video_player_android:copyDebugJniLibsProjectOnly : > Task :wakelock_plus:mergeDebugJniLibFolders : > Task :wakelock_plus:mergeDebugNativeLibs NO-SOURCE : > Task :wakelock_plus:copyDebugJniLibsProjectOnly : > Task :webview_flutter_android:mergeDebugJniLibFolders : > Task :webview_flutter_android:mergeDebugNativeLibs NO-SOURCE : > Task :webview_flutter_android:copyDebugJniLibsProjectOnly : > Task :app:validateSigningDevDebug : > Task :app:writeDevDebugAppMetadata : > Task :app:writeDevDebugSigningConfigVersions : > Task :app:mergeDevDebugNativeLibs : > Task :app:stripDevDebugDebugSymbols : > Task :app:packageDevDebug FAILED : ASM Instrumentation process wasn't able to resolve some classes, this means that : the instrumented classes might contain corrupt stack frames. Make sure the : dependencies that contain these classes are on the runtime or the provided : classpath. Otherwise, the jvm might fail to load the corrupt classes at runtime : when running in a jvm environment like unit tests. : : Classes that weren't resolved: : > androidx.window.extensions.embedding.ActivityEmbeddingComponent : > androidx.window.extensions.layout.WindowLayoutComponent : > androidx.window.sidecar.SidecarDeviceState : > androidx.window.sidecar.SidecarInterface : > com.google.common.util.concurrent.ListenableFuture : > java.net.http.HttpTimeoutException : > javax.naming.NamingException : > javax.naming.directory.Attributes : > sun.misc.Unsafe : > androidx.compose.animation.tooling.ComposeAnimatedProperty : : : Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. : : You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. : : For more on this, please refer to https://docs.gradle.org/8.4/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. : 714 actionable tasks: 713 executed, 1 up-to-date FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:packageDevDebug'. > A failure occurred while executing com.android.build.gradle.tasks.PackageAndroidArtifact$IncrementalSplitterRunnable > java.lang.OutOfMemoryError (no error message) * Try: > Run with --stacktrace option to get the stack trace. > Run with --info or --debug option to get more log output. > Run with --scan to get full insights. > Get more help at https://help.gradle.org. BUILD FAILED in 6m 12s ✗ Failed to build apk with entrypoint test_bundle.dart (Gradle build failed with code 1) (373.5s) Exception: Gradle build failed with code 1 #0 AndroidTestBackend.build. (package:patrol_cli/src/android/android_test_backend.dart:79:9) #1 DisposeScope.run (package:dispose_scope/src/dispose_scope.dart:46:7) #2 AndroidTestBackend.build (package:patrol_cli/src/android/android_test_backend.dart:49:5) #3 BuildAndroidCommand.run (package:patrol_cli/src/commands/build_android.dart:160:7) #4 CommandRunner.runCommand (package:args/command_runner.dart:212:13) #5 PatrolCommandRunner.runCommand (package:patrol_cli/src/runner/patrol_command_runner.dart:366:18) #6 PatrolCommandRunner.run (package:patrol_cli/src/runner/patrol_command_runner.dart:310:18) #7 patrolCommandRunner (package:patrol_cli/src/runner/patrol_command_runner.dart:71:20) #8 main (file:///Users/builder/.pub-cache/hosted/pub.dev/patrol_cli-3.2.1/bin/main.dart:6:20) See the logs above to learn what happened. Also consider running with --verbose. If the logs still aren't useful, then it's a bug - please report it. Exception: Gradle build failed with code 1 #0 AndroidTestBackend.build. (package:patrol_cli/src/android/android_test_backend.dart:79:9) #1 DisposeScope.run (package:dispose_scope/src/dispose_scope.dart:46:7) #2 AndroidTestBackend.build (package:patrol_cli/src/android/android_test_backend.dart:49:5) #3 BuildAndroidCommand.run (package:patrol_cli/src/commands/build_android.dart:160:7) #4 CommandRunner.runCommand (package:args/command_runner.dart:212:13) #5 PatrolCommandRunner.runCommand (package:patrol_cli/src/runner/patrol_command_runner.dart:366:18) #6 PatrolCommandRunner.run (package:patrol_cli/src/runner/patrol_command_runner.dart:310:18) #7 patrolCommandRunner (package:patrol_cli/src/runner/patrol_command_runner.dart:71:20) #8 main (file:///Users/builder/.pub-cache/hosted/pub.dev/patrol_cli-3.2.1/bin/main.dart:6:20) Build failed :| Step 8 script `Build Patrol` exited with status code 1 ```
Logs of SUCCESSFUL build ``` : > Task :patrol:mergeDebugJniLibFolders UP-TO-DATE : > Task :patrol:mergeDebugNativeLibs NO-SOURCE : > Task :patrol:copyDebugJniLibsProjectOnly UP-TO-DATE : > Task :permission_handler_android:mergeDebugJniLibFolders UP-TO-DATE : > Task :permission_handler_android:mergeDebugNativeLibs NO-SOURCE : > Task :permission_handler_android:copyDebugJniLibsProjectOnly UP-TO-DATE : > Task :share_plus:mergeDebugJniLibFolders UP-TO-DATE : > Task :share_plus:mergeDebugNativeLibs NO-SOURCE : > Task :share_plus:copyDebugJniLibsProjectOnly UP-TO-DATE : > Task :shared_preferences_android:mergeDebugJniLibFolders UP-TO-DATE : > Task :shared_preferences_android:mergeDebugNativeLibs NO-SOURCE : > Task :shared_preferences_android:copyDebugJniLibsProjectOnly UP-TO-DATE : > Task :sqflite:mergeDebugJniLibFolders UP-TO-DATE : > Task :sqflite:mergeDebugNativeLibs NO-SOURCE : > Task :sqflite:copyDebugJniLibsProjectOnly UP-TO-DATE : > Task :sqlcipher_flutter_libs:mergeDebugJniLibFolders UP-TO-DATE : > Task :sqlcipher_flutter_libs:mergeDebugNativeLibs NO-SOURCE : > Task :sqlcipher_flutter_libs:copyDebugJniLibsProjectOnly UP-TO-DATE : > Task :url_launcher_android:mergeDebugJniLibFolders UP-TO-DATE : > Task :url_launcher_android:mergeDebugNativeLibs NO-SOURCE : > Task :url_launcher_android:copyDebugJniLibsProjectOnly UP-TO-DATE : > Task :video_player_android:mergeDebugJniLibFolders UP-TO-DATE : > Task :video_player_android:mergeDebugNativeLibs NO-SOURCE : > Task :video_player_android:copyDebugJniLibsProjectOnly UP-TO-DATE : > Task :wakelock_plus:mergeDebugJniLibFolders UP-TO-DATE : > Task :wakelock_plus:mergeDebugNativeLibs NO-SOURCE : > Task :wakelock_plus:copyDebugJniLibsProjectOnly UP-TO-DATE : > Task :webview_flutter_android:mergeDebugJniLibFolders UP-TO-DATE : > Task :webview_flutter_android:mergeDebugNativeLibs NO-SOURCE : > Task :webview_flutter_android:copyDebugJniLibsProjectOnly UP-TO-DATE : > Task :app:mergeDevDebugAndroidTestNativeLibs NO-SOURCE : > Task :app:checkDevDebugAndroidTestDuplicateClasses : > Task :app:validateSigningDevDebugAndroidTest : > Task :app:mergeExtDexDevDebugAndroidTest : > Task :app:mergeLibDexDevDebugAndroidTest : > Task :app:writeDevDebugAndroidTestSigningConfigVersions : > Task :app:mergeProjectDexDevDebugAndroidTest : > Task :app:packageDevDebugAndroidTest : > Task :app:createDevDebugAndroidTestApkListingFileRedirect : > Task :app:assembleDevDebugAndroidTest : : Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. : : You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. : : For more on this, please refer to https://docs.gradle.org/8.4/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. : : BUILD SUCCESSFUL in 8s : 715 actionable tasks: 47 executed, 668 up-to-date ✓ Completed building apk with entrypoint test_bundle.dart (315.8s) ```

Patrol version

patrol: ^3.11.0

Patrol Doctor output

Patrol Doctor output ``` Patrol CLI version: 3.2.1 Flutter command: flutter Flutter 3.24.1 • channel stable Android: • Program adb found in /usr/local/share/android-sdk/platform-tools/adb • Env var $ANDROID_HOME set to /usr/local/share/android-sdk iOS / macOS: • Program xcodebuild found in /usr/bin/xcodebuild • Program ideviceinstaller not found (install with `brew install ideviceinstaller`) ```

Flutter Doctor output

Flutter Doctor output ``` ```
jBorkowska commented 1 week ago

Hi @martin1080p ! Some additional questions:

I checked my project and org.gradle.jvmargs is set to Xmx4608m, so even less and I never encountered this error. Do you build the tests multiple times on the same workflow, so the machine is not clean? Or this happens on a clean machine?

Maybe this much memory is indeed needed, but it is unlikely imo. Did you try to increase this parameter?

martin1080p commented 1 week ago

This error hasn't occurred when tested locally on Win, Linux and Mac.

This parameter was already increased from -Xms2048M, where the same error occurred as well. But sometimes like with this setting, it has been built successfully.

Unfortunately I am unable to share the whole project since it's commercial. However I might be able to share some pieces of code on demand.

jBorkowska commented 5 days ago

I think we should search for solution around the workflow or codemagic machines. Could you share what your workflow looks like? Can be just steps names, maybe there is something that consumes most of the memory before building

We also found this, maybe you'll find it helpful: https://docs.codemagic.io/troubleshooting/common-android-issues/#java-heap-space-out-of-memory-error

martin1080p commented 4 days ago

@jBorkowska

android-integration-tests:
    name: Android Integration tests
    environment:
      <<: *android-apk-environment
      vars: *dev-variables
    scripts:
      - *tools-setup
      - *android-local-props-setup
      - *project-setup
      # - *analyze
      # - *dcm
      # - *tests
      - name: Patrol and GCloud setup
        script: |
          echo "Install patrol_cli"
          dart pub global activate patrol_cli
          patrol doctor

          echo "Setting up GCloud"
          echo $FIREBASE_INTEGRATION_KEY > ./gcloud_key_file.json
          gcloud auth activate-service-account --key-file=gcloud_key_file.json
          gcloud projects list
          gcloud --quiet config set project $FIREBASE_PROJECT_ID
          # TODO: TEMP solution
          gcloud components update
      #- *build-apk-android
      - name: Build Patrol
        working_directory: apps/bakalari
        script: |
          # Generate gradlew first
          flutter build apk --config-only -t lib/$RUN_FILE --flavor $FLAVOR
          patrol build android -t integration_test --verbose
      - name: Wakeup server
        script: curl --head --connect-timeout 60 --max-time 90 https://11.ext.bakalari.cz/
      - name: Run test
        working_directory: apps/bakalari
        script: |
          echo "Starting tests"
          ./scripts/firebase-test-lab-android.sh -l "$PROJECT_BUILD_NUMBER" -t 5m -p android-preset-small