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 a java injector for testing #20789

Merged
merged 6 commits into from
Aug 30, 2020
Merged

Conversation

xster
Copy link
Member

@xster xster commented Aug 26, 2020

I was working on https://github.com/flutter/engine/pull/20769/files#diff-1e3150b8858cc1cf6e4f83a2c5172e1aR372 and couldn't test it. We're reaching the limit of scalability for ad-hoc constructor dependency injection especially if it needs to leak the dependencies through the whole plumbing.

Make an injector to make testing easier. Start with the FlutterLoader and swap its singleton getter to use the testable injector.

@auto-assign auto-assign bot requested a review from liyuqian August 26, 2020 18:32
@xster xster requested review from mehmetf, jason-simmons and GaryQian and removed request for liyuqian August 26, 2020 18:56
Copy link
Member

@jason-simmons jason-simmons left a comment

Choose a reason for hiding this comment

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

LGTM

Should FlutterLoader.getInstance and FlutterLoader.getInstanceForTest be removed or deprecated?

@xster
Copy link
Member Author

xster commented Aug 28, 2020

Oh that's a good point. Thanks. I don't see any getInstance uses in google3 but just to be safe, deprecated for now.

Looking at getInstanceForTest, it seems like it's not really what it says it does. I don't think we should have added it in the first place either. Refactored the test that uses it to just use mockito spy which is a lot simpler anyway.

@xster xster added the waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land. label Aug 28, 2020
@fluttergithubbot
Copy link
Contributor

This pull request is not suitable for automatic merging in its current state.

  • Please get at least one approved review before re-applying this label. Reviewers: If you left a comment approving, please use the "approve" review action instead.

@fluttergithubbot fluttergithubbot removed the waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land. label Aug 28, 2020
@@ -252,7 +252,8 @@ public void notifyLowMemoryWarning() {
public static class DartEntrypoint {
@NonNull
public static DartEntrypoint createDefault() {
return new DartEntrypoint(FlutterMain.findAppBundlePath(), "main");
return new DartEntrypoint(
FlutterInjector.instance().flutterLoader().findAppBundlePath(), "main");
Copy link
Contributor

Choose a reason for hiding this comment

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

This still implies findAppBundlePath needs to return a default if FlutterLoader is not inited.

Copy link
Member Author

@xster xster Aug 28, 2020

Choose a reason for hiding this comment

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

This is somewhat implicit but the DartExecutor is created by the engine and only creates it after having loaded the native library. If I understood your question correctly. We can add asserts and stuff too to make the dependency explicit.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, we should add asserts since this is public API IIRC.

Copy link
Member Author

Choose a reason for hiding this comment

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

Turns out this needs a sizable refactor 🤣 3ce3419

PTAL

FlutterLoader.Settings newSettings = new FlutterLoader.Settings();
newSettings.setLogTag(settings.getLogTag());
FlutterLoader.getInstance().startInitialization(applicationContext, newSettings);
FlutterInjector.instance().flutterLoader().startInitialization(applicationContext, newSettings);
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be less verbose to expose helper functions to fetch loader from the injector. Sort of like how modules work in DI frameworks.

Copy link
Member Author

Choose a reason for hiding this comment

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

sure, it's a good idea. I'm currently leaning towards leaving things as simple as possible rather than having a production DI system since it's mostly for us and I want to keep it with as few indirections as possible for now.

@@ -30,43 +30,17 @@ public void pluginsCanAccessFlutterAssetPaths() {
FlutterApplicationInfo emptyInfo =
new FlutterApplicationInfo(null, null, null, null, null, null, false, false);
Copy link
Contributor

Choose a reason for hiding this comment

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

You no longer need this.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks

return;
}
FlutterLoader.getInstance().ensureInitializationComplete(applicationContext, args);
FlutterInjector.instance()
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a breaking change... Apps testing via robolectric will need to do something else to avoid the native library load such as using a mockito spy and overriding loadNativeLibrary.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ya, I thought it might be as well, though I'm not seeing anyone using it cs/isrunninginrobolectrictest. Am I searching it wrong? I'm happy to let https://github.com/flutter/engine/pull/20789/files#diff-8e0c9afcddc7151854497b73e0484fccR92 read out of something in the flutterinjector as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am not against the change :) We just need to document it. You are right, I don't think g3 is using this but someone else might.

Copy link
Member Author

Choose a reason for hiding this comment

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

Our new thing is that breaking changes are things that break tests 😐 https://flutter.dev/docs/resources/compatibility

Copy link
Contributor

Choose a reason for hiding this comment

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

🤷 Up to you :)

@xster
Copy link
Member Author

xster commented Aug 30, 2020

I'm gonna submit this so I can chain my next PR. Windows passed on luci, not sure why it's not reflecting on github.

@xster xster merged commit 15f5696 into flutter:master Aug 30, 2020
@xster xster deleted the java-test-injector branch August 30, 2020 05:29
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 30, 2020
@xster
Copy link
Member Author

xster commented Sep 1, 2020

I did end up breaking a test in the plugins repo T.T

Breaking change doc flutter/website#4561

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.

5 participants