Skip to content

test_native_upload_by_handler - Directory label does not match #39

@pdurbin

Description

@pdurbin

I'm on 87c694d and testing the "unstable" image, which is Dataverse as of IQSS/dataverse@111e091 (post 6.7.1).

test_native_upload_by_handler is failing with "Directory label does not match". That is to say, the name of the directory.

% python -m pytest -v           
======================================= test session starts =======================================
platform darwin -- Python 3.13.3, pytest-8.4.1, pluggy-1.6.0 -- /Users/PDurbin/github/gdcc/python-dvuploader/venv/bin/python
cachedir: .pytest_cache
rootdir: /Users/PDurbin/github/gdcc/python-dvuploader
configfile: pyproject.toml
plugins: asyncio-1.1.0, httpx-0.35.0, anyio-4.10.0, cov-6.2.1
asyncio: mode=Mode.AUTO, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collected 34 items                                                                                

tests/integration/test_native_upload.py::TestNativeUpload::test_native_upload PASSED        [  2%]
tests/integration/test_native_upload.py::TestNativeUpload::test_forced_native_upload PASSED [  5%]
tests/integration/test_native_upload.py::TestNativeUpload::test_native_upload_with_proxy PASSED [  8%]
tests/integration/test_native_upload.py::TestNativeUpload::test_native_upload_by_handler FAILED [ 11%]
tests/integration/test_native_upload.py::TestNativeUpload::test_native_upload_with_large_tabular_files_loop PASSED [ 14%]
tests/integration/test_native_upload.py::TestNativeUpload::test_native_upload_with_large_tabular_files PASSED [ 17%]
tests/integration/test_native_upload.py::TestNativeUpload::test_native_upload_with_large_tabular_files_parallel PASSED [ 20%]
tests/integration/test_native_upload.py::TestNativeUpload::test_zip_file_upload PASSED      [ 23%]
tests/integration/test_native_upload.py::TestNativeUpload::test_zipzip_file_upload PASSED   [ 26%]
tests/integration/test_native_upload.py::TestNativeUpload::test_too_many_zip_files PASSED   [ 29%]
tests/unit/test_cli.py::TestParseYAMLConfig::test_full_input PASSED                         [ 32%]
tests/unit/test_cli.py::TestCLIMain::test_kwarg_arg_input PASSED                            [ 35%]
tests/unit/test_cli.py::TestCLIMain::test_recurse PASSED                                    [ 38%]
tests/unit/test_cli.py::TestCLIMain::test_yaml_input PASSED                                 [ 41%]
tests/unit/test_cli.py::TestCLIMain::test_no_input PASSED                                   [ 44%]
tests/unit/test_directupload.py::Test_AddFileToDs::test_successfully_add_file_with_valid_filepath PASSED [ 47%]
tests/unit/test_directupload.py::Test_AddFileToDs::test_successfully_replace_file_with_valid_filepath PASSED [ 50%]
tests/unit/test_directupload.py::Test_AddFileToDs::test_successfully_add_and_replace_file_with_valid_filepath PASSED [ 52%]
tests/unit/test_directupload.py::Test_ValidateTicketResponse::test_no_exceptions_when_fields_present PASSED [ 55%]
tests/unit/test_directupload.py::Test_ValidateTicketResponse::test_raises_assertion_error_when_abort_field_missing PASSED [ 58%]
tests/unit/test_file.py::TestFile::test_read_file PASSED                                    [ 61%]
tests/unit/test_file.py::TestFile::test_read_non_existent_file PASSED                       [ 64%]
tests/unit/test_file.py::TestFile::test_read_non_file PASSED                                [ 67%]
tests/unit/test_utils.py::TestAddDirectory::test_all_files_added_except_hidden PASSED       [ 70%]
tests/unit/test_utils.py::TestAddDirectory::test_all_files_added_except_hidden_and_dunder PASSED [ 73%]
tests/unit/test_utils.py::TestBuildUrl::test_returns_endpoint_if_no_query_parameters PASSED [ 76%]
tests/unit/test_utils.py::TestBuildUrl::test_returns_complete_URL_with_query_parameters PASSED [ 79%]
tests/unit/test_utils.py::TestBuildUrl::test_handles_query_parameters_with_integer_values PASSED [ 82%]
tests/unit/test_utils.py::TestBuildUrl::test_returns_endpoint_without_question_mark_if_empty_dictionary PASSED [ 85%]
tests/unit/test_utils.py::TestBuildUrl::test_raises_TypeError_if_endpoint_not_string PASSED [ 88%]
tests/unit/test_utils.py::TestBuildUrl::test_raises_TypeError_if_query_parameter_keys_not_strings PASSED [ 91%]
tests/unit/test_utils.py::TestRetrieveDatasetFiles::test_return_files_list PASSED           [ 94%]
tests/unit/test_utils.py::TestRetrieveDatasetFiles::test_raise_http_error PASSED            [ 97%]
tests/unit/test_utils.py::TestSetupPbar::test_returns_progress_bar_object PASSED            [100%]

============================================ FAILURES =============================================
_________________________ TestNativeUpload.test_native_upload_by_handler __________________________

