예제 #1
0
def test_basic(
    nydus_anchor,
    nydus_image: RafsImage,
    io_duration,
    backend,
    rafs_conf: RafsConf,
    fs_version,
):
    """
    title: Basic functionality test
    description: Mount rafs with different mount options
    pass_criteria:
      - Rafs can be mounted.
      - Rafs can be unmounted.
    """
    nydus_image.set_backend(backend,
                            blob_dir=()).create_image(fs_version=fs_version)
    rafs_conf.set_rafs_backend(backend)

    rafs = RafsMount(nydus_anchor, nydus_image, rafs_conf)
    rafs.mount()
    assert rafs.is_mounted()

    workload_gen = WorkloadGen(nydus_anchor.mount_point, nydus_image.rootfs())

    workload_gen.setup_workload_generator()
    workload_gen.io_read(io_duration)

    nydus_anchor.check_nydusd_health()
    assert workload_gen.io_error == False
    assert workload_gen.verify_entire_fs()

    assert rafs.is_mounted()
    rafs.umount()
예제 #2
0
def test_prefetch_without_cache(nydus_anchor: NydusAnchor,
                                nydus_scratch_image: RafsImage,
                                rafs_conf: RafsConf):
    """Files prefetch test

    1. relative hinted prefetch files
    2. absolute hinted prefetch files
    3. source rootfs root dir.
    """

    rafs_conf.enable_fs_prefetch().set_rafs_backend(Backend.BACKEND_PROXY)
    rafs_conf.dump_rafs_conf()

    dist = Distributor(nydus_scratch_image.rootfs(), 4, 4)
    dist.generate_tree()
    dist.put_directories(20)
    dist.put_multiple_files(40, Size(8, Unit.KB))
    dist.put_hardlinks(6)
    dist.put_multiple_chinese_files(random.randint(20, 28), Size(20, Unit.KB))

    hint_files = ["/"]
    hint_files.extend(dist.files)
    hint_files.extend(dist.dirs)
    hint_files.extend(dist.symlinks)
    hint_files.extend(dist.hardlinks)

    hint_files = [os.path.join("/", p) for p in hint_files]
    hint_files = "\n".join(hint_files)

    nydus_scratch_image.set_backend(Backend.BACKEND_PROXY).create_image(
        readahead_policy="fs", readahead_files=hint_files.encode())

    rafs = RafsMount(nydus_anchor, nydus_scratch_image, rafs_conf)
    rafs.mount()
    assert rafs.is_mounted()

    workload_gen = WorkloadGen(nydus_anchor.mount_point,
                               nydus_scratch_image.rootfs())

    # TODO: Run several parallel read workers against the mount_point
    workload_gen.setup_workload_generator()
    workload_gen.torture_read(8, 5)
    workload_gen.finish_torture_read()

    assert NydusAnchor.check_nydusd_health()
    assert not workload_gen.io_error

    assert rafs.is_mounted()
    rafs.umount()
예제 #3
0
def test_meta(nydus_anchor: NydusAnchor, rafs_conf: RafsConf,
              nydus_scratch_image: RafsImage):
    anchor = nydus_anchor
    rafs_conf.set_rafs_backend(Backend.BACKEND_PROXY).enable_rafs_blobcache()
    rafs_conf.dump_rafs_conf()

    dist = Distributor(nydus_scratch_image.rootfs(), 8, 5)
    dist.generate_tree()

    xattr_verifier = verifier.XattrVerifier(anchor.mount_point, dist)
    xattr_verifier.scratch(nydus_scratch_image.rootfs())

    symlink_verifier = verifier.SymlinkVerifier(anchor.mount_point, dist)
    symlink_verifier.scratch()

    # Do some meta operations on scratch dir before creating rafs image file.
    # Use scratch dir as image source dir as we just prepared test meta into it.
    nydus_scratch_image.set_backend(Backend.BACKEND_PROXY).create_image()
    rafs = RafsMount(anchor, nydus_scratch_image, rafs_conf)
    rafs.thread_num(4).mount()
    assert rafs.is_mounted()

    xattr_verifier.verify(anchor.mount_point)
    symlink_verifier.verify(anchor.mount_point, nydus_scratch_image.rootfs())

    workload_gen = WorkloadGen(anchor.mount_point,
                               nydus_scratch_image.rootfs())
    workload_gen.setup_workload_generator()

    workload_gen.torture_read(10, 3)
    workload_gen.finish_torture_read()

    assert workload_gen.io_error == False
    assert anchor.check_nydusd_health()
예제 #4
0
def test_prefetch_with_cache(
    nydus_anchor,
    nydus_scratch_image: RafsImage,
    rafs_conf: RafsConf,
    thread_cnt,
    compressor,
    is_cache_compressed,
):
    """
    title: Prefetch from various backend
    description:
      - Enable rafs backend blob cache, as it is disabled by default
    pass_criteria:
      - Rafs can be mounted.
      - Rafs can be unmounted.
    """
    rafs_conf.enable_rafs_blobcache(is_compressed=is_cache_compressed)
    rafs_conf.set_rafs_backend(Backend.BACKEND_PROXY, prefix="object_prefix/")
    rafs_conf.enable_fs_prefetch(threads_count=4,
                                 bandwidth_rate=Size(40, Unit.MB).B)
    rafs_conf.dump_rafs_conf()

    dist = Distributor(nydus_scratch_image.rootfs(), 4, 4)
    dist.generate_tree()
    dist.put_directories(20)
    dist.put_multiple_files(40, Size(3, Unit.MB))
    dist.put_hardlinks(6)
    dist.put_multiple_chinese_files(random.randint(20, 28), Size(20, Unit.KB))

    nydus_scratch_image.set_backend(Backend.BACKEND_PROXY,
                                    prefix="object_prefix/").create_image(
                                        compressor=compressor,
                                        readahead_policy="fs",
                                        readahead_files="/".encode(),
                                    )

    rafs = RafsMount(nydus_anchor, nydus_scratch_image, rafs_conf)
    rafs.thread_num(4).mount()

    nc = NydusAPIClient(rafs.get_apisock())
    workload_gen = WorkloadGen(nydus_anchor.mount_point,
                               nydus_scratch_image.rootfs())
    m = nc.get_blobcache_metrics()
    time.sleep(0.3)
    assert m["prefetch_data_amount"] != 0

    workload_gen.setup_workload_generator()
    workload_gen.torture_read(thread_cnt, 10)

    assert NydusAnchor.check_nydusd_health()

    workload_gen.finish_torture_read()
    assert not workload_gen.io_error

    # In this way, we can check if nydusd is crashed.
    assert rafs.is_mounted()
    rafs.umount()
