Jenkins + Play 1.2.4: проблемы с файлами блокировки cobertura/отчет

У нас есть приложение Play 1.2.4, и мы получили Jenkins (на Ubuntu) для приложения. У нас проблемы с Cobertura.

После запуска тестов (успешно) время от времени мы получаем следующую ошибку:

---------------------------------------
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at net.sourceforge.cobertura.util.FileLocker.lock(FileLocker.java:124)
        at play.modules.cobertura.CoberturaPlugin$CoberturaPluginShutdownThread.run(Unknown Source)
Caused by: java.nio.channels.OverlappingFileLockException
        at sun.nio.ch.FileChannelImpl$SharedFileLockTable.checkList(FileChannelImpl.java:1166)
        at sun.nio.ch.FileChannelImpl$SharedFileLockTable.add(FileChannelImpl.java:1068)
        at sun.nio.ch.FileChannelImpl.lock(FileChannelImpl.java:824)
        at java.nio.channels.FileChannel.lock(FileChannel.java:860)
        ... 6 more
---------------------------------------
Unable to get lock on /var/lib/jenkins/jobs/project/workspace/cobertura.ser.lock: null
This is known to happen on Linux kernel 2.6.20.
Make sure cobertura.jar is in the root classpath of the jvm 
process running the instrumented code.  If the instrumented code 
is running in a web server, this means cobertura.jar should be in 
the web server lib directory.
Don't put multiple copies of cobertura.jar in different WEB-INF/lib directories.
Only one classloader should load cobertura.  It should be the root classloader.
---------------------------------------
lock file could not be deleted

Это не похоже на "разрыв сборки", но дальше по сборке мы получаем следующее (что приводит к сбою отчетов в cobertura)

Publishing Cobertura coverage report...
No coverage results were found using the pattern 'test-result/code-coverage/coverage.xml' relative to '/var/lib/jenkins/jobs/project/workspace'.  Did you enter a pattern relative to the correct directory?  Did you generate the XML report(s) for Cobertura?
Build step 'Publish Cobertura Coverage Report' changed build result to FAILURE

Выполнение последующей сборки вручную обычно проходит.

В соответствии с покрытие нулевого кода с cobertura 1.9.2, но тесты работают, я попытался установить -Dcobertura.use.java.nio = false после автоматического тестирования игры -command.

Поскольку эта ошибка происходила только время от времени, я не совсем уверен, помогло ли это. Но после этого у нас возникла проблема с зависанием игры:

  ...
  Executing /opt/play-1.2.4/play auto-test "/var/lib/jenkins/jobs/project/workspace"  -Dcobertura.use.java.nio=false
  [workspace] $ /opt/play-1.2.4/play auto-test "/var/lib/jenkins/jobs/project/workspace" -Dcobertura.use.java.nio=false
  <build stuck here for a couple of days>

Поскольку ничто не было полностью детерминированным, немного сложно сказать о причинах здесь. (Кажется, это происходит после одного или двух сборок после перезапуска jenkins/сервера)

В настоящее время я рассматриваю возможность отключения Cobertura в нашем проекте, но если у кого-то есть другие идеи, это было бы здорово =)

Ответ 1

Очевидно, что это связано с проблемами блокировки JVM либо в вашей реализации JVM, либо, точнее, в том, как вы развертываете JAR-модуль cobertura.

Jenkins может генерировать много потоков JVM, и если cobetura находится на вашем глобальном пути класса, возможно, что происходят какие-то странные столкновения.

Я предполагаю, в конечном счете, что это должно быть связано с незначительной ошибкой в ​​cobertura (если сложная блокировка файла corbertura не решает еще одну более важную проблему).

Согласно исходному коду для Cobertura FileLock (cobertura/src/main/java/net/sourceforge/cobertura/util/FileLocker.java), есть несколько проблем, связанных с множественной загрузкой JVM в банку Cobertura.

Чтобы решить, убедитесь, что есть только одна копия и одно приложение, запускающее и использующее Corbetura.

Причина, по которой ваша реализация VM исправила это, скорее всего, заключается в том, что вы уменьшили количество изменчивости в способе загрузки cobetrura. Возможно, вы перезагружаете свою виртуальную машину с более высокой частотой, чем ваш сервер jenkins.

В наших сборниках jenkins corbertura мы просто используем плагин maven, и, похоже, он работает нормально без проблем (но опять же, мы не используем java 1.7, и не используем Play).

Ответ 2

Это немного беспокоило нас (игра 1.2.4/Дженкинс). Существует некоторая проблема из-за перекрывающихся последовательностей между плагином jenkins cobertura (публикация отчета) и модулем cobertura для платформы. Я считаю, что это чисто случайное совпадение и, следовательно, прерывистое. У нас есть следующая работа по поводу отсутствия лучшего разрешения.

Убрано сообщение jenkins cobertura публикует действие из основной задачи сборки. Мы создали новую работу jenkins, которая настраивается с публикацией отчета о покрытии сообщения cobertura. В новом задании у нас есть действие оболочки, чтобы скопировать файл coverage.xml из основного рабочего пространства сборки в рабочее пространство нового задания для отчета о покрытии cobertura для публикации. Копия (по понятным причинам) делается для того, чтобы избежать использования как cobertura, так и jenkins cobertura в той же работе.

Это не лучший, но рад видеть отчет/графики покрытия: -)

Ответ 3

Фокус в том, чтобы использовать один файл данных (cobertura.ser) для каждого модуля, чтобы избежать блокировок из параллельных задач.

С ant:

<cobertura-instrument todir="${build.dir}" datafile="cobertura.ser.${modulename}">
    ...

В конце слияние многих файлов cobertura в один файл cobertura:

<target name="merge-coverage">
    <cobertura-merge datafile="cobertura.ser">
        <fileset dir="${build.dir}">
            <include name="cobertura.ser.*" />
        </fileset>
    </cobertura-merge>
</target>

Ответ 4

-Dcobertura.use.java.nio = false предыдущий, кажется, требует изменения true, чтобы иметь возможность использовать блокировку файлов, как объяснялось ваше сообщение об ошибке.

Кроме того, где-то в приложении, вероятно, потребуется добавить полный путь к папке для cobertura.

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

Ответ 5

Вы установили

%test.play.tmp=none

в вашем файле application.conf?