On Tue, May 15, 2018 at 7:25 AM, Waldek Kozaczuk <jwkozac...@gmail.com>
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 <jwkoz...@gmail.com>
>> Committer: Nadav Har'El <n...@scylladb.com>
>> 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 <jwkoz...@gmail.com>
>> Message-Id: <1521695448-28564-5-git-send-email-jwkozac...@gmail.com>
>>
>> ---
>> 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 $@.skel > $@
>> -        @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 osv-dev+unsubscr...@googlegroups.com.
> 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 osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to