Skip to content

Add test apps template and fireci commands to measure sdk startup times. #2611

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

Merged
merged 6 commits into from
May 5, 2021

Conversation

yifanyang
Copy link
Contributor

No description provided.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Apr 22, 2021

Coverage Report

Affected SDKs

  • firebase-database

    SDK overall coverage changed from 48.85% (3f0779e) to 48.88% (01dd79eb) by +0.03%.

    Filename Base (3f0779e) Head (01dd79eb) Diff
    ChildChangeAccumulator.java 83.33% 96.67% +13.33%
    QueryParams.java 90.36% 89.76% -0.60%
  • firebase-messaging

    SDK overall coverage changed from ? (3f0779e) to 83.43% (01dd79eb) by ?.

    Click to show coverage changes in 23 files.
    Filename Base (3f0779e) Head (01dd79eb) Diff
    CommonNotificationBuilder.java ? 91.63% ?
    Constants.java ? 92.86% ?
    DisplayNotification.java ? 91.38% ?
    EnhancedIntentService.java ? 80.00% ?
    ExecutorFactory.java ? 0.00% ?
    FcmExecutors.java ? 85.71% ?
    FirebaseMessaging.java ? 65.00% ?
    FirebaseMessagingRegistrar.java ? 83.33% ?
    FirebaseMessagingService.java ? 94.79% ?
    FirelogAnalyticsEvent.java ? 26.67% ?
    ImageDownload.java ? 87.18% ?
    MessagingAnalytics.java ? 63.93% ?
    NotificationParams.java ? 98.71% ?
    PoolableExecutors.java ? 29.17% ?
    RemoteMessage.java ? 95.48% ?
    RemoteMessageCreator.java ? 88.89% ?
    SendException.java ? 100.00% ?
    SharedPreferencesQueue.java ? 98.44% ?
    ThreadPriority.java ? 100.00% ?
    TopicOperation.java ? 90.00% ?
    TopicsStore.java ? 100.00% ?
    TopicsSubscriber.java ? 89.66% ?
    TopicsSyncTask.java ? 53.33% ?
  • firebase-perf

    SDK overall coverage changed from ? (3f0779e) to 70.63% (01dd79eb) by ?.

    Click to show coverage changes in 95 files.
    Filename Base (3f0779e) Head (01dd79eb) Diff
    AddTrace.java ? 0.00% ?
    AndroidApplicationInfo.java ? 34.71% ?
    AndroidApplicationInfoOrBuilder.java ? 0.00% ?
    AndroidLogger.java ? 97.78% ?
    AndroidMemoryReading.java ? 38.36% ?
    AndroidMemoryReadingOrBuilder.java ? 0.00% ?
    AppStartTrace.java ? 85.71% ?
    AppStateMonitor.java ? 86.78% ?
    AppStateUpdateHandler.java ? 92.59% ?
    ApplicationInfo.java ? 45.00% ?
    ApplicationInfoOrBuilder.java ? 0.00% ?
    ApplicationProcessState.java ? 73.91% ?
    Clock.java ? 100.00% ?
    ConfigResolver.java ? 97.23% ?
    ConfigurationConstants.java ? 99.21% ?
    ConfigurationFlag.java ? 100.00% ?
    Constants.java ? 95.65% ?
    Counter.java ? 90.91% ?
    CpuGaugeCollector.java ? 93.10% ?
    CpuMetricReading.java ? 39.33% ?
    CpuMetricReadingOrBuilder.java ? 0.00% ?
    DaggerFirebasePerformanceComponent.java ? 100.00% ?
    DeviceCacheManager.java ? 76.03% ?
    FirebasePerfApplicationInfoValidator.java ? 92.86% ?
    FirebasePerfGaugeMetricValidator.java ? 100.00% ?
    FirebasePerfHttpClient.java ? 93.85% ?
    FirebasePerfMetricProto.java ? 0.00% ?
    FirebasePerfNetworkValidator.java ? 86.67% ?
    FirebasePerfOkHttpClient.java ? 44.90% ?
    FirebasePerfProvider.java ? 76.92% ?
    FirebasePerfRegistrar.java ? 100.00% ?
    FirebasePerfTraceValidator.java ? 88.24% ?
    FirebasePerfUrlConnection.java ? 44.26% ?
    FirebasePerformance.java ? 82.95% ?
    FirebasePerformanceAttributable.java ? 0.00% ?
    FirebasePerformanceComponent.java ? 0.00% ?
    FirebasePerformanceInitializer.java ? 33.33% ?
    FirebasePerformanceModule.java ? 100.00% ?
    FirebasePerformanceModule_ProvidesConfigResolverFactory.java ? 100.00% ?
    FirebasePerformanceModule_ProvidesFirebaseAppFactory.java ? 100.00% ?
    FirebasePerformanceModule_ProvidesFirebaseInstallationsFactory.java ? 100.00% ?
    FirebasePerformanceModule_ProvidesGaugeManagerFactory.java ? 100.00% ?
    FirebasePerformanceModule_ProvidesRemoteConfigComponentFactory.java ? 100.00% ?
    FirebasePerformanceModule_ProvidesRemoteConfigManagerFactory.java ? 100.00% ?
    FirebasePerformanceModule_ProvidesTransportFactoryProviderFactory.java ? 100.00% ?
    FirebasePerformance_Factory.java ? 100.00% ?
    FlgTransport.java ? 83.33% ?
    GaugeManager.java ? 98.39% ?
    GaugeMetadata.java ? 32.21% ?
    GaugeMetadataManager.java ? 84.21% ?
    GaugeMetadataOrBuilder.java ? 0.00% ?
    GaugeMetric.java ? 39.47% ?
    GaugeMetricOrBuilder.java ? 0.00% ?
    HttpMetric.java ? 91.78% ?
    ImmutableBundle.java ? 100.00% ?
    InstrHttpInputStream.java ? 92.86% ?
    InstrHttpOutputStream.java ? 98.00% ?
    InstrHttpURLConnection.java ? 93.42% ?
    InstrHttpsURLConnection.java ? 94.32% ?
    InstrURLConnectionBase.java ? 95.24% ?
    InstrumentApacheHttpResponseHandler.java ? 100.00% ?
    InstrumentOkHttpEnqueueCallback.java ? 100.00% ?
    LogWrapper.java ? 23.08% ?
    MemoryGaugeCollector.java ? 90.00% ?
    NetworkConnectionInfo.java ? 0.00% ?
    NetworkConnectionInfoOrBuilder.java ? 0.00% ?
    NetworkRequestMetric.java ? 49.16% ?
    NetworkRequestMetricBuilder.java ? 95.97% ?
    NetworkRequestMetricBuilderUtil.java ? 75.00% ?
    NetworkRequestMetricOrBuilder.java ? 0.00% ?
    Optional.java ? 86.67% ?
    PendingPerfEvent.java ? 100.00% ?
    PerfMetric.java ? 33.67% ?
    PerfMetricOrBuilder.java ? 0.00% ?
    PerfMetricValidator.java ? 90.32% ?
    PerfSession.java ? 93.33% ?
    PerfSessionOrBuilder.java ? 0.00% ?
    RateLimiter.java ? 90.27% ?
    RemoteConfigManager.java ? 92.24% ?
    ResourceType.java ? 0.00% ?
    SessionAwareObject.java ? 0.00% ?
    SessionManager.java ? 100.00% ?
    SessionVerbosity.java ? 68.42% ?
    StorageUnit.java ? 57.89% ?
    Timer.java ? 93.75% ?
    Trace.java ? 96.69% ?
    TraceMetric.java ? 43.42% ?
    TraceMetricBuilder.java ? 100.00% ?
    TraceMetricOrBuilder.java ? 0.00% ?
    TransportInfo.java ? 0.00% ?
    TransportInfoOrBuilder.java ? 0.00% ?
    TransportManager.java ? 95.10% ?
    URLAllowlist.java ? 94.44% ?
    URLWrapper.java ? 0.00% ?
    Utils.java ? 78.57% ?
  • firebase-storage

    SDK overall coverage changed from 85.81% (3f0779e) to 85.85% (01dd79eb) by +0.04%.

    Filename Base (3f0779e) Head (01dd79eb) Diff
    UploadTask.java 80.22% 80.58% +0.36%

