mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-05-24 00:09:19 -04:00
Enhance test cleanup by adding core shutdown logic
This commit adds core shutdown logic to multiple test scenarios in the `file_copy_pull_test.rs` and `volume_tracking_test.rs` files. The shutdown ensures that file descriptors are released after test completion, improving resource management and preventing potential leaks. This change enhances the reliability of the tests by ensuring a clean state after execution.
This commit is contained in:
@@ -196,6 +196,11 @@ async fn alice_pull_source_scenario() {
|
||||
}
|
||||
|
||||
println!("Alice: PULL source test completed");
|
||||
|
||||
// Cleanup: shutdown core to release file descriptors
|
||||
core.shutdown()
|
||||
.await
|
||||
.expect("Failed to shutdown Alice core");
|
||||
}
|
||||
|
||||
/// Bob's role in PULL test - initiates PULL to get files from Alice
|
||||
@@ -505,6 +510,9 @@ async fn bob_pull_receiver_scenario() {
|
||||
}
|
||||
|
||||
println!("Bob: PULL test completed");
|
||||
|
||||
// Cleanup: shutdown core to release file descriptors
|
||||
core.shutdown().await.expect("Failed to shutdown Bob core");
|
||||
}
|
||||
|
||||
/// Main test orchestrator for PULL operations
|
||||
@@ -566,4 +574,4 @@ async fn test_file_copy_pull() {
|
||||
panic!("PULL transfer test failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,6 +235,9 @@ async fn test_volume_tracking_lifecycle() {
|
||||
}
|
||||
|
||||
info!("Volume tracking lifecycle test completed successfully");
|
||||
|
||||
// Cleanup: shutdown core to release file descriptors
|
||||
core.shutdown().await.expect("Failed to shutdown core");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -440,6 +443,9 @@ async fn test_volume_tracking_multiple_libraries() {
|
||||
);
|
||||
|
||||
info!("Multiple library volume tracking test completed successfully");
|
||||
|
||||
// Cleanup: shutdown core to release file descriptors
|
||||
core.shutdown().await.expect("Failed to shutdown core");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -503,6 +509,9 @@ async fn test_automatic_system_volume_tracking() {
|
||||
}
|
||||
|
||||
info!("Automatic system volume tracking test completed");
|
||||
|
||||
// Cleanup: shutdown core to release file descriptors
|
||||
core.shutdown().await.expect("Failed to shutdown core");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -592,6 +601,9 @@ async fn test_auto_tracking_disabled() {
|
||||
}
|
||||
|
||||
info!("Manual tracking control test completed");
|
||||
|
||||
// Cleanup: shutdown core to release file descriptors
|
||||
core.shutdown().await.expect("Failed to shutdown core");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -683,6 +695,9 @@ async fn test_volume_state_updates() {
|
||||
);
|
||||
|
||||
info!("Volume state update test completed");
|
||||
|
||||
// Cleanup: shutdown core to release file descriptors
|
||||
core.shutdown().await.expect("Failed to shutdown core");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -762,6 +777,9 @@ async fn test_volume_speed_test() {
|
||||
}
|
||||
|
||||
info!("Volume speed test completed");
|
||||
|
||||
// Cleanup: shutdown core to release file descriptors
|
||||
core.shutdown().await.expect("Failed to shutdown core");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -842,6 +860,9 @@ async fn test_volume_types_and_properties() {
|
||||
|
||||
// Should have at least one system volume
|
||||
assert!(system_count > 0, "Should detect at least one system volume");
|
||||
|
||||
// Cleanup: shutdown core to release file descriptors
|
||||
core.shutdown().await.expect("Failed to shutdown core");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -971,6 +992,9 @@ async fn test_volume_tracking_persistence() {
|
||||
}
|
||||
|
||||
info!("Volume tracking persistence test completed");
|
||||
|
||||
// Cleanup: shutdown core to release file descriptors
|
||||
core.shutdown().await.expect("Failed to shutdown core");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -1096,6 +1120,9 @@ async fn test_volume_tracking_edge_cases() {
|
||||
}
|
||||
|
||||
info!("Volume edge cases test completed");
|
||||
|
||||
// Cleanup: shutdown core to release file descriptors
|
||||
core.shutdown().await.expect("Failed to shutdown core");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -1164,6 +1191,9 @@ async fn test_volume_refresh_and_detection() {
|
||||
}
|
||||
|
||||
info!("Volume refresh and detection test completed");
|
||||
|
||||
// Cleanup: shutdown core to release file descriptors
|
||||
core.shutdown().await.expect("Failed to shutdown core");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -1268,4 +1298,7 @@ async fn test_volume_monitor_service() {
|
||||
// Don't stop the monitor as it's managed by Core
|
||||
|
||||
info!("Volume monitor service test completed");
|
||||
|
||||
// Cleanup: shutdown core to release file descriptors
|
||||
core.shutdown().await.expect("Failed to shutdown core");
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Tag as TagIcon, Plus } from '@phosphor-icons/react';
|
||||
import { Tag as TagIcon, Plus, CaretRight } from '@phosphor-icons/react';
|
||||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import clsx from 'clsx';
|
||||
@@ -98,25 +98,34 @@ export function TagsGroup({
|
||||
const createTag = useLibraryMutation('tags.create');
|
||||
|
||||
// Fetch tags with real-time updates using search with empty query
|
||||
const { data: tagsData, isLoading } = useNormalizedQuery({
|
||||
// Using select to normalize TagSearchResult[] to Tag[] for consistent cache structure
|
||||
const { data: tags = [], isLoading } = useNormalizedQuery({
|
||||
wireMethod: 'query:tags.search',
|
||||
input: { query: '' },
|
||||
resourceType: 'tag'
|
||||
resourceType: 'tag',
|
||||
select: (data: any) => data?.tags?.map((result: any) => result.tag || result).filter(Boolean) ?? []
|
||||
});
|
||||
|
||||
// Extract tags from search results
|
||||
// Handle both TagSearchResult ({ tag, relevance, ... }) and raw Tag objects
|
||||
// (resource events may inject raw Tag objects into the cache)
|
||||
const tags = tagsData?.tags?.map((result: any) => result.tag || result).filter(Boolean) ?? [];
|
||||
|
||||
const handleCreateTag = async () => {
|
||||
if (!newTagName.trim()) return;
|
||||
|
||||
try {
|
||||
const result = await createTag.mutateAsync({
|
||||
canonical_name: newTagName.trim(),
|
||||
display_name: null,
|
||||
formal_name: null,
|
||||
abbreviation: null,
|
||||
aliases: [],
|
||||
namespace: null,
|
||||
tag_type: null,
|
||||
color: `#${Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0')}`,
|
||||
icon: null,
|
||||
description: null,
|
||||
is_organizational_anchor: null,
|
||||
privacy_level: null,
|
||||
search_weight: null,
|
||||
attributes: null,
|
||||
apply_to: null
|
||||
});
|
||||
|
||||
// Navigate to the new tag
|
||||
|
||||
@@ -36,17 +36,14 @@ export function TagSelector({
|
||||
const createTag = useLibraryMutation('tags.create');
|
||||
|
||||
// Fetch all tags using search with empty query
|
||||
const { data: tagsData } = useNormalizedQuery({
|
||||
// Using select to normalize TagSearchResult[] to Tag[] for consistent cache structure
|
||||
const { data: allTags = [] } = useNormalizedQuery({
|
||||
wireMethod: 'query:tags.search',
|
||||
input: { query: '' },
|
||||
resourceType: 'tag'
|
||||
resourceType: 'tag',
|
||||
select: (data: any) => data?.tags?.map((result: any) => result.tag || result).filter(Boolean) ?? []
|
||||
});
|
||||
|
||||
// Extract tags from search results
|
||||
// Handle both TagSearchResult ({ tag, relevance, ... }) and raw Tag objects
|
||||
// (resource events may inject raw Tag objects into the cache)
|
||||
const allTags = tagsData?.tags?.map((result: any) => result.tag || result).filter(Boolean) ?? [];
|
||||
|
||||
// Check if query matches an existing tag
|
||||
const exactMatch = allTags.find(
|
||||
tag => tag.canonical_name.toLowerCase() === query.toLowerCase()
|
||||
|
||||
@@ -26,13 +26,14 @@ import { useEffect, useMemo, useState, useRef } from "react";
|
||||
import { useQuery, useQueryClient, QueryClient } from "@tanstack/react-query";
|
||||
import { useSpacedriveClient } from "./useClient";
|
||||
import type { Event } from "../generated/types";
|
||||
import type { SdPath } from "../types";
|
||||
import invariant from "tiny-invariant";
|
||||
import * as v from "valibot";
|
||||
import type { Simplify } from "type-fest";
|
||||
|
||||
// Types
|
||||
|
||||
export type UseNormalizedQueryOptions<I> = Simplify<{
|
||||
export type UseNormalizedQueryOptions<I, O = any, TSelected = O> = Simplify<{
|
||||
/** Wire method to call (e.g., "query:files.directory_listing") */
|
||||
wireMethod: string;
|
||||
/** Input for the query */
|
||||
@@ -42,13 +43,15 @@ export type UseNormalizedQueryOptions<I> = Simplify<{
|
||||
/** Whether query is enabled (default: true) */
|
||||
enabled?: boolean;
|
||||
/** Optional path scope for server-side filtering */
|
||||
pathScope?: any; // SdPath type
|
||||
pathScope?: SdPath;
|
||||
/** Whether to include descendants (recursive) or only direct children (exact) */
|
||||
includeDescendants?: boolean;
|
||||
/** Resource ID for single-resource queries */
|
||||
resourceId?: string;
|
||||
/** Enable debug logging for this query instance */
|
||||
debug?: boolean;
|
||||
/** Optional select function to transform query data */
|
||||
select?: (data: O) => TSelected;
|
||||
}>;
|
||||
|
||||
// Runtime Validation Schemas (Valibot)
|
||||
@@ -93,8 +96,8 @@ const ResourceDeletedSchema = v.object({
|
||||
/**
|
||||
* useNormalizedQuery - Main hook
|
||||
*/
|
||||
export function useNormalizedQuery<I, O>(
|
||||
options: UseNormalizedQueryOptions<I>,
|
||||
export function useNormalizedQuery<I, O = any, TSelected = O>(
|
||||
options: UseNormalizedQueryOptions<I, O, TSelected>,
|
||||
) {
|
||||
const client = useSpacedriveClient();
|
||||
const queryClient = useQueryClient();
|
||||
@@ -121,7 +124,7 @@ export function useNormalizedQuery<I, O>(
|
||||
);
|
||||
|
||||
// Standard TanStack Query
|
||||
const query = useQuery<O>({
|
||||
const query = useQuery<O, Error, TSelected>({
|
||||
queryKey,
|
||||
queryFn: async () => {
|
||||
invariant(libraryId, "Library ID must be set before querying");
|
||||
@@ -131,6 +134,7 @@ export function useNormalizedQuery<I, O>(
|
||||
);
|
||||
},
|
||||
enabled: (options.enabled ?? true) && !!libraryId,
|
||||
select: options.select,
|
||||
});
|
||||
|
||||
// Refs for stable access to latest values without triggering re-subscription
|
||||
@@ -796,4 +800,4 @@ export function safeMerge(
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user