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

Add tests for QR sharing and import #3886

Merged
merged 29 commits into from
Jun 29, 2020
Merged

Conversation

seadowg
Copy link
Member

@seadowg seadowg commented Jun 1, 2020

This involved a bunch of refactoring to make the QR flows more testable.

This also:

  • Adds testing for adding/removing sensitive details from QR code
  • Deletes ignored tests that were partially testing these feature
  • Removes Rx from QR code generation (and updated the STATE.md about this)
  • Use Scheduler abstraction (using Coroutiner under the hood) to deal with async work (as a replacement for AsyncTask and Rx)
  • Introduces PreferencesProvider object for grabbing general, admin or meta shared preferences without dealing with the shared preferences abstractions (update to STATE.md about this as well)
  • Reworks CI to avoid OOM errors that started to block this (but we were seeing occasionally on master). As part of this I've made quality checks and unit tests run in parallel.

What has been done to verify that this works as intended?

Ran through test lab and CI a whole bunch of times

Why is this the best possible solution? Were any other approaches considered?

I think for this it would be best to bring up questions and discuss rather than run through the different changes here.

How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?

There have been changes to both the configure/share QR flow and the audio widget so both would be good to test.

Before submitting this PR, please make sure you have:

  • run ./gradlew checkAll and confirmed all checks still pass OR confirm CircleCI build passes and run ./gradlew connectedDebugAndroidTest locally.
  • verified that any code or assets from external sources are properly credited in comments and/or in the about file.
  • verified that any new UI elements use theme colors. UI Components Style guidelines

@seadowg seadowg force-pushed the qr-robolectric branch 6 times, most recently from add291c to 4e839a8 Compare June 8, 2020 20:31
@seadowg seadowg requested a review from lognaturel June 8, 2020 20:45
@seadowg seadowg marked this pull request as ready for review June 8, 2020 20:45
@lognaturel
Copy link
Member

lognaturel commented Jun 11, 2020

We expect debug builds not to work on Android < 7 for the same reasons as #3772 (comment).

@andrewsiew2 You may be interested to take a look. We'd love your review!

Copy link
Member

@lognaturel lognaturel left a comment

Choose a reason for hiding this comment

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

I went through this relatively quickly and focused on the high-level patterns. As noted in the description, the PR is a bit all over the place but it's relatively easy to follow the reasoning going commit by commit so I'm comfortable with it.

I didn't take the time to review the circleci rework in detail. Things look reasonable, I like the references to the CircleCI docs, and I trust that if it doesn't work we'll know immediately.

I also don't know much about Kotlin Coroutines so it's hard for me to evaluate CoroutineScheduler. It certainly looks straightforward, but I don't know if there are any tradeoffs to consider. @seadowg were there any particular decisions you had to make? Like is Dispatchers.IO the only viable background scope? It would also be good for @grzesiek2010 to take a quick look to know this is coming and have a chance to raise objections or questions. The good news is that with the Scheduler interface it's not a big deal to swap out the implementation if needed for some reason. Is there any impact on APK size? In the last version we already went up by 1mb for some reason so we should be careful about watching for bumps.

PreferencesProvider is a positive change to me.

Other than that the QRCodeViewModel and testing changes look good to me with a couple small things inline.

@seadowg
Copy link
Member Author

seadowg commented Jun 16, 2020

@lognaturel in terms of coroutines I'm honestly not that experienced either. As far as decisions go:

  • I followed the docs on Coroutine performance for making decisions about dispatchers (https://developer.android.com/kotlin/coroutines-adv#main-safety). We can definitely do even better and have coroutines run in the specific viewModelScope/lifecycleScope and also start using the Dispatchers.Default where appropriate. I think this really requires the call site to be Kotlin however so that's a bit down the line.
  • There is the Espresso trade off - Espresso is unable to sync with Coroutine dispatchers in the same way it does for AsyncTask's thread pool. I've built tooling (the CountingScheduler etc) around this however.
  • There probably is an impact to APK size: I think we might need to make sure our submodules are proguarded as it looks like they aren't right now. I don't think we'll see a large increase other than that as it looks like we were already pulling in the Kotlin standard lib as part of Android deps. I'd prefer to not add anything to this PR though and suggest we measure that and fix after merge.

@lognaturel
Copy link
Member

I'm satisfied by those answers. It can be iterated on, anyway.

I think we might need to make sure our submodules are proguarded as it looks like they aren't right now

That likely explains the size increase with the last release. Could you please file an issue for the v1.28 milestone?

When you make those couple small changes above it's an accept from me.

@seadowg
Copy link
Member Author

seadowg commented Jun 17, 2020

@lognaturel ach I made those changes and then didn't push them. My bad. They're up now.

@seadowg
Copy link
Member Author

seadowg commented Jun 24, 2020

I'm going to set this to "needs testing" as I'm starting to get into problems where I want to work on top of some of this stuff AND other PRs that are in review. @grzesiek2010 if you have any comments happy to chat here or on Slack!

@getodk-bot label "needs testing"

@kkrawczyk123
Copy link
Contributor

@seadowg I have started testing but unfortunately Collect is crashing when open Configure via QR code from both menu and admin settings on Android 7 and 10 - it is not on Android 5.1 so it is connected to permissions. When I enabled Camera permissions through App settings I was able to open it and the crash was not visible.
stacktrace:
2020-06-24 15:54:56.090 17945-17945/org.odk.collect.android E/AndroidRuntime: FATAL EXCEPTION: main Process: org.odk.collect.android, PID: 17945 java.lang.NullPointerException: Attempt to invoke virtual method 'void org.odk.collect.android.preferences.qr.QRCodeMenuDelegate.onCreateOptionsMenu(android.view.MenuInflater, android.view.Menu)' on a null object reference at org.odk.collect.android.preferences.qr.QRCodeTabsActivity.onCreateOptionsMenu(QRCodeTabsActivity.java:107) at android.app.Activity.onCreatePanelMenu(Activity.java:4093) at androidx.fragment.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:324) at androidx.appcompat.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:94) at androidx.appcompat.app.AppCompatDelegateImpl$AppCompatWindowCallback.onCreatePanelMenu(AppCompatDelegateImpl.java:2830) at androidx.appcompat.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:94) at androidx.appcompat.app.ToolbarActionBar.populateOptionsMenu(ToolbarActionBar.java:455) at androidx.appcompat.app.ToolbarActionBar$1.run(ToolbarActionBar.java:56) at android.os.Handler.handleCallback(Handler.java:883) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7356) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

I have also checked the master where the crash does not occur.

@seadowg
Copy link
Member Author

seadowg commented Jun 24, 2020

@kkrawczyk123 ach I see the problem. Pushing a fix now.

@kkrawczyk123
Copy link
Contributor

Tested with success!
Verified on Androids: 5.1, 7.0, 8.1, 9.0 and 10.

Tested cases:

  • configure via QR code
  • scan
  • valid
  • invalid
  • inverted
  • generate
  • import from QR code file
  • invalid
  • valid
  • Admin password
  • different Admin password and server password - they are not mixed
  • checked all permission dialogs: no crashes
  • barcode widget
  • front barcode widget
  • audio widget
  • selfie widget
  • selfie video widget

@getodk-bot unlabel "needs testing"
@getodk-bot label "behavior verified"

@seadowg seadowg merged commit a6189d8 into getodk:master Jun 29, 2020
@seadowg seadowg deleted the qr-robolectric branch June 29, 2020 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants