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

[RunAllTests] Fix part of #2787: Add support for proto lesson loading from local assets #2978

Merged

Conversation

BenHenning
Copy link
Member

@BenHenning BenHenning commented Mar 23, 2021

Fix part of #2787

This adds initial support for loading the new lessons needed for alpha. In particular, to better prepare the codebase for post-alpha beta work, this PR is introducing support for directly loading proto assets rather than JSON (bypassing the entire JSON loading pipeline). This requires punching a few holes into various retrievers/controllers (gated by a new qualified boolean: LoadLessonProtosFromAssets) to load proto rather than JSON. The resulting proto code is a bit simpler than the JSON versions since typing becomes much simpler.

In order to ensure the new pathways are (mostly) working in tests, this PR enables proto caching in some tests. However doing this isn't straightforward: we don't want to check actual binary proto files into the codebase since they are binary files and will unnecessarily bloat our repository. Textproto is a more reasonable alternative since it's plaintext (and actually a bit more compact than JSON), but complicated to use: proto lite does not support loading via TextFormat. Rather than introducing a dependency on JsonFormat (to avoid JSON altogether), I decided instead to introduce a custom Starlark rule in Bazel to, at build time, convert textproto files to binary files & include those at build time. This works quite well: for both the apk itself & tests we can load binary pb files as though we're including them directly. Also, for this reason is why the PR includes textproto conversions of our development assets.

However, the above approach only works for Bazel. To mitigate this, the few test suites that were updated to verify the fixes conditionally enable proto loading based on whether the environment is Bazel. This is a bit hacky, but it seems like the best solution in the interim until we can entirely move off of Gradle per #59.

Other considerations for this PR:

  • This removes dependence on test story 1 entirely because it includes structural elements that are incompatible with the pipeline used to convert to text/binary proto. This seems fine since we don't actually need these interactions for testing or development.
  • This removes support for confirmed unclassified answers since they aren't used at all, and probably won't be in Android.
  • This PR does not introduce support for the up-to-date interactions that will be shipped with the alpha. That will happen in a later PR (mainly [RunAllTests] Fix #2944, #2787, #298, #3007: Update interactions to support new localization structures #2985).
  • The textproto files introduced in this PR were generated using an in-progress script that's also being used to download the assets that will be used for alpha. Follow up with me if you want to see the script.
  • Enabling proto caching & running the APK locally will yield to images not loading. This is partly due to [RunAllTests] Fix #2941: Fix glide image loading in Bazel #2979 (in that they can't load without that fix), but mostly due to the fact that all of our dev assets short-circuit thumbnails (which is why we never discovered Locked lesson thumbnails don't blur when loaded as SVGs #2940 until working on alpha)

Note that I can't actually verify Espresso tests are working with these
versions since the Bazel project doesn't yet have Espresso tests set up.
@BenHenning BenHenning changed the title Fix #2787: Add support for proto lesson loading from local assets [Blocked: #2977] Fix part of #2787: Add support for proto lesson loading from local assets [Blocked: #2977] Mar 23, 2021
@BenHenning BenHenning changed the base branch from develop to fix-protobuf-duplication-issue March 23, 2021 06:19
@BenHenning BenHenning marked this pull request as ready for review March 24, 2021 09:52
@BenHenning BenHenning marked this pull request as draft March 24, 2021 09:52
@BenHenning
Copy link
Member Author

BenHenning commented Mar 24, 2021

/cc @vinitamurthi

.addAllSubtopic(subtopicList)
.setTopicPlayAvailability(topicPlayAvailability)
.build()
}

