diff --git a/src/borg/archive.py b/src/borg/archive.py index a2c23abb9f..ceffbb9e17 100644 --- a/src/borg/archive.py +++ b/src/borg/archive.py @@ -142,11 +142,15 @@ def show_progress(self, item=None, final=False, stream=None, dt=None): if dt is None or now - self.last_progress > dt: self.last_progress = now if self.output_json: - data = self.as_dict() + if not final: + data = self.as_dict() + data['path'] = remove_surrogates(item.path if item else '') + else: + data = {} data.update({ 'time': time.time(), 'type': 'archive_progress', - 'path': remove_surrogates(item.path if item else ''), + 'finished': final, }) msg = json.dumps(data) end = '\n' diff --git a/src/borg/testsuite/archive.py b/src/borg/testsuite/archive.py index db9ed573b5..3f8535ff5a 100644 --- a/src/borg/testsuite/archive.py +++ b/src/borg/testsuite/archive.py @@ -1,3 +1,4 @@ +import json from collections import OrderedDict from datetime import datetime, timezone from io import StringIO @@ -61,6 +62,34 @@ def test_stats_format(stats): assert repr(stats) == f'' +def test_stats_progress_json(stats): + stats.output_json = True + + out = StringIO() + stats.show_progress(item=Item(path='foo'), stream=out) + result = json.loads(out.getvalue()) + assert result['type'] == 'archive_progress' + assert isinstance(result['time'], float) + assert result['finished'] is False + assert result['path'] == 'foo' + assert result['original_size'] == 20 + assert result['compressed_size'] == 10 + assert result['deduplicated_size'] == 10 + assert result['nfiles'] == 0 # this counter gets updated elsewhere + + out = StringIO() + stats.show_progress(stream=out, final=True) + result = json.loads(out.getvalue()) + assert result['type'] == 'archive_progress' + assert isinstance(result['time'], float) + assert result['finished'] is True # see #6570 + assert 'path' not in result + assert 'original_size' not in result + assert 'compressed_size' not in result + assert 'deduplicated_size' not in result + assert 'nfiles' not in result + + class MockCache: class MockRepo: