|
38 | 38 | LOGGER = get_logger(name=__name__) |
39 | 39 |
|
40 | 40 |
|
| 41 | +@pytest.fixture(scope="session") |
| 42 | +def catalog_pod_model_counts( |
| 43 | + admin_client: DynamicClient, |
| 44 | + recreated_model_catalog_configmap: ConfigMap, |
| 45 | +) -> dict[str, int]: |
| 46 | + """ |
| 47 | + Session-scoped fixture that extracts model counts from catalog pod logs. |
| 48 | +
|
| 49 | + Scrapes logs for earliest occurrences of: |
| 50 | + - "redhat_ai_validated_models: loaded x models" |
| 51 | + - "redhat_ai_models: loaded y models" |
| 52 | +
|
| 53 | + Returns: |
| 54 | + Dictionary with keys "redhat_ai_validated_models" and "redhat_ai_models" |
| 55 | + containing the extracted model counts |
| 56 | + """ |
| 57 | + # Get the model catalog pod |
| 58 | + namespace_name = py_config["model_registry_namespace"] |
| 59 | + catalog_pods = get_model_catalog_pod(client=admin_client, model_registry_namespace=namespace_name) |
| 60 | + assert len(catalog_pods) > 0, f"No model catalog pods found in namespace {namespace_name}" |
| 61 | + |
| 62 | + catalog_pod = catalog_pods[0] # Use the first pod if multiple exist |
| 63 | + |
| 64 | + # Get pod logs |
| 65 | + logs = catalog_pod.log(container="catalog") |
| 66 | + |
| 67 | + # Define regex patterns for extraction |
| 68 | + patterns = { |
| 69 | + "redhat_ai_validated_models": r"redhat_ai_validated_models: loaded (\d+) models", |
| 70 | + "redhat_ai_models": r"redhat_ai_models: loaded (\d+) models", |
| 71 | + } |
| 72 | + |
| 73 | + # Extract counts |
| 74 | + model_counts = {} |
| 75 | + for key, pattern in patterns.items(): |
| 76 | + match = re.search(pattern, logs) |
| 77 | + if match: |
| 78 | + model_counts[key] = int(match.group(1)) |
| 79 | + else: |
| 80 | + LOGGER.warning(f"Pattern '{pattern}' not found in catalog pod logs") |
| 81 | + model_counts[key] = 0 # Default to 0 if not found |
| 82 | + |
| 83 | + LOGGER.info(f"Extracted model counts from catalog pod logs: {model_counts}") |
| 84 | + return model_counts |
| 85 | + |
| 86 | + |
| 87 | +@pytest.fixture(scope="session") |
| 88 | +def recreated_model_catalog_configmap( |
| 89 | + admin_client: DynamicClient, |
| 90 | +) -> ConfigMap: |
| 91 | + """ |
| 92 | + Session-scoped fixture that deletes the DEFAULT_CUSTOM_MODEL_CATALOG ConfigMap |
| 93 | + and waits for it to be automatically recreated, and cleans up catalog pod, to start with a fresh log |
| 94 | +
|
| 95 | + Returns: |
| 96 | + ConfigMap: The recreated ConfigMap instance |
| 97 | + """ |
| 98 | + namespace_name = py_config["model_registry_namespace"] |
| 99 | + # TODO: RHOAIENG-46741 would require changing this to look for configmaps based on label |
| 100 | + # Get the existing ConfigMap |
| 101 | + configmap = ConfigMap( |
| 102 | + name=DEFAULT_CUSTOM_MODEL_CATALOG, client=admin_client, namespace=namespace_name, ensure_exists=True |
| 103 | + ) |
| 104 | + |
| 105 | + LOGGER.info(f"Deleting ConfigMap {DEFAULT_CUSTOM_MODEL_CATALOG} to test recreation") |
| 106 | + |
| 107 | + # Delete the ConfigMap |
| 108 | + configmap.delete() |
| 109 | + |
| 110 | + LOGGER.info(f"ConfigMap {DEFAULT_CUSTOM_MODEL_CATALOG} deleted, waiting for recreation") |
| 111 | + |
| 112 | + # Wait for it to be recreated using TimeoutSampler |
| 113 | + recreated_configmap = ConfigMap( |
| 114 | + name=DEFAULT_CUSTOM_MODEL_CATALOG, |
| 115 | + client=admin_client, |
| 116 | + namespace=namespace_name, |
| 117 | + ) |
| 118 | + |
| 119 | + # Use TimeoutSampler to wait for recreation (2 minutes timeout) |
| 120 | + for sample in TimeoutSampler( |
| 121 | + wait_timeout=120, # 2 minutes |
| 122 | + sleep=5, |
| 123 | + func=lambda: recreated_configmap.exists, |
| 124 | + exceptions_dict={NotFoundError: []}, |
| 125 | + ): |
| 126 | + if sample: # ConfigMap exists |
| 127 | + break |
| 128 | + |
| 129 | + LOGGER.info(f"ConfigMap {DEFAULT_CUSTOM_MODEL_CATALOG} recreated successfully") |
| 130 | + wait_for_model_catalog_pod_ready_after_deletion(client=admin_client, model_registry_namespace=namespace_name) |
| 131 | + return recreated_configmap |
| 132 | + |
| 133 | + |
41 | 134 | @pytest.fixture() |
42 | 135 | def sparse_override_catalog_source( |
43 | 136 | request: pytest.FixtureRequest, |
|
0 commit comments