1/* 2Copyright 2018 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package apiregistration 18 19import ( 20 "reflect" 21 "testing" 22) 23 24var ( 25 a APIServiceConditionType = "A" 26 b APIServiceConditionType = "B" 27) 28 29func TestGetAPIServiceConditionByType(t *testing.T) { 30 conditionA := makeNewAPIServiceCondition(a, "a reason", "a message", ConditionTrue) 31 conditionB := makeNewAPIServiceCondition(b, "b reason", "b message", ConditionTrue) 32 tests := []*struct { 33 name string 34 apiService *APIService 35 conditionType APIServiceConditionType 36 expectedCondition *APIServiceCondition 37 }{ 38 { 39 name: "Should find a matching condition from apiService", 40 apiService: makeNewAPIService("v1", 100, conditionA, conditionB), 41 conditionType: a, 42 expectedCondition: &conditionA, 43 }, 44 { 45 name: "Should not find a matching condition", 46 apiService: makeNewAPIService("v1", 100, conditionA), 47 conditionType: b, 48 expectedCondition: nil, 49 }, 50 } 51 52 for _, tc := range tests { 53 actual := GetAPIServiceConditionByType(tc.apiService, tc.conditionType) 54 if !reflect.DeepEqual(tc.expectedCondition, actual) { 55 t.Errorf("expected %s, actual %s", tc.expectedCondition, actual) 56 } 57 } 58} 59 60func TestIsAPIServiceConditionTrue(t *testing.T) { 61 conditionATrue := makeNewAPIServiceCondition(a, "a reason", "a message", ConditionTrue) 62 conditionAFalse := makeNewAPIServiceCondition(a, "a reason", "a message", ConditionFalse) 63 tests := []*struct { 64 name string 65 apiService *APIService 66 conditionType APIServiceConditionType 67 expected bool 68 }{ 69 { 70 name: "Should return false when condition of type is not present", 71 apiService: makeNewAPIService("v1", 100), 72 conditionType: a, 73 expected: false, 74 }, 75 { 76 name: "Should return false when condition of type is present but status is not ConditionTrue", 77 apiService: makeNewAPIService("v1", 100, conditionAFalse), 78 conditionType: a, 79 expected: false, 80 }, 81 { 82 name: "Should return false when condition of type is present but status is not ConditionTrue", 83 apiService: makeNewAPIService("v1", 100, conditionATrue), 84 conditionType: a, 85 expected: true, 86 }, 87 } 88 89 for _, tc := range tests { 90 if isConditionTrue := IsAPIServiceConditionTrue(tc.apiService, tc.conditionType); isConditionTrue != tc.expected { 91 t.Errorf("expected condition of type %v to be %v, actually was %v", 92 tc.conditionType, isConditionTrue, tc.expected) 93 94 } 95 } 96} 97 98func TestSetAPIServiceCondition(t *testing.T) { 99 conditionA1 := makeNewAPIServiceCondition(a, "a1 reason", "a1 message", ConditionTrue) 100 conditionA2 := makeNewAPIServiceCondition(a, "a2 reason", "a2 message", ConditionTrue) 101 tests := []*struct { 102 name string 103 apiService *APIService 104 conditionType APIServiceConditionType 105 initialCondition *APIServiceCondition 106 setCondition APIServiceCondition 107 expectedCondition *APIServiceCondition 108 }{ 109 { 110 name: "Should set a new condition with type where previously there was no condition of that type", 111 apiService: makeNewAPIService("v1", 100), 112 conditionType: a, 113 initialCondition: nil, 114 setCondition: conditionA1, 115 expectedCondition: &conditionA1, 116 }, 117 { 118 name: "Should override a condition of type, when a condition of that type existed previously", 119 apiService: makeNewAPIService("v1", 100, conditionA1), 120 conditionType: a, 121 initialCondition: &conditionA1, 122 setCondition: conditionA2, 123 expectedCondition: &conditionA2, 124 }, 125 } 126 127 for _, tc := range tests { 128 startingCondition := GetAPIServiceConditionByType(tc.apiService, tc.conditionType) 129 if !reflect.DeepEqual(startingCondition, tc.initialCondition) { 130 t.Errorf("expected to find condition %s initially, actual was %s", tc.initialCondition, startingCondition) 131 132 } 133 SetAPIServiceCondition(tc.apiService, tc.setCondition) 134 actual := GetAPIServiceConditionByType(tc.apiService, tc.setCondition.Type) 135 if !reflect.DeepEqual(actual, tc.expectedCondition) { 136 t.Errorf("expected %s, actual %s", tc.expectedCondition, actual) 137 } 138 } 139} 140 141func TestSortedAPIServicesByVersion(t *testing.T) { 142 tests := []*struct { 143 name string 144 versions []string 145 expected []string 146 }{ 147 { 148 name: "case1", 149 versions: []string{"v1", "v2"}, 150 expected: []string{"v2", "v1"}, 151 }, 152 { 153 name: "case2", 154 versions: []string{"v2", "v10"}, 155 expected: []string{"v10", "v2"}, 156 }, 157 { 158 name: "case3", 159 versions: []string{"v2", "v2beta1", "v10beta2", "v10beta1", "v10alpha1", "v1"}, 160 expected: []string{"v2", "v1", "v10beta2", "v10beta1", "v2beta1", "v10alpha1"}, 161 }, 162 { 163 name: "case4", 164 versions: []string{"v1", "v2", "test", "foo10", "final", "foo2", "foo1"}, 165 expected: []string{"v2", "v1", "final", "foo1", "foo10", "foo2", "test"}, 166 }, 167 { 168 name: "case5_from_documentation", 169 versions: []string{"v12alpha1", "v10", "v11beta2", "v10beta3", "v3beta1", "v2", "v11alpha2", "foo1", "v1", "foo10"}, 170 expected: []string{"v10", "v2", "v1", "v11beta2", "v10beta3", "v3beta1", "v12alpha1", "v11alpha2", "foo1", "foo10"}, 171 }, 172 } 173 174 for _, tc := range tests { 175 apiServices := make([]*APIService, 0) 176 for _, v := range tc.versions { 177 apiServices = append(apiServices, makeNewAPIService(v, 100)) 178 } 179 sortedServices := SortedByGroupAndVersion(apiServices) 180 actual := make([]string, 0) 181 for _, s := range sortedServices[0] { 182 actual = append(actual, s.Spec.Version) 183 } 184 if !reflect.DeepEqual(tc.expected, actual) { 185 t.Errorf("expected %s, actual %s", tc.expected, actual) 186 } 187 } 188} 189 190func makeNewAPIService(version string, priority int32, conditions ...APIServiceCondition) *APIService { 191 status := APIServiceStatus{Conditions: conditions} 192 return &APIService{Spec: APIServiceSpec{Version: version, VersionPriority: priority}, Status: status} 193} 194 195func makeNewAPIServiceCondition(conditionType APIServiceConditionType, reason string, message string, status ConditionStatus) APIServiceCondition { 196 return APIServiceCondition{Type: conditionType, Reason: reason, Message: message, Status: status} 197} 198