yeg
2026-08-26 de98fe81cca90dd855e0519f065e77fce56333ef
ruoyi-device/src/test/java/com/ruoyi/device/registry/DeviceAdapterRegistryTest.java
@@ -7,6 +7,11 @@
import static org.junit.jupiter.api.Assertions.assertNotSame;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.jupiter.api.Test;
import com.ruoyi.device.api.DeviceAdapter;
@@ -25,10 +30,10 @@
            AdapterInstanceConfig config = config("127.0.0.1", true);
            registry.synchronize(config);
            DeviceAdapter first = registry.require("lab-bts");
            DeviceAdapter first = registry.execute("lab-bts", adapter -> adapter);
            registry.synchronize(config);
            assertSame(first, registry.require("lab-bts"));
            assertSame(first, registry.execute("lab-bts", adapter -> adapter));
            assertFalse(factory.adapters.get(0).closed.get());
        }
    }
@@ -45,13 +50,106 @@
            registry.synchronize(config("127.0.0.2", true));
            assertTrue(first.closed.get());
            assertNotSame(first, registry.require("lab-bts"));
            assertNotSame(first, registry.execute("lab-bts", adapter -> adapter));
            registry.synchronize(config("127.0.0.2", false));
            assertTrue(factory.adapters.get(1).closed.get());
            assertFalse(registry.contains("lab-bts"));
            assertThrows(AdapterRegistryException.class, () -> registry.require("lab-bts"));
            assertThrows(AdapterRegistryException.class,
                    () -> registry.execute("lab-bts", adapter -> adapter));
        }
    }
    @Test
    void serializesOperationsForTheSameAdapterInstance() throws Exception
    {
        RecordingFactory factory = new RecordingFactory();
        try (DeviceAdapterRegistry registry = new DeviceAdapterRegistry(List.of(factory)))
        {
            registry.synchronize(config("127.0.0.1", true));
            CountDownLatch firstEntered = new CountDownLatch(1);
            CountDownLatch releaseFirst = new CountDownLatch(1);
            CountDownLatch secondEntered = new CountDownLatch(1);
            ExecutorService executor = Executors.newFixedThreadPool(2);
            try
            {
                Future<?> first = executor.submit(() -> registry.execute("lab-bts", adapter -> {
                    firstEntered.countDown();
                    await(releaseFirst);
                    return null;
                }));
                assertTrue(firstEntered.await(1, TimeUnit.SECONDS));
                Future<?> second = executor.submit(() -> registry.execute("lab-bts", adapter -> {
                    secondEntered.countDown();
                    return null;
                }));
                assertFalse(secondEntered.await(100, TimeUnit.MILLISECONDS));
                releaseFirst.countDown();
                first.get(1, TimeUnit.SECONDS);
                second.get(1, TimeUnit.SECONDS);
                assertTrue(secondEntered.await(1, TimeUnit.SECONDS));
            }
            finally
            {
                executor.shutdownNow();
            }
        }
    }
    @Test
    void configurationReplacementWaitsForRunningOperationBeforeClosingAdapter() throws Exception
    {
        RecordingFactory factory = new RecordingFactory();
        try (DeviceAdapterRegistry registry = new DeviceAdapterRegistry(List.of(factory)))
        {
            registry.synchronize(config("127.0.0.1", true));
            StubAdapter firstAdapter = factory.adapters.get(0);
            CountDownLatch operationEntered = new CountDownLatch(1);
            CountDownLatch releaseOperation = new CountDownLatch(1);
            CountDownLatch replacementStarted = new CountDownLatch(1);
            ExecutorService executor = Executors.newFixedThreadPool(2);
            try
            {
                Future<?> operation = executor.submit(() -> registry.execute("lab-bts", adapter -> {
                    operationEntered.countDown();
                    await(releaseOperation);
                    return null;
                }));
                assertTrue(operationEntered.await(1, TimeUnit.SECONDS));
                Future<?> replacement = executor.submit(() -> {
                    replacementStarted.countDown();
                    registry.synchronize(config("127.0.0.2", true));
                });
                assertTrue(replacementStarted.await(1, TimeUnit.SECONDS));
                assertFalse(replacement.isDone());
                assertFalse(firstAdapter.closed.get());
                releaseOperation.countDown();
                operation.get(1, TimeUnit.SECONDS);
                replacement.get(1, TimeUnit.SECONDS);
                assertTrue(firstAdapter.closed.get());
            }
            finally
            {
                executor.shutdownNow();
            }
        }
    }
    private static void await(CountDownLatch latch)
    {
        try
        {
            if (!latch.await(1, TimeUnit.SECONDS)) throw new AssertionError("等待适配器测试信号超时");
        }
        catch (InterruptedException exception)
        {
            Thread.currentThread().interrupt();
            throw new AssertionError("等待适配器测试信号被中断", exception);
        }
    }