folder_test.v

3.3 KB · raw

1module remote23import os45fn scratch(name string) !string {6	dir := os.join_path(os.temp_dir(), 'koh3_remote_${os.getpid()}_${name}')7	os.rmdir_all(dir) or {}8	os.mkdir_all(dir, os.MkdirParams{})!9	return dir10}1112fn test_a_missing_key_is_not_an_error() {13	base := scratch('missing')!14	defer {15		os.rmdir_all(base) or {}16	}17	mut backend := new_folder(base)!18	object := backend.get('repo/nothing')!19	assert !object.found20	assert object.body.len == 021}2223fn test_put_if_absent_refuses_a_second_write() {24	base := scratch('absent')!25	defer {26		os.rmdir_all(base) or {}27	}28	mut backend := new_folder(base)!29	assert backend.put_if_absent('repo/objects/abc', 'first'.bytes())!30	assert !backend.put_if_absent('repo/objects/abc', 'second'.bytes())!31	object := backend.get('repo/objects/abc')!32	assert object.body == 'first'.bytes()33	assert object.tag == tag_of('first'.bytes())34}3536fn test_put_if_match_only_swaps_the_version_that_was_read() {37	base := scratch('match')!38	defer {39		os.rmdir_all(base) or {}40	}41	mut backend := new_folder(base)!42	backend.put_if_absent('repo/head', 'one'.bytes())!43	tag := backend.get('repo/head')!.tag4445	// A stale tag loses.46	assert !backend.put_if_match('repo/head', 'two'.bytes(), 'a-stale-tag')!47	assert backend.get('repo/head')!.body == 'one'.bytes()4849	// The current tag wins.50	assert backend.put_if_match('repo/head', 'two'.bytes(), tag)!51	assert backend.get('repo/head')!.body == 'two'.bytes()5253	// An absent key can only be created when the caller read it as absent.54	assert !backend.put_if_match('repo/fresh', 'x'.bytes(), tag)!55	assert backend.put_if_match('repo/created', 'x'.bytes(), '')!56	assert backend.get('repo/created')!.found57}5859fn test_list_walks_the_prefix() {60	base := scratch('list')!61	defer {62		os.rmdir_all(base) or {}63	}64	mut backend := new_folder(base)!65	backend.put_if_absent('repo/saves/aaa', 'a'.bytes())!66	backend.put_if_absent('repo/saves/bbb', 'b'.bytes())!67	backend.put_if_absent('repo/objects/ccc', 'c'.bytes())!68	assert backend.list('repo/saves')! == ['repo/saves/aaa', 'repo/saves/bbb']69	assert backend.list('repo/nothing')!.len == 07071	// A writer mid-publish, or one that died, leaves its own files behind.72	// They are not keys: a listing that returned them would send steal after73	// events and saves that do not exist.74	os.write_file(os.join_path(base, 'repo/saves/ddd.tmp-4242'), 'half')!75	os.write_file(os.join_path(base, 'repo/saves/aaa.lock'), '4242')!76	os.write_file(os.join_path(base, 'repo/saves/aaa.lock.4242.1790000000'), '4242')!77	assert backend.list('repo/saves')! == ['repo/saves/aaa', 'repo/saves/bbb']78}7980fn test_delete_removes_the_key() {81	base := scratch('delete')!82	defer {83		os.rmdir_all(base) or {}84	}85	mut backend := new_folder(base)!86	backend.put_if_absent('repo/objects/abc', 'gone'.bytes())!87	backend.delete('repo/objects/abc')!88	assert !backend.get('repo/objects/abc')!.found89}9091fn test_check_passes_on_a_working_remote_and_leaves_nothing_behind() {92	base := scratch('check')!93	defer {94		os.rmdir_all(base) or {}95	}96	mut backend := new_folder(base)!97	check(mut backend)!98	assert !backend.get(probe_key)!.found99100	// A check interrupted after its first write leaves the probe behind; the101	// next check must not mistake it for a remote that refuses writes.102	backend.put_if_absent(probe_key, 'left over'.bytes())!103	check(mut backend)!104	assert !backend.get(probe_key)!.found105}