|
|
|
Как написать тесты на экзекутор ?
|
|||
|---|---|---|---|
|
#18+
Давайте и я изложу своё ИМХО. С интеграционными тестами всё более-менее и так понятно, поднимаем любимую реализацию JMS локально и тестируем. Про многопоточные юнит тесты. Первая и самая унылая категория - напихать многопоточный код ассертами и выполнять его в многопоточной среде, пока что-нибудь не сломается. Дешево, сердито и рассматривать тут нечего - такие тесты долго идут, жрут цпу и ничего не гарантируют. Вторая - тестирование многопоточного кода в одном потоке. Как известно, при выполнении корректно синхронизированного многопоточного кода он разворачивается в так называемый synchronization order, в котором операции идут строго последовательно. Поэтому правильный тест многопоточного кода должен тестировать конкретные synchronization orders. Как этого добиться? Нужно в своем коде избавиться от: - Thread.sleep - wait/notify И вместо этого использовать ScheduledExecutor. Запустить два куска кода параллельно? Загрузите обе таски в екзекутор. Запустить их последовательно? Загрузить в екзекутор первую таску и в конце её загрузить вторую. Нужно сделать паузу? Загрузить таску в SheduledExecutor с нужной задержкой. Нужна более сложная система координации тасок? ConcurrentLinkedQueue<Runnable> в помощь. Всё это нужно писать на скале или хотя бы на джаве с CompletableFuture. Тестировать такой многопоточный код можно, просто сделав мок экзекутора, который будет запускать свои таски в нужном для теста порядке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2017, 18:51 |
|
||
|
Как написать тесты на экзекутор ?
|
|||
|---|---|---|---|
|
#18+
scfВторая - тестирование многопоточного кода в одном потоке. Как известно, при выполнении корректно синхронизированного многопоточного кода он разворачивается в так называемый synchronization order, в котором операции идут строго последовательно. Извините, но это бред. [/quote]И вместо этого использовать ScheduledExecutor. Запустить два куска кода параллельно? Загрузите обе таски в екзекутор. Запустить их последовательно? Загрузить в екзекутор первую таску и в конце её загрузить вторую. Нужно сделать паузу? Загрузить таску в SheduledExecutor с нужной задержкой. Нужна более сложная система координации тасок? ConcurrentLinkedQueue<Runnable> в помощь. Всё это нужно писать на скале или хотя бы на джаве с CompletableFuture. Тестировать такой многопоточный код можно, просто сделав мок экзекутора, который будет запускать свои таски в нужном для теста порядке.[/quote] Во-первых у ScheduledExecutor'а есть вариант однопоточной работы. Во-вторых ничего вы так не поймаете. Вот, к примеру, последняя ошибка в многпоточном коде, которую я поймал, была связана с тем, что после выполнения задачи выполнялось две операции- запись в mongo статуса задачи и удаление из map'ы в памяти. Именно в таком порядке. Иногда (ОЧЕНЬ иногда) другой (из 30, ага) поток успевал схватить свободную задачу и записать в map'у. После этого первый поток удалял задачу из map'ы и второй потом выдавал exception (т.к. в map'е нет его задачи). Тест автор кода поленился написать. Искали ошибку долго (тем более, что на 20 нодах с 30 потоков каждая ошибка случалась раз в сутки). Но тест (который падал) я, когда нашёл ошибку, написать смог А Ваш вариант не найдёт такую ошибку никогда. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2017, 20:33 |
|
||
|
Как написать тесты на экзекутор ?
|
|||
|---|---|---|---|
|
#18+
scfТестировать такой многопоточный код можно, просто сделав мок экзекутора, который будет запускать свои таски в нужном для теста порядке. Отличное предложение, особенно учитывая, что автору именно экзекутор и надо тестировать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2017, 20:47 |
|
||
|
Как написать тесты на экзекутор ?
|
|||
|---|---|---|---|
|
#18+
Andrei TscfТестировать такой многопоточный код можно, просто сделав мок экзекутора, который будет запускать свои таски в нужном для теста порядке. Отличное предложение, особенно учитывая, что автору именно экзекутор и надо тестировать.Тут нужно учитывать один очень важный момент: тема вопроса, в большинстве случаев, редко совпадает с тем, что описано в первом посте. имховое имхо ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2017, 21:35 |
|
||
|
Как написать тесты на экзекутор ?
|
|||
|---|---|---|---|
|
#18+
Alexey TominЗачем? А если тест гоняется на древнем одноядерном процессоре, то он упадёт, что ли? В реальности всё одно потоки ждут обычно- обычно сеть, или диск. В крайнем случае память. Загрузить ядро работой даже на 50%- это большая удача. Не надо ударяться в софистику. стоит вполне конкретная задача топикстартера. Этот тест её решает. Я писал код, в котором, к примеру, можно было выполнять к серверу не более 5 запросов в секунду, при этом ответы были медленные, поэтому работало 30 потоков. Тесты были, первоначальные ошибки поймали, потом код работал сутками и ограничения не превышал. Так что тесты писать можно. Было бы желание. Ну... этот курьез можно рассматривать как исключение их правил. Или как вполне себе нормальный кейс. Ваше приложение не способно работать на одноядерном процессоре. По сабжу я все таки настаиваю на том что тесты надо писать на функционал а не на шаблоны мультизадачности. Отдельная задача - тесты производительности. Но ведь то что написано в топике таковыми не является. Верно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2017, 22:29 |
|
||
|
Как написать тесты на экзекутор ?
|
|||
|---|---|---|---|
|
#18+
Alexey Tomin, Следите за руками: - тестируемый кусок кода добавляет задачи в executor - если в коде нет wait/notify и задачи добавляются для исполнения "сразу", то можно считать, что они должны выполниться одновременно - многопоточный тредпул может их выполнить в любом порядке - тестовый executor должен их выполнить в *конкретном* порядке, указанном в тесте. Если есть тесты на все имеющие смысл порядки, то эти тесты покроют вашу ошибку с кешами. - если некоторая задача после выполнения добавляет в executor другие задачи "сразу", то они участвуют в выборе порядка выполнения на общих основаниях - задачи, добавленные через scheduled executor, рассматриваются после окончания выполнения задач, назначенных на "сейчас" Примерно так. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2017, 22:30 |
|
||
|
Как написать тесты на экзекутор ?
|
|||
|---|---|---|---|
|
#18+
scfСледите за руками: ... Примерно так. Каждый тест должен что-то проверять. unit-тест проверяет конкретный небольшой кусок кода с минимальным объёмом не относящегося к делу кода. Автору нужно проверить, что некоторый executor не выполняет одновременно задачи, которые это явно запрещают. Т.е. нужно взять наш executor (именно тестируемый, а не какой-то другой), затем вложить в него набор задач (простейших, без побочного кода) и проверить, что при возможности исполнить задачи параллельно некоторые не будут работать одновременно. Лучше проверить, что тест работает- для этого надо внедрить ошибку "все последовательно" и "всё параллельно" и увидеть, как тест упал (параллельность такое дело- там да, надо проверять правильность тестов). То, что Вы написали не имеет отношения к делу- executor другой, а задачи те же. Зачем? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2017, 10:16 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=39513691&tid=2122620]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
53ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
46ms |
get tp. blocked users: |
1ms |
| others: | 191ms |
| total: | 332ms |

| 0 / 0 |
