// TestStreamEncodeDecode generates random streams of EncDatums and passes them // through a StreamEncoder and a StreamDecoder func TestStreamEncodeDecode(t *testing.T) { rng, _ := randutil.NewPseudoRand() for test := 0; test < 100; test++ { rowLen := 1 + rng.Intn(20) info := make([]DatumInfo, rowLen) for i := range info { info[i].Type = sqlbase.RandColumnType(rng) info[i].Encoding = sqlbase.RandDatumEncoding(rng) } numRows := rng.Intn(100) rows := make(sqlbase.EncDatumRows, numRows) for i := range rows { rows[i] = make(sqlbase.EncDatumRow, rowLen) for j := range rows[i] { rows[i][j].SetDatum(info[j].Type, sqlbase.RandDatum(rng, info[j].Type, true)) } } var trailerErr error if rng.Intn(10) == 0 { trailerErr = fmt.Errorf("test error %d", rng.Intn(100)) } testRowStream(t, rng, rows, trailerErr) } }
func TestHashRouter(t *testing.T) { const numCols = 6 const numRows = 200 rng, _ := randutil.NewPseudoRand() alloc := &sqlbase.DatumAlloc{} // Generate tables of possible values for each column; we have fewer possible // values than rows to guarantee many occurrences of each value. vals := make([][]sqlbase.EncDatum, numCols) for i := 0; i < numCols; i++ { typ := sqlbase.RandColumnType(rng) vals[i] = make([]sqlbase.EncDatum, numRows/10) for j := range vals[i] { vals[i][j].SetDatum(typ, sqlbase.RandDatum(rng, typ, true)) } } testCases := []struct { hashColumns []uint32 numBuckets int }{ {[]uint32{0}, 2}, {[]uint32{3}, 4}, {[]uint32{1, 3}, 4}, {[]uint32{5, 2}, 3}, {[]uint32{0, 1, 2, 3, 4}, 5}, } for _, tc := range testCases { bufs := make([]*RowBuffer, tc.numBuckets) recvs := make([]RowReceiver, tc.numBuckets) for i := 0; i < tc.numBuckets; i++ { bufs[i] = &RowBuffer{} recvs[i] = bufs[i] } hr, err := makeHashRouter(tc.hashColumns, recvs) if err != nil { t.Fatal(err) } for i := 0; i < numRows; i++ { row := make(sqlbase.EncDatumRow, numCols) for j := 0; j < numCols; j++ { row[j] = vals[j][rng.Intn(len(vals[j]))] } ok := hr.PushRow(row) if !ok { t.Fatalf("PushRow returned false") } } hr.Close(nil) for bIdx, b := range bufs { if !b.closed { t.Errorf("bucket not closed") } if b.err != nil { t.Error(b.err) } for _, row := range b.rows { // Verify there are no rows that // - have the same values with this row on all the hashColumns, and // - ended up in a different bucket for b2Idx, b2 := range bufs { if b2Idx == bIdx { continue } for _, row2 := range b2.rows { equal := true for _, c := range tc.hashColumns { cmp, err := row[c].Compare(alloc, &row2[c]) if err != nil { t.Fatal(err) } if cmp != 0 { equal = false break } } if equal { t.Errorf("rows %s and %s in different buckets", row, row2) } } } } } } }