Example #1
0
func TestParseInputAndroid(t *testing.T) {
	// These inputs are valid
	goodInputs := []struct {
		input   string
		version string
	}{
		{"W/google-breakpad(0): 1.2.3.4\n", "1.2.3.4"},
		{"W/google-breakpad(0): 1234\n", "1234"},
		{"W/google-breakpad(0123): 0\n", "0"},
		{"W/google-breakpad(0): 0\n #00  pc 006fbe5a  libchromeview.so\n", "0"},
		{"W/google-breakpad(0): 0\n #00  pc 006fbe5a  libchromeview.so (func)\n", "0"},
		{"W/google-breakpad(0): 0\n #00  xx 006fbe5a  libchromeview.so\n", "0"},
		{"W/google-breakpad(0): 0\n #99  pc 006fbe5a  libchromeview.so\n", "0"},
	}

	var testmod testModuleInfoServiceAndroid

	for _, test := range goodInputs {
		parser := NewAndroidParser(context.Background(), &testmod, "")
		if err := parser.ParseInput(test.input); err != nil {
			t.Error("Did not expect error for input: " + test.input)
		}

		if test.version != testmod.version {
			t.Error("Expected version: " + test.version + " for input: " + test.input)
		}
	}

	// These inputs are not valid
	badInputs := []struct {
		input    string
		errorStr string
	}{
		{"W/google-breakpad(0): b7247ee2-5177-40fd-8959-33bc2f793db9\n", "Version number of Chrome"},
		{"W/google-breakpad(0): 1.2.3.4.\n", "Version number of Chrome"},
		{"W/google-breakpad(0): 1234\n #18446744073709551616  pc 006fbe5a  /system/lib/libchromeview.so\n", "frame number"},
	}

	for _, test := range badInputs {
		parser := NewAndroidParser(context.Background(), &testmod, "")
		if err := parser.ParseInput(test.input); err == nil {
			t.Error("Expected error for input: " + test.input)
		} else {
			if !strings.Contains(err.Error(), test.errorStr) {
				t.Error("Expected \"" + test.errorStr + "\" as the error")
			}
		}
	}
}
Example #2
0
// TestSymbolizeAndroid tests the symbolize function of androidParser.  This function
// is almost identical to the TestSymbolize function in input_apple_test.go.
func TestSymbolizeAndroid(t *testing.T) {
	files := []string{
		"android1.txt",
		"android2.txt",
	}

	for _, file := range files {
		var testmod testModuleInfoServiceAndroid

		inputData, err := testutils.ReadSourceFile(testdata(file))
		if err != nil {
			t.Errorf("Failed to read file : " + file)
			continue
		}

		tables := []breakpad.SymbolTable{
			&testTable{name: "libchromeview.so", symbol: "Framework"},
		}

		parser := NewAndroidParser(context.Background(), &testmod, "")
		err = parser.ParseInput(string(inputData))
		if err != nil {
			t.Errorf("%s: %s", file, err)
			continue
		}

		// Write the output to a .actual file, which can be used to create a new baseline
		// .expected file by copying it into the testdata/ directory.

		actual := parser.Symbolize(tables)
		actualFileName, actualFile, err := testutils.CreateTempFile(file + ".actual")
		if err != nil {
			t.Errorf("Could not create actual file output: %v", err)
			continue
		}
		fmt.Fprint(actualFile, actual)
		actualFile.Close()

		expectedFileName := testutils.GetSourceFilePath(testdata(file + ".expected"))
		err = testutils.CheckFilesEqual(expectedFileName, actualFileName)
		if err != nil {
			t.Errorf("Input data for %s does not symbolize to expected output", file)
			t.Error(err)
		}
	}
}
Example #3
0
func TestGetTableCache(t *testing.T) {
	*cacheSize = 5

	// Create a new Handler. The mux is a throw-away.
	handler := RegisterHandlers(http.NewServeMux())
	supplier := new(cacheTestSupplier)
	supplier.reset()
	handler.Init(supplier)

	const kInitialName = "initial fill #%d"

	// Supply five tables to max out the cache.
	go func() {
		for i := 1; i <= *cacheSize; i++ {
			supplier.c <- breakpad.SupplierResponse{
				Table: newTestTable(fmt.Sprintf(kInitialName, i)),
			}
		}
		supplier.c <- breakpad.SupplierResponse{
			Error: errors.New("cache miss when should be cache hit"),
		}
		close(supplier.c)
	}()

	// Now receieve those five from the cache, twice.
	for iter := 0; iter < 2; iter++ {
		for i := 1; i <= *cacheSize; i++ {
			ident := fmt.Sprintf(kInitialName, i)

			table, err := handler.getTable(context.Background(), breakpad.SupplierRequest{"module", ident})
			if err != nil {
				t.Errorf("Error getting '%s': %v", ident, err)
				continue
			}

			if table.Identifier() != ident {
				t.Errorf("Identifier mismatch, expected '%s', got '%s'", ident, table.Identifier())
			}
		}
	}

	// Receive pending messages until the channel gets closed.
	for _ = range supplier.c {
	}
	supplier.reset()

	// After iterating through the cache twice, initial #5 is MRU, so #1 will
	// be the first to be evicted.
	const kEvictFirst = "evict initial fill #1"
	go func() {
		supplier.c <- breakpad.SupplierResponse{
			Table: newTestTable(kEvictFirst),
		}
		supplier.c <- breakpad.SupplierResponse{
			Error: errors.New("unexpected supplier request"),
		}
		close(supplier.c)
	}()

	// Get a different table, which will evict #1.
	table, err := handler.getTable(context.Background(), breakpad.SupplierRequest{"module", kEvictFirst})
	if err != nil {
		t.Errorf("error getting '%s': %v", kEvictFirst, err)
	} else {
		if table.Identifier() != kEvictFirst {
			t.Errorf("Identifier mismatch, expected '%s', got '%s'", kEvictFirst, table.Identifier())
		}
	}

	// Now get a table that should be in the cache.
	ident := fmt.Sprintf(kInitialName, 3)
	table, err = handler.getTable(context.Background(), breakpad.SupplierRequest{"module", ident})
	if err != nil {
		t.Errorf("error getting '%s' after evicting #1: %v", ident, err)
	} else {
		if table.Identifier() != ident {
			t.Errorf("Identifier mismatch, expected '%s', got '%s'", ident, table.Identifier())
		}
	}

	cacheOrder := []string{
		fmt.Sprintf(kInitialName, 2),
		fmt.Sprintf(kInitialName, 4),
		fmt.Sprintf(kInitialName, 5),
		kEvictFirst,
		fmt.Sprintf(kInitialName, 3),
	}
	i := 0
	for e := handler.mru.Front(); e != nil; e = e.Next() {
		ident = cacheOrder[i]
		if e.Value.(breakpad.SymbolTable).Identifier() != ident {
			t.Errorf("cache index %d mismatch, expected '%s', got '%v'", i, ident, e.Value)
		}
		if _, ok := handler.symbolCache[ident]; !ok {
			t.Errorf("cache entry '%s' not present in symbol cache", ident)
		}
		i++
	}
	if len(handler.symbolCache) != *cacheSize {
		t.Errorf("symbol cache size mismatch, expected %d, got %d", *cacheSize, len(handler.symbolCache))
	}
}