Skip to content

refactor: update keploy sdk version in pom - #11

Merged
Sarthak160 merged 1 commit into
mainfrom
Sarthak160-patch-1
Sep 9, 2022
Merged

Sarthak160 merged 1 commit into
mainfrom
Sarthak160-patch-1

Conversation

@Sarthak160

Copy link
Copy Markdown
Contributor

Pull Request Template

Description

Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.

Fixes # (issue)

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration

Additional Context (Please include any Screenshots/gifs if relevant)

...

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules
  • I have checked my code and corrected any misspellings
  • I have tagged the reviewers in a comment below incase my pull request is ready for a review
  • I have signed the commit message to agree to Developer Certificate of Origin (DCO) (to certify that you wrote or otherwise have the right to submit your contribution to the project.) by adding "--signoff" to my git commit command.

@Sarthak160
Sarthak160 merged commit 7d18b52 into main Sep 9, 2022
nehagup pushed a commit that referenced this pull request Sep 18, 2026
…L) (#149)

* Add spring-boot-product-catalog sample (Spring Boot + PostgreSQL)

A product-catalog REST API demonstrating Keploy replacing hand-written
API tests. Ships a committed test set of 57 cases and 190 Postgres mocks
under keploy/products-crud/, plus an app-only docker-compose.keploy.yml
that replays the full suite green with no database present.

- Full CRUD, category filters, inventory summary, stock adjustment
- Multi-stage Dockerfile (Temurin 21), docker-compose for record/replay
- Paths-scoped CI workflow: Maven build + end-to-end smoke test
- Listed as sample #11 in the root README

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

* Align 404 message with the recorded contract

The not-found message was 'Product not found with id: <id>', but the
committed GET/PUT/DELETE 404 tests assert body.message as 'Product <id>
not found' (only header.Date is noise). Restore the recorded wording so
the suite replays green as the README states, and add a guard comment so
the contract-sensitive string isn't reworded again.

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

* Address review: healthcheck, seed coverage, fail-loud readiness, atomic stock

- docker-compose.yml: add an app healthcheck (Actuator /health via curl) so
  'docker compose up --wait' blocks until the app is actually ready. Left the
  DB-absent docker-compose.keploy.yml alone, where a db health check would fail.
- seed.sh: exercise GET /summary and PATCH /{id}/stock (409 + 404) so the README's
  're-record picks them up' claim holds; fail loudly if the app never becomes ready
  instead of silently proceeding and exiting 0.
- ProductService/ProductRepository: make adjustStock an atomic guarded UPDATE so
  concurrent PATCHes can't lose an update or bypass the >= 0 guard. Scoped to the
  (un-recorded) stock path via a @Modifying query rather than @Version, which would
  change every INSERT/UPDATE and break the committed Postgres mocks.

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

* Use Actuator readiness probe for the app healthcheck

The aggregate /actuator/health endpoint runs the JDBC db indicator on every
poll (interval: 5s), which Keploy captures as extra Postgres mocks during
keploy record and bloats mocks.yaml. The readiness group (already enabled via
management.endpoint.health.probes.enabled) doesn't touch the DB, so it still
gives 'docker compose up --wait' a real ready-to-serve signal without polluting
the recorded capture.

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

* Address review: non-root image, workflow ordering, config + entity cleanup

- Dockerfile: run the JVM as a non-root 'spring' user.
- workflow: smoke now 'needs: build', so it doesn't rebuild and burn its timeout
  when the build has already failed.
- keploy.yml: drop the unused mongoPassword default (this app is Postgres-only).
- Product: remove the setCreatedAt setter; createdAt is @PrePersist-assigned on an
  updatable=false column, so a setter is silently dropped on save and misleads callers.
- seed.sh: fail loudly in create() when the POST fails or returns no id, instead of
  appending an empty id and corrupting later phases.

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

* Adopt classic spring-boot-starter-web / -test; harden seed.sh with set -e

- pom.xml: use spring-boot-starter-web and the aggregate spring-boot-starter-test
  instead of the 4.x modular starters. Both resolve on 4.1.0 (verified), but the
  classic starters are the conventional choice for a sample; -web still brings
  embedded Tomcat (tomcat-embed-core 11.0.22) + spring-webmvc.
- seed.sh: enable 'set -e' so a failure in any phase (not just create()) aborts
  loudly. Hardened id_of to 'grep -m1' (no downstream head -> no SIGPIPE) so the
  pipeline stays clean under -e + pipefail, and guarded the id extraction with
  '|| true' to preserve the friendly no-id error.

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

* Address review: 404-vs-409 on stock race, type-mismatch handler, drop dead test

- ProductService.adjustStock: on a 0-row update, re-check existsById so a product
  deleted concurrently between findById and the UPDATE returns 404, not a misleading 409.
- GlobalExceptionHandler: handle MethodArgumentTypeMismatchException so a non-numeric
  path variable (/api/products/abc) returns the uniform {status,error,message} 400 shape
  instead of Spring's default ProblemDetail.
- Remove the placeholder @SpringBootTest (it needs a live DB, so CI skipped it and it was
  dead code) and the now-unused spring-boot-starter-test dependency. The Keploy recorded
  suite is this sample's test coverage.

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

* Re-record suite: cover /summary + /{id}/stock, deterministic ordering, name length=120

Regenerates the Keploy test set against the updated app so all committed changes that
touch recorded state land together and replay stays green:

- Coverage: the suite now exercises all seven endpoints — adds GET /api/products/summary
  and PATCH /api/products/{id}/stock (restock, ship, 409 over-decrement, 404), closing the
  previously documented gap. 57 -> 63 test cases, 190 -> 214 Postgres mocks.
- Determinism: list/filter/summary queries now use an explicit ORDER BY id
  (findByCategoryIgnoreCaseOrderByIdAsc / findAll(Sort.by("id"))), so re-records reproduce
  a stable row order instead of Postgres heap order.
- Schema: name column is length = 120, matching the @SiZe(max = 120) validation constraint;
  the regenerated CREATE-table mock reflects it, so the DB-absent replay still starts clean.
- README updated for the new counts and full-coverage note.

Verified green both ways: 'keploy test' (real DB) and the DB-absent docker-compose.keploy.yml
replay both report Total: 63  Passed: 63  Failed: 0.

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

* Housekeeping: ignoreOrdering=false (ordering now deterministic), refresh seed.sh comment

- keploy.yml: set ignoreOrdering to false. List/filter/summary responses are now sorted
  by id (and the summary's category rollup + low-stock list are built in that stable
  order), so there is no non-deterministic ordering left for Keploy to tolerate. Verified
  the DB-absent replay still passes 63/63 under strict ordering.
- seed.sh: update the stale header comment (~50 -> ~60+ cases) and mention the summary,
  stock, and 409 paths it now drives.

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

* Keep mocks.yaml committed: drop auto-added /*/mocks.yaml from keploy/.gitignore

The keploy tooling re-adds this ignore on each run, but this sample commits mocks.yaml
on purpose (it's what makes the DB-absent replay self-contained), so the ignore is removed
to keep the config coherent.

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

* Handle HttpMessageNotReadableException for the uniform 400 error shape

A malformed/unparseable JSON body (e.g. {"name": }, truncated payload) threw
HttpMessageNotReadableException, which bypassed the advice and fell through to Spring's
default error shape. Add a handler so it returns the same {status, error, message} 400 as
every other error path. Not exercised by the recorded suite (seed.sh always sends
well-formed JSON), so it doesn't affect the committed replay.

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

* Complete the uniform error contract + fix README record metadata

Finding 1 (415): add HttpMediaTypeNotSupportedException handler so a missing/wrong
Content-Type returns the uniform {status,error,message} 415 instead of Spring's default.

Also close the rest of the same gap pattern in one pass so every error path is uniform:
- HttpRequestMethodNotSupportedException -> 405 (e.g. POST /api/products/{id})
- NoResourceFoundException -> 404 (unknown path)
- a catch-all Exception handler -> 500 (logged, generic message) as the backstop, so no
  exception can ever fall through to Spring's default error shape again.
None of these paths are in the recorded suite (specific 404/409/400 handlers still win for
the recorded traffic), so the committed replay is unaffected.

Finding 2: README keploy record --metadata description now matches the committed
config.yaml (adds summary + stock + validation).

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

* Handle HttpMediaTypeNotAcceptableException as body-less 406

The catch-all Exception handler from e9550a0 was swallowing
HttpMediaTypeNotAcceptableException (thrown when Spring can't render an error-response
body in the client's requested Accept format, e.g. an error hit with Accept:
application/xml), turning a correct 406 into a 500. Add an explicit handler that returns
a body-less 406 — the body is exactly what can't be negotiated, so it must not carry one,
otherwise it recurses back into the catch-all. Recorded suite unaffected (all 63 cases
send Accept: */*, which accepts JSON, so replay never reaches this path).

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

* Give custom exceptions a @ResponseStatus fallback so unwritable-body errors resolve correctly

When a client sends an un-negotiable Accept (e.g. application/xml) on an error path, the
@ExceptionHandler runs and builds its JSON body, but the write fails with
HttpMediaTypeNotAcceptableException. Spring does not re-enter @ExceptionHandler resolution
for an exception raised inside exception handling, so the original ResourceNotFoundException
/ InsufficientStockException propagated to the container as a 500.

Spring's built-in exceptions implement ErrorResponse and self-resolve body-lessly in this
case; our custom RuntimeExceptions had no fallback. Annotating them with @ResponseStatus
lets ResponseStatusExceptionResolver answer with the right status (404 / 409) body-lessly.
The @ExceptionHandler still wins for normal requests, so the uniform {status,error,message}
body — and the recorded 63-case suite (all Accept: */*) — is unchanged.

Also drop handleNotAcceptable: it never fired (the write failure isn't re-entrant), and
success-path 406 is already produced by Spring's built-in negotiation.

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>

---------

Signed-off-by: dhananjay6561 <dhananjayaggarwal6561@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant