[dump_breakpad_symbols] Drop symbolize pkg usage.

These APIs are deprecated in favor of using elflib.ReadIdsFile
to read IDs files.

TC-168

Change-Id: I85d5bb7df077b39229df32cd0fa94442790efaed
diff --git a/cmd/dump_breakpad_symbols/main.go b/cmd/dump_breakpad_symbols/main.go
index d54a0da..8026f72 100755
--- a/cmd/dump_breakpad_symbols/main.go
+++ b/cmd/dump_breakpad_symbols/main.go
@@ -5,6 +5,7 @@
 package main
 
 import (
+	"fuchsia.googlesource.com/tools/elflib"
 	// TODO(kjharland): Use a safer hash algorithm. sha256 or sha2, etc.
 	"crypto/sha1"
 	"encoding/hex"
@@ -18,8 +19,6 @@
 	"path"
 	"path/filepath"
 	"strings"
-
-	"fuchsia.googlesource.com/tools/symbolize"
 )
 
 const usage = `usage: dump_breakpad_symbols [options] file1 file2 ... fileN
@@ -101,12 +100,6 @@
 	}
 	defer summaryFile.Close()
 
-	// Create a symbolize.Source from each IDs file.
-	var IDsFiles []symbolize.BinaryFileSource
-	for _, path := range flag.Args() {
-		IDsFiles = append(IDsFiles, symbolize.NewIDsSource(path))
-	}
-
 	// Callback to run breakpad `dump_syms` command.
 	execDumpSyms := func(args []string) ([]byte, error) {
 		return exec.Command(dumpSymsPath, args...).Output()
@@ -117,8 +110,22 @@
 		return os.Create(path)
 	}
 
+	// Open the input files for reading.  In practice there are very few files,
+	// so it's fine to open them all at once.
+	var inputReaders []io.Reader
+	inputPaths := flag.Args()
+	for _, path := range inputPaths {
+		file, err := os.Open(path)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "ERROR: Failed to open %s: %v\n", path, err)
+			os.Exit(1)
+		}
+		defer file.Close()
+		inputReaders = append(inputReaders, file)
+	}
+
 	// Process the IDsFiles.
-	summary := processIdsFiles(IDsFiles, outdir, execDumpSyms, createFile)
+	summary := processIdsFiles(inputReaders, outdir, execDumpSyms, createFile)
 
 	// Write the summary.
 	if err := writeSummary(summaryFile, summary); err != nil {
@@ -126,14 +133,14 @@
 		os.Exit(1)
 	}
 	// Write the dep file.
-	if err := writeDepFile(depFile, summaryFilename, IDsFiles); err != nil {
+	if err := writeDepFile(depFile, summaryFilename, inputPaths); err != nil {
 		fmt.Fprintf(os.Stderr, "failed to write depfile %s: %v", depFilename, err)
 		os.Exit(1)
 	}
 }
 
 // processIdsFiles dumps symbol data for each executable in a set of ids files.
-func processIdsFiles(idsFiles []symbolize.BinaryFileSource, outdir string, execDumpSyms ExecDumpSyms, createFile CreateFile) map[string]string {
+func processIdsFiles(idsFiles []io.Reader, outdir string, execDumpSyms ExecDumpSyms, createFile CreateFile) map[string]string {
 	// Binary paths we've already seen.  Duplicates are skipped.
 	visited := make(map[string]bool)
 	binaryToSymbolFile := make(map[string]string)
@@ -141,12 +148,13 @@
 	// Iterate through the given set of filepaths.
 	for _, idsFile := range idsFiles {
 		// Extract the paths to each binary from the IDs file.
-		binaries, err := idsFile.GetBinaries()
+		binaries, err := elflib.ReadIDsFile(idsFile)
 		if err != nil {
-			log.Printf("ERROR: failed to extract paths from %s: %v", idsFile, err)
+			fmt.Fprintln(os.Stderr, err)
 			continue
 		}
 
+		// Generate the symbol file for each binary.
 		for _, bin := range binaries {
 			binaryPath := bin.Filepath
 
@@ -213,19 +221,10 @@
 //
 // summaryPath is the summary file generated by this command.
 // IDsFiles are the input sources to this command.
-func writeDepFile(w io.Writer, summaryFilename string, IDsFiles []symbolize.BinaryFileSource) error {
-	// Write the dep file.
-	var idsFileNames []string
-	for _, f := range IDsFiles {
-		idsFileNames = append(idsFileNames, f.Name())
-	}
-
-	contents := []byte(fmt.Sprintf("%s: %s\n", summaryFilename, strings.Join(idsFileNames, " ")))
-	if _, err := w.Write(contents); err != nil {
-		return err
-	}
-
-	return nil
+func writeDepFile(w io.Writer, summaryFilename string, IDsFiles []string) error {
+	contents := []byte(fmt.Sprintf("%s: %s\n", summaryFilename, strings.Join(IDsFiles, " ")))
+	_, err := w.Write(contents)
+	return err
 }
 
 // Writes the given symbol file data to the given writer after massaging the data.
diff --git a/cmd/dump_breakpad_symbols/main_test.go b/cmd/dump_breakpad_symbols/main_test.go
index 3ab9003..15d7cf3 100644
--- a/cmd/dump_breakpad_symbols/main_test.go
+++ b/cmd/dump_breakpad_symbols/main_test.go
@@ -9,58 +9,69 @@
 	"fmt"
 	"io"
 	"io/ioutil"
+	"strings"
 	"testing"
-
-	"fuchsia.googlesource.com/tools/elflib"
-	"fuchsia.googlesource.com/tools/symbolize"
 )
 
-// TestReadWriteCloser helps mimic io.ReadWriteCloser for file-like objects during tests.
-type TestReadWriteCloser struct {
+// FakeFile is a file-like io.ReadWriteCloser for testing.
+type FakeFile struct {
+	path string
 	*bytes.Buffer
 }
 
+// The filepath of this FakeFile.
+func (f *FakeFile) Name() string {
+	return f.path
+}
+
 // Close implements io.WriteCloser
-func (wc *TestReadWriteCloser) Close() error {
+func (f *FakeFile) Close() error {
 	// Noop
 	return nil
 }
 
-func NewTestReadWriteCloser() io.ReadWriteCloser {
-	return &TestReadWriteCloser{
-		new(bytes.Buffer),
+func NewFakeFile(path string, contents string) *FakeFile {
+	return &FakeFile{
+		Buffer: bytes.NewBuffer([]byte(contents)),
+		path:   path,
 	}
 }
 
 func TestRunCommand(t *testing.T) {
 	// Expects dump_breakpad_symbols to produce the specified summary and
 	// ninja depfile from the given input sources.
-	expectOutputs := func(inputSources []symbolize.BinaryFileSource, expectedSummary string, expectedDepFile string) {
-		// The dep file to write.
-		depFile := NewTestReadWriteCloser()
-
-		// The summary file to write.
-		summaryFile := NewTestReadWriteCloser()
+	expectOutputs := func(t *testing.T, inputs []*FakeFile, expectedSummary string, expectedDepFile string) {
+		depFile := NewFakeFile("deps.d", "")
+		summaryFile := NewFakeFile("summary.json", "")
 
 		// Callback to mock executing the breakpad dump_syms binary.
 		execDumpSyms := func(args []string) ([]byte, error) {
 			return []byte("FAKE_SYMBOL_DATA_LINE_1\nFAKE_SYMBOL_DATA_LINE_2"), nil
 		}
 
-		// Mock file I/O.
+		// Callback to perform file I/O.
 		createFile := func(path string) (io.ReadWriteCloser, error) {
-			return NewTestReadWriteCloser(), nil
+			return NewFakeFile(path, ""), nil
 		}
 
-		// Do what main() does...
-
-		// Process the IDsFiles.
-		summary := processIdsFiles(inputSources, "/out/", execDumpSyms, createFile)
-		summaryFilename := "summary.json"
+		// Convert input files from `[]FakeFile` to `[]io.Reader`
+		fileReaders := make([]io.Reader, len(inputs))
+		for i := range inputs {
+			fileReaders[i] = inputs[i]
+		}
+		// Process the input files.
+		summary := processIdsFiles(fileReaders, "/out/", execDumpSyms, createFile)
 		if err := writeSummary(summaryFile, summary); err != nil {
-			t.Fatalf("failed to write summary %s: %v", summaryFilename, err)
+			t.Fatalf("failed to write summary %s: %v", summaryFile.Name(), err)
 		}
-		if err := writeDepFile(depFile, summaryFilename, inputSources); err != nil {
+
+		// Extract input filepaths.
+		inputPaths := make([]string, len(inputs))
+		for i := range inputs {
+			inputPaths[i] = inputs[i].Name()
+		}
+		// Write the dep file
+		if err := writeDepFile(depFile, summaryFile.Name(), inputPaths); err != nil {
 			t.Fatalf("failed to write depfile %s: %v", depFilename, err)
 		}
 
@@ -84,50 +95,49 @@
 	}
 
 	t.Run("should produce an emtpy summary if no data is provided", func(t *testing.T) {
-		inputSources := []symbolize.BinaryFileSource{
-			symbolize.NewMockSource("idsA.txt", []elflib.BinaryFileRef{}),
-			symbolize.NewMockSource("idsB.txt", []elflib.BinaryFileRef{}),
+		inputSources := []*FakeFile{
+			NewFakeFile("idsA.txt", ""),
+			NewFakeFile("idsB.txt", ""),
 		}
 		expectedSummary := "{}"
 		expectedDepFile := fmt.Sprintf("summary.json: %s %s\n", "idsA.txt", "idsB.txt")
-
-		expectOutputs(inputSources, expectedSummary, expectedDepFile)
+		expectOutputs(t, inputSources, expectedSummary, expectedDepFile)
 	})
 
 	t.Run("should handle a single input file", func(t *testing.T) {
 		// Create a testing input file with fake hash values and binary paths.
-		inputSources := []symbolize.BinaryFileSource{
-			symbolize.NewMockSource("ids.txt", []elflib.BinaryFileRef{
-				{BuildID: "01634b09", Filepath: "/path/to/binaryA.elf"},
-				{BuildID: "02298167", Filepath: "/path/to/binaryB"},
-				{BuildID: "025abbbc", Filepath: "/path/to/binaryC.so"},
-			}),
+		inputSources := []*FakeFile{
+			NewFakeFile("ids.txt", strings.TrimSpace(`
+				01634b09 /path/to/binaryA.elf
+				02298167 /path/to/binaryB
+				025abbbc /path/to/binaryC.so
+			`)),
 		}
 		expectedSummary, err := json.MarshalIndent(map[string]string{
 			"/path/to/binaryA.elf": "/out/fe9881defb9ed1ddb9a89c38be973515f6ad7f0f.sym",
 			"/path/to/binaryB":     "/out/f03de72df78157dd14ae1cc031ddba9873947179.sym",
 			"/path/to/binaryC.so":  "/out/edbe4e45241c98dcde3538160073a0d6b097b780.sym",
 		}, "", "  ")
+
 		if err != nil {
 			t.Fatal(err)
 		}
 		expectedDepFile := "summary.json: ids.txt\n"
-
-		expectOutputs(inputSources, string(expectedSummary), expectedDepFile)
+		expectOutputs(t, inputSources, string(expectedSummary), expectedDepFile)
 	})
 
 	t.Run("should handle multiple input files", func(t *testing.T) {
-		inputSources := []symbolize.BinaryFileSource{
-			symbolize.NewMockSource("idsA.txt", []elflib.BinaryFileRef{
-				{BuildID: "01634b09", Filepath: "/path/to/binaryA.elf"},
-				{BuildID: "02298167", Filepath: "/path/to/binaryB"},
-				{BuildID: "025abbbc", Filepath: "/path/to/binaryC.so"},
-			}),
-			symbolize.NewMockSource("idsB.txt", []elflib.BinaryFileRef{
-				{BuildID: "01634b09", Filepath: "/path/to/binaryD"},
-				{BuildID: "02298167", Filepath: "/path/to/binaryE"},
-				{BuildID: "025abbbc", Filepath: "/path/to/binaryF"},
-			}),
+		inputSources := []*FakeFile{
+			NewFakeFile("idsA.txt", strings.TrimSpace(`
+				01634b09 /path/to/binaryA.elf
+				02298167 /path/to/binaryB
+				025abbbc /path/to/binaryC.so
+			`)),
+			NewFakeFile("idsB.txt", strings.TrimSpace(`
+				01634b09 /path/to/binaryD
+				02298167 /path/to/binaryE
+				025abbbc /path/to/binaryF
+			`)),
 		}
 		expectedSummary, err := json.MarshalIndent(map[string]string{
 			"/path/to/binaryA.elf": "/out/fe9881defb9ed1ddb9a89c38be973515f6ad7f0f.sym",
@@ -142,26 +152,26 @@
 		}
 		expectedDepFile := "summary.json: idsA.txt idsB.txt\n"
 
-		expectOutputs(inputSources, string(expectedSummary), expectedDepFile)
+		expectOutputs(t, inputSources, string(expectedSummary), expectedDepFile)
 	})
 
 	t.Run("should skip duplicate binary paths", func(t *testing.T) {
-		inputSources := []symbolize.BinaryFileSource{
-			symbolize.NewMockSource("idsA.txt", []elflib.BinaryFileRef{
-				{BuildID: "01634b09", Filepath: "/path/to/binaryA"},
-				{BuildID: "02298167", Filepath: "/path/to/binaryB"},
-				{BuildID: "asdf87fs", Filepath: "/path/to/binaryC"},
-			}),
-			symbolize.NewMockSource("idsB.txt", []elflib.BinaryFileRef{
-				{BuildID: "01634b09", Filepath: "/path/to/binaryA"},
-				{BuildID: "02298167", Filepath: "/path/to/binaryB"},
-				{BuildID: "asdf87fs", Filepath: "/path/to/binaryC"},
-			}),
-			symbolize.NewMockSource("idsC.txt", []elflib.BinaryFileRef{
-				{BuildID: "01634b09", Filepath: "/path/to/binaryA"},
-				{BuildID: "02298167", Filepath: "/path/to/binaryB"},
-				{BuildID: "asdf87fs", Filepath: "/path/to/binaryC"},
-			}),
+		inputSources := []*FakeFile{
+			NewFakeFile("idsA.txt", strings.TrimSpace(`
+				01634b09 /path/to/binaryA
+				02298167 /path/to/binaryB
+				asdf87fs /path/to/binaryC
+			`)),
+			NewFakeFile("idsB.txt", strings.TrimSpace(`
+				01634b09 /path/to/binaryA
+				02298167 /path/to/binaryB
+				asdf87fs /path/to/binaryC
+			`)),
+			NewFakeFile("idsC.txt", strings.TrimSpace(`
+				01634b09 /path/to/binaryA
+				02298167 /path/to/binaryB
+				asdf87fs /path/to/binaryC
+			`)),
 		}
 		expectedSummary, err := json.MarshalIndent(map[string]string{
 			"/path/to/binaryA": "/out/43e5a3c9eb9829f2eb11007223de1fb0b721a909.sym",
@@ -173,7 +183,7 @@
 		}
 		expectedDepFile := "summary.json: idsA.txt idsB.txt idsC.txt\n"
 
-		expectOutputs(inputSources, string(expectedSummary), expectedDepFile)
+		expectOutputs(t, inputSources, string(expectedSummary), expectedDepFile)
 	})
 }