예제 #5
0
def test_blobcache(
    nydus_anchor: NydusAnchor,
    nydus_image: RafsImage,
    rafs_conf: RafsConf,
    compressor,
    backend,
):
    """
    Allocate a file with local test working directory.
    Loop the file so to get a small file system which is easy to get full.
    Change blob cache location the above test blobdir
    """

    blobdir = "/blobdir"

    blob_backend = "blob_backend"
    fd = os.open(blob_backend, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
    os.posix_fallocate(fd, 0, 1024 * 1024 * 4)
    os.close(fd)

    utils.execute(["mkfs.ext4", "-F", blob_backend])
    utils.execute(["mount", blob_backend, blobdir])

    rafs_conf.enable_rafs_blobcache()
    rafs_conf.set_rafs_backend(backend)
    rafs_conf.dump_rafs_conf()

    cache_file = os.listdir(blobdir)
    assert len(cache_file) == 1

    rafs = RafsMount(nydus_anchor, nydus_image, rafs_conf)
    rafs.mount()
    assert rafs.is_mounted()

    workload_gen = WorkloadGen(nydus_anchor.mount_point,
                               nydus_anchor.source_dir)

    workload_gen.setup_workload_generator()
    workload_gen.torture_read(4, 15)

    nydus_anchor.start_stats_checker()
    workload_gen.finish_torture_read()
    nydus_anchor.stop_stats_checker()

    cache_file = os.listdir(blobdir)
    assert len(cache_file) >= 2

    if workload_gen.io_error:
        warnings.warn(
            UserWarning("Rafs will return EIO if blobcache file is full"))

    rafs.umount()

    ret, _ = utils.execute(["umount", blobdir])
    assert ret

    os.unlink(blob_backend)
예제 #6
0
def test_blob_prefetch(nydus_anchor: NydusAnchor,
                       nydus_scratch_image: RafsImage, readahead_policy):
    """
    description:
        For rafs, there are two types of prefetching.
        1. Prefetch files from fs-layer, which means each file is prefetched one by one.
        2. Prefetch directly from backend/blob layer, which means a range will be fetched from blob
    """
    # Try to delete any access log since if it present, bootstrap blob prefetch won't work.
    utils.execute("rm -rf *.access", shell=True)

    dist = Distributor(nydus_scratch_image.rootfs(), 8, 2)
    dist.generate_tree()
    dist.put_directories(20)
    dist.put_multiple_files(100, Size(64, Unit.KB))
    dist.put_symlinks(30)
    dist.put_hardlinks(20)
    dist.put_multiple_files(40, Size(64, Unit.KB))

    utils.clean_pagecache()

    hint_files = dist.files[-40:]
    hint_files.extend(dist.symlinks[-20:])

    hint_files = [os.path.join("/", p) for p in hint_files]
    hint_files = "\n".join(hint_files)

    nydus_scratch_image.set_backend(Backend.LOCALFS).create_image(
        readahead_policy=readahead_policy,
        readahead_files=hint_files.encode(),
    )

    rafs_conf = RafsConf(nydus_anchor, nydus_scratch_image)
    rafs_conf.set_rafs_backend(Backend.LOCALFS, image=nydus_scratch_image)
    rafs_conf.enable_records_readahead(interval=1)
    rafs_conf.dump_rafs_conf()

    rafs = RafsMount(nydus_anchor, nydus_scratch_image, rafs_conf)
    with utils.timer("Mount elapse"):
        rafs.thread_num(7).mount()
    assert rafs.is_mounted()

    wg = WorkloadGen(nydus_anchor.mount_point, nydus_scratch_image.rootfs())

    # TODO: Run several parallel read workers against the mount_point
    wg.setup_workload_generator()
    wg.torture_read(5, 5)
    wg.finish_torture_read()

    utils.clean_pagecache()
예제 #7
0
def test_iostats(nydus_anchor: NydusAnchor, nydus_image: RafsImage,
                 rafs_conf: RafsConf):
    rafs_id = "/"
    rafs_conf.enable_files_iostats().enable_latest_read_files(
    ).set_rafs_backend(Backend.OSS)
    nydus_image.set_backend(Backend.OSS).create_image()
    rafs = RafsMount(nydus_anchor, nydus_image, rafs_conf)

    rafs.mount()
    assert rafs.is_mounted()

    nc = NydusAPIClient(rafs.get_apisock())

    duration = 5

    wg = WorkloadGen(nydus_anchor.mount_point, nydus_image.rootfs())
    wg.setup_workload_generator()
    wg.torture_read(4, duration)

    while duration:
        time.sleep(1)
        duration -= 1
        nc.get_global_metrics()
        nc.get_files_metrics(rafs_id)
        nc.get_backend_metrics(rafs_id)

    wg.finish_torture_read()

    duration = 7
    wg.torture_read(4, duration)
    # Disable it firstly and then enable it.
    # TODO: files metrics can't be toggled dynamically now. Try to implement it.
    # nc.disable_files_metrics(rafs_id)
    # nc.enable_files_metrics(rafs_id)

    r = nc.get_latest_files_metrics(rafs_id)
    print(r)

    while duration:
        time.sleep(1)
        duration -= 1
        nc.get_files_metrics(rafs_id)

    wg.finish_torture_read()
    rafs.umount()
예제 #8
0
def test_signal_handling(nydus_anchor: NydusAnchor,
                         nydus_scratch_image: RafsImage, rafs_conf: RafsConf,
                         sig):

    dist = Distributor(nydus_scratch_image.rootfs(), 2, 2)
    dist.generate_tree()
    dist.put_multiple_files(5, Size(2, Unit.KB))

    nydus_scratch_image.set_backend(Backend.BACKEND_PROXY).create_image()

    victim = os.path.join(nydus_anchor.mount_point, dist.files[-1])

    rafs_conf.set_rafs_backend(Backend.BACKEND_PROXY)

    rafs = RafsMount(nydus_anchor, nydus_scratch_image, rafs_conf)
    rafs.mount()
    fd = os.open(victim, os.O_RDONLY)
    assert rafs.is_mounted()
    os.kill(rafs.p.pid, sig)
    time.sleep(3)

    assert not os.path.ismount(nydus_anchor.mount_point)

    rafs.p.wait()