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

When appium starts it prevents the initialisation of a RealmDB #793

Open
patrickdargel opened this issue Jun 14, 2022 · 12 comments
Open

When appium starts it prevents the initialisation of a RealmDB #793

patrickdargel opened this issue Jun 14, 2022 · 12 comments
Labels

Comments

@patrickdargel
Copy link

patrickdargel commented Jun 14, 2022

The Problem

When starting the Andoird App via Appium, the driver terminates with the message: "org.openqa.selenium.SessionNotCreatedException: Could not start a new session. Response code 500. Message: A new session could not be created."
logcat shows following issue: "Caused by: kotlin.UninitializedPropertyAccessException: lateinit property filesDir has not been initialized"
From our point of view it seems like the Android app gets started in a way, the prevents or fails the initialisation of the realmDB.

Environment

Android App

Test automation

  • [email protected]
  • appium java-client 8.1.1
  • selenium 4.2.1
  • spresso-driver [email protected]
  • espressoBuildConfig capability:
    • "{"compileSdk":31} ," +
    • ""additionalAndroidTestDependencies": " +
      • "["androidx.compose.runtime:runtime:1.1.1" , " +
      • ""androidx.compose.ui:ui-tooling:1.1.1" , " +
      • ""androidx.compose.foundation:foundation:1.1.1" , " +
      • ""androidx.compose.material:material:1.1.1" ] }");

### Details
logcat output:

06-08 15:03:02.695  2067  2067 E MonitoringInstr: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
06-08 15:03:02.695  2067  2067 E MonitoringInstr: Caused by: java.lang.reflect.InvocationTargetException
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at java.lang.reflect.Method.invoke(Native Method)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   ... 1 more
06-08 15:03:02.695  2067  2067 E MonitoringInstr: Caused by: kotlin.UninitializedPropertyAccessException_bGF0ZWluaXQgcHJvcGVydHkgZmlsZXNEaXIgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVk: lateinit property filesDir has not been initialized
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.di.RealmModule.provideRealmDatabase(RealmModule.kt:66)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.di.RealmModule_ProvideRealmDatabaseFactory.provideRealmDatabase(RealmModule_ProvideRealmDatabaseFactory.java:47)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.DaggerApp_HiltComponents_SingletonC$SingletonCImpl$SwitchingProvider.get(DaggerApp_HiltComponents_SingletonC.java:1148)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.DaggerApp_HiltComponents_SingletonC$SingletonCImpl.settingsRepository(DaggerApp_HiltComponents_SingletonC.java:1018)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.DaggerApp_HiltComponents_SingletonC$SingletonCImpl.settingsUseCase(DaggerApp_HiltComponents_SingletonC.java:1022)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.DaggerApp_HiltComponents_SingletonC$SingletonCImpl.access$2700(DaggerApp_HiltComponents_SingletonC.java:948)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.DaggerApp_HiltComponents_SingletonC$SingletonCImpl$SwitchingProvider.get(DaggerApp_HiltComponents_SingletonC.java:1145)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.DaggerApp_HiltComponents_SingletonC$SingletonCImpl.injectApp2(DaggerApp_HiltComponents_SingletonC.java:1125)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.DaggerApp_HiltComponents_SingletonC$SingletonCImpl.injectApp(DaggerApp_HiltComponents_SingletonC.java:1120)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.Hilt_App.hiltInternalInject(Hilt_App.java:49)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.Hilt_App.onCreate(Hilt_App.java:40)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.App.onCreate(App.kt:26)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1192)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at androidx.test.runner.MonitoringInstrumentation.callApplicationOnCreate(MonitoringInstrumentation.java:442)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7573)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at android.app.ActivityThread.access$1500(ActivityThread.java:301)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2166)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at android.os.Handler.dispatchMessage(Handler.java:106)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at android.os.Looper.loop(Looper.java:246)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at android.app.ActivityThread.main(ActivityThread.java:8633)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   ... 3 more
06-08 15:03:02.695  2067  2067 E MonitoringInstr: Caused by: kotlin.UninitializedPropertyAccessException: lateinit property filesDir has not been initialized
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at io.realm.internal.platform.RealmInitializer$Companion.getFilesDir(RealmInitializer.kt:32)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at io.realm.internal.platform.SystemUtilsAndroidKt.appFilesDirectory(SystemUtilsAndroid.kt:11)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at io.realm.internal.ConfigurationImpl.normalizePath(ConfigurationImpl.kt:180)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at io.realm.internal.ConfigurationImpl.<init>(ConfigurationImpl.kt:88)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at io.realm.internal.RealmConfigurationImpl.<init>(RealmConfigurationImpl.kt:42)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at io.realm.RealmConfiguration$Builder.build(RealmConfiguration.kt:79)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at io.realm.RealmConfiguration$Builder.build(RealmConfiguration.kt:47)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.db.SchemaKt.openRealmWith(Schema.kt:47)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   at de.gematik.ti.erp.app.di.RealmModule.provideRealmDatabase(RealmModule.kt:52)
06-08 15:03:02.695  2067  2067 E MonitoringInstr:   ... 24 more
@KazuCocoa
Copy link
Member

