Skip to content

Conversation

@yzh119
Copy link
Collaborator

@yzh119 yzh119 commented Oct 20, 2025

📌 Description

This PR fixes the test suite broken by #1761 , which introduced checksum validation for downloaded artifacts.

Commit #1761 made the following breaking changes:

  • Renamed get_cubin_file_list() -> get_subdir_file_list()
  • Added checksums.txt download requirement for each cubin subdirectory

The test test_get_cubin_file_list was not updated accordingly, this PR updates tests/test_artifacts.py to align with the new API:

  • Update function import: Change from get_cubin_file_list to get_subdir_file_list
  • Handle tuple returns: Unpack (path, checksum) tuples to extract file paths
cubin_files = list(get_subdir_file_list())
cubin_file_paths = [path for path, _ in cubin_files]  # Extract paths only
  • Add checksums.txt mocks: Mock HTTP responses for checksums.txt files in all four subdirectories (FMHA, GEMM, BMM, DeepGEMM)
  • Update assertions: All assertions now check against cubin_file_paths instead of the raw tuple list
  • Add temporary directory: Use tmp_path fixture to simulate local cubin directory for checksum downloads

🔍 Related Issues

#1761

🚀 Pull Request Checklist

Thank you for contributing to FlashInfer! Before we review your pull request, please make sure the following items are complete.

✅ Pre-commit Checks

  • I have installed pre-commit by running pip install pre-commit (or used your preferred method).
  • I have installed the hooks with pre-commit install.
  • I have run the hooks manually with pre-commit run --all-files and fixed any reported issues.

If you are unsure about how to set up pre-commit, see the pre-commit documentation.

🧪 Tests

  • Tests have been added or updated as needed.
  • All tests are passing (unittest, etc.).

Reviewer Notes

cc @jimmyzho @hypdeb

Summary by CodeRabbit

  • Tests

    • Expanded test coverage for artifact file handling with enhanced subdirectory support.
  • Refactor

    • Reorganized public API for artifact file retrieval to improve functionality.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @yzh119, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves a critical issue where the test_artifacts.py test suite was failing due to recent modifications in how FlashInfer handles artifact downloads and checksum validation. The changes ensure the test correctly interacts with the updated artifact API, including handling new function signatures and the requirement for checksums.txt files, thereby restoring the integrity of the artifact testing process.

Highlights

  • Test Suite Fix: Addresses a broken test suite (test_artifacts.py) caused by recent changes in artifact checksum validation and API renaming.
  • API Alignment: Updates the test to use the new get_subdir_file_list function and correctly handle its tuple return format (path, checksum).
  • Checksum Mocking: Introduces comprehensive mocking for checksums.txt files across all relevant cubin subdirectories (FMHA, GEMM, BMM, DeepGEMM) to simulate artifact downloads.
  • Temporary Directory: Utilizes a temporary directory fixture (tmp_path) for local cubin directory simulation during checksum downloads.
  • Test Script Update: Adds the test_artifacts.py test to the task_jit_run_tests_part4.sh script to ensure it runs as part of the CI.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request successfully fixes the broken test_artifacts.py unit test by updating it to align with the new API for handling artifacts, including the introduction of checksum validation. The changes correctly adapt the test to the renamed function, handle the new tuple return format, and mock the necessary checksums.txt files. My review includes a couple of suggestions to refactor the test code to reduce duplication, which will improve its long-term maintainability.

Comment on lines +321 to +345
# Add mock responses for checksums.txt files
fmha_checksums_url = safe_urljoin(
test_cubin_repository,
safe_urljoin(artifact_paths.TRTLLM_GEN_FMHA, "checksums.txt"),
)
responses.add(responses.GET, fmha_checksums_url, body=checksums_fmha, status=200)

gemm_checksums_url = safe_urljoin(
test_cubin_repository,
safe_urljoin(artifact_paths.TRTLLM_GEN_GEMM, "checksums.txt"),
)
responses.add(responses.GET, gemm_checksums_url, body=checksums_gemm, status=200)

bmm_checksums_url = safe_urljoin(
test_cubin_repository,
safe_urljoin(artifact_paths.TRTLLM_GEN_BMM, "checksums.txt"),
)
responses.add(responses.GET, bmm_checksums_url, body=checksums_bmm, status=200)

