Testing plugin action using testData, but no repository found

Answered

Hello. I am trying to test a plugin action that is only visible if there is git installed for a project. I created a directory in testdata that has mock git data (with configs, refs, etc.), and somewhere in my test I rename the mock git directory to .git in another temporary directory when setting up the test.

I tried using BasePlatformTestCase so that I can use configureByFile() to refer to the temporary directory. However, my tests fail because GitRepository.getRepositories() returns an empty list when using Git4Idea functions in my source code, resulting in null.

I don't know if I'm misunderstanding the documentation or Git4Idea source code, so I was wondering if anyone could help me with this.

Thanks in advance

8 comments
Comment actions Permalink

I'm sorry, but I couldn't find GitRepository.getRepositories() which you refer. Did you mean GitRepositoryManager.getRepositories()?

Can you share your code?

0
Comment actions Permalink

Hi Jakub,

My apologies, yes I meant to say GitRepositoryManager.getRepositories().

I'll try to simplify how my code looks at the moment:

 

MyAction.java

public class MyAction extends AnAction {

...

public class MyAction extends AnAction {
@Override
public void update(AnActionEvent e) {
GitRepository repo = MyUtilFile.getCurrentRepository(e.getProject());
e.getPresentation().setVisible(repo != null);
}
}
}

 

MyUtilFile.java

public class MyUtilFile {

...


public static GitRepository getCurrentRepository(Project project) {
// Returns null here in my test because no repositories are found
if (GitRepositoryManager.getInstance(project).getRepositories().isEmpty()) {
return null;
}
return GitRepositoryManager.getInstance(project)
.getRepositories()
.get(0);
}
}

 

MyActionTest.java

