Skip to content

Commit

Permalink
Make Pod creation from a Job more correct in mock
Browse files Browse the repository at this point in the history
Randomize the Pod name in a similar way that Kubernetes does when
the default generateName behavior is used. If an explicit name was
set in the pod template in the Job, use that name; don't replace it
with a generated name. Honor generateName set in the pod template
in the Job.
  • Loading branch information
rra committed Sep 8, 2023
1 parent 4ef9299 commit 714c95d
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 21 deletions.
3 changes: 3 additions & 0 deletions changelog.d/20230908_152325_rra_DM_40691_queue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Bug fixes

- When creating a `Pod` from a `Job` in the Kubernetes mock using `generateName`, randomize the `Pod` name like Kubernetes does rather than using a fixed name. This forces tests to scan correctly for pods associated with a job. If the `Pod` `name` or `generateName` was explicitly configured in the `Job` template, honor it.
41 changes: 20 additions & 21 deletions src/safir/testing/kubernetes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1221,9 +1221,12 @@ async def create_namespaced_job(self, namespace: str, body: V1Job) -> None:
"""Create a job object.
A pod corresponding to this job will also be created. The pod will
have a label ``job-name`` set to the name of the Job object. Its
name will be the job's name prepended to ``-abcde``. If
``initial_pod_phase`` on the mock is set to ``Running``, the
have a label ``job-name`` set to the name of the ``Job`` object, and
will honor the ``name`` or ``generateName`` metadata from the pod spec
in the ``Job``. If neither is set, it will use the job name followed
by ``-`` as the base for a generated name.
If ``initial_pod_phase`` on the mock is set to ``Running``, the
``status.active`` field of the job will be set to 1.
Parameters
Expand All @@ -1244,24 +1247,20 @@ async def create_namespaced_job(self, namespace: str, body: V1Job) -> None:
stream = self._event_streams[namespace]["Job"]
body.metadata.resource_version = stream.next_resource_version
self._store_object(namespace, "Job", name, body)
# Pretend to spawn a pod
# If there is no metadata, create a V1ObjectMeta object with just
# namespace, a "generateName" of the job name, and a "job-name"
# label, which appears to be what Kubernetes does.
template = body.spec.template
podmd = template.metadata
if podmd is None:
podmd = V1ObjectMeta(
namespace=namespace,
generate_name=f"{name}-",
)
# In real life, the name has five random alphanumeric characters,
# but for testing we'd like to know what the spawned pod is going to
# be called. But in real life, if you set "generateName" you can't
# also set the pod name.
podmd.name = name + "-abcde"
podmd.labels["job-name"] = name
pod = V1Pod(metadata=podmd, spec=template.spec)

# Normally, Kubernetes will immediately spawn a Pod using the
# specification in the Job. Simulate that here.
pod = V1Pod(
metadata=body.spec.template.metadata or V1ObjectMeta(),
spec=body.spec.template.spec,
)
if not pod.metadata.name:
if not pod.metadata.generate_name:
pod.metadata.generate_name = f"{name}-"
base = pod.metadata.generate_name
pod.metadata.name = base + os.urandom(3).hex()[:5]
pod.metadata.labels["job-name"] = name
pod.metadata.namespace = namespace
await self.create_namespaced_pod(namespace, pod)
if pod.status.phase == "Running":
body.status = V1JobStatus(active=1)
Expand Down

0 comments on commit 714c95d

Please sign in to comment.