blob: 22a27cbdd8596fb305e3aad3c56a07ac386294ef [file] [log] [blame]
/* 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.
*/
#include <stdlib.h>
#define TESTLUCY_USE_SHORT_NAMES
#include "Lucy/Util/ToolSet.h"
#include "charmony.h"
#include "Clownfish/HashIterator.h"
#include "Clownfish/TestHarness/TestBatchRunner.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 String *cfmeta_file = NULL;
static String *cfmeta_temp = NULL;
static String *cf_file = NULL;
static String *foo = NULL;
static String *bar = NULL;
static String *seg_1 = NULL;
TestCompoundFileWriter*
TestCFWriter_new() {
return (TestCompoundFileWriter*)Class_Make_Obj(TESTCOMPOUNDFILEWRITER);
}
static void
S_init_strings(void) {
cfmeta_file = Str_newf("cfmeta.json");
cfmeta_temp = Str_newf("cfmeta.json.temp");
cf_file = Str_newf("cf.dat");
foo = Str_newf("foo");
bar = Str_newf("bar");
seg_1 = Str_newf("seg_1");
}
static void
S_destroy_strings(void) {
DECREF(cfmeta_file);
DECREF(cfmeta_temp);
DECREF(cf_file);
DECREF(foo);
DECREF(bar);
DECREF(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(TestBatchRunner *runner) {
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(runner, "Consolidate completes despite leftover files");
DECREF(cf_writer);
TEST_TRUE(runner, Folder_Exists(folder, cf_file),
"cf.dat file written");
TEST_TRUE(runner, Folder_Exists(folder, cfmeta_file),
"cfmeta.json file written");
TEST_FALSE(runner, Folder_Exists(folder, foo),
"original file zapped");
TEST_FALSE(runner, Folder_Exists(folder, cfmeta_temp),
"detritus from failed consolidation zapped");
DECREF(folder);
}
static void
test_offsets(TestBatchRunner *runner) {
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_Utf8(cf_metadata, "files", 5), HASH);
bool offsets_ok = true;
TEST_TRUE(runner, Hash_Get_Size(files) > 0, "Multiple files");
HashIterator *iter = HashIter_new(files);
while (HashIter_Next(iter)) {
String *file = HashIter_Get_Key(iter);
Hash *stats = (Hash*)CERTIFY(HashIter_Get_Value(iter), HASH);
Obj *offset = CERTIFY(Hash_Fetch_Utf8(stats, "offset", 6), OBJ);
int64_t offs = Json_obj_to_i64(offset);
if (offs % 8 != 0) {
offsets_ok = false;
char *str = Str_To_Utf8(file);
FAIL(runner, "Offset %" PRId64 " for %s not a multiple of 8",
offset, str);
free(str);
break;
}
}
DECREF(iter);
if (offsets_ok) {
PASS(runner, "All offsets are multiples of 8");
}
DECREF(cf_metadata);
DECREF(cf_writer);
DECREF(folder);
}
void
TestCFWriter_Run_IMP(TestCompoundFileWriter *self, TestBatchRunner *runner) {
TestBatchRunner_Plan(runner, (TestBatch*)self, 7);
S_init_strings();
test_Consolidate(runner);
test_offsets(runner);
S_destroy_strings();
}