check_sol -- Skrypt do automatycznego sprawdzania poprawności programów, tj. zgodności wyjścia programu z wyjściem wzorcowym dla zadanych plików wejściowych. Główne funkcje:
- kompilacja kodu najbardziej popularnych języków lub użycie skompilowanego programu,
- automatyczne uruchomienie programu dla zbioru lub całego katalogu plików wejściowych (.in) oraz sprawdzenie wyjścia standardowego/błędów,
- porównywanie identycznościowe wyjścia programu z wzorcowym; można jednak dostarczyć własny program
sprawdzający, dowolnie definiujący zgodność wyjść (patrz opcja
--compare), - czytelna, pokolorowana, konfigurowalna postać wyjścia,
- pomiar i limity czasu wykonania oraz zajętej pamięci,
- generowanie samych testów.
- program
time(najczęściej/usr/bin/time, nie mylić z poleceniem powłoki o tejże nazwie), - uprawnienia do wykonania polecenia
ulimit, jeśli używane są limity czasu lub pamięci, - odpowiednie kompilatory w przypadku podania pliku z kodem jako argumentu.
W celu instalacji należy uruchomić załączony skrypt install.sh. Zainstaluje on pliki w podanym
katalogu (domyślnie ~/.check_sol), uzupełni odpowiednio konfigurację oraz wykona testowe
uruchomienie skryptu. Żeby wygodniej korzystać ze skryptu check_sol, można po pierwszej instalacji
umieścić link do niego w katalogu na zmiennej $PATH, na przykład
ln -s <katalog-instalacji>/check_sol /usr/local/bin/check_sol
W trybie normalnym, dla każdego testu wypisywany jest jeden wiersz wyniku:
-
numer i nazwa testu,
-
orientacyjna zużyta pamięć, w kiB, jeśli program działał wystarczająco długo żeby ją zmierzyć,
-
czas wykonanie programu, w sekundach z dokładnością do setnych,
-
wynik testu:
AC-- Answer Correct, odpowiedź zgodna z wzorcową,TL-- Time Limit (Exceeded), przekroczony limit czasu wykonania,ML-- Memory Limit (Exceeded), przekroczony limit zajmowanej pamięci,WA-- Wrong Answer, odpowiedź niezgodna z wzorcową,RE-- Runtime Error, błąd wykonania????-- inny błąd (np. brak plików)
W trzech ostatnich przypadkach w kolejnym wierszu zostanie wypisany opis błędu.
W trybie skróconego wyjścia (patrz --short-output) dla każdego testu wypisywany jest tylko jeden
znak wyniku testu, analogicznie jak wyżej.
Po zakończeniu testowania wyświetlane jest podsumowanie -- liczba wyników różnego rodzaju, maksymalny czas oraz pamięć dla testu.
W pliku check_sol_example.png zobaczyć można przykład wyjścia skryptu dla danych spreparowanych
tak, by pokazywać różne możliwe przypadki.
-s | --solution PLIKkod programu do sprawdzenia. Obsługiwane są pliki.cpp,.cc,.c,.pas, inne należy skompilować ręcznie i użyć opcji-S. Domyślne flagi kompilacji ustawione są w plikucheck_sol.cfg, ale honorowane są ustawienia zmiennych środowiskowych. Podanie tego parametru lub-Sjest konieczne.-S | --sol-exec PLIKskompilowany program do sprawdzenia. Powinien mieć prawa do uruchomienia. Podanie tego parametru lub-sjest konieczne.-i | --input PLIKIpliki wejściowe, dla których ma zostać uruchomiony program. Argumentem może być plik lub lista plików, jak również katalog -- wtedy użyte zostaną wszystkie zawarte w nim pliki.in. Parametr konieczny.-o | --output KATALOGkatalog zawierający plik[i] wyjściowe. Muszą mieć nazwy identyczne z podanymi plikami wejściowymi oraz rozszerzenie.out. Parametr konieczny.-c | --compare PLIKkod programu sprawdzającego zgodność wyjść. Obecnie obsługiwany jest tylko format .cpp (aczkolwiek można dostarczyć inny przez-C). Jeśli nie zostanie podany ten parametr ani-C, zostanie użyta domyślna sprawdzaczka, określona w pliku konfiguracyjnym. Aby dowiedzieć się, jak powinien wyglądać program sprawdzający, przeczytaj komentarz na początkudefault_compare.cppw katalogu instalacyjnym.-C | --comp-exec PLIKskompilowany program sprawdzający zgodność wyjść.-e | --no-errorspowoduje zatrzymanie sprawdzania po pierwszym błędnym teście.-m | --mem-limit LICZBAustawia limit pamięci dla programu naLICZBAkilobajtów (lubLICZBAmegabajtów, jeśliLICZBAma dopisekM). Uwaga: przy zbyt niskich (kilkanaście MiB i mniej) limitach zachowanie programów jest dość nieokreślone.-M | -Mem-limit LICZBAalias do-m <LICZBA>M(limit pamięci w MiB).-t | --time-limit LICZBAustawia limit czasu wykonania jednego testu naLICZBAsekund.-h | --short-outputzamiast jednego wiersza wyniku dla każdego testu wypisuje pojedynczy znak statusu sprawdzenia -- przydatne przy testowaniu na dużej liczbie przykładów.-N | --no-deletenie usuwa plików tymczasowych tworzonych przez program. Przydatne w połączeniu z--no-errors, gdyż te pliki zawierają dane dot. wykonania ostatniego testu.-E | --check-stderrporównuje również standardowe wyjście błędu programów. Zakłada, że wzorcowe wyjścia błędu mają rozszerzenie.erri znajdują się w katalogu z plikami.out.-g | --gen-outszamiast porównywać plikami.outw katalogu podanym w-o, używa zadanego programu do jego wygenerowania. Przy-Egeneruje w tymże katalogu również pliki.err. Uwaga: generowane pliki nadpisują dotychczasowe pliki o tej samej nazwie.-G | --gen-tests PLIKuznaje plik rozwiązania za generator testów, przyjmujący parametry określone w PLIKu konfiguracyjnym. Zobacz sekcję Generowanie testów, opisującą format tych plików. Opcja generowania wyłącza-g, zaś opcje sprawdzenia nie mają znaczenia. Pozostają aktywne limity czasu i pamięci. Uwaga: generowane pliki nadpisują dotychczasowe.
check_sol -s zadanie.cpp -i testy -o testy: najprostsze sprawdzenie kodu zadanie.cpp
na wszystkich plikach .in z katalogu testy.
check_sol -s zadanie.cc -i tests/in -o tests/out -E -t 1 -m 50M -e: skompilowanie pliku
zadanie.cc i uruchomienie go na wszystkich plikach wejściowych z katalogu tests/in, sprawdzając
zgodność z wyjściami .out i .err w katalogu tests/out, z limitem 1 sekundy i 50MiB pamięci
oraz przerwaniem testowania po pierwszym błędzie.
check_sol -S generator -G gen_cfg -i testy: wygenerowanie testów do katalogu testy programem
generator na podstawie konfiguracji w pliku gen_cfg.
Można zamiast pliku rozwiązania podać program generujący testy. Program taki powinien przyjmować odpowiednią liczbę parametrów z wiersza poleceń. Liczba generowanych testów, ich nazwa i parametry powinny zostać zapisane w skrypcie konfiguracyjnym. Skrypt powinien ustawiać następujące zmienne:
TEST_NAME-- prefiks nazwy generowanych plików wejściowych (nazwa01.in, ...)TEST_COUNT-- liczba testów do wygenerowaniaPARAMS-- lista parametrów generatoraparam1, ...-- tablice o nazwach wskazywanych przez$PARAMS, zawierające przynajmniej$TEST_COUNTelementów- zamiast
PARAMSoraz osobnych tablic można zdefiniować tablicęGEN_TESTS_PARAMS, zawierającą przynajmniej$TEST_COUNTelementów -- wierszy gotowych do przekazania generatorowi.
Zaleca się, żeby jako jeden z parametrów podać ziarno generatora liczb losowych. Można wtedy, zamiast wysyłać duże pliki wejściowe, wysłać sam generator i plik konfiguracyjny, uzyskując na dowolnej maszynie taki sam zestaw testów. Ponadto, skrypt może zawierać inne komendy, zostaną one wykonane przed rozpoczęciem generowania (nawet wymienione zmienne mogą być generowane, a nie podane wprost). Parametry powinny mieć unikalne nazwy.
Przykładowy prosty generator, wypisujący n losowych liczb z zakresu [0..n):
sscanf(argv[1], "%d", &seed);
sscanf(argv[2], "%d", &n);
srand(seed);
for (int i=0; i<n; ++i) printf("%d ", rand()%n);Przykładowy plik konfiguracyjny powyższego generatora:
TEST_NAME=nazwa
TEST_COUNT=5
PARAMS="P_SEED P_ILE"
P_SEED=(123 950 1209 5392 2)
P_ILE=(4 10 50 123 500000)Konfiguracja tych samych testów, przy użyciu drugiego sposobu definiowania zmiennych:
TEST_NAME=nazwa
TEST_COUNT=5
GEN_TESTS_PARAMS=("123 4" "950 10" "1209 50" "5392 123" "2 500000")W katalogu instalacyjnym znajduje się plik check_sol.cfg. Można w nim ustawić domyślne
kompilatory i ich flagi oraz nieco skonfigurować kolory i szerokość wyjścia skryptu.
- W czasie sprawdzeń nie powinien być uruchomiony inny program o nazwie identycznej ze sprawdzanym
(gdzie programy kompilowane przez
check_solmają rozszerzenie.e. - Program (z zamierzenia) nie jest całkowicie idiotoodporny -- argumenty wykonania powinny być użyte zgodnie z przeznaczeniem.
- Przerwanie programu sygnałem SIGABRT wykrywane jest jako przekroczenie limitu pamięci, gdzie prawdziwa jest implikacja w lewo -- ten sygnał pojawia się też np. po niezłapanym wyjątku...
Znalezione błędy, jak i sugestie nowych funkcjonalności można zgłaszać przez GitHub:
https://github.com/quezak/check_sol/issues
- v2.11: opcja
-M - v2.10: nowa domyślna sprawdzaczka
- v2.05: możliwość podania wyszczególnionych plików wejściowych
- v2.03: wczytywanie ze środowiska ustawień kompilacji
- v2.0: generowanie testów, selftest przy instalacji
- v1.9: opcja generowania plików wyjściowych
- v1.8-1.89: liczne poprawki związane z czytelnością i stylem kodu.
- v1.7.1: dodane sprawdzenie wyjścia błędów.
- v1.7: wersja z momentu założenia repozytorium. Liczyła kilka ładnych lat i nie była napisana zbyt ładnie.
