Reland "[Chrome Stdlib] Use DEPS to download diff test data"
This is a reland of commit 6c8f992499
This reland adds the deps entry for chrome_5672_histograms.pftrace.gz
which was missing in the original CL, causing b/342182426 which caused
the original CL to be reverted.
Original change's description:
> [Chrome Stdlib] Use DEPS to download diff test data
>
> We want to download Perfetto test data via GCS dependencies in DEPS
> rather than Perfetto's test_data script. To make this change we:
>
> 1. Modify the test_data.py script to wrap
> `upload_to_google_storage_first_class.py` instead of Perfetto's
> `test_data` script.
> 2. Add a Presubmit check to ensure the .sha256 files are in sync with
> the deps entries.
> 3. Update docs to give instructions for the new workflow
>
> Change-Id: I20616c95553f93603e338dd9fa47e84facfb60d8
> Bug: 312895063
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5545295
> Reviewed-by: Stephen Nusko <nuskos@chromium.org>
> Commit-Queue: Rasika Navarange <rasikan@google.com>
> Reviewed-by: Dominic Battre <battre@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1304407}
Bug: 312895063
Change-Id: I6bcd74324612e5c49ae59bee3f0b20f673d70b81
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5562906
Reviewed-by: Dominic Battre <battre@chromium.org>
Reviewed-by: Stephen Nusko <nuskos@chromium.org>
Commit-Queue: Rasika Navarange <rasikan@google.com>
Cr-Commit-Position: refs/heads/main@{#1305095}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
e877e150ee
commit
c2d33d2eab
87
DEPS
87
DEPS
@@ -1958,6 +1958,83 @@ deps = {
|
|||||||
'src/third_party/perfetto':
|
'src/third_party/perfetto':
|
||||||
Var('android_git') + '/platform/external/perfetto.git' + '@' + '03fe17e0be05dd6c60cf6351a696c1864468b982',
|
Var('android_git') + '/platform/external/perfetto.git' + '@' + '03fe17e0be05dd6c60cf6351a696c1864468b982',
|
||||||
|
|
||||||
|
'src/base/tracing/test/data': {
|
||||||
|
'bucket': 'perfetto',
|
||||||
|
'objects': [
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/chrome_fcp_lcp_navigations.pftrace-ae01d849fbd75a98be1b7ddd5a8873217c377b393a1d5bbd788ed3364f7fefc3',
|
||||||
|
'sha256sum': 'ae01d849fbd75a98be1b7ddd5a8873217c377b393a1d5bbd788ed3364f7fefc3',
|
||||||
|
'size_bytes': 2398645,
|
||||||
|
'generation': 1697714434866488,
|
||||||
|
'output_file': 'chrome_fcp_lcp_navigations.pftrace'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/chrome_input_with_frame_view.pftrace-a93548822e481508c728ccc5da3ad34afcd0aec02ca7a7a4dad84ff340ee5975',
|
||||||
|
'sha256sum': 'a93548822e481508c728ccc5da3ad34afcd0aec02ca7a7a4dad84ff340ee5975',
|
||||||
|
'size_bytes': 6392331,
|
||||||
|
'generation': 1711402389089075,
|
||||||
|
'output_file': 'chrome_input_with_frame_view.pftrace'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/scroll_offsets_trace_2.pftrace-2ddd9f78d91d51e39c72c520bb54fdc9dbf1333ae722e87633fc345159296289',
|
||||||
|
'sha256sum': '2ddd9f78d91d51e39c72c520bb54fdc9dbf1333ae722e87633fc345159296289',
|
||||||
|
'size_bytes': 1496388,
|
||||||
|
'generation': 1712592637141461,
|
||||||
|
'output_file': 'scroll_offsets_trace_2.pftrace'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/top_level_java_choreographer_slices-8001e73b2458e94f65a606bb558a645ba5bca553b57fe416001f6c2175675a8a',
|
||||||
|
'sha256sum': '8001e73b2458e94f65a606bb558a645ba5bca553b57fe416001f6c2175675a8a',
|
||||||
|
'size_bytes': 5323017,
|
||||||
|
'generation': 1671708979893186,
|
||||||
|
'output_file': 'top_level_java_choreographer_slices'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/chrome_page_load_all_categories_not_extended.pftrace.gz-6586e9e2bbc0c996caddb321a0374328654983733e6ffd7f4635ac07db32a493',
|
||||||
|
'sha256sum': '6586e9e2bbc0c996caddb321a0374328654983733e6ffd7f4635ac07db32a493',
|
||||||
|
'size_bytes': 1277750,
|
||||||
|
'generation': 1652442088902445,
|
||||||
|
'output_file': 'chrome_page_load_all_categories_not_extended.pftrace.gz'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/speedometer.perfetto_trace.gz-8a159b354d74a3ca0d38ce9cd071ef47de322db4261ee266bfafe04d70310529',
|
||||||
|
'sha256sum': '8a159b354d74a3ca0d38ce9cd071ef47de322db4261ee266bfafe04d70310529',
|
||||||
|
'size_bytes': 891088,
|
||||||
|
'generation': 1684336047660953,
|
||||||
|
'output_file': 'speedometer.perfetto_trace.gz'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/cpu_powerups_1.pb-70f5511ba0cd6ce1359e3cadb4d1d9301fb6e26be85158e3384b06f41418d386',
|
||||||
|
'sha256sum': '70f5511ba0cd6ce1359e3cadb4d1d9301fb6e26be85158e3384b06f41418d386',
|
||||||
|
'size_bytes': 2033064,
|
||||||
|
'generation': 1669652389509708,
|
||||||
|
'output_file': 'cpu_powerups_1.pb'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/chrome_5672_histograms.pftrace.gz-a09bd44078ac71bcfbc901b0544750e8344d0d0f6f96e220f700a5a53fa932ee',
|
||||||
|
'sha256sum': 'a09bd44078ac71bcfbc901b0544750e8344d0d0f6f96e220f700a5a53fa932ee',
|
||||||
|
'size_bytes': 1127472,
|
||||||
|
'generation': 1684946598804577,
|
||||||
|
'output_file': 'chrome_5672_histograms.pftrace.gz'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/chrome_custom_navigation_trace.gz-ff68279e3cec94076b69259d756eed181a63eaf834d8b956a7f4ba665fabf939',
|
||||||
|
'sha256sum': 'ff68279e3cec94076b69259d756eed181a63eaf834d8b956a7f4ba665fabf939',
|
||||||
|
'size_bytes': 7572484,
|
||||||
|
'generation': 1666713705258900,
|
||||||
|
'output_file': 'chrome_custom_navigation_trace.gz'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/scroll_offsets.pftrace-62101edb5204fec8bea30124f65d4e49bda0808d7b036e95f89445aaad6d8d98',
|
||||||
|
'sha256sum': '62101edb5204fec8bea30124f65d4e49bda0808d7b036e95f89445aaad6d8d98',
|
||||||
|
'size_bytes': 769741,
|
||||||
|
'generation': 1693402148909129,
|
||||||
|
'output_file': 'scroll_offsets.pftrace'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'dep_type': 'gcs'
|
||||||
|
},
|
||||||
|
|
||||||
'src/third_party/perl': {
|
'src/third_party/perl': {
|
||||||
'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '8ef97ff3b7332e38e61b347a2fbed425a4617151',
|
'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '8ef97ff3b7332e38e61b347a2fbed425a4617151',
|
||||||
'condition': 'checkout_win',
|
'condition': 'checkout_win',
|
||||||
@@ -5199,16 +5276,6 @@ hooks = [
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
# Download test data for Perfetto diff tests
|
|
||||||
{
|
|
||||||
'name': 'perfetto_testdata',
|
|
||||||
'condition': 'host_os == "linux"',
|
|
||||||
'pattern': '\\.sha256',
|
|
||||||
'action': [ 'vpython3',
|
|
||||||
'src/base/tracing/test/test_data.py',
|
|
||||||
'download',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
# Pull down WPR Archive files
|
# Pull down WPR Archive files
|
||||||
{
|
{
|
||||||
'name': 'Fetch WPR archive files',
|
'name': 'Fetch WPR archive files',
|
||||||
|
55
PRESUBMIT.py
55
PRESUBMIT.py
@@ -3372,6 +3372,61 @@ def CheckForNewDEPSDownloadFromGoogleStorageHooks(input_api, output_api):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def CheckEachPerfettoTestDataFileHasDepsEntry(input_api, output_api):
|
||||||
|
test_data_filter = lambda f: input_api.FilterSourceFile(
|
||||||
|
f, files_to_check=[r'^base/tracing/test/data/.*\.sha256'])
|
||||||
|
if not any(input_api.AffectedFiles(file_filter=test_data_filter)):
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Find DEPS entry
|
||||||
|
deps_entry = []
|
||||||
|
for f in input_api.AffectedFiles(include_deletes=False):
|
||||||
|
if f.LocalPath() == 'DEPS':
|
||||||
|
new_deps = _ParseDeps('\n'.join(f.NewContents()))['deps']
|
||||||
|
deps_entry = new_deps['src/base/tracing/test/data']
|
||||||
|
if not deps_entry:
|
||||||
|
return [output_api.PresubmitError(
|
||||||
|
'You must update the DEPS file when you update a '
|
||||||
|
'.sha256 file in base/tracing/test/data'
|
||||||
|
)]
|
||||||
|
|
||||||
|
output = []
|
||||||
|
for f in input_api.AffectedFiles(file_filter=test_data_filter):
|
||||||
|
objects = deps_entry['objects']
|
||||||
|
if not f.NewContents():
|
||||||
|
# Deleted file so check that DEPS entry removed
|
||||||
|
sha256_from_file = f.OldContents()[0]
|
||||||
|
object_entry = next(
|
||||||
|
(item for item in objects if item["sha256sum"] == sha256_from_file),
|
||||||
|
None)
|
||||||
|
if object_entry:
|
||||||
|
output.append(output_api.PresubmitError(
|
||||||
|
'You deleted %s so you must also remove the corresponding DEPS entry.'
|
||||||
|
% f.LocalPath()
|
||||||
|
))
|
||||||
|
continue
|
||||||
|
|
||||||
|
sha256_from_file = f.NewContents()[0]
|
||||||
|
object_entry = next(
|
||||||
|
(item for item in objects if item["sha256sum"] == sha256_from_file),
|
||||||
|
None)
|
||||||
|
if not object_entry:
|
||||||
|
output.append(output_api.PresubmitError(
|
||||||
|
'No corresponding DEPS entry found for %s. '
|
||||||
|
'Run `base/tracing/test/test_data.py get_deps --filepath %s` '
|
||||||
|
'to generate the DEPS entry.'
|
||||||
|
% (f.LocalPath(), f.LocalPath())
|
||||||
|
))
|
||||||
|
|
||||||
|
if output:
|
||||||
|
output.append(output_api.PresubmitError(
|
||||||
|
'The DEPS entry for `src/base/tracing/test/data` in the DEPS file has not been '
|
||||||
|
'updated properly. Run `base/tracing/test/test_data.py get_all_deps` to see what '
|
||||||
|
'the DEPS entry should look like.'
|
||||||
|
))
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
def CheckAddedDepsHaveTargetApprovals(input_api, output_api):
|
def CheckAddedDepsHaveTargetApprovals(input_api, output_api):
|
||||||
"""When a dependency prefixed with + is added to a DEPS file, we
|
"""When a dependency prefixed with + is added to a DEPS file, we
|
||||||
want to make sure that the change is reviewed by an OWNER of the
|
want to make sure that the change is reviewed by an OWNER of the
|
||||||
|
@@ -225,6 +225,132 @@ class CheckNoUNIT_TESTInSourceFilesTest(unittest.TestCase):
|
|||||||
MockInputApi(), MockFile('some/path/source.cc', lines))
|
MockInputApi(), MockFile('some/path/source.cc', lines))
|
||||||
self.assertEqual(0, len(errors))
|
self.assertEqual(0, len(errors))
|
||||||
|
|
||||||
|
|
||||||
|
class CheckEachPerfettoTestDataFileHasDepsEntry(unittest.TestCase):
|
||||||
|
|
||||||
|
def testNewSha256FileNoDEPS(self):
|
||||||
|
input_api = MockInputApi()
|
||||||
|
input_api.files = [
|
||||||
|
MockFile('base/tracing/test/data/new.pftrace.sha256', []),
|
||||||
|
]
|
||||||
|
results = PRESUBMIT.CheckEachPerfettoTestDataFileHasDepsEntry(input_api, MockOutputApi())
|
||||||
|
self.assertEqual(
|
||||||
|
('You must update the DEPS file when you update a .sha256 file '
|
||||||
|
'in base/tracing/test/data'), results[0].message)
|
||||||
|
|
||||||
|
def testNewSha256FileSuccess(self):
|
||||||
|
input_api = MockInputApi()
|
||||||
|
new_deps = """deps = {
|
||||||
|
'src/base/tracing/test/data': {
|
||||||
|
'bucket': 'perfetto',
|
||||||
|
'objects': [
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/new.pftrace-a1b2c3f4',
|
||||||
|
'sha256sum': 'a1b2c3f4',
|
||||||
|
'size_bytes': 1,
|
||||||
|
'generation': 1,
|
||||||
|
'output_file': 'new.pftrace'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'dep_type': 'gcs'
|
||||||
|
},
|
||||||
|
}""".splitlines()
|
||||||
|
input_api.files = [
|
||||||
|
MockFile('base/tracing/test/data/new.pftrace.sha256', ['a1b2c3f4']),
|
||||||
|
MockFile('DEPS', new_deps),
|
||||||
|
]
|
||||||
|
results = PRESUBMIT.CheckEachPerfettoTestDataFileHasDepsEntry(input_api, MockOutputApi())
|
||||||
|
self.assertEqual(0, len(results))
|
||||||
|
|
||||||
|
def testNewSha256FileWrongSha256(self):
|
||||||
|
input_api = MockInputApi()
|
||||||
|
new_deps = """deps = {
|
||||||
|
'src/base/tracing/test/data': {
|
||||||
|
'bucket': 'perfetto',
|
||||||
|
'objects': [
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/new.pftrace-a1b2c3f4',
|
||||||
|
'sha256sum': 'wrong_hash',
|
||||||
|
'size_bytes': 1,
|
||||||
|
'generation': 1,
|
||||||
|
'output_file': 'new.pftrace'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'dep_type': 'gcs'
|
||||||
|
},
|
||||||
|
}""".splitlines()
|
||||||
|
f = MockFile('base/tracing/test/data/new.pftrace.sha256', ['a1b2c3f4'])
|
||||||
|
input_api.files = [
|
||||||
|
f,
|
||||||
|
MockFile('DEPS', new_deps),
|
||||||
|
]
|
||||||
|
results = PRESUBMIT.CheckEachPerfettoTestDataFileHasDepsEntry(input_api, MockOutputApi())
|
||||||
|
self.assertEqual((
|
||||||
|
'No corresponding DEPS entry found for %s. '
|
||||||
|
'Run `base/tracing/test/test_data.py get_deps --filepath %s` '
|
||||||
|
'to generate the DEPS entry.' % (f.LocalPath(), f.LocalPath())),
|
||||||
|
results[0].message)
|
||||||
|
|
||||||
|
def testDeleteSha256File(self):
|
||||||
|
input_api = MockInputApi()
|
||||||
|
old_deps = """deps = {
|
||||||
|
'src/base/tracing/test/data': {
|
||||||
|
'bucket': 'perfetto',
|
||||||
|
'objects': [
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/new.pftrace-a1b2c3f4',
|
||||||
|
'sha256sum': 'a1b2c3f4',
|
||||||
|
'size_bytes': 1,
|
||||||
|
'generation': 1,
|
||||||
|
'output_file': 'new.pftrace'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'dep_type': 'gcs'
|
||||||
|
},
|
||||||
|
}""".splitlines()
|
||||||
|
f = MockFile('base/tracing/test/data/new.pftrace.sha256', [], ['a1b2c3f4'], action='D')
|
||||||
|
input_api.files = [
|
||||||
|
f,
|
||||||
|
MockFile('DEPS', old_deps),
|
||||||
|
]
|
||||||
|
results = PRESUBMIT.CheckEachPerfettoTestDataFileHasDepsEntry(input_api, MockOutputApi())
|
||||||
|
self.assertEqual((
|
||||||
|
'You deleted %s so you must also remove the corresponding DEPS entry.'
|
||||||
|
% f.LocalPath()), results[0].message)
|
||||||
|
|
||||||
|
def testDeleteSha256Success(self):
|
||||||
|
input_api = MockInputApi()
|
||||||
|
new_deps = """deps = {
|
||||||
|
'src/base/tracing/test/data': {
|
||||||
|
'bucket': 'perfetto',
|
||||||
|
'objects': [],
|
||||||
|
'dep_type': 'gcs'
|
||||||
|
},
|
||||||
|
}""".splitlines()
|
||||||
|
old_deps = """deps = {
|
||||||
|
'src/base/tracing/test/data': {
|
||||||
|
'bucket': 'perfetto',
|
||||||
|
'objects': [
|
||||||
|
{
|
||||||
|
'object_name': 'test_data/new.pftrace-a1b2c3f4',
|
||||||
|
'sha256sum': 'a1b2c3f4',
|
||||||
|
'size_bytes': 1,
|
||||||
|
'generation': 1,
|
||||||
|
'output_file': 'new.pftrace'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'dep_type': 'gcs'
|
||||||
|
},
|
||||||
|
}""".splitlines()
|
||||||
|
f = MockFile('base/tracing/test/data/new.pftrace.sha256', [], ['a1b2c3f4'], action='D')
|
||||||
|
input_api.files = [
|
||||||
|
f,
|
||||||
|
MockFile('DEPS', new_deps, old_deps),
|
||||||
|
]
|
||||||
|
results = PRESUBMIT.CheckEachPerfettoTestDataFileHasDepsEntry(input_api, MockOutputApi())
|
||||||
|
self.assertEqual(0, len(results))
|
||||||
|
|
||||||
|
|
||||||
class CheckAddedDepsHaveTestApprovalsTest(unittest.TestCase):
|
class CheckAddedDepsHaveTestApprovalsTest(unittest.TestCase):
|
||||||
|
|
||||||
def calculate(self, old_include_rules, old_specific_include_rules,
|
def calculate(self, old_include_rules, old_specific_include_rules,
|
||||||
|
@@ -10,6 +10,7 @@ Currently, the diff tests only run on Linux. You can build and run the diff test
|
|||||||
|
|
||||||
```
|
```
|
||||||
$ gn gen --args='' out/Linux
|
$ gn gen --args='' out/Linux
|
||||||
|
$ gclient sync
|
||||||
$ autoninja -C out/Linux perfetto_diff_tests
|
$ autoninja -C out/Linux perfetto_diff_tests
|
||||||
$ out/Linux/bin/run_perfetto_diff_tests
|
$ out/Linux/bin/run_perfetto_diff_tests
|
||||||
```
|
```
|
||||||
@@ -22,13 +23,34 @@ Your new diff test should go in `base/tracing/test/trace_processor/diff_tests/ch
|
|||||||
|
|
||||||
If you are adding a **new TestSuite**, be sure to add it to `include_index.py` so the runner knows to run this new TestSuite.
|
If you are adding a **new TestSuite**, be sure to add it to `include_index.py` so the runner knows to run this new TestSuite.
|
||||||
|
|
||||||
If your test requires modifying or adding new test data i.e. a new trace in `base/tracing/test/data`, you will need to upload this to the GCS bucket. These trace files are too large to be checked-in to the codebase so we check-in only `.sha256` files. You can upload any new traces with this script:
|
### Adding New Test Data
|
||||||
|
|
||||||
|
If your test requires modifying or adding new test data i.e. a new trace in `base/tracing/test/data`, you will need to upload this to the GCS bucket.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ base/tracing/test/test_data.py upload --verbose
|
$ base/tracing/test/test_data.py upload <path_to_file>
|
||||||
```
|
```
|
||||||
|
|
||||||
This script will upload your file and generate the `.sha256` file in the `base/tracing/test/data/` directory. You can then upload this file with your CL.
|
This script will output a deps entry which you will need to add to the [DEPS file](../../../DEPS) (see examples in the `src/base/tracing/test/data` entry).
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"path": {
|
||||||
|
"dep_type": "gcs",
|
||||||
|
"bucket": "perfetto",
|
||||||
|
"objects": [
|
||||||
|
{
|
||||||
|
"object_name": "test_data/file_name-a1b2c3f4",
|
||||||
|
"sha256sum": "a1b2c3f4",
|
||||||
|
"size_bytes": 12345,
|
||||||
|
"generation": 1234567
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
You will need to **manually** add this to the deps entry. After adding this entry, running `gclient sync` will download the test files in your local repo. See these [docs](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/gcs_dependencies.md) for the GCS dependency workflow.
|
||||||
|
|
||||||
|
Perfetto has it's own way to download GCS objects with the [test_data](../../../third_party/perfetto/tools/test_data) script. This script uses .sha256 files to download. The `test_data.py upload` command will also generate the `file_name-a1b2c3f4.sha256` in `base/tracing/test/data`. You will need to check-in these files in the codebase so they can by rolled to Perfetto, so the tests can work there too.
|
||||||
|
|
||||||
## Writing TestTraceProcessor Tests
|
## Writing TestTraceProcessor Tests
|
||||||
|
|
||||||
|
@@ -4,45 +4,161 @@
|
|||||||
# found in the LICENSE file.
|
# found in the LICENSE file.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
A wrapper script for //third_party/perfetto/tools/test_data. The wrapper
|
A wrapper script for upload_to_google_storage_first_class.py.
|
||||||
ensures that we upload the correct directory.
|
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
./test_data.py status # Prints the status of new & modified files.
|
|
||||||
./test_data.py download # To sync remote>local (used by gclient runhooks).
|
|
||||||
./test_data.py upload # To upload newly created and modified files.
|
|
||||||
|
|
||||||
WARNING: the `download` command will overwrite any locally modified files.
|
# Uploads file and generates .sha256 file
|
||||||
If you want to keep locally modified test data, you should upload it before
|
$ ./test_data.py upload data/trace.pftrace
|
||||||
running `gclient runhooks` otherwise you will lose this data.
|
|
||||||
|
# Generates deps entry for a single file
|
||||||
|
$ ./test_data.py get_deps data/trace.pftrace
|
||||||
|
|
||||||
|
# Generate full deps entry for all files in base/tracing/test/data/
|
||||||
|
$ ./test_data.py get_all_deps
|
||||||
|
|
||||||
|
The upload command uploads the given file to the gs://perfetto bucket and
|
||||||
|
generates a .sha256 file in the base/tracing/test/data/ directory,
|
||||||
|
which is rolled to the Perfetto repository.
|
||||||
|
The .sha256 file is used by Perfetto to download the files with their
|
||||||
|
own test_data download script (third_party/perfetto/tools/test_data).
|
||||||
|
|
||||||
|
The script outputs a GCS entry which should be manually added to the
|
||||||
|
deps dict in /DEPS. See
|
||||||
|
https://chromium.googlesource.com/chromium/src/+/HEAD/docs/gcs_dependencies.md.
|
||||||
|
|
||||||
|
The files are uploaded as gs://perfetto/test_data/file_name-a1b2c3f4.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
|
||||||
def main():
|
SRC_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
|
||||||
parser = argparse.ArgumentParser()
|
TEST_DATA_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), 'data'))
|
||||||
parser.add_argument('cmd', choices=['status', 'download', 'upload'])
|
DEPOT_TOOLS_PATH = os.path.abspath(os.path.join(SRC_PATH, 'third_party', 'depot_tools'))
|
||||||
parser.add_argument('--verbose', '-v', action='store_true')
|
sys.path.append(DEPOT_TOOLS_PATH)
|
||||||
args = parser.parse_args()
|
from upload_to_google_storage_first_class import get_sha256sum
|
||||||
|
from download_from_google_storage import Gsutil, GSUTIL_DEFAULT_PATH
|
||||||
|
|
||||||
src_root = os.path.abspath(os.path.join(__file__, '..', '..', '..', '..'))
|
|
||||||
perfetto_dir = os.path.join(src_root, 'third_party', 'perfetto')
|
|
||||||
tool = os.path.join(perfetto_dir, "tools", "test_data")
|
|
||||||
test_dir = os.path.join(src_root, 'base', 'tracing', 'test', 'data')
|
|
||||||
|
|
||||||
command = ['vpython3', tool, '--dir', test_dir, '--overwrite', args.cmd]
|
# Write .sha256 file to be rolled into Perfetto.
|
||||||
if args.verbose:
|
def write_sha256_file(filepath: str):
|
||||||
command.append('--verbose')
|
sha256sum = get_sha256sum(filepath)
|
||||||
|
with open(filepath + '.sha256', 'w') as sha_file:
|
||||||
|
sha_file.write(sha256sum)
|
||||||
|
return sha256sum
|
||||||
|
|
||||||
|
|
||||||
|
# Run `upload_to_google_storage_first_class.py --bucket perfetto <file>`.
|
||||||
|
def upload_file(filepath: str, dry_run: bool, force: bool):
|
||||||
|
sha256sum = write_sha256_file(filepath)
|
||||||
|
|
||||||
|
# Perfetto uses 'test_data/file_name-a1b2c3f4' object name format.
|
||||||
|
object_name = '%s/%s-%s' % ('test_data', os.path.basename(filepath), sha256sum)
|
||||||
|
|
||||||
|
tool = 'upload_to_google_storage_first_class.py'
|
||||||
|
command = [tool, '--bucket', 'perfetto', '--object-name', object_name, filepath]
|
||||||
|
if dry_run:
|
||||||
|
command.append('--dry-run')
|
||||||
|
if force:
|
||||||
|
command.append('--force')
|
||||||
|
|
||||||
completed_process = subprocess.run(
|
completed_process = subprocess.run(
|
||||||
command,
|
command,
|
||||||
check=False,
|
check=False,
|
||||||
capture_output=True)
|
capture_output=True)
|
||||||
sys.stderr.buffer.write(completed_process.stderr)
|
|
||||||
sys.stdout.buffer.write(completed_process.stdout)
|
if completed_process.returncode == 0:
|
||||||
|
print('Manually add the deps entry below to the DEPS file. See '
|
||||||
|
'https://chromium.googlesource.com/chromium/src/+/HEAD/docs/gcs_dependencies.md '
|
||||||
|
'for more details. Run `test_data.py get_all_deps` to get the full deps entry.')
|
||||||
|
sys.stdout.buffer.write(completed_process.stdout)
|
||||||
|
else:
|
||||||
|
sys.stderr.buffer.write(completed_process.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
# Generate the deps entry for `filepath`, assuming it has been uploaded already.
|
||||||
|
def generate_deps_entry(filepath: str):
|
||||||
|
sha256sum = get_sha256sum(filepath)
|
||||||
|
object_name = '%s/%s-%s' % ('test_data', os.path.basename(filepath), sha256sum)
|
||||||
|
|
||||||
|
# Run `gcloud storage ls -L gs://perfetto/test_data/file_name-a1b2c3f4` to
|
||||||
|
# get the 'generation' and 'size_bytes' fields for the deps entry
|
||||||
|
gsutil = Gsutil(GSUTIL_DEFAULT_PATH)
|
||||||
|
gsutil_args = ['ls', '-L', 'gs://perfetto/%s' % object_name]
|
||||||
|
code, out, err = gsutil.check_call(*gsutil_args)
|
||||||
|
if code != 0:
|
||||||
|
raise Exception(code, err + ' ' + object_name)
|
||||||
|
generation = int(out.split()[out.split().index('Generation:') + 1])
|
||||||
|
size = int(out.split()[out.split().index('Content-Length:') + 1])
|
||||||
|
|
||||||
|
return {
|
||||||
|
'object_name': object_name,
|
||||||
|
'sha256sum': sha256sum,
|
||||||
|
'size_bytes': size,
|
||||||
|
'generation': generation,
|
||||||
|
'output_file': os.path.basename(filepath),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Generate the full deps entry for Perfetto test data
|
||||||
|
def generate_all_deps():
|
||||||
|
path = os.path.join(SRC_PATH, 'base/tracing/test/data')
|
||||||
|
objects = []
|
||||||
|
for file in os.listdir(path):
|
||||||
|
if file.endswith('.sha256'):
|
||||||
|
filepath = os.path.join(path, file)[:-7]
|
||||||
|
assert os.path.isfile(filepath), 'File does not exist'
|
||||||
|
object_entry = generate_deps_entry(filepath)
|
||||||
|
objects.append(object_entry)
|
||||||
|
return {
|
||||||
|
'src/base/tracing/test/data': {
|
||||||
|
'bucket':
|
||||||
|
'perfetto',
|
||||||
|
'objects': objects,
|
||||||
|
'dep_type':
|
||||||
|
'gcs',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
subparsers = parser.add_subparsers(dest='cmd')
|
||||||
|
|
||||||
|
upload_parser = subparsers.add_parser('upload', help='Upload a file to gs://perfetto')
|
||||||
|
upload_parser.add_argument('filepath', help='Path to file you want to upload')
|
||||||
|
upload_parser.add_argument('--dry-run', action='store_true',
|
||||||
|
help='Check if file already exists on GCS without '
|
||||||
|
'uploading it and output DEP blob.')
|
||||||
|
upload_parser.add_argument('-f',
|
||||||
|
'--force',
|
||||||
|
action='store_true',
|
||||||
|
help='Force upload even if remote file exists.')
|
||||||
|
|
||||||
|
get_deps_parser = subparsers.add_parser('get_deps', help='Print deps entry for a single file')
|
||||||
|
get_deps_parser.add_argument('filepath', help='Path to test data file you want the deps entry for.')
|
||||||
|
|
||||||
|
subparsers.add_parser('get_all_deps', help='Print deps entry for all files in `base/tracing/test/data/`')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.cmd == 'get_all_deps':
|
||||||
|
print(json.dumps(generate_all_deps(), indent=2).replace('"', "'"))
|
||||||
|
return
|
||||||
|
|
||||||
|
filepath = os.path.abspath(args.filepath)
|
||||||
|
assert os.path.dirname(filepath) == TEST_DATA_PATH, ('You can only '
|
||||||
|
'upload files in base/tracing/test/data/')
|
||||||
|
|
||||||
|
if args.cmd == 'upload':
|
||||||
|
upload_file(filepath, args.dry_run, args.force)
|
||||||
|
elif args.cmd == 'get_deps':
|
||||||
|
print(json.dumps(generate_deps_entry(filepath), indent=2).replace('"', "'"))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(main())
|
sys.exit(main())
|
Reference in New Issue
Block a user