Skip to content

Layers -13 Switch to Delete layer api for cleanup in tests#1846

Open
bhanvimenghani wants to merge 7 commits intokruize:mvp_demofrom
bhanvimenghani:del_layers_for_cleanup
Open

Layers -13 Switch to Delete layer api for cleanup in tests#1846
bhanvimenghani wants to merge 7 commits intokruize:mvp_demofrom
bhanvimenghani:del_layers_for_cleanup

Conversation

@bhanvimenghani
Copy link
Copy Markdown
Contributor

@bhanvimenghani bhanvimenghani commented Mar 10, 2026

Description

This pr is on top of 1826 pr. In this PR we are switching over to make use of delete layer functionality in already existing layer related tests.

Fixes # (issue)

Type of change

  • Bug fix
  • New feature
  • Docs update
  • Breaking change (What changes might users need to make in their application due to this PR?)
  • Requires DB changes

How has this been tested?

Please describe the tests that were run to verify your changes and steps to reproduce. Please specify any test configuration required.

  • New Test X
  • Functional testsuite

Test Configuration

  • Kubernetes clusters tested on:

Checklist 🎯

  • Followed coding guidelines
  • Comments added
  • Dependent changes merged
  • Documentation updated
  • Tests added or updated

Additional information

Include any additional information such as links, test results, screenshots here

Summary by Sourcery

Add full CRUD support for layer resources via REST APIs and update tests to use the new deleteLayer endpoint for cleanup.

New Features:

  • Expose updateLayer and deleteLayer REST endpoints for managing existing layers.
  • Return structured JSON responses for all layer API success and error cases.

Bug Fixes:

  • Validate empty or null request bodies and null elements in arrays when creating or updating layers to prevent invalid layer definitions.

Enhancements:

  • Extend LayerService to support update and delete operations, including query parameter validation, detailed error handling, and appropriate HTTP status codes.
  • Add DAO methods and database queries for updating and deleting layer records, with corresponding metrics for DB operations.
  • Refine create-layer success handling to accept a custom HTTP status code while preserving the view-layers hint for create operations.

Tests:

  • Replace direct DB layer cleanup in tests with calls to the deleteLayer REST API helper, ensuring test cleanup goes through the public API.

@bhanvimenghani bhanvimenghani self-assigned this Mar 10, 2026
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Mar 10, 2026

Reviewer's Guide

Adds full CRUD support for Layer entities via REST APIs, standardizes JSON responses and error handling, introduces DB update/delete methods with metrics, and updates tests to use the new Delete Layer API instead of direct DB cleanup.

Sequence diagram for the Delete Layer REST API

sequenceDiagram
    actor Client
    participant LayerService
    participant ExperimentDAOImpl
    participant Database

    Client->>LayerService: HTTP DELETE /deleteLayer?name=layerName
    LayerService->>LayerService: validate layerName param
    alt invalid layerName
        LayerService-->>Client: 400 JSON error INVALID_LAYER_NAME
    else valid layerName
        LayerService->>LayerService: validate query params against DELETE_LAYERS_QUERY_PARAMS_SUPPORTED
        alt invalid query params
            LayerService-->>Client: 400 JSON error INVALID_QUERY_PARAMS
        else valid params
            LayerService->>ExperimentDAOImpl: loadLayerByName(layerName)
            ExperimentDAOImpl->>Database: SELECT_FROM_LAYER_BY_NAME
            Database-->>ExperimentDAOImpl: existingLayers
            alt layer not found
                LayerService-->>Client: 404 JSON error DELETE_LAYER_ENTRY_NOT_FOUND_WITH_NAME
            else layer exists
                LayerService->>ExperimentDAOImpl: deleteLayerByName(layerName)
                ExperimentDAOImpl->>Database: DELETE_FROM_LAYER_BY_NAME
                Database-->>ExperimentDAOImpl: deletedCount
                alt delete success
                    LayerService-->>Client: 200 JSON success DELETE_LAYER_SUCCESS_MSG
                else delete failed
                    LayerService-->>Client: 500 JSON error with DB message
                end
            end
        end
    end
Loading

Sequence diagram for the Update Layer REST API

sequenceDiagram
    actor Client
    participant LayerService
    participant ExperimentDAOImpl
    participant Database

    Client->>LayerService: HTTP PUT /updateLayer?name=layerName with JSON body
    LayerService->>LayerService: validate layerName param
    alt invalid layerName
        LayerService-->>Client: 400 JSON error INVALID_LAYER_NAME
    else valid layerName
        LayerService->>LayerService: validate query params against UPDATE_LAYERS_QUERY_PARAMS_SUPPORTED
        alt invalid query params
            LayerService-->>Client: 400 JSON error INVALID_QUERY_PARAMS
        else valid params
            LayerService->>LayerService: read request body
            alt empty body
                LayerService-->>Client: 400 JSON error INVALID_LAYER_JSON
            else non empty body
                LayerService->>LayerService: convertInputJSONToCreateLayer(inputData)
                alt converter throws IllegalArgumentException or JSONException
                    LayerService-->>Client: 400 JSON error VALIDATION_FAILED or MISSING_REQUIRED_FIELD
                else conversion ok
                    LayerService->>LayerService: compare URL layerName with kruizeLayer.layerName
                    alt mismatch
                        LayerService-->>Client: 400 JSON error LAYER_NAME_MISMATCH
                    else match
                        LayerService->>LayerService: validate(kruizeLayer) via LayerValidation
                        alt validation fails
                            LayerService-->>Client: 400 JSON error VALIDATION_FAILED
                        else validation ok
                            LayerService->>ExperimentDAOImpl: loadLayerByName(kruizeLayer.layerName)
                            ExperimentDAOImpl->>Database: SELECT_FROM_LAYER_BY_NAME
                            Database-->>ExperimentDAOImpl: existingLayers
                            alt not found
                                LayerService-->>Client: 404 JSON error LAYER_NOT_FOUND
                            else found
                                LayerService->>LayerService: convertToLayerEntry(kruizeLayer)
                                LayerService->>ExperimentDAOImpl: updateLayerToDB(layerEntry)
                                ExperimentDAOImpl->>Database: merge(kruizeLayerEntry)
                                Database-->>ExperimentDAOImpl: update result
                                alt update success
                                    LayerService-->>Client: 200 JSON success UPDATE_LAYER_SUCCESS_MSG
                                else update failed
                                    LayerService-->>Client: 500 JSON error UPDATE_LAYER_TO_DB_FAILURE
                                end
                            end
                        end
                    end
                end
            end
        end
    end
Loading

Updated class diagram for LayerService, ExperimentDAO, and related types

classDiagram
    class LayerService {
        +doPost(HttpServletRequest request, HttpServletResponse response) void
        +doGet(HttpServletRequest request, HttpServletResponse response) void
        +doPut(HttpServletRequest request, HttpServletResponse response) void
        +doDelete(HttpServletRequest request, HttpServletResponse response) void
        -convertToLayerEntry(KruizeLayer kruizeLayer) KruizeLMLayerEntry
        -sendSuccessResponse(HttpServletResponse response, String message, int httpStatusCode) void
        -sendErrorResponse(HttpServletResponse response, Exception e, int httpStatusCode, String errorMsg) void
        -createGsonObject() Gson
        -sendJsonResponse(HttpServletResponse response, String message, int statusCode, String status) void
    }

    class ExperimentDAO {
        <<interface>>
        +addLayerToDB(KruizeLMLayerEntry kruizeLayerEntry) ValidationOutputData
        +updateLayerToDB(KruizeLMLayerEntry kruizeLayerEntry) ValidationOutputData
        +deleteLayerByName(String layerName) ValidationOutputData
        +loadAllLayers() List~KruizeLMLayerEntry~
        +loadLayerByName(String layerName) List~KruizeLMLayerEntry~
    }

    class ExperimentDAOImpl {
        +addLayerToDB(KruizeLMLayerEntry kruizeLayerEntry) ValidationOutputData
        +updateLayerToDB(KruizeLMLayerEntry kruizeLayerEntry) ValidationOutputData
        +deleteLayerByName(String layerName) ValidationOutputData
        +loadAllLayers() List~KruizeLMLayerEntry~
        +loadLayerByName(String layerName) List~KruizeLMLayerEntry~
    }

    class MetricsConfig {
        +timerAddLayerDB Timer
        +timerLoadAllLayers Timer
        +timerLoadLayerByName Timer
        +timerUpdateLayerDB Timer
        +timerDeleteLayerDB Timer
        +timerBAddLayerDB Timer_Builder
        +timerBLoadAllLayers Timer_Builder
        +timerBLoadLayerByName Timer_Builder
        +timerBUpdateLayerDB Timer_Builder
        +timerBDeleteLayerDB Timer_Builder
    }

    class KruizeSupportedTypes {
        +CREATE_LAYERS_QUERY_PARAMS_SUPPORTED Set~String~
        +LIST_LAYERS_QUERY_PARAMS_SUPPORTED Set~String~
        +UPDATE_LAYERS_QUERY_PARAMS_SUPPORTED Set~String~
        +DELETE_LAYERS_QUERY_PARAMS_SUPPORTED Set~String~
    }

    class AnalyzerErrorConstants_UpdateLayerAPI {
        +INVALID_LAYER_NAME String
        +LAYER_NOT_FOUND String
        +INVALID_LAYER_JSON String
        +UPDATE_LAYER_TO_DB_FAILURE String
        +LAYER_NAME_MISMATCH String
        +VALIDATION_FAILED String
        +UNEXPECTED_ERROR String
        +INVALID_QUERY_PARAMS String
        +MISSING_REQUIRED_FIELD String
    }

    class AnalyzerErrorConstants_DeleteLayerAPI {
        +DELETE_LAYER_ENTRY_NOT_FOUND_WITH_NAME String
        +DELETE_LAYER_ENTRY_ERROR_MSG String
        +INVALID_LAYER_NAME String
        +UNEXPECTED_ERROR String
        +INVALID_QUERY_PARAMS String
    }

    class KruizeConstants_LayerAPIMessages {
        +CREATE_LAYER_SUCCESS_MSG String
        +UPDATE_LAYER_SUCCESS_MSG String
        +DELETE_LAYER_SUCCESS_MSG String
        +VIEW_LAYERS_MSG String
        +ADD_LAYER_TO_DB String
        +UPDATE_LAYER_TO_DB String
        +DELETE_LAYER_FROM_DB String
        +LOAD_LAYER_FAILURE String
        +LOAD_ALL_LAYERS_FAILURE String
    }

    class ServerContext {
        +CREATE_LAYER String
        +LIST_LAYERS String
        +UPDATE_LAYER String
        +DELETE_LAYER String
    }

    class AnalyzerConstants {
        +LAYER_NAME String
    }

    LayerService ..> ExperimentDAO : uses
    ExperimentDAOImpl ..|> ExperimentDAO
    LayerService ..> MetricsConfig : uses metrics
    LayerService ..> KruizeSupportedTypes : uses query param sets
    LayerService ..> AnalyzerErrorConstants_UpdateLayerAPI : uses error messages
    LayerService ..> AnalyzerErrorConstants_DeleteLayerAPI : uses error messages
    LayerService ..> KruizeConstants_LayerAPIMessages : uses success messages
    Analyzer ..> LayerService : registers servlet
    ServerContext ..> LayerService : endpoint paths
Loading

File-Level Changes

Change Details Files
Extend Layer REST API to support update and delete operations with consistent JSON responses and validation.
  • Document LayerService as supporting create, list, update, and delete operations
  • Validate non-empty request body in create-layer POST and return 400 with structured error on empty payload
  • Adjust create-layer success response to accept a status code and use HTTP 201 Created
  • Handle IllegalArgumentException from JSON converter as a 400 validation error
  • Implement doPut for /updateLayer: validate query params, body, name consistency, run LayerValidation, ensure layer exists, update DB, and return structured JSON responses
  • Implement doDelete for /deleteLayer: validate query params, ensure layer exists, delete by name from DB, and return structured JSON responses
  • Refactor success and error responses to use a shared sendJsonResponse helper, making both success and error replies JSON with message/httpcode/status
src/main/java/com/autotune/analyzer/services/LayerService.java
Add DAO and DB-layer support for updating and deleting layers, plus related metrics and SQL constants.
  • Extend ExperimentDAO interface with updateLayerToDB and deleteLayerByName methods
  • Implement updateLayerToDB using Hibernate merge, transaction handling, metrics timer, and structured ValidationOutputData result
  • Implement deleteLayerByName using HQL delete by layer name, with transaction handling and error logging
  • Add DELETE_FROM_LAYER_BY_NAME query constant
  • Introduce Micrometer timers and builders for update/delete layer DB operations in MetricsConfig
