diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4eb1b41d..1f455143 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,9 +1,37 @@ +# Copyright (c) 2024-present, arana-db Community. All rights reserved. +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + name: ci + on: pull_request: push: branches: - main + +permissions: + contents: read + +env: + CARGO_TERM_COLOR: always + CARGO_INCREMENTAL: 0 + CARGO_PROFILE_DEV_DEBUG: 0 + RUST_BACKTRACE: short + jobs: license-check: name: license header check @@ -14,15 +42,10 @@ jobs: - name: check license header uses: apache/skywalking-eyes/header@main + # Format check only needs one OS — rustfmt output is platform-independent format: - strategy: - matrix: - include: - - os: macos-latest - - os: ubuntu-latest - - os: windows-latest name: cargo fmt - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -30,19 +53,20 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable - components: rustfmt, clippy + components: rustfmt - - name: Run fmt + - name: Check formatting run: make fmt-check cargo-clippy: strategy: + fail-fast: false matrix: include: - os: macos-latest - os: ubuntu-latest - os: windows-latest - name: cargo clippy + name: cargo clippy (${{ matrix.os }}) runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v6 @@ -51,7 +75,18 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable - components: rustfmt, clippy + components: clippy + + - name: Cache Cargo registry + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-clippy-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-clippy- - name: Install protoc (Linux) if: matrix.os == 'ubuntu-latest' @@ -79,12 +114,13 @@ jobs: build-and-test: strategy: + fail-fast: false matrix: include: - os: macos-latest - os: ubuntu-latest - os: windows-latest - name: build and test + name: build and test (${{ matrix.os }}) runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v6 @@ -93,7 +129,17 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable - components: rustfmt, clippy + + - name: Cache Cargo registry + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo- - name: Install protoc (Linux) if: matrix.os == 'ubuntu-latest' @@ -122,3 +168,53 @@ jobs: - name: Run Unit Test run: make test + + - name: Upload test results on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-results-${{ matrix.os }} + path: target/nextest/ + + # Integration tests (Python) only on ubuntu + integration-test: + name: integration test + runs-on: ubuntu-latest + needs: [build-and-test] + steps: + - uses: actions/checkout@v6 + + - name: Setup toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Cache Cargo registry + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo- + + - name: Install protoc + run: | + sudo apt-get update + sudo apt-get install -y protobuf-compiler + + - name: Build project + run: make build + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.x' + + - name: Install Python dependencies + run: make -C tests install-deps + + - name: Run integration tests + run: make -C tests test-python diff --git a/.github/workflows/clean-cache.yml b/.github/workflows/clean-cache.yml new file mode 100644 index 00000000..f807cb9d --- /dev/null +++ b/.github/workflows/clean-cache.yml @@ -0,0 +1,46 @@ +# Copyright (c) 2024-present, arana-db Community. All rights reserved. +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Delete all Actions caches associated with a PR branch after the PR is closed. +# This prevents Cargo caches from accumulating across merged/closed PRs +# and consuming repository storage quota. +name: Cleanup PR Caches + +on: + pull_request: + types: [closed] + +permissions: + actions: write + +jobs: + cleanup: + runs-on: ubuntu-latest + steps: + - name: Delete PR branch caches + run: | + gh extension install actions/gh-actions-cache + BRANCH="refs/pull/${{ github.event.pull_request.number }}/merge" + echo "Cleaning caches for branch: ${BRANCH}" + for key in $(gh actions-cache list -R "$REPO" -B "$BRANCH" -L 100 | cut -f 1); do + gh actions-cache delete "$key" -R "$REPO" -B "$BRANCH" --confirm + echo "Deleted cache: $key" + done + echo "Done." + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 00000000..ab971836 --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,61 @@ +# Copyright (c) 2024-present, arana-db Community. All rights reserved. +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Security Audit + +on: + push: + branches: + - main + schedule: + # Run every Monday at 6:00 UTC + - cron: '0 6 * * 1' + +permissions: + contents: read + +jobs: + # Check for known vulnerabilities in dependencies + # Non-blocking: reports findings but does not fail the PR check. + # Fix the reported vulnerabilities separately by updating dependencies. + cargo-audit: + name: cargo audit + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v6 + + - name: Install cargo-audit + run: cargo install cargo-audit + + - name: Run cargo audit + run: cargo audit + + # Check dependency licenses and advisories. + # Non-blocking: requires a deny.toml config to be meaningful. + cargo-deny: + name: cargo deny + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v6 + + - name: Install cargo-deny + run: cargo install cargo-deny + + - name: Check advisories and licenses + run: cargo deny check advisories licenses diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 2aafa243..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,131 +0,0 @@ -name: Tests - -on: - push: - branches: [ main, master, develop ] - pull_request: - branches: [ main, master, develop ] - -env: - CARGO_TERM_COLOR: always - -jobs: - test: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v6 - - - name: Setup Rust toolchain - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: stable - components: rustfmt, clippy - - - name: Install protoc (Linux) - run: | - sudo apt-get update - sudo apt-get install -y protobuf-compiler - - - name: Cache Cargo registry - uses: actions/cache@v4 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - target - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - - name: Build project - run: make build - - - name: Run unit tests - run: make test - - - name: Setup Python - uses: actions/setup-python@v6 - with: - python-version: '3.x' - - - name: Install Python dependencies - run: make -C tests install-deps - - - name: Run integration tests (will skip if no Redis server) - run: make -C tests test-python - - test-windows: - runs-on: windows-latest - - steps: - - name: Checkout code - uses: actions/checkout@v6 - - - name: Setup Rust toolchain - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: stable - components: rustfmt, clippy - - - name: Install protoc (Windows) - run: | - $protocVersion = "27.1" - $protocZip = "protoc-$protocVersion-win64.zip" - $protocUrl = "https://github.com/protocolbuffers/protobuf/releases/download/v$protocVersion/$protocZip" - $protocPath = "$env:RUNNER_TEMP\protoc" - Invoke-WebRequest -Uri $protocUrl -OutFile "$env:RUNNER_TEMP\$protocZip" - Expand-Archive -Path "$env:RUNNER_TEMP\$protocZip" -DestinationPath $protocPath - echo "$protocPath\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - - name: Build project - run: make build - - - name: Run unit tests - run: make test - - test-macos: - runs-on: macos-latest - - steps: - - name: Checkout code - uses: actions/checkout@v6 - - - name: Setup Rust toolchain - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: stable - components: rustfmt, clippy - - - name: Install protoc (macOS) - run: | - brew install protobuf - - - name: Build project - run: make build - - - name: Run unit tests - run: make test - - lint: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v6 - - - name: Setup Rust toolchain - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: stable - components: rustfmt, clippy - - - name: Install protoc (Linux) - run: | - sudo apt-get update - sudo apt-get install -y protobuf-compiler - - - name: Check code formatting - run: make fmt - - - name: Run Clippy linter - run: make lint diff --git a/Makefile b/Makefile index 41be6872..822a52a2 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ fmt-check: lint: @echo "Linting code..." - @cargo clippy --manifest-path ./Cargo.toml --all-features --workspace -- -D warnings + @cargo clippy --manifest-path ./Cargo.toml --all-features --workspace -- -D warnings -D clippy::unwrap_used help: @echo "Available commands:" diff --git a/src/cmd/src/hscan.rs b/src/cmd/src/hscan.rs index ee3d18f4..b232bd2d 100644 --- a/src/cmd/src/hscan.rs +++ b/src/cmd/src/hscan.rs @@ -144,6 +144,7 @@ impl Cmd for HScanCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/incrbyfloat.rs b/src/cmd/src/incrbyfloat.rs index a5cb7ae0..4a6eb362 100644 --- a/src/cmd/src/incrbyfloat.rs +++ b/src/cmd/src/incrbyfloat.rs @@ -91,6 +91,7 @@ impl Cmd for IncrbyFloatCmd { } } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/list.rs b/src/cmd/src/list.rs index 5d836c88..f66c9afc 100644 --- a/src/cmd/src/list.rs +++ b/src/cmd/src/list.rs @@ -828,6 +828,7 @@ impl Cmd for RPoplpushCmd { // Tests are covered by the comprehensive storage layer tests in src/storage/tests/redis_list_test.rs // The command layer is a thin wrapper around the storage operations +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/sadd.rs b/src/cmd/src/sadd.rs index 084f513c..09bd193e 100644 --- a/src/cmd/src/sadd.rs +++ b/src/cmd/src/sadd.rs @@ -73,6 +73,7 @@ impl Cmd for SaddCmd { } } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/scard.rs b/src/cmd/src/scard.rs index fa33811c..f4e5e8a4 100644 --- a/src/cmd/src/scard.rs +++ b/src/cmd/src/scard.rs @@ -75,6 +75,7 @@ impl Cmd for ScardCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/sdiff.rs b/src/cmd/src/sdiff.rs index a7de053f..804d6aca 100644 --- a/src/cmd/src/sdiff.rs +++ b/src/cmd/src/sdiff.rs @@ -84,6 +84,7 @@ impl Cmd for SdiffCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/sdiffstore.rs b/src/cmd/src/sdiffstore.rs index 777c60e6..3e035239 100644 --- a/src/cmd/src/sdiffstore.rs +++ b/src/cmd/src/sdiffstore.rs @@ -79,6 +79,7 @@ impl Cmd for SdiffstoreCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/sinter.rs b/src/cmd/src/sinter.rs index 84322984..f70c1184 100644 --- a/src/cmd/src/sinter.rs +++ b/src/cmd/src/sinter.rs @@ -84,6 +84,7 @@ impl Cmd for SinterCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/sinterstore.rs b/src/cmd/src/sinterstore.rs index 4d97c0ba..ddebd866 100644 --- a/src/cmd/src/sinterstore.rs +++ b/src/cmd/src/sinterstore.rs @@ -79,6 +79,7 @@ impl Cmd for SinterstoreCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/sismember.rs b/src/cmd/src/sismember.rs index e1cde181..f2684306 100644 --- a/src/cmd/src/sismember.rs +++ b/src/cmd/src/sismember.rs @@ -72,6 +72,7 @@ impl Cmd for SismemberCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/smembers.rs b/src/cmd/src/smembers.rs index 5a836ae7..fc48a163 100644 --- a/src/cmd/src/smembers.rs +++ b/src/cmd/src/smembers.rs @@ -76,6 +76,7 @@ impl Cmd for SmembersCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/smove.rs b/src/cmd/src/smove.rs index 22c05e1a..602b776d 100644 --- a/src/cmd/src/smove.rs +++ b/src/cmd/src/smove.rs @@ -73,6 +73,7 @@ impl Cmd for SmoveCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/spop.rs b/src/cmd/src/spop.rs index beaf1895..9d730800 100644 --- a/src/cmd/src/spop.rs +++ b/src/cmd/src/spop.rs @@ -126,6 +126,7 @@ impl Cmd for SpopCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/srandmember.rs b/src/cmd/src/srandmember.rs index eb85ff94..df3174d6 100644 --- a/src/cmd/src/srandmember.rs +++ b/src/cmd/src/srandmember.rs @@ -116,6 +116,7 @@ impl Cmd for SrandmemberCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/srem.rs b/src/cmd/src/srem.rs index 4348a2c5..e5c87e71 100644 --- a/src/cmd/src/srem.rs +++ b/src/cmd/src/srem.rs @@ -74,6 +74,7 @@ impl Cmd for SremCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/sscan.rs b/src/cmd/src/sscan.rs index f3d1c4cb..8c8d4405 100644 --- a/src/cmd/src/sscan.rs +++ b/src/cmd/src/sscan.rs @@ -142,6 +142,7 @@ impl Cmd for SscanCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/sunion.rs b/src/cmd/src/sunion.rs index 4c2b727b..6ca16be7 100644 --- a/src/cmd/src/sunion.rs +++ b/src/cmd/src/sunion.rs @@ -84,6 +84,7 @@ impl Cmd for SunionCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/sunionstore.rs b/src/cmd/src/sunionstore.rs index 1d6670f0..05413660 100644 --- a/src/cmd/src/sunionstore.rs +++ b/src/cmd/src/sunionstore.rs @@ -79,6 +79,7 @@ impl Cmd for SunionstoreCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/zadd.rs b/src/cmd/src/zadd.rs index 7d5562c9..515f6663 100644 --- a/src/cmd/src/zadd.rs +++ b/src/cmd/src/zadd.rs @@ -116,6 +116,7 @@ impl Cmd for ZaddCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/zincrby.rs b/src/cmd/src/zincrby.rs index 4049c189..321fdfd4 100644 --- a/src/cmd/src/zincrby.rs +++ b/src/cmd/src/zincrby.rs @@ -109,6 +109,7 @@ impl Cmd for ZincrbyCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/zscan.rs b/src/cmd/src/zscan.rs index b94925f9..5068c6c0 100644 --- a/src/cmd/src/zscan.rs +++ b/src/cmd/src/zscan.rs @@ -144,6 +144,7 @@ impl Cmd for ZscanCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/cmd/src/zscore.rs b/src/cmd/src/zscore.rs index 5b484246..21f9fbc1 100644 --- a/src/cmd/src/zscore.rs +++ b/src/cmd/src/zscore.rs @@ -91,6 +91,7 @@ impl Cmd for ZscoreCmd { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/common/macro/src/macro_stack_trace_debug.rs b/src/common/macro/src/macro_stack_trace_debug.rs index 2553963e..33ba998a 100644 --- a/src/common/macro/src/macro_stack_trace_debug.rs +++ b/src/common/macro/src/macro_stack_trace_debug.rs @@ -24,7 +24,10 @@ use crate::error_variant::ErrorVariant; pub fn stack_trace_style_impl(args: TokenStream2, input: TokenStream2) -> TokenStream2 { let input_cloned: TokenStream2 = input.clone(); - let error_enum_definition: ItemEnum = syn::parse2(input_cloned).unwrap(); + let error_enum_definition: ItemEnum = match syn::parse2(input_cloned) { + Ok(v) => v, + Err(e) => return e.to_compile_error(), + }; let enum_name = error_enum_definition.ident; let mut variants = vec![]; diff --git a/src/common/runtime/additional_unit_tests.rs b/src/common/runtime/additional_unit_tests.rs index 89b3d346..c5a66e33 100644 --- a/src/common/runtime/additional_unit_tests.rs +++ b/src/common/runtime/additional_unit_tests.rs @@ -24,6 +24,8 @@ //! - Request/response serialization and correlation //! - Configuration validation and defaults +#![allow(clippy::unwrap_used)] + use std::time::Duration; use serde_json; diff --git a/src/common/runtime/config.rs b/src/common/runtime/config.rs index 5f0a98fc..87203214 100644 --- a/src/common/runtime/config.rs +++ b/src/common/runtime/config.rs @@ -470,6 +470,7 @@ impl RuntimeConfig { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/common/runtime/error.rs b/src/common/runtime/error.rs index b92af2b9..2dd6edc0 100644 --- a/src/common/runtime/error.rs +++ b/src/common/runtime/error.rs @@ -295,6 +295,7 @@ pub enum ErrorSeverity { Critical = 4, } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/common/runtime/error_logging.rs b/src/common/runtime/error_logging.rs index 6926dd35..a0572648 100644 --- a/src/common/runtime/error_logging.rs +++ b/src/common/runtime/error_logging.rs @@ -570,6 +570,7 @@ macro_rules! log_dual_runtime_error { }; } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/common/runtime/lib.rs b/src/common/runtime/lib.rs index 865a4953..4124397d 100644 --- a/src/common/runtime/lib.rs +++ b/src/common/runtime/lib.rs @@ -28,12 +28,15 @@ pub mod message; pub mod metrics; pub mod storage_server; +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests; +#[allow(clippy::unwrap_used)] #[cfg(test)] mod additional_unit_tests; +#[allow(clippy::unwrap_used)] #[cfg(test)] mod stress_tests; diff --git a/src/common/runtime/manager.rs b/src/common/runtime/manager.rs index 63604cfe..a6b02cc4 100644 --- a/src/common/runtime/manager.rs +++ b/src/common/runtime/manager.rs @@ -601,6 +601,7 @@ impl Drop for RuntimeManager { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/common/runtime/message.rs b/src/common/runtime/message.rs index db19667d..0916e52c 100644 --- a/src/common/runtime/message.rs +++ b/src/common/runtime/message.rs @@ -1383,6 +1383,7 @@ impl StorageClient { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/common/runtime/metrics.rs b/src/common/runtime/metrics.rs index f95fdb08..51594f94 100644 --- a/src/common/runtime/metrics.rs +++ b/src/common/runtime/metrics.rs @@ -388,12 +388,12 @@ impl MetricsCollector { health_status, timestamp: SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(), }; // Store the latest metrics - *last_metrics.write().unwrap() = Some(runtime_metrics.clone()); + *last_metrics.write().expect("lock poisoned") = Some(runtime_metrics.clone()); // Log key metrics periodically if let Ok(elapsed) = SystemTime::now().duration_since(UNIX_EPOCH) { @@ -419,7 +419,7 @@ impl MetricsCollector { /// Get the latest metrics snapshot pub fn get_metrics(&self) -> Option { - self.last_metrics.read().unwrap().clone() + self.last_metrics.read().expect("lock poisoned").clone() } /// Get network metrics tracker for recording network events @@ -451,7 +451,7 @@ impl MetricsCollector { self.channel_tracker.reset().await; self.health_monitor.reset().await; - *self.last_metrics.write().unwrap() = None; + *self.last_metrics.write().expect("lock poisoned") = None; } } /// Network metrics tracker for recording network runtime events @@ -1279,10 +1279,10 @@ impl HealthMonitor { /// Get current health status pub async fn get_health_status(&self) -> HealthStatus { - let network_health = self.network_health.read().unwrap().clone(); - let storage_health = self.storage_health.read().unwrap().clone(); - let channel_health = self.channel_health.read().unwrap().clone(); - let _last_check = *self.last_health_check.read().unwrap(); + let network_health = self.network_health.read().expect("lock poisoned").clone(); + let storage_health = self.storage_health.read().expect("lock poisoned").clone(); + let channel_health = self.channel_health.read().expect("lock poisoned").clone(); + let _last_check = *self.last_health_check.read().expect("lock poisoned"); // Determine overall system health let overall_health = @@ -1295,7 +1295,7 @@ impl HealthMonitor { overall_health, last_health_check: SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(), } } @@ -1375,6 +1375,7 @@ impl HealthMonitor { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; @@ -1645,7 +1646,7 @@ impl HealthCheckEndpoints { ) -> HealthCheckResponse { let timestamp = SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(); let metrics = metrics_collector.get_metrics(); @@ -1704,7 +1705,7 @@ impl HealthCheckEndpoints { ) -> HealthCheckResponse { let timestamp = SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(); // Liveness check is basic - just check if the system is running @@ -1919,6 +1920,7 @@ impl HealthCheckEndpoints { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod health_tests { use super::*; diff --git a/src/common/runtime/storage_server.rs b/src/common/runtime/storage_server.rs index 5605a6e4..94619b63 100644 --- a/src/common/runtime/storage_server.rs +++ b/src/common/runtime/storage_server.rs @@ -1532,6 +1532,7 @@ mod util { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/common/runtime/stress_tests.rs b/src/common/runtime/stress_tests.rs index 8cbb338c..b8b81262 100644 --- a/src/common/runtime/stress_tests.rs +++ b/src/common/runtime/stress_tests.rs @@ -25,6 +25,8 @@ //! //! Requirements covered: 6.1, 6.2, 6.3, 6.4, 6.5 +#![allow(clippy::unwrap_used)] + use std::sync::Arc; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::time::Duration; diff --git a/src/common/runtime/tests.rs b/src/common/runtime/tests.rs index c2b046b1..007623bf 100644 --- a/src/common/runtime/tests.rs +++ b/src/common/runtime/tests.rs @@ -17,6 +17,8 @@ //! Unit tests for dual runtime architecture core components +#![allow(clippy::unwrap_used)] + use std::time::Duration; // Import the dual runtime components diff --git a/src/conf/kiwi.conf b/src/conf/kiwi.conf index 53088232..8ab08005 100644 --- a/src/conf/kiwi.conf +++ b/src/conf/kiwi.conf @@ -190,6 +190,10 @@ memory 10M # Log directory for Kiwi logs # log-dir /data/kiwi_rs/logs +# Directory where RocksDB data files are stored. +# When db-instance-num > 1, each instance creates a subdirectory (e.g., ./db/0, ./db/1). +# db-dir ./db + # Enable Redis compatibility mode # redis-compatible-mode yes diff --git a/src/conf/src/config.rs b/src/conf/src/config.rs index 87c75075..4ccbbd04 100644 --- a/src/conf/src/config.rs +++ b/src/conf/src/config.rs @@ -226,6 +226,7 @@ pub struct Config { pub binding: String, pub timeout: u32, pub log_dir: String, + pub db_dir: String, pub redis_compatible_mode: bool, pub db_instance_num: usize, @@ -242,6 +243,7 @@ impl Default for Config { timeout: 50, memory: 1024 * 1024 * 1024, // 1GB log_dir: "/data/kiwi_rs/logs".to_string(), + db_dir: "./db".to_string(), redis_compatible_mode: false, rocksdb_max_subcompactions: 0, @@ -347,6 +349,17 @@ impl Config { "log-dir" => { config.log_dir = value; } + "db-dir" => { + let trimmed = value.trim(); + if trimmed.is_empty() { + return Err(Error::InvalidConfig { + source: serde_ini::de::Error::Custom( + "db-dir must not be empty".to_string(), + ), + }); + } + config.db_dir = trimmed.to_string(); + } "redis-compatible-mode" => { config.redis_compatible_mode = parse_bool_from_string(&value).map_err(|e| Error::InvalidConfig { diff --git a/src/conf/src/lib.rs b/src/conf/src/lib.rs index f6deb887..16af91ae 100644 --- a/src/conf/src/lib.rs +++ b/src/conf/src/lib.rs @@ -18,6 +18,7 @@ pub mod config; pub mod de_func; pub mod error; +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use config::Config; @@ -60,6 +61,7 @@ mod tests { assert_eq!(50, config.timeout); assert_eq!("/data/kiwi_rs/logs", config.log_dir); + assert_eq!("./db", config.db_dir); assert!(!config.redis_compatible_mode); assert_eq!(3, config.db_instance_num); @@ -78,6 +80,7 @@ mod tests { timeout: 100, redis_compatible_mode: false, log_dir: "".to_string(), + db_dir: "./db".to_string(), memory: 1024, rocksdb_max_subcompactions: 0, rocksdb_max_background_jobs: 4, @@ -104,4 +107,28 @@ mod tests { invalid_config.port = 8080; assert!(invalid_config.validate().is_ok()); } + + #[test] + fn test_db_dir_default() { + let config = Config::default(); + assert_eq!("./db", config.db_dir); + } + + #[test] + fn test_db_dir_from_config_file() { + use std::io::Write; + + let filename = format!("kiwi_test_db_dir_{}.conf", std::process::id()); + let tmp = std::env::temp_dir().join(filename); + let config_path = tmp.to_str().unwrap(); + let mut f = std::fs::File::create(config_path).unwrap(); + writeln!(f, "port 7379").unwrap(); + writeln!(f, "db-dir /data/kiwi/db").unwrap(); + drop(f); + + let config = Config::load(config_path).unwrap(); + assert_eq!("/data/kiwi/db", config.db_dir); + + let _ = std::fs::remove_file(config_path); + } } diff --git a/src/engine/src/rocksdb_engine.rs b/src/engine/src/rocksdb_engine.rs index e6694047..88b7ce63 100644 --- a/src/engine/src/rocksdb_engine.rs +++ b/src/engine/src/rocksdb_engine.rs @@ -203,6 +203,7 @@ impl Drop for RocksdbEngine { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use rocksdb::{DB, Options}; diff --git a/src/executor/src/executor.rs b/src/executor/src/executor.rs index 67fe315a..7d0527ea 100644 --- a/src/executor/src/executor.rs +++ b/src/executor/src/executor.rs @@ -163,6 +163,7 @@ impl CmdExecutor { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use std::sync::Arc; diff --git a/src/kstd/src/lock_mgr.rs b/src/kstd/src/lock_mgr.rs index d878f67a..fa8285c7 100644 --- a/src/kstd/src/lock_mgr.rs +++ b/src/kstd/src/lock_mgr.rs @@ -241,6 +241,7 @@ impl<'a> Drop for ScopeRecordMultiLock<'a> { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/kstd/src/slice.rs b/src/kstd/src/slice.rs index bad8cf6e..63e21ddf 100644 --- a/src/kstd/src/slice.rs +++ b/src/kstd/src/slice.rs @@ -81,7 +81,7 @@ impl Slice { .iter() .fold(String::with_capacity(slice.len() * 2), |mut acc, byte| { use std::fmt::Write; - write!(&mut acc, "{byte:02X}").unwrap(); + write!(&mut acc, "{byte:02X}").expect("write to String cannot fail"); acc }) } else { @@ -111,6 +111,7 @@ impl Slice { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/kstd/src/status.rs b/src/kstd/src/status.rs index 1bc8338d..384b73cd 100644 --- a/src/kstd/src/status.rs +++ b/src/kstd/src/status.rs @@ -64,6 +64,7 @@ impl fmt::Display for Status { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/net/benches/network_benchmark.rs b/src/net/benches/network_benchmark.rs index ee8c5472..6035ab6b 100644 --- a/src/net/benches/network_benchmark.rs +++ b/src/net/benches/network_benchmark.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + #[path = "../tests/performance_tests.rs"] mod performance_tests; diff --git a/src/net/src/async_resp_parser.rs b/src/net/src/async_resp_parser.rs index 5f023773..dc3957b2 100644 --- a/src/net/src/async_resp_parser.rs +++ b/src/net/src/async_resp_parser.rs @@ -216,6 +216,7 @@ impl CommandBatch { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/net/src/buffer.rs b/src/net/src/buffer.rs index 914b842a..8f0d3018 100644 --- a/src/net/src/buffer.rs +++ b/src/net/src/buffer.rs @@ -443,6 +443,7 @@ impl BufferedReader { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/net/src/lib.rs b/src/net/src/lib.rs index f74124d1..6c4180d5 100644 --- a/src/net/src/lib.rs +++ b/src/net/src/lib.rs @@ -99,7 +99,9 @@ impl ServerFactory { } } #[cfg(unix)] - "unix" => Some(Box::new(unix::UnixServer::new(addr))), + "unix" => unix::UnixServer::new(addr, None) + .ok() + .map(|s| Box::new(s) as Box), #[cfg(not(unix))] "unix" => None, _ => None, @@ -110,13 +112,16 @@ impl ServerFactory { pub fn create_legacy_server( protocol: &str, addr: Option, + db_dir: Option<&str>, ) -> Option> { match protocol.to_lowercase().as_str() { - "tcp" => TcpServer::new(addr) + "tcp" => TcpServer::new(addr, db_dir) .ok() .map(|s| Box::new(s) as Box), #[cfg(unix)] - "unix" => Some(Box::new(unix::UnixServer::new(addr))), + "unix" => unix::UnixServer::new(addr, db_dir) + .ok() + .map(|s| Box::new(s) as Box), #[cfg(not(unix))] "unix" => None, _ => None, @@ -172,9 +177,10 @@ impl ServerFactory { protocol: &str, addr: Option, raft_node: Arc, + db_dir: Option<&str>, ) -> Option> { match protocol.to_lowercase().as_str() { - "tcp" => ClusterTcpServer::new(addr, raft_node) + "tcp" => ClusterTcpServer::new(addr, raft_node, db_dir) .ok() .map(|s| Box::new(s) as Box), _ => None, diff --git a/src/net/src/network_handle.rs b/src/net/src/network_handle.rs index 802ac172..6511dc18 100644 --- a/src/net/src/network_handle.rs +++ b/src/net/src/network_handle.rs @@ -531,6 +531,7 @@ fn generate_storage_error_response(error: &DualRuntimeError, command: &str) -> R RespData::Error(error_message.into()) } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/net/src/network_server.rs b/src/net/src/network_server.rs index 65a99afa..f0b68c10 100644 --- a/src/net/src/network_server.rs +++ b/src/net/src/network_server.rs @@ -256,6 +256,7 @@ impl ServerTrait for NetworkServer { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/net/src/optimized_handler.rs b/src/net/src/optimized_handler.rs index 0c9e20d6..24571864 100644 --- a/src/net/src/optimized_handler.rs +++ b/src/net/src/optimized_handler.rs @@ -355,6 +355,7 @@ pub struct OptimizedHandlerStats { pub buffer_stats: crate::buffer::BufferStats, } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/net/src/pipeline.rs b/src/net/src/pipeline.rs index d8bb363b..897c9e89 100644 --- a/src/net/src/pipeline.rs +++ b/src/net/src/pipeline.rs @@ -198,7 +198,7 @@ impl CommandPipeline { // Process batch if full if batch.is_full(config.max_batch_size) { - let batch_to_process = current_batch.take().unwrap(); + let batch_to_process = current_batch.take().expect("batch was just checked Some"); Self::process_batch( batch_to_process, storage.clone(), @@ -395,6 +395,7 @@ pub enum PipelineError { Timeout, } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/net/src/pool.rs b/src/net/src/pool.rs index 0d867055..bf13ebc4 100644 --- a/src/net/src/pool.rs +++ b/src/net/src/pool.rs @@ -262,6 +262,7 @@ pub enum PoolError { CreateFailed(Box), } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/net/src/raft_network_handle.rs b/src/net/src/raft_network_handle.rs index d0ba6dd3..187abc5a 100644 --- a/src/net/src/raft_network_handle.rs +++ b/src/net/src/raft_network_handle.rs @@ -397,6 +397,7 @@ pub fn is_read_command(cmd_name: &str) -> bool { ) } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/net/src/storage_client.rs b/src/net/src/storage_client.rs index 2130b406..2612c999 100644 --- a/src/net/src/storage_client.rs +++ b/src/net/src/storage_client.rs @@ -383,6 +383,7 @@ impl Clone for StorageClient { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/net/src/tcp.rs b/src/net/src/tcp.rs index 5598e743..e0987e76 100644 --- a/src/net/src/tcp.rs +++ b/src/net/src/tcp.rs @@ -115,10 +115,9 @@ pub struct TcpServer { } impl TcpServer { - pub fn new(addr: Option) -> Result> { - // TODO: Get storage options from config + pub fn new(addr: Option, db_dir: Option<&str>) -> Result> { let storage_options = Arc::new(StorageOptions::default()); - let db_path = PathBuf::from("./db"); + let db_path = PathBuf::from(db_dir.unwrap_or("./db")); let mut storage = Storage::new(1, 0); let executor = Arc::new(CmdExecutorBuilder::new().build()); @@ -165,10 +164,10 @@ impl ClusterTcpServer { pub fn new( addr: Option, raft_node: Arc, + db_dir: Option<&str>, ) -> Result> { - // TODO: Get storage options from config let storage_options = Arc::new(StorageOptions::default()); - let db_path = PathBuf::from("./db"); + let db_path = PathBuf::from(db_dir.unwrap_or("./db")); let mut storage = Storage::new(1, 0); let executor = Arc::new(CmdExecutorBuilder::new().build()); diff --git a/src/net/src/unix.rs b/src/net/src/unix.rs index 56c045f8..5c2ce819 100644 --- a/src/net/src/unix.rs +++ b/src/net/src/unix.rs @@ -33,20 +33,22 @@ pub struct UnixServer { } impl UnixServer { - pub fn new(path: Option) -> Self { + pub fn new(path: Option, db_dir: Option<&str>) -> Result> { let path = path.unwrap_or_else(|| "/tmp/kiwidb.sock".to_string()); let storage_options = Arc::new(StorageOptions::default()); - let db_path = PathBuf::from("./db"); + let db_path = PathBuf::from(db_dir.unwrap_or("./db")); let mut storage = Storage::new(1, 0); - storage.open(storage_options, db_path).unwrap(); + storage + .open(storage_options, db_path) + .map_err(|e| Box::new(e) as Box)?; let executor = Arc::new(CmdExecutorBuilder::new().build()); - Self { + Ok(Self { path, storage: Arc::new(storage), cmd_table: Arc::new(create_command_table()), executor, - } + }) } } diff --git a/src/net/tests/mod.rs b/src/net/tests/mod.rs index 00e8154e..9fab2b2f 100644 --- a/src/net/tests/mod.rs +++ b/src/net/tests/mod.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + pub mod performance_tests; pub use performance_tests::{NetworkPerformanceTests, PerformanceResults, PerformanceTestConfig}; diff --git a/src/net/tests/network_integration_tests.rs b/src/net/tests/network_integration_tests.rs index 94972f51..5ee19fdd 100644 --- a/src/net/tests/network_integration_tests.rs +++ b/src/net/tests/network_integration_tests.rs @@ -17,6 +17,8 @@ //! Integration tests for network layer with Raft awareness +#![allow(clippy::unwrap_used)] + use net::raft_network_handle::{ClusterMode, is_read_command, is_write_command}; #[test] diff --git a/src/net/tests/performance_tests.rs b/src/net/tests/performance_tests.rs index d9c3a18a..86a81c9d 100644 --- a/src/net/tests/performance_tests.rs +++ b/src/net/tests/performance_tests.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + use std::sync::Arc; use std::time::{Duration, Instant}; diff --git a/src/raft/benches/performance_benchmark.rs b/src/raft/benches/performance_benchmark.rs index 2e85b3f2..fff42f53 100644 --- a/src/raft/benches/performance_benchmark.rs +++ b/src/raft/benches/performance_benchmark.rs @@ -27,6 +27,8 @@ //! - P99 Latency: < 10ms //! - Adaptor overhead: < 1ms +#![allow(clippy::unwrap_used)] + use bytes::Bytes; use criterion::{BenchmarkId, Criterion, Throughput, black_box, criterion_group, criterion_main}; use raft::error::RaftResult; diff --git a/src/raft/src/adaptor_integration.rs b/src/raft/src/adaptor_integration.rs index 3b67da45..2a31347c 100644 --- a/src/raft/src/adaptor_integration.rs +++ b/src/raft/src/adaptor_integration.rs @@ -462,6 +462,7 @@ pub fn create_raft_storage_with_engine( Ok((log_storage, state_machine)) } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/binlog/entry.rs b/src/raft/src/binlog/entry.rs index 384acad4..26ad303e 100644 --- a/src/raft/src/binlog/entry.rs +++ b/src/raft/src/binlog/entry.rs @@ -155,6 +155,7 @@ impl BinlogEntry { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/binlog/reader.rs b/src/raft/src/binlog/reader.rs index 404997fe..a3de8a2a 100644 --- a/src/raft/src/binlog/reader.rs +++ b/src/raft/src/binlog/reader.rs @@ -83,6 +83,7 @@ fn read_varint(data: &[u8]) -> Result<(u32, usize), RaftError> { Ok((value, offset)) } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/binlog/writer.rs b/src/raft/src/binlog/writer.rs index a3489c91..f3065bac 100644 --- a/src/raft/src/binlog/writer.rs +++ b/src/raft/src/binlog/writer.rs @@ -93,9 +93,11 @@ impl Default for BinlogWriter { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; + use crate::binlog::entry::OperationType; use bytes::Bytes; #[test] @@ -114,6 +116,3 @@ mod tests { assert!(!buffer.is_empty()); } } - -#[cfg(test)] -use super::entry::OperationType; diff --git a/src/raft/src/chaos_tests.rs b/src/raft/src/chaos_tests.rs index aefc1b21..bd070338 100644 --- a/src/raft/src/chaos_tests.rs +++ b/src/raft/src/chaos_tests.rs @@ -15,4 +15,5 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Chaos testing for Raft implementation \ No newline at end of file +//! Chaos testing for Raft implementation +#![allow(clippy::unwrap_used)] diff --git a/src/raft/src/cluster_config.rs b/src/raft/src/cluster_config.rs index 9d95d0f9..e5e0e7f9 100644 --- a/src/raft/src/cluster_config.rs +++ b/src/raft/src/cluster_config.rs @@ -505,6 +505,7 @@ impl ClusterConfigManager { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/cluster_tests.rs b/src/raft/src/cluster_tests.rs index 96605ad5..c6238329 100644 --- a/src/raft/src/cluster_tests.rs +++ b/src/raft/src/cluster_tests.rs @@ -22,6 +22,8 @@ //! - Failover and recovery tests //! - Data consistency verification tests +#![allow(clippy::unwrap_used)] + use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; diff --git a/src/raft/src/config_change.rs b/src/raft/src/config_change.rs index e95f97b4..4268fe22 100644 --- a/src/raft/src/config_change.rs +++ b/src/raft/src/config_change.rs @@ -2530,5 +2530,6 @@ pub struct SafetyCheckpoint { pub raft_metrics_snapshot: Option>, } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests; diff --git a/src/raft/src/config_change/tests.rs b/src/raft/src/config_change/tests.rs index dbfe782f..ff58bf09 100644 --- a/src/raft/src/config_change/tests.rs +++ b/src/raft/src/config_change/tests.rs @@ -17,6 +17,8 @@ //! Tests for configuration change safety mechanisms +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod tests { use super::super::*; diff --git a/src/raft/src/config_change_tests.rs b/src/raft/src/config_change_tests.rs index 2e7dc309..42ed3300 100644 --- a/src/raft/src/config_change_tests.rs +++ b/src/raft/src/config_change_tests.rs @@ -19,6 +19,8 @@ //! //! Tests for adding and removing nodes from the Raft cluster +#![allow(clippy::unwrap_used)] + use std::collections::BTreeSet; use std::sync::Arc; use std::time::Duration; diff --git a/src/raft/src/consistency.rs b/src/raft/src/consistency.rs index c9be5ec5..7bb72b85 100644 --- a/src/raft/src/consistency.rs +++ b/src/raft/src/consistency.rs @@ -103,7 +103,7 @@ impl ConsistencyChecker { ) -> RaftResult { let current_timestamp = SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(); // Get current applied index from state machine @@ -218,7 +218,7 @@ impl ConsistencyChecker { pub async fn recover_consistency(&self, target_index: LogIndex) -> RaftResult<()> { let current_timestamp = SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(); log::info!( @@ -391,6 +391,7 @@ impl ConsistencyMonitor { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/consistency_handler.rs b/src/raft/src/consistency_handler.rs index dbb2494b..bf5eb4e2 100644 --- a/src/raft/src/consistency_handler.rs +++ b/src/raft/src/consistency_handler.rs @@ -575,7 +575,7 @@ impl ConsistencyHandler { } return Ok(ConsistencyValidation::RequiresRedirect { - leader_id: leader_id.unwrap(), + leader_id: leader_id.expect("leader_id checked non-None above"), }); } @@ -602,6 +602,7 @@ impl ConsistencyHandler { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/conversion.rs b/src/raft/src/conversion.rs index 4f4df89b..71f3c0e6 100644 --- a/src/raft/src/conversion.rs +++ b/src/raft/src/conversion.rs @@ -373,5 +373,6 @@ pub fn from_storage_error(err: OpenraftStorageError) -> RaftError { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests; diff --git a/src/raft/src/conversion/tests.rs b/src/raft/src/conversion/tests.rs index ec14b0a6..e0718bc8 100644 --- a/src/raft/src/conversion/tests.rs +++ b/src/raft/src/conversion/tests.rs @@ -17,6 +17,8 @@ //! Unit tests for type conversion functions +#![allow(clippy::unwrap_used)] + use super::*; use bytes::Bytes; use openraft::{CommittedLeaderId, Entry, EntryPayload, LogId}; diff --git a/src/raft/src/discovery.rs b/src/raft/src/discovery.rs index c35eab6a..25f90fc4 100644 --- a/src/raft/src/discovery.rs +++ b/src/raft/src/discovery.rs @@ -1723,6 +1723,7 @@ pub struct ReplicationLagSummary { pub critical_lag_nodes: Vec, } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/error/tests.rs b/src/raft/src/error/tests.rs index 9af1cd87..3a20b617 100644 --- a/src/raft/src/error/tests.rs +++ b/src/raft/src/error/tests.rs @@ -17,6 +17,8 @@ //! Unit tests for error types +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod tests { use super::super::*; diff --git a/src/raft/src/failover_tests.rs b/src/raft/src/failover_tests.rs index 7b8570a1..ce4b24ef 100644 --- a/src/raft/src/failover_tests.rs +++ b/src/raft/src/failover_tests.rs @@ -23,6 +23,8 @@ //! - Data consistency during failover //! - Multiple leader failures +#![allow(clippy::unwrap_used)] + use std::time::Duration; use tokio::time::sleep; diff --git a/src/raft/src/health_monitor.rs b/src/raft/src/health_monitor.rs index 0275cfff..2fe02c58 100644 --- a/src/raft/src/health_monitor.rs +++ b/src/raft/src/health_monitor.rs @@ -173,7 +173,7 @@ impl ClusterHealthMonitor { active_anomalies: Vec::new(), last_updated: SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(), cluster_health: ClusterHealth { total_members: 1, @@ -201,7 +201,7 @@ impl ClusterHealthMonitor { /// Start the health monitoring loop pub async fn start(&self) -> RaftResult<()> { { - let mut running = self.running.write().unwrap(); + let mut running = self.running.write().expect("lock poisoned"); if *running { return Ok(()); } @@ -219,7 +219,7 @@ impl ClusterHealthMonitor { tokio::spawn(async move { let mut interval = interval(Duration::from_secs(config.check_interval_secs)); - while *running.read().unwrap() { + while *running.read().expect("lock poisoned") { interval.tick().await; if let Err(e) = Self::perform_health_check( @@ -242,18 +242,18 @@ impl ClusterHealthMonitor { /// Stop the health monitoring pub fn stop(&self) { - let mut running = self.running.write().unwrap(); + let mut running = self.running.write().expect("lock poisoned"); *running = false; } /// Get current health status pub fn get_current_status(&self) -> ClusterHealthStatus { - self.current_status.read().unwrap().clone() + self.current_status.read().expect("lock poisoned").clone() } /// Get health history pub fn get_health_history(&self, limit: Option) -> Vec { - let history = self.health_history.read().unwrap(); + let history = self.health_history.read().expect("lock poisoned"); let limit = limit.unwrap_or(history.len()); history.iter().rev().take(limit).cloned().collect() } @@ -262,7 +262,7 @@ impl ClusterHealthMonitor { pub fn get_active_anomalies(&self) -> Vec { self.anomalies .read() - .unwrap() + .expect("lock poisoned") .iter() .filter(|a| a.active) .cloned() @@ -276,11 +276,11 @@ impl ClusterHealthMonitor { /// Update cluster health information pub fn update_cluster_health(&self, cluster_health: ClusterHealth) { - let mut status = self.current_status.write().unwrap(); + let mut status = self.current_status.write().expect("lock poisoned"); status.cluster_health = cluster_health; status.last_updated = SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(); } @@ -296,7 +296,7 @@ impl ClusterHealthMonitor { let metrics = metrics_collector.get_metrics(); let now = SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(); // Detect anomalies @@ -433,7 +433,7 @@ impl ClusterHealthMonitor { // Update anomalies { - let mut anomalies_guard = anomalies.write().unwrap(); + let mut anomalies_guard = anomalies.write().expect("lock poisoned"); // Mark existing anomalies as inactive if they're resolved for anomaly in anomalies_guard.iter_mut() { @@ -501,7 +501,7 @@ impl ClusterHealthMonitor { // Update current status let updated_status = { - let mut status = current_status.write().unwrap(); + let mut status = current_status.write().expect("lock poisoned"); status.overall_status = overall_status; status.active_anomalies = detected_anomalies.clone(); status.last_updated = now; @@ -528,7 +528,7 @@ impl ClusterHealthMonitor { // Add to health history { - let mut history = health_history.write().unwrap(); + let mut history = health_history.write().expect("lock poisoned"); let record = HealthRecord { timestamp: now, status: overall_status, @@ -575,6 +575,7 @@ impl ClusterHealthMonitor { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/integration_tests.rs b/src/raft/src/integration_tests.rs index 5ef2d63f..0472079a 100644 --- a/src/raft/src/integration_tests.rs +++ b/src/raft/src/integration_tests.rs @@ -17,6 +17,8 @@ //! Integration tests for Raft cluster functionality +#![allow(clippy::unwrap_used)] + use crate::error::RaftResult; use crate::network::KiwiRaftNetworkFactory; use crate::state_machine::{KiwiStateMachine, StorageEngine}; diff --git a/src/raft/src/integration_tests_working.rs b/src/raft/src/integration_tests_working.rs index 696ba6d7..a3b1bd90 100644 --- a/src/raft/src/integration_tests_working.rs +++ b/src/raft/src/integration_tests_working.rs @@ -17,6 +17,8 @@ // Working integration tests that avoid OpenRaft lifetime issues +#![allow(clippy::unwrap_used)] + use bytes::Bytes; use std::sync::Arc; diff --git a/src/raft/src/lib.rs b/src/raft/src/lib.rs index 484961de..7e3056b1 100644 --- a/src/raft/src/lib.rs +++ b/src/raft/src/lib.rs @@ -50,9 +50,11 @@ use openraft::Config; pub mod binlog; pub mod cluster_config; +#[allow(clippy::unwrap_used)] #[cfg(test)] pub mod cluster_tests; pub mod config_change; +#[allow(clippy::unwrap_used)] #[cfg(test)] pub mod config_change_tests; pub mod consistency; @@ -60,6 +62,7 @@ pub mod consistency_handler; pub mod conversion; pub mod discovery; pub mod error; +#[allow(clippy::unwrap_used)] #[cfg(test)] pub mod failover_tests; pub mod health_monitor; @@ -111,6 +114,7 @@ pub fn default_raft_config() -> Config { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod unit_tests { use super::*; @@ -142,12 +146,15 @@ mod unit_tests { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] pub mod integration_tests; +#[allow(clippy::unwrap_used)] #[cfg(test)] pub mod integration_tests_working; +#[allow(clippy::unwrap_used)] #[cfg(test)] #[path = "tests/mod.rs"] mod test_harness; diff --git a/src/raft/src/logging.rs b/src/raft/src/logging.rs index e0f66f09..9bfe0b52 100644 --- a/src/raft/src/logging.rs +++ b/src/raft/src/logging.rs @@ -1645,6 +1645,7 @@ impl<'a> Drop for TimingGuard<'a> { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/metrics.rs b/src/raft/src/metrics.rs index 7077d6e8..0a38bcc9 100644 --- a/src/raft/src/metrics.rs +++ b/src/raft/src/metrics.rs @@ -180,7 +180,7 @@ impl MetricsCollector { pub fn new(node_id: NodeId) -> Self { let now = SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(); let initial_metrics = RaftMetrics { @@ -246,10 +246,10 @@ impl MetricsCollector { /// Update metrics from openraft metrics pub fn update_from_openraft(&self, openraft_metrics: &OpenRaftMetrics) { - let mut metrics = self.metrics.write().unwrap(); + let mut metrics = self.metrics.write().expect("lock poisoned"); let now = SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(); // Update state metrics @@ -323,7 +323,7 @@ impl MetricsCollector { cluster_size: usize, last_heartbeat_ms: u64, ) { - let mut metrics = self.metrics.write().unwrap(); + let mut metrics = self.metrics.write().expect("lock poisoned"); metrics.state.current_term = current_term; metrics.state.current_leader = current_leader; metrics.state.node_state = node_state.to_string(); @@ -342,7 +342,7 @@ impl MetricsCollector { last_contact_ms: u64, replication_latency_ms: f64, ) { - let mut metrics = self.metrics.write().unwrap(); + let mut metrics = self.metrics.write().expect("lock poisoned"); metrics .replication .replication_lag @@ -359,7 +359,7 @@ impl MetricsCollector { /// Record replication failure for a follower pub fn record_replication_failure(&self, follower_id: NodeId) { - let mut metrics = self.metrics.write().unwrap(); + let mut metrics = self.metrics.write().expect("lock poisoned"); let failures = metrics .replication .replication_failures @@ -381,7 +381,7 @@ impl MetricsCollector { /// Update network RTT for a node pub fn update_network_rtt(&self, node_id: NodeId, rtt_ms: f64) { - let mut metrics = self.metrics.write().unwrap(); + let mut metrics = self.metrics.write().expect("lock poisoned"); metrics.network.rtt_ms.insert(node_id, rtt_ms); } @@ -393,7 +393,7 @@ impl MetricsCollector { snapshots_count: u64, snapshot_size_bytes: u64, ) { - let mut metrics = self.metrics.write().unwrap(); + let mut metrics = self.metrics.write().expect("lock poisoned"); metrics.storage.log_entries_count = log_entries_count; metrics.storage.log_size_bytes = log_size_bytes; metrics.storage.snapshots_count = snapshots_count; @@ -402,7 +402,7 @@ impl MetricsCollector { /// Get current metrics snapshot pub fn get_metrics(&self) -> RaftMetrics { - let mut metrics = self.metrics.read().unwrap().clone(); + let mut metrics = self.metrics.read().expect("lock poisoned").clone(); // Update performance metrics from tracker let perf_stats = self.performance_tracker.get_stats(); @@ -426,7 +426,7 @@ impl MetricsCollector { metrics.timestamp = SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(); metrics @@ -466,7 +466,7 @@ impl PerformanceTracker { .fetch_add(latency_ms, Ordering::Relaxed); // Keep only recent latencies (last 1000 requests) - let mut latencies = self.latencies.write().unwrap(); + let mut latencies = self.latencies.write().expect("lock poisoned"); latencies.push(latency_ms); if latencies.len() > 1000 { latencies.remove(0); @@ -476,7 +476,7 @@ impl PerformanceTracker { fn get_stats(&self) -> PerformanceMetrics { let count = self.request_count.load(Ordering::Relaxed); let total_latency = self.total_latency_ms.load(Ordering::Relaxed); - let elapsed = self.last_reset.read().unwrap().elapsed(); + let elapsed = self.last_reset.read().expect("lock poisoned").elapsed(); let avg_latency = if count > 0 { total_latency as f64 / count as f64 @@ -491,7 +491,7 @@ impl PerformanceTracker { }; // Calculate percentiles - let latencies = self.latencies.read().unwrap(); + let latencies = self.latencies.read().expect("lock poisoned"); let mut sorted_latencies = latencies.clone(); sorted_latencies.sort_unstable(); @@ -529,8 +529,8 @@ impl PerformanceTracker { fn reset(&self) { self.request_count.store(0, Ordering::Relaxed); self.total_latency_ms.store(0, Ordering::Relaxed); - self.latencies.write().unwrap().clear(); - *self.last_reset.write().unwrap() = Instant::now(); + self.latencies.write().expect("lock poisoned").clear(); + *self.last_reset.write().expect("lock poisoned") = Instant::now(); } } @@ -618,7 +618,7 @@ impl StorageTracker { fn get_stats(&self) -> StorageStats { let count = self.operation_count.load(Ordering::Relaxed); let total_latency = self.total_latency_ms.load(Ordering::Relaxed); - let elapsed = self.last_reset.read().unwrap().elapsed(); + let elapsed = self.last_reset.read().expect("lock poisoned").elapsed(); let avg_latency = if count > 0 { total_latency as f64 / count as f64 @@ -641,7 +641,7 @@ impl StorageTracker { fn reset(&self) { self.operation_count.store(0, Ordering::Relaxed); self.total_latency_ms.store(0, Ordering::Relaxed); - *self.last_reset.write().unwrap() = Instant::now(); + *self.last_reset.write().expect("lock poisoned") = Instant::now(); } } @@ -678,17 +678,17 @@ impl ErrorTracker { // Update error counts by type { - let mut errors_by_type = self.errors_by_type.write().unwrap(); + let mut errors_by_type = self.errors_by_type.write().expect("lock poisoned"); *errors_by_type.entry(error_type.to_string()).or_insert(0) += 1; } // Add to recent errors (keep last 100) { - let mut recent_errors = self.recent_errors.write().unwrap(); + let mut recent_errors = self.recent_errors.write().expect("lock poisoned"); let error_sample = ErrorSample { timestamp: SystemTime::now() .duration_since(UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(), error_type: error_type.to_string(), message: message.to_string(), @@ -716,19 +716,20 @@ impl ErrorTracker { total_operations: total, failed_operations: failed, error_rate_percent: error_rate, - errors_by_type: self.errors_by_type.read().unwrap().clone(), - recent_errors: self.recent_errors.read().unwrap().clone(), + errors_by_type: self.errors_by_type.read().expect("lock poisoned").clone(), + recent_errors: self.recent_errors.read().expect("lock poisoned").clone(), } } fn reset(&self) { self.total_operations.store(0, Ordering::Relaxed); self.failed_operations.store(0, Ordering::Relaxed); - self.errors_by_type.write().unwrap().clear(); - self.recent_errors.write().unwrap().clear(); + self.errors_by_type.write().expect("lock poisoned").clear(); + self.recent_errors.write().expect("lock poisoned").clear(); } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/monitoring_api.rs b/src/raft/src/monitoring_api.rs index baf3fba1..a3aefe16 100644 --- a/src/raft/src/monitoring_api.rs +++ b/src/raft/src/monitoring_api.rs @@ -43,7 +43,9 @@ pub struct MonitoringApiConfig { impl Default for MonitoringApiConfig { fn default() -> Self { Self { - bind_address: "127.0.0.1:8080".parse().unwrap(), + bind_address: "127.0.0.1:8080" + .parse() + .expect("hard-coded default bind address must be a valid SocketAddr"), enable_cors: true, api_key: None, } @@ -67,7 +69,7 @@ impl ApiResponse { error: None, timestamp: std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(), } } @@ -79,7 +81,7 @@ impl ApiResponse { error: Some(message), timestamp: std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(), } } @@ -319,7 +321,7 @@ async fn export_data( health_history, export_timestamp: std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs(), }; @@ -506,6 +508,7 @@ async fn handle_rejection( Ok(warp::reply::with_status(json, code)) } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/network.rs b/src/raft/src/network.rs index 34e53ecb..5beecd9d 100644 --- a/src/raft/src/network.rs +++ b/src/raft/src/network.rs @@ -1204,7 +1204,7 @@ impl RaftConnection { } } - Err(last_error.unwrap()) + Err(last_error.expect("at least one attempt was made")) } /// Send a message to the connected node @@ -1575,7 +1575,7 @@ impl RaftNetworkClient { } } - Err(last_error.unwrap()) + Err(last_error.expect("at least one attempt was made")) } /// Single HTTP request attempt @@ -1788,6 +1788,7 @@ impl OpenRaftNetwork for RaftNetworkClient { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { // TODO: Add tests for KiwiRaftNetworkFactory and RaftNetworkClient diff --git a/src/raft/src/openraft_compatibility.rs b/src/raft/src/openraft_compatibility.rs index 0281ac54..987ed0b1 100644 --- a/src/raft/src/openraft_compatibility.rs +++ b/src/raft/src/openraft_compatibility.rs @@ -103,6 +103,7 @@ impl OpenRaftCompatibilityLayer { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/performance.rs b/src/raft/src/performance.rs index eadc2ef6..97b0df70 100644 --- a/src/raft/src/performance.rs +++ b/src/raft/src/performance.rs @@ -305,7 +305,7 @@ impl ReplicationPipeline { if let Some(queue) = follower_queue { if let Some(pos) = queue.iter().position(|req| req.request_id == request_id) { - let request = queue.remove(pos).unwrap(); + let request = queue.remove(pos).expect("position was just found"); let latency = request.sent_at.elapsed(); // Update stats @@ -356,7 +356,7 @@ impl ReplicationPipeline { for (follower_id, queue) in inflight.iter_mut() { while let Some(request) = queue.front() { if now.duration_since(request.sent_at) > request.timeout { - let expired = queue.pop_front().unwrap(); + let expired = queue.pop_front().expect("front was just checked"); expired_requests.push((*follower_id, expired.request_id)); // Update stats diff --git a/src/raft/src/placeholder_types/tests.rs b/src/raft/src/placeholder_types/tests.rs index 023f8105..b095b05f 100644 --- a/src/raft/src/placeholder_types/tests.rs +++ b/src/raft/src/placeholder_types/tests.rs @@ -17,6 +17,8 @@ //! Unit tests for placeholder types +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod tests { use super::super::*; diff --git a/src/raft/src/protocol_compatibility.rs b/src/raft/src/protocol_compatibility.rs index 7a61cce3..9e81325a 100644 --- a/src/raft/src/protocol_compatibility.rs +++ b/src/raft/src/protocol_compatibility.rs @@ -1628,6 +1628,7 @@ impl RedisProtocolCompatibility { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/redis_integration.rs b/src/raft/src/redis_integration.rs index 726087a6..1323fa91 100644 --- a/src/raft/src/redis_integration.rs +++ b/src/raft/src/redis_integration.rs @@ -751,6 +751,7 @@ impl RaftRedisHandler { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod read_routing_tests { use super::*; @@ -858,6 +859,7 @@ mod read_routing_tests { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/replication_mode.rs b/src/raft/src/replication_mode.rs index 98d2faa9..11fd7d94 100644 --- a/src/raft/src/replication_mode.rs +++ b/src/raft/src/replication_mode.rs @@ -199,6 +199,7 @@ impl ReplicationModeManager { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/rocksdb_integration/event_listener.rs b/src/raft/src/rocksdb_integration/event_listener.rs index a7c590e5..ccf9d0d0 100644 --- a/src/raft/src/rocksdb_integration/event_listener.rs +++ b/src/raft/src/rocksdb_integration/event_listener.rs @@ -148,6 +148,7 @@ impl LogIndexEventListener { // For now, we remove it to allow the code to compile // TODO: Re-implement using the correct RocksDB event listener API for version 0.23.0 +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/rocksdb_integration/table_properties_collector.rs b/src/raft/src/rocksdb_integration/table_properties_collector.rs index e95b6813..df937f30 100644 --- a/src/raft/src/rocksdb_integration/table_properties_collector.rs +++ b/src/raft/src/rocksdb_integration/table_properties_collector.rs @@ -116,6 +116,7 @@ impl LogIndexTablePropertiesCollector { // For now, we remove it to allow the code to compile // TODO: Re-implement using the correct RocksDB table properties collector API for version 0.23.0 +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/router.rs b/src/raft/src/router.rs index e10f64b1..9728c8e8 100644 --- a/src/raft/src/router.rs +++ b/src/raft/src/router.rs @@ -441,6 +441,7 @@ impl RequestRouter { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; @@ -482,6 +483,7 @@ mod tests { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] #[path = "router_tests.rs"] mod router_tests; diff --git a/src/raft/src/router_tests.rs b/src/raft/src/router_tests.rs index 57af1fe6..76117bbd 100644 --- a/src/raft/src/router_tests.rs +++ b/src/raft/src/router_tests.rs @@ -17,6 +17,8 @@ //! Tests for the RequestRouter +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod tests { use crate::node::RaftNode; diff --git a/src/raft/src/segment_log.rs b/src/raft/src/segment_log.rs index 40c8eab0..b2e1eeda 100644 --- a/src/raft/src/segment_log.rs +++ b/src/raft/src/segment_log.rs @@ -262,7 +262,9 @@ impl SegmentLog { *segment_file = Some(file); } - let file = segment_file.as_mut().unwrap(); + let file = segment_file + .as_mut() + .expect("segment file was just opened above"); // Write header and data file.write_all(&header_bytes) @@ -338,6 +340,7 @@ impl SegmentLog { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/sequence_mapping.rs b/src/raft/src/sequence_mapping.rs index 1a20d6b3..6ebffe72 100644 --- a/src/raft/src/sequence_mapping.rs +++ b/src/raft/src/sequence_mapping.rs @@ -153,6 +153,7 @@ impl Default for SequenceMappingQueue { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/serialization/tests.rs b/src/raft/src/serialization/tests.rs index b35b283f..f3560a6d 100644 --- a/src/raft/src/serialization/tests.rs +++ b/src/raft/src/serialization/tests.rs @@ -17,6 +17,8 @@ //! Unit tests for command serialization +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod tests { use super::super::*; diff --git a/src/raft/src/simple_adaptor_test.rs b/src/raft/src/simple_adaptor_test.rs index 2723e9b4..464b418a 100644 --- a/src/raft/src/simple_adaptor_test.rs +++ b/src/raft/src/simple_adaptor_test.rs @@ -17,6 +17,8 @@ // Simple test to verify OpenRaft Adaptor pattern works +#![allow(clippy::unwrap_used)] + use std::io::Cursor; use std::ops::RangeBounds; diff --git a/src/raft/src/simple_storage.rs b/src/raft/src/simple_storage.rs index fa195976..f2788209 100644 --- a/src/raft/src/simple_storage.rs +++ b/src/raft/src/simple_storage.rs @@ -53,6 +53,7 @@ pub fn create_simple_raft_storage_with_engine>( }) } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/snapshot.rs b/src/raft/src/snapshot.rs index c380ee06..7b43795b 100644 --- a/src/raft/src/snapshot.rs +++ b/src/raft/src/snapshot.rs @@ -374,6 +374,7 @@ impl SnapshotManager { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/state_machine/mod.rs b/src/raft/src/state_machine/mod.rs index 5f28a06e..0a14ed88 100644 --- a/src/raft/src/state_machine/mod.rs +++ b/src/raft/src/state_machine/mod.rs @@ -21,5 +21,6 @@ pub mod core; pub use core::{KiwiStateMachine, StateMachineSnapshot, StorageEngine}; +#[allow(clippy::unwrap_used)] #[cfg(test)] pub mod tests; diff --git a/src/raft/src/state_machine/tests.rs b/src/raft/src/state_machine/tests.rs index 028eab58..eb37ef79 100644 --- a/src/raft/src/state_machine/tests.rs +++ b/src/raft/src/state_machine/tests.rs @@ -17,6 +17,8 @@ // Simple state machine tests using working Adaptor pattern +#![allow(clippy::unwrap_used)] + use super::*; use bytes::Bytes; // Removed unused imports diff --git a/src/raft/src/storage/adaptor_tests.rs b/src/raft/src/storage/adaptor_tests.rs index 7f9942b6..d4d91110 100644 --- a/src/raft/src/storage/adaptor_tests.rs +++ b/src/raft/src/storage/adaptor_tests.rs @@ -17,6 +17,8 @@ //! Tests for RaftStorageAdaptor +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod tests { use std::sync::Arc; diff --git a/src/raft/src/storage/backend.rs b/src/raft/src/storage/backend.rs index ec46ab44..daf5d130 100644 --- a/src/raft/src/storage/backend.rs +++ b/src/raft/src/storage/backend.rs @@ -625,6 +625,7 @@ pub fn create_backend_with_options>( } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/storage/core.rs b/src/raft/src/storage/core.rs index 3ad85152..3cb0f0d9 100644 --- a/src/raft/src/storage/core.rs +++ b/src/raft/src/storage/core.rs @@ -1025,7 +1025,7 @@ impl RaftSnapshotBuilder for Arc { let snapshot_id = format!("snapshot-{}-{}", last_log_term, last_log_index); let timestamp = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs() as i64; let stored_meta = StoredSnapshotMeta { @@ -1107,7 +1107,7 @@ impl RaftSnapshotBuilder for RaftStorage { let snapshot_id = format!("snapshot-{}-{}", last_log_term, last_log_index); let timestamp = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) - .unwrap() + .expect("system time before UNIX epoch") .as_secs() as i64; let stored_meta = StoredSnapshotMeta { @@ -1166,6 +1166,7 @@ impl RaftSnapshotBuilder for RaftStorage { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod raft_log_reader_tests { use super::*; @@ -1253,6 +1254,7 @@ mod raft_log_reader_tests { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod raft_snapshot_builder_tests { use super::*; diff --git a/src/raft/src/storage/mod.rs b/src/raft/src/storage/mod.rs index 83235bc3..1ff1c7aa 100644 --- a/src/raft/src/storage/mod.rs +++ b/src/raft/src/storage/mod.rs @@ -26,8 +26,10 @@ pub use adaptor::*; pub use backend::*; pub use core::*; +#[allow(clippy::unwrap_used)] #[cfg(test)] pub mod adaptor_tests; +#[allow(clippy::unwrap_used)] #[cfg(test)] pub mod tests; diff --git a/src/raft/src/storage/tests.rs b/src/raft/src/storage/tests.rs index bf8c5d9e..95f6e172 100644 --- a/src/raft/src/storage/tests.rs +++ b/src/raft/src/storage/tests.rs @@ -17,6 +17,8 @@ //! Comprehensive unit tests for Raft storage layer +#![allow(clippy::unwrap_used)] + use super::*; use crate::error::StorageError; use crate::{LogIndex, NodeId, RaftError, Term}; diff --git a/src/raft/src/storage_engine/redis_storage_engine.rs b/src/raft/src/storage_engine/redis_storage_engine.rs index 8ab99165..bf5c67e0 100644 --- a/src/raft/src/storage_engine/redis_storage_engine.rs +++ b/src/raft/src/storage_engine/redis_storage_engine.rs @@ -263,6 +263,7 @@ impl StorageEngine for RedisStorageEngine { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/raft/src/storage_engine/tests.rs b/src/raft/src/storage_engine/tests.rs index 556c5af8..f29426f4 100644 --- a/src/raft/src/storage_engine/tests.rs +++ b/src/raft/src/storage_engine/tests.rs @@ -17,6 +17,8 @@ //! Tests for the storage engine module +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod tests { use super::super::*; diff --git a/src/raft/src/tests/adaptor_integration_tests.rs b/src/raft/src/tests/adaptor_integration_tests.rs index 8835d60b..9c9a3bac 100644 --- a/src/raft/src/tests/adaptor_integration_tests.rs +++ b/src/raft/src/tests/adaptor_integration_tests.rs @@ -19,6 +19,8 @@ //! //! These tests verify basic functionality without relying on problematic trait implementations. +#![allow(clippy::unwrap_used)] + use crate::state_machine::KiwiStateMachine; use crate::storage::RaftStorage; use crate::types::{ClientRequest, ConsistencyLevel, RedisCommand, RequestId}; diff --git a/src/raft/src/tests/concurrent_tests.rs b/src/raft/src/tests/concurrent_tests.rs index 951147a6..7a1b48ef 100644 --- a/src/raft/src/tests/concurrent_tests.rs +++ b/src/raft/src/tests/concurrent_tests.rs @@ -23,6 +23,8 @@ //! 3. The locking strategy prevents deadlocks //! 4. Performance is acceptable under concurrent load +#![allow(clippy::unwrap_used)] + use std::sync::Arc; use std::time::Duration; use tokio::time::Instant; diff --git a/src/raft/src/tests/failure_recovery_tests.rs b/src/raft/src/tests/failure_recovery_tests.rs index c08ea11f..2007bd62 100644 --- a/src/raft/src/tests/failure_recovery_tests.rs +++ b/src/raft/src/tests/failure_recovery_tests.rs @@ -22,6 +22,8 @@ //! - Snapshot recovery correctness //! - Log replay after restart +#![allow(clippy::unwrap_used)] + use crate::node::{RaftNode, RaftNodeInterface}; use crate::types::{ ClientRequest, ClusterConfig, ConsistencyLevel, NodeId, RedisCommand, RequestId, diff --git a/src/raft/src/tests/mod.rs b/src/raft/src/tests/mod.rs index 097ea111..e194f17e 100644 --- a/src/raft/src/tests/mod.rs +++ b/src/raft/src/tests/mod.rs @@ -17,6 +17,8 @@ //! Test modules for Raft implementation +#![allow(clippy::unwrap_used)] + pub mod concurrent_tests; // Integration tests for task 9: Openraft Adaptor integration diff --git a/src/raft/src/tests/raft_core_flow_tests.rs b/src/raft/src/tests/raft_core_flow_tests.rs index f0fb881f..92a1eb20 100644 --- a/src/raft/src/tests/raft_core_flow_tests.rs +++ b/src/raft/src/tests/raft_core_flow_tests.rs @@ -23,6 +23,8 @@ //! - State machine application //! - Leader election +#![allow(clippy::unwrap_used)] + use crate::node::{RaftNode, RaftNodeInterface}; use crate::types::{ ClientRequest, ClusterConfig, ConsistencyLevel, NodeId, RedisCommand, RequestId, diff --git a/src/raft/src/types/tests.rs b/src/raft/src/types/tests.rs index 507f0fd7..204733e0 100644 --- a/src/raft/src/types/tests.rs +++ b/src/raft/src/types/tests.rs @@ -17,6 +17,8 @@ //! Unit tests for core types +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod tests { use super::super::*; diff --git a/src/raft/tests/integration_tests.rs b/src/raft/tests/integration_tests.rs index 95fb93ce..efc4f7cd 100644 --- a/src/raft/tests/integration_tests.rs +++ b/src/raft/tests/integration_tests.rs @@ -16,3 +16,5 @@ // limitations under the License. //! Raft integration tests + +#![allow(clippy::unwrap_used)] diff --git a/src/raft/tests/leader_redirect_and_read_consistency_test.rs b/src/raft/tests/leader_redirect_and_read_consistency_test.rs index 49e6f7c0..13e782d3 100644 --- a/src/raft/tests/leader_redirect_and_read_consistency_test.rs +++ b/src/raft/tests/leader_redirect_and_read_consistency_test.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + use bytes::Bytes; use raft::{ RaftNode, RaftNodeInterface, diff --git a/src/raft/tests/redis_engine_integration_test.rs b/src/raft/tests/redis_engine_integration_test.rs index 3cec99ab..37878887 100644 --- a/src/raft/tests/redis_engine_integration_test.rs +++ b/src/raft/tests/redis_engine_integration_test.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + use bytes::Bytes; use raft::{ RaftNode, RaftNodeInterface, diff --git a/src/raft/tests/snapshot_and_restart_test.rs b/src/raft/tests/snapshot_and_restart_test.rs index 7d0c493e..84e59adc 100644 --- a/src/raft/tests/snapshot_and_restart_test.rs +++ b/src/raft/tests/snapshot_and_restart_test.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + use bytes::Bytes; use raft::{ RaftNode, RaftNodeInterface, diff --git a/src/resp/src/encode.rs b/src/resp/src/encode.rs index 05b0f508..c0ac4fe8 100644 --- a/src/resp/src/encode.rs +++ b/src/resp/src/encode.rs @@ -557,6 +557,7 @@ impl RespEncode for RespEncoder { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/resp/src/negotiation.rs b/src/resp/src/negotiation.rs index 4d5a16e8..cc80791c 100644 --- a/src/resp/src/negotiation.rs +++ b/src/resp/src/negotiation.rs @@ -260,6 +260,7 @@ impl ProtocolNegotiator { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/resp/src/parse.rs b/src/resp/src/parse.rs index b37f594b..e758f1b5 100644 --- a/src/resp/src/parse.rs +++ b/src/resp/src/parse.rs @@ -494,6 +494,7 @@ impl Drop for RespParse { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::Bytes; diff --git a/src/resp/src/types.rs b/src/resp/src/types.rs index 651b0a22..9ab2da2c 100644 --- a/src/resp/src/types.rs +++ b/src/resp/src/types.rs @@ -348,6 +348,7 @@ impl fmt::Debug for RespData { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/resp/tests/integration_tests.rs b/src/resp/tests/integration_tests.rs index 88759142..2fff1ef1 100644 --- a/src/resp/tests/integration_tests.rs +++ b/src/resp/tests/integration_tests.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + use bytes::Bytes; use resp::{ command::{CommandType, RespCommand}, diff --git a/src/server/src/main.rs b/src/server/src/main.rs index 1c0c6981..a8ceb063 100644 --- a/src/server/src/main.rs +++ b/src/server/src/main.rs @@ -130,10 +130,10 @@ fn main() -> std::io::Result<()> { info!("Storage components initialized, starting storage server..."); // Initialize storage server in storage runtime (runs in background) - + let db_dir = config.db_dir.clone(); storage_handle.spawn(async move { info!("Initializing storage server..."); - match initialize_storage_server(storage_receiver).await { + match initialize_storage_server(storage_receiver, &db_dir).await { Ok(_) => { error!("Storage server exited unexpectedly - this should never happen!"); } @@ -260,12 +260,13 @@ fn main() -> std::io::Result<()> { /// Initialize the storage server in the storage runtime async fn initialize_storage_server( request_receiver: tokio::sync::mpsc::Receiver, + db_dir: &str, ) -> Result<(), DualRuntimeError> { info!("Initializing storage server..."); // Create storage options and path let storage_options = Arc::new(StorageOptions::default()); - let db_path = PathBuf::from("./db"); + let db_path = PathBuf::from(db_dir); // Create storage instance (not yet opened) let mut storage = Storage::new(1, 0); // Single instance, db_id 0 diff --git a/src/storage/src/base_data_value_format.rs b/src/storage/src/base_data_value_format.rs index 58f5d361..4611bc5b 100644 --- a/src/storage/src/base_data_value_format.rs +++ b/src/storage/src/base_data_value_format.rs @@ -145,6 +145,7 @@ impl ParsedBaseDataValue { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/base_key_format.rs b/src/storage/src/base_key_format.rs index 8ef26bed..bb2c5e95 100644 --- a/src/storage/src/base_key_format.rs +++ b/src/storage/src/base_key_format.rs @@ -90,6 +90,7 @@ impl ParsedBaseKey { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/base_meta_value_format.rs b/src/storage/src/base_meta_value_format.rs index 58743e83..14129bac 100644 --- a/src/storage/src/base_meta_value_format.rs +++ b/src/storage/src/base_meta_value_format.rs @@ -236,6 +236,7 @@ impl ParsedBaseMetaValue { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod base_meta_value_tests { use bytes::Buf; @@ -324,6 +325,7 @@ mod base_meta_value_tests { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod parsed_base_meta_value_tests { use bytes::BytesMut; diff --git a/src/storage/src/base_value_format.rs b/src/storage/src/base_value_format.rs index 8d7c90e3..64ac6cf8 100644 --- a/src/storage/src/base_value_format.rs +++ b/src/storage/src/base_value_format.rs @@ -277,6 +277,7 @@ macro_rules! delegate_parsed_value { }; } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/batch.rs b/src/storage/src/batch.rs index e1e7773a..3cd3db53 100644 --- a/src/storage/src/batch.rs +++ b/src/storage/src/batch.rs @@ -284,6 +284,7 @@ impl Batch for BinlogBatch { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/cluster_storage.rs b/src/storage/src/cluster_storage.rs index 3fd69cee..702151cd 100644 --- a/src/storage/src/cluster_storage.rs +++ b/src/storage/src/cluster_storage.rs @@ -102,6 +102,7 @@ impl std::ops::Deref for ClusterStorage { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/coding.rs b/src/storage/src/coding.rs index 2bcb9229..9a8abc8d 100644 --- a/src/storage/src/coding.rs +++ b/src/storage/src/coding.rs @@ -35,7 +35,7 @@ macro_rules! impl_fixed_int_32 { } fn from_le_bytes(bytes: &[u8]) -> Self { - let arr: [u8; 4] = bytes.try_into().unwrap(); + let arr: [u8; 4] = bytes.try_into().expect("slice length mismatch"); u32::from_le_bytes(arr) as Self } } @@ -52,7 +52,7 @@ macro_rules! impl_fixed_int_64 { } fn from_le_bytes(bytes: &[u8]) -> Self { - let arr: [u8; 8] = bytes.try_into().unwrap(); + let arr: [u8; 8] = bytes.try_into().expect("slice length mismatch"); u64::from_le_bytes(arr) as Self } } @@ -79,6 +79,7 @@ pub fn decode_fixed(buf: &[u8]) -> T { T::from_le_bytes(&buf[..size]) } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { diff --git a/src/storage/src/custom_comparator.rs b/src/storage/src/custom_comparator.rs index bc350822..24e769a2 100644 --- a/src/storage/src/custom_comparator.rs +++ b/src/storage/src/custom_comparator.rs @@ -23,11 +23,13 @@ use crate::{ }; pub fn lists_data_key_comparator_name() -> CString { - CString::new("floyd.ListsDataKeyComparator").unwrap() + CString::new("floyd.ListsDataKeyComparator") + .expect("hard-coded comparator name contains no NUL bytes") } pub fn zsets_score_key_comparator_name() -> CString { - CString::new("floyd.ZSetsScoreKeyComparator").unwrap() + CString::new("floyd.ZSetsScoreKeyComparator") + .expect("hard-coded comparator name contains no NUL bytes") } /// ## ListsDataKey format @@ -195,6 +197,7 @@ pub fn zsets_score_key_compare(a: &[u8], b: &[u8]) -> Ordering { a_rest.cmp(b_rest) } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/data_compaction_filter.rs b/src/storage/src/data_compaction_filter.rs index fc9518b8..d27c20fd 100644 --- a/src/storage/src/data_compaction_filter.rs +++ b/src/storage/src/data_compaction_filter.rs @@ -246,6 +246,7 @@ impl CompactionFilterFactory for DataCompactionFilterFactory { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/expiration_manager.rs b/src/storage/src/expiration_manager.rs index f1dacefe..62e473e8 100644 --- a/src/storage/src/expiration_manager.rs +++ b/src/storage/src/expiration_manager.rs @@ -300,6 +300,7 @@ impl ExpirationManager { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/list_meta_value_format.rs b/src/storage/src/list_meta_value_format.rs index f0e61e6f..7325db49 100644 --- a/src/storage/src/list_meta_value_format.rs +++ b/src/storage/src/list_meta_value_format.rs @@ -320,6 +320,7 @@ impl ParsedListsMetaValue { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/lists_data_key_format.rs b/src/storage/src/lists_data_key_format.rs index d9c05093..8170a4e8 100644 --- a/src/storage/src/lists_data_key_format.rs +++ b/src/storage/src/lists_data_key_format.rs @@ -223,6 +223,7 @@ impl ParsedListsDataKey { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/member_data_key_format.rs b/src/storage/src/member_data_key_format.rs index 1cbabb84..112cdeea 100644 --- a/src/storage/src/member_data_key_format.rs +++ b/src/storage/src/member_data_key_format.rs @@ -113,7 +113,7 @@ impl ParsedMemberDataKey { // version let version_end_idx = key_end_idx + size_of::(); let version_slice = &encoded_key[key_end_idx..version_end_idx]; - let version = u64::from_be_bytes(version_slice.try_into().unwrap()); + let version = u64::from_be_bytes(version_slice.try_into().expect("slice length mismatch")); // data let data_slice = &encoded_key[version_end_idx..end_idx]; @@ -146,6 +146,7 @@ impl ParsedMemberDataKey { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/meta_compaction_filter.rs b/src/storage/src/meta_compaction_filter.rs index 8ef109b0..2f7f85cc 100644 --- a/src/storage/src/meta_compaction_filter.rs +++ b/src/storage/src/meta_compaction_filter.rs @@ -125,6 +125,7 @@ impl CompactionFilterFactory for MetaCompactionFilterFactory { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use chrono::Utc; diff --git a/src/storage/src/raft_integration.rs b/src/storage/src/raft_integration.rs index 6376b8fb..888c27f5 100644 --- a/src/storage/src/raft_integration.rs +++ b/src/storage/src/raft_integration.rs @@ -91,6 +91,7 @@ pub fn create_raft_storage_engine(redis: Arc) -> raft::storage_engine::Re raft::storage_engine::RedisStorageEngine::new(Arc::new(adapter)) } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/redis.rs b/src/storage/src/redis.rs index 12feea8e..34afad6e 100644 --- a/src/storage/src/redis.rs +++ b/src/storage/src/redis.rs @@ -531,7 +531,7 @@ impl Redis { Ok(self .scan_cursors_store .lock() - .unwrap() + .expect("lock poisoned") .get(&index_key) .map(|entry| entry.value().clone())) } diff --git a/src/storage/src/redis_hyperloglog.rs b/src/storage/src/redis_hyperloglog.rs index fa3292ec..c20a5b64 100644 --- a/src/storage/src/redis_hyperloglog.rs +++ b/src/storage/src/redis_hyperloglog.rs @@ -61,7 +61,7 @@ impl Redis { // Check if it's the right type if parsed_meta.data_type() != DataType::HyperLogLog { - if parsed_meta.is_expired(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()) { + if parsed_meta.is_expired(SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before UNIX epoch").as_secs()) { // Treat as not found if expired // Initialize new HyperLogLog for element in elements { @@ -72,7 +72,7 @@ impl Redis { } else { return Err(StorageError::InvalidFormat(format!("Wrong type for key: {}", String::from_utf8_lossy(key)))); } - } else if parsed_meta.is_expired(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()) { + } else if parsed_meta.is_expired(SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before UNIX epoch").as_secs()) { // Initialize new HyperLogLog if expired for element in elements { if self.hll_add_to_registers(&mut registers, element) { @@ -137,7 +137,7 @@ impl Redis { } // Check if expired - if parsed_meta.is_expired(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()) { + if parsed_meta.is_expired(SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before UNIX epoch").as_secs()) { *ret = 0; return Ok(()); } @@ -170,7 +170,7 @@ impl Redis { } // Check if expired - if parsed_meta.is_expired(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()) { + if parsed_meta.is_expired(SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before UNIX epoch").as_secs()) { continue; } @@ -223,7 +223,7 @@ impl Redis { } // Check if expired - if parsed_meta.is_expired(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()) { + if parsed_meta.is_expired(SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before UNIX epoch").as_secs()) { continue; } diff --git a/src/storage/src/redis_lists.rs b/src/storage/src/redis_lists.rs index e184f8ee..32054b2f 100644 --- a/src/storage/src/redis_lists.rs +++ b/src/storage/src/redis_lists.rs @@ -1041,8 +1041,8 @@ impl Redis { } let insert_position = match before_or_after { - BeforeOrAfter::Before => pivot_index.unwrap(), - BeforeOrAfter::After => pivot_index.unwrap() + 1, + BeforeOrAfter::Before => pivot_index.expect("pivot_index checked non-None above"), + BeforeOrAfter::After => pivot_index.expect("pivot_index checked non-None above") + 1, }; // Insert the new value at the calculated position diff --git a/src/storage/src/redis_multi.rs b/src/storage/src/redis_multi.rs index a32ca12d..a213e353 100644 --- a/src/storage/src/redis_multi.rs +++ b/src/storage/src/redis_multi.rs @@ -47,7 +47,7 @@ impl Redis { let parsed_meta = ParsedInternalValue::new(&meta_value); // Check if expired - let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); + let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before UNIX epoch").as_secs(); if parsed_meta.is_expired(now) { return Ok(0); } @@ -138,7 +138,7 @@ impl Redis { let parsed_meta = ParsedInternalValue::new(&meta_value); // Check if expired - let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); + let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before UNIX epoch").as_secs(); if parsed_meta.is_expired(now) { return Ok(false); } @@ -171,7 +171,7 @@ impl Redis { let mut parsed_meta = ParsedInternalValue::new(&meta_value); // Check if expired - let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); + let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before UNIX epoch").as_secs(); if parsed_meta.is_expired(now) { return Ok(0); } @@ -209,7 +209,7 @@ impl Redis { } // Calculate TTL - let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); + let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before UNIX epoch").as_secs(); if etime <= now { // Key has expired return Ok(-2); @@ -244,7 +244,7 @@ impl Redis { let parsed_meta = ParsedInternalValue::new(&meta_value); // Check if expired - let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); + let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before UNIX epoch").as_secs(); if parsed_meta.is_expired(now) { return Err(StorageError::KeyNotFound(String::from_utf8_lossy(key).to_string())); } @@ -396,7 +396,7 @@ impl Redis { // Get score from value let parsed_value = ParsedInternalValue::new(&value); let score_bytes = parsed_value.user_value(); - let score = f64::from_be_bytes(score_bytes[0..8].try_into().unwrap()); + let score = f64::from_be_bytes(score_bytes[0..8].try_into().expect("slice length mismatch")); // Create score key let new_score_key = self.encode_zsets_score_key(new_key, version, score, member); diff --git a/src/storage/src/redis_sets.rs b/src/storage/src/redis_sets.rs index dc1464e9..2218d5d8 100644 --- a/src/storage/src/redis_sets.rs +++ b/src/storage/src/redis_sets.rs @@ -414,7 +414,9 @@ impl Redis { let count_usize = (-count_val) as usize; let mut result = Vec::with_capacity(count_usize); for _ in 0..count_usize { - let member = all_members.choose(&mut rng).unwrap(); + let member = all_members + .choose(&mut rng) + .expect("all_members is non-empty"); result.push(member.clone()); } Ok(result) @@ -2078,7 +2080,7 @@ impl Redis { return Ok(result); } - let val = meta_val.unwrap(); + let val = meta_val.expect("meta_val checked non-None above"); // Type check self.check_type(&val, DataType::Set)?; @@ -2496,6 +2498,7 @@ pub(crate) fn glob_match(pattern: &str, text: &str) -> bool { match_recursive(&pattern_chars, &text_chars, 0, 0) } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod glob_tests { use super::glob_match; diff --git a/src/storage/src/slot_indexer.rs b/src/storage/src/slot_indexer.rs index 351f9d08..b1496e89 100644 --- a/src/storage/src/slot_indexer.rs +++ b/src/storage/src/slot_indexer.rs @@ -64,6 +64,7 @@ pub fn key_to_slot_id(key: &[u8]) -> usize { State::::calculate(key) as usize } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/storage_define.rs b/src/storage/src/storage_define.rs index ab9411b5..cffe6448 100644 --- a/src/storage/src/storage_define.rs +++ b/src/storage/src/storage_define.rs @@ -128,6 +128,7 @@ pub fn seek_userkey_delim(data: &[u8]) -> usize { data.len() } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/storage_murmur3.rs b/src/storage/src/storage_murmur3.rs index 211d4765..56356f81 100644 --- a/src/storage/src/storage_murmur3.rs +++ b/src/storage/src/storage_murmur3.rs @@ -15,6 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#[allow(clippy::unwrap_used)] #[cfg(test)] pub fn murmur3_32>(data: T, seed: u32) -> u32 { let data = data.as_ref(); @@ -72,6 +73,7 @@ pub fn murmur3_32>(data: T, seed: u32) -> u32 { hash } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests { use super::*; diff --git a/src/storage/src/strings_value_format.rs b/src/storage/src/strings_value_format.rs index a8fa022b..e90215f3 100644 --- a/src/storage/src/strings_value_format.rs +++ b/src/storage/src/strings_value_format.rs @@ -171,6 +171,7 @@ impl ParsedStringsValue { } } +#[allow(clippy::unwrap_used)] #[cfg(test)] mod tests_string_value { use super::*; @@ -221,7 +222,9 @@ mod tests_string_value { } } +#[allow(clippy::unwrap_used)] #[allow(dead_code)] +#[cfg(test)] mod tests_parsed_string_value { use super::*; diff --git a/src/storage/src/zset_score_key_format.rs b/src/storage/src/zset_score_key_format.rs index 215785a5..a9499b87 100644 --- a/src/storage/src/zset_score_key_format.rs +++ b/src/storage/src/zset_score_key_format.rs @@ -131,12 +131,12 @@ impl ParsedZSetsScoreKey { // version (little-endian) let version_slice = &encoded_key[key_end_idx..key_end_idx + size_of::()]; - let version = u64::from_le_bytes(version_slice.try_into().unwrap()); + let version = u64::from_le_bytes(version_slice.try_into().expect("slice length mismatch")); let version_end_idx = key_end_idx + size_of::(); // score (little-endian, decode from raw IEEE 754 bits) let score_slice = &encoded_key[version_end_idx..version_end_idx + size_of::()]; - let score_bits = u64::from_le_bytes(score_slice.try_into().unwrap()); + let score_bits = u64::from_le_bytes(score_slice.try_into().expect("slice length mismatch")); let score = f64::from_bits(score_bits); let score_end_idx = version_end_idx + size_of::(); diff --git a/src/storage/tests/cursor_management_test.rs b/src/storage/tests/cursor_management_test.rs index 2f80d2de..f172964e 100644 --- a/src/storage/tests/cursor_management_test.rs +++ b/src/storage/tests/cursor_management_test.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod cursor_management_test { use std::sync::Arc; diff --git a/src/storage/tests/redis_basic_test.rs b/src/storage/tests/redis_basic_test.rs index bab39124..4d1f8780 100644 --- a/src/storage/tests/redis_basic_test.rs +++ b/src/storage/tests/redis_basic_test.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod redis_basic_test { use std::sync::{Arc, atomic::Ordering}; diff --git a/src/storage/tests/redis_hash_test.rs b/src/storage/tests/redis_hash_test.rs index 8e6a003b..49a17365 100644 --- a/src/storage/tests/redis_hash_test.rs +++ b/src/storage/tests/redis_hash_test.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod redis_hash_test { use std::sync::Arc; diff --git a/src/storage/tests/redis_list_test.rs b/src/storage/tests/redis_list_test.rs index 0f8484e8..736c81f6 100644 --- a/src/storage/tests/redis_list_test.rs +++ b/src/storage/tests/redis_list_test.rs @@ -17,6 +17,8 @@ //! Unit tests for Redis list operations +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod redis_list_test { use std::sync::Arc; diff --git a/src/storage/tests/redis_set_test.rs b/src/storage/tests/redis_set_test.rs index bfe88a74..7e9251c1 100644 --- a/src/storage/tests/redis_set_test.rs +++ b/src/storage/tests/redis_set_test.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod redis_set_test { use std::sync::Arc; diff --git a/src/storage/tests/redis_string_test.rs b/src/storage/tests/redis_string_test.rs index 6ee124ae..903ebe94 100644 --- a/src/storage/tests/redis_string_test.rs +++ b/src/storage/tests/redis_string_test.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + #[cfg(test)] mod redis_string_test { use std::{sync::Arc, thread, time::Duration}; diff --git a/src/storage/tests/redis_zset_test.rs b/src/storage/tests/redis_zset_test.rs index 9d8dee1a..b6d67f47 100644 --- a/src/storage/tests/redis_zset_test.rs +++ b/src/storage/tests/redis_zset_test.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + mod redis_zset_test { use kstd::lock_mgr::LockMgr; use std::sync::Arc; diff --git a/src/storage/tests/storage_basic_test.rs b/src/storage/tests/storage_basic_test.rs index 11e32bb2..913fce71 100644 --- a/src/storage/tests/storage_basic_test.rs +++ b/src/storage/tests/storage_basic_test.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + use std::sync::Arc; use storage::storage::Storage; diff --git a/src/storage/tests/ttl_test.rs b/src/storage/tests/ttl_test.rs index 7d494deb..51fc94c7 100644 --- a/src/storage/tests/ttl_test.rs +++ b/src/storage/tests/ttl_test.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![allow(clippy::unwrap_used)] + use std::sync::Arc; use storage::{StorageOptions, storage::Storage, unique_test_db_path};