Skip to content

Commit d714ac1

Browse files
authored
Bugfix: annotation blob value syncing (#1265)
Bugfix for annotation blob value syncing, adds sync test for annotation blobs Signed-off-by: David Gilligan-Cook <dcook@imageworks.com>
1 parent 2946a9a commit d714ac1

File tree

2 files changed

+93
-2
lines changed

2 files changed

+93
-2
lines changed

crates/spfs/src/sync.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,10 @@ impl<'src, 'dst> Syncer<'src, 'dst> {
398398
match annotation.value() {
399399
AnnotationValue::String(_) => Ok(SyncAnnotationResult::InternalValue),
400400
AnnotationValue::Blob(digest) => {
401-
if !self.processed_digests.insert(*digest) {
401+
if self.processed_digests.contains(&digest) {
402+
// do not insert here because annotation blobs
403+
// share a digest with payloads which must be
404+
// visited at least once to sync
402405
return Ok(SyncAnnotationResult::Duplicate);
403406
}
404407
self.reporter.visit_annotation(&annotation);

crates/spfs/src/sync_test.rs

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use super::Syncer;
1111
use crate::config::Config;
1212
use crate::fixtures::*;
1313
use crate::prelude::*;
14-
use crate::{Error, encoding, storage, tracking};
14+
use crate::{Error, encoding, graph, storage, tracking};
1515

1616
#[rstest]
1717
#[tokio::test]
@@ -133,6 +133,94 @@ async fn test_sync_ref(
133133
assert!(repo_a.has_object(layer.digest().unwrap()).await);
134134
}
135135

136+
#[rstest]
137+
#[case::fs(tmprepo("fs"), tmprepo("fs"))]
138+
#[case::tar(tmprepo("tar"), tmprepo("tar"))]
139+
#[cfg_attr(feature = "server", case::rpc(tmprepo("rpc"), tmprepo("rpc")))]
140+
#[tokio::test]
141+
// This test just needs the config to not change while it is running.
142+
#[serial_test::serial(config)]
143+
async fn test_sync_ref_including_annotation_blob(
144+
#[case]
145+
#[future]
146+
repo_a: TempRepo,
147+
#[case]
148+
#[future]
149+
repo_b: TempRepo,
150+
tmpdir: tempfile::TempDir,
151+
) {
152+
use std::borrow::Cow;
153+
154+
use crate::graph::AnnotationValue;
155+
156+
init_logging();
157+
let repo_a = repo_a.await;
158+
let repo_b = repo_b.await;
159+
160+
let src_dir = tmpdir.path().join("source");
161+
ensure(src_dir.join("dir/file.txt"), "hello");
162+
ensure(src_dir.join("dir2/otherfile.txt"), "hello2");
163+
ensure(src_dir.join("dir//dir/dir/file.txt"), "hello, world");
164+
165+
let manifest = crate::Committer::new(&repo_a)
166+
.commit_dir(src_dir.as_path())
167+
.await
168+
.unwrap();
169+
170+
// Set up an annotation in a blob for this test
171+
let value = "this is a test annotation blob for syncing";
172+
let annotation_digest = repo_a
173+
.commit_blob(Box::pin(std::io::Cursor::new(
174+
value.to_owned().into_bytes(),
175+
)))
176+
.await
177+
.unwrap();
178+
let annotation_value = AnnotationValue::Blob(Cow::Owned(annotation_digest));
179+
let layer_with_annotation = graph::Layer::new_with_manifest_and_annotation(
180+
manifest.to_graph_manifest().digest().unwrap(),
181+
"test key",
182+
annotation_value,
183+
);
184+
repo_a.write_object(&layer_with_annotation).await.unwrap();
185+
186+
let platform = repo_a
187+
.create_platform(layer_with_annotation.digest().unwrap().into())
188+
.await
189+
.unwrap();
190+
let tag = tracking::TagSpec::parse("testing").unwrap();
191+
repo_a
192+
.push_tag(&tag, &platform.digest().unwrap())
193+
.await
194+
.unwrap();
195+
196+
Syncer::new(&repo_a, &repo_b)
197+
.sync_ref("testing")
198+
.await
199+
.expect("failed to sync ref");
200+
201+
assert!(repo_b.read_ref("testing").await.is_ok());
202+
assert!(repo_b.has_object(platform.digest().unwrap()).await);
203+
assert!(
204+
repo_b
205+
.has_object(layer_with_annotation.digest().unwrap())
206+
.await
207+
);
208+
assert!(repo_b.has_object(annotation_digest).await);
209+
210+
Syncer::new(&repo_b, &repo_a)
211+
.sync_ref("testing")
212+
.await
213+
.expect("failed to sync back");
214+
215+
assert!(repo_a.read_ref("testing").await.is_ok());
216+
assert!(
217+
repo_a
218+
.has_object(layer_with_annotation.digest().unwrap())
219+
.await
220+
);
221+
assert!(repo_a.has_object(annotation_digest).await);
222+
}
223+
136224
#[rstest]
137225
#[case::fs(tmprepo("fs"), tmprepo("fs"))]
138226
#[case::tar(tmprepo("tar"), tmprepo("tar"))]

0 commit comments

Comments
 (0)