src/main/java/com/autotune/database/dao/ExperimentDAO.java
src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java
src/main/java/com/autotune/database/helper/DBConstants.java
src/main/java/com/autotune/utils/MetricsConfig.java
Improve layer JSON conversion and error constants for update/delete APIs.
  • Add AnalyzerErrorConstants.UpdateLayerAPI and DeleteLayerAPI groups with specific error messages for invalid names, JSON, validation failures, missing fields, and unexpected errors
  • Tighten Converters.convertInputJSONToCreateLayer by rejecting null elements in queries, label, and tunables arrays via IllegalArgumentException so callers can surface clearer validation errors
src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java
src/main/java/com/autotune/analyzer/serviceObjects/Converters.java
Wire new Layer endpoints into the server context and analyzer servlet mappings, and define the shared layer-name query param.
  • Register LayerService to handle /updateLayer and /deleteLayer endpoints in Analyzer.addServlets
  • Add ServerContext.UPDATE_LAYER and ServerContext.DELETE_LAYER URL paths
  • Introduce AnalyzerConstants.LAYER_NAME constant ('name') for query parameter usage
src/main/java/com/autotune/analyzer/Analyzer.java
src/main/java/com/autotune/utils/ServerContext.java
src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java
Switch tests and helpers from direct DB deletion via kubectl/psql to using the Delete Layer REST API.
  • Replace delete_layer_from_db helper with delete_layer that calls DELETE /deleteLayer with 'name' query parameter and logs request/response
  • Update test fixtures and tests for create/list layer REST APIs to use delete_layer() for pre/post cleanup instead of DB-level deletion
tests/scripts/helpers/kruize.py
tests/scripts/local_monitoring_tests/rest_apis/test_create_layer.py
tests/scripts/local_monitoring_tests/rest_apis/test_list_layers.py
Extend layer-related constants with messages for update/delete operations.
  • Add success and logging messages for update and delete layer operations in KruizeConstants.LayerAPIMessages
src/main/java/com/autotune/utils/KruizeConstants.java

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 5 issues, and left some high level feedback:

  • In LayerService, the query-parameter validation logic in doPut and doDelete is nearly identical and could be factored into a shared helper to reduce duplication and keep the supported-params checks consistent.
  • sendJsonResponse creates a new Gson instance on every call; consider reusing a single preconfigured Gson field to avoid repeated allocations and keep serialization configuration centralized.
  • In ExperimentDAOImpl.updateLayerToDB and deleteLayerByName, the exception handling still uses e.printStackTrace() alongside structured logging and does not consistently check tx.isActive() before rollback in all paths; cleaning this up and aligning rollback and logging behavior would make DB error handling more robust and less noisy.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `LayerService`, the query-parameter validation logic in `doPut` and `doDelete` is nearly identical and could be factored into a shared helper to reduce duplication and keep the supported-params checks consistent.
- `sendJsonResponse` creates a new `Gson` instance on every call; consider reusing a single preconfigured `Gson` field to avoid repeated allocations and keep serialization configuration centralized.
- In `ExperimentDAOImpl.updateLayerToDB` and `deleteLayerByName`, the exception handling still uses `e.printStackTrace()` alongside structured logging and does not consistently check `tx.isActive()` before rollback in all paths; cleaning this up and aligning rollback and logging behavior would make DB error handling more robust and less noisy.

## Individual Comments

### Comment 1
<location path="src/main/java/com/autotune/analyzer/services/LayerService.java" line_range="117-120" />
<code_context>
                 sendErrorResponse(response, null, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                         String.format(AnalyzerErrorConstants.APIErrors.CreateLayerAPI.ADD_LAYER_TO_DB_FAILURE, addedToDB.getMessage()));
             }
