mxsm / mxsm/rocketmq-rust

[Test🧪] Add unit tests for the Topic deletion request and result classification

Open
#10,770 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Difficulty level/Easy good first issue help wanted rocketmq-tools crate rust testing🧪
Dominant language
Rust
Stars
1.5k
Forks
264
Avg merge
1h 34m
Merged PRs (30d)
567

Description

Prerequisites
  • I have searched existing test issues
Test Scope
Crate: rocketmq-admin-core
File: rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/core/topic/deletion.rs
Coverage: the file has no test module at all, and no tests/ file covers it

src/core/topic/deletion.rs is 280 lines and has no #[cfg(test)] module. The
integration tests under tests/ do not cover it either:
tests/batch_admin_delete.rs exercises DeleteTopicsInBrokerRequest and
DeleteSubscriptionGroupsRequest, which are different types in different modules.

The file holds one validated request and one result classifier:

// line 41
    pub fn try_new(topic: impl Into<String>, cluster_name: Option<String>) -> Result<Self> {
        let topic = topic.into();
        let topic = topic.trim();
        if !TopicValidator::validate_topic(topic).valid() {
            return Err(invalid_request());
        }
        let cluster_name = cluster_name
            .map(|name| name.trim().to_owned())
            .filter(|name| !name.is_empty())
            .ok_or_else(invalid_request)?;
        // ...
    }
// line 58
    pub fn with_optional_namesrv_addr(mut self, namesrv_addr: Option<String>) -> Self {
        self.namesrv_addr = namesrv_addr
            .map(|addr| addr.trim().to_owned())
            .filter(|addr| !addr.is_empty());
        self
    }
// lines 106, 110 and 121
    pub fn is_complete_success(&self) -> bool {
        self.failures.is_empty() && self.name_server_deleted
    }

    pub fn is_partial_failure(&self) -> bool {
        !self.broker_addrs.is_empty() && (!self.failures.is_empty() || !self.name_server_deleted)
    }

    pub fn ensure_complete(&self) -> Result<()> {
        // ... permission denied when the first failure says so, otherwise a broker operation error
    }

ensure_complete is the projection the adapter uses to turn a partial result into
a status, and it branches on the first failure's error_code string. None of that
branching is pinned by a test.

This module is behind no feature gate for the request type, so the tests run with
cargo test -p rocketmq-admin-core on default features. validated, further down
the file, is gated on #[cfg(any(feature = "client-adapter", test))], so it is
also reachable from a test module.

Test Cases

Add a #[cfg(test)] mod tests block at the end of
src/core/topic/deletion.rs with use super::*;.

DeleteTopicRequest::try_new:

  • A valid topic and cluster are accepted, and topic() and cluster_name()
    return the trimmed values for input such as (" TopicA ", Some(" cluster-a ")).
  • A None cluster name is rejected.
  • A cluster name of "" and of " " is both rejected.
  • An invalid topic is rejected, for example one containing / or : which
    TopicValidator::validate_topic refuses.
  • Every rejection returns core.argument.invalid, asserted as
    error.descriptor().code().as_str() == "core.argument.invalid".

with_optional_namesrv_addr:

  • Some(" 127.0.0.1:9876 ") is stored trimmed.
  • Some(" ") and None both leave namesrv_addr() as None.

DeleteTopicResult::is_complete_success and is_partial_failure:

  • No failures and name_server_deleted == true is a complete success, and it
    is not a partial failure.
  • No failures and name_server_deleted == false is not a complete success. Add
    a case with at least one broker address and assert whether it counts as a
    partial failure, recording the current answer.
  • A result with an empty broker_addrs is never a partial failure, even when
    it has failures, and a comment records that rule.

DeleteTopicResult::ensure_complete:

  • A complete success returns Ok(()).
  • A failure whose error_code is "BROKER_PERMISSION_DENIED" returns an
    error with code auth.permission.denied.
  • A failure whose error_code is "auth.permission.denied" returns the same
    code, pinning that both spellings are accepted.
  • Only the first failure is inspected: put a non-permission failure first
    and a permission failure second, and assert the returned code is the broker
    operation error rather than the permission error.
  • Any other incomplete result returns the broker operation error code.
Willing to contribute?
  • I can submit a PR for this

Acceptance Criteria

  • src/core/topic/deletion.rs gains a #[cfg(test)] mod tests block covering
    every case above.
  • The production types and functions are unchanged. These tests pin current
    behaviour; if a case looks wrong, raise it in the issue thread.
  • cargo test -p rocketmq-admin-core topic::deletion passes.

Validation

Run from the repository root:

cargo fmt -p rocketmq-admin-core -- --check
cargo test -p rocketmq-admin-core topic::deletion
cargo test -p rocketmq-admin-core

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/core/topic/deletion.rs and read the request constructors and result classification methods around the referenced lines. Add the #[cfg(test)] module with the listed validation, trimming, classification, and first-failure cases. Run cargo fmt -p rocketmq-admin-core -- --check, then cargo test -p rocketmq-admin-core topic::deletion and the full crate test suite.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
testing-qa
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
82/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.