public class MyActionTest extends BasePlatformTestCase {
@Override
public void setUp() throws Exception {
super.setUp();
String thisDir = System.getProperty("user.dir");
String path = createTempDirTestFixture().getTempDirPath();

File src = new File(thisDir + "/src/test/testData/exampleProject");
File dst = new File(path);

FileUtils.copyDirectory(src, dst);

// exampleProject has a gitdir inside with mock git data
File oldGDir = new File(path + "/gitdir");
File newGitDir = new File(path + "/.git");

// Attempting to rename gitdir to .git
oldGitDir.renameTo(newGitDir);
}

@Override
protected TempDirTestFixture createTempDirTestFixture() {
return super.createTempDirTestFixture();
}

@Override
protected Project getProject() {
return super.getProject();
}

@Override
public String getTestDataPath() {
return "src/test/testdata/exampleProject";
}

public void testIsVisibleWithGitRepo() {
myFixture.configureByFile("src/file.txt");
AnAction action = new MyAction();
Presentation presentation = myFixture.testAction(action);
assertTrue(presentation.isVisible());
0
Comment actions Permalink

Can you try, after renaming the GIT directory to .git, call the following method?

GitRepositoryManager.getInstance(it).getRepositoryForRoot(VirtualFile)

It is supposed to refresh the information about the repository.

0
Comment actions Permalink

Hi sorry for the late follow-up (timezones).

 

When running the following, repo is still null:

VirtualFile file = LocalFileSystem.getInstance().findFileByPath(dst.getAbsolutePath());
GitRepository repo = GitRepositoryManager.getInstance(getProject()).getRepositoryForRoot(file);

 

I also tried newGitDir.getAbsolutePath() to get the virtual file using findFileByPath. But not even with this a repo instance is defined. However, I can confirm that the renaming does work as intended. Here is how the path dst.getAbsolutePath() looks like: file:///Users/svorden/git/myproject/temp:/root

0
Comment actions Permalink

It's better to explicitly make sure that IDE knows about renamed directory, see VfsUtil.markDirtyAndRefresh().

Main issue is that test root needs to be registered in vcs mappings (the ones from "Settings | Version Control" tab).
This can be done using ProjectLevelVcsManager.getInstance(project).setDirectoryMappings(singletonList(new VcsDirectoryMapping(virtualFile.getPath(), GitVcs.NAME))).

See GitSingleRepoTest in IJ-community sources as an example.

0
Comment actions Permalink

Hi Aleksey,

By running the code you provided using ProjectLevelVcsManagerrepo is no longer null. Thanks! This is how my code looks like:

file = LocalFileSystem.getInstance().findFileByPath(dst.getAbsolutePath());
ProjectLevelVcsManager.getInstance(getProject()).setDirectoryMappings(Collections.singletonList(new VcsDirectoryMapping(dst.getAbsolutePath(), GitVcs.NAME)));
GitRepositoryManager.getInstance(getProject()).getRepositoryForRoot(file);

 

I'm now facing an issue though when I run my test. I don't know if it's related to my test though and I'd like some of your input:

Virtual pointer 'file:///Users/svorden/git/myproject/temp:/root' hasn't been disposed: --------------Creation trace: 
java.lang.Throwable
at com.intellij.openapi.util.TraceableDisposable.<init>(TraceableDisposable.java:31)
at com.intellij.openapi.vfs.impl.VirtualFilePointerImpl.<init>(VirtualFilePointerImpl.java:40)
at com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl.getOrCreate(VirtualFilePointerManagerImpl.java:340)
at com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl.create(VirtualFilePointerManagerImpl.java:219)
at com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl.create(VirtualFilePointerManagerImpl.java:130)
at com.intellij.openapi.vcs.impl.projectlevelman.NewMappings.lambda$collectMappedRoots$4(NewMappings.java:259)
at com.intellij.openapi.application.ReadAction.lambda$run$1(ReadAction.java:52)
at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:865)
at com.intellij.openapi.application.ReadAction.compute(ReadAction.java:61)
at com.intellij.openapi.application.ReadAction.run(ReadAction.java:51)
at com.intellij.openapi.vcs.impl.projectlevelman.NewMappings.collectMappedRoots(NewMappings.java:247)
at com.intellij.openapi.vcs.impl.projectlevelman.NewMappings.updateMappedRoots(NewMappings.java:195)
at com.intellij.openapi.vcs.impl.projectlevelman.NewMappings.updateVcsMappings(NewMappings.java:183)
at com.intellij.openapi.vcs.impl.projectlevelman.NewMappings.setDirectoryMappings(NewMappings.java:407)
at com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl.setDirectoryMappings(ProjectLevelVcsManagerImpl.java:392)
at org.ualberta.smr.explainmergeconflict.actions.MyActionTest.setUp(MyActionTest.java:58)
at com.intellij.testFramework.UsefulTestCase.defaultRunBare(UsefulTestCase.java:390)
at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait$1.invoke(EdtTestUtil.kt:18)
at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait$1.invoke(EdtTestUtil.kt:13)
at com.intellij.testFramework.EdtTestUtilKt$runInEdtAndWait$3.run(EdtTestUtil.kt:67)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:303)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:417)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
-------------Own trace:
com.intellij.openapi.util.TraceableDisposable$DisposalException: 207634160
at com.intellij.openapi.util.TraceableDisposable.getStackTrace(TraceableDisposable.java:121)
at com.intellij.openapi.vfs.impl.VirtualFilePointerTracker.assertPointersAreDisposed(VirtualFilePointerTracker.java:86)
at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.lambda$tearDown$38(CodeInsightTestFixtureImpl.java:1281)
at com.intellij.testFramework.RunAll.collectExceptions(RunAll.java:57)
at com.intellij.testFramework.RunAll.runAll(RunAll.java:35)
at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.tearDown(CodeInsightTestFixtureImpl.java:1234)
at com.intellij.testFramework.fixtures.BasePlatformTestCase.tearDown(BasePlatformTestCase.java:61)
at org.ualberta.smr.explainmergeconflict.actions.MyActionTest.tearDown(MyActionTest.java:65)
at com.intellij.testFramework.UsefulTestCase.defaultRunBare(UsefulTestCase.java:402)
at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait$1.invoke(EdtTestUtil.kt:18)
at com.intellij.testFramework.EdtTestUtil$Companion$runInEdtAndWait$1.invoke(EdtTestUtil.kt:13)
at com.intellij.testFramework.EdtTestUtilKt$runInEdtAndWait$3.run(EdtTestUtil.kt:67)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:303)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:417)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
0
Comment actions Permalink

Memory leak might be caused by second createTempDirTestFixture call. Using 'myFixture.getTempDirPath()' should fix the issue.

0
Comment actions Permalink

Also, you're using in-memory mock VFS paths together with java.io.File. This is likely to cause issues.

 

UPD: It should not be an issue, as "temp:///" file system is disabled by default.

0

Please sign in to leave a comment.