+        } catch (IllegalArgumentException e) {
+            // Handle validation errors from converter (e.g., null elements in arrays)
+            LOGGER.error("Invalid input in layer creation request: {}", e.getMessage());
+            sendErrorResponse(response, e, HttpServletResponse.SC_BAD_REQUEST,
+                    "Validation failed: " + e.getMessage());
         } catch (MonitoringAgentNotSupportedException e) {
</code_context>
<issue_to_address>
**🚨 suggestion (security):** Align create-layer validation errors with existing error constants instead of hardcoding the message.

In the `IllegalArgumentException` branch, the error body is currently `

Suggested implementation:

```java
        } catch (IllegalArgumentException e) {
            // Handle validation errors from converter (e.g., null elements in arrays)
            LOGGER.error("Invalid input in layer creation request: {}", e.getMessage());
            sendErrorResponse(response, e, HttpServletResponse.SC_BAD_REQUEST,
                    String.format(AnalyzerErrorConstants.APIErrors.CreateLayerAPI.CREATE_LAYER_INVALID_REQUEST, e.getMessage()));
        } catch (MonitoringAgentNotSupportedException e) {
            LOGGER.error("Failed to create layer: {}", e.getMessage());
            sendErrorResponse(response, new Exception(e), HttpServletResponse.SC_BAD_REQUEST,
                    String.format(AnalyzerErrorConstants.APIErrors.CreateLayerAPI.CREATE_LAYER_INVALID_REQUEST, e.getMessage()));

```

1. Ensure that `AnalyzerErrorConstants.APIErrors.CreateLayerAPI.CREATE_LAYER_INVALID_REQUEST` exists and matches the formatting used here (e.g., `"Validation failed: %s"`).  
2. If a differently named constant already exists for create-layer validation errors, replace `CREATE_LAYER_INVALID_REQUEST` in the snippet with that existing constant instead of introducing a new one.  
3. If `AnalyzerErrorConstants` is not already imported in this file, confirm that the import is present at the top of `LayerService.java`.
</issue_to_address>

### Comment 2
<location path="src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java" line_range="710-715" />
<code_context>
+            tx.commit();
+            validationOutputData.setSuccess(true);
+            statusValue = "success";
+        } catch (HibernateException e) {
+            LOGGER.error("Not able to update layer due to: {}", e.getMessage(), e);
+            if (tx != null && tx.isActive()) tx.rollback();
+            e.printStackTrace();
+            validationOutputData.setSuccess(false);
+            validationOutputData.setMessage(e.getMessage());
+        } catch (Exception e) {
+            LOGGER.error("Not able to update layer due to: {}", e.getMessage(), e);
</code_context>
<issue_to_address>
**suggestion:** Avoid redundant `printStackTrace()` and unify exception handling/logging in `updateLayerToDB`.

In `updateLayerToDB`, both catch blocks already log the exception (including the stack trace via the logger), so the extra `e.printStackTrace()` in the `HibernateException` branch is redundant and noisy. You can drop that call and consider merging the two catch blocks into a single one that logs once and sets `validationOutputData` consistently.
</issue_to_address>

### Comment 3
<location path="src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java" line_range="738-689" />
<code_context>
+    public ValidationOutputData deleteLayerByName(String layerName) {
</code_context>
<issue_to_address>
**suggestion:** Instrument `deleteLayerByName` with the new DB timers to keep metrics consistent.

You’ve added `timerDeleteLayerDB` and `timerBDeleteLayerDB` in `MetricsConfig`, but `deleteLayerByName` doesn’t use them. Please wrap the delete logic in a `Timer.Sample` and record the result via `MetricsConfig.timerDeleteLayerDB` with the appropriate status tag, matching the pattern used in `addLayerToDB`/`updateLayerToDB`.

Suggested implementation:

```java
    @Override
    public ValidationOutputData deleteLayerByName(String layerName) {
        // Start DB metrics timer for deleteLayerByName
        Timer.Sample sample = Timer.start(MetricsConfig.meterRegistry);
        String deleteStatus = KruizeConstants.METRICS.TIMER_METRIC_STATUS_SUCCESS;
        ValidationOutputData validationOutputData = new ValidationOutputData(false, null, null);

```

To fully implement the metrics instrumentation consistent with `addLayerToDB` / `updateLayerToDB`, you should also:

1. In the `catch` block(s) inside `deleteLayerByName`, set `deleteStatus` to the failure constant you use elsewhere (for example `KruizeConstants.METRICS.TIMER_METRIC_STATUS_FAILURE`) before handling/logging the exception.
2. In a `finally` block that always executes (outside your inner `try { tx = session.beginTransaction(); ... }` but inside the `try (Session session = ...)`), stop and record the timer using the same pattern as the other DB methods, for example something along the lines of:
   ```java
   MetricsConfig.recordDBTimer(MetricsConfig.timerDeleteLayerDB, sample, deleteStatus);
   ```
   or whatever helper / tagging pattern you already use for `addLayerToDB` and `updateLayerToDB`.
3. Ensure the following imports are present at the top of the file, adjusted to your actual package structure:
   ```java
   import io.micrometer.core.instrument.Timer;
   import com.autotune.utils.MetricsConfig;
   import com.autotune.utils.KruizeConstants;
   ```
4. Mirror any status tag keys/values (`status`, `success`, `failure`, etc.) exactly as used in the existing DB-layer methods so that metrics remain consistent across operations.
</issue_to_address>

### Comment 4
<location path="tests/scripts/local_monitoring_tests/rest_apis/test_create_layer.py" line_range="40" />
<code_context>
     # Cleanup before test - clean up all known layer names
     for layer_name in CLEANUP_LAYER_NAMES:
-        delete_layer_from_db(layer_name)
+        delete_layer(layer_name)
     yield
     # Cleanup after test - clean up all known layer names
</code_context>
<issue_to_address>
**issue (testing):** Extend create-layer tests to cover new validation cases (empty body and null elements in arrays)

The new validation logic in `convertInputJSONToCreateLayer` and `LayerService.doPost` (empty/whitespace bodies and `null` elements in `queries`, `label`, and `tunables`) isn’t covered by the current tests. Please add targeted tests, e.g.:
- Empty request body to `/createLayer` → expect 400 with `CreateLayerAPI.INVALID_LAYER_JSON`.
- Valid JSON except `queries` contains a `null` element → expect 400 and the `IllegalArgumentException` message.
- Similar cases for `label` and `tunables` containing `null`.
This will verify the new validations and help prevent regressions in JSON parsing behavior.
</issue_to_address>

### Comment 5
<location path="tests/scripts/local_monitoring_tests/rest_apis/test_create_layer.py" line_range="134" />
<code_context>
         layer_name = input_json['layer_name']

     # Cleanup before test to ensure clean state
-    delete_layer_from_db(layer_name)
+    delete_layer(layer_name)
</code_context>
<issue_to_address>
**suggestion (testing):** Have cleanup logic assert on delete API response instead of ignoring failures

Cleanup now depends on `delete_layer(layer_name)` but its result isn’t checked, so failed deletes (wrong URL/params, server errors) could leave state dirty and cause flaky tests. Please move this into a shared helper/fixture that calls `delete_layer(layer_name)` and asserts the response `status_code` is 200 (deleted) or 404 (already absent), failing otherwise, so delete issues surface directly instead of as indirect test failures.

Suggested implementation:

```python
def ensure_layer_deleted(layer_name: str) -> None:
    """
    Ensure a layer is deleted via the delete API.

    Asserts that the delete response status code is either:
      * 200 - layer successfully deleted
      * 404 - layer already absent
    Any other status code fails the test so cleanup issues surface directly.
    """
    response = delete_layer(layer_name)
    assert response.status_code in (200, 404), (
        f"Failed to delete layer {layer_name!r}: "
        f"expected status 200 or 404, got {response.status_code}"
    )


@pytest.mark.layers

```

```python
    yield
    # Cleanup after test - clean up all known layer names
    for layer_name in CLEANUP_LAYER_NAMES:
        ensure_layer_deleted(layer_name)

```

```python
    yield
    # Cleanup after test - clean up all known layer names
    for layer_name in CLEANUP_LAYER_NAMES:
        ensure_layer_deleted(layer_name)

```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/main/java/com/autotune/analyzer/services/LayerService.java
Comment thread src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java
Comment thread src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java
Comment thread tests/scripts/local_monitoring_tests/rest_apis/test_create_layer.py Outdated
Comment thread tests/scripts/local_monitoring_tests/rest_apis/test_create_layer.py
@bhanvimenghani bhanvimenghani changed the title Switch to Delete layer api for cleanup in tests Layers -13 Switch to Delete layer api for cleanup in tests Mar 12, 2026
@bhanvimenghani bhanvimenghani added this to the Kruize 0.11.0 Release milestone Apr 8, 2026
@bhanvimenghani bhanvimenghani moved this to Under Review in Monitoring Apr 8, 2026
@bhanvimenghani bhanvimenghani force-pushed the del_layers_for_cleanup branch from ba08c72 to 2f0c1d9 Compare April 21, 2026 18:03
Copy link
Copy Markdown
Member

@bharathappali bharathappali left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything else LGTM, except the sourcery comments in tests code. @bhanvimenghani please kindly address the sourcery review comments. Thanks!

@bhanvimenghani
Copy link
Copy Markdown
Contributor Author

Everything else LGTM, except the sourcery comments in tests code. @bhanvimenghani please kindly address the sourcery review comments. Thanks!

@bharathappali can you please take a look once again

Copy link
Copy Markdown
Member

@bharathappali bharathappali left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Under Review

Development

Successfully merging this pull request may close these issues.

2 participants