k8s.io/apiserver@v0.31.1/pkg/admission/plugin/webhook/errors/statuserror_test.go (about)

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package errors
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    24  )
    25  
    26  func TestToStatusErr(t *testing.T) {
    27  	hookName := "foo"
    28  	deniedBy := fmt.Sprintf("admission webhook %q denied the request", hookName)
    29  	tests := []struct {
    30  		name           string
    31  		result         *metav1.Status
    32  		expectedError  string
    33  		expectedCode   int32
    34  		expectedStatus string
    35  	}{
    36  		{
    37  			"nil result",
    38  			nil,
    39  			deniedBy + " without explanation",
    40  			400,
    41  			metav1.StatusFailure,
    42  		},
    43  		{
    44  			"only message",
    45  			&metav1.Status{
    46  				Message: "you shall not pass",
    47  			},
    48  			deniedBy + ": you shall not pass",
    49  			400,
    50  			metav1.StatusFailure,
    51  		},
    52  		{
    53  			"only reason",
    54  			&metav1.Status{
    55  				Reason: metav1.StatusReasonForbidden,
    56  			},
    57  			deniedBy + ": Forbidden",
    58  			400,
    59  			metav1.StatusFailure,
    60  		},
    61  		{
    62  			"message and reason",
    63  			&metav1.Status{
    64  				Message: "you shall not pass",
    65  				Reason:  metav1.StatusReasonForbidden,
    66  			},
    67  			deniedBy + ": you shall not pass",
    68  			400,
    69  			metav1.StatusFailure,
    70  		},
    71  		{
    72  			"no message, no reason",
    73  			&metav1.Status{},
    74  			deniedBy + " without explanation",
    75  			400,
    76  			metav1.StatusFailure,
    77  		},
    78  		{
    79  			"custom 4xx status code",
    80  			&metav1.Status{Code: 401},
    81  			deniedBy + " without explanation",
    82  			401,
    83  			metav1.StatusFailure,
    84  		},
    85  		{
    86  			"custom 5xx status code",
    87  			&metav1.Status{Code: 500},
    88  			deniedBy + " without explanation",
    89  			500,
    90  			metav1.StatusFailure,
    91  		},
    92  		{
    93  			"200 status code",
    94  			&metav1.Status{Code: 200},
    95  			deniedBy + " without explanation",
    96  			400,
    97  			metav1.StatusFailure,
    98  		},
    99  		{
   100  			"300 status code",
   101  			&metav1.Status{Code: 300},
   102  			deniedBy + " without explanation",
   103  			400,
   104  			metav1.StatusFailure,
   105  		},
   106  		{
   107  			"399 status code",
   108  			&metav1.Status{Code: 399},
   109  			deniedBy + " without explanation",
   110  			400,
   111  			metav1.StatusFailure,
   112  		},
   113  		{
   114  			"missing status",
   115  			&metav1.Status{},
   116  			deniedBy + " without explanation",
   117  			400,
   118  			metav1.StatusFailure,
   119  		},
   120  		{
   121  			"success status overridden",
   122  			&metav1.Status{Status: metav1.StatusSuccess},
   123  			deniedBy + " without explanation",
   124  			400,
   125  			metav1.StatusFailure,
   126  		},
   127  		{
   128  			"failure status preserved",
   129  			&metav1.Status{Status: metav1.StatusFailure},
   130  			deniedBy + " without explanation",
   131  			400,
   132  			metav1.StatusFailure,
   133  		},
   134  		{
   135  			"custom status preserved",
   136  			&metav1.Status{Status: "custom"},
   137  			deniedBy + " without explanation",
   138  			400,
   139  			"custom",
   140  		},
   141  	}
   142  	for _, test := range tests {
   143  		err := ToStatusErr(hookName, test.result)
   144  		if err == nil || err.Error() != test.expectedError {
   145  			t.Errorf("%s: expected an error saying %q, but got %v", test.name, test.expectedError, err)
   146  		}
   147  		if err.ErrStatus.Code != test.expectedCode {
   148  			t.Errorf("%s: expected code %d, got %d", test.name, test.expectedCode, err.ErrStatus.Code)
   149  		}
   150  		if err.ErrStatus.Status != test.expectedStatus {
   151  			t.Errorf("%s: expected code %q, got %q", test.name, test.expectedStatus, err.ErrStatus.Status)
   152  		}
   153  	}
   154  }