Skip to content

Commit ea4007f

Browse files
committed
expand tests
1 parent 4756f5e commit ea4007f

File tree

4 files changed

+87
-8
lines changed

4 files changed

+87
-8
lines changed

src/aiida/cmdline/commands/cmd_archive.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ class ExtrasImportCode(Enum):
338338
'--extras-mode-new',
339339
type=click.Choice(EXTRAS_MODE_NEW),
340340
default='import',
341-
help='Specify whether to import extras of new nodes: ' 'import: import extras. ' 'none: do not import extras.',
341+
help='Specify whether to import extras of new nodes: import: import extras. none: do not import extras.',
342342
)
343343
@click.option(
344344
'--comment-mode',

src/aiida/tools/archive/create.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ def querybuilder():
247247
entity_ids[EntityTypes.USER].add(entry.pk)
248248
else:
249249
raise ArchiveExportError(
250-
f'I was given {entry} ({type(entry)}),' ' which is not a User, Node, Computer, or Group instance'
250+
f'I was given {entry} ({type(entry)}), which is not a User, Node, Computer, or Group instance'
251251
)
252252
group_nodes, link_data = _collect_required_entities(
253253
querybuilder,
@@ -712,7 +712,7 @@ def _check_unsealed_nodes(querybuilder: QbType, node_ids: set[int], batch_size:
712712
if unsealed_node_pks:
713713
raise ExportValidationError(
714714
'All ProcessNodes must be sealed before they can be exported. '
715-
f"Node(s) with PK(s): {', '.join(str(pk) for pk in unsealed_node_pks)} is/are not sealed."
715+
f'Node(s) with PK(s): {", ".join(str(pk) for pk in unsealed_node_pks)} is/are not sealed.'
716716
)
717717

718718

@@ -803,18 +803,18 @@ def get_init_summary(
803803
"""Get summary for archive initialisation"""
804804
parameters = [['Path', str(outfile)], ['Version', archive_version], ['Compression', compression]]
805805

806-
result = f"\n{tabulate(parameters, headers=['Archive Parameters', ''])}"
806+
result = f'\n{tabulate(parameters, headers=["Archive Parameters", ""])}'
807807

808808
inclusions = [
809809
['Computers/Nodes/Groups/Users', 'All' if collect_all else 'Selected'],
810810
['Computer Authinfos', include_authinfos],
811811
['Node Comments', include_comments],
812812
['Node Logs', include_logs],
813813
]
814-
result += f"\n\n{tabulate(inclusions, headers=['Inclusion rules', ''])}"
814+
result += f'\n\n{tabulate(inclusions, headers=["Inclusion rules", ""])}'
815815

816816
if not collect_all:
817-
rules_table = [[f"Follow links {' '.join(name.split('_'))}s", value] for name, value in traversal_rules.items()]
818-
result += f"\n\n{tabulate(rules_table, headers=['Traversal rules', ''])}"
817+
rules_table = [[f'Follow links {" ".join(name.split("_"))}s', value] for name, value in traversal_rules.items()]
818+
result += f'\n\n{tabulate(rules_table, headers=["Traversal rules", ""])}'
819819

820820
return result + '\n'

tests/cmdline/commands/test_archive_create.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,17 @@ def test_info_empty_archive(run_cli_command):
208208
filename_input = get_archive_file('empty.aiida', filepath='export/migrate')
209209
result = run_cli_command(cmd_archive.archive_info, [filename_input], raises=True)
210210
assert 'archive file unreadable' in result.output
211+
212+
213+
def test_create_tmp_dir_option(run_cli_command, tmp_path):
214+
"""Test that the --tmp-dir CLI option passes through correctly."""
215+
node = Dict().store()
216+
217+
custom_tmp = tmp_path / 'custom_tmp'
218+
custom_tmp.mkdir()
219+
filename_output = tmp_path / 'archive.aiida'
220+
221+
options = ['--tmp-dir', str(custom_tmp), '-N', node.pk, '--', filename_output]
222+
223+
run_cli_command(cmd_archive.create, options)
224+
assert filename_output.is_file()

tests/tools/archive/test_simple.py

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ def crashing_filter(_):
158158

159159

160160
@pytest.mark.usefixtures('aiida_profile_clean')
161-
def test_tmp_dir(tmp_path, aiida_profile_clean):
161+
def test_tmp_dir_basic(tmp_path):
162162
"""Test that tmp_dir parameter is used correctly."""
163163
node = orm.Int(42).store()
164164
custom_tmp = tmp_path / 'custom_tmp'
@@ -201,3 +201,68 @@ def mock_temp_dir_error(*args, **kwargs):
201201
with patch('tempfile.TemporaryDirectory', side_effect=mock_temp_dir_error):
202202
with pytest.raises(ArchiveExportError, match='Insufficient disk space.*--tmp-dir'):
203203
create_archive([node], filename=filename, tmp_dir=custom_tmp)
204+
205+
206+
@pytest.mark.usefixtures('aiida_profile_clean')
207+
def test_tmp_dir_auto_create(tmp_path):
208+
"""Test automatic creation of non-existent tmp_dir."""
209+
node = orm.Int(42).store()
210+
filename = tmp_path / 'export.aiida'
211+
custom_tmp = tmp_path / 'nonexistent_tmp' # Don't create it!
212+
213+
create_archive([node], filename=filename, tmp_dir=custom_tmp)
214+
assert filename.exists()
215+
# Verify the directory was created
216+
assert custom_tmp.exists()
217+
218+
219+
@pytest.mark.usefixtures('aiida_profile_clean')
220+
def test_tmp_dir_permission_error(tmp_path):
221+
"""Test tmp_dir permission validation."""
222+
import stat
223+
224+
node = orm.Int(42).store()
225+
filename = tmp_path / 'export.aiida'
226+
readonly_tmp = tmp_path / 'readonly_tmp'
227+
readonly_tmp.mkdir()
228+
229+
# Make directory read-only
230+
readonly_tmp.chmod(stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
231+
232+
try:
233+
with pytest.raises(ArchiveExportError, match='is not writable'):
234+
create_archive([node], filename=filename, tmp_dir=readonly_tmp)
235+
finally:
236+
# Restore permissions for cleanup
237+
readonly_tmp.chmod(stat.S_IRWXU)
238+
239+
240+
@pytest.mark.usefixtures('aiida_profile_clean')
241+
def test_tmp_dir_default_behavior(tmp_path):
242+
"""Test default tmp_dir behavior (no tmp_dir specified)."""
243+
node = orm.Int(42).store()
244+
filename = tmp_path / 'export.aiida'
245+
246+
# Don't specify tmp_dir - test the default path
247+
create_archive([node], filename=filename)
248+
assert filename.exists()
249+
250+
251+
@pytest.mark.usefixtures('aiida_profile_clean')
252+
def test_tmp_dir_general_os_error(tmp_path):
253+
"""Test general OS error handling."""
254+
from unittest.mock import patch
255+
256+
node = orm.Int(42).store()
257+
custom_tmp = tmp_path / 'custom_tmp'
258+
custom_tmp.mkdir()
259+
filename = tmp_path / 'export.aiida'
260+
261+
def mock_temp_dir_error(*args, **kwargs):
262+
error = OSError('Permission denied')
263+
error.errno = 13 # Different from 28
264+
raise error
265+
266+
with patch('aiida.tools.archive.create.tempfile.TemporaryDirectory', side_effect=mock_temp_dir_error):
267+
with pytest.raises(ArchiveExportError, match='Failed to create temporary directory'):
268+
create_archive([node], filename=filename, tmp_dir=custom_tmp)

0 commit comments

Comments
 (0)