5 changed files with 202 additions and 3 deletions
@ -0,0 +1,196 @@
@@ -0,0 +1,196 @@
|
||||
/****************************************************************************
|
||||
* |
||||
* Copyright (C) 2012 PX4 Development Team. All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions |
||||
* are met: |
||||
* |
||||
* 1. Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* 2. Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in |
||||
* the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* 3. Neither the name PX4 nor the names of its contributors may be |
||||
* used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||||
* POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
/**
|
||||
* @file test_file2.c |
||||
* |
||||
* File write test. |
||||
*/ |
||||
|
||||
#include <sys/stat.h> |
||||
#include <dirent.h> |
||||
#include <stdio.h> |
||||
#include <stddef.h> |
||||
#include <unistd.h> |
||||
#include <fcntl.h> |
||||
#include <systemlib/err.h> |
||||
#include <systemlib/perf_counter.h> |
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
#include <getopt.h> |
||||
|
||||
#define FLAG_FSYNC 1 |
||||
#define FLAG_LSEEK 2 |
||||
|
||||
/*
|
||||
return a predictable value for any file offset to allow detection of corruption |
||||
*/ |
||||
static uint8_t get_value(uint32_t ofs) |
||||
{ |
||||
union { |
||||
uint32_t ofs; |
||||
uint8_t buf[4]; |
||||
} u; |
||||
u.ofs = ofs; |
||||
return u.buf[ofs % 4]; |
||||
} |
||||
|
||||
static void test_corruption(const char *filename, uint32_t write_chunk, uint32_t write_size, uint16_t flags) |
||||
{ |
||||
printf("Testing on %s with write_chunk=%u write_size=%u\n",
|
||||
filename, (unsigned)write_chunk, (unsigned)write_size); |
||||
|
||||
uint32_t ofs = 0; |
||||
int fd = open(filename, O_CREAT | O_RDWR | O_TRUNC); |
||||
if (fd == -1) { |
||||
perror(filename); |
||||
exit(1); |
||||
} |
||||
|
||||
// create a file of size write_size, in write_chunk blocks
|
||||
uint8_t counter = 0; |
||||
while (ofs < write_size) { |
||||
uint8_t buffer[write_chunk]; |
||||
for (uint16_t j=0; j<write_chunk; j++) { |
||||
buffer[j] = get_value(ofs); |
||||
ofs++; |
||||
} |
||||
if (write(fd, buffer, sizeof(buffer)) != sizeof(buffer)) { |
||||
printf("write failed at offset %u\n", ofs); |
||||
exit(1); |
||||
} |
||||
if (flags & FLAG_FSYNC) { |
||||
fsync(fd); |
||||
} |
||||
if (counter % 100 == 0) { |
||||
printf("write ofs=%u\r", ofs); |
||||
} |
||||
counter++; |
||||
} |
||||
close(fd); |
||||
|
||||
printf("write ofs=%u\n", ofs); |
||||
|
||||
// read and check
|
||||
fd = open(filename, O_RDONLY); |
||||
if (fd == -1) { |
||||
perror(filename); |
||||
exit(1); |
||||
} |
||||
|
||||
counter = 0; |
||||
ofs = 0; |
||||
while (ofs < write_size) { |
||||
uint8_t buffer[write_chunk]; |
||||
if (counter % 100 == 0) { |
||||
printf("read ofs=%u\r", ofs); |
||||
} |
||||
counter++; |
||||
if (read(fd, buffer, sizeof(buffer)) != sizeof(buffer)) { |
||||
printf("read failed at offset %u\n", ofs); |
||||
exit(1); |
||||
} |
||||
for (uint16_t j=0; j<write_chunk; j++) { |
||||
if (buffer[j] != get_value(ofs)) { |
||||
printf("corruption at ofs=%u got %u\n", ofs, buffer[j]); |
||||
exit(1); |
||||
} |
||||
ofs++; |
||||
} |
||||
if (flags & FLAG_LSEEK) { |
||||
lseek(fd, 0, SEEK_CUR); |
||||
} |
||||
} |
||||
printf("read ofs=%u\n", ofs); |
||||
close(fd); |
||||
unlink(filename); |
||||
printf("All OK\n");
|
||||
} |
||||
|
||||
static void usage(void) |
||||
{ |
||||
printf("test file2 [options] [filename]\n"); |
||||
printf("\toptions:\n"); |
||||
printf("\t-s SIZE set file size\n"); |
||||
printf("\t-c CHUNK set IO chunk size\n"); |
||||
printf("\t-F fsync on every write\n"); |
||||
printf("\t-L lseek on every read\n"); |
||||
} |
||||
|
||||
int test_file2(int argc, char *argv[]) |
||||
{ |
||||
int opt; |
||||
uint16_t flags = 0; |
||||
const char *filename = "/fs/microsd/testfile2.dat"; |
||||
uint32_t write_chunk = 64; |
||||
uint32_t write_size = 5*1024; |
||||
|
||||
while ((opt = getopt(argc, argv, "c:s:FLh")) != EOF) { |
||||
switch (opt) { |
||||
case 'F': |
||||
flags |= FLAG_FSYNC; |
||||
break; |
||||
case 'L': |
||||
flags |= FLAG_LSEEK; |
||||
break; |
||||
case 's': |
||||
write_size = strtoul(optarg, NULL, 0); |
||||
break; |
||||
case 'c': |
||||
write_chunk = strtoul(optarg, NULL, 0); |
||||
break; |
||||
case 'h': |
||||
default: |
||||
usage(); |
||||
exit(1); |
||||
} |
||||
} |
||||
|
||||
argc -= optind; |
||||
argv += optind; |
||||
|
||||
if (argc > 0) { |
||||
filename = argv[0]; |
||||
} |
||||
|
||||
/* check if microSD card is mounted */ |
||||
struct stat buffer; |
||||
if (stat("/fs/microsd/", &buffer)) { |
||||
warnx("no microSD card mounted, aborting file test"); |
||||
return 1; |
||||
} |
||||
|
||||
test_corruption(filename, write_chunk, write_size, flags); |
||||
return 0; |
||||
} |
||||
|
Loading…
Reference in new issue