conversion_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. /*
  2. Copyright 2017 The Kubernetes Authors.
  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. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package v1_test
  14. import (
  15. "testing"
  16. appsv1 "k8s.io/api/apps/v1"
  17. "k8s.io/api/core/v1"
  18. apiequality "k8s.io/apimachinery/pkg/api/equality"
  19. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  20. "k8s.io/apimachinery/pkg/util/intstr"
  21. "k8s.io/kubernetes/pkg/api/legacyscheme"
  22. "k8s.io/kubernetes/pkg/apis/apps"
  23. api "k8s.io/kubernetes/pkg/apis/core"
  24. utilpointer "k8s.io/utils/pointer"
  25. )
  26. func TestV12StatefulSetSpecConversion(t *testing.T) {
  27. replicas := utilpointer.Int32Ptr(2)
  28. selector := &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}
  29. appsv1Template := v1.PodTemplateSpec{
  30. ObjectMeta: metav1.ObjectMeta{Name: "foo"},
  31. Spec: v1.PodSpec{
  32. RestartPolicy: v1.RestartPolicy("bar"),
  33. SecurityContext: new(v1.PodSecurityContext),
  34. },
  35. }
  36. apiTemplate := api.PodTemplateSpec{
  37. ObjectMeta: metav1.ObjectMeta{Name: "foo"},
  38. Spec: api.PodSpec{
  39. RestartPolicy: api.RestartPolicy("bar"),
  40. SecurityContext: new(api.PodSecurityContext),
  41. },
  42. }
  43. testcases := map[string]struct {
  44. stsSpec1 *apps.StatefulSetSpec
  45. stsSepc2 *appsv1.StatefulSetSpec
  46. }{
  47. "StatefulSetSpec Conversion 1": {
  48. stsSpec1: &apps.StatefulSetSpec{
  49. Replicas: *replicas,
  50. Template: apiTemplate,
  51. },
  52. stsSepc2: &appsv1.StatefulSetSpec{
  53. Replicas: replicas,
  54. Template: appsv1Template,
  55. },
  56. },
  57. "StatefulSetSpec Conversion 2": {
  58. stsSpec1: &apps.StatefulSetSpec{
  59. Replicas: *replicas,
  60. Selector: selector,
  61. Template: apiTemplate,
  62. ServiceName: "foo",
  63. PodManagementPolicy: apps.PodManagementPolicyType("bar"),
  64. },
  65. stsSepc2: &appsv1.StatefulSetSpec{
  66. Replicas: replicas,
  67. Selector: selector,
  68. Template: appsv1Template,
  69. ServiceName: "foo",
  70. PodManagementPolicy: appsv1.PodManagementPolicyType("bar"),
  71. },
  72. },
  73. }
  74. for k, tc := range testcases {
  75. // apps -> appsv1
  76. internal1 := &appsv1.StatefulSetSpec{}
  77. if err := legacyscheme.Scheme.Convert(tc.stsSpec1, internal1, nil); err != nil {
  78. t.Errorf("%q - %q: unexpected error: %v", k, "from apps to appsv1", err)
  79. }
  80. if !apiequality.Semantic.DeepEqual(internal1, tc.stsSepc2) {
  81. t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from apps to appsv1", tc.stsSepc2, internal1)
  82. }
  83. // appsv1 -> apps
  84. internal2 := &apps.StatefulSetSpec{}
  85. if err := legacyscheme.Scheme.Convert(tc.stsSepc2, internal2, nil); err != nil {
  86. t.Errorf("%q - %q: unexpected error: %v", k, "from appsv1 to apps", err)
  87. }
  88. if !apiequality.Semantic.DeepEqual(internal2, tc.stsSpec1) {
  89. t.Errorf("%q- %q: expected\n\t%#v, got \n\t%#v", k, "from appsv1 to apps", tc.stsSpec1, internal2)
  90. }
  91. }
  92. }
  93. func TestV1StatefulSetStatusConversion(t *testing.T) {
  94. observedGeneration := new(int64)
  95. *observedGeneration = 2
  96. collisionCount := new(int32)
  97. *collisionCount = 1
  98. testcases := map[string]struct {
  99. stsStatus1 *apps.StatefulSetStatus
  100. stsStatus2 *appsv1.StatefulSetStatus
  101. }{
  102. "StatefulSetStatus Conversion 1": {
  103. stsStatus1: &apps.StatefulSetStatus{
  104. Replicas: int32(3),
  105. ReadyReplicas: int32(1),
  106. CurrentReplicas: int32(3),
  107. UpdatedReplicas: int32(3),
  108. CurrentRevision: "12345",
  109. UpdateRevision: "23456",
  110. ObservedGeneration: observedGeneration,
  111. },
  112. stsStatus2: &appsv1.StatefulSetStatus{
  113. Replicas: int32(3),
  114. ReadyReplicas: int32(1),
  115. CurrentReplicas: int32(3),
  116. UpdatedReplicas: int32(3),
  117. CurrentRevision: "12345",
  118. UpdateRevision: "23456",
  119. ObservedGeneration: *observedGeneration,
  120. },
  121. },
  122. "StatefulSetStatus Conversion 2": {
  123. stsStatus1: &apps.StatefulSetStatus{
  124. ObservedGeneration: observedGeneration,
  125. Replicas: int32(3),
  126. ReadyReplicas: int32(1),
  127. CurrentReplicas: int32(3),
  128. UpdatedReplicas: int32(3),
  129. CurrentRevision: "12345",
  130. UpdateRevision: "23456",
  131. CollisionCount: collisionCount,
  132. },
  133. stsStatus2: &appsv1.StatefulSetStatus{
  134. ObservedGeneration: *observedGeneration,
  135. Replicas: int32(3),
  136. ReadyReplicas: int32(1),
  137. CurrentReplicas: int32(3),
  138. UpdatedReplicas: int32(3),
  139. CurrentRevision: "12345",
  140. UpdateRevision: "23456",
  141. CollisionCount: collisionCount,
  142. },
  143. },
  144. }
  145. for k, tc := range testcases {
  146. // apps -> appsv1
  147. internal1 := &appsv1.StatefulSetStatus{}
  148. if err := legacyscheme.Scheme.Convert(tc.stsStatus1, internal1, nil); err != nil {
  149. t.Errorf("%q - %q: unexpected error: %v", k, "from apps to appsv1", err)
  150. }
  151. if !apiequality.Semantic.DeepEqual(internal1, tc.stsStatus2) {
  152. t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from apps to appsv1", tc.stsStatus2, internal1)
  153. }
  154. // appsv1 -> apps
  155. internal2 := &apps.StatefulSetStatus{}
  156. if err := legacyscheme.Scheme.Convert(tc.stsStatus2, internal2, nil); err != nil {
  157. t.Errorf("%q - %q: unexpected error: %v", k, "from appsv1 to apps", err)
  158. }
  159. if !apiequality.Semantic.DeepEqual(internal2, tc.stsStatus1) {
  160. t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from appsv1 to apps", tc.stsStatus1, internal2)
  161. }
  162. }
  163. }
  164. func TestV1StatefulSetUpdateStrategyConversion(t *testing.T) {
  165. partition := utilpointer.Int32Ptr(2)
  166. appsv1rollingUpdate := new(appsv1.RollingUpdateStatefulSetStrategy)
  167. appsv1rollingUpdate.Partition = partition
  168. appsrollingUpdate := new(apps.RollingUpdateStatefulSetStrategy)
  169. appsrollingUpdate.Partition = *partition
  170. testcases := map[string]struct {
  171. stsUpdateStrategy1 *apps.StatefulSetUpdateStrategy
  172. stsUpdateStrategy2 *appsv1.StatefulSetUpdateStrategy
  173. }{
  174. "StatefulSetUpdateStrategy Conversion 1": {
  175. stsUpdateStrategy1: &apps.StatefulSetUpdateStrategy{Type: apps.StatefulSetUpdateStrategyType("foo")},
  176. stsUpdateStrategy2: &appsv1.StatefulSetUpdateStrategy{Type: appsv1.StatefulSetUpdateStrategyType("foo")},
  177. },
  178. "StatefulSetUpdateStrategy Conversion 2": {
  179. stsUpdateStrategy1: &apps.StatefulSetUpdateStrategy{
  180. Type: apps.StatefulSetUpdateStrategyType("foo"),
  181. RollingUpdate: appsrollingUpdate,
  182. },
  183. stsUpdateStrategy2: &appsv1.StatefulSetUpdateStrategy{
  184. Type: appsv1.StatefulSetUpdateStrategyType("foo"),
  185. RollingUpdate: appsv1rollingUpdate,
  186. },
  187. },
  188. }
  189. for k, tc := range testcases {
  190. // apps -> appsv1
  191. internal1 := &appsv1.StatefulSetUpdateStrategy{}
  192. if err := legacyscheme.Scheme.Convert(tc.stsUpdateStrategy1, internal1, nil); err != nil {
  193. t.Errorf("%q - %q: unexpected error: %v", "apps -> appsv1", k, err)
  194. }
  195. if !apiequality.Semantic.DeepEqual(internal1, tc.stsUpdateStrategy2) {
  196. t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", "apps -> appsv1", k, tc.stsUpdateStrategy2, internal1)
  197. }
  198. // appsv1 -> apps
  199. internal2 := &apps.StatefulSetUpdateStrategy{}
  200. if err := legacyscheme.Scheme.Convert(tc.stsUpdateStrategy2, internal2, nil); err != nil {
  201. t.Errorf("%q - %q: unexpected error: %v", "appsv1 -> apps", k, err)
  202. }
  203. if !apiequality.Semantic.DeepEqual(internal2, tc.stsUpdateStrategy1) {
  204. t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", "appsv1 -> apps", k, tc.stsUpdateStrategy1, internal2)
  205. }
  206. }
  207. }
  208. func TestV1RollingUpdateDaemonSetConversion(t *testing.T) {
  209. intorstr := intstr.FromInt(1)
  210. testcases := map[string]struct {
  211. rollingUpdateDs1 *apps.RollingUpdateDaemonSet
  212. rollingUpdateDs2 *appsv1.RollingUpdateDaemonSet
  213. }{
  214. "RollingUpdateDaemonSet Conversion 2": {
  215. rollingUpdateDs1: &apps.RollingUpdateDaemonSet{MaxUnavailable: intorstr},
  216. rollingUpdateDs2: &appsv1.RollingUpdateDaemonSet{MaxUnavailable: &intorstr},
  217. },
  218. }
  219. for k, tc := range testcases {
  220. // apps -> v1
  221. internal1 := &appsv1.RollingUpdateDaemonSet{}
  222. if err := legacyscheme.Scheme.Convert(tc.rollingUpdateDs1, internal1, nil); err != nil {
  223. t.Errorf("%q - %q: unexpected error: %v", k, "from apps to v1", err)
  224. }
  225. if !apiequality.Semantic.DeepEqual(internal1, tc.rollingUpdateDs2) {
  226. t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from apps to v1", tc.rollingUpdateDs2, internal1)
  227. }
  228. // v1 -> apps
  229. internal2 := &apps.RollingUpdateDaemonSet{}
  230. if err := legacyscheme.Scheme.Convert(tc.rollingUpdateDs2, internal2, nil); err != nil {
  231. t.Errorf("%q - %q: unexpected error: %v", k, "from v1 to apps", err)
  232. }
  233. if !apiequality.Semantic.DeepEqual(internal2, tc.rollingUpdateDs1) {
  234. t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from v1 to apps", tc.rollingUpdateDs1, internal2)
  235. }
  236. }
  237. }
  238. func TestV1DeploymentConversion(t *testing.T) {
  239. replica := utilpointer.Int32Ptr(2)
  240. rollbackTo := new(apps.RollbackConfig)
  241. rollbackTo.Revision = int64(2)
  242. testcases := map[string]struct {
  243. deployment1 *apps.Deployment
  244. deployment2 *appsv1.Deployment
  245. }{
  246. "Deployment Conversion 1": {
  247. deployment1: &apps.Deployment{
  248. Spec: apps.DeploymentSpec{
  249. Replicas: *replica,
  250. RollbackTo: rollbackTo,
  251. Template: api.PodTemplateSpec{
  252. Spec: api.PodSpec{
  253. SecurityContext: new(api.PodSecurityContext),
  254. },
  255. },
  256. },
  257. },
  258. deployment2: &appsv1.Deployment{
  259. ObjectMeta: metav1.ObjectMeta{
  260. Annotations: map[string]string{appsv1.DeprecatedRollbackTo: "2"},
  261. },
  262. Spec: appsv1.DeploymentSpec{
  263. Replicas: replica,
  264. Template: v1.PodTemplateSpec{
  265. Spec: v1.PodSpec{
  266. SecurityContext: new(v1.PodSecurityContext),
  267. },
  268. },
  269. },
  270. },
  271. },
  272. "Deployment Conversion 2": {
  273. deployment1: &apps.Deployment{
  274. Spec: apps.DeploymentSpec{
  275. Replicas: *replica,
  276. Template: api.PodTemplateSpec{
  277. Spec: api.PodSpec{
  278. SecurityContext: new(api.PodSecurityContext),
  279. },
  280. },
  281. },
  282. },
  283. deployment2: &appsv1.Deployment{
  284. Spec: appsv1.DeploymentSpec{
  285. Replicas: replica,
  286. Template: v1.PodTemplateSpec{
  287. Spec: v1.PodSpec{
  288. SecurityContext: new(v1.PodSecurityContext),
  289. },
  290. },
  291. },
  292. },
  293. },
  294. }
  295. for k, tc := range testcases {
  296. // apps -> v1beta2
  297. internal1 := &appsv1.Deployment{}
  298. if err := legacyscheme.Scheme.Convert(tc.deployment1, internal1, nil); err != nil {
  299. t.Errorf("%q - %q: unexpected error: %v", k, "from apps to v1beta2", err)
  300. }
  301. if !apiequality.Semantic.DeepEqual(internal1, tc.deployment2) {
  302. t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from apps to v1beta2", tc.deployment2, internal1)
  303. }
  304. // v1beta2 -> apps
  305. internal2 := &apps.Deployment{}
  306. if err := legacyscheme.Scheme.Convert(tc.deployment2, internal2, nil); err != nil {
  307. t.Errorf("%q - %q: unexpected error: %v", k, "from v1beta2 to apps", err)
  308. }
  309. if !apiequality.Semantic.DeepEqual(internal2, tc.deployment1) {
  310. t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "from v1beta2 to apps", tc.deployment1, internal2)
  311. }
  312. }
  313. }
  314. func TestV1DeploymentSpecConversion(t *testing.T) {
  315. replica := utilpointer.Int32Ptr(2)
  316. revisionHistoryLimit := utilpointer.Int32Ptr(2)
  317. progressDeadlineSeconds := utilpointer.Int32Ptr(2)
  318. testcases := map[string]struct {
  319. deploymentSpec1 *apps.DeploymentSpec
  320. deploymentSpec2 *appsv1.DeploymentSpec
  321. }{
  322. "DeploymentSpec Conversion 1": {
  323. deploymentSpec1: &apps.DeploymentSpec{
  324. Replicas: *replica,
  325. Template: api.PodTemplateSpec{
  326. Spec: api.PodSpec{
  327. SecurityContext: new(api.PodSecurityContext),
  328. },
  329. },
  330. },
  331. deploymentSpec2: &appsv1.DeploymentSpec{
  332. Replicas: replica,
  333. Template: v1.PodTemplateSpec{
  334. Spec: v1.PodSpec{
  335. SecurityContext: new(v1.PodSecurityContext),
  336. },
  337. },
  338. },
  339. },
  340. "DeploymentSpec Conversion 2": {
  341. deploymentSpec1: &apps.DeploymentSpec{
  342. Replicas: *replica,
  343. RevisionHistoryLimit: revisionHistoryLimit,
  344. MinReadySeconds: 2,
  345. Paused: true,
  346. Template: api.PodTemplateSpec{
  347. Spec: api.PodSpec{
  348. SecurityContext: new(api.PodSecurityContext),
  349. },
  350. },
  351. },
  352. deploymentSpec2: &appsv1.DeploymentSpec{
  353. Replicas: replica,
  354. RevisionHistoryLimit: revisionHistoryLimit,
  355. MinReadySeconds: 2,
  356. Paused: true,
  357. Template: v1.PodTemplateSpec{
  358. Spec: v1.PodSpec{
  359. SecurityContext: new(v1.PodSecurityContext),
  360. },
  361. },
  362. },
  363. },
  364. "DeploymentSpec Conversion 3": {
  365. deploymentSpec1: &apps.DeploymentSpec{
  366. Replicas: *replica,
  367. ProgressDeadlineSeconds: progressDeadlineSeconds,
  368. Template: api.PodTemplateSpec{
  369. Spec: api.PodSpec{
  370. SecurityContext: new(api.PodSecurityContext),
  371. },
  372. },
  373. },
  374. deploymentSpec2: &appsv1.DeploymentSpec{
  375. Replicas: replica,
  376. ProgressDeadlineSeconds: progressDeadlineSeconds,
  377. Template: v1.PodTemplateSpec{
  378. Spec: v1.PodSpec{
  379. SecurityContext: new(v1.PodSecurityContext),
  380. },
  381. },
  382. },
  383. },
  384. }
  385. // apps -> appsv1
  386. for k, tc := range testcases {
  387. internal := &appsv1.DeploymentSpec{}
  388. if err := legacyscheme.Scheme.Convert(tc.deploymentSpec1, internal, nil); err != nil {
  389. t.Errorf("%q - %q: unexpected error: %v", "apps -> appsv1", k, err)
  390. }
  391. if !apiequality.Semantic.DeepEqual(internal, tc.deploymentSpec2) {
  392. t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", "apps -> appsv1", k, tc.deploymentSpec2, internal)
  393. }
  394. }
  395. // appsv1 -> apps
  396. for k, tc := range testcases {
  397. internal := &apps.DeploymentSpec{}
  398. if err := legacyscheme.Scheme.Convert(tc.deploymentSpec2, internal, nil); err != nil {
  399. t.Errorf("%q - %q: unexpected error: %v", "appsv1 -> apps", k, err)
  400. }
  401. if !apiequality.Semantic.DeepEqual(internal, tc.deploymentSpec1) {
  402. t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", "appsv1 -> apps", k, tc.deploymentSpec1, internal)
  403. }
  404. }
  405. }
  406. func TestV1DeploymentStrategyConversion(t *testing.T) {
  407. maxUnavailable := intstr.FromInt(2)
  408. maxSurge := intstr.FromInt(2)
  409. appsRollingUpdate := apps.RollingUpdateDeployment{MaxUnavailable: maxUnavailable, MaxSurge: maxSurge}
  410. appsv1RollingUpdate := appsv1.RollingUpdateDeployment{MaxUnavailable: &maxUnavailable, MaxSurge: &maxSurge}
  411. testcases := map[string]struct {
  412. deploymentStrategy1 *apps.DeploymentStrategy
  413. deploymentStrategy2 *appsv1.DeploymentStrategy
  414. }{
  415. "DeploymentStrategy Conversion 1": {
  416. deploymentStrategy1: &apps.DeploymentStrategy{Type: apps.DeploymentStrategyType("foo")},
  417. deploymentStrategy2: &appsv1.DeploymentStrategy{Type: appsv1.DeploymentStrategyType("foo")},
  418. },
  419. "DeploymentStrategy Conversion 2": {
  420. deploymentStrategy1: &apps.DeploymentStrategy{Type: apps.DeploymentStrategyType("foo"), RollingUpdate: &appsRollingUpdate},
  421. deploymentStrategy2: &appsv1.DeploymentStrategy{Type: appsv1.DeploymentStrategyType("foo"), RollingUpdate: &appsv1RollingUpdate},
  422. },
  423. }
  424. for k, tc := range testcases {
  425. // apps -> appsv1
  426. internal1 := &appsv1.DeploymentStrategy{}
  427. if err := legacyscheme.Scheme.Convert(tc.deploymentStrategy1, internal1, nil); err != nil {
  428. t.Errorf("%q - %q: unexpected error: %v", k, "apps -> appsv1", err)
  429. }
  430. if !apiequality.Semantic.DeepEqual(internal1, tc.deploymentStrategy2) {
  431. t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "apps -> appsv1", tc.deploymentStrategy2, internal1)
  432. }
  433. // appsv1 -> apps
  434. internal2 := &apps.DeploymentStrategy{}
  435. if err := legacyscheme.Scheme.Convert(tc.deploymentStrategy2, internal2, nil); err != nil {
  436. t.Errorf("%q - %q: unexpected error: %v", k, "appsv1 -> apps", err)
  437. }
  438. if !apiequality.Semantic.DeepEqual(internal2, tc.deploymentStrategy1) {
  439. t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "appsv1 -> apps", tc.deploymentStrategy1, internal2)
  440. }
  441. }
  442. }
  443. func TestV1RollingUpdateDeploymentConversion(t *testing.T) {
  444. nilIntStr := intstr.IntOrString{}
  445. maxUnavailable := intstr.FromInt(2)
  446. maxSurge := intstr.FromInt(2)
  447. testcases := map[string]struct {
  448. rollingUpdateDeployment1 *apps.RollingUpdateDeployment
  449. rollingUpdateDeployment2 *appsv1.RollingUpdateDeployment
  450. }{
  451. "RollingUpdateDeployment Conversion 1": {
  452. rollingUpdateDeployment1: &apps.RollingUpdateDeployment{},
  453. rollingUpdateDeployment2: &appsv1.RollingUpdateDeployment{MaxUnavailable: &nilIntStr, MaxSurge: &nilIntStr},
  454. },
  455. "RollingUpdateDeployment Conversion 2": {
  456. rollingUpdateDeployment1: &apps.RollingUpdateDeployment{MaxUnavailable: maxUnavailable},
  457. rollingUpdateDeployment2: &appsv1.RollingUpdateDeployment{MaxUnavailable: &maxUnavailable, MaxSurge: &nilIntStr},
  458. },
  459. "RollingUpdateDeployment Conversion 3": {
  460. rollingUpdateDeployment1: &apps.RollingUpdateDeployment{MaxSurge: maxSurge},
  461. rollingUpdateDeployment2: &appsv1.RollingUpdateDeployment{MaxSurge: &maxSurge, MaxUnavailable: &nilIntStr},
  462. },
  463. "RollingUpdateDeployment Conversion 4": {
  464. rollingUpdateDeployment1: &apps.RollingUpdateDeployment{MaxUnavailable: maxUnavailable, MaxSurge: maxSurge},
  465. rollingUpdateDeployment2: &appsv1.RollingUpdateDeployment{MaxUnavailable: &maxUnavailable, MaxSurge: &maxSurge},
  466. },
  467. }
  468. for k, tc := range testcases {
  469. // apps -> appsv1
  470. internal1 := &appsv1.RollingUpdateDeployment{}
  471. if err := legacyscheme.Scheme.Convert(tc.rollingUpdateDeployment1, internal1, nil); err != nil {
  472. t.Errorf("%q - %q: unexpected error: %v", k, "apps -> appsv1", err)
  473. }
  474. if !apiequality.Semantic.DeepEqual(internal1, tc.rollingUpdateDeployment2) {
  475. t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "apps -> appsv1", tc.rollingUpdateDeployment2, internal1)
  476. }
  477. // appsv1 -> apps
  478. internal2 := &apps.RollingUpdateDeployment{}
  479. if err := legacyscheme.Scheme.Convert(tc.rollingUpdateDeployment2, internal2, nil); err != nil {
  480. t.Errorf("%q - %q: unexpected error: %v", k, "appsv1 -> apps", err)
  481. }
  482. if !apiequality.Semantic.DeepEqual(internal2, tc.rollingUpdateDeployment1) {
  483. t.Errorf("%q - %q: expected\n\t%#v, got \n\t%#v", k, "appsv1 -> apps", tc.rollingUpdateDeployment1, internal2)
  484. }
  485. }
  486. }
  487. func TestV1ReplicaSetSpecConversion(t *testing.T) {
  488. replicas := new(int32)
  489. *replicas = 2
  490. matchExpressions := []metav1.LabelSelectorRequirement{
  491. {Key: "foo", Operator: metav1.LabelSelectorOpIn, Values: []string{"foo"}},
  492. }
  493. matchLabels := map[string]string{"foo": "bar"}
  494. selector := &metav1.LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions}
  495. testcases := map[string]struct {
  496. replicaset1 *apps.ReplicaSetSpec
  497. replicaset2 *appsv1.ReplicaSetSpec
  498. }{
  499. "ReplicaSetSpec Conversion 1": {
  500. replicaset1: &apps.ReplicaSetSpec{
  501. Replicas: *replicas,
  502. MinReadySeconds: 2,
  503. Template: api.PodTemplateSpec{
  504. Spec: api.PodSpec{
  505. SecurityContext: new(api.PodSecurityContext),
  506. },
  507. },
  508. },
  509. replicaset2: &appsv1.ReplicaSetSpec{
  510. Replicas: replicas,
  511. MinReadySeconds: 2,
  512. Template: v1.PodTemplateSpec{
  513. Spec: v1.PodSpec{
  514. SecurityContext: new(v1.PodSecurityContext),
  515. },
  516. },
  517. },
  518. },
  519. "ReplicaSetSpec Conversion 2": {
  520. replicaset1: &apps.ReplicaSetSpec{
  521. Replicas: *replicas,
  522. Selector: selector,
  523. Template: api.PodTemplateSpec{
  524. Spec: api.PodSpec{
  525. SecurityContext: new(api.PodSecurityContext),
  526. },
  527. },
  528. },
  529. replicaset2: &appsv1.ReplicaSetSpec{
  530. Replicas: replicas,
  531. Selector: selector,
  532. Template: v1.PodTemplateSpec{
  533. Spec: v1.PodSpec{
  534. SecurityContext: new(v1.PodSecurityContext),
  535. },
  536. },
  537. },
  538. },
  539. }
  540. for k, tc := range testcases {
  541. // apps -> appsv1
  542. internal1 := &appsv1.ReplicaSetSpec{}
  543. if err := legacyscheme.Scheme.Convert(tc.replicaset1, internal1, nil); err != nil {
  544. t.Errorf("%q - %q: unexpected error: %v", k, "apps -> appsv1", err)
  545. }
  546. if !apiequality.Semantic.DeepEqual(internal1, tc.replicaset2) {
  547. t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", k, "apps -> appsv1", tc.replicaset2, internal1)
  548. }
  549. // appsv1 -> apps
  550. internal2 := &apps.ReplicaSetSpec{}
  551. if err := legacyscheme.Scheme.Convert(tc.replicaset2, internal2, nil); err != nil {
  552. t.Errorf("%q - %q: unexpected error: %v", k, "appsv1 -> apps", err)
  553. }
  554. if !apiequality.Semantic.DeepEqual(internal2, tc.replicaset1) {
  555. t.Errorf("%q - %q: expected\n\t%+v, got \n\t%+v", k, "appsv1 -> apps", tc.replicaset1, internal2)
  556. }
  557. }
  558. }