self = <tests.integration.test_native_upload.TestNativeUpload object at 0x107bc6fd0>
credentials = ('http://localhost:8080', 'b645ba0f-eff8-4697-89d5-ad6c9fde8b96')

    def test_native_upload_by_handler(
        self,
        credentials,
    ):
        BASE_URL, API_TOKEN = credentials
    
        # Arrange
        byte_string = b"Hello, World!"
        files = [
            File(
                filepath="subdir/file.txt",
                handler=BytesIO(byte_string),
                description="This is a test",
            ),
            File(
                filepath="biggerfile.txt",
                handler=BytesIO(byte_string * 10000),
                description="This is a test",
            ),
        ]
    
        # Create Dataset
        pid = create_dataset(
            parent="Root",
            server_url=BASE_URL,
            api_token=API_TOKEN,
        )
    
        # Act
        uploader = DVUploader(files=files)
        uploader.upload(
            persistent_id=pid,
            api_token=API_TOKEN,
            dataverse_url=BASE_URL,
            n_parallel_uploads=1,
        )
    
        # Assert
        expected = [
            ("", "biggerfile.txt"),
            ("subdir", "file.txt"),
        ]
    
        files = retrieve_dataset_files(
            dataverse_url=BASE_URL,
            persistent_id=pid,
            api_token=API_TOKEN,
        )
    
        assert len(files) == 2
    
        for ex_dir, ex_f in expected:
            file = next(file for file in files if file["label"] == ex_f)
    
            assert file["label"] == ex_f, (
                f"File label does not match for file {json.dumps(file)}"
            )
    
>           assert file.get("directoryLabel", "") == ex_dir, (
                f"Directory label does not match for file {json.dumps(file)}"
            )
E           AssertionError: Directory label does not match for file {"description": "", "label": "file.txt", "restricted": false, "version": 1, "datasetVersionId": 4, "categories": ["DATA"], "dataFile": {"id": 16, "persistentId": "", "filename": "file.txt", "contentType": "text/plain", "friendlyType": "Plain Text", "filesize": 13, "description": "", "categories": ["DATA"], "storageIdentifier": "local://198c79fc9ca-f998aa3fe2fa", "rootDataFileId": -1, "md5": "65a8e27d8879283831b664bd8b7f0ad4", "checksum": {"type": "MD5", "value": "65a8e27d8879283831b664bd8b7f0ad4"}, "tabularData": false, "creationDate": "2025-08-20", "lastUpdateTime": "2025-08-20T13:16:35Z", "fileAccessRequest": false}}
E           assert '' == 'subdir'
E             
E             - subdir

tests/integration/test_native_upload.py:218: AssertionError
-------------------------------------- Captured stdout call ---------------------------------------


╭───────── DVUploader ──────────╮
│ Server: http://localhost:8080 │
│ PID: doi:10.5072/FK2/RAEX7Q   │
│ Files: 2                      │
╰───────────────────────────────╯
🔎 Checking dataset files           
┏━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━┓
┃ File           ┃ Status ┃ Action ┃
┡━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━┩
│ file.txt       │ New    │ Upload │
│ biggerfile.txt │ New    │ Upload │
└────────────────┴────────┴────────┘

⚠️  Direct upload not supported. Falling back to Native API.

🚀 Uploading files

(
    'File subdir/file.txt not found in Dataverse repository.',
    'This may be due to the file not being uploaded to the repository:'
)
package_0.zip ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00

✅ Upload complete

======================================== warnings summary =========================================
tests/integration/test_native_upload.py: 10 warnings
tests/unit/test_cli.py: 3 warnings
  /Users/PDurbin/github/gdcc/python-dvuploader/venv/lib/python3.13/site-packages/httpx/_models.py:408: DeprecationWarning: Use 'content=<...>' to upload raw bytes/text content.
    headers, stream = encode_request(

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
========================================= tests coverage ==========================================
________________________ coverage: platform darwin, python 3.13.3-final-0 _________________________

Name                         Stmts   Miss  Cover
------------------------------------------------
dvuploader/__init__.py           7      0   100%
dvuploader/checksum.py          36     12    67%
dvuploader/cli.py               47      4    91%
dvuploader/config.py             7      5    29%
dvuploader/directupload.py     146     92    37%
dvuploader/dvuploader.py       107     22    79%
dvuploader/file.py              49      3    94%
dvuploader/nativeupload.py     122      4    97%
dvuploader/packaging.py         35      4    89%
dvuploader/utils.py             47      0   100%
------------------------------------------------
TOTAL                          603    146    76%
===================================== short test summary info =====================================
FAILED tests/integration/test_native_upload.py::TestNativeUpload::test_native_upload_by_handler - AssertionError: Directory label does not match for file {"description": "", "label": "file.txt", "restricted": false, "version": 1, "datasetVersionId": 4, "categories": ["DATA"], "dataFile": {"id": 16, "persistentId": "", "filename": "file.txt", "contentType": "text/plain", "friendlyType": "Plain Text", "filesize": 13, "description": "", "categories": ["DATA"], "storageIdentifier": "local://198c79fc9ca-f998aa3fe2fa", "rootDataFileId": -1, "md5": "65a8e27d8879283831b664bd8b7f0ad4", "checksum": {"type": "MD5", "value": "65a8e27d8879283831b664bd8b7f0ad4"}, "tabularData": false, "creationDate": "2025-08-20", "lastUpdateTime": "2025-08-20T13:16:35Z", "fileAccessRequest": false}}
assert '' == 'subdir'
  
  - subdir
====================== 1 failed, 33 passed, 13 warnings in 107.59s (0:01:47) ======================

We've seen this failure in recent PRs:

I wonder if the change in behavior relates to this PR that was merged for Dataverse 6.7:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions