in eden/mononoke/derived_data/fsnodes/derive.rs [586:859]
fn nested_directories_test(fb: FacebookInit) {
let runtime = Runtime::new().unwrap();
let repo = runtime.block_on(ManyFilesDirs::getrepo(fb));
let derivation_ctx = repo.repo_derived_data().manager().derivation_context(None);
let ctx = CoreContext::test_mock(fb);
// Derive fsnodes for the first two commits. We will look at commit 3 and 4.
let parent_fsnode_id = {
let parent_hg_cs = "5a28e25f924a5d209b82ce0713d8d83e68982bc8";
let (_bcs_id, bcs) = runtime
.block_on(bonsai_changeset_from_hg(&ctx, &repo, parent_hg_cs))
.unwrap();
let f = derive_fsnode(&ctx, &derivation_ctx, vec![], get_file_changes(&bcs));
runtime.block_on(f).unwrap()
};
let parent_fsnode_id = {
let parent_hg_cs = "2f866e7e549760934e31bf0420a873f65100ad63";
let (_bcs_id, bcs) = runtime
.block_on(bonsai_changeset_from_hg(&ctx, &repo, parent_hg_cs))
.unwrap();
let f = derive_fsnode(
&ctx,
&derivation_ctx,
vec![parent_fsnode_id.clone()],
get_file_changes(&bcs),
);
runtime.block_on(f).unwrap()
};
let parent_fsnode_id = {
let parent_hg_cs = "d261bc7900818dea7c86935b3fb17a33b2e3a6b4";
let (_bcs_id, bcs) = runtime
.block_on(bonsai_changeset_from_hg(&ctx, &repo, parent_hg_cs))
.unwrap();
let f = derive_fsnode(
&ctx,
&derivation_ctx,
vec![parent_fsnode_id.clone()],
get_file_changes(&bcs),
);
let root_fsnode_id = runtime.block_on(f).unwrap();
// Make sure it's saved in the blobstore.
let root_fsnode = runtime
.block_on(root_fsnode_id.load(&ctx, repo.blobstore()))
.unwrap();
// Make sure the fsnodes describe the full manifest.
let all_fsnodes: BTreeMap<_, _> = runtime
.block_on(
iterate_all_manifest_entries(&ctx, &repo, Entry::Tree(root_fsnode_id))
.try_collect(),
)
.unwrap();
assert_eq!(
all_fsnodes.keys().collect::<Vec<_>>(),
vec![
&None,
&Some(MPath::new("1").unwrap()),
&Some(MPath::new("2").unwrap()),
&Some(MPath::new("dir1").unwrap()),
&Some(MPath::new("dir1/file_1_in_dir1").unwrap()),
&Some(MPath::new("dir1/file_2_in_dir1").unwrap()),
&Some(MPath::new("dir1/subdir1").unwrap()),
&Some(MPath::new("dir1/subdir1/file_1").unwrap()),
&Some(MPath::new("dir1/subdir1/subsubdir1").unwrap()),
&Some(MPath::new("dir1/subdir1/subsubdir1/file_1").unwrap()),
&Some(MPath::new("dir1/subdir1/subsubdir2").unwrap()),
&Some(MPath::new("dir1/subdir1/subsubdir2/file_1").unwrap()),
&Some(MPath::new("dir1/subdir1/subsubdir2/file_2").unwrap()),
&Some(MPath::new("dir2").unwrap()),
&Some(MPath::new("dir2/file_1_in_dir2").unwrap()),
]
);
// Make sure the root fsnode is correct. Test the simple format hashes are as expected.
let simple_format_sha1 = {
let text = concat!(
"e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e file 1\0",
"7448d8798a4380162d4b56f9b452e2f6f9e24e7a file 2\0",
"be0dface7b74d8a69b39fb4691ef9eee36077ede tree dir1\0",
"ad02b5a5f778d9ad6afd42fcc8e0b889254b5215 tree dir2\0",
);
let mut digest = sha1::Sha1::new();
digest.input(&text);
let bytes = digest.result().into();
Sha1::from_byte_array(bytes)
};
let simple_format_sha256 = {
let text = concat!(
"4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 file 1\0",
"53c234e5e8472b6ac51c1ae1cab3fe06fad053beb8ebfd8977b010655bfdd3c3 file 2\0",
"eebf7e41f348db6b31c11fe7adf577bd0951300436a1fd37e53d628127b3517e tree dir1\0",
"583c3d388efb78eb9dec46626662d6657bb53706c1ee10770c0fb3e859bd36e1 tree dir2\0",
);
let mut digest = sha2::Sha256::new();
digest.input(&text);
let bytes = digest.result().into();
Sha256::from_byte_array(bytes)
};
assert_eq!(
root_fsnode.summary(),
&FsnodeSummary {
simple_format_sha1,
simple_format_sha256,
child_files_count: 2,
child_files_total_size: 4,
child_dirs_count: 2,
descendant_files_count: 9,
descendant_files_total_size: 67,
}
);
// Check one of the deeper fsnodes.
let deep_fsnode_id = match all_fsnodes.get(&Some(MPath::new("dir1/subdir1").unwrap())) {
Some(Entry::Tree(fsnode_id)) => fsnode_id,
_ => panic!("dir1/subdir1 fsnode should be a tree"),
};
let deep_fsnode = runtime
.block_on(deep_fsnode_id.load(&ctx, repo.blobstore()))
.unwrap();
let deep_fsnode_entries: Vec<_> = deep_fsnode.list().collect();
assert_eq!(
deep_fsnode_entries,
vec![
(
&MPathElement::new(b"file_1".to_vec()).unwrap(),
&FsnodeEntry::File(FsnodeFile::new(
ContentId::from_str(
"271119c630193464c55cf7feb72c16dd18b953e65ee85047d4d956381cdb96d9",
)
.unwrap(),
FileType::Regular,
9,
Sha1::from_str("eba7b799b1e587506677c108eaa51ca273ddcfdc").unwrap(),
Sha256::from_str(
"8bfab644c313b0227b1862786426697a9b5283eea8eb6066cc8d8e134ce0daa6",
)
.unwrap(),
)),
),
(
&MPathElement::new(b"subsubdir1".to_vec()).unwrap(),
&FsnodeEntry::Directory(FsnodeDirectory::new(
FsnodeId::from_str(
"a8deafcaa9fdafad84447d754b1e24140f1113e68b3f7ec17c55a4fd9c90fdc7",
)
.unwrap(),
FsnodeSummary {
simple_format_sha1: Sha1::from_str(
"b58f168a508c4388f496b21acee468b13b89ac50",
)
.unwrap(),
simple_format_sha256: Sha256::from_str(
"dc19c9a55b59d97dbb2912e5acb1bad17c1aa2835c4cf288f2d47bb0b0b539bc",
)
.unwrap(),
child_files_count: 1,
child_files_total_size: 9,
child_dirs_count: 0,
descendant_files_count: 1,
descendant_files_total_size: 9,
},
)),
),
(
&MPathElement::new(b"subsubdir2".to_vec()).unwrap(),
&FsnodeEntry::Directory(FsnodeDirectory::new(
FsnodeId::from_str(
"3daadf48916e4b25e28e21a15de4352188154fcaa749207eb00fb72dbd812343",
)
.unwrap(),
FsnodeSummary {
simple_format_sha1: Sha1::from_str(
"89babd6eab901598b3df0a0c3318b83bd2edfa4b",
)
.unwrap(),
simple_format_sha256: Sha256::from_str(
"5fa3074b0a96f8ac8f5ab31266d1ce95b1c84a35e8b3f4b8108385881e9e9f15",
)
.unwrap(),
child_files_count: 2,
child_files_total_size: 18,
child_dirs_count: 0,
descendant_files_count: 2,
descendant_files_total_size: 18,
},
)),
),
]
);
assert_eq!(
deep_fsnode.summary(),
&FsnodeSummary {
simple_format_sha1: Sha1::from_str("56daa486e90686b5ead6f3ce360a6cbb7b73f23f")
.unwrap(),
simple_format_sha256: Sha256::from_str(
"8c24cf135f74933775b0ac1453c127c987874beb6fde5454ccf9c6c8c726e032"
)
.unwrap(),
child_files_count: 1,
child_files_total_size: 9,
child_dirs_count: 2,
descendant_files_count: 4,
descendant_files_total_size: 36,
}
);
root_fsnode_id
};
{
let child_hg_cs = "051946ed218061e925fb120dac02634f9ad40ae2";
let (_bcs_id, bcs) = runtime
.block_on(bonsai_changeset_from_hg(&ctx, &repo, child_hg_cs))
.unwrap();
let f = derive_fsnode(
&ctx,
&derivation_ctx,
vec![parent_fsnode_id.clone()],
get_file_changes(&bcs),
);
let root_fsnode_id = runtime.block_on(f).unwrap();
// Make sure it's saved in the blobstore
let root_fsnode = runtime
.block_on(root_fsnode_id.load(&ctx, repo.blobstore()))
.unwrap();
// Make sure the fsnodes describe the full manifest.
let all_fsnodes: BTreeMap<_, _> = runtime
.block_on(
iterate_all_manifest_entries(&ctx, &repo, Entry::Tree(root_fsnode_id))
.try_collect(),
)
.unwrap();
assert_eq!(
all_fsnodes.keys().collect::<Vec<_>>(),
vec![
&None,
&Some(MPath::new("1").unwrap()),
&Some(MPath::new("2").unwrap()),
&Some(MPath::new("dir1").unwrap()),
&Some(MPath::new("dir2").unwrap()),
&Some(MPath::new("dir2/file_1_in_dir2").unwrap()),
]
);
// Make sure the root fsnode is correct.
assert_eq!(
root_fsnode.summary(),
&FsnodeSummary {
simple_format_sha1: Sha1::from_str("753b41c7bf23bda7eabb71095867c2ddf3e485df")
.unwrap(),
simple_format_sha256: Sha256::from_str(
"d86a29b0e92bcbff179e20a27fde18aacedc225a6c4884a7760d2880794c9e51"
)
.unwrap(),
child_files_count: 3,
child_files_total_size: 16,
child_dirs_count: 1,
descendant_files_count: 4,
descendant_files_total_size: 25,
}
);
}
}