Files
openide/java/java-tests/testSrc/com/intellij/util/indexing/MultiProjectIndexTest.kt
Dmitry Batkovich d65f524f97 rocksdb index: rebuilt db when exited abnormally, do not access closed db
GitOrigin-RevId: d2e8b25e9584e63db0054e67c6206f4dbf62e867
2021-04-13 15:41:33 +00:00

142 lines
5.6 KiB
Kotlin

// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.util.indexing
import com.intellij.find.ngrams.TrigramIndex
import com.intellij.ide.plugins.loadExtensionWithText
import com.intellij.openapi.module.JavaModuleType
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ex.ProjectManagerEx
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.psi.stubs.StubIndexKey
import com.intellij.psi.stubs.StubUpdatingIndex
import com.intellij.testFramework.*
import com.intellij.testFramework.rules.TempDirectory
import com.intellij.util.ui.UIUtil
import junit.framework.TestCase
import org.junit.Rule
import org.junit.Test
import java.nio.file.Path
import java.util.concurrent.atomic.AtomicInteger
import kotlin.io.path.writeText
import kotlin.test.assertEquals
const val fileNameMarkerPrefix = "TestFoo"
@RunsInEdt
class MultiProjectIndexTest {
@Rule
@JvmField
val tempDir = TempDirectory()
@Rule
@JvmField
val disposable = DisposableRule()
@Rule
@JvmField
val appRule = ApplicationRule()
@Rule
@JvmField
val runInEdt = EdtRule()
@Test
fun `test index extension process files intersection`() {
val text = "<fileBasedIndexInfrastructureExtension implementation=\"" + CountingTestExtension::class.java.name + "\"/>"
Disposer.register(disposable.disposable, loadExtensionWithText(text, CountingTestExtension::class.java.classLoader))
val ext = FileBasedIndexInfrastructureExtension.EP_NAME.findExtension(CountingTestExtension::class.java)!!
val projectPath1 = tempDir.newDirectory("project1").toPath()
val projectPath2 = tempDir.newDirectory("project2").toPath()
val commonContentRoot = tempDir.newDirectory("common-content-root").toPath()
commonContentRoot.resolve("${fileNameMarkerPrefix}1.txt").writeText("hidden gem")
commonContentRoot.resolve("${fileNameMarkerPrefix}2.txt").writeText("foobar")
val project1 = openProject(projectPath1)
val project2 = openProject(projectPath2)
val module1 = PsiTestUtil.addModule(project1, JavaModuleType.getModuleType(), "module1", projectPath1.toVirtualFile())
val module2 = PsiTestUtil.addModule(project2, JavaModuleType.getModuleType(), "module2", projectPath1.toVirtualFile())
PsiTestUtil.addContentRoot(module1, commonContentRoot.toVirtualFile())
assertEquals(0, ext.trigramCounter.get())
assertEquals(2, ext.stubCounter.get()) // stubs should not be build for txt files
val commonBundledFileCount = ext.commonBundledFileCounter.get()
PsiTestUtil.addContentRoot(module2, commonContentRoot.toVirtualFile())
assertEquals(2, ext.trigramCounter.get())
assertEquals(2, ext.stubCounter.get())
assertEquals(commonBundledFileCount, ext.commonBundledFileCounter.get())
ProjectManagerEx.getInstanceEx().forceCloseProject(project1)
ProjectManagerEx.getInstanceEx().forceCloseProject(project2)
TestCase.assertTrue(project1.isDisposed)
TestCase.assertTrue(project2.isDisposed)
}
private fun openProject(path: Path): Project {
val project = PlatformTestUtil.loadAndOpenProject(path, disposable.disposable)
do {
UIUtil.dispatchAllInvocationEvents() // for post-startup activities
}
while (DumbService.getInstance(project).isDumb)
return project
}
private fun Path.toVirtualFile(): VirtualFile = VirtualFileManager.getInstance().refreshAndFindFileByNioPath(this)!!
}
class CountingTestExtension : FileBasedIndexInfrastructureExtension {
val stubCounter = AtomicInteger()
val trigramCounter = AtomicInteger()
val commonBundledFileCounter = AtomicInteger()
override fun createFileIndexingStatusProcessor(project: Project): FileBasedIndexInfrastructureExtension.FileIndexingStatusProcessor? {
return object : FileBasedIndexInfrastructureExtension.FileIndexingStatusProcessor {
override fun shouldProcessUpToDateFiles(): Boolean = true
override fun processUpToDateFile(file: IndexedFile, inputId: Int, indexId: ID<*, *>): Boolean {
if (file.fileName.startsWith(fileNameMarkerPrefix)) {
if (indexId == TrigramIndex.INDEX_ID) {
trigramCounter.incrementAndGet()
}
else if (indexId == StubUpdatingIndex.INDEX_ID) {
stubCounter.incrementAndGet()
}
}
if (file.fileName == "svg20.rnc" && indexId == TrigramIndex.INDEX_ID) {
commonBundledFileCounter.incrementAndGet()
}
return true
}
override fun tryIndexFileWithoutContent(file: IndexedFile, inputId: Int, indexId: ID<*, *>): Boolean = false
override fun hasIndexForFile(file: VirtualFile, inputId: Int, extension: FileBasedIndexExtension<*, *>): Boolean = false
}
}
override fun <K : Any?, V : Any?> combineIndex(indexExtension: FileBasedIndexExtension<K, V>,
baseIndex: UpdatableIndex<K, V, FileContent>): UpdatableIndex<K, V, FileContent> {
return baseIndex
}
override fun onFileBasedIndexVersionChanged(indexId: ID<*, *>) = Unit
override fun onStubIndexVersionChanged(indexId: StubIndexKey<*, *>) = Unit
override fun initialize(indexLayoutId: String?): FileBasedIndexInfrastructureExtension.InitializationResult =
FileBasedIndexInfrastructureExtension.InitializationResult.SUCCESSFULLY
override fun resetPersistentState() = Unit
override fun resetPersistentState(indexId: ID<*, *>) = Unit
override fun shutdown() = Unit
override fun getVersion(): Int = 0
}