|  | package store | 
|  |  | 
|  | import ( | 
|  | "context" | 
|  | "fmt" | 
|  | "testing" | 
|  | "time" | 
|  |  | 
|  | "github.com/stretchr/testify/assert" | 
|  | "github.com/stretchr/testify/require" | 
|  | "go.skia.org/infra/codesize/go/common" | 
|  | ) | 
|  |  | 
|  | func TestStore_Index_InvalidJSONMetadataFile_Error(t *testing.T) { | 
|  | store := newStoreForTesting() | 
|  | err := store.Index(context.Background(), "kaboom.tsv") | 
|  | require.Error(t, err) | 
|  | assert.Contains(t, err.Error(), "invalid character '{'") | 
|  | } | 
|  |  | 
|  | func TestStore_Index_CalledTwiceWithSameFile_FileIndexedOnce(t *testing.T) { | 
|  | store := newStoreForTesting() | 
|  |  | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Foo/dm.tsv")) | 
|  | assert.Len(t, store.GetMostRecentBinaries(10), 1) | 
|  | assert.Len(t, store.GetMostRecentBinaries(10)[0].Binaries, 1) | 
|  |  | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Foo/fm.tsv")) | 
|  | assert.Len(t, store.GetMostRecentBinaries(10), 1) | 
|  | assert.Len(t, store.GetMostRecentBinaries(10)[0].Binaries, 2) | 
|  |  | 
|  | // Same file as previous call. | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Foo/fm.tsv")) | 
|  | assert.Len(t, store.GetMostRecentBinaries(10), 1) | 
|  | assert.Len(t, store.GetMostRecentBinaries(10)[0].Binaries, 2) | 
|  |  | 
|  | require.NoError(t, store.Index(context.Background(), "commit2/Build-Foo/dm.tsv")) | 
|  | assert.Len(t, store.GetMostRecentBinaries(10), 2) | 
|  | assert.Len(t, store.GetMostRecentBinaries(10)[0].Binaries, 1) | 
|  | assert.Len(t, store.GetMostRecentBinaries(10)[1].Binaries, 2) | 
|  |  | 
|  | // Same file as previous call. | 
|  | require.NoError(t, store.Index(context.Background(), "commit2/Build-Foo/dm.tsv")) | 
|  | assert.Len(t, store.GetMostRecentBinaries(10), 2) | 
|  | assert.Len(t, store.GetMostRecentBinaries(10)[0].Binaries, 1) | 
|  | assert.Len(t, store.GetMostRecentBinaries(10)[1].Binaries, 2) | 
|  | } | 
|  |  | 
|  | func TestStore_IndexThenGetMostRecentBinaries_Success(t *testing.T) { | 
|  | store := newStoreForTesting() | 
|  |  | 
|  | // Store is initially empty. | 
|  | assert.Empty(t, store.GetMostRecentBinaries(10)) | 
|  |  | 
|  | // Index a bunch of binaries. | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Foo/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Foo/fm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Bar/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "commit2/Build-Foo/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "issue9876/patchset3/job1/Build-Foo/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "issue9876/patchset3/job2/Build-Bar/fm.tsv")) | 
|  |  | 
|  | // Retrieve all binaries from the store. | 
|  | assert.Equal(t, []BinariesFromCommitOrPatchset{ | 
|  | { | 
|  | CommitOrPatchset: CommitOrPatchset{ | 
|  | Commit: "commit2", | 
|  | }, | 
|  | Binaries: []Binary{ | 
|  | { | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T16:34:48Z", | 
|  | CompileTaskName: "Build-Foo", | 
|  | BinaryName:      "dm", | 
|  | Revision:        "commit2", | 
|  | }, | 
|  | BloatyOutputFileGCSPath: "commit2/Build-Foo/dm.tsv", | 
|  | Timestamp:               time.Date(2022, time.February, 16, 16, 34, 48, 0, time.UTC), | 
|  | }, | 
|  | }, | 
|  | }, | 
|  | { | 
|  | CommitOrPatchset: CommitOrPatchset{ | 
|  | Commit: "commit1", | 
|  | }, | 
|  | Binaries: []Binary{ | 
|  | { | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T15:23:19Z", | 
|  | CompileTaskName: "Build-Foo", | 
|  | BinaryName:      "dm", | 
|  | Revision:        "commit1", | 
|  | }, | 
|  | BloatyOutputFileGCSPath: "commit1/Build-Foo/dm.tsv", | 
|  | Timestamp:               time.Date(2022, time.February, 16, 15, 23, 19, 0, time.UTC), | 
|  | }, | 
|  | { | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T15:22:50Z", | 
|  | CompileTaskName: "Build-Foo", | 
|  | BinaryName:      "fm", | 
|  | Revision:        "commit1", | 
|  | }, | 
|  | BloatyOutputFileGCSPath: "commit1/Build-Foo/fm.tsv", | 
|  | Timestamp:               time.Date(2022, time.February, 16, 15, 22, 50, 0, time.UTC), | 
|  | }, | 
|  | { | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T15:21:53Z", | 
|  | CompileTaskName: "Build-Bar", | 
|  | BinaryName:      "dm", | 
|  | Revision:        "commit1", | 
|  | }, | 
|  | BloatyOutputFileGCSPath: "commit1/Build-Bar/dm.tsv", | 
|  | Timestamp:               time.Date(2022, time.February, 16, 15, 21, 53, 0, time.UTC), | 
|  | }, | 
|  | }, | 
|  | }, | 
|  | { | 
|  | CommitOrPatchset: CommitOrPatchset{ | 
|  | PatchIssue: "509137", | 
|  | PatchSet:   "11", | 
|  | }, | 
|  | Binaries: []Binary{ | 
|  | { | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T14:34:25Z", | 
|  | CompileTaskName: "Build-Foo", | 
|  | BinaryName:      "dm", | 
|  | BloatyDiffArgs:  []string{"build/dm", "--", "build_nopatch/dm"}, | 
|  | PatchIssue:      "509137", | 
|  | PatchSet:        "11", | 
|  | Revision:        "commit3", | 
|  | }, | 
|  | BloatyOutputFileGCSPath:         "issue9876/patchset3/job1/Build-Foo/dm.tsv", | 
|  | BloatySizeDiffOutputFileGCSPath: "issue9876/patchset3/job1/Build-Foo/dm.diff.txt", | 
|  | Timestamp:                       time.Date(2022, time.February, 16, 14, 34, 25, 0, time.UTC), | 
|  | }, | 
|  | { | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T14:26:52Z", | 
|  | CompileTaskName: "Build-Bar", | 
|  | BinaryName:      "fm", | 
|  | PatchIssue:      "509137", | 
|  | PatchSet:        "11", | 
|  | Revision:        "commit3", | 
|  | }, | 
|  | BloatyOutputFileGCSPath: "issue9876/patchset3/job2/Build-Bar/fm.tsv", | 
|  | Timestamp:               time.Date(2022, time.February, 16, 14, 26, 52, 0, time.UTC), | 
|  | }, | 
|  | }, | 
|  | }, | 
|  | }, | 
|  | store.GetMostRecentBinaries(10)) | 
|  |  | 
|  | // Retrieve only the two most recent results. | 
|  | assert.Equal(t, []BinariesFromCommitOrPatchset{ | 
|  | { | 
|  | CommitOrPatchset: CommitOrPatchset{ | 
|  | Commit: "commit2", | 
|  | }, | 
|  | Binaries: []Binary{ | 
|  | { | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T16:34:48Z", | 
|  | CompileTaskName: "Build-Foo", | 
|  | BinaryName:      "dm", | 
|  | Revision:        "commit2", | 
|  | }, | 
|  | BloatyOutputFileGCSPath: "commit2/Build-Foo/dm.tsv", | 
|  | Timestamp:               time.Date(2022, time.February, 16, 16, 34, 48, 0, time.UTC), | 
|  | }, | 
|  | }, | 
|  | }, | 
|  | { | 
|  | CommitOrPatchset: CommitOrPatchset{ | 
|  | Commit: "commit1", | 
|  | }, | 
|  | Binaries: []Binary{ | 
|  | { | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T15:23:19Z", | 
|  | CompileTaskName: "Build-Foo", | 
|  | BinaryName:      "dm", | 
|  | Revision:        "commit1", | 
|  | }, | 
|  | BloatyOutputFileGCSPath: "commit1/Build-Foo/dm.tsv", | 
|  | Timestamp:               time.Date(2022, time.February, 16, 15, 23, 19, 0, time.UTC), | 
|  | }, | 
|  | { | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T15:22:50Z", | 
|  | CompileTaskName: "Build-Foo", | 
|  | BinaryName:      "fm", | 
|  | Revision:        "commit1", | 
|  | }, | 
|  | BloatyOutputFileGCSPath: "commit1/Build-Foo/fm.tsv", | 
|  | Timestamp:               time.Date(2022, time.February, 16, 15, 22, 50, 0, time.UTC), | 
|  | }, | 
|  | { | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T15:21:53Z", | 
|  | CompileTaskName: "Build-Bar", | 
|  | BinaryName:      "dm", | 
|  | Revision:        "commit1", | 
|  | }, | 
|  | BloatyOutputFileGCSPath: "commit1/Build-Bar/dm.tsv", | 
|  | Timestamp:               time.Date(2022, time.February, 16, 15, 21, 53, 0, time.UTC), | 
|  | }, | 
|  | }, | 
|  | }, | 
|  | }, | 
|  | store.GetMostRecentBinaries(2)) | 
|  | } | 
|  |  | 
|  | func TestStore_GetBinary_NonExistentBinary_Error(t *testing.T) { | 
|  | store := newStoreForTesting() | 
|  |  | 
|  | assert.Empty(t, store.GetMostRecentBinaries(10)) | 
|  | _, ok := store.GetBinary(CommitOrPatchset{Commit: "no such commit"}, "dm", "Build-Foo") | 
|  | assert.False(t, ok) | 
|  | } | 
|  |  | 
|  | func TestStore_IndexThenGetBinary_Success(t *testing.T) { | 
|  | store := newStoreForTesting() | 
|  |  | 
|  | // Store is initially empty. | 
|  | assert.Empty(t, store.GetMostRecentBinaries(10)) | 
|  |  | 
|  | // Index a bunch of binaries. | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Foo/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Foo/fm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Bar/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "commit2/Build-Foo/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "issue9876/patchset3/job1/Build-Foo/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "issue9876/patchset3/job2/Build-Bar/fm.tsv")) | 
|  |  | 
|  | // Get a binary from a commit. | 
|  | binary, ok := store.GetBinary( | 
|  | CommitOrPatchset{Commit: "commit1"}, | 
|  | "dm", | 
|  | "Build-Foo") | 
|  | require.True(t, ok) | 
|  | assert.Equal(t, Binary{ | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T15:23:19Z", | 
|  | CompileTaskName: "Build-Foo", | 
|  | BinaryName:      "dm", | 
|  | Revision:        "commit1", | 
|  | }, | 
|  | BloatyOutputFileGCSPath: "commit1/Build-Foo/dm.tsv", | 
|  | Timestamp:               time.Date(2022, time.February, 16, 15, 23, 19, 0, time.UTC), | 
|  | }, | 
|  | binary) | 
|  |  | 
|  | // Get a binary from a tryjob. | 
|  | binary, ok = store.GetBinary( | 
|  | CommitOrPatchset{PatchIssue: "509137", PatchSet: "11"}, | 
|  | "fm", | 
|  | "Build-Bar") | 
|  | require.True(t, ok) | 
|  | assert.Equal(t, Binary{ | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T14:26:52Z", | 
|  | CompileTaskName: "Build-Bar", | 
|  | BinaryName:      "fm", | 
|  | PatchIssue:      "509137", | 
|  | PatchSet:        "11", | 
|  | Revision:        "commit3", | 
|  | }, | 
|  | BloatyOutputFileGCSPath: "issue9876/patchset3/job2/Build-Bar/fm.tsv", | 
|  | Timestamp:               time.Date(2022, time.February, 16, 14, 26, 52, 0, time.UTC), | 
|  | }, | 
|  | binary) | 
|  | } | 
|  |  | 
|  | func TestStore_GetBloatyOutputFileContents_NonExistentBinary_Error(t *testing.T) { | 
|  | store := newStoreForTesting() | 
|  |  | 
|  | _, err := store.GetBloatyOutputFileContents(context.Background(), Binary{ | 
|  | BloatyOutputFileGCSPath: "no-such-file.tsv", | 
|  | }) | 
|  | require.Error(t, err) | 
|  | assert.Contains(t, err.Error(), "not found: no-such-file.tsv") | 
|  | } | 
|  |  | 
|  | func TestStore_IndexThenGetBloatyOutputFileContents_Success(t *testing.T) { | 
|  | store := newStoreForTesting() | 
|  |  | 
|  | // Store is initially empty. | 
|  | assert.Empty(t, store.GetMostRecentBinaries(10)) | 
|  |  | 
|  | // Index a bunch of binaries. | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Foo/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Foo/fm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Bar/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "commit2/Build-Foo/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "issue9876/patchset3/job1/Build-Foo/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "issue9876/patchset3/job2/Build-Bar/fm.tsv")) | 
|  |  | 
|  | // Binary from a commit. | 
|  | bytes, err := store.GetBloatyOutputFileContents(context.Background(), Binary{ | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T15:23:19Z", | 
|  | CompileTaskName: "Build-Foo", | 
|  | BinaryName:      "dm", | 
|  | Revision:        "commit1", | 
|  | }, | 
|  | BloatyOutputFileGCSPath: "commit1/Build-Foo/dm.tsv", | 
|  | Timestamp:               time.Date(2022, time.February, 16, 15, 23, 19, 0, time.UTC), | 
|  | }) | 
|  | require.NoError(t, err) | 
|  | assert.Equal(t, "Fake Bloaty output 1", string(bytes)) | 
|  |  | 
|  | // Binary from a tryjob. | 
|  | bytes, err = store.GetBloatyOutputFileContents(context.Background(), Binary{ | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T14:26:52Z", | 
|  | CompileTaskName: "Build-Bar", | 
|  | BinaryName:      "fm", | 
|  | PatchIssue:      "509137", | 
|  | PatchSet:        "11", | 
|  | Revision:        "commit3", | 
|  | }, | 
|  | BloatyOutputFileGCSPath: "issue9876/patchset3/job2/Build-Bar/fm.tsv", | 
|  | Timestamp:               time.Date(2022, time.February, 16, 14, 26, 52, 0, time.UTC), | 
|  | }) | 
|  | require.NoError(t, err) | 
|  | assert.Equal(t, "Fake Bloaty output 6", string(bytes)) | 
|  | } | 
|  |  | 
|  | func TestStore_GetBloatySizeDiffOutputFileContents_NonExistentBinary_Error(t *testing.T) { | 
|  | store := newStoreForTesting() | 
|  |  | 
|  | _, err := store.GetBloatySizeDiffOutputFileContents(context.Background(), Binary{ | 
|  | BloatySizeDiffOutputFileGCSPath: "no-such-file.diff.txt", | 
|  | }) | 
|  | require.Error(t, err) | 
|  | assert.Contains(t, err.Error(), "not found: no-such-file.diff.txt") | 
|  | } | 
|  |  | 
|  | func TestStore_GetBloatySizeDiffOutputFileContents_Success(t *testing.T) { | 
|  | store := newStoreForTesting() | 
|  |  | 
|  | // Store is initially empty. | 
|  | assert.Empty(t, store.GetMostRecentBinaries(10)) | 
|  |  | 
|  | // Index a bunch of binaries. | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Foo/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Foo/fm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "commit1/Build-Bar/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "commit2/Build-Foo/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "issue9876/patchset3/job1/Build-Foo/dm.tsv")) | 
|  | require.NoError(t, store.Index(context.Background(), "issue9876/patchset3/job2/Build-Bar/fm.tsv")) | 
|  |  | 
|  | // Binary from a tryjob. | 
|  | bytes, err := store.GetBloatySizeDiffOutputFileContents(context.Background(), Binary{ | 
|  | Metadata: common.BloatyOutputMetadata{ | 
|  | Version:         1, | 
|  | Timestamp:       "2022-02-16T14:34:25Z", | 
|  | CompileTaskName: "Build-Foo", | 
|  | BinaryName:      "dm", | 
|  | BloatyDiffArgs:  []string{"build/dm", "--", "build_nopatch/dm"}, | 
|  | PatchIssue:      "509137", | 
|  | PatchSet:        "11", | 
|  | Revision:        "commit3", | 
|  | }, | 
|  | BloatyOutputFileGCSPath:         "issue9876/patchset3/job1/Build-Foo/dm.tsv", | 
|  | BloatySizeDiffOutputFileGCSPath: "issue9876/patchset3/job1/Build-Foo/dm.diff.txt", | 
|  | Timestamp:                       time.Date(2022, time.February, 16, 14, 34, 25, 0, time.UTC), | 
|  | }) | 
|  | require.NoError(t, err) | 
|  | assert.Equal(t, "Fake Bloaty diff", string(bytes)) | 
|  | } | 
|  |  | 
|  | // newStoreForTesting returns a Store that "downloads" files from the fake GCS bucket defined by | 
|  | // the fakeGCSBucket map below. | 
|  | func newStoreForTesting() Store { | 
|  | return New(func(ctx context.Context, path string) ([]byte, error) { | 
|  | contents, ok := fakeGCSBucket[path] | 
|  | if !ok { | 
|  | return nil, fmt.Errorf("not found: %s", path) | 
|  | } | 
|  | return []byte(contents), nil | 
|  | }) | 
|  | } | 
|  |  | 
|  | // The JSON metadata files only contain those fields relevant to indexing. The particular filenames | 
|  | // do not matter. | 
|  | var fakeGCSBucket = map[string]string{ | 
|  | // A binary from a commit (i.e. not a tryjob). | 
|  | "commit1/Build-Foo/dm.json": ` | 
|  | { | 
|  | "version": 1, | 
|  | "timestamp": "2022-02-16T15:23:19Z", | 
|  | "compile_task_name": "Build-Foo", | 
|  | "binary_name": "dm", | 
|  | "patch_issue": "", | 
|  | "patch_set": "", | 
|  | "revision": "commit1" | 
|  | } | 
|  | `, | 
|  | "commit1/Build-Foo/dm.tsv": "Fake Bloaty output 1", | 
|  |  | 
|  | // Same commit and compile task as previous file, different binary. | 
|  | "commit1/Build-Foo/fm.json": ` | 
|  | { | 
|  | "version": 1, | 
|  | "timestamp": "2022-02-16T15:22:50Z", | 
|  | "compile_task_name": "Build-Foo", | 
|  | "binary_name": "fm", | 
|  | "patch_issue": "", | 
|  | "patch_set": "", | 
|  | "revision": "commit1" | 
|  | } | 
|  | `, | 
|  | "commit1/Build-Foo/fm.tsv": "Fake Bloaty output 2", | 
|  |  | 
|  | // Same commit as previous file, different compile task. | 
|  | "commit1/Build-Bar/dm.json": ` | 
|  | { | 
|  | "version": 1, | 
|  | "timestamp": "2022-02-16T15:21:53Z", | 
|  | "compile_task_name": "Build-Bar", | 
|  | "binary_name": "dm", | 
|  | "patch_issue": "", | 
|  | "patch_set": "", | 
|  | "revision": "commit1" | 
|  | } | 
|  | `, | 
|  | "commit1/Build-Bar/dm.tsv": "Fake Bloaty output 3", | 
|  |  | 
|  | // New commit. | 
|  | "commit2/Build-Foo/dm.json": ` | 
|  | { | 
|  | "version": 1, | 
|  | "timestamp": "2022-02-16T16:34:48Z", | 
|  | "compile_task_name": "Build-Foo", | 
|  | "binary_name": "dm", | 
|  | "patch_issue": "", | 
|  | "patch_set": "", | 
|  | "revision": "commit2" | 
|  | } | 
|  | `, | 
|  | "commit2/Build-Foo/dm.tsv": "Fake Bloaty output 4", | 
|  |  | 
|  | // A binary from a tryjob. | 
|  | "issue9876/patchset3/job1/Build-Foo/dm.json": ` | 
|  | { | 
|  | "version": 1, | 
|  | "timestamp": "2022-02-16T14:34:25Z", | 
|  | "compile_task_name": "Build-Foo", | 
|  | "binary_name": "dm", | 
|  | "bloaty_diff_args": [ | 
|  | "build/dm", | 
|  | "--", | 
|  | "build_nopatch/dm" | 
|  | ], | 
|  | "patch_issue": "509137", | 
|  | "patch_set": "11", | 
|  | "revision": "commit3" | 
|  | } | 
|  | `, | 
|  | "issue9876/patchset3/job1/Build-Foo/dm.tsv":      "Fake Bloaty output 5", | 
|  | "issue9876/patchset3/job1/Build-Foo/dm.diff.txt": "Fake Bloaty diff", | 
|  |  | 
|  | // Same tryjob as previous file, different compile task and binary, missing size diff. | 
|  | "issue9876/patchset3/job2/Build-Bar/fm.json": ` | 
|  | { | 
|  | "version": 1, | 
|  | "timestamp": "2022-02-16T14:26:52Z", | 
|  | "compile_task_name": "Build-Bar", | 
|  | "binary_name": "fm", | 
|  | "patch_issue": "509137", | 
|  | "patch_set": "11", | 
|  | "revision": "commit3" | 
|  | } | 
|  | `, | 
|  | "issue9876/patchset3/job2/Build-Bar/fm.tsv": "Fake Bloaty output 6", | 
|  |  | 
|  | "kaboom.json": `{{{{{"malformed JSON file": "kaboom"}`, | 
|  | "kaboom.tsv":  "Invalid file.", | 
|  | } |