Scalacheck, модульное тестирование многопроцессорных алгоритмов
В настоящее время я разрабатываю инфраструктуру Scala для многопроцессорных параллельных алгоритмов с использованием MPJ-Express (то есть вариант Java MPI).
MPJ-Express, и в основном все MPI-варианты, работают, запуская множество процессов с помощью одной и той же программы. Поскольку я не контролирую процессы во время выполнения (моя программа не порождает процессы), я не могу использовать стандартные модули модульного тестирования по следующим причинам:
Не все процессы будут иметь локальную копию результатов после выполнения (в идеале, результаты должны собираться в произвольном корневом процессе)
Отсутствие контроля над стандартным выпуском. Нелегко получить выход только из одного процесса.
- Отсутствие контроля потока. Все процессы должны проходить один и тот же тест в одно и то же время, чтобы разрешить использование однопрограммных алгоритмов с несколькими данными.
Номер 2 - это, в основном, проблема, поскольку 3 может работать как положено, а 1 можно исправить с помощью дополнительной операции связи. Кто-нибудь имеет практический опыт или знает о лучших стратегиях модульного тестирования для многопроцессорных алгоритмов?
РЕДАКТИРОВАТЬ
Сейчас мне кажется, что мне повезло с использованием следующего кода, использующего scalacheck:
package it.vigtig.thesis.collection.scalacheck
import java.io.OutputStream
import java.io.PrintStream
import org.scalacheck.Prop.forAll
import org.scalacheck.Properties
import it.vigtig.thesis.env.DistEnv.globalRank
import it.vigtig.thesis.env.DistEnv.parallelize
object CollectionCheck {
def main(args: Array[String]) {
parallelize(args) {
if (globalRank > 0) {
Console.setOut(new PrintStream(new OutputStream() {
def write(b: Int) { //nop
}
}))
}
ST.main(Array())
}
}
}
object ST extends Properties("String") {
// def println(a: String*) = gprintln(a)
property("startsWith") = forAll((a: String, b: String) => (a + b).startsWith(a))
property("concatenate") = forAll((a: String, b: String) =>
(a + b).length > a.length && (a + b).length > b.length)
property("substring") = forAll((a: String, b: String, c: String) =>
(a + b + c).substring(a.length, a.length + b.length) == b)
}
Приведенный выше код перенаправляет метод scala-println в операцию nop для всех других процессов, кроме p=0. Я должен иметь возможность запускать наборы тестов с параллельными методами, позволяя только корневому процессу проверять результаты. Выше приведен следующий результат:
MPJ Express (0.38) is started in the multicore configuration
rank-0: 0.212437745 time taken for initialize
+ String.startsWith: OK, passed 100 tests.
! String.concatenate: Falsified after 0 passed tests.
> ARG_0:
> ARG_1:
+ String.substring: OK, passed 100 tests.
1 ответ
github.com/rickynils/scalacheck/issues/37 По-видимому, это было связано с некоторой ошибкой в скалярной проверке. Эта ошибка будет исправлена, но сейчас кажется, что вы можете клонировать репозиторий в этом посте и получить рабочую копию!:)