Test Logs

Notes

HTML coverage reports can be produced locally with ./gradlew <product>:checkCoverage.
Report files are located at <product-build-dir>/reports/jacoco/.

Head commit (01dd79eb) is created by Prow via merging commits: 3f0779e 1d71481.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Apr 22, 2021

Binary Size Report

Affected SDKs

No changes between base commit (3f0779e) and head commit (01dd79eb).

Test Logs

Notes

Head commit (01dd79eb) is created by Prow via merging commits: 3f0779e 1d71481.

Copy link
Member

@vkryachko vkryachko left a comment

Choose a reason for hiding this comment

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

My understanding was that mactobenchmark would contain:

  • config.yaml
  • template/ dir

However it contains many files that look like the could be generated, like the base gradle build as well as gradle wrapper itself(can we use gradle wrapper from the root directory)?

gradle.run('assembleAllForSmokeTests')
artifact_versions = _parse_artifacts()

os.chdir('macrobenchmark')
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense to use the contextmanager you have below? i.e. with chdir('foo')

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file is now renamed to macrobenchmark.py. This method call is replaced with with chdir('macrobenchmark'):, at line 48.

@yifanyang
Copy link
Contributor Author

@rlazo @vkryachko

I have updated this pull request with some changes:

  • renamed startup_time.py to macrobenchmark.py
  • removed gradle wrapper from src, but call gradle wrapper task to init at runtime
  • executions of test app assembly and FTL uploading for different SDKs now run concurrently
  • test apps modules are no longer subprojects of the same rootproject at macrobenchmark folder. Test apps modules of different SDKs are now subprojects to its own rootproject for each SDK

