Ejemplo n.º 1
0
// 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)
	}
}
Ejemplo n.º 2
0
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)
						}
					}
				}
			}
		}
	}
}