...

Source file src/github.com/go-kivik/kivik/v4/couchdb/iter_test.go

Documentation: github.com/go-kivik/kivik/v4/couchdb

     1  // Licensed under the Apache License, Version 2.0 (the "License"); you may not
     2  // use this file except in compliance with the License. You may obtain a copy of
     3  // the License at
     4  //
     5  //  http://www.apache.org/licenses/LICENSE-2.0
     6  //
     7  // Unless required by applicable law or agreed to in writing, software
     8  // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     9  // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    10  // License for the specific language governing permissions and limitations under
    11  // the License.
    12  
    13  package couchdb
    14  
    15  import (
    16  	"context"
    17  	"errors"
    18  	"io"
    19  	"strings"
    20  	"testing"
    21  	"time"
    22  
    23  	"gitlab.com/flimzy/testy"
    24  )
    25  
    26  func TestCancelableReadCloser(t *testing.T) {
    27  	t.Run("no cancellation", func(t *testing.T) {
    28  		t.Parallel()
    29  		rc := newCancelableReadCloser(
    30  			context.Background(),
    31  			io.NopCloser(strings.NewReader("foo")),
    32  		)
    33  		result, err := io.ReadAll(rc)
    34  		if !testy.ErrorMatches("", err) {
    35  			t.Errorf("Unexpected error: %s", err)
    36  		}
    37  		if string(result) != "foo" {
    38  			t.Errorf("Unexpected result: %s", string(result))
    39  		}
    40  	})
    41  	t.Run("pre-cancelled", func(t *testing.T) {
    42  		t.Parallel()
    43  		ctx, cancel := context.WithCancel(context.Background())
    44  		cancel()
    45  		rc := newCancelableReadCloser(
    46  			ctx,
    47  			io.NopCloser(io.MultiReader(
    48  				testy.DelayReader(100*time.Millisecond),
    49  				strings.NewReader("foo")),
    50  			),
    51  		)
    52  		result, err := io.ReadAll(rc)
    53  		if !testy.ErrorMatches("context canceled", err) {
    54  			t.Errorf("Unexpected error: %s", err)
    55  		}
    56  		if string(result) != "" {
    57  			t.Errorf("Unexpected result: %s", string(result))
    58  		}
    59  	})
    60  	t.Run("canceled mid-flight", func(t *testing.T) {
    61  		t.Parallel()
    62  		ctx, cancel := context.WithTimeout(context.Background(), 150*time.Millisecond)
    63  		defer cancel()
    64  		r := io.MultiReader(
    65  			strings.NewReader("foo"),
    66  			testy.DelayReader(time.Second),
    67  			strings.NewReader("bar"),
    68  		)
    69  		rc := newCancelableReadCloser(
    70  			ctx,
    71  			io.NopCloser(r),
    72  		)
    73  		_, err := io.ReadAll(rc)
    74  		if !testy.ErrorMatches("context deadline exceeded", err) {
    75  			t.Errorf("Unexpected error: %s", err)
    76  		}
    77  	})
    78  	t.Run("read error, not canceled", func(t *testing.T) {
    79  		t.Parallel()
    80  		rc := newCancelableReadCloser(
    81  			context.Background(),
    82  			io.NopCloser(testy.ErrorReader("foo", errors.New("read err"))),
    83  		)
    84  		_, err := io.ReadAll(rc)
    85  		if !testy.ErrorMatches("read err", err) {
    86  			t.Errorf("Unexpected error: %s", err)
    87  		}
    88  	})
    89  	t.Run("closed early", func(t *testing.T) {
    90  		t.Parallel()
    91  		rc := newCancelableReadCloser(
    92  			context.Background(),
    93  			io.NopCloser(testy.NeverReader()),
    94  		)
    95  		_ = rc.Close()
    96  		result, err := io.ReadAll(rc)
    97  		if !testy.ErrorMatches("iterator closed", err) {
    98  			t.Errorf("Unexpected error: %s", err)
    99  		}
   100  		if string(result) != "" {
   101  			t.Errorf("Unexpected result: %s", string(result))
   102  		}
   103  	})
   104  }
   105  

View as plain text