From 803e4c8150dde1e466e116961499b8b9586098d7 Mon Sep 17 00:00:00 2001 From: Alexander Rolfes <9316893+Wiseqube@users.noreply.github.com> Date: Tue, 10 Sep 2024 09:15:43 +0200 Subject: [PATCH] Fix sync writing __source__ falsely into frozen layers (#130) --- CHANGELOG | 4 ++++ perfact/zodbsync/tests/test_sync.py | 36 ++++++++++++++++++++++++++++- perfact/zodbsync/zodbsync.py | 3 +-- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 446cf8b..e12761e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +23.1.3+dev.2 + * Fixed a bug where zodbsync was writing `source`-files into frozen + layers + 23.1.2+dev.1 * Fix layer-update for cases where the last element in both checksum files is not the same. diff --git a/perfact/zodbsync/tests/test_sync.py b/perfact/zodbsync/tests/test_sync.py index 47a00f9..dfdd044 100644 --- a/perfact/zodbsync/tests/test_sync.py +++ b/perfact/zodbsync/tests/test_sync.py @@ -1654,7 +1654,7 @@ def test_playback_hook_failed(self): assert 'NewFolder2' not in self.app.objectIds() @contextmanager - def addlayer(self, seqnum='00'): + def addlayer(self, seqnum='00', frozen=True): """ Create a temp directory and add a config that uses this as additional code layer. @@ -1666,6 +1666,7 @@ def addlayer(self, seqnum='00'): with tempfile.TemporaryDirectory() as layer: with open(path, 'w') as f: f.write('base_dir = "{}"\n'.format(layer)) + f.write('frozen = {}\n'.format(frozen)) os.mkdir(os.path.join(layer, '__root__')) # Force re-reading config if hasattr(self, 'runner'): @@ -2152,3 +2153,36 @@ def test_layer_update_warn(self, caplog): assert expect + '/Test' in caplog.text assert 'AttributeError' not in caplog.text assert expect + '/ToDelete/Sub' in caplog.text + + def test_layer_frozen(self): + """ + Verify that changed files are properly written into the custom + layer in case the layer below is frozen. + """ + with self.runner.sync.tm: + self.app.manage_addProduct['OFSP'].manage_addFile(id='blob') + + with self.addlayer(frozen=True) as layer: + self.run('record', '/blob') + shutil.move( + '{}/__root__/blob'.format(self.repo.path), + '{}/__root__/blob'.format(layer), + ) + with self.runner.sync.tm: + self.app.blob.manage_edit( + filedata='text_content', + content_type='text/plain', + title='BLOB' + ) + self.run('record', '/') + root = os.path.join(self.repo.path, '__root__') + # both meta and source file are in custom layer + assert os.path.exists(os.path.join(root, 'blob/__meta__')) + assert os.path.exists(os.path.join(root, 'blob/__source__.txt')) + source_fmt = '{}/__root__/blob/__source__.txt' + with open(source_fmt.format(layer)) as f: + # source in layer should still be empty + assert f.read() == '' + with open(source_fmt.format(self.repo.path)) as f: + # ... content is in custom layer! + assert f.read() == 'text_content' diff --git a/perfact/zodbsync/zodbsync.py b/perfact/zodbsync/zodbsync.py index 9a3dd54..85cf1c0 100644 --- a/perfact/zodbsync/zodbsync.py +++ b/perfact/zodbsync/zodbsync.py @@ -470,7 +470,6 @@ def fs_write(self, path, data): obj_id=path.rstrip('/').rsplit('/', 1)[-1], ) src_fname = '{}.{}'.format(base, ext) - src_path = os.path.join(base_dir, src_fname) new_data['src_fnames'] = [src_fname] new_data['source'] = source @@ -494,7 +493,7 @@ def fs_write(self, path, data): self.logger.debug( "Will write %d bytes of source" % len(source) ) - with open(src_path, 'wb') as f: + with open(os.path.join(write_base, src_fname), 'wb') as f: f.write(source) # We wrote the object to the topmost layer, so the index where the