private fun loadSubtopic(topicId: String, subtopicId: Int): Subtopic {
val subtopicRecord = assetRepository.loadProtoFromLocalAssets(
assetName = "${topicId}_$subtopicId",
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm wondering if there's a better way to sent this request rather than the assetname which is a slightly vague variable name since it looks like it's picking up assets for different ids. Maybe asset type (as an enum), asset Id (which is called asset name here) , and base message?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure I follow--what advantage does an enum give us here? The main typing mechanism is the base message type, and introducing an enum may require us to keep the types & enum in-sync which will add complexity.

Copy link
Contributor

Choose a reason for hiding this comment

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

My suggestion was because we are setting the asset name to be of a different format based on the asset types (i.e. subtopics have a different format of asset name (being topicId_subtopicID) , where as other assets have a different format for their asset names. But it looks like this is because of the way the file names are created, and given that this code may be unnecessary in a few months I guess its okay.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah--I don't think we should over-index on this since the long-term solution should utilize more of a database-type structure for managing files. Thanks for bringing this up, though!

return if (loadLessonProtosFromAssets) {
val topicIdList =
assetRepository.loadProtoFromLocalAssets(
assetName = "topics",
Copy link
Contributor

Choose a reason for hiding this comment

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

Here this kind of breaks the paradigm for assetName compared to the fields that are being used above, so I think it may be better to keep assetType, assetId, and baseMessage

Copy link
Member Author

Choose a reason for hiding this comment

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

It's not a type though, it's the actual file name checked into the APK. Calling it 'assetType' would be misleading. Perhaps 'assetBaseFIilename' would be the most clear, but it's a bit lengthy. I also don't understand how you're distinguishing between 'type' and 'ID'. This is the topic list so it doesn't have an ID.

It could be named better but I'm following existing filenames to keep things a bit simpler. We'll be removing all of this code in coming months, anyway, in favor of downloading & caching completely dynamically.

Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as above..given that this code will be dead soon I think its okay

Copy link
Member Author

Choose a reason for hiding this comment

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

Ack, thanks.

This actually provides Bazel-only support for converting text protos to
binary and including those as assets so that we can avoid checking in
binary protos to the codebase.
This imports local conversions of all existing dev assets as text proto
leveraging the Bazel-only conversion system to convert these to binary
protos and include them as assets.

This is a necessary step to both eventually replace JSON assets with
text proto, and to test that the new proto loading pipeline is working
as designed.
Various attempts to fix existing tests + move some of the domain tests
over to actually using proto when running with Bazel.

App module tests are hanging currently for unknown reasons (only in
Bazel).
3.1.0 causes tests to hang indefinitely when run with Bazel.
This moves the coroutine dispatchers to a new threading subpackage. It
also simplifies the TestCoroutineDispatcher interface & implementations
(which required moving runUntilIdle to CoroutineExecutorServiceTest).

The test coroutine annotations were also moved to their own files.
This introduces new Bazel libraries for:
- Test dispatchers
- Fake system/Oppia clocks
- Robolectric dependencies
This also fixes some threading issues in the dispatcher, and clarifies
some of its API that was previously unclear (and can lead to subtle race
conditions).
This required a bunch of refactoring, adding the first examples of
dedicated Bazel test build files, and introducing a new test pattern for
sharing code between different implementations. Further, it refined the
API for TesCoroutineDispatcher & fixed some issues in the
implementations (especially Robolectric).

Tests verified as non-flaky in Robolectric across 1000 runs, and 0.2%
flaky across 1000 runs for Espresso (though that may be fixed; waiting
on a follow-up run to confirm stability).
@BenHenning BenHenning changed the title Fix part of #2787: Add support for proto lesson loading from local assets [Blocked: #2977] [RunAllTests] Fix part of #2787: Add support for proto lesson loading from local assets [Blocked: #2977] Apr 12, 2021
@BenHenning BenHenning changed the base branch from fix-protobuf-duplication-issue to develop April 12, 2021 23:59
@BenHenning BenHenning changed the title [RunAllTests] Fix part of #2787: Add support for proto lesson loading from local assets [Blocked: #2977] [RunAllTests] Fix part of #2787: Add support for proto lesson loading from local assets Apr 13, 2021
@BenHenning BenHenning marked this pull request as ready for review April 13, 2021 00:02
@BenHenning
Copy link
Member Author

Thanks @vinitamurthi. FYI that this is ready for full review--PTAL.

@anandwana001 & @rt4914 PTAL as codeowners.

Copy link
Contributor

@rt4914 rt4914 left a comment

Choose a reason for hiding this comment

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

LGTM for code-owner files.

@rt4914 rt4914 removed their assignment Apr 13, 2021
@vinitamurthi vinitamurthi removed their assignment Apr 13, 2021
…oto-lesson-loading-from-local-assets

Conflicts:
	app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt
	domain/src/test/java/org/oppia/android/domain/exploration/ExplorationDataControllerTest.kt
	domain/src/test/java/org/oppia/android/domain/topic/TopicControllerTest.kt
	domain/src/test/java/org/oppia/android/domain/topic/TopicListControllerTest.kt
	testing/src/test/java/org/oppia/android/testing/story/StoryProgressTestHelperTest.kt
Copy link
Contributor

@anandwana001 anandwana001 left a comment

Choose a reason for hiding this comment

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

LGTM, nit change but can be ignored


def _extract_proto_sources(deps):
"""
Returns the list of proto source files that make up the specified list of proto dependencies.
Copy link
Contributor

Choose a reason for hiding this comment

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

we can use the # for comments, nit fix, not blocking

Copy link
Member Author

Choose a reason for hiding this comment

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

@anandwana001 I don't think we should be. See https://skydoc.bazel.build/docs/writing.html for examples on writing Skydocs. They use multi-line strings, not #. I think we should be treating # as line comments and """ as documentation (which also matches Oppia web).

I did notice I'm not formatting on the correct line, but we can fix that in a later PR by making all documentation consistent.

@BenHenning
Copy link
Member Author

ClassroomService Bazel failure will be fixed by #2916.

@BenHenning
Copy link
Member Author

Thanks all for the review! Merging this now to keep the PR chain moving forward.

@BenHenning BenHenning merged commit cb1ddc8 into develop Apr 15, 2021
@BenHenning BenHenning deleted the add-support-for-proto-lesson-loading-from-local-assets branch April 15, 2021 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants