You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
462 lines
15 KiB
462 lines
15 KiB
/*
|
|
* vfs-test.c: VFS Regression Test
|
|
*
|
|
* (c) 2002, JP Rosevear.
|
|
* (c) 2004, Florent Pillet
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
* Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
*
|
|
* This regression test calls every DLP function except the following:
|
|
* dlp_CallApplication
|
|
* dlp_ResetSystem
|
|
* dlp_ProcessRPC
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include "pi-debug.h"
|
|
#include "pi-socket.h"
|
|
#include "pi-dlp.h"
|
|
#include "pi-error.h"
|
|
#include "pi-source.h"
|
|
#include "pi-header.h"
|
|
|
|
|
|
/* For various protocol versions, set to 0 to not test those versions */
|
|
#define DLP_1_1 1
|
|
#define DLP_1_2 1
|
|
#define DLP_1_3 1
|
|
|
|
/* Logging defines */
|
|
#define CHECK_RESULT(func) \
|
|
if (result < 0) { \
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_ERR, "VFSTEST " #func " failed (%d, last palmos error: 0x%04x)\n", result, pi_palmos_error(sd))); \
|
|
if (result == PI_ERR_SOCK_DISCONNECTED) \
|
|
goto error; \
|
|
}
|
|
|
|
#define TEST_VFS_DIR "/vfs-test"
|
|
#define TEST_VFS_FILE "/vfs-test/test.dat"
|
|
#define TEST_VFS_FILE2 "/vfs-test/test2.dat"
|
|
#define TEST_VFS_FILE2_SHORT "test2.dat"
|
|
#define BIG_FILE_SIZE (2 * 1024 * 1024) /* test vfs read/write with 1Mb data */
|
|
|
|
int main (int argc, char **argv)
|
|
{
|
|
int i,
|
|
j,
|
|
sd,
|
|
result,
|
|
refs[200],
|
|
ref_length,
|
|
len,
|
|
numStrings;
|
|
char *strings;
|
|
FileRef fileRef;
|
|
unsigned long fileAttrs;
|
|
unsigned char *buf1;
|
|
|
|
time_t t1, t2;
|
|
char name[255],
|
|
oldName[255];
|
|
|
|
unsigned long flags;
|
|
|
|
sd = pilot_connect (argv[1]);
|
|
if (sd < 0) return 1;
|
|
|
|
t1 = time (NULL);
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "VFSTEST Starting at %s", ctime (&t1)));
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Test: Expansion
|
|
*
|
|
* Direct Testing Functions:
|
|
* dlp_ExpSlotEnumerate
|
|
* dlp_ExpCardPresent
|
|
* dlp_ExpCardInfo
|
|
*
|
|
* Indirect Testing Functions:
|
|
* None
|
|
*
|
|
*********************************************************************/
|
|
#if DLP_1_3
|
|
ref_length = sizeof (refs) / sizeof (refs[0]);
|
|
result = dlp_ExpSlotEnumerate (sd, &ref_length, refs);
|
|
CHECK_RESULT(dlp_ExpSlotEnumerate);
|
|
|
|
for (i = 0; i < ref_length; i++) {
|
|
result = dlp_ExpCardPresent (sd, refs[i]);
|
|
if (result == PI_ERR_DLP_PALMOS) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_ERR, "* dlp_ExpCardPresent: card not present in slot %d, PalmOS err 0x%04x\n", i, pi_palmos_error(sd)));
|
|
} else {
|
|
CHECK_RESULT(dlp_ExpCardPresent);
|
|
if (result >= 0) {
|
|
strings = NULL;
|
|
result = dlp_ExpCardInfo (sd, refs[i], &flags, &numStrings, &strings);
|
|
CHECK_RESULT(dlp_ExpCardInfo);
|
|
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Expansion card {%d}: "
|
|
"capabilities = 0x%08lx, numStrings = %d\n", refs[i], flags, numStrings));
|
|
|
|
if (strings) {
|
|
char *p = strings;
|
|
for (j = 0; j < numStrings; j++) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "\tstring[%d] = '%s'\n", j, p));
|
|
p += strlen (p) + 1;
|
|
}
|
|
free (strings);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Test: VFS Volumes, files and directories
|
|
*
|
|
* Direct Testing Functions:
|
|
* dlp_VFSDirCreate
|
|
* dlp_VFSDirEntryEnumerate
|
|
* dlp_VFSFileClose
|
|
* dlp_VFSFileCreate
|
|
* dlp_VFSFileDelete
|
|
* dlp_VFSFileEOF
|
|
* dlp_VFSFileGetAttributes
|
|
* dlp_VFSFileGetDate
|
|
* dlp_VFSFileOpen
|
|
* dlp_VFSFileRead
|
|
* dlp_VFSFileRename
|
|
* dlp_VFSFileResize
|
|
* dlp_VFSFileSeek
|
|
* dlp_VFSFileSetAttributes
|
|
* dlp_VFSFileSetDate
|
|
* dlp_VFSFileSize
|
|
* dlp_VFSFileTell
|
|
* dlp_VFSFileWrite
|
|
* dlp_VFSGetDefaultDir
|
|
* dlp_VFSVolumeEnumerate
|
|
* dlp_VFSVolumeGetLabel
|
|
* dlp_VFSVolumeInfo
|
|
* dlp_VFSVolumeSetLabel
|
|
* dlp_VFSVolumeSize
|
|
*
|
|
* Indirect Testing Functions:
|
|
* None
|
|
*
|
|
*********************************************************************/
|
|
#if DLP_1_3
|
|
ref_length = sizeof (refs) / sizeof (refs[0]);
|
|
result = dlp_VFSVolumeEnumerate (sd, &ref_length, refs);
|
|
CHECK_RESULT(dlp_VFSVolumeEnumerate);
|
|
|
|
for (i = 0; i < ref_length; i++) {
|
|
struct VFSInfo vfs;
|
|
long used, total;
|
|
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "\nTESTING VOLUME %d/%d {ref=%d}\n\n", i+1, ref_length, refs[i]));
|
|
|
|
result = dlp_VFSVolumeInfo (sd, refs[i], &vfs);
|
|
CHECK_RESULT(dlp_VFSVolumeInfo);
|
|
if (result >= 0) {
|
|
name[0] = 0;
|
|
if (vfs.attributes & 0x00000004)
|
|
strcpy (name, "hidden ");
|
|
if (vfs.attributes & 0x00000002)
|
|
strcat (name, "read-only ");
|
|
if (vfs.attributes & 0x00000001)
|
|
strcat (name, "slot-based");
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Volume attributes:\n\tattributes: %s\n", name));
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "\tfsType: '%4.4s'\n\tfsCreator: '%4.4s'\n\tmountClass: '%4.4s'\n", &vfs.fsType, &vfs.fsCreator, &vfs.mountClass));
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "\tslotLibRefNum: %d\n\tslotRefNum: %d\n\tmediaType: '%4.4s'\n\n", vfs.slotLibRefNum, vfs.slotRefNum, &vfs.mediaType));
|
|
}
|
|
|
|
result = dlp_VFSVolumeSize (sd, refs[i], &used, &total);
|
|
CHECK_RESULT(dlp_VFSVolumeSize);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* volume used: %ld / %ld bytes\n", used, total));
|
|
}
|
|
|
|
/* volume label test */
|
|
len = sizeof (name);
|
|
result = dlp_VFSVolumeGetLabel (sd, refs[i], &len, name);
|
|
CHECK_RESULT(dlp_VFSVolumeGetLabel);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* volume label: '%s'\n", name));
|
|
}
|
|
strcpy (oldName, name);
|
|
|
|
result = dlp_VFSVolumeSetLabel (sd, refs[i], "Test");
|
|
CHECK_RESULT(dlp_VFSVolumeSetLabel);
|
|
if (result >= 0) {
|
|
len = sizeof (name);
|
|
result = dlp_VFSVolumeGetLabel (sd, refs[i], &len, name);
|
|
CHECK_RESULT(dlp_VFSVolumeGetLabel);
|
|
if (result >= 0) {
|
|
if (strcmp("Test", name)) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_ERR, "* ERROR: Label change mismatch\n"));
|
|
} else {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Label change successful\n"));
|
|
}
|
|
}
|
|
|
|
result = dlp_VFSVolumeSetLabel (sd, refs[i], oldName);
|
|
CHECK_RESULT(dlp_VFSVolumeSetLabel);
|
|
}
|
|
|
|
/* directory listing test */
|
|
len = sizeof (name);
|
|
result = dlp_VFSGetDefaultDir (sd, refs[i], ".prc", name, &len);
|
|
CHECK_RESULT(dlp_VFSGetDefaultDir);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Listing directory contents at '%s'\n", name));
|
|
|
|
result = dlp_VFSFileOpen (sd, refs[i], name, 0x0007 /* vfsModeReadWrite */, &fileRef);
|
|
CHECK_RESULT(dlp_VFSFileOpen);
|
|
if (result >= 0) {
|
|
unsigned long dirIterator = vfsIteratorStart;
|
|
do {
|
|
struct VFSDirInfo dirItems[16];
|
|
int dirCount;
|
|
|
|
memset (dirItems, 0, sizeof(dirItems));
|
|
dirCount = 16;
|
|
result = dlp_VFSDirEntryEnumerate (sd, fileRef, &dirIterator, &dirCount, dirItems);
|
|
CHECK_RESULT(dlp_VFSDirEntryEnumerate);
|
|
|
|
if (result >= 0) {
|
|
for (j = 0; j < dirCount; j++) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "\t'%s' attrs = 0x%08lx\n", dirItems[j].name, dirItems[j].attr));
|
|
}
|
|
}
|
|
} while (dirIterator != vfsIteratorStop && result >= 0);
|
|
|
|
result = dlp_VFSFileClose (sd, fileRef);
|
|
CHECK_RESULT(dlp_VFSFileClose);
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Closed directory %s\n", name));
|
|
}
|
|
}
|
|
|
|
/* directory creation test */
|
|
result = dlp_VFSDirCreate (sd, refs[i], "/vfs-test");
|
|
CHECK_RESULT(dlp_VFSDirCreate);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Created directory %s\n", TEST_VFS_DIR));
|
|
|
|
/* file access tests */
|
|
result = dlp_VFSFileCreate (sd, refs[i], TEST_VFS_FILE);
|
|
CHECK_RESULT(dlp_VFSFileCreate);
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Created file %s\n", TEST_VFS_FILE));
|
|
|
|
result = dlp_VFSFileOpen (sd, refs[i], TEST_VFS_FILE, 0x0007 /* read-write */, &fileRef);
|
|
CHECK_RESULT(dlp_VFSFileOpen);
|
|
if (result >= 0) {
|
|
pi_buffer_t *fileBuf =
|
|
pi_buffer_new (BIG_FILE_SIZE);
|
|
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Opened file %s\n", TEST_VFS_FILE));
|
|
|
|
strcpy (name, "a test string written to a file\n");
|
|
result = dlp_VFSFileWrite (sd, fileRef, (unsigned char *)name, strlen (name));
|
|
CHECK_RESULT(dlp_VFSFileWrite);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Wrote small string to file %s\n", TEST_VFS_FILE));
|
|
|
|
result = dlp_VFSFileTell (sd, fileRef, &j);
|
|
CHECK_RESULT(dlp_VFSFileTell);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Current seek position: %d\n", j));
|
|
}
|
|
|
|
result = dlp_VFSFileSeek (sd, fileRef, vfsOriginBeginning, 0);
|
|
CHECK_RESULT(dlp_VFSFileSeek);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Seeked to beginning of file\n", j));
|
|
}
|
|
|
|
result = dlp_VFSFileRead (sd, fileRef, fileBuf, strlen(name));
|
|
CHECK_RESULT(dlp_VFSFileRead);
|
|
if (fileBuf->used != strlen (name)) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* ERROR: File read: read %d instead of the expected %d\n", len, strlen (name)));
|
|
} else if (memcmp (name, fileBuf->data, fileBuf->used)) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* ERROR: File read: read data mismatch\n", fileBuf->used, strlen (name)));
|
|
pi_dumpdata (name, fileBuf->used);
|
|
pi_dumpdata (fileBuf->data, fileBuf->used);
|
|
} else {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* File read: successfully read the data back\n"));
|
|
}
|
|
}
|
|
|
|
/* huge file write/read test - allocate a big buffer,
|
|
don't clean it (keep the garbage), write it to the
|
|
file and read it back them compare */
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Please wait, writing %ld bytes of data to the file...\n", (long)BIG_FILE_SIZE));
|
|
buf1 = (unsigned char *)malloc (BIG_FILE_SIZE);
|
|
if (buf1) {
|
|
result = dlp_VFSFileWrite (sd, fileRef, buf1, BIG_FILE_SIZE);
|
|
CHECK_RESULT(dlp_VFSFileWrite);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Successful, now reading it back...\n"));
|
|
|
|
result = dlp_VFSFileSeek (sd, fileRef, vfsOriginCurrent, -BIG_FILE_SIZE);
|
|
CHECK_RESULT(dlp_VFSFileSeek);
|
|
|
|
result = dlp_VFSFileRead (sd, fileRef, fileBuf, BIG_FILE_SIZE);
|
|
CHECK_RESULT(dlp_VFSFileRead);
|
|
if (result >= 0) {
|
|
if (fileBuf->used != BIG_FILE_SIZE || memcmp (buf1, fileBuf->data, BIG_FILE_SIZE))
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* ERROR, data differs!\n"));
|
|
else
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Successful, all bytes are the same...\n"));
|
|
}
|
|
}
|
|
}
|
|
if (buf1)
|
|
free (buf1);
|
|
pi_buffer_free (fileBuf);
|
|
|
|
result = dlp_VFSFileEOF (sd, fileRef);
|
|
if (pi_palmos_error(sd) == 0x2A07) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* File EOF: YES\n"));
|
|
} else if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* File EOF: NO\n"));
|
|
} else {
|
|
CHECK_RESULT(dlp_VFSFileEOF);
|
|
}
|
|
|
|
result = dlp_VFSFileSize (sd, fileRef, &len);
|
|
CHECK_RESULT(dlp_VFSFileSize);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* File size: %d bytes\n", len));
|
|
}
|
|
|
|
result = dlp_VFSFileGetAttributes (sd, fileRef, &fileAttrs);
|
|
CHECK_RESULT(dlp_VFSFileGetAttributes);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* File attributes: 0x%08lx\n", fileAttrs));
|
|
}
|
|
|
|
fileAttrs |= 0x00000001L;
|
|
result = dlp_VFSFileSetAttributes (sd, fileRef, fileAttrs);
|
|
CHECK_RESULT(dlp_VFSFileSetAttributes);
|
|
|
|
result = dlp_VFSFileGetAttributes (sd, fileRef, &fileAttrs);
|
|
CHECK_RESULT(dlp_VFSFileGetAttributes);
|
|
if (fileAttrs & 0x00000001L) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Successfully set read-only bit on file attributes\n"));
|
|
}
|
|
|
|
fileAttrs &= ~0x00000001L;
|
|
result = dlp_VFSFileSetAttributes (sd, fileRef, fileAttrs);
|
|
CHECK_RESULT(dlp_VFSFileSetAttributes);
|
|
|
|
result = dlp_VFSFileResize (sd, fileRef, 1024);
|
|
CHECK_RESULT(dlp_VFSFileResize);
|
|
|
|
result = dlp_VFSFileSize (sd, fileRef, &len);
|
|
CHECK_RESULT(dlp_VFSFileGetSize);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* File size after resize: %d\n", len));
|
|
}
|
|
|
|
result = dlp_VFSFileGetDate (sd, fileRef, vfsFileDateCreated, &t1);
|
|
CHECK_RESULT(dlp_VFSFileGetDate);
|
|
if (result >= 0) {
|
|
ctime_r (&t1, name);
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Date created: %s", name));
|
|
}
|
|
|
|
result = dlp_VFSFileGetDate (sd, fileRef, vfsFileDateModified, &t2);
|
|
CHECK_RESULT(dlp_VFSFileGetDate);
|
|
if (result >= 0) {
|
|
ctime_r (&t2, name);
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Date modified: %s", name));
|
|
}
|
|
|
|
result = dlp_VFSFileGetDate (sd, fileRef, vfsFileDateAccessed, &t2);
|
|
CHECK_RESULT(dlp_VFSFileGetDate);
|
|
if (result >= 0) {
|
|
ctime_r (&t2, name);
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Date accessed: %s", name));
|
|
}
|
|
|
|
t1 -= 3600 * 24;
|
|
result = dlp_VFSFileSetDate (sd, fileRef, vfsFileDateCreated, t1);
|
|
CHECK_RESULT(dlp_VFSFileSetDate);
|
|
if (result >= 0) {
|
|
result = dlp_VFSFileGetDate (sd, fileRef, vfsFileDateCreated, &t2);
|
|
CHECK_RESULT(dlp_VFSFileGetDate);
|
|
if (result >= 0) {
|
|
if (t1 == t2)
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* dlp_VFSFileSetDate successful\n"));
|
|
else
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* BUG: dlp_VFSFileSetDate FAILED\n"));
|
|
}
|
|
}
|
|
|
|
result = dlp_VFSFileClose (sd, fileRef);
|
|
CHECK_RESULT(dlp_VFSFileClose);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Closed file %s\n", TEST_VFS_FILE));
|
|
}
|
|
}
|
|
|
|
result = dlp_VFSFileRename (sd, refs[i], TEST_VFS_FILE, TEST_VFS_FILE2_SHORT);
|
|
CHECK_RESULT(dlp_VFSFileRename);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Renamed file %s to %s\n", TEST_VFS_FILE, TEST_VFS_FILE2_SHORT));
|
|
}
|
|
|
|
result = dlp_VFSFileDelete (sd, refs[i], TEST_VFS_FILE2);
|
|
CHECK_RESULT(dlp_VFSFileDelete);
|
|
if (result >= 0) {
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Deleted file %s\n", TEST_VFS_FILE2));
|
|
}
|
|
}
|
|
|
|
result = dlp_VFSFileDelete (sd, refs[i], "/vfs-test");
|
|
CHECK_RESULT(dlp_VFSFileDelete);
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "* Deleted directory /vfs-test\n"));
|
|
}
|
|
#endif
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Test: VFS Import/Export Databases
|
|
*
|
|
* Direct Testing Functions:
|
|
* dlp_VFSImportDatabaseFromFile
|
|
* dlp_VFSExportDatabaseFromFile
|
|
*
|
|
* Indirect Testing Functions:
|
|
* None
|
|
*
|
|
*********************************************************************/
|
|
|
|
t1 = time (NULL);
|
|
LOG((PI_DBG_USER, PI_DBG_LVL_INFO, "VFSTEST Ending at %s", ctime (&t1)));
|
|
|
|
error:
|
|
pi_close (sd);
|
|
|
|
return 0;
|
|
}
|
|
|