Skip to content

Commit 7167d48

Browse files
authored
Merge 0dffae6 into fc8aa1a
2 parents fc8aa1a + 0dffae6 commit 7167d48

File tree

7 files changed

+122
-14
lines changed

7 files changed

+122
-14
lines changed

.github/workflows/health-metrics.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,12 @@ jobs:
122122
echo $INTEG_TESTS_GOOGLE_SERVICES | base64 -d > $BENCHMARK_APP_LOCATION
123123
- name: Run startup-time tests (presubmit)
124124
if: ${{ github.event_name == 'pull_request' }}
125-
run: fireci macrobenchmark ci --pull-request
125+
run: |
126+
git diff --name-only HEAD~1 | \
127+
xargs printf -- '--changed-git-paths %s\n' | \
128+
xargs ./gradlew writeChangedProjects --output-file-path=modules.json
129+
fireci macrobenchmark ci --pull-request --changed-modules-file modules.json
126130
- name: Run startup-time tests (post-submit)
127131
if: ${{ github.event_name == 'push' }}
128-
run: fireci macrobenchmark ci --push
132+
run: |
133+
fireci macrobenchmark ci --push

ci/fireci/fireciplugins/macrobenchmark/commands.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@
1515
import asyncio
1616
import click
1717
import json
18+
import logging
1819

1920
from .analyze import analyzer
2021
from .run import runner
2122
from fireci import ci_command, ci_utils, uploader
2223
from pathlib import Path
2324
from typing import List
2425

26+
logger = logging.getLogger('fireci.macrobenchmark')
27+
2528

2629
@ci_command(cls=click.Group)
2730
def macrobenchmark():
@@ -38,7 +41,7 @@ def macrobenchmark():
3841
)
3942
@click.option(
4043
'--local/--remote',
41-
required=True,
44+
default=True,
4245
help='Run the test on local devices or Firebase Test Lab.'
4346
)
4447
@click.option(
@@ -132,28 +135,45 @@ def analyze(
132135
required=True,
133136
help='Whether the test is running for a pull request or a push event.'
134137
)
138+
@click.option(
139+
'--changed-modules-file',
140+
type=click.Path(resolve_path=True, path_type=Path),
141+
help='Contains a list of changed modules in the current pull request.'
142+
)
135143
@click.option(
136144
'--repeat',
137145
default=10,
138146
show_default=True,
139147
help='Number of times to repeat the test (for obtaining more data points).'
140148
)
141149
@ci_command(group=macrobenchmark)
142-
def ci(pull_request, repeat):
150+
def ci(pull_request: bool, changed_modules_file: Path, repeat: int):
143151
"""Run tests in CI and upload results to the metric service."""
144152

145-
# TODO(yifany): run tests only for affected product in pull requests
146-
147153
output_path = Path("macrobenchmark-test-output.json")
148154
exception = None
155+
149156
try:
150-
asyncio.run(runner.start(build_only=False, local=False, repeat=repeat, output=output_path))
157+
if pull_request:
158+
asyncio.run(
159+
runner.start(
160+
build_only=False,
161+
local=False,
162+
repeat=repeat,
163+
output=output_path,
164+
changed_modules_file=changed_modules_file,
165+
)
166+
)
167+
else:
168+
asyncio.run(runner.start(build_only=False, local=False, repeat=repeat, output=output_path))
151169
except Exception as e:
170+
logger.error(f"Error: {e}")
152171
exception = e
153172

154173
with open(output_path) as output_file:
155174
output = json.load(output_file)
156-
ftl_dirs = list(filter(lambda x: x['project'] == 'all-included', output))[0]['successful_runs']
175+
project_name = 'test-changed' if pull_request else 'test-all'
176+
ftl_dirs = list(filter(lambda x: x['project'] == project_name, output))[0]['successful_runs']
157177
ftl_bucket_name = 'fireescape-benchmark-results'
158178

159179
log = ci_utils.ci_log_link()

ci/fireci/fireciplugins/macrobenchmark/run/runner.py

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,25 @@
2222
from .test_project_builder import TestProjectBuilder
2323
from .utils import execute
2424
from pathlib import Path
25-
from typing import Dict
25+
from typing import Dict, List, Set
2626

2727

2828
logger = logging.getLogger('fireci.macrobenchmark')
2929

3030

31-
async def start(build_only: bool, local: bool, repeat: int, output: Path):
31+
async def start(
32+
build_only: bool,
33+
local: bool,
34+
repeat: int,
35+
output: Path,
36+
changed_modules_file: Path = None
37+
):
3238
logger.info('Starting macrobenchmark test ...')
3339

3440
config = _process_config_yaml()
3541
product_versions = _assemble_all_products()
3642
test_dir = _prepare_test_directory()
43+
changed_traces = _process_changed_modules(changed_modules_file)
3744
template_project_dir = Path('health-metrics/benchmark/template')
3845

3946
test_projects = [
@@ -42,6 +49,7 @@ async def start(build_only: bool, local: bool, repeat: int, output: Path):
4249
test_dir,
4350
template_project_dir,
4451
product_versions,
52+
changed_traces,
4553
).build() for test_config in config['test-apps']]
4654

