github.com/apache/arrow/go/v16@v16.1.0/arrow/ipc/reader_test.go (about)

     1  // Licensed to the Apache Software Foundation (ASF) under one
     2  // or more contributor license agreements.  See the NOTICE file
     3  // distributed with this work for additional information
     4  // regarding copyright ownership.  The ASF licenses this file
     5  // to you under the Apache License, Version 2.0 (the
     6  // "License"); you may not use this file except in compliance
     7  // with the License.  You may obtain a copy of the License at
     8  //
     9  // http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  package ipc
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"io"
    23  	"testing"
    24  
    25  	"github.com/apache/arrow/go/v16/arrow"
    26  	"github.com/apache/arrow/go/v16/arrow/array"
    27  	"github.com/apache/arrow/go/v16/arrow/memory"
    28  	"github.com/stretchr/testify/assert"
    29  	"github.com/stretchr/testify/require"
    30  )
    31  
    32  func TestReaderCatchPanic(t *testing.T) {
    33  	alloc := memory.NewGoAllocator()
    34  	schema := arrow.NewSchema([]arrow.Field{
    35  		{Name: "s", Type: arrow.BinaryTypes.String},
    36  	}, nil)
    37  
    38  	b := array.NewRecordBuilder(alloc, schema)
    39  	defer b.Release()
    40  
    41  	b.Field(0).(*array.StringBuilder).AppendValues([]string{"foo", "bar", "baz"}, nil)
    42  	rec := b.NewRecord()
    43  	defer rec.Release()
    44  
    45  	buf := new(bytes.Buffer)
    46  	writer := NewWriter(buf, WithSchema(schema))
    47  	require.NoError(t, writer.Write(rec))
    48  
    49  	for i := buf.Len() - 100; i < buf.Len(); i++ {
    50  		buf.Bytes()[i] = 0
    51  	}
    52  
    53  	reader, err := NewReader(buf)
    54  	require.NoError(t, err)
    55  
    56  	_, err = reader.Read()
    57  	if assert.Error(t, err) {
    58  		assert.Contains(t, err.Error(), "arrow/ipc: unknown error while reading")
    59  	}
    60  }
    61  
    62  func TestReaderCheckedAllocator(t *testing.T) {
    63  	alloc := memory.NewCheckedAllocator(memory.NewGoAllocator())
    64  	defer alloc.AssertSize(t, 0)
    65  	schema := arrow.NewSchema([]arrow.Field{
    66  		{
    67  			Name: "s",
    68  			Type: &arrow.DictionaryType{
    69  				ValueType: arrow.BinaryTypes.String,
    70  				IndexType: arrow.PrimitiveTypes.Int32,
    71  			},
    72  		},
    73  	}, nil)
    74  
    75  	b := array.NewRecordBuilder(alloc, schema)
    76  	defer b.Release()
    77  
    78  	bldr := b.Field(0).(*array.BinaryDictionaryBuilder)
    79  	bldr.Append([]byte("foo"))
    80  	bldr.Append([]byte("bar"))
    81  	bldr.Append([]byte("baz"))
    82  
    83  	rec := b.NewRecord()
    84  	defer rec.Release()
    85  
    86  	buf := new(bytes.Buffer)
    87  	writer := NewWriter(buf, WithSchema(schema), WithAllocator(alloc))
    88  	defer writer.Close()
    89  	require.NoError(t, writer.Write(rec))
    90  
    91  	reader, err := NewReader(buf, WithAllocator(alloc))
    92  	require.NoError(t, err)
    93  	defer reader.Release()
    94  
    95  	_, err = reader.Read()
    96  	require.NoError(t, err)
    97  }
    98  
    99  func BenchmarkIPC(b *testing.B) {
   100  	alloc := memory.NewCheckedAllocator(memory.NewGoAllocator())
   101  	defer alloc.AssertSize(b, 0)
   102  
   103  	schema := arrow.NewSchema([]arrow.Field{
   104  		{
   105  			Name: "s",
   106  			Type: &arrow.DictionaryType{
   107  				ValueType: arrow.BinaryTypes.String,
   108  				IndexType: arrow.PrimitiveTypes.Int32,
   109  			},
   110  		},
   111  	}, nil)
   112  
   113  	rb := array.NewRecordBuilder(alloc, schema)
   114  	defer rb.Release()
   115  
   116  	bldr := rb.Field(0).(*array.BinaryDictionaryBuilder)
   117  	bldr.Append([]byte("foo"))
   118  	bldr.Append([]byte("bar"))
   119  	bldr.Append([]byte("baz"))
   120  
   121  	rec := rb.NewRecord()
   122  	defer rec.Release()
   123  
   124  	for _, codec := range []struct {
   125  		name        string
   126  		codecOption Option
   127  	}{
   128  		{
   129  			name: "plain",
   130  		},
   131  		{
   132  			name:        "zstd",
   133  			codecOption: WithZstd(),
   134  		},
   135  		{
   136  			name:        "lz4",
   137  			codecOption: WithLZ4(),
   138  		},
   139  	} {
   140  		options := []Option{WithSchema(schema), WithAllocator(alloc)}
   141  		if codec.codecOption != nil {
   142  			options = append(options, codec.codecOption)
   143  		}
   144  		b.Run(fmt.Sprintf("Writer/codec=%s", codec.name), func(b *testing.B) {
   145  			buf := new(bytes.Buffer)
   146  			for i := 0; i < b.N; i++ {
   147  				func() {
   148  					buf.Reset()
   149  					writer := NewWriter(buf, options...)
   150  					defer writer.Close()
   151  					if err := writer.Write(rec); err != nil {
   152  						b.Fatal(err)
   153  					}
   154  				}()
   155  			}
   156  		})
   157  
   158  		b.Run(fmt.Sprintf("Reader/codec=%s", codec.name), func(b *testing.B) {
   159  			buf := new(bytes.Buffer)
   160  			writer := NewWriter(buf, options...)
   161  			defer writer.Close()
   162  			require.NoError(b, writer.Write(rec))
   163  			bufBytes := buf.Bytes()
   164  
   165  			b.ResetTimer()
   166  			for i := 0; i < b.N; i++ {
   167  				func() {
   168  					reader, err := NewReader(bytes.NewReader(bufBytes), WithAllocator(alloc))
   169  					if err != nil {
   170  						b.Fatal(err)
   171  					}
   172  					defer reader.Release()
   173  					for {
   174  						if _, err := reader.Read(); err != nil {
   175  							if err == io.EOF {
   176  								break
   177  							}
   178  							b.Fatal(err)
   179  						}
   180  					}
   181  				}()
   182  			}
   183  		})
   184  	}
   185  }