Skip to content

Conversation

@kans
Copy link
Contributor

@kans kans commented Jan 2, 2026

One test was incorrectly passing in the case that we couldn't decode a c1z (ie, we didn't cleanup the directory).

Summary by CodeRabbit

  • Refactor

    • Improved decompression flow with robust resource cleanup and consistent temporary-directory handling; now returns additional diagnostic working-directory info and ensures dirs/files are closed/removed on all error and success paths.
  • Tests

    • Updated tests to verify working-directory creation, cleanup behavior, and temporary-directory placement for both success and error scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 2, 2026

Walkthrough

Replaces internal c1z loader with a decompressor that returns both a decompressed DB file path and the temporary working directory. Adds centralized cleanup to close opened resources and remove temporary dirs on error/success; call sites and tests updated to the new signature.

Changes

Cohort / File(s) Summary
Core refactor
pkg/dotc1z/file.go
loadC1z removed and replaced by decompressC1z(c1zPath, workingDir, ...opts) (dbPath, workingDir, error). Introduces cleanupDir closure to close decoder/files and remove temp dir on error and finalization; consolidates resource management and error propagation.
Call sites updated
pkg/dotc1z/c1file.go, pkg/dotc1z/dotc1z.go
Calls switched to decompressC1z(...). pkg/dotc1z/dotc1z.go captures dbFilePath, _, err and proceeds with NewC1File; pkg/dotc1z/c1file.go calls decompress and ignores the extra returned value where unused.
Tests updated
pkg/dotc1z/file_test.go
Tests updated to expect (dbPath, workingDir, err) from decompressC1z, added assertions for working-dir cleanup on error and that workingDir is created under the provided tmp dir on success.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • jirwin

Poem

🐰 I hopped through folders, soft and spry,
Unwrapped the c1z with careful eye,
I closed each latch, swept every track,
Tidied the paths and put files back,
Now cleaner trails let bytes hop by 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'More tempdir cleanup' is vague and generic, using non-specific language that doesn't clearly convey the main technical change being implemented. Consider using a more descriptive title that explains the specific improvement, such as 'Add proper tempdir cleanup on decode errors' or 'Ensure temporary directories are cleaned up when C1Z decompression fails'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4187470 and 2182588.

📒 Files selected for processing (4)
  • pkg/dotc1z/c1file.go
  • pkg/dotc1z/dotc1z.go
  • pkg/dotc1z/file.go
  • pkg/dotc1z/file_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/dotc1z/dotc1z.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-01-02T17:21:01.723Z
Learnt from: ggreer
Repo: ConductorOne/baton-sdk PR: 616
File: pkg/synccompactor/compactor_test.go:44-52
Timestamp: 2026-01-02T17:21:01.723Z
Learning: In tests that verify cleanup behavior (e.g., ensuring temporary artifacts are removed or directories are empty after an operation), treat cleanup failures as test failures by asserting on the cleanup call (e.g., require.NoError(t, err) or assert.NoError(t, err)). This ensures that the cleanup path is explicitly tested and any cleanup error fails the test, confirming correct behavior of the cleanup code.

Applied to files:

  • pkg/dotc1z/file_test.go
🧬 Code graph analysis (1)
pkg/dotc1z/file.go (1)
pkg/dotc1z/decoder.go (2)
  • DecoderOption (57-57)
  • NewDecoder (209-242)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: go-test (1.25.2, ubuntu-latest)
  • GitHub Check: go-test (1.25.2, windows-latest)
  • GitHub Check: go-lint
🔇 Additional comments (3)
pkg/dotc1z/file_test.go (1)

15-48: LGTM! Cleanup verification tests are well structured.

The tests properly verify that:

  1. Temporary directories are cleaned up on decode errors (line 28)
  2. Working directories are created in the specified location (line 46)

The use of require.NoDirExists and require.Contains ensures cleanup behavior is explicitly tested, aligning with best practices for cleanup verification.

pkg/dotc1z/file.go (2)

18-21: Comment fix applied correctly.

The typo identified in the previous review ("taht" → "that") has been fixed. The comment now accurately describes the function's behavior and return values.


21-94: Well-structured cleanup implementation.

