blob: c34542ec011154dae81a48aa3f4472265ba9b7e8 [file] [log] [blame]
// Copyright 2021 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package symbolize
import (
"bytes"
"context"
"strings"
"testing"
"go.chromium.org/tast/core/cmd/tast/internal/symbolize/fakecmd"
"go.chromium.org/tast/core/internal/logging"
"go.chromium.org/tast/core/internal/logging/loggingtest"
)
func TestSymbolize(t *testing.T) {
cleanUp, err := fakecmd.Install("fakecmd/scripts/gsutil")
if err != nil {
t.Fatal(err)
}
defer cleanUp()
const crashpadMDMP = "breakpad/testdata/chrome.20210406.155226.62533.9042.dmp"
tests := []struct {
desc string
minidumpPath string
buildRoot string
builderPath string
verifyError func(*testing.T, error)
verifyLog func(*testing.T, string)
}{
{
// Dumps generated by breakpad do not require extra parameters.
desc: "lsb-release",
minidumpPath: "breakpad/testdata/abort.20180103.145440.12345.20827.dmp",
},
{
// Show an error, when processing Crashpad dump without additional parameters.
desc: "no_lsb-release",
minidumpPath: crashpadMDMP,
verifyError: func(t *testing.T, err error) {
msg := "minidump does not contain release info, please supply --builderpath or --buildroot"
if err == nil || !strings.Contains(err.Error(), msg) {
t.Errorf("wanted error containing %q, but got %q", msg, err)
}
},
},
{
// When buildroot is supplied, symbols are generated.
//
// The directory supplied in the test does not exist,
// but it doesn't matter - we verify the we tried to generate symbols.
desc: "no_lsb-release_buildroot",
minidumpPath: crashpadMDMP,
buildRoot: "/build/root/",
verifyLog: func(t *testing.T, log string) {
if !strings.Contains(log, "Generating 4 symbol file(s) from /build/root/") {
t.Errorf("expected that symbols would be generated, but it did not happen; log: %q", log)
}
},
},
{
// When builder path is supplied, we try to download symbols.
desc: "no_lsb-release_builderpath",
minidumpPath: crashpadMDMP,
builderPath: "name-release/R12-34.0.0",
verifyLog: func(t *testing.T, log string) {
if !strings.Contains(log, "Extracting 4 symbol file(s) from gs://chromeos-image-archive/name-release/R12-34.0.0/debug_breakpad.tar.xz") {
t.Errorf("expected that symbols would be download, but it did not happen; log: %q", log)
}
},
},
{
// Crashpad dumps with chromeos-* annotations do not require extra arguments.
desc: "crashpad-annotations",
minidumpPath: "breakpad/testdata/chrome.20210706.000145.15087.8090.dmp",
verifyLog: func(t *testing.T, log string) {
if !strings.Contains(log, "Extracting 5 symbol file(s) from gs://chromeos-image-archive/betty-release/R93-14070.0.0/debug_breakpad.tar.xz") {
t.Errorf("expected that symbols would be download, but it did not happen; log: %q", log)
}
},
},
{
// We download additional symbols for Lacros minidumps.
desc: "lacros",
minidumpPath: "breakpad/testdata/chrome.20210929.052823.26188.4743.dmp",
// No-op. In tests, downloading Lacros debug symbols crashes,
// which is fine, and having non-nil verifyError lets us ignore it.
verifyError: func(t *testing.T, err error) {},
verifyLog: func(t *testing.T, log string) {
if !strings.Contains(log, "Extracting Lacros symbols from gs://chrome-unsigned/desktop-5c0tCh/95.0.4637.0/lacros64/lacros_debug.zip") {
t.Errorf("expected that Lacros symbols would be download, but it did not happen; log: %q", log)
}
},
},
}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
logger := loggingtest.NewLogger(t, logging.LevelDebug)
ctx := logging.AttachLogger(context.Background(), logger)
cfg := Config{
// We are using /dev/null to avoid strange effect,
// when one tests writes symbols and another reads them.
SymbolDir: "/dev/null",
BuildRoot: tt.buildRoot,
BuilderPath: tt.builderPath,
}
err := SymbolizeCrash(ctx, tt.minidumpPath, &bytes.Buffer{}, cfg)
if tt.verifyError != nil {
tt.verifyError(t, err)
} else if err != nil {
t.Errorf("got error: %q", err)
}
if tt.verifyLog != nil {
tt.verifyLog(t, logger.String())
}
})
}
}