Как сравнить вывод рабочего процесса?

Я выполняю сравнительный тест на gem5 средстве моделирования, которое продолжает печатать вывод к терминалу в то время как его выполнение. Я уже сохранил демонстрационное выполнение того же сравнительного теста в текстовом файле.

Таким образом, теперь я хочу сравнить поток вывода, распечатанный с консолью с текстовым файлом предыдущего золотого выполнения. Если существует различие в с выводом по сравнению с текстовым файлом, моделирование должно быть завершено автоматически.

Сравнительный тест берет партию времени для выполнения. Я только интересуюсь первой ошибкой в текущем выполнении, так, чтобы я мог сэкономить время ожидания до выполнения для завершения для сравнения обоих выводов.

5
задан 24 March 2019 в 01:46

3 ответа

Я не мог сопротивляться озадачивающий немного далее при нахождении надлежащего способа сравнить вывод рабочий процесс (в терминале) против "золотого выполнения" файл, поскольку Вы упоминаете его.

, Как поймать вывод рабочего процесса

, я использовал эти script команда с -f опция. Это пишет текущее (текстовое) терминальное содержание в файл; -f опция состоит в том, чтобы обновить выходной файл на каждом событии записи к терминалу. Команда сценария сделана вести учет всего, что происходит в окне терминала.
сценарий ниже периодически импортирует этот вывод.

, Что этот сценарий делает

при выполнении сценария в окне терминала он открывает второе окно терминала, инициируемое с эти script -f команда. В этом (втором) окне терминала необходимо выполнить команду для запуска процесса сравнительного теста. В то время как этот процесс сравнительного теста приводит к своим результатам, эти результаты периодически (каждые 2 секунды) по сравнению с Вашим "золотым выполнением". Если различие произошло, вывод отличия отображен в "основном" (первом) терминале, и сценарий завершается. Строка появляется в формате:

error: ('Solutions: 13.811084', 'Solutions: 13.811084 aap noot mies')

explanation:

error: (<golden_run_result>, <current_differing_output>)

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

, Как использовать

  • Копия сценарий ниже в пустой файл.
    , Когда Вы смотрите на свое "золотое выполнение" файл, первый раздел (прежде чем фактический тест запустится) не важно и мог бы разойтись в различных системах. Поэтому необходимо определить строку, где эффективная выходная мощность начинается. В Вашем случае я установил его на:

    first_line = "**** REAL SIMULATION ****"
    

    изменение это при необходимости.

  • Установленный путь к Вашему "золотому выполнению" файл.
  • Сохраняют сценарий как compare.py, выполняют его командой:

    python3 /path/to/compare.py
    

    '

  • второе окно открывается, говоря Script started, the file is named </path/to/file>
  • в этом втором окне, выполните свое эталонное тестирование, первый отличающийся результат появляется в первом окне:

enter image description here

, Как я протестировал

, я создал небольшую программу, которая печатает строки отредактированной версии Вашего золотого выполнения, один за другим. Я заставил сценарий сравнить его с исходным "золотым выполнением" файл.

сценарий:

#!/usr/bin/env python3

import subprocess
import os
import time

home = os.environ["HOME"]

# files / first_line; edit if necessaary
golden_run = "/home/jacob/Bureaublad/log_example"
first_line = "**** REAL SIMULATION ****"

# don't change anything below
typescript_outputfile = home+"/"+"scriptlog.txt"
# commands
startup_command = "gnome-terminal -x script -f "+typescript_outputfile
clean_textcommand = "col -bp <"+typescript_outputfile+" | less -R"
# remove old outputfile
try:
    os.remove(typescript_outputfile)
except Exception:
    pass
# initiate typescript
subprocess.Popen(["/bin/bash", "-c", startup_command])
time.sleep(1)
# read golden run
with open(golden_run) as src:
    original = src.read()
orig_section = original[original.find(first_line):]
# read last output of current results so far
def get_last():
    read = subprocess.check_output(["/bin/bash", "-c", clean_textcommand]).decode("utf-8")
    if not first_line+"\n" in read:
        return "Waiting for first line"
    else:
        return read[read.find(first_line):]
    with open(typescript_outputfile, "wt") as clear:
        clear.write("\n")
# loop
while True:
    current = get_last()
    if current == "\n":
        pass
    else:
        if not current in orig_section and current != "Waiting for first line":
            orig = orig_section.split("\n")
            breakpoint = current.split("\n")
            diff = [(orig[i], breakpoint[i]) for i in range(len(breakpoint)) \
                    if not orig[i] == breakpoint[i]]
            print("error: "+str(diff[0]))
            break
        else:
            pass
    time.sleep(5)
3
ответ дан 23 November 2019 в 09:13

Можно использовать diff util.

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

У меня нет Вашего выполнения программы, таким образом, я записал это моделирование:

#!/bin/bash
    while read -r line; do
        echo "$line";
        sleep 1;
    done < bad_file

Это читает из другого файла (bad_file), и вывод линию за линией каждую секунду.

Теперь запуская этот скрипт и перенаправление это произвело к log файл.

$ simulate > log &

Также я записал сценарий средства проверки:

#!/bin/bash

helper(){
    echo "This script takes two file pathes as arguments."
    echo "$0 path/to/file1 path/to/file2"
}

validate_input(){
    if [[ $# != 2 ]]; then 
        helper
        exit 1
    fi

    if [[ ! -f "$1" ]]; then
        echo "$1" file is not exist.
        helper
        exit 1
    fi
    if [[ ! -f "$2" ]]; then
        echo "$2" file is not exist.
        helper
        exit 1
    fi
}

diff_files(){
# As input takes two file and check
# difference between files. Only checks
# number of lines you have right now in
# your $2 file, and compare it with exactly
# the same number of lines in $1
    diff -q -a -w <(tail -n+"$ULINES" $1 | head -n "$CURR_LINE") <(tail -n+"$ULINES" $2 | head -n "$CURR_LINE")
}

get_curr_lines(){
# count of lines currenly have minus ULINES
    echo "$[$(cat $1 | wc -l) - $ULINES]"
}

print_diff_lines(){
    diff -a -w --unchanged-line-format="" --new-line-format=":%dn: %L" "$1" "$2" | grep -o ":[0-9]*:" | tr -d ":"
}

ULINES=15 # count of first unused lines. How many first lines to ignore

validate_input "$1" "$2"
CURR_LINE=$(get_curr_lines "$2") # count of lines currenly have minus ULINES

if [[ $CURR_LINE < 0 ]];then
    exit 0
fi

IS_DIFF=$(diff_files "$1" "$2")
if [[ -z "$IS_DIFF" ]];then
    echo "Do nothing if they are the same"
else
    echo "Do something if files already different"
    echo "Line number: " `print_diff_lines "$1" "$2"`
fi

Не забывайте делать это исполняемым файлом chmod +x checker.sh.

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

$ ./checker.sh path_to_golden path_to_log

Это количество количества средства проверки строк Вы имеете прямо сейчас в Вашем log файл, и сравнивает его с точно тем же количеством строк в golden_file.

Вы выполняете средство проверки каждую секунду и выполняетесь, уничтожают команду в случае необходимости

Если Вы хотите Вас, может записать функцию удара для выполнения checker.sh каждую секунду:

$ chk_every() { while true; do ./checker.sh $1 $2; sleep 1; done; }

Часть предыдущего ответа о разности

Можно сравнить их линию за линией как текстовый файл

От man diff

NAME
   diff - compare files line by line

   -a, --text
          treat all files as text

   -q, --brief
          report only when files differ

   -y, --side-by-side
          output in two columns

Если мы сравниваем наши файлы:

$ diff -a <(tail -n+15 file1) <(tail -n+15 file2)

Мы будем видеть этот вывод:

2905c2905
< Solutions: 0.686669
---
> Solutions: 0.686670
2959c2959
< Solutions: 0.279124
---
> Solutions: 0.279125
3030c3030
< Solutions: 0.539016
---
> Solutions: 0.539017
3068c3068
< Solutions: 0.308278
---
> Solutions: 0.308279

Это показывает строку, которая отличается

И вот заключительная команда, я принимающий Вам не хочу проверять сначала 15 строк:

$ diff -y -a <(tail -n+15 file1) <(tail -n+15 file2)

Это покажет Вам всем различия в двух столбцах. Если Вы только хотите знать, там любое использование различия это:

$ diff -q -a <(tail -n+15 file1) <(tail -n+15 file2)

Это ничего не распечатает, если файлы будут тем же

3
ответ дан 23 November 2019 в 09:13

Я понятия не имею, насколько сложный Ваши входные данные всего лишь, Вы могли использовать что-то как awk считать каждую строку, как это входит и сравнивает его с известным значением.

$ for i in 1 2 3 4 5; do echo $i; sleep 1; done | \
  awk '{print "Out:", $0; fflush(); if ($1==2) exit(0)}'
Out: 1
Out: 2

В этом случае я подаю отложенный на время поток чисел и awk работает, пока первая переменная во входе (единственная переменная здесь) не равняется 2, затем выходит и при этом фиксирует поток.

0
ответ дан 23 November 2019 в 09:13

Другие вопросы по тегам:

Похожие вопросы: