You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

90 lines
2.4 KiB

  1. // Copyright 2016 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package internal
  15. import (
  16. "context"
  17. "errors"
  18. "fmt"
  19. "testing"
  20. "time"
  21. gax "github.com/googleapis/gax-go/v2"
  22. "google.golang.org/grpc/codes"
  23. "google.golang.org/grpc/status"
  24. )
  25. func TestRetry(t *testing.T) {
  26. ctx := context.Background()
  27. // Without a context deadline, retry will run until the function
  28. // says not to retry any more.
  29. n := 0
  30. endRetry := errors.New("end retry")
  31. err := retry(ctx, gax.Backoff{},
  32. func() (bool, error) {
  33. n++
  34. if n < 10 {
  35. return false, nil
  36. }
  37. return true, endRetry
  38. },
  39. func(context.Context, time.Duration) error { return nil })
  40. if got, want := err, endRetry; got != want {
  41. t.Errorf("got %v, want %v", err, endRetry)
  42. }
  43. if n != 10 {
  44. t.Errorf("n: got %d, want %d", n, 10)
  45. }
  46. // If the context has a deadline, sleep will return an error
  47. // and end the function.
  48. n = 0
  49. err = retry(ctx, gax.Backoff{},
  50. func() (bool, error) { return false, nil },
  51. func(context.Context, time.Duration) error {
  52. n++
  53. if n < 10 {
  54. return nil
  55. }
  56. return context.DeadlineExceeded
  57. })
  58. if err == nil {
  59. t.Error("got nil, want error")
  60. }
  61. }
  62. func TestRetryPreserveError(t *testing.T) {
  63. // Retry tries to preserve the type and other information from
  64. // the last error returned by the function.
  65. err := retry(context.Background(), gax.Backoff{},
  66. func() (bool, error) {
  67. return false, status.Error(codes.NotFound, "not found")
  68. },
  69. func(context.Context, time.Duration) error {
  70. return context.DeadlineExceeded
  71. })
  72. got, ok := status.FromError(err)
  73. if !ok {
  74. t.Fatalf("got %T, wanted a status", got)
  75. }
  76. if g, w := got.Code(), codes.NotFound; g != w {
  77. t.Errorf("got code %v, want %v", g, w)
  78. }
  79. wantMessage := fmt.Sprintf("retry failed with %v; last error: not found", context.DeadlineExceeded)
  80. if g, w := got.Message(), wantMessage; g != w {
  81. t.Errorf("got message %q, want %q", g, w)
  82. }
  83. }