func TestTallyBasic(t *testing.T) {
	// Create a tile to test against.
	tile := tiling.NewTile()
	trace1 := types.NewGoldenTrace()
	trace1.Values[0] = "aaa"
	trace1.Values[1] = "aaa"
	trace1.Values[2] = "bbb"
	trace1.Params_[types.PRIMARY_KEY_FIELD] = "foo"
	trace1.Params_["corpus"] = "gm"
	tile.Traces["foo:x86"] = trace1

	trace2 := types.NewGoldenTrace()
	trace2.Values[0] = "ccc"
	trace2.Values[1] = "aaa"
	trace2.Params_[types.PRIMARY_KEY_FIELD] = "foo"
	trace2.Params_["corpus"] = "image"
	tile.Traces["foo:x86_64"] = trace2

	// Test tallyTile with our Tile.
	trace, test := tallyTile(tile)
	if got, want := len(trace), 2; got != want {
		t.Errorf("Wrong trace count: Got %v Want %v", got, want)
	}
	if got, want := (trace["foo:x86"])["aaa"], 2; got != want {
		t.Errorf("Miscount: Got %v Want %v", got, want)
	}

	if got, want := len(test), 1; got != want {
		t.Errorf("Wrong trace count: Got %v Want %v", got, want)
	}
	if got, want := (test["foo"])["aaa"], 3; got != want {
		t.Errorf("Miscount: Got %v Want %v", got, want)
	}
	if got, want := (test["foo"])["bbb"], 1; got != want {
		t.Errorf("Miscount: Got %v Want %v", got, want)
	}
	if got, want := (test["foo"])["ccc"], 1; got != want {
		t.Errorf("Miscount: Got %v Want %v", got, want)
	}

	// Test tallyBy with our Tile.
	ta := tallyBy(tile, trace, url.Values{"corpus": []string{"gm"}})
	if got, want := len(ta), 2; got != want {
		t.Errorf("Wrong trace count: Got %v Want %v", got, want)
	}
	if got, want := ta["aaa"], 2; got != want {
		t.Errorf("Miscount: Got %v Want %v", got, want)
	}
	if got, want := ta["bbb"], 1; got != want {
		t.Errorf("Miscount: Got %v Want %v", got, want)
	}
}
// addResultToTile adds the Digests from the DMResults to the tile at the given offset.
func addResultToTile(res *DMResults, tile *tiling.Tile, offset int, counter metrics.Counter) {
	res.ForEach(func(traceID, digest string, params map[string]string) {
		if ext, ok := params["ext"]; !ok || ext != "png" {
			return // Skip non-PNG results they are be converted to PNG by a separate process.
		}

		var trace *types.GoldenTrace
		var ok bool
		needsUpdate := false
		if tr, ok := tile.Traces[traceID]; !ok {
			trace = types.NewGoldenTrace()
			tile.Traces[traceID] = trace
			needsUpdate = true
		} else {
			trace = tr.(*types.GoldenTrace)
			if !util.MapsEqual(params, tile.Traces[traceID].Params()) {
				needsUpdate = true
			}
		}
		trace.Params_ = params

		if needsUpdate {
			// Update the Tile's ParamSet with any new keys or values we see.
			for k, v := range params {
				if _, ok = tile.ParamSet[k]; !ok {
					tile.ParamSet[k] = []string{v}
				} else if !util.In(v, tile.ParamSet[k]) {
					tile.ParamSet[k] = append(tile.ParamSet[k], v)
				}
			}
		}
		trace.Values[offset] = digest
		counter.Inc(1)
	})
}