Git Product home page Git Product logo

Comments (9)

cgdecker avatar cgdecker commented on May 6, 2024

Yeah, there should be a way to configure this. I didn't make it configurable initially because I'm not sure what the best way to expose configuration for it is. It's rather fine-grained to expose as a top-level configuration option, and it's not impossible that at some point we may want to expose a way to configure that WatchService implementation at a higher level.

from jimfs.

cschoell avatar cschoell commented on May 6, 2024

Real pita here as well ... I want to use jimFS to speed up my (integration) unit tests and that's a show stopper in that regard really ;)

I solved it by making the fields accessible via reflection and setting the values straight after creating the watchservice ... but seriously - thats an ultra ugly hack ;)

Really great project otherwise though👍

from jimfs.

pvorb avatar pvorb commented on May 6, 2024

@cschoell May I ask how you did that? I also tried to use reflection to change the pollingTime of the PollingWatchService, but because FileSystem returns a new instance every time, that's no applicable approach for testing.

@cgdecker A configuration property would be much appreciated.

from jimfs.

cschoell avatar cschoell commented on May 6, 2024

@pvorb I basically have a single method / place where I create a new WatchService from my FileSystem. In my Unit Test I override the method which calls <FileSystem>.newWatchService() (or alternatively replace some watchsystem provider object...?) and I'm good to go....

Example code of class to test inside my unit test:

XYService underTest = new XYService() {
        @Override
        protected WatchService createWatchservice() throws IOException {
            WatchService watchservice = super.createWatchservice();
            //very ugly hack to make com.google.common.jimfs.PollingWatchService usable in a timely fashion
            //there is no straight forward way to configure the polling time (It's statically set to 5 SECONDS)
            ReflectionTestUtils.setField(watchservice, "pollingTime", 5);
            ReflectionTestUtils.setField(watchservice, "timeUnit", TimeUnit.MILLISECONDS);
            return watchservice;
        }
    };

... ReflectionTestUtils is from the Spring Test Framework btw ;)

from jimfs.

pvorb avatar pvorb commented on May 6, 2024

@cschoell Thank you for the inspiration.

Unfortunately it doesn't fit my particular situation. I want to test a class that directly calls FileSystem.newWatchService() (in the test case, it's a JimfsFileSystem), but I can't override that method since JimfsFileSystem is final. Even PowerMock can't do it since the class is package-private. Probably I also need to abstract some kind of WatchServiceProvider (XYService like you called it). Nonetheless, thanks for the quick reply.

from jimfs.

cschoell avatar cschoell commented on May 6, 2024

Happy I was able to help a bit ;)

XYService is the class which Im Testing though - which is anonymously extended in the Unit Test... And in this case my "provider" is just a method called ’createWatchservice’ which I override...

Just to clarify ;)

from jimfs.

sparty02 avatar sparty02 commented on May 6, 2024

👍 On this! In the meantime, for anybody interested, I leveraged the following workaround:

Decorator to setup the PollingWatchService with a configurable polling interval (note it has to be in the com.google.common.jimfs package due to the visibility of items in the JimfsFileSystem:

package com.google.common.jimfs;

import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.WatchService;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.nio.file.spi.FileSystemProvider;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.assertj.core.util.Objects;

public class PollOnWatchFileSystemDecorator extends FileSystem
{

    private final JimfsFileSystem delegate;
    private final long pollingTime;
    private final TimeUnit timeUnit;

    public PollOnWatchFileSystemDecorator(FileSystem delegate, long pollingTime, TimeUnit timeUnit)
    {
        if (!(delegate instanceof JimfsFileSystem))
        {
            throw new RuntimeException(
                "Decorator only works with instances of the JimfsFileSystem");
        }

        this.delegate = Objects.castIfBelongsToType(delegate, JimfsFileSystem.class);
        this.pollingTime = pollingTime;
        this.timeUnit = timeUnit;
    }

    @Override
    public FileSystemProvider provider()
    {
        return delegate.provider();
    }

    @Override
    public void close() throws IOException
    {
        delegate.close();
    }

    @Override
    public boolean isOpen()
    {
        return delegate.isOpen();
    }

    @Override
    public boolean isReadOnly()
    {
        return delegate.isReadOnly();
    }

    @Override
    public String getSeparator()
    {
        return delegate.getSeparator();
    }

    @Override
    public Iterable<Path> getRootDirectories()
    {
        return delegate.getRootDirectories();
    }

    @Override
    public Iterable<FileStore> getFileStores()
    {
        return delegate.getFileStores();
    }

    @Override
    public Set<String> supportedFileAttributeViews()
    {
        return delegate.supportedFileAttributeViews();
    }

    @Override
    public Path getPath(String first, String... more)
    {
        return delegate.getPath(first, more);
    }

    @Override
    public PathMatcher getPathMatcher(String syntaxAndPattern)
    {
        return delegate.getPathMatcher(syntaxAndPattern);
    }

    @Override
    public UserPrincipalLookupService getUserPrincipalLookupService()
    {
        return delegate.getUserPrincipalLookupService();
    }

    @Override
    public WatchService newWatchService() throws IOException
    {
        return new PollingWatchService(delegate.getDefaultView(), delegate.getPathService(),
            delegate.getFileStore().state(), pollingTime, timeUnit);
    }

}

...then in the consuming class:

FileSystem unixFs = Jimfs.newFileSystem(com.google.common.jimfs.Configuration.unix());
FileSystem fileSystem = new PollOnWatchFileSystemDecorator(unixFs, 1, TimeUnit.SECONDS);

from jimfs.

cgdecker avatar cgdecker commented on May 6, 2024

I do agree that it should be addressed. As I indicated above, the main thing that's made me hesitant about just throwing a new option into Configuration is that it effectively locks in polling as the only type of watch service that can be used. At the very least, it makes it difficult to change that in an elegant way later (if, say, we wanted to add a watch service implementation that gets change notifications pushed to it rather than polling the file system).

I've actually got something in the works for this that should address the above concern, it just obviously hasn't been a high priority for me unfortunately. I'll try to make the changes in the next couple of weeks, and then perhaps make a 1.1 release.

from jimfs.

pvorb avatar pvorb commented on May 6, 2024

Thank you for adding WatchServiceConfiguration!

from jimfs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.