Удаленный запуск дампа данных выполнения jacoco с помощью агента Jacoco - PullRequest
4 голосов
/ 01 марта 2020

Я использовал официальный пример сервера Socket , чтобы запустить сервер Socket для подключения к моему jacocoagent.jar. Я запускаю свой целевой jar следующим образом:

java -javaagent:jacocoagent.jar=dumponexit=false,output=tcpclient,address=localhost,port=6300 -jar demo-0.0.1-SNAPSHOT.jar

Я изменил код сервера, чтобы добавить метод для захвата дампа. Ниже приведен полный код:

public class JacocoSocketServer {
    private static final String DESTFILE = "jacoco-server.exec";
    private static final String ADDRESS = "localhost";
    private static final int PORT = 6300;

    private static final Logger LOGGER = Logger.getLogger(JacocoSocketServer.class.getName());
    /**
     * Start the server as a standalone program.
     *
     * @param args
     * @throws IOException
     */
    public static void main(final String[] args) throws IOException {

        LOGGER.log(Level.INFO, "Output file is " + new File(DESTFILE).getAbsolutePath());

        final RemoteControlWriter fileWriter = new RemoteControlWriter(new FileOutputStream(DESTFILE));

        LOGGER.log(Level.INFO, "Starting TCP server on: " + ADDRESS + ":" + PORT);

        final ServerSocket server = new ServerSocket(PORT, 0, InetAddress.getByName(ADDRESS));
        final List<Handler> listHandler = new ArrayList<>();

        Runnable runDumpTimer = () -> {
            while (true) {
                Iterator<Handler> it = listHandler.iterator();
                while (it.hasNext()) {
                    Handler handler = it.next();
                    boolean toRemove = false;
                    String id = handler.getId();
                    try {
                        if (!handler.isAlive()) {
                            LOGGER.log(Level.INFO, String.format("Socket closed, removing handler: %s", id));
                            toRemove = true;
                        } else {
                            handler.captureDump(true, true);
                        }
                    } catch (IOException e) {
                        LOGGER.log(Level.INFO, "Socket error: " + e.getMessage() + ", removing handler: " + id);
                        toRemove = true;
                    } finally {
                        if (toRemove) {
                            it.remove();
                        }
                    }
                }
            }
        };
        Thread threadDumpTimer = new Thread(runDumpTimer, "threadDumpTimer");
        threadDumpTimer.start();
        while (true) {
            Socket socket = server.accept();
            System.out.println("Remote connection detected, openning socket on local port: "
                    + socket.getLocalPort());
            final Handler handler = new Handler(socket, fileWriter);
            listHandler.add(handler);
            new Thread(handler).start();
        }
    }
    private static class Handler
            implements
            Runnable,
            ISessionInfoVisitor,
            IExecutionDataVisitor {
        private final Socket socket;
        private final RemoteControlReader reader;
        private final RemoteControlWriter fileWriter;
        private final RemoteControlWriter remoteWriter;
        private String id;
        public String getId() {
            return id;
        }
        Handler(final Socket socket, final RemoteControlWriter fileWriter) throws IOException {
            this.socket = socket;
            this.fileWriter = fileWriter;
            // Just send a valid header:
            remoteWriter = new RemoteControlWriter(socket.getOutputStream());
            reader = new RemoteControlReader(socket.getInputStream());
            reader.setSessionInfoVisitor(this);
            reader.setExecutionDataVisitor(this);
        }
        public void run() {
            try {
                while (reader.read()) {
                }
                socket.close();
                synchronized (fileWriter) {
                    fileWriter.flush();
                }
            } catch (final IOException e) {
                e.printStackTrace();
            }
        }

        public void visitSessionInfo(final SessionInfo info) {
            id = info.getId();
            LOGGER.log(Level.INFO, String.format("Retrieving execution Data for session: %s", info.getId()));
            synchronized (fileWriter) {
                fileWriter.visitSessionInfo(info);
            }
        }
        public void visitClassExecution(final ExecutionData data) {
            synchronized (fileWriter) {
                fileWriter.visitClassExecution(data);
            }
        }
        void captureDump(boolean dump, boolean reset) throws IOException {
            remoteWriter.visitDumpCommand(dump, reset);
        }
        boolean isAlive() {
            return socket != null
                    && socket.isConnected();
        }
    }
}

Приведенный выше код будет бесконечно продолжать записывать дампы в указанный файл, что, очевидно, не является ожидаемым результатом.

Как только я запускаю сервер, Затем я запускаю целевой jar, и я выполню несколько функциональных тестовых случаев на jar. После завершения этих тестовых случаев я хочу запустить дамп данных выполнения и сбросить хранилище, чтобы в следующий раз, когда я запустил дамп, в нем были только данные о соответствующем сеансе.

PS: я использовал для запуска сервер периодически принимает дампы через определенные промежутки времени (отсюда и некоторые имена переменных), но это больше не нужно.

PPS: я прочитал следующие вопросы, у всех из которых были схожие требования к моим , но я не смог найти способ удаленного сброса данных по команде:

https://groups.google.com/forum/#! msg / jacoco / MUTIM5yS6ZQ / KSA5Og4xBgAJ

https://sourceforge.net/p/eclemma/discussion/614870/thread/083acdaa/

https://groups.google.com/forum/#! Topic / jacoco / QAmXUZjviPk

https://groups.google.com/forum/#! Msg / jacoco / V7Bmz5r0P24 / PdCC5apIoqgJ

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...