The initialization should be proper place. Probably your app under test does not work with Espresso framework (by Google) with current implementation.

@patrickdargel
Copy link
Author

patrickdargel commented Jun 15, 2022

@KazuCocoa Thanks a lot for your quick response.
I tried to highlight it under the environment part, but I will try to outline it a little bit clearer:
The app under test works with the Espresso framework in its current implementation.
I have added the respective espresso version androidx.test.espresso:espresso-core:3.4.0 to the environment

I sincerely hope I did not misunderstand you.

@KazuCocoa
Copy link
Member

hm, thank you.

The app start itself as same as vanilla espresso does since Appium espresso driver itself does not launch the app under test. Espresso framework does.

The app under test works with the Espresso framework in its current implementation.

Do your code do something in the Espresso test code side?

@patrickdargel
Copy link
Author

thank you.

Our code does not do anything to the Espresso test code side.
Our current test code is very basic so, if desired, I could share the class with you.

@KazuCocoa
Copy link
Member

This espresso driver starts with androidx.test.runner.AndroidJUnitRunner as below, so basically the lifecycle also depends on androidx.test.runner.AndroidJUnitRunner. We do not customize it.

const cmd = [
'shell',
'am', 'instrument',
'-w',
'-e', 'debug', process.env.ESPRESSO_JAVA_DEBUG === 'true',
'-e', 'disableAnalytics', true, // To avoid unexpected error by google analytics
];
if (_.isBoolean(this.disableSuppressAccessibilityService)) {
cmd.push('-e', 'DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES', this.disableSuppressAccessibilityService);
}
cmd.push(`${TEST_APK_PKG}/androidx.test.runner.AndroidJUnitRunner`);

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

I haven't used Realm, but when is https://github.com/realm/realm-kotlin/blob/4fb30d70e0a7ef671d98c47249079bbaf8a9b764/packages/library-base/src/androidMain/kotlin/io/realm/kotlin/internal/platform/RealmInitializer.kt#L35 called?

@patrickdargel
Copy link
Author

patrickdargel commented Jun 20, 2022

The RealmInitializer is called in the AndroidManifest.xml

   <application>
        <provider
                android:name="androidx.startup.InitializationProvider"
                tools:node="merge"
                android:authorities="${applicationId}.androidx-startup"
                android:exported="false">
            <meta-data
                    android:name="io.realm.kotlin.internal.platform.RealmInitializer"
                    android:value="androidx.startup" />
        </provider>
    </application>

https://github.com/realm/realm-kotlin/blob/4fb30d70e0a7ef671d98c47249079bbaf8a9b764/packages/library-base/src/androidMain/AndroidManifest.xml

@KazuCocoa
Copy link
Member

Should the Manifest in the espresso's apk one? So, should the android test package also have it?

@patrickdargel
Copy link
Author

Sorry for the long delay. Thank you for the suggestion KazuCocoa. We try to include as much of the dependencies as we could and also tried to bring the Manifest into the Automation Suite.
Sadly, the issue could not be solved.

@KazuCocoa
Copy link
Member

@okafke
Copy link

okafke commented Jul 7, 2022

Should the Manifest in the espresso's apk one? So, should the android test package also have it?

By adding the realm dependency to the espresso build config the generated espresso apk's Manifest will contain the Initializer, but it still won't get called.

It also needs to be mentioned that this issue is not limited to the RealmDB. With Appium-Espresso none of the androidx.startup.Initializers from the Manifest will get called. I was able to recreate this on multiple apps that use other App Startup Initializers. To name two:

All these apps are fine when started normally.


The one workaround I was able to find is to initialize the Initializer manually before it's needed, like this:

AppInitializer.getInstance(applicationContext).initializeComponent(RealmInitializer::class.java) 

but I think it would be much more feasible if Initializers would also work in the documented way with Appium Espresso.

mm, then, potentially should https://github.com/appium/appium-espresso-driver/blob/master/espresso-server/app/src/androidTest/java/io/appium/espressoserver/EspressoServerRunnerTest.kt#L64 have something for RealmDB usage...?

I'm not deep enough into the matter to help, but sure, support for App Startup in general would be nice.

@okafke
Copy link

okafke commented Jan 26, 2023

I checked the code that starts the app in ActivityHelpers and I do not see anything that could cause this. Could this be an issue of Androidx Startup itself?

This ticket seems related: https://issuetracker.google.com/issues/230844558
When running instrumented tests, Androidx start up may run it's initializers before the instrumentation is ready.

@KazuCocoa
Copy link
Member

hm, thank for the informatin

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

No branches or pull requests

3 participants