deepgemm_checksums_url = safe_urljoin(
test_cubin_repository, safe_urljoin(artifact_paths.DEEPGEMM, "checksums.txt")
)
responses.add(
responses.GET, deepgemm_checksums_url, body=checksums_deepgemm, status=200
)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The setup for mock responses for checksums.txt files is repetitive. You can refactor this by using a dictionary to map artifact paths to their checksum data and then loop through it to add the responses. This will make the code more concise and easier to maintain if more subdirectories are added in the future.

Suggested change
# Add mock responses for checksums.txt files
fmha_checksums_url = safe_urljoin(
test_cubin_repository,
safe_urljoin(artifact_paths.TRTLLM_GEN_FMHA, "checksums.txt"),
)
responses.add(responses.GET, fmha_checksums_url, body=checksums_fmha, status=200)
gemm_checksums_url = safe_urljoin(
test_cubin_repository,
safe_urljoin(artifact_paths.TRTLLM_GEN_GEMM, "checksums.txt"),
)
responses.add(responses.GET, gemm_checksums_url, body=checksums_gemm, status=200)
bmm_checksums_url = safe_urljoin(
test_cubin_repository,
safe_urljoin(artifact_paths.TRTLLM_GEN_BMM, "checksums.txt"),
)
responses.add(responses.GET, bmm_checksums_url, body=checksums_bmm, status=200)
deepgemm_checksums_url = safe_urljoin(
test_cubin_repository, safe_urljoin(artifact_paths.DEEPGEMM, "checksums.txt")
)
responses.add(
responses.GET, deepgemm_checksums_url, body=checksums_deepgemm, status=200
)
# Add mock responses for checksums.txt files
checksum_data = {
artifact_paths.TRTLLM_GEN_FMHA: checksums_fmha,
artifact_paths.TRTLLM_GEN_GEMM: checksums_gemm,
artifact_paths.TRTLLM_GEN_BMM: checksums_bmm,
artifact_paths.DEEPGEMM: checksums_deepgemm,
}
for path, body in checksum_data.items():
url = safe_urljoin(
test_cubin_repository, safe_urljoin(path, "checksums.txt")
)
responses.add(responses.GET, url, body=body, status=200)

Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like a good suggestion

