On Tue, May 15, 2018 at 7:25 AM, Waldek Kozaczuk <[email protected]>
wrote:

> Nadav,
>
> Thanks for applying this patch.
>
> It would be nice to add './script/build check fs=rofs' to one of the
> Jenkins job. What do you think?
>

I'll leave this to Avi's consideration, he's in charge of the Jenkins
scripts.

One question, though - are we should that it's fine to change the "fs="
without a "make clean"?
E.g., would

./script/build check
./script/build check fs=rofs
./script/build check

Really build a ZFS build, then a ROFS build, then again a ZFS build, even
though the only thing changed is the command line?
If this doesn't work, then Jenkins won't work properly (I believe it
doesn't bother with a "make clean" every time).


>
> Waldek
>
> On Sunday, May 13, 2018 at 5:44:29 PM UTC-4, Bot Droid wrote:
>>
>> From: Waldemar Kozaczuk <[email protected]>
>> Committer: Nadav Har'El <[email protected]>
>> Branch: master
>>
>> Enhanced tests to allows testing rofs/ramfs image
>>
>> This patch adds new unit tests and modifies existing ones to make
>> it possible to test images with read-only filesystem mounted
>> at root and ramfs mounted at /tmp.
>>
>> Following changes are part of this patch:
>>
>> - modified tests module makefile to divide all tests
>>    into three groups - zfs specific, rofs/ramfs specific and
>>    remaining ones applicable to any filesystem; some of the tests
>>    are filtered out temporarily of rofs/ramfs image due to
>> bugs/shortcomings
>>    of ramfs filesystem which are described in more detail in makefile
>>    itself
>>
>> - added new test tst-concurrent-read.cc to verify concurrent reads; the
>> test
>>    can be compiled to test either read/write (zfs) or read-only
>> filesystem
>> (rofs)
>>
>> - enhanced tst-chdir.cc, tst-readdir.cc and tst-symlink.cc tests
>>    by adding READ_ONLY_FS macro parameter to test both read/write (zfs)
>>    and read-only file system (rofs); these 3 tests and
>> tst-concurrent-read.cc
>>    are part of rofs/ramfs image compiled in both read/write and read-only
>>    mode (for example tst-chdir.so and tst-chdir-rofs.so)
>>
>> - modified tst-fallocate.cc and tst-fs-link.cc to use /tmp directory
>>    instead of /usr
>>
>> In order to build rofs test image and execute following command
>> can be used:
>>
>> ./script/build check fs=rofs
>>
>> By default test image is built with zfs filesystem mounted.
>>
>> Signed-off-by: Waldemar Kozaczuk <[email protected]>
>> Message-Id: <[email protected]>
>>
>> ---
>> diff --git a/modules/tests/Makefile b/modules/tests/Makefile
>> --- a/modules/tests/Makefile
>> +++ b/modules/tests/Makefile
>> @@ -4,6 +4,7 @@ module: usr.manifest build_all_tests
>>   src := $(OSV_BASE)
>>   out := $(OSV_BUILD_PATH)
>>   arch := $(ARCH)
>> +fs_type := $(fs_type)
>>   # TODO: consider setting $(out) not to OSV_BUILD_PATH but to
>> ./build/$ARCH.
>>   # TODO: need to set up CXX, etc., for cross compilation, as in the main
>>   # Makefile...
>> @@ -50,23 +51,49 @@ $(out)/%.o: $(src)/%.cc
>>   $(out)/%.o: $(src)/%.c
>>           $(makedir)
>>           $(call quiet, $(CC) $(CFLAGS) -c -o $@ $< , CC $*.c)
>> +$(out)/tests/rofs/%.o: $(src)/tests/%.cc
>> +        $(makedir)
>> +        $(call quiet, $(CXX) $(CXXFLAGS) -DREAD_ONLY_FS -c -o $@ $<, CXX
>> $*.cc)
>> +$(out)/tests/rofs/%.o: $(src)/tests/%.c
>> +        $(makedir)
>> +        $(call quiet, $(CC) $(CFLAGS) -DREAD_ONLY_FS -c -o $@ $< , CC
>> $*.c)
>>   $(out)/%.so: $(out)/%.o
>>           $(call quiet, $(CXX) $(CXXFLAGS) -shared -o $@ $< $(LIBS), LD
>> $*.so)
>>
>> +# The rofs test image mounts /tmp as ramfs and 4 tests that exercise
>> file
>> system
>> +# fail due to some unresolved bugs or other shortcomings of the ramfs
>> implementation
>> +# and are temporarily removed from the rofs-only-tests list. The tests
>> tst-readdir.so
>> +# and tst-rename.so would fail until the issue #68 is fixed. Similarly
>> +# tst-fs-link.so do not pass due to lack of hard links support in the
>> ramfs
>> +# implementation. Lastly tst-fallocate.so also does not work with ramfs
>>
>> due to
>> +# the shortcomings in ramfs implementation of statfs that does not
>> report
>> free/used
>> +# blocks adequately.
>> +#
>> +# These 4 tests are compiled from the same source files but passed in
>> READ_ONLY_FS
>> +# to switch relevant logic in those tests to exercise scenarios
>> applicable
>> +# to read-only filesystem
>> +rofs-only-tests := rofs/tst-chdir.so rofs/tst-symlink.so
>> rofs/tst-readdir.so \
>> +        rofs/tst-concurrent-read.so
>> +
>> +zfs-only-tests := tst-readdir.so tst-fallocate.so tst-fs-link.so \
>> +        tst-concurrent-read.so
>> +
>> +specific-fs-tests := $($(fs_type)-only-tests)
>> +
>>   tests := tst-pthread.so misc-ramdisk.so tst-vblk.so tst-bsd-evh.so \
>>           misc-bsd-callout.so tst-bsd-kthread.so tst-bsd-taskqueue.so \
>>           tst-fpu.so tst-preempt.so tst-tracepoint.so tst-hub.so \
>>           misc-console.so misc-leak.so misc-readbench.so
>> misc-mmap-anon-perf.so \
>>           tst-mmap-file.so misc-mmap-big-file.so tst-mmap.so tst-huge.so
>> \
>>           tst-elf-permissions.so misc-mutex.so misc-sockets.so
>> tst-condvar.so \
>>           tst-queue-mpsc.so tst-af-local.so tst-pipe.so tst-yield.so \
>> -        misc-ctxsw.so tst-readdir.so tst-read.so tst-symlink.so
>> tst-openat.so \
>> +        misc-ctxsw.so tst-read.so tst-symlink.so tst-openat.so \
>>           tst-eventfd.so tst-remove.so misc-wake.so tst-epoll.so
>> misc-lfring.so \
>>           misc-fsx.so tst-sleep.so tst-resolve.so tst-except.so \
>>           misc-tcp-sendonly.so tst-tcp-nbwrite.so misc-tcp-hash-srv.so \
>>           misc-loadbalance.so misc-scheduler.so tst-console.so tst-app.so
>> \
>>           misc-setpriority.so misc-timeslice.so misc-tls.so misc-gtod.so
>> \
>> -        tst-dns-resolver.so tst-fs-link.so tst-kill.so tst-truncate.so \
>> +        tst-dns-resolver.so tst-kill.so tst-truncate.so \
>>           misc-panic.so tst-utimes.so tst-utimensat.so tst-futimesat.so \
>>           misc-tcp.so tst-strerror_r.so misc-random.so misc-urandom.so \
>>           tst-commands.so tst-threadcomplete.so tst-timerfd.so \
>> @@ -75,7 +102,7 @@ tests := tst-pthread.so misc-ramdisk.so tst-vblk.so
>> tst-bsd-evh.so \
>>           tst-concurrent-init.so tst-ring-spsc-wraparound.so tst-shm.so \
>>           tst-align.so tst-cxxlocale.so misc-tcp-close-without-reading.so
>> \
>>           tst-sigwait.so tst-sampler.so misc-malloc.so misc-memcpy.so \
>> -        misc-free-perf.so tst-fallocate.so misc-printf.so
>> tst-hostname.so \
>> +        misc-free-perf.so misc-printf.so tst-hostname.so \
>>           tst-sendfile.so misc-lock-perf.so tst-uio.so tst-printf.so \
>>           tst-pthread-affinity.so tst-pthread-tsd.so tst-thread-local.so
>> \
>>           tst-zfs-mount.so tst-regex.so tst-tcp-siocoutq.so \
>> @@ -111,7 +138,7 @@ $(out)/tests/tst-tls.so: \
>>           $(makedir)
>>           $(call quiet, cd $(out); $(CXX) $(CXXFLAGS) -shared -o $@ $<
>> tests/libtls.so, CXX tst-tls.so)
>>
>> -boost-tests := tst-rename.so tst-vfs.so tst-libc-locking.so
>> misc-fs-stress.so \
>> +boost-tests := tst-vfs.so tst-libc-locking.so misc-fs-stress.so \
>>           misc-bdev-write.so misc-bdev-wlatency.so misc-bdev-rw.so \
>>           tst-promise.so tst-dlfcn.so tst-stat.so tst-wait-for.so \
>>           tst-bsd-tcp1.so tst-bsd-tcp1-zsnd.so tst-bsd-tcp1-zrcv.so \
>> @@ -120,6 +147,12 @@ boost-tests := tst-rename.so tst-vfs.so
>> tst-libc-locking.so misc-fs-stress.so \
>>           tst-rcu-hashtable.so tst-unordered-ring-mpsc.so \
>>           tst-seek.so
>>
>> +rofs-only-boost-tests :=
>> +
>> +zfs-only-boost-tests := tst-rename.so
>> +
>> +boost-tests += $($(fs_type)-only-boost-tests)
>> +
>>   BOOSTLIBS=$(src)/external/$(ARCH)/misc.bin/usr/lib64
>>   $(boost-tests:%=$(out)/tests/%): LIBS += \
>>            $(BOOSTLIBS)/libboost_unit_test_framework.so \
>> @@ -157,15 +190,20 @@ $(solaris-tests:%=$(out)/tests/%): COMMON+= \
>>           -I $(src)/bsd/sys -I $(src)/bsd -I $(src)/bsd/$(ARCH)
>>
>>   all_tests := $(tests:%=tests/%)
>> +all_tests += $(specific-fs-tests:%=tests/%)
>>
>>   build_all_tests: $(all_tests:%=$(out)/%)
>> -.PHONY: build_all_tests
>> +.PHONY: build_all_tests clean
>>
>>   # Automatically generate usr.manifest which includes all tests.
>> -usr.manifest: $(lastword $(MAKEFILE_LIST)) usr.manifest.skel
>> +usr.manifest: $(lastword $(MAKEFILE_LIST)) usr.manifest.skel FORCE
>>           @echo "  generating modules/tests/usr.manifest"
>>           @cat [email protected] > $@
>> -        @echo $(all_tests) | tr ' ' '\n' | awk '{print "/" $$0 ": ./"
>> $$0}' >> $@
>> +        @echo $(all_tests) | tr ' ' '\n' | grep -v
>> "tests/rofs/tst-.*.so" |
>> awk '{print "/" $$0 ": ./" $$0}' >> $@
>> +        @echo $(all_tests) | tr ' ' '\n' | grep "tests/rofs/tst-.*.so" |
>>
>> sed 's/\.so//' | awk 'BEGIN { FS = "/" } ; { print "/tests/"
>> $$3 "-rofs.so: ./tests/" $$2 "/" $$3 ".so"}' >> $@
>> +        ./create_static.sh $(out) $(fs_type)
>> +.PHONY: FORCE
>> +FORCE:
>>
>>   clean:
>>           -rm -f usr.manifest
>> diff --git a/modules/tests/create_static.sh
>> b/modules/tests/create_static.sh
>> --- a/modules/tests/create_static.sh
>> +++ b/modules/tests/create_static.sh
>> @@ -0,0 +1,36 @@
>> +#!/bin/bash
>> +
>> +THIS_PATH=$(readlink -f $0)
>> +THIS_DIRECTORY=$(dirname ${THIS_PATH})
>> +OUT=$1
>> +FS=${2-zfs}
>> +
>> +#Clean the directory
>> +rm -rf ${OUT}/tests/static
>> +
>> +if [ ${FS} = "rofs" ]
>> +then
>> +        mkdir -p ${OUT}/tests/static/rofs/tst-readdir-empty
>> +        mkdir -p ${OUT}/tests/static/rofs/tst-readdir
>> +        touch ${OUT}/tests/static/rofs/tst-readdir/aaa
>> +
>> +        mkdir -p ${OUT}/tests/static/rofs/tst-chdir
>> +        touch ${OUT}/tests/static/rofs/tst-chdir/f
>> +
>> +        mkdir -p ${OUT}/tests/static/rofs/tst-symlink
>> +        touch ${OUT}/tests/static/rofs/tst-symlink/f1
>> +        cd ${OUT}/tests/static/rofs/tst-symlink && ln -s f1 f2_AAA
>> +
>> +        echo '/rofs/tst-readdir-empty: 
>> ./tests/static/rofs/tst-readdir-empty'
>> >>
>> ${THIS_DIRECTORY}/usr.manifest
>> +        echo '/rofs/tst-chdir/f: ./tests/static/rofs/tst-chdir/f' >>
>> ${THIS_DIRECTORY}/usr.manifest
>> +        echo '/rofs/tst-readdir/aaa: ./tests/static/rofs/tst-readdir/aaa'
>> >>
>> ${THIS_DIRECTORY}/usr.manifest
>> +        echo '/rofs/tst-symlink/f1: ./tests/static/rofs/tst-symlink/f1'
>> >>
>> ${THIS_DIRECTORY}/usr.manifest
>> +        echo '/rofs/tst-symlink/f2_AAA: ->/rofs/tst-symlink/f1' >>
>> ${THIS_DIRECTORY}/usr.manifest
>> +
>> +        #This file is around 700K so it is a good test sample for the
>> concurrent
>> test
>> +        echo '/rofs/mmap-file-test1: ./core/spinlock.o' >>
>> ${THIS_DIRECTORY}/usr.manifest
>> +        echo '/rofs/mmap-file-test2: ./core/spinlock.o' >>
>> ${THIS_DIRECTORY}/usr.manifest
>> +else
>> +        echo '/tmp/mmap-file-test1: ./core/spinlock.o' >>
>> ${THIS_DIRECTORY}/usr.manifest
>> +        echo '/tmp/mmap-file-test2: ./core/spinlock.o' >>
>> ${THIS_DIRECTORY}/usr.manifest
>> +fi
>> diff --git a/scripts/build b/scripts/build
>> --- a/scripts/build
>> +++ b/scripts/build
>> @@ -153,7 +153,7 @@ if [ "$export" == "selected" ]
>>   then
>>           no_required_arg="--no-required"
>>   fi
>> -jdkbase=$jdkbase ARCH=$arch mode=$mode OSV_BASE=$SRC
>> OSV_BUILD_PATH=$OSV_BUILD_PATH scripts/module.py $j_arg build -c $modules
>>
>> $usrskel_arg $no_required_arg
>> +fs_type=$fs_type jdkbase=$jdkbase ARCH=$arch mode=$mode OSV_BASE=$SRC
>> OSV_BUILD_PATH=$OSV_BUILD_PATH scripts/module.py $j_arg build -c $modules
>>
>> $usrskel_arg $no_required_arg
>>
>>   bootfs_manifest=$manifest make "${args[@]}" | tee -a build.out
>>   # check exit status of make
>> diff --git a/tests/tst-chdir.cc b/tests/tst-chdir.cc
>> --- a/tests/tst-chdir.cc
>> +++ b/tests/tst-chdir.cc
>> @@ -15,6 +15,12 @@
>>
>>   #include <iostream>
>>
>> +#if defined(READ_ONLY_FS)
>> +#define SUBDIR "rofs"
>> +#else
>> +#define SUBDIR "tmp"
>> +#endif
>> +
>>   int tests = 0, fails = 0;
>>
>>   #define expect(actual, expected) do_expect(actual, expected, #actual,
>> #expected, __FILE__, __LINE__)
>> @@ -37,36 +43,50 @@ bool do_expect(T actual, T expected, const char
>> *actuals, const char *expecteds,
>>
>>   int main(int argc, char **argv)
>>   {
>> +#if defined(READ_ONLY_FS)
>> +    expect_errno(mkdir("/rofs/tst-chdir-non-existent", 0777), EROFS);
>> +#else
>>       expect(mkdir("/tmp/tst-chdir", 0777), 0);
>> -
>> +#endif
>>       /********* test chdir() **************/
>>       // chdir to non-existant subdirectory returns ENOENT:
>> -    expect_errno(chdir("/tmp/tst-chdir/x"), ENOENT);
>> +    expect_errno(chdir("/" SUBDIR "/tst-chdir/x"), ENOENT);
>>       // chdir to path with non-existant middle component returns
>> ENOTDIR:
>> -    expect_errno(chdir("/tmp/tst-chdir/x/y"), ENOENT);
>> +    expect_errno(chdir("/" SUBDIR " /tst-chdir/x/y"), ENOENT);
>>       // chdir to a non-directory file, or if a non-directory is part of
>> the
>>       // path, fails with ENOTDIR:
>> +#if defined(READ_ONLY_FS)
>> +    expect_errno(mknod("/rofs/tst-chdir/f-nonexistent", 0777|S_IFREG,
>> 0),
>> EROFS);
>> +#else
>>       expect(mknod("/tmp/tst-chdir/f", 0777|S_IFREG, 0), 0);
>> -    expect_errno(chdir("/tmp/tst-chdir/f"), ENOTDIR);
>> -    expect_errno(chdir("/tmp/tst-chdir/f/g"), ENOTDIR);
>> +#endif
>> +    expect_errno(chdir("/" SUBDIR "/tst-chdir/f"), ENOTDIR);
>> +    expect_errno(chdir("/" SUBDIR "/tst-chdir/f/g"), ENOTDIR);
>> +#if defined(READ_ONLY_FS)
>> +    expect_errno(unlink("/rofs/tst-chdir/f"), EROFS);
>> +#else
>>       expect(unlink("/tmp/tst-chdir/f"), 0);
>> +#endif
>>       // chdir to existing directory succeeds:
>>       expect(chdir("/"), 0);
>> -    expect(chdir("/tmp"), 0);
>> -    expect(chdir("/tmp/tst-chdir"), 0);
>> -    expect(chdir("/tmp/tst-chdir/"), 0);
>> +    expect(chdir("/" SUBDIR), 0);
>> +    expect(chdir("/" SUBDIR "/tst-chdir"), 0);
>> +    expect(chdir("/" SUBDIR "/tst-chdir/"), 0);
>>       expect(chdir("/"), 0);
>>       // chdir actually "works" (changes the return value of getcwd)
>>       char buf[1024];
>> -    expect(chdir("/tmp/tst-chdir"), 0);
>> +    expect(chdir("/" SUBDIR "/tst-chdir"), 0);
>>       getcwd(buf, sizeof(buf));
>> -    expect(strcmp(buf, "/tmp/tst-chdir"), 0);
>> +    expect(strcmp(buf, "/" SUBDIR "/tst-chdir"), 0);
>>       expect(chdir("/"), 0);
>>
>> -
>> +#if defined(READ_ONLY_FS)
>> +    expect_errno(rmdir("/rofs/tst-chdir"), ENOTEMPTY);
>> +#else
>>       // Finally remove the temporary directory (assumes the above left
>>       // nothing in it)
>>       expect(rmdir("/tmp/tst-chdir"), 0);
>> +#endif
>>
>>       std::cout << "SUMMARY: " << tests << " tests, " << fails << "
>> failures\n";
>>       return fails == 0 ? 0 : 1;
>> diff --git a/tests/tst-concurrent-read.cc b/tests/tst-concurrent-read.cc
>> --- a/tests/tst-concurrent-read.cc
>> +++ b/tests/tst-concurrent-read.cc
>> @@ -0,0 +1,104 @@
>> +#include <stdio.h>
>> +#include <string.h>
>> +#include <sys/mman.h>
>> +#include <sys/stat.h>
>> +#include <fcntl.h>
>> +#include <unistd.h>
>> +#include <stdlib.h>
>> +#include <time.h>
>> +
>> +#include <iostream>
>> +#include <thread>
>> +#include <vector>
>> +#include <atomic>
>> +
>> +#if defined(READ_ONLY_FS)
>> +#define SUBDIR "rofs"
>> +#else
>> +#define SUBDIR "tmp"
>> +#endif
>> +
>> +int tests = 0, fails = 0;
>> +
>> +using namespace std;
>> +
>> +#define expect(actual, expected) do_expect(actual, expected, #actual,
>> #expected, __FILE__, __LINE__)
>> +template<typename T>
>> +bool do_expect(T actual, T expected, const char *actuals, const char
>> *expecteds, const char *file, int line)
>> +{
>> +    ++tests;
>> +    if (actual != expected) {
>> +        fails++;
>> +        cout << "FAIL: " << file << ":" << line << ": For " << actuals
>> <<
>> +                  ", expected " << expecteds << ", saw " << actual
>> << ".\n";
>> +        return false;
>> +    }
>> +    return true;
>> +}
>> +
>> +int main()
>> +{
>> +    srand (time(NULL));
>> +    //
>> +    // First read first file using mmap
>> +    string file_1("/" SUBDIR "/mmap-file-test1");
>> +    int fd1 = open(file_1.c_str(), O_RDONLY, 0666);
>> +    expect(fd1 >= 0, true );
>> +
>> +    struct stat sb;
>> +    if (fstat (fd1, &sb) == -1) {
>> +        perror ("fstat");
>> +        return 1;
>> +    }
>> +
>> +    if (!S_ISREG (sb.st_mode)) {
>> +        cerr << file_1 << " is not a file\n";
>> +        return 1;
>> +    }
>> +
>> +    off_t length = sb.st_size;
>> +    void *address = mmap(0, length, PROT_READ, MAP_PRIVATE, fd1, 0);
>> +    if (address == MAP_FAILED) {
>> +        return 1;
>> +    }
>> +
>> +    string file_2("/" SUBDIR "/mmap-file-test2");
>> +    int fd2 = open(file_2.c_str(), O_RDONLY, 0666);
>> +    expect(fd2 >= 0, true );
>> +
>> +    vector<thread> readers;
>> +
>> +    int thread_count = 10, reads_count = 100;
>> +    atomic<long> identical_count(0);
>> +    for(int i = 0; i < thread_count; i++) {
>> +
>> readers.emplace_back(thread([i,reads_count,fd2,length,address,&identical_count]{
>>
>> +            unsigned char buffer[4096];
>> +            for(int step = 0; step < reads_count; step++) {
>> +                off_t offset = rand() % length;
>> +                size_t amount = min(length - offset, 4096l);
>> +
>> +                int ret = pread(fd2, buffer, amount, offset);
>> +                expect(ret > 0, true);
>> +                if( ret > 0 ) {
>> +                    auto is_identical = memcmp(buffer,
>> static_cast<unsigned char*>(address) + offset, amount) == 0 ? 1 : 0;
>> +                    identical_count += is_identical;
>> +                }
>> +                else {
>> +                    cout << "[" << i << "] FAILED to read " << amount <<
>> "
>> bytes at " << offset << "\n";
>> +                }
>> +            }
>> +        }));
>> +    }
>> +
>> +    for(auto &t : readers) {
>> +        t.join();
>> +    }
>> +
>> +    cout << "Identical count " << identical_count.load() << endl;
>> +
>> +    munmap(address,length);
>> +    close(fd1);
>> +    close(fd2);
>> +
>> +    expect(identical_count.load(),(long)(thread_count * reads_count));
>> +}
>> diff --git a/tests/tst-fallocate.cc b/tests/tst-fallocate.cc
>> --- a/tests/tst-fallocate.cc
>> +++ b/tests/tst-fallocate.cc
>> @@ -48,7 +48,7 @@ int main(int argc, char *argv[])
>>       struct stat st;
>>       struct statfs fs;
>>
>> -    strcpy(path, "/usr/tst-fallocateXXXXXX");
>> +    strcpy(path, "/tmp/tst-fallocateXXXXXX");
>>       mktemp(path);
>>
>>       // Create a temporary file that's used in testing.
>> diff --git a/tests/tst-fs-link.cc b/tests/tst-fs-link.cc
>> --- a/tests/tst-fs-link.cc
>> +++ b/tests/tst-fs-link.cc
>> @@ -32,8 +32,8 @@ extern "C" int namei(char *, struct dentry **);
>>   static int check_vnode_duplicity(void)
>>   {
>>       int err = 0;
>> -    char oldpath[64] = "/usr/tst-fs-linkXXXXXX";
>> -    char newpath[64] = "/usr/tst-fs-linkXXXXXX";
>> +    char oldpath[64] = "/tmp/tst-fs-linkXXXXXX";
>> +    char newpath[64] = "/tmp/tst-fs-linkXXXXXX";
>>       struct dentry *olddp, *newdp;
>>
>>       mktemp(oldpath);
>> @@ -91,10 +91,10 @@ int main(int argc, char *argv[])
>>           newpath = argv[2];
>>       } else {
>>
>> -        strcpy(oldp, "/usr/tst-fs-linkXXXXXX");
>> +        strcpy(oldp, "/tmp/tst-fs-linkXXXXXX");
>>           mktemp(oldp);
>>
>> -        strcpy(newp, "/usr/tst-fs-linkXXXXXX");
>> +        strcpy(newp, "/tmp/tst-fs-linkXXXXXX");
>>           mktemp(newp);
>>
>>           oldpath = oldp;
>> diff --git a/tests/tst-readdir.cc b/tests/tst-readdir.cc
>> --- a/tests/tst-readdir.cc
>> +++ b/tests/tst-readdir.cc
>> @@ -13,22 +13,32 @@
>>
>>   #include <osv/debug.hh>
>>
>> +#if defined(READ_ONLY_FS)
>> +#define SUBDIR "rofs"
>> +#else
>> +#define SUBDIR "tmp"
>> +#endif
>> +
>>   int tests = 0, fails = 0;
>>
>>   static void report(bool ok, const char* msg)
>>   {
>>       ++tests;
>>       fails += !ok;
>> -    debug("%s: %s\n", (ok ? "PASS" : "FAIL"), msg);
>> +    printf("%s: %s\n", (ok ? "PASS" : "FAIL"), msg);
>>   }
>>
>>   int main(int argc, char **argv)
>>   {
>>       debug("Testing readdir() and related functions\n");
>> -    report(mkdir("/tmp/tst-readdir", 0777) == 0, "mkdir");
>> +#if defined(READ_ONLY_FS)
>> +    report(mkdir("/rofs/tst-readdir-empty2", 0777) == -1 && errno ==
>> EROFS, "mkdir");
>> +#else
>> +    report(mkdir("/tmp/tst-readdir-empty", 0777) == 0, "mkdir empty");
>> +#endif
>>
>>       // test readdir() on empty directory
>> -    DIR *dir = opendir("/tmp/tst-readdir");
>> +    DIR *dir = opendir("/" SUBDIR "/tst-readdir-empty");
>>       report(dir != NULL, "opendir");
>>       struct dirent *ent;
>>       ent = readdir(dir);
>> @@ -43,11 +53,15 @@ int main(int argc, char **argv)
>>       report(iret == 0, "closedir");
>>
>>       // test readdir() on directory with one file
>> -    int fd;
>> -    fd=creat("/tmp/tst-readdir/aaa", 0777);
>> +#if defined(READ_ONLY_FS)
>> +    report(creat("/rofs/tst-readdir/non-existent", 0777) < 0 && errno
>> ==
>> EROFS, "creat");
>> +#else
>> +    report(mkdir("/tmp/tst-readdir", 0777) == 0, "mkdir empty");
>> +    int fd=creat("/tmp/tst-readdir/aaa", 0777);
>>       report(fd>=0, "creat");
>>       close(fd);
>> -    dir = opendir("/tmp/tst-readdir");
>> +#endif
>> +    dir = opendir("/" SUBDIR "/tst-readdir");
>>       report(dir != NULL, "opendir");
>>       ent = readdir(dir);
>>       report(ent != NULL, "readdir");
>> @@ -64,7 +78,7 @@ int main(int argc, char **argv)
>>       report(iret == 0, "closedir");
>>
>>       // test readdir_r() on directory with one file
>> -    dir = opendir("/tmp/tst-readdir");
>> +    dir = opendir("/" SUBDIR "/tst-readdir");
>>       report(dir != NULL, "opendir");
>>       ent = (struct dirent *)malloc(4096);
>>       struct dirent *r;
>> @@ -80,7 +94,7 @@ int main(int argc, char **argv)
>>       free(ent);
>>
>>       // test rewinddir(), still on a directory with one file
>> -    dir = opendir("/tmp/tst-readdir");
>> +    dir = opendir("/" SUBDIR "/tst-readdir");
>>       report(dir != NULL, "opendir");
>>       ent = (struct dirent *)malloc(4096);
>>       report(readdir_r(dir, ent, &r)==0 && r!=NULL, "readdir_r");
>> @@ -106,7 +120,7 @@ int main(int argc, char **argv)
>>       free(ent);
>>
>>       // test telldir(), seekdir()
>> -    dir = opendir("/tmp/tst-readdir");
>> +    dir = opendir("/" SUBDIR "/tst-readdir");
>>       report(dir != NULL, "opendir");
>>       ent = (struct dirent *)malloc(4096);
>>       report(readdir_r(dir, ent, &r)==0 && r!=NULL, "readdir_r");
>> @@ -128,6 +142,11 @@ int main(int argc, char **argv)
>>       report(iret == 0, "closedir");
>>       free(ent);
>>
>> +#if defined(READ_ONLY_FS)
>> +    report(unlink("/rofs/tst-readdir/aaa")==-1 && errno == EROFS,
>> "unlink
>> aaa");
>> +    report(rmdir("/rofs/tst-readdir")==-1 && errno == ENOTEMPTY,
>> "rmdir");
>> +    report(mknod("/rofs/tst-readdir/b", 0777|S_IFREG, 0) == -1 && errno
>> ==
>> EROFS, "mknod");
>> +#else
>>       // clean up the temporary directory we created with one file.
>>       report(unlink("/tmp/tst-readdir/aaa")==0, "unlink aaa");
>>       report(rmdir("/tmp/tst-readdir")==0, "rmdir");
>> @@ -192,9 +211,10 @@ int main(int argc, char **argv)
>>       report(unlink("/tmp/tst-readdir/c")==0, "unlink");
>>       report(unlink("/tmp/tst-readdir/d")==0, "unlink");
>>       report(rmdir("/tmp/tst-readdir")==0, "rmdir");
>> +    report(rmdir("/tmp/tst-readdir-empty")==0, "rmdir empty");
>> +#endif
>>
>> -
>> -    debug("SUMMARY: %d tests, %d failures\n", tests, fails);
>> +    printf("SUMMARY: %d tests, %d failures\n", tests, fails);
>>       return fails == 0 ? 0 : 1;
>>   }
>>
>> diff --git a/tests/tst-symlink.cc b/tests/tst-symlink.cc
>> --- a/tests/tst-symlink.cc
>> +++ b/tests/tst-symlink.cc
>> @@ -13,37 +13,47 @@
>>   #include <unistd.h>
>>   #include <limits.h>
>>   #include <stdlib.h>
>> +#include <iostream>
>>
>>   #define debug printf
>>
>> -#define TESTDIR    "/tmp"
>> +#if defined(READ_ONLY_FS)
>> +#define TESTDIR    "/rofs/tst-symlink"
>> +#else
>> +#define TESTDIR    "/tmp/tst-symlink"
>> +#endif
>>
>>   #define N1    "f1"
>>   #define N2    "f2_AAA"
>>   #define N3    "f3"
>>   #define N4    "f4"
>>   #define N5    "f5"
>> +#define N6    "f6"
>>   #define D1    "d1"
>>   #define D2    "d2_AAA"
>>   #define D3    "d3"
>>   #define D4    "d4"
>>
>>   int tests = 0, fails = 0;
>>
>> -static void report(bool ok, const char *msg)
>> +static void report(bool ok, const char* msg)
>>   {
>>       ++tests;
>>       fails += !ok;
>> -    debug("%s: %s\n", (ok ? "PASS" : "FAIL"), msg);
>> -    if (fails)
>> +    printf("%s: %s\n", (ok ? "PASS" : "FAIL"), msg);
>> +    if (fails) {
>> +        printf("Errno: %d\n", errno);
>>           exit(0);
>> +    }
>>   }
>>
>> +#if !defined(READ_ONLY_FS)
>>   static void fill_buf(char *b, unsigned int no)
>>   {
>>       memset(b, 'A', no - 1);
>>       b[no - 1] = 0;
>>   }
>> +#endif
>>
>>   static bool search_dir(const char *dir, const char *name)
>>   {
>> @@ -67,54 +77,79 @@ int main(int argc, char **argv)
>>   {
>>       struct stat buf;
>>       int rc;
>> -    int error;
>> -    time_t t1;
>>       char path[PATH_MAX];
>>       int fd;
>> -    int fd1;
>> -    char b1[4097];
>> -    char b2[4097];
>> -    char path1[PATH_MAX];
>>
>>       debug("Testing symlink() and related functions.\n");
>>
>>       report(sizeof(path) >= 4096, "sizeof(PATH_MAX)");
>>
>> +#if defined(READ_ONLY_FS)
>> +    report(-1 == mkdir("/rofs/tst-symlink1", 0777) && errno ==
>> EROFS, "mkdir");
>> +#else
>> +    report(0 == mkdir(TESTDIR, 0777), "mkdir");
>> +#endif
>> +
>>       report(chdir(TESTDIR) == 0, "chdir");
>>
>>       /*
>>        * test to check
>> -     * access to symlink
>> -     * file type
>> +     *    access to symlink
>> +     *    file type
>>        */
>> +
>> +#if defined(READ_ONLY_FS)
>> +    fd = open(N1, O_RDONLY);
>> +#else
>>       fd = creat(N1, 0777);
>> +#endif
>>       report(fd >= 0, "creat");
>>       report(search_dir(TESTDIR, N1) == true, "search dir");
>>
>>       report(lstat(N1, &buf) == 0, "lstat");
>>       report(S_ISREG(buf.st_mode) == 1, "file mode");
>>
>> +#if defined(READ_ONLY_FS)
>> +    report(symlink(N1, N6) == -1 && errno == EROFS, "symlink");
>> +    report(search_dir(TESTDIR, N2) == true, "search dir");
>> +#else
>>       report(symlink(N1, N2) == 0, "symlink");
>>       report(search_dir(TESTDIR, N2) == true, "search dir");
>> +#endif
>>
>> +#if defined(READ_ONLY_FS)
>> +    report(access(N1, R_OK) == 0, "access1");
>> +    report(access(N1, R_OK | W_OK) == -1 && errno == EROFS, "access2");
>> +    report(access(N2, R_OK) == 0, "access3");
>> +    report(access(N2, R_OK | W_OK) == -1 && errno == EROFS, "access4");
>> +#else
>>       report(access(N1, R_OK | W_OK) == 0, "access");
>>       report(access(N2, R_OK | W_OK) == 0, "access");
>> +#endif
>>
>>       rc = readlink(N2, path, sizeof(path));
>>       report(rc >= 0, "readlink");
>>       path[rc] = 0;
>> +#if defined(READ_ONLY_FS)
>> +    report(strcmp(path, TESTDIR "/" N1) == 0, "readlink path");
>> +#else
>>       report(strcmp(path, N1) == 0, "readlink path");
>> -
>> +#endif
>>       report(lstat(N2, &buf) == 0, "lstat");
>>       report(S_ISLNK(buf.st_mode) == 1, "file mode");
>>
>>       close(fd);
>> +#if defined(READ_ONLY_FS)
>> +    report(unlink(N1) == -1 && errno == EROFS, "unlink");
>> +#else
>>       report(unlink(N1) == 0, "unlink");
>> +#endif
>>       report(lstat(N2, &buf) == 0, "lstat");
>>       report(S_ISLNK(buf.st_mode) == 1, "file mode");
>>
>> +#if !defined(READ_ONLY_FS)
>>       rc = stat(N2, &buf);
>> -    error = errno;
>> +    int error = errno;
>>       report(rc < 0, "stat");
>>       report(error == ENOENT, "ENOENT expected");
>>
>> @@ -130,7 +165,10 @@ int main(int argc, char **argv)
>>       report(fd >= 0, "creat");
>>       report(symlink(N1, N2) == 0, "symlink");
>>
>> -    fd1 = open(N2, O_RDONLY);
>> +    char b1[4097];
>> +    char b2[4097];
>> +
>> +    int fd1 = open(N2, O_RDONLY);
>>       report(fd1 >= 0, "symlink open");
>>
>>       fill_buf(b1, sizeof(b1));
>> @@ -143,11 +181,14 @@ int main(int argc, char **argv)
>>       report(rc == sizeof(b2), "symlink read");
>>
>>       report(memcmp(b1, b2, sizeof(b1)) == 0, "data verification");
>> +#endif
>>
>>   #ifdef NOT_YET
>>       rc = ftruncate(fd1, 0);
>>       report(rc != 0 && errno == EINVAL, "symlink fd truncate");
>>   #endif
>> +
>> +#if !defined(READ_ONLY_FS)
>>       report(ftruncate(fd, 0) == 0, "file fd truncate");
>>       report(fstat(fd, &buf) == 0, "fstat file");
>>       report(buf.st_size == 0, "file size after truncate");
>> @@ -192,7 +233,7 @@ int main(int argc, char **argv)
>>       report(fd >= 0, "creat");
>>       report(mkdir(D1, 0777) == 0, "mkdir");
>>       report(stat(D1, &buf) == 0, "stat");
>> -    t1 = buf.st_ctime;
>> +    time_t t1 = buf.st_ctime;
>>       sleep(1);
>>
>>       snprintf(path, sizeof(path), "%s/%s", D1, N2);
>> @@ -221,6 +262,7 @@ int main(int argc, char **argv)
>>       report(symlink(N1, path) == 0, "symlink");
>>       report(unlink(path) == 0, "unlink");
>>
>> +    printf("-->Smok\n");
>>       fill_buf(path, 257);
>>       rc = symlink(N1, path);
>>       error = errno;
>> @@ -300,6 +342,7 @@ int main(int argc, char **argv)
>>       report(fd >= 0, "create file");
>>       close(fd);
>>
>> +    char path1[PATH_MAX];
>>       report(symlink(D1, D2) == 0, "symlink to directory"); /* /tmp/d2 ->
>>
>> /tmp/d1 */
>>       snprintf(path1, sizeof(path1), "%s/%s", D1, N2);
>>       report(rename(path, path1) == 0, "rename(f1,f2)");
>> @@ -344,7 +387,14 @@ int main(int argc, char **argv)
>>       report(unlink(path) == 0, "unlink(d4/f5)");
>>       report(unlink(D3) == 0, "unlink(d3)");
>>       report(rmdir(D4) == 0, "rmdir");
>> +#endif
>> +
>> +#if defined(READ_ONLY_FS)
>> +    report(-1 == rmdir(TESTDIR) && errno == ENOTEMPTY, "rmdir");
>> +#else
>> +    report(0 == rmdir(TESTDIR), "rmdir");
>> +#endif
>>
>> -    debug("SUMMARY: %d tests, %d failures\n", tests, fails);
>> +    std::cout << "SUMMARY: " << tests << " tests, " << fails << "
>> failures\n";
>>       return (fails == 0 ? 0 : 1);
>>   }
>> diff --git a/tests/tst-uio.cc b/tests/tst-uio.cc
>> --- a/tests/tst-uio.cc
>> +++ b/tests/tst-uio.cc
>> @@ -73,9 +73,9 @@ int main()
>>       // keeps track of how much it copied. Unbelievably, we had such a
>> bug
>>       // in OSv and didn't notice it for over a year.
>>   #ifdef __OSV__
>> -    const char* fn = "/tests/tst-rename.so";   // A file roughly 200KB
>> in
>> size.
>> +    const char* fn = "/tests/tst-regex.so";   // A file roughly 200KB in
>>
>> size.
>>   #else
>> -    const char* fn = "build/release/tests/tst-rename.so";
>> +    const char* fn = "build/release/tests/tst-regex.so";
>>   #endif
>>       int fd;
>>       expect_success(fd, open(fn, O_RDONLY));
>> diff --git a/tests/tst-zfs-mount.cc b/tests/tst-zfs-mount.cc
>> --- a/tests/tst-zfs-mount.cc
>> +++ b/tests/tst-zfs-mount.cc
>> @@ -162,7 +162,7 @@ int main(int argc, char **argv)
>>       report(fd > 0, "create /tmp/foo");
>>
>>       report(write(fd, &foo, sizeof(foo)) == sizeof(foo), "write
>> sizeof(foo)
>> bytes to fd");
>> -    //report(pwrite(fd, &foo, sizeof(foo), LONG_MAX) == -1 && errno ==
>> EFBIG, "check for maximum allowed offset");
>> +    report(pwrite(fd, &foo, sizeof(foo), LONG_MAX) == -1 && errno ==
>> EFBIG, "check for maximum allowed offset");
>>       report(fsync(fd) == 0, "fsync fd");
>>       report(fstat(fd, &s) == 0, "fstat fd");
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "OSv Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to