...

Source file src/google.golang.org/grpc/internal/serviceconfig/duration_test.go

Documentation: google.golang.org/grpc/internal/serviceconfig

     1  /*
     2   *
     3   * Copyright 2023 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * 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   */
    18  
    19  package serviceconfig
    20  
    21  import (
    22  	"fmt"
    23  	"math"
    24  	"strings"
    25  	"testing"
    26  	"time"
    27  
    28  	"google.golang.org/grpc/internal/grpcrand"
    29  )
    30  
    31  // Tests both marshalling and unmarshalling of Durations.
    32  func TestDuration_MarshalUnmarshal(t *testing.T) {
    33  	testCases := []struct {
    34  		json         string
    35  		td           time.Duration
    36  		unmarshalErr error
    37  		noMarshal    bool
    38  	}{
    39  		// Basic values.
    40  		{json: `"1s"`, td: time.Second},
    41  		{json: `"-100.700s"`, td: -100*time.Second - 700*time.Millisecond},
    42  		{json: `".050s"`, td: 50 * time.Millisecond, noMarshal: true},
    43  		{json: `"-.001s"`, td: -1 * time.Millisecond, noMarshal: true},
    44  		{json: `"-0.200s"`, td: -200 * time.Millisecond},
    45  		// Positive near / out of bounds.
    46  		{json: `"9223372036s"`, td: 9223372036 * time.Second},
    47  		{json: `"9223372037s"`, td: math.MaxInt64, noMarshal: true},
    48  		{json: `"9223372036.854775807s"`, td: math.MaxInt64},
    49  		{json: `"9223372036.854775808s"`, td: math.MaxInt64, noMarshal: true},
    50  		{json: `"315576000000s"`, td: math.MaxInt64, noMarshal: true},
    51  		{json: `"315576000001s"`, unmarshalErr: fmt.Errorf("out of range")},
    52  		// Negative near / out of bounds.
    53  		{json: `"-9223372036s"`, td: -9223372036 * time.Second},
    54  		{json: `"-9223372037s"`, td: math.MinInt64, noMarshal: true},
    55  		{json: `"-9223372036.854775808s"`, td: math.MinInt64},
    56  		{json: `"-9223372036.854775809s"`, td: math.MinInt64, noMarshal: true},
    57  		{json: `"-315576000000s"`, td: math.MinInt64, noMarshal: true},
    58  		{json: `"-315576000001s"`, unmarshalErr: fmt.Errorf("out of range")},
    59  		// Parse errors.
    60  		{json: `123s`, unmarshalErr: fmt.Errorf("invalid character")},
    61  		{json: `"5m"`, unmarshalErr: fmt.Errorf("malformed duration")},
    62  		{json: `"5.3.2s"`, unmarshalErr: fmt.Errorf("malformed duration")},
    63  		{json: `"x.3s"`, unmarshalErr: fmt.Errorf("malformed duration")},
    64  		{json: `"3.xs"`, unmarshalErr: fmt.Errorf("malformed duration")},
    65  		{json: `"3.1234567890s"`, unmarshalErr: fmt.Errorf("malformed duration")},
    66  		{json: `".s"`, unmarshalErr: fmt.Errorf("malformed duration")},
    67  		{json: `"s"`, unmarshalErr: fmt.Errorf("malformed duration")},
    68  	}
    69  	for _, tc := range testCases {
    70  		// Seed `got` with a random value to ensure we properly reset it in all
    71  		// non-error cases.
    72  		got := Duration(grpcrand.Uint64())
    73  		err := got.UnmarshalJSON([]byte(tc.json))
    74  		if (err == nil && time.Duration(got) != tc.td) ||
    75  			(err != nil) != (tc.unmarshalErr != nil) || !strings.Contains(fmt.Sprint(err), fmt.Sprint(tc.unmarshalErr)) {
    76  			t.Errorf("UnmarshalJSON of %v = %v, %v; want %v, %v", tc.json, time.Duration(got), err, tc.td, tc.unmarshalErr)
    77  		}
    78  
    79  		if tc.unmarshalErr == nil && !tc.noMarshal {
    80  			d := Duration(tc.td)
    81  			got, err := d.MarshalJSON()
    82  			if string(got) != tc.json || err != nil {
    83  				t.Errorf("MarshalJSON of %v = %v, %v; want %v, nil", d, string(got), err, tc.json)
    84  			}
    85  		}
    86  	}
    87  }
    88  

View as plain text