Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -445,10 +445,12 @@ def ParseStatusChanges(
A list of samples, with various percentiles for each status condition.
"""

conditions = kubernetes_conditions.GetStatusConditionsForResourceType(
resource_type,
resources_to_ignore,
suppress_logging=_ShouldSuppressLogging(),
conditions: list[kubernetes_conditions.KubernetesStatusCondition] = (
kubernetes_conditions.GetStatusConditionsForResourceType(
resource_type,
resources_to_ignore,
suppress_logging=_ShouldSuppressLogging(),
)
)
# Filter out conditions that are too early.
conditions = [c for c in conditions if c.epoch_time >= start_time]
Expand Down Expand Up @@ -482,7 +484,7 @@ def ParseStatusChanges(
return samples

for condition in conditions:
metadata = {
metadata = condition.metadata | {
'k8s_resource_name': condition.resource_name,
}
samples.append(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ class KubernetesStatusCondition:
resource_name: str
epoch_time: int
event: str
metadata: dict[str, str]

@classmethod
def FromJsonPathResult(
cls, resource_type: str, resource_name: str, condition: dict[str, Any]
cls, resource_type: str, resource_name: str, condition: dict[str, Any],
extra_metadata: dict[str, str],
) -> 'KubernetesStatusCondition':
"""Parses the json result of kubectl get."""
str_time = condition['lastTransitionTime']
Expand All @@ -48,6 +50,7 @@ def FromJsonPathResult(
resource_name,
epoch_time=ConvertToEpochTime(str_time),
event=condition['type'],
metadata=extra_metadata,
)

@classmethod
Expand Down Expand Up @@ -88,8 +91,17 @@ def GetStatusConditionsForResourceType(
)
data = json.loads(stdout)
name_to_conditions = {}
name_to_metadata: dict[str, dict[str, str]] = {}
for item in data.get('items', []):
name = item.get('metadata', {}).get('name')
metadata = item.get('metadata', {})
name = metadata.get('name')
labels = metadata.get('labels', {})
found_metadata = {}
if 'node.kubernetes.io/instance-type' in labels:
found_metadata['machine_type'] = labels[
'node.kubernetes.io/instance-type'
]
name_to_metadata[name] = found_metadata
conditions = item.get('status', {}).get('conditions')
if name is not None and conditions is not None:
name_to_conditions[name] = conditions
Expand All @@ -106,7 +118,7 @@ def GetStatusConditionsForResourceType(
continue
results.append(
KubernetesStatusCondition.FromJsonPathResult(
resource_type, name, conditions
resource_type, name, conditions, name_to_metadata[name]
)
)

Expand Down
40 changes: 40 additions & 0 deletions tests/kubernetes_conditions_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,46 @@ def testPodStatusConditionsWithIgnoredResources(self):
)
self.assertLen(conditions, 2)

def testStatusConditionsWithInstanceType(self):
stdout = json.dumps({
'items': [
{
'metadata': {
'name': 'node123',
'labels': {
'node.kubernetes.io/instance-type': 'n2-standard-4',
},
},
'status': {
'conditions': [
{
'lastProbeTime': None,
'lastTransitionTime': '1970-01-01T00:01:19Z',
'status': 'True',
'type': 'Ready',
},
]
},
},
]
})
self.enter_context(
mock.patch.object(
kubectl,
'RunKubectlCommand',
return_value=(stdout, '', 0),
)
)
conditions = kubernetes_conditions.GetStatusConditionsForResourceType(
'node',
frozenset(),
)
self.assertLen(conditions, 1)
self.assertEqual(
conditions[0].metadata,
{'machine_type': 'n2-standard-4'},
)


if __name__ == '__main__':
unittest.main()
46 changes: 46 additions & 0 deletions tests/linux_benchmarks/kubernetes_scale_benchmark_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,52 @@ def testReportLatenciesMultipleStatsOnePod(self):
},
)

@flagsaver.flagsaver(kubernetes_scale_report_latency_percentiles=False)
@flagsaver.flagsaver(kubernetes_scale_report_individual_latencies=True)
def testReportLatenciesContainsMachineType(self):
stdout = json.dumps({
'items': [
{
'metadata': {
'name': 'node1',
'labels': {
'node.kubernetes.io/instance-type': 'n2-standard-4',
},
},
'status': {
'conditions': [
{
'lastProbeTime': None,
'lastTransitionTime': '1970-01-01T00:01:00Z',
'status': 'True',
'type': 'Ready',
},
]
},
},
]
})
self.enter_context(
mock.patch.object(
kubectl,
'RunKubectlCommand',
side_effect=[(stdout, '', 0)],
)
)
samples = kubernetes_scale_benchmark.ParseStatusChanges(
'node', start_time=0
)
samples_by_metric = _SamplesByMetric(samples)
self.assertIn('node_Ready', samples_by_metric)
node_ready_sample = samples_by_metric['node_Ready']
self.assertEqual(
node_ready_sample.metadata,
{
'k8s_resource_name': 'node1',
'machine_type': 'n2-standard-4',
},
)

@flagsaver.flagsaver(kubernetes_scale_num_replicas=10)
def testCheckFailuresPassesWithCorrectNumberOfPods(self):
self.cluster.event_poller = kubernetes_events.KubernetesEventPoller(set)
Expand Down
Loading