The refactored decompressC1z properly handles resource cleanup:

  • Creates its own temporary directory for better isolation
  • Defines a centralized cleanupDir function that closes all resources in the correct order
  • Calls cleanup on all error paths and the success path
  • Only removes the temporary directory on error (leaves it intact on success for the caller to use)
  • Uses errors.Join to accumulate multiple errors

The approach of returning the working directory as a second value enables test verification of cleanup behavior, which aligns with the PR objectives.


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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
pkg/dotc1z/dotc1z.go (1)

52-58: Potential resource leak if NewC1File fails.

If decompressC1z succeeds but NewC1File fails (line 58), the temporary directory is not cleaned up. Consider cleaning up the working directory on error:

🔎 Proposed fix
 func NewExternalC1FileReader(ctx context.Context, tmpDir string, externalResourceC1ZPath string) (connectorstore.Reader, error) {
-	dbFilePath, _, err := decompressC1z(externalResourceC1ZPath, tmpDir)
+	dbFilePath, workingDir, err := decompressC1z(externalResourceC1ZPath, tmpDir)
 	if err != nil {
 		return nil, fmt.Errorf("error loading external resource c1z file: %w", err)
 	}

-	return NewC1File(ctx, dbFilePath)
+	c1File, err := NewC1File(ctx, dbFilePath)
+	if err != nil {
+		_ = os.RemoveAll(workingDir)
+		return nil, err
+	}
+	return c1File, nil
 }
🧹 Nitpick comments (2)
pkg/dotc1z/file_test.go (1)

31-47: Missing cleanup of workingDir in successful test case.

The "custom tmpDir" test creates a working directory that persists after the test. While t.TempDir() handles tmpDir cleanup, the created workingDir contains the db file and should be explicitly cleaned up to follow the pattern from the error case test:

🔎 Proposed fix
 	t.Run("custom tmpDir", func(t *testing.T) {
 		tmpDir := t.TempDir()
 		customTmpDir := filepath.Join(tmpDir, "custom")
 		err := os.MkdirAll(customTmpDir, 0755)
 		require.NoError(t, err)
 		defer os.RemoveAll(customTmpDir)

 		nonExistentPath := filepath.Join(tmpDir, "nonexistent2.c1z")
 		dbPath, workingDir, err := decompressC1z(nonExistentPath, customTmpDir)
 		require.NoError(t, err)
 		require.NotEmpty(t, dbPath)
 		require.FileExists(t, dbPath)
+		defer os.RemoveAll(workingDir)

 		// Verify it was created in the custom tmpDir
 		require.Contains(t, dbPath, customTmpDir)
 		require.Contains(t, workingDir, customTmpDir)
 	})
pkg/dotc1z/file.go (1)

64-68: Consider distinguishing "not found" from other errors.

The current logic treats all os.Stat errors the same as a zero-size file, but some errors (e.g., permission denied) may warrant different handling. This could mask real issues:

🔎 Proposed improvement
 	stat, err := os.Stat(c1zPath)
-	if err != nil || stat.Size() == 0 {
-		// TODO(kans): it would be nice to know more about the error....
+	if err != nil {
+		if !os.IsNotExist(err) {
+			// Non-trivial error (permission denied, etc.) - propagate it
+			return "", tmpDir, cleanupDir(err)
+		}
+		// File doesn't exist - treat as "create new"
+		return dbFilePath, tmpDir, cleanupDir(nil)
+	}
+	if stat.Size() == 0 {
+		// Empty file - treat as "create new"
 		return dbFilePath, tmpDir, cleanupDir(nil)
 	}
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e03e6e2 and a7188ca.

📒 Files selected for processing (4)
  • pkg/dotc1z/c1file.go
  • pkg/dotc1z/dotc1z.go
  • pkg/dotc1z/file.go
  • pkg/dotc1z/file_test.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-01-02T17:21:01.723Z
Learnt from: ggreer
Repo: ConductorOne/baton-sdk PR: 616
File: pkg/synccompactor/compactor_test.go:44-52
Timestamp: 2026-01-02T17:21:01.723Z
Learning: In tests that verify cleanup behavior (e.g., ensuring temporary artifacts are removed or directories are empty after an operation), treat cleanup failures as test failures by asserting on the cleanup call (e.g., require.NoError(t, err) or assert.NoError(t, err)). This ensures that the cleanup path is explicitly tested and any cleanup error fails the test, confirming correct behavior of the cleanup code.

Applied to files:

  • pkg/dotc1z/file_test.go
🧬 Code graph analysis (1)
pkg/dotc1z/file.go (1)
pkg/dotc1z/decoder.go (2)
  • DecoderOption (57-57)
  • NewDecoder (209-242)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: go-test (1.25.2, windows-latest)
🔇 Additional comments (2)
pkg/dotc1z/c1file.go (1)

190-193: LGTM!

The second return value (tmpDir) is correctly ignored here because cleanup is already handled by C1File.Close() via cleanupDbDir(c.dbFilePath, ...) which removes filepath.Dir(dbFilePath) — effectively the same directory.

pkg/dotc1z/file.go (1)

30-56: LGTM!

The cleanup closure correctly handles resource cleanup in reverse order of creation and properly joins errors. The conditional removal of tmpDir only on error is correct — on success, the caller takes ownership of the directory.

@kans kans force-pushed the kans/cleanup-temp-dir-on-decode-error branch from a7188ca to 4187470 Compare January 3, 2026 00:04
@kans kans force-pushed the kans/cleanup-temp-dir-on-decode-error branch from 4187470 to 2182588 Compare January 5, 2026 17:30
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
pkg/dotc1z/c1file.go (1)

191-211: Resource leak if NewC1File fails.

If decompressC1z succeeds but NewC1File fails (line 208), the temporary directory created by decompressC1z is not cleaned up, leading to a resource leak.

🔎 Proposed fix
 	c1File, err := NewC1File(ctx, dbFilePath, c1fopts...)
 	if err != nil {
-		return nil, err
+		return nil, cleanupDbDir(dbFilePath, err)
 	}
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4187470 and 2182588.

📒 Files selected for processing (4)
  • pkg/dotc1z/c1file.go
  • pkg/dotc1z/dotc1z.go
  • pkg/dotc1z/file.go
  • pkg/dotc1z/file_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/dotc1z/dotc1z.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-01-02T17:21:01.723Z
Learnt from: ggreer
Repo: ConductorOne/baton-sdk PR: 616
File: pkg/synccompactor/compactor_test.go:44-52
Timestamp: 2026-01-02T17:21:01.723Z
Learning: In tests that verify cleanup behavior (e.g., ensuring temporary artifacts are removed or directories are empty after an operation), treat cleanup failures as test failures by asserting on the cleanup call (e.g., require.NoError(t, err) or assert.NoError(t, err)). This ensures that the cleanup path is explicitly tested and any cleanup error fails the test, confirming correct behavior of the cleanup code.

Applied to files:

  • pkg/dotc1z/file_test.go
🧬 Code graph analysis (1)
pkg/dotc1z/file.go (1)
pkg/dotc1z/decoder.go (2)
  • DecoderOption (57-57)
  • NewDecoder (209-242)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: go-test (1.25.2, ubuntu-latest)
  • GitHub Check: go-test (1.25.2, windows-latest)
  • GitHub Check: go-lint
🔇 Additional comments (3)
pkg/dotc1z/file_test.go (1)

15-48: LGTM! Cleanup verification tests are well structured.

The tests properly verify that:

  1. Temporary directories are cleaned up on decode errors (line 28)
  2. Working directories are created in the specified location (line 46)

The use of require.NoDirExists and require.Contains ensures cleanup behavior is explicitly tested, aligning with best practices for cleanup verification.

pkg/dotc1z/file.go (2)

18-21: Comment fix applied correctly.

The typo identified in the previous review ("taht" → "that") has been fixed. The comment now accurately describes the function's behavior and return values.


21-94: Well-structured cleanup implementation.

The refactored decompressC1z properly handles resource cleanup:

  • Creates its own temporary directory for better isolation
  • Defines a centralized cleanupDir function that closes all resources in the correct order
  • Calls cleanup on all error paths and the success path
  • Only removes the temporary directory on error (leaves it intact on success for the caller to use)
  • Uses errors.Join to accumulate multiple errors

The approach of returning the working directory as a second value enables test verification of cleanup behavior, which aligns with the PR objectives.

@kans kans merged commit 267b919 into main Jan 5, 2026
6 checks passed
@kans kans deleted the kans/cleanup-temp-dir-on-decode-error branch January 5, 2026 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants