/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define C_LUCY_CHARBUF #include "Lucy/Util/ToolSet.h" #include "Lucy/Test.h" #include "Lucy/Test/Store/TestCompoundFileWriter.h" #include "Lucy/Store/CompoundFileWriter.h" #include "Lucy/Store/FileHandle.h" #include "Lucy/Store/OutStream.h" #include "Lucy/Store/RAMFolder.h" #include "Lucy/Util/Json.h" static CharBuf cfmeta_file = ZCB_LITERAL("cfmeta.json"); static CharBuf cfmeta_temp = ZCB_LITERAL("cfmeta.json.temp"); static CharBuf cf_file = ZCB_LITERAL("cf.dat"); static CharBuf foo = ZCB_LITERAL("foo"); static CharBuf bar = ZCB_LITERAL("bar"); static CharBuf seg_1 = ZCB_LITERAL("seg_1"); static Folder* S_folder_with_contents() { RAMFolder *folder = RAMFolder_new(&seg_1); OutStream *foo_out = RAMFolder_Open_Out(folder, &foo); OutStream *bar_out = RAMFolder_Open_Out(folder, &bar); OutStream_Write_Bytes(foo_out, "foo", 3); OutStream_Write_Bytes(bar_out, "bar", 3); OutStream_Close(foo_out); OutStream_Close(bar_out); DECREF(foo_out); DECREF(bar_out); return (Folder*)folder; } static void test_Consolidate(TestBatch *batch) { Folder *folder = S_folder_with_contents(); FileHandle *fh; // Fake up detritus from failed consolidation. fh = Folder_Open_FileHandle(folder, &cf_file, FH_CREATE | FH_WRITE_ONLY | FH_EXCLUSIVE); DECREF(fh); fh = Folder_Open_FileHandle(folder, &cfmeta_temp, FH_CREATE | FH_WRITE_ONLY | FH_EXCLUSIVE); DECREF(fh); CompoundFileWriter *cf_writer = CFWriter_new(folder); CFWriter_Consolidate(cf_writer); PASS(batch, "Consolidate completes despite leftover files"); DECREF(cf_writer); TEST_TRUE(batch, Folder_Exists(folder, &cf_file), "cf.dat file written"); TEST_TRUE(batch, Folder_Exists(folder, &cfmeta_file), "cfmeta.json file written"); TEST_FALSE(batch, Folder_Exists(folder, &foo), "original file zapped"); TEST_FALSE(batch, Folder_Exists(folder, &cfmeta_temp), "detritus from failed consolidation zapped"); DECREF(folder); } static void test_offsets(TestBatch *batch) { Folder *folder = S_folder_with_contents(); CompoundFileWriter *cf_writer = CFWriter_new(folder); Hash *cf_metadata; Hash *files; CFWriter_Consolidate(cf_writer); cf_metadata = (Hash*)CERTIFY( Json_slurp_json(folder, &cfmeta_file), HASH); files = (Hash*)CERTIFY( Hash_Fetch_Str(cf_metadata, "files", 5), HASH); CharBuf *file; Obj *filestats; bool_t offsets_ok = true; TEST_TRUE(batch, Hash_Get_Size(files) > 0, "Multiple files"); Hash_Iterate(files); while (Hash_Next(files, (Obj**)&file, &filestats)) { Hash *stats = (Hash*)CERTIFY(filestats, HASH); Obj *offset = CERTIFY(Hash_Fetch_Str(stats, "offset", 6), OBJ); int64_t offs = Obj_To_I64(offset); if (offs % 8 != 0) { offsets_ok = false; FAIL(batch, "Offset %" I64P " for %s not a multiple of 8", offset, CB_Get_Ptr8(file)); break; } } if (offsets_ok) { PASS(batch, "All offsets are multiples of 8"); } DECREF(cf_metadata); DECREF(cf_writer); DECREF(folder); } void TestCFWriter_run_tests() { TestBatch *batch = TestBatch_new(7); TestBatch_Plan(batch); test_Consolidate(batch); test_offsets(batch); DECREF(batch); }