Can you help take another look at this pull request? Thanks!

@yifanyang yifanyang marked this pull request as ready for review April 30, 2021 16:53

async def _parse_artifact_versions():
proc = await asyncio.subprocess.create_subprocess_exec('./gradlew', 'assembleAllForSmokeTests')
await proc.wait()
Copy link
Collaborator

Choose a reason for hiding this comment

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

wouldn't line 56 await be enough? not sure

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds to me it is required. So if I don't await on it, it gives me this warning:

/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/unix_events.py:878: RuntimeWarning: A loop is being detached from a child watcher with pending handlers
  RuntimeWarning)

My understanding is that it means the underneath Future object may not be settled before my code exit. Also in the python doc for asyncio subprocess, the first example and the last example also await on proc.communicate() and proc.wait() respectively.

This also reminds me that I forgot to await at other places in the code. The problem was masked previously. I fixed in the new commit.

proc = await asyncio.subprocess.create_subprocess_exec('./gradlew', 'assembleAllForSmokeTests')
await proc.wait()

with open('build/m2repository/changed-artifacts.json', 'r') as json_file:
Copy link
Collaborator

Choose a reason for hiding this comment

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

'r' is the default

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


async def _create_gradle_wrapper():
with open('macrobenchmark/settings.gradle', 'w'):
pass
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Without a settings.gradle file, ./gradlew wrapper failed with this error:

FAILURE: Build failed with an exception.

* What went wrong:
Project directory '/Users/yifany/Documents/firebase/firebase-android-sdk/macrobenchmark' is not part of the build defined by settings file '/Users/yifany/Documents/firebase/firebase-android-sdk/settings.gradle'. If this is an unrelated build, it must have its own settings file.

And looks like an empty settings.gradle is good enough.

asyncio.run(_launch_macrobenchmark_test())


async def _launch_macrobenchmark_test():
Copy link
Member

Choose a reason for hiding this comment

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

What is the motivation for all the asyncs? not sure it's warranted for this simple use case

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here is how I come to all these async code:

  1. gcloud calls takes long time, and I want to parallelize this part
  2. now that test apps for different SDKs are isolated, to build them I need to run ./gradlew assemble assembleAndroidTest one by one in each rootprojects for all SDKs (previously all test apps are subprojects of the same root project, so I only had to run one gradle command, and org.gradle.parallel=true takes care of the parallelization). Anyway I think I want to parallelize this part as well
  3. with Popen and blocking wait, I'm able to make apk assembling and FTL uploading for different SDKs concurrent, respectively. But with async code, it's convenient for me to even make uploading for one SDK only depend on its corresponding assembling.
  4. It also seems easier for me to handle stdout/stderr streaming (with color and sdk name decoration) to parent process from multiple subprocesses with async.
  5. at this point, I feel like it's actually easier for me to write async code.

I do agree that it brings a lot of (unnecessarily) complexity. Maybe there are simpler ways to do it without async, and I just have not found them. What do you think? I'd like to have a quick GVC if you have time?

Copy link
Member

Choose a reason for hiding this comment

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

Actually, I take it back. It does seem to provide a lot of value, not the least of which is that it provides concurrency out of the box without having to deal with it explicitly and makes the code to read simple. Using asyncio sgtm

@yifanyang yifanyang merged commit 976ea2f into master May 5, 2021
@yifanyang yifanyang deleted the yifany/startup-time branch May 5, 2021 20:13
@google-oss-bot
Copy link
Contributor

@yifanyang: The following test failed, say /retest to rerun them all:

Test name Commit Details Rerun command
device-check-changed 1d71481 link /test device-check-changed

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@firebase firebase locked and limited conversation to collaborators Jun 5, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants