You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2006/10/28 04:22:04 UTC

svn commit: r468615 - in /lucene/lucy/trunk/charmonizer: charm_test.c src/Charmonizer/Modules/LargeFiles.charm src/Charmonizer/Test/LargeFiles.charm

Author: marvin
Date: Fri Oct 27 19:22:03 2006
New Revision: 468615

URL: http://svn.apache.org/viewvc?view=rev&rev=468615
Log:
Add tests for large file support, which only fire if pre-testing indicates
that sparse files are available.

Added:
    lucene/lucy/trunk/charmonizer/src/Charmonizer/Test/LargeFiles.charm
Modified:
    lucene/lucy/trunk/charmonizer/charm_test.c
    lucene/lucy/trunk/charmonizer/src/Charmonizer/Modules/LargeFiles.charm

Modified: lucene/lucy/trunk/charmonizer/charm_test.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/charmonizer/charm_test.c?view=diff&rev=468615&r1=468614&r2=468615
==============================================================================
--- lucene/lucy/trunk/charmonizer/charm_test.c (original)
+++ lucene/lucy/trunk/charmonizer/charm_test.c Fri Oct 27 19:22:03 2006
@@ -13,6 +13,7 @@
 TestGroup tests[] = {
     { "FuncMacro", chaz_TestHand_test_FuncMacro },
     { "Integers", chaz_TestHand_test_Integers },
+    { "LargeFiles", chaz_TestHand_test_LargeFiles },
     { "UnusedVars", chaz_TestHand_test_UnusedVars },
     { "VariadicMacros", chaz_TestHand_test_VariadicMacros },
     { NULL, NULL }

Modified: lucene/lucy/trunk/charmonizer/src/Charmonizer/Modules/LargeFiles.charm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/charmonizer/src/Charmonizer/Modules/LargeFiles.charm?view=diff&rev=468615&r1=468614&r2=468615
==============================================================================
--- lucene/lucy/trunk/charmonizer/src/Charmonizer/Modules/LargeFiles.charm (original)
+++ lucene/lucy/trunk/charmonizer/src/Charmonizer/Modules/LargeFiles.charm Fri Oct 27 19:22:03 2006
@@ -1,12 +1,38 @@
 #define CHAZ_USE_SHORT_NAMES
 
+#include "Charmonizer/Core/HeadCheck.h"
 #include "Charmonizer/Core/ModHandler.h"
+#include "Charmonizer/Core/Stat.h"
 #include "Charmonizer/Core/Util.h"
 #include "Charmonizer/Modules/LargeFiles.h"
+#include <errno.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 
+/* Determine whether we can use sparse files.
+ */
+static chaz_bool_t 
+check_sparse_files();
+
+/* Helper for check_sparse_files().  
+ */
+static void
+test_sparse_file(long offset, Stat *st);
+
+/* See if trying to write a 5 GB file in a subprocess bombs out.  If it
+ * doesn't, then the test suite can safely verify large file support.
+ */
+static chaz_bool_t
+can_create_big_files();
+
+static char* code_buf = NULL;
+static size_t code_buf_len = 0;
+static char fseek_command[10];
+static char ftell_command[10];
+static char loff_type[10];
+
+/* code for checking ftello/fseeko and off_t */
 static char ftello_code[] = METAQUOTE
     #include "_charm.h"
     #include <sys/types.h>
@@ -20,6 +46,7 @@
     }
 METAQUOTE;
 
+/* code for checking ftello64/fseeko64 and off64_t */
 static char ftello64_code[] = METAQUOTE
     #include "_charm.h"
     int main() {
@@ -32,6 +59,7 @@
     }
 METAQUOTE;
 
