Skip to content

Commit 3c2842f

Browse files
committed
Add ownership transfer test
1 parent ec136db commit 3c2842f

File tree

1 file changed

+139
-20
lines changed

1 file changed

+139
-20
lines changed

test/integration/apiserver/apply/apply_test.go

Lines changed: 139 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -296,28 +296,28 @@ func TestApplyUpdateApplyConflictForced(t *testing.T) {
296296
"kind": "Deployment",
297297
"metadata": {
298298
"name": "deployment",
299-
"labels": {"app": "nginx"}
299+
"labels": {"app": "nginx"}
300300
},
301301
"spec": {
302-
"replicas": 3,
303-
"selector": {
304-
"matchLabels": {
305-
"app": "nginx"
306-
}
307-
},
308-
"template": {
309-
"metadata": {
310-
"labels": {
311-
"app": "nginx"
312-
}
313-
},
314-
"spec": {
315-
"containers": [{
316-
"name": "nginx",
317-
"image": "nginx:latest"
318-
}]
319-
}
320-
}
302+
"replicas": 3,
303+
"selector": {
304+
"matchLabels": {
305+
"app": "nginx"
306+
}
307+
},
308+
"template": {
309+
"metadata": {
310+
"labels": {
311+
"app": "nginx"
312+
}
313+
},
314+
"spec": {
315+
"containers": [{
316+
"name": "nginx",
317+
"image": "nginx:latest"
318+
}]
319+
}
320+
}
321321
}
322322
}`)
323323

@@ -1873,6 +1873,125 @@ func TestApplyUnsetSharedFields(t *testing.T) {
18731873
}
18741874
}
18751875

1876+
// TestApplyCanTransferFieldOwnershipToController verifies that when an applier creates an
1877+
// object, a controller takes ownership of a field, and the applier
1878+
// then omits the field from its applied configuration, that the field value persists.
1879+
func TestApplyCanTransferFieldOwnershipToController(t *testing.T) {
1880+
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
1881+
1882+
_, client, closeFn := setup(t)
1883+
defer closeFn()
1884+
1885+
// Applier creates a deployment with replicas set to 3
1886+
apply := []byte(`{
1887+
"apiVersion": "apps/v1",
1888+
"kind": "Deployment",
1889+
"metadata": {
1890+
"name": "deployment-shared-map-item-removal",
1891+
"labels": {"app": "nginx"}
1892+
},
1893+
"spec": {
1894+
"replicas": 3,
1895+
"selector": {
1896+
"matchLabels": {
1897+
"app": "nginx"
1898+
}
1899+
},
1900+
"template": {
1901+
"metadata": {
1902+
"labels": {
1903+
"app": "nginx"
1904+
}
1905+
},
1906+
"spec": {
1907+
"containers": [{
1908+
"name": "nginx",
1909+
"image": "nginx:latest",
1910+
}]
1911+
}
1912+
}
1913+
}
1914+
}`)
1915+
1916+
appliedObj, err := client.CoreV1().RESTClient().Patch(types.ApplyPatchType).
1917+
AbsPath("/apis/apps/v1").
1918+
Namespace("default").
1919+
Resource("deployments").
1920+
Name("deployment-shared-map-item-removal").
1921+
Param("fieldManager", "test_applier").
1922+
Body(apply).
1923+
Do(context.TODO()).
1924+
Get()
1925+
if err != nil {
1926+
t.Fatalf("Failed to create object using Apply patch: %v", err)
1927+
}
1928+
1929+
// a controller takes over the replicas field
1930+
applied, ok := appliedObj.(*appsv1.Deployment)
1931+
if !ok {
1932+
t.Fatalf("Failed to convert response object to Deployment")
1933+
}
1934+
replicas := int32(4)
1935+
applied.Spec.Replicas = &replicas
1936+
_, err = client.AppsV1().Deployments("default").
1937+
Update(context.TODO(), applied, metav1.UpdateOptions{FieldManager: "test_updater"})
1938+
if err != nil {
1939+
t.Fatalf("Failed to create object using Apply patch: %v", err)
1940+
}
1941+
1942+
// applier omits replicas
1943+
apply = []byte(`{
1944+
"apiVersion": "apps/v1",
1945+
"kind": "Deployment",
1946+
"metadata": {
1947+
"name": "deployment-shared-map-item-removal",
1948+
"labels": {"app": "nginx"}
1949+
},
1950+
"spec": {
1951+
"selector": {
1952+
"matchLabels": {
1953+
"app": "nginx"
1954+
}
1955+
},
1956+
"template": {
1957+
"metadata": {
1958+
"labels": {
1959+
"app": "nginx"
1960+
}
1961+
},
1962+
"spec": {
1963+
"containers": [{
1964+
"name": "nginx",
1965+
"image": "nginx:latest",
1966+
}]
1967+
}
1968+
}
1969+
}
1970+
}`)
1971+
1972+
patched, err := client.CoreV1().RESTClient().Patch(types.ApplyPatchType).
1973+
AbsPath("/apis/apps/v1").
1974+
Namespace("default").
1975+
Resource("deployments").
1976+
Name("deployment-shared-map-item-removal").
1977+
Param("fieldManager", "test_applier").
1978+
Body(apply).
1979+
Do(context.TODO()).
1980+
Get()
1981+
if err != nil {
1982+
t.Fatalf("Failed to create object using Apply patch: %v", err)
1983+
}
1984+
1985+
// ensure the container is deleted even though a controller updated a field of the container
1986+
deployment, ok := patched.(*appsv1.Deployment)
1987+
if !ok {
1988+
t.Fatalf("Failed to convert response object to Deployment")
1989+
}
1990+
if *deployment.Spec.Replicas != 4 {
1991+
t.Errorf("Expected deployment.spec.replicas to be 4, but got %d", deployment.Spec.Replicas)
1992+
}
1993+
}
1994+
18761995
// TestApplyCanRemoveMapItemsContributedToByControllers verifies that when an applier creates an
18771996
// object, a controller modifies the contents of the map item via update, and the applier
18781997
// then omits the item from its applied configuration, that the item is removed.

0 commit comments

Comments
 (0)