Comment on lines 353 to 381
for expected_file_name in expected_gemm_cubin_files:
expected_file_path = artifact_paths.TRTLLM_GEN_GEMM + "/" + expected_file_name
assert any(expected_file_path in url for url in cubin_files), (
expected_file_path = safe_urljoin(
artifact_paths.TRTLLM_GEN_GEMM, expected_file_name
)
assert any(expected_file_path in url for url in cubin_file_paths), (
f"Expected cubin file '{expected_file_path}' not found in cubin file list"
)

for expected_file_name in expected_fmha_cubin_files:
expected_file_path = artifact_paths.TRTLLM_GEN_FMHA + "/" + expected_file_name
assert any(expected_file_path in url for url in cubin_files), (
expected_file_path = safe_urljoin(
artifact_paths.TRTLLM_GEN_FMHA, expected_file_name
)
assert any(expected_file_path in url for url in cubin_file_paths), (
f"Expected cubin file '{expected_file_path}' not found in cubin file list"
)

for expected_file_name in expected_bmm_cubin_files:
expected_file_path = artifact_paths.TRTLLM_GEN_BMM + "/" + expected_file_name
assert any(expected_file_path in url for url in cubin_files), (
expected_file_path = safe_urljoin(
artifact_paths.TRTLLM_GEN_BMM, expected_file_name
)
assert any(expected_file_path in url for url in cubin_file_paths), (
f"Expected cubin file '{expected_file_path}' not found in cubin file list"
)

for expected_file_name in expected_deepgemm_cubin_files:
expected_file_path = artifact_paths.DEEPGEMM + "/" + expected_file_name
assert any(expected_file_path in url for url in cubin_files), (
expected_file_path = safe_urljoin(artifact_paths.DEEPGEMM, expected_file_name)
assert any(expected_file_path in url for url in cubin_file_paths), (
f"Expected cubin file '{expected_file_path}' not found in cubin file list"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The assertion logic to check for expected cubin files is duplicated across four loops. This can be consolidated into a single loop by using a dictionary that maps artifact paths to their corresponding expected file sets. This refactoring will improve code readability and maintainability.

    assertion_data = {
        artifact_paths.TRTLLM_GEN_GEMM: expected_gemm_cubin_files,
        artifact_paths.TRTLLM_GEN_FMHA: expected_fmha_cubin_files,
        artifact_paths.TRTLLM_GEN_BMM: expected_bmm_cubin_files,
        artifact_paths.DEEPGEMM: expected_deepgemm_cubin_files,
    }

    for path, expected_files in assertion_data.items():
        for expected_file_name in expected_files:
            expected_file_path = safe_urljoin(path, expected_file_name)
            assert any(expected_file_path in url for url in cubin_file_paths), (
                f"Expected cubin file '{expected_file_path}' not found in cubin file list"
            )

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 20, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

The changes add a new test invocation to the test suite and refactor the artifacts module API. The function get_cubin_file_list() is renamed to get_subdir_file_list(), with corresponding test logic updated to use the new function and integrate subdirectory-based file listing with checksums validation.

Changes

Cohort / File(s) Summary
Test Suite Extension
scripts/task_jit_run_tests_part4.sh
Adds pytest -s tests/test_artifacts.py test invocation to the execution workflow
API Refactoring and Test Updates
tests/test_artifacts.py
Renames public function get_cubin_file_list() to get_subdir_file_list(); updates test imports and logic to use new function; introduces temporary directory setup via FLASHINFER_CUBIN_DIR environment variable; replaces hardcoded path concatenations with safe_urljoin() calls; refactors assertions to validate extracted file paths from (path, checksum) tuples

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

The changes involve an API rename with straightforward but multi-faceted updates across test logic. While the scope is focused on a single test file and shell script, the refactoring requires verification of: function rename correctness, environment variable handling, URL construction via safe_urljoin(), and assertion alignment with the new tuple-based return structure.

Poem

🐰 A function renamed, from old to new,
get_subdir_file_list now comes into view,
With checksums dancing in subdirectory halls,
Safe URLs joining, wherever it calls!
Tests march onward, validation stands tall!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "unittest: fix test_artifacts.py" directly and clearly reflects the main change in the pull request. It specifically identifies that this is a test fix affecting the test_artifacts.py file, which aligns with the primary objective of updating the tests to work with the new API from PR #1761. The title is concise, non-vague, and provides sufficient clarity for someone scanning commit history to understand the core change without ambiguity.
Description Check ✅ Passed The PR description is comprehensive and follows the repository template structure. All required sections are present and properly completed: the Description section provides detailed context about why the fix was needed and what specific changes were made; Related Issues correctly links to #1761; and the Pull Request Checklist includes the Pre-commit Checks and Tests sections with appropriate checkbox selections and reviewer notes. The description even includes a code example illustrating the tuple unpacking changes, which provides valuable clarity for reviewers.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tests/test_artifacts.py (2)

208-208: Fix the comment to match the variable name.

The comment says "Expected BMM cubin files" but the variable is expected_deepgemm_cubin_files.

Apply this diff:

-# Expected BMM cubin files from the mock response
+# Expected DeepGEMM cubin files from the mock response
 expected_deepgemm_cubin_files = {

209-213: Add missing DeepGEMM cubin file to expected set.

The mock response and checksums data both include kernel.fp8_m_grouped_gemm.007404769193.cubin, but the expected_deepgemm_cubin_files set only contains 3 of the 4 files. Add the missing file:

 expected_deepgemm_cubin_files = {
+    "kernel.fp8_m_grouped_gemm.007404769193.cubin",
     "kernel.fp8_m_grouped_gemm.007d9ebdca7e.cubin",
     "kernel.fp8_m_grouped_gemm.02acb2ba71fd.cubin",
     "kernel.fp8_m_grouped_gemm.0457375eb02f.cubin",
 }

Also fix the comment on line 208: it says "Expected BMM cubin files" but should say "Expected DeepGEMM cubin files".

🧹 Nitpick comments (3)
tests/test_artifacts.py (3)

321-345: Consider refactoring the repetitive mock setup.

The setup for mock responses could be simplified using a dictionary to map artifact paths to checksum data, as suggested in previous reviews. This would improve maintainability if more subdirectories are added.

As per previous review suggestions, you could refactor like this:

# Add mock responses for checksums.txt files
checksum_data = {
    artifact_paths.TRTLLM_GEN_FMHA: checksums_fmha,
    artifact_paths.TRTLLM_GEN_GEMM: checksums_gemm,
    artifact_paths.TRTLLM_GEN_BMM: checksums_bmm,
    artifact_paths.DEEPGEMM: checksums_deepgemm,
}
for path, body in checksum_data.items():
    url = safe_urljoin(
        test_cubin_repository, safe_urljoin(path, "checksums.txt")
    )
    responses.add(responses.GET, url, body=body, status=200)

353-381: Consider consolidating the assertion logic.

The assertion loops are duplicated across four subdirectories. As noted in previous reviews, this could be consolidated using a dictionary that maps artifact paths to expected file sets.

As per previous review suggestions:

assertion_data = {
    artifact_paths.TRTLLM_GEN_GEMM: expected_gemm_cubin_files,
    artifact_paths.TRTLLM_GEN_FMHA: expected_fmha_cubin_files,
    artifact_paths.TRTLLM_GEN_BMM: expected_bmm_cubin_files,
    artifact_paths.DEEPGEMM: expected_deepgemm_cubin_files,
}

for path, expected_files in assertion_data.items():
    for expected_file_name in expected_files:
        expected_file_path = safe_urljoin(path, expected_file_name)
        assert any(expected_file_path in url for url in cubin_file_paths), (
            f"Expected cubin file '{expected_file_path}' not found in cubin file list"
        )

347-393: Add assertions for checksums.txt files.

Based on the implementation in flashinfer/artifacts.py (lines 171-174), get_subdir_file_list() yields checksums.txt files for each subdirectory. However, the test only verifies cubin files and meta info headers, missing verification of the checksums.txt entries.

Add verification for checksums.txt files:

# After line 393, add:

# Check that checksums.txt files are included for each subdirectory
expected_checksum_files = [
    safe_urljoin(artifact_paths.TRTLLM_GEN_FMHA, "checksums.txt"),
    safe_urljoin(artifact_paths.TRTLLM_GEN_GEMM, "checksums.txt"),
    safe_urljoin(artifact_paths.TRTLLM_GEN_BMM, "checksums.txt"),
    safe_urljoin(artifact_paths.DEEPGEMM, "checksums.txt"),
]

for expected_checksum_file in expected_checksum_files:
    assert any(expected_checksum_file in path for path in cubin_file_paths), (
        f"Expected checksums.txt file '{expected_checksum_file}' not found in cubin file list"
    )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9ee58ac and 0660b25.

📒 Files selected for processing (2)
  • scripts/task_jit_run_tests_part4.sh (1 hunks)
  • tests/test_artifacts.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/test_artifacts.py (2)
flashinfer/artifacts.py (1)
  • get_subdir_file_list (146-184)
flashinfer/jit/cubin_loader.py (1)
  • safe_urljoin (38-42)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Deploy Docs
🔇 Additional comments (4)
scripts/task_jit_run_tests_part4.sh (1)

19-19: LGTM!

The addition of the artifacts test to the test suite is appropriate and correctly formatted.

tests/test_artifacts.py (3)

1-5: LGTM!

The import statement correctly reflects the renamed function get_subdir_file_list.


282-293: LGTM!

The test function correctly uses the tmp_path fixture to provide a temporary directory for checksum downloads, and properly configures the environment via monkeypatching.


347-350: LGTM!

The code correctly handles the new API's tuple return values by unpacking them and extracting just the paths for assertion comparisons.

@yzh119
Copy link
Collaborator Author

yzh119 commented Oct 20, 2025

/bot run

@flashinfer-bot
Copy link
Collaborator

GitLab MR !86 has been created, and the CI pipeline #36905871 is currently running. I'll report back once the pipeline job completes.

@flashinfer-bot
Copy link
Collaborator

[FAILED] Pipeline #36905871: 5/17 passed

@yzh119 yzh119 merged commit 8b220a5 into flashinfer-ai:main Oct 23, 2025
4 checks passed
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.

5 participants