Files
kubernetes.core/tests/unit/module_utils/test_apply.py
Abhijeet Kasurde 91b80b1d1d Enable black formatting test (#259)
Enable black formatting test

SUMMARY
Signed-off-by: Abhijeet Kasurde akasurde@redhat.com
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
plugins/action/k8s_info.py
plugins/connection/kubectl.py
plugins/doc_fragments/helm_common_options.py
plugins/doc_fragments/k8s_auth_options.py
plugins/doc_fragments/k8s_delete_options.py
plugins/doc_fragments/k8s_name_options.py
plugins/doc_fragments/k8s_resource_options.py
plugins/doc_fragments/k8s_scale_options.py
plugins/doc_fragments/k8s_state_options.py
plugins/doc_fragments/k8s_wait_options.py
plugins/filter/k8s.py
plugins/inventory/k8s.py
plugins/lookup/k8s.py
plugins/lookup/kustomize.py
plugins/module_utils/ansiblemodule.py
plugins/module_utils/apply.py
plugins/module_utils/args_common.py
plugins/module_utils/client/discovery.py
plugins/module_utils/client/resource.py
plugins/module_utils/common.py
plugins/module_utils/exceptions.py
plugins/module_utils/hashes.py
plugins/module_utils/helm.py
plugins/module_utils/k8sdynamicclient.py
plugins/module_utils/selector.py
plugins/modules/helm.py
plugins/modules/helm_info.py
plugins/modules/helm_plugin.py
plugins/modules/helm_plugin_info.py
plugins/modules/helm_repository.py
plugins/modules/helm_template.py
plugins/modules/k8s.py
plugins/modules/k8s_cluster_info.py
plugins/modules/k8s_cp.py
plugins/modules/k8s_drain.py
plugins/modules/k8s_exec.py
plugins/modules/k8s_info.py
plugins/modules/k8s_json_patch.py
plugins/modules/k8s_log.py
plugins/modules/k8s_rollback.py
plugins/modules/k8s_scale.py
plugins/modules/k8s_service.py
tests/integration/targets/kubernetes/library/test_tempfile.py
tests/unit/module_utils/test_apply.py
tests/unit/module_utils/test_common.py
tests/unit/module_utils/test_discoverer.py
tests/unit/module_utils/test_hashes.py
tests/unit/module_utils/test_marshal.py
tests/unit/module_utils/test_selector.py
tox.ini

Reviewed-by: None <None>
Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: None <None>
2021-10-18 15:32:05 +00:00

491 lines
16 KiB
Python

# Copyright [2017] [Red Hat, Inc.]
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from ansible_collections.kubernetes.core.plugins.module_utils.apply import (
merge,
apply_patch,
)
tests = [
dict(
last_applied=dict(
kind="ConfigMap", metadata=dict(name="foo"), data=dict(one="1", two="2")
),
desired=dict(
kind="ConfigMap", metadata=dict(name="foo"), data=dict(one="1", two="2")
),
expected={},
),
dict(
last_applied=dict(
kind="ConfigMap", metadata=dict(name="foo"), data=dict(one="1", two="2")
),
desired=dict(
kind="ConfigMap",
metadata=dict(name="foo"),
data=dict(one="1", two="2", three="3"),
),
expected=dict(data=dict(three="3")),
),
dict(
last_applied=dict(
kind="ConfigMap", metadata=dict(name="foo"), data=dict(one="1", two="2")
),
desired=dict(
kind="ConfigMap", metadata=dict(name="foo"), data=dict(one="1", three="3")
),
expected=dict(data=dict(two=None, three="3")),
),
dict(
last_applied=dict(
kind="ConfigMap",
metadata=dict(name="foo", annotations=dict(this="one", hello="world")),
data=dict(one="1", two="2"),
),
desired=dict(
kind="ConfigMap", metadata=dict(name="foo"), data=dict(one="1", three="3")
),
expected=dict(metadata=dict(annotations=None), data=dict(two=None, three="3")),
),
dict(
last_applied=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(ports=[dict(port=8080, name="http")]),
),
actual=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(ports=[dict(port=8080, protocol="TCP", name="http")]),
),
desired=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(ports=[dict(port=8080, name="http")]),
),
expected=dict(spec=dict(ports=[dict(port=8080, protocol="TCP", name="http")])),
),
dict(
last_applied=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(ports=[dict(port=8080, name="http")]),
),
actual=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(ports=[dict(port=8080, protocol="TCP", name="http")]),
),
desired=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(ports=[dict(port=8081, name="http")]),
),
expected=dict(spec=dict(ports=[dict(port=8081, name="http")])),
),
dict(
last_applied=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(ports=[dict(port=8080, name="http")]),
),
actual=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(ports=[dict(port=8080, protocol="TCP", name="http")]),
),
desired=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(
ports=[dict(port=8443, name="https"), dict(port=8080, name="http")]
),
),
expected=dict(
spec=dict(
ports=[
dict(port=8443, name="https"),
dict(port=8080, name="http", protocol="TCP"),
]
)
),
),
dict(
last_applied=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(
ports=[dict(port=8443, name="https"), dict(port=8080, name="http")]
),
),
actual=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(
ports=[
dict(port=8443, protocol="TCP", name="https"),
dict(port=8080, protocol="TCP", name="http"),
]
),
),
desired=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(ports=[dict(port=8080, name="http")]),
),
expected=dict(spec=dict(ports=[dict(port=8080, name="http", protocol="TCP")])),
),
dict(
last_applied=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(
ports=[
dict(port=8443, name="https", madeup="xyz"),
dict(port=8080, name="http"),
]
),
),
actual=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(
ports=[
dict(port=8443, protocol="TCP", name="https", madeup="xyz"),
dict(port=8080, protocol="TCP", name="http"),
]
),
),
desired=dict(
kind="Service",
metadata=dict(name="foo"),
spec=dict(ports=[dict(port=8443, name="https")]),
),
expected=dict(
spec=dict(
ports=[dict(madeup=None, port=8443, name="https", protocol="TCP")]
)
),
),
dict(
last_applied=dict(
kind="Pod",
metadata=dict(name="foo"),
spec=dict(
containers=[
dict(
name="busybox",
image="busybox",
resources=dict(
requests=dict(cpu="100m", memory="100Mi"),
limits=dict(cpu="100m", memory="100Mi"),
),
)
]
),
),
actual=dict(
kind="Pod",
metadata=dict(name="foo"),
spec=dict(
containers=[
dict(
name="busybox",
image="busybox",
resources=dict(
requests=dict(cpu="100m", memory="100Mi"),
limits=dict(cpu="100m", memory="100Mi"),
),
)
]
),
),
desired=dict(
kind="Pod",
metadata=dict(name="foo"),
spec=dict(
containers=[
dict(
name="busybox",
image="busybox",
resources=dict(
requests=dict(cpu="50m", memory="50Mi"),
limits=dict(memory="50Mi"),
),
)
]
),
),
expected=dict(
spec=dict(
containers=[
dict(
name="busybox",
image="busybox",
resources=dict(
requests=dict(cpu="50m", memory="50Mi"),
limits=dict(cpu=None, memory="50Mi"),
),
)
]
)
),
),
dict(
desired=dict(
kind="Pod",
spec=dict(
containers=[
dict(
name="hello",
volumeMounts=[dict(name="test", mountPath="/test")],
)
],
volumes=[dict(name="test", configMap=dict(name="test"))],
),
),
last_applied=dict(
kind="Pod",
spec=dict(
containers=[
dict(
name="hello",
volumeMounts=[dict(name="test", mountPath="/test")],
)
],
volumes=[dict(name="test", configMap=dict(name="test"))],
),
),
actual=dict(
kind="Pod",
spec=dict(
containers=[
dict(
name="hello",
volumeMounts=[
dict(name="test", mountPath="/test"),
dict(
mountPath="/var/run/secrets/kubernetes.io/serviceaccount",
name="default-token-xyz",
),
],
)
],
volumes=[
dict(name="test", configMap=dict(name="test")),
dict(
name="default-token-xyz",
secret=dict(secretName="default-token-xyz"),
),
],
),
),
expected=dict(
spec=dict(
containers=[
dict(
name="hello",
volumeMounts=[
dict(name="test", mountPath="/test"),
dict(
mountPath="/var/run/secrets/kubernetes.io/serviceaccount",
name="default-token-xyz",
),
],
)
],
volumes=[
dict(name="test", configMap=dict(name="test")),
dict(
name="default-token-xyz",
secret=dict(secretName="default-token-xyz"),
),
],
)
),
),
# This next one is based on a real world case where definition was mostly
# str type and everything else was mostly unicode type (don't ask me how)
dict(
last_applied={
u"kind": u"ConfigMap",
u"data": {u"one": "1", "three": "3", "two": "2"},
u"apiVersion": u"v1",
u"metadata": {u"namespace": u"apply", u"name": u"apply-configmap"},
},
actual={
u"kind": u"ConfigMap",
u"data": {u"one": "1", "three": "3", "two": "2"},
u"apiVersion": u"v1",
u"metadata": {
u"namespace": u"apply",
u"name": u"apply-configmap",
u"resourceVersion": "1714994",
u"creationTimestamp": u"2019-08-17T05:08:05Z",
u"annotations": {},
u"selfLink": u"/api/v1/namespaces/apply/configmaps/apply-configmap",
u"uid": u"fed45fb0-c0ac-11e9-9d95-025000000001",
},
},
desired={
"kind": u"ConfigMap",
"data": {"one": "1", "three": "3", "two": "2"},
"apiVersion": "v1",
"metadata": {"namespace": "apply", "name": "apply-configmap"},
},
expected=dict(),
),
# apply a Deployment, then scale the Deployment (which doesn't affect last-applied)
# then apply the Deployment again. Should un-scale the Deployment
dict(
last_applied={
"kind": u"Deployment",
"spec": {
"replicas": 1,
"template": {
"spec": {
"containers": [
{
"name": "this_must_exist",
"envFrom": [
{"configMapRef": {"name": "config-xyz"}},
{"secretRef": {"name": "config-wxy"}},
],
}
]
}
},
},
"metadata": {"namespace": "apply", "name": u"apply-deployment"},
},
actual={
"kind": u"Deployment",
"spec": {
"replicas": 0,
"template": {
"spec": {
"containers": [
{
"name": "this_must_exist",
"envFrom": [
{"configMapRef": {"name": "config-xyz"}},
{"secretRef": {"name": "config-wxy"}},
],
}
]
}
},
},
"metadata": {"namespace": "apply", "name": u"apply-deployment"},
},
desired={
"kind": u"Deployment",
"spec": {
"replicas": 1,
"template": {
"spec": {
"containers": [
{
"name": "this_must_exist",
"envFrom": [{"configMapRef": {"name": "config-abc"}}],
}
]
}
},
},
"metadata": {"namespace": "apply", "name": u"apply-deployment"},
},
expected={
"spec": {
"replicas": 1,
"template": {
"spec": {
"containers": [
{
"name": "this_must_exist",
"envFrom": [{"configMapRef": {"name": "config-abc"}}],
}
]
}
},
}
},
),
dict(
last_applied={"kind": "MadeUp", "toplevel": {"original": "entry"}},
actual={
"kind": "MadeUp",
"toplevel": {
"original": "entry",
"another": {"nested": {"entry": "value"}},
},
},
desired={
"kind": "MadeUp",
"toplevel": {
"original": "entry",
"another": {"nested": {"entry": "value"}},
},
},
expected={},
),
]
def test_merges():
for test in tests:
assert (
merge(
test["last_applied"],
test["desired"],
test.get("actual", test["last_applied"]),
)
== test["expected"]
)
def test_apply_patch():
actual = dict(
kind="ConfigMap",
metadata=dict(
name="foo",
annotations={
"kubectl.kubernetes.io/last-applied-configuration": '{"data":{"one":"1","two":"2"},"kind":"ConfigMap",'
'"metadata":{"annotations":{"hello":"world","this":"one"},"name":"foo"}}',
"this": "one",
"hello": "world",
},
),
data=dict(one="1", two="2"),
)
desired = dict(
kind="ConfigMap", metadata=dict(name="foo"), data=dict(one="1", three="3")
)
expected = dict(
metadata=dict(
annotations={
"kubectl.kubernetes.io/last-applied-configuration": '{"data":{"one":"1","three":"3"},"kind":"ConfigMap","metadata":{"name":"foo"}}',
"this": None,
"hello": None,
}
),
data=dict(two=None, three="3"),
)
assert apply_patch(actual, desired) == (actual, expected)