(t *testing.T)
| 27 | ) |
| 28 | |
| 29 | func TestClusterUnaryClientInterceptor(t *testing.T) { |
| 30 | genericErr := errors.New("generic error") |
| 31 | testCases := map[string]struct { |
| 32 | invokerError error |
| 33 | cluster string |
| 34 | expectedErr error |
| 35 | expectedMetrics string |
| 36 | expectedLogs string |
| 37 | shouldPanic bool |
| 38 | }{ |
| 39 | "if no cluster label is set ClusterUnaryClientInterceptor panics": { |
| 40 | cluster: "", |
| 41 | shouldPanic: true, |
| 42 | }, |
| 43 | "if cluster label is set it should be propagated to invoker": { |
| 44 | cluster: "cluster", |
| 45 | }, |
| 46 | "if invoker returns a wrong cluster error it is handled by the interceptor": { |
| 47 | cluster: "cluster", |
| 48 | invokerError: grpcutil.Status(codes.FailedPrecondition, `request intended for cluster "cluster" - this is cluster "another-cluster"`, &grpcutil.ErrorDetails{Cause: grpcutil.WRONG_CLUSTER_VALIDATION_LABEL}).Err(), |
| 49 | expectedErr: grpcutil.Status(codes.Internal, `request rejected by the server: request intended for cluster "cluster" - this is cluster "another-cluster"`).Err(), |
| 50 | expectedMetrics: ` |
| 51 | # HELP test_request_invalid_cluster_validation_labels_total Number of requests with invalid cluster validation label. |
| 52 | # TYPE test_request_invalid_cluster_validation_labels_total counter |
| 53 | test_request_invalid_cluster_validation_labels_total{method="GET"} 1 |
| 54 | `, |
| 55 | expectedLogs: `level=warn msg="request rejected by the server: request intended for cluster \"cluster\" - this is cluster \"another-cluster\"" method=GET cluster_validation_labels=[cluster]`, |
| 56 | }, |
| 57 | "if invoker returns a generic error the error is propagated": { |
| 58 | cluster: "cluster", |
| 59 | invokerError: genericErr, |
| 60 | expectedErr: genericErr, |
| 61 | }, |
| 62 | } |
| 63 | verifyClusterPropagation := func(ctx context.Context, expectedCluster string) { |
| 64 | md, ok := metadata.FromOutgoingContext(ctx) |
| 65 | require.True(t, ok) |
| 66 | clusterIDs, ok := md[clusterutil.MetadataClusterValidationLabelKey] |
| 67 | require.True(t, ok) |
| 68 | require.Len(t, clusterIDs, 1) |
| 69 | require.Equal(t, expectedCluster, clusterIDs[0]) |
| 70 | } |
| 71 | invalidClusterValidationReporter := func(cluster string, logger log.Logger, invalidClusterRequests *prometheus.CounterVec) InvalidClusterValidationReporter { |
| 72 | return func(msg string, method string) { |
| 73 | level.Warn(logger).Log("msg", msg, "method", method, "cluster_validation_labels", fmt.Sprintf("[%s]", cluster)) |
| 74 | invalidClusterRequests.WithLabelValues(method).Inc() |
| 75 | } |
| 76 | } |
| 77 | for testName, testCase := range testCases { |
| 78 | t.Run(testName, func(t *testing.T) { |
| 79 | defer func() { |
| 80 | r := recover() |
| 81 | require.Equal(t, testCase.shouldPanic, r != nil) |
| 82 | }() |
| 83 | buf := bytes.NewBuffer(nil) |
| 84 | logger := createLogger(t, buf) |
| 85 | reg := prometheus.NewRegistry() |
| 86 | interceptor := ClusterUnaryClientInterceptor(testCase.cluster, invalidClusterValidationReporter(testCase.cluster, logger, newRequestInvalidClusterValidationLabelsTotalCounter(reg))) |
nothing calls this directly
no test coverage detected