+/* code for checking size of long */
 static char sizeof_long_code[] = METAQUOTE
     #include "_charm.h"
     int main() {
@@ -45,9 +73,6 @@
 chaz_LargeFiles_run(FILE *conf_fh) 
 {
     char *output;
-    char fseek_command[10];
-    char ftell_command[10];
-    char loff_type[10];
     size_t output_len;
     chaz_bool_t has_off64_t = false;
     int sizeof_off_t = -1;
@@ -87,7 +112,6 @@
             &output_len);
         if (output != NULL) {
             sizeof_long = strtol(output, NULL, 10);
-            /* if longs are 8 bytes, ftell/fseek will work */
             if (sizeof_long == 8) {
                 success = true;
                 strcpy(fseek_command, "fseek");
@@ -97,6 +121,18 @@
         }
     }
 
+    /* check for sparse files */
+    if (check_sparse_files()) {
+        append_conf(conf_fh, "#define CHAZ_HAS_SPARSE_FILES\n");
+        /* see if we can create a 5 GB file without crashing */
+        if (success && can_create_big_files())
+            append_conf(conf_fh, "#define CHAZ_CAN_CREATE_BIG_FILES\n");
+    }
+    else {
+        append_conf(conf_fh, "#define CHAZ_NO_SPARSE_FILES\n");
+    }
+
+    /* write the affirmations/definitions */
     if (success) {
         append_conf(conf_fh, 
             "#define %sHAS_LARGE_FILE_SUPPORT\n"
@@ -110,6 +146,7 @@
         );
     }
 
+    /* short names */
     if (want_short_names && success) {
         Start_Short_Names(conf_fh);
         shorten_constant(conf_fh, "HAS_LARGE_FILE_SUPPORT");
@@ -120,6 +157,104 @@
     }
     
     End_Run(conf_fh);
+}
+
+static chaz_bool_t 
+check_sparse_files()
+{
+    Stat st_a, st_b;
+
+    /* bail out if we can't stat() a file */
+    if (!check_header("sys/stat.h"))
+        return false;
+
+    /* write and stat a 1 MB file and a 2 MB file, both of them sparse */
+    test_sparse_file(1000000, &st_a);
+    test_sparse_file(2000000, &st_b);
+    if (!(st_a.valid && st_b.valid))
+        return false;
+    if (st_a.size != 1000001)
+        die ("Expected size of 1000001 but got %ld", (long)st_a.size);
+    if (st_b.size != 2000001)
+        die ("Expected size of 2000001 but got %ld", (long)st_b.size);
+
+    /* see if two files with very different lengths have the same block size */
+    if (st_a.blocks == st_b.blocks)
+        return true;
+    else
+        return false;
+} 
+
+static void
+test_sparse_file(long offset, Stat *st)
+{
+    FILE *sparse_fh;
+
+    /* make sure the file's not there, then open */
+    remove_and_verify("_charm_sparse");
+    if ( (sparse_fh = fopen("_charm_sparse", "w+")) == NULL )
+        die("Couldn't open file '_charm_sparse'");
+
+    /* seek fh to [offset], write a byte, close file, check for errors */
+    if ( (fseek(sparse_fh, offset, SEEK_SET)) == -1)
+        die("seek failed: %s", strerror(errno));
+    if ( (fprintf(sparse_fh, "X")) != 1 )
+        die("fprintf failed");
+    if (fclose(sparse_fh))
+        die("Error closing file '_charm_sparse': %s", strerror(errno));
+
+    /* stat the file */
+    Stat_stat("_charm_sparse", st);
+
+    remove("_charm_sparse");
+}
+
+/* open a file, seek to a loc, print a char, and communicate success */
+static char create_bigfile_code_a[] = METAQUOTE
+    #include "_charm.h"
+    int main() {
+        FILE *fh = fopen("_charm_large_file_test", "w+");
+        int check_seek;
+        Charm_Setup;
+        /* bail unless seek succeeds */
+        check_seek = 
+METAQUOTE;
+
+static char create_bigfile_code_b[] = METAQUOTE
+            (fh, 5000000000, SEEK_SET);
+        if (check_seek == -1)
+            exit(1);
+        /* bail unless we write successfully */
+        if (fprintf(fh, "X") != 1)
+            exit(1);
+        if (fclose(fh))
+            exit(1);
+        /* communicate success to Charmonizer */
+        printf("1");
+        return 0;
+    }
+METAQUOTE;
+
+static chaz_bool_t
+can_create_big_files()
+{
+    char *output;
+    size_t output_len;
+    FILE *truncating_fh;
+
+    /* concat the source strings, compile the file, capture output */
+    code_buf_len = join_strings(&code_buf, code_buf_len,
+        create_bigfile_code_a, fseek_command, create_bigfile_code_b, NULL);
+    output = capture_output(code_buf, code_buf_len, &output_len);
+
+    /* truncate, just in case the call to remove fails */
+    truncating_fh = fopen("_charm_large_file_test", "w");
+    if (truncating_fh != NULL)
+        fclose(truncating_fh);
+    remove_and_verify("_charm_large_file_test");
+
+    /* return true if the test app made it to the finish line */
+    return output == NULL ? false : true;
 }
 
 

Added: lucene/lucy/trunk/charmonizer/src/Charmonizer/Test/LargeFiles.charm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/charmonizer/src/Charmonizer/Test/LargeFiles.charm?view=auto&rev=468615
==============================================================================
--- lucene/lucy/trunk/charmonizer/src/Charmonizer/Test/LargeFiles.charm (added)
+++ lucene/lucy/trunk/charmonizer/src/Charmonizer/Test/LargeFiles.charm Fri Oct 27 19:22:03 2006
@@ -0,0 +1,102 @@
+#define CHAZ_USE_SHORT_NAMES
+
+#include "_charm_test.h"
+
+#ifdef HAS_SYS_TYPES_H
+  #include <sys/types.h>
+#endif
+
+#include <stdio.h>
+#include "Charmonizer/Test/TestHandler.h"
+
+void 
+chaz_TestHand_test_LargeFiles(int *num_tests, int *num_passed, 
+                              int *num_failed, int *num_skipped)
+{
+    int test_num  = 0;
+    FILE *fh;
+    LOFFSET_TYPE offset;
+    int check_val;
+    char check_char;
+
+    /* a little over 4 GB, and a little over 2 GB */
+    LOFFSET_TYPE gb4_plus = ((LOFFSET_TYPE)0x7FFFFFFF << 1) + 100;
+    LOFFSET_TYPE gb2_plus = (LOFFSET_TYPE)0x7FFFFFFF + 200;
+    
+    /* gb4_plus modulo 4 GB */
+    i32_t wrap_gb4 = gb4_plus;
+
+    *num_tests    = 10;
+    *num_passed   = 0;
+    *num_failed   = 0;
+    *num_skipped  = *num_tests;
+
+    Assert_True((sizeof(LOFFSET_TYPE) == 8), "offset type has 8 bytes");
+
+#ifndef HAS_LARGE_FILE_SUPPORT
+    Skip_Remaining("No large file support");
+#endif
+#ifndef CHAZ_HAS_SPARSE_FILES
+    Skip_Remaining("Can't verify large file support without sparse files");
+#endif
+#ifndef CHAZ_CAN_CREATE_BIG_FILES
+    Skip_Remaining("Unsafe to create 5GB sparse files on this system");
+#endif
+
+    fh = fopen("_charm_large_file_test", "w+");
+    if (fh == NULL)
+        Skip_Remaining("Failed to open file");
+
+    check_val = Lfseek(fh, gb4_plus, SEEK_SET);
+    Assert_True((check_val == 0), "Lfseek above 4 GB");
+
+    offset = Lftell(fh);
+    Assert_True((offset = gb4_plus), "Lftell above 4 GB");
+
+    check_val = fprintf(fh, "X");
+    Assert_True((check_val == 1), "print above 4 GB");
+
+    check_val = Lfseek(fh, gb2_plus, SEEK_SET);
+    Assert_True((check_val == 0), "Lfseek above 2 GB");
+
+    offset = Lftell(fh);
+    Assert_True((offset = gb2_plus), "Lftell above 2 GB");
+
+    check_val = Lfseek(fh, -1, SEEK_END);
+    Assert_True((check_val == 0), "seek to near end");
+
+    check_char = fgetc(fh);
+    Assert_True((check_char == 'X'), "read value after multiple seeks");
+
+    Lfseek(fh, wrap_gb4, SEEK_SET);
+    check_char = fgetc(fh);
+    Assert_True((check_char == '\0'), "No wraparound");
+
+    check_val = fclose(fh);
+    Assert_True((check_val == 0), "fclose succeeds after all that");
+
+    /* truncate, just in case the call to remove fails */
+    fh = fopen("_charm_large_file_test", "w+");
+    if (fh != NULL)
+        fclose(fh);
+    remove("_charm_large_file_test");
+}
+
+
+
+/**
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+