4755
if not build_only:
@@ -99,3 +107,42 @@ def _prepare_test_directory() -> Path:
99107
test_dir = tempfile.mkdtemp(prefix='benchmark-test-')
100108
logger.info(f'Temporary test directory created at: {test_dir}')
101109
return Path(test_dir)
110+
111+
112+
def _process_changed_modules(path: Path) -> List[str]:
113+
trace_names = {
114+
":appcheck": ["fire-app-check"],
115+
":firebase-abt": ["fire-abt"],
116+
":firebase-appdistribution": ["fire-appdistribution"],
117+
":firebase-config": ["fire-rc"],
118+
":firebase-common": ["Firebase", "ComponentDiscovery", "Runtime"],
119+
":firebase-components": ["Firebase", "ComponentDiscovery", "Runtime"],
120+
":firebase-database": ["fire-rtdb"],
121+
":firebase-datatransport": ["fire-transport"],
122+
":firebase-dynamic-links": ["fire-dl"],
123+
":firebase-crashlytics": ["fire-cls"],
124+
":firebase-crashlytics-ndk": ["fire-cls"],
125+
":firebase-firestore": ["fire-fst"],
126+
":firebase-functions": ["fire-fn"],
127+
":firebase-inappmessaging": ["fire-fiam"],
128+
":firebase-inappmessaging-display": ["fire-fiamd"],
129+
":firebase-installations": ["fire-installations"],
130+
":firebase-installations-interop": ["fire-installations"],
131+
":firebase-messaging": ["fire-fcm"],
132+
":firebase-messaging-directboot": ["fire-fcm"],
133+
":firebase-ml-modeldownloader": ["firebase-ml-modeldownloader"],
134+
":firebase-perf": ["fire-perf"],
135+
":firebase-storage": ["fire-gcs"],
136+
":transport": ["fire-transport"],
137+
}
138+
139+
results: Set[str] = set()
140+
if path:
141+
with open(path) as changed_modules_file:
142+
changed_modules = json.load(changed_modules_file)
143+
for module in changed_modules:
144+
for product in trace_names:
145+
if module.startswith(product):
146+
results.update(trace_names[product])
147+
logger.info(f"Extracted changed traces {results} from {path}")
148+
return list(results)

ci/fireci/fireciplugins/macrobenchmark/run/test_project_builder.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from .test_project import TestProject
2222
from .utils import execute
2323
from pathlib import Path
24-
from typing import Any, Dict
24+
from typing import Any, Dict, List
2525

2626

2727
logger = logging.getLogger('fireci.macrobenchmark')
@@ -33,13 +33,15 @@ def __init__(
3333
test_config: Any,
3434
test_dir: Path,
3535
template_project_dir: Path,
36-
product_versions: Dict[str, str]
36+
product_versions: Dict[str, str],
37+
changed_traces: List[str],
3738
):
3839
self.test_config = test_config
3940
self.template_project_dir = template_project_dir
4041
self.product_versions = product_versions
42+
self.changed_traces = changed_traces
4143

42-
self.name = test_config['name']
44+
self.name = 'test-changed' if changed_traces else 'test-all'
4345
self.logger = LogDecorator(logger, self.name)
4446
self.project_dir = test_dir.joinpath(self.name)
4547

@@ -66,7 +68,7 @@ def _flesh_out_mustache_template_files(self):
6668
mustache_context = {
6769
'm2repository': os.path.abspath('build/m2repository'),
6870
'plugins': self.test_config.get('plugins', []),
69-
'traces': self.test_config.get('traces', []),
71+
'traces': [],
7072
'dependencies': [],
7173
}
7274

@@ -79,6 +81,11 @@ def _flesh_out_mustache_template_files(self):
7981
dependency = {'key': dep, 'version': self.product_versions[dep]}
8082
mustache_context['dependencies'].append(dependency)
8183

84+
if 'traces' in self.test_config:
85+
for trace in self.test_config['traces']:
86+
if not self.changed_traces or trace in self.changed_traces:
87+
mustache_context['traces'].append(trace)
88+
8289
renderer = pystache.Renderer()
8390
mustaches = self.project_dir.rglob('**/*.mustache')
8491
for mustache in mustaches:

health-metrics/benchmark/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ test-apps:
5656
- fire-installations
5757
- firebase-ml-modeldownloader
5858
- fire-perf
59+
- fire-perf-early
5960
- fire-rc
6061
- fire-rtdb
6162
- fire-transport
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
16+
package com.google.firebase
17+
18+
import com.google.firebase.FirebaseApp
19+
20+
internal fun initializeAllComponentsForBenchmark(app: FirebaseApp) {
21+
app.initializeAllComponents()
22+
}
23+

health-metrics/benchmark/template/app/src/main/java/com/google/firebase/benchmark/MainActivity.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@ package com.google.firebase.benchmark
1616

1717
import androidx.appcompat.app.AppCompatActivity
1818
import android.os.Bundle
19+
import com.google.firebase.FirebaseApp
20+
import com.google.firebase.initializeAllComponentsForBenchmark
1921

2022
class MainActivity : AppCompatActivity() {
2123
override fun onCreate(savedInstanceState: Bundle?) {
2224
super.onCreate(savedInstanceState)
2325
setContentView(R.layout.activity_main)
26+
27+
val app = FirebaseApp.getInstance()
28+
initializeAllComponentsForBenchmark(app)
2429
}
2530
}

0 commit comments

Comments
 (0)