[updater] more appropriate annotation; simpler test

GitOrigin-RevId: 46fcfc5c9984017d4e6ab9a39d4d9f3885a928ee
This commit is contained in:
Roman Shevchenko
2024-01-31 21:05:31 +01:00
committed by intellij-monorepo-bot
parent 99fd3449ba
commit f14bf01ef8
2 changed files with 44 additions and 53 deletions

View File

@@ -23,7 +23,7 @@ import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.LongByReference;
import com.sun.jna.win32.StdCallLibrary;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.VisibleForTesting;
import java.io.File;
import java.util.ArrayList;
@@ -76,7 +76,7 @@ public final class NativeFileManager {
}
}
@ApiStatus.Internal
@VisibleForTesting
public static List<Process> getProcessesUsing(File file, int initialBufferSize) {
// If the DLL was not present (XP or other OS), do not try to find it again.
if (!ourFailed) {

View File

@@ -2,74 +2,65 @@
package com.intellij.updater;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
public class NativeFileManagerTest {
class NativeFileManagerTest {
@TempDir Path tempDir;
@SuppressWarnings("SSBasedInspection") // suppress inspections about IntelliJ-only API
@Test public void singleProcessHoldsFile() throws IOException, InterruptedException {
if (!Utils.IS_WINDOWS) return;
@Test void singleProcessHoldsFile() throws IOException, InterruptedException {
assumeTrue(Utils.IS_WINDOWS);
var testFile = File.createTempFile("process-locked-test", ".tmp");
var testFile = Files.writeString(tempDir.resolve("process-locked-test.tmp"), "");
var process = startProcessHoldingFile(testFile);
try {
var process = startProcessHoldingFile(testFile);
try {
var holders = NativeFileManager.getProcessesUsing(testFile).stream()
.map(p -> (long)p.pid).collect(Collectors.toList());
assertThat(holders).containsExactly(process.pid());
} finally {
var holders = NativeFileManager.getProcessesUsing(testFile.toFile()).stream().mapToLong(p -> (long)p.pid).toArray();
assertThat(holders).containsExactly(process.pid());
}
finally {
process.destroy();
process.waitFor();
}
assertThat(NativeFileManager.getProcessesUsing(testFile.toFile())).isEmpty();
}
@Test void moreProcessesThanBufferSize() throws IOException, InterruptedException {
assumeTrue(Utils.IS_WINDOWS);
var processCount = 5;
var bufferSize = processCount - 1; // check that we still receive all the processes even with smaller buffer size
var testFile = Files.writeString(tempDir.resolve("process-locked-test.tmp"), "");
var processes = new Process[processCount];
for (int i = 0; i < processCount; i++) {
processes[i] = startProcessHoldingFile(testFile);
}
try {
var expectedPids = Arrays.stream(processes).mapToLong(Process::pid).toArray();
var holders = NativeFileManager.getProcessesUsing(testFile.toFile(), bufferSize).stream().mapToLong(p -> (long)p.pid).toArray();
assertThat(holders).hasSize(processCount).contains(expectedPids);
}
finally {
for (var process : processes) {
process.destroy();
process.waitFor();
}
assertThat(NativeFileManager.getProcessesUsing(testFile)).isEmpty();
} finally {
var ignored = testFile.delete();
}
assertThat(NativeFileManager.getProcessesUsing(testFile.toFile())).isEmpty();
}
@SuppressWarnings("SSBasedInspection") // suppress inspections about IntelliJ-only API
@Test public void moreProcessesThanBufferSize() throws IOException, InterruptedException {
if (!Utils.IS_WINDOWS) return;
final int processCount = 5;
final int bufferSize = processCount - 1; // check that we still receive all the processes even with smaller buffer size
var testFile = File.createTempFile("process-locked-test", ".tmp");
try {
var processes = new Process[processCount];
for (int i = 0; i < processCount; i++) {
processes[i] = startProcessHoldingFile(testFile);
}
try {
var expectedPids = Arrays.stream(processes).map(Process::pid).collect(Collectors.toList());
var holders = NativeFileManager.getProcessesUsing(testFile, bufferSize).stream()
.map(p -> (long)p.pid).collect(Collectors.toList());
assertThat(holders).hasSize(processCount);
assertThat(holders).containsAll(expectedPids);
} finally {
for (var process : processes) {
process.destroy();
process.waitFor();
}
}
assertThat(NativeFileManager.getProcessesUsing(testFile)).isEmpty();
} finally {
var ignored = testFile.delete();
}
}
private static Process startProcessHoldingFile(File file) throws IOException {
private static Process startProcessHoldingFile(Path file) throws IOException {
var command = String.format(
"$handle = [IO.File]::Open('%s', [IO.FileMode]::Open, [IO.FileAccess]::ReadWrite, [IO.FileShare]::ReadWrite); Write-Output 'ok'; Start-Sleep 10",
file);