Skip to content

Latest commit

 

History

History
179 lines (131 loc) · 8.97 KB

File metadata and controls

179 lines (131 loc) · 8.97 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Overview

This is a comprehensive test suite for pCloud's sync functionality. It tests file synchronization between local drives and pCloud's cloud storage using real pCloud Drive instances. Tests verify data integrity using SHA1 checksums.

The test suite supports two testing modes:

  • Drive Mode: Tests with mounted virtual drive
  • Sync Folder Mode: Tests with both a mounted virtual drive and a regular folder synced via pCloud app

Project Structure

fstests/
├── tests/                          # Test suite
│   ├── conftest.py                 # Shared pytest fixtures
│   ├── drive/                     # Virtual Drive mode tests
│   │   └── conftest.py            # Drive-specific fixtures (VirtualDriveHelper)
│   ├── sync/                       # Sync Folder mode tests
│   │   └── conftest.py            # Sync-specific fixtures (SyncFolderHelper)
├── utils/                          # Helper utilities
│   ├── pcloud_helper.py            # pCloud API wrapper
│   ├── file_operations.py          # Local file operations hepler
│   ├── virtual_drive_helper.py     # Virtual drive helper
│   ├── sync_folder_helper.py       # Sync folder helper
│   ├── test_helper.py              # Base class for drive/sync helpers
│   └── test_context.py             # A test case helper. Used by each test to perform various operations
├── .env.example                    # Example configuration
├── requirements.txt                # Python dependencies
└── pytest.ini                      # Pytest configuration

Setup and Configuration

Initial Setup

Check README.md for instructions on how to set up and configure the project.

Running Tests

Check README.md for instructions on how to run tests.

Architecture

Core Helper Classes

The test suite is built around helper classes in utils/:

1. PCloudHelper (utils/pcloud_helper.py)

  • Wrapper for pCloud API operations
  • You must use this class whenever you need to communicate with the pCloud API.

2. TestHelper (utils/test_helper.py)

  • A base class for the other two file system helpers.
  • All methods and properties used by the TestContext class must be first declared here. If there would be no difference between the implementation for methods/properties in any of the subclasses, then the implementation should be added in this class. Otherwise, the implementation in this class should just throw an exception specifying that this method must be implemented in subclasses.
  • Provides a folder within which all tests would run.

3. VirtualDriveHelper (utils/virtual_drive_helper.py)

  • A subclass of TestHelper.
  • Provides specialized methods and properties when working in drive-only mode.
  • Works with real mounted drive filesystem
  • Instantiated by tests/drive/conftest.py

4. SyncFolderHelper (utils/sync_folder_helper.py)

  • A subclass of TestHelper.
  • Provides specialized methods and properties when working in drive+sync mode.
  • Works with real mounted drive filesystem
  • Instantiated by tests/sync/conftest.py
  • Supports triple verification (sync folder → cloud → virtual drive)

5. FileOperations (utils/file_operations.py)

  • Local file system operations
  • All local file system operations must go through here.

6. TestContext (utils/test_context.py)

  • The class used by all test methods.
  • It exposes API for the test methods.
  • Provides a test folder (inside the TestHelper's test folder) unique for each test method.

Pytest Fixtures

Key fixtures:

  • sync_helper: Helper instance provided by per-directory conftest files (tests/drive/conftest.py or tests/sync/conftest.py). Not used by tests directly. Tests use it via the test_subfolder fixture.
  • test_subfolder: The TestContext context class which provides an isolated test subfolder and operations that can be used by methods. Defined in tests/conftest.py.
  • pcloud: Direct pCloud API access. Defined in tests/conftest.py.

Development Guidelines

Strong typing

Use strong types everywhere and write type-safe code. Make sure to check the types of function parameters and return value before calling a function or if modifying the handling of its return value. Same thing for properties. There must be no hidden classes that are used in multiple places. No Any types.

SOLID

Follow the SOLID principle. Write clean, easy-to-read and maintainable code.

  • Avoid making the same variable in multiple places. Make it easy to swap values. Whenever you see that you're creating the same variable with the same value in multiple places, consider storing it in a local variable.
  • Avoid duplicating logic and code in helpers. Prefer to extract common logic in methods and call those methods where needed.

Comments

Only comment API for helpers and other used by the tests. Don't comment the implementation details unless it is not obvious what the code does. Don't comment the tests unless the code is convoluted and/or long and it is not obvious what the test does or how it does it.

Code style

This project uses ruff to maintain code style. After you finish making changes to files, run the following commands to fix linter errors and reformat:

ruff check . --fix
ruff format .

Note that after you run those commands, the files you just modified would have changed. If you need to apply further changes, you need to read them again.

Test Markers

Tests use a two-dimension marker scheme:

Speed tier (exactly one per test, mutually exclusive):

  • essential — fast, high-value tests suitable for per-commit runs. Simple CRUD, basic sync verification, small files.
  • extended — thorough but not punishing tests for nightly/PR runs. Larger files (50MB+), multi-step workflows, advanced conflict scenarios.
  • stress — heavy, large-scale tests for weekly/manual runs. Hundreds of files, GB-sized files, concurrent operations, combined workflows.
  • manual — requires human intervention or specific hardware setup.

Functional area (one or more per test):

  • filesystem — all drive-mode tests (in tests/drive/)
  • sync — all sync-folder-mode tests (in tests/sync/)

How to apply markers:

  • For files where all tests share the same speed tier, use module-level pytestmark:
    pytestmark = [pytest.mark.essential, pytest.mark.filesystem]
  • For files with mixed speed tiers, use module-level for the area marker and per-function decorators for speed:
    pytestmark = [pytest.mark.filesystem]
    
    @pytest.mark.essential
    def test_simple(test_subfolder): ...
    
    @pytest.mark.extended
    def test_heavy(test_subfolder): ...

Adding New Tests

  • Every new test must include appropriate speed tier and area markers.
  • Plan carefully how you would approach each test case. Think about what needs to be tested and the minimum amount of steps that need to be taken to unequivocally test this case.
  • Place tests in appropriate file under tests/
  • Use test_subfolder fixture when making any local/remote file I/O.
  • Follow naming: test_descriptive_name
  • Use FileOperations for local file I/O only when you need access to files/folders outside the test subfolder.
  • Use pcloud fixture when you need direct access to the pCloud API and the test_subfolder does not provide a useful method/property. First think about adding such method to the test_subfolder (and adding it to the TestHelper and subclasses). use the test_subfolder helper.
  • Use the default timeout for methods unless necessary to reduce/increase it.
  • Always conform to the helper method parameter types.
  • Always wait for any local modifications to sync to the cloud and vice versa to verify file operations. If running multiple file operations, prefer to first batch all local I/O and then check for remote existence or vice-versa. This makes sure the tests aren't needlessly slow as all batched file operations will get synced quicker compared to performing them one by one and then waiting.

Example test structure:

def test_my_new_feature(test_subfolder):
    """Test description"""
    # Create test file
    test_subfolder.create_file('test.txt', content='content')

    # Wait to sync
    assert test_subfolder.wait_for_file_sync('test.txt')

Working with Helpers

When modifying helper classes:

  • Both VirtualDriveHelper and SyncFolderHelper must support same interface inherited by TestHelper. They must not override methods that don't require to be overridden in the base class.
  • Always work with Path when doing any local file I/O. This makes sure tests run on both Linux/macOS and Windows.
  • Always work with PurePosixPath when working with any paths outside of local file I/O. This makes sure you don't make random mistakes with path construction/parsing.

Troubleshooting

Check README.md for troubleshooting tips.