Общие сведения

ВступлениеПодготовка к запускуАрхитектура платформы TestoПорядок запускаПолитика запуска тестов

Обучающие материалы по Testo для Hyper-V

Часть 1. Самый первый тестЧасть 2. Устанавливаем Ubuntu ServerЧасть 3. Доступ в Интернет из виртуальной машиныЧасть 4. Гостевые дополненияЧасть 5. ПараметрыЧасть 6. КешированиеЧасть 7. Связываем две машины по сетиЧасть 8. ФлешкиЧасть 9. МакросыЧасть 10. Конструкция ifЧасть 11. No snapshotsЧасть 12. Управление мышкойЧасть 13. Импортирование жёстких дисковЧасть 14. JS-селекторыЧасть 15. Циклы

Обучающие материалы по Testo для QEMU

Часть 1. Самый первый тестЧасть 2. Устанавливаем Ubuntu ServerЧасть 3. Гостевые дополненияЧасть 4. ПараметрыЧасть 5. КешированиеЧасть 6. Доступ в Интернет из виртуальной машиныЧасть 7. Связываем две машины по сетиЧасть 8. ФлешкиЧасть 9. МакросыЧасть 10. Конструкция ifЧасть 11. No snapshotsЧасть 12. Управление мышкойЧасть 13. Импортирование жёстких дисковЧасть 14. JS-селекторыЧасть 15. ЦиклыЧасть 16. Макросы с объявлениями

Спецификация языка

Общая структура скриптовых файловБазовые конструкции языкаOбъявление виртуальной машиныОбъявление виртуального флеш-накопителяОбъявление виртуальной сетиПараметрыОбъявление тестовМакросыДействия с виртуальными машинамиДействия с мышкойПоиск изображений на экранеДействия с виртуальными флеш-накопителямиУсловияЦиклыСписок идентификаторов клавиш

Запросы на языке Javascript

Общая концепция построения JS-селекторовВстроенные глобальные функции JavascriptИсключенияКласс TextTensorКласс ImgTensorКласс Point

Часть 6. Кеширование

С чем Вы познакомитесь

В этой части вы познакомитесь с механизмом кеширования в платформе Testo.

Начальные условия

  1. Платформа Testo установлена.
  2. Гипервизор Hyper-V установлен.
  3. Имеется установочный образ Ubuntu server 16.04 с расположением C:\iso\ubuntu_server.iso. Местоположение и название установочного файла может быть другим, в этом случае нужно будет соответствующим образом поправить параметр ISO_DIR, передаваемый через командную строку во время запуска тестов.
  4. Имеется образ с гостевыми дополнениями Testo для Hyper-V в одной папке с установочным образом Ubuntu.
  5. Хост имеет доступ в Интернет.
  6. (Рекомендовано) Настроена подсветка синтаксиса Testo-lang в Sublime Text 3.
  7. (Рекомендовано) Проделаны шаги из пятой части.

Вступление

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

Очевидно, что в таких условиях прогон тестов "с нуля" каждый раз становится неэффективным - ведь подготовка виртуального стенда может занимать по времени гораздо больше времени, чем собственно проведение значимых тестов.

Поэтому в платформе Testo большое внимание уделяется вопросу экономии времени при прогоне тестов в тех случаях, когда это возможно.

Основная идея заключается в следующем: при первом запуске тестов (когда даже виртуальные машины еще не созданы) все эти тесты прогоняются с нуля, от начала до конца - в полном объёме. Каждый успешный тест при этом кешируется. Это означает следующее:

  1. Для всех виртуальных машин и виртуальных флешек создаются физические снепшоты, которые позволяют "запомнить" состояние этих сущностей на момент окончания теста (только если у теста не указан атрибут no_snapshots, который мы рассмотрим позднее);
  2. Для теста создаётся набор метаданных, которые хранятся на диске и позволяют зафиксировать множество различных факторов, которые затем будут помогать при оценке актуальности кеша.

Если тест по какой-то причине "свалился", то кеш для него не создаётся и все тесты, которые от него зависят (тесты-потомки), автоматически помечаются как проваленные.

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

При повторном запуске тестов платформа Testo сначала оценивает актуальность кеша уже прошедших успешных тестов. В этом процессе задействовано много факторов, среди которых основные это:

  1. Целостность самих тестовых сценариев (причем незначимые изменения не учитываются);
  2. Целостность конфигураций виртуальных машин и флешек, участвующих в тесте;
  3. Целостность файлов, которые попадают внутрь виртуальной машины с помощью действия copyto.

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

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

Если просуммировать всё вышесказанное, то получается следующая картина:

  1. Первый раз тесты прогоняются достаточно долго, т.к. выполняются все "подготовительные" тесты: установка ОС, настройка IP-адресов и прочее;
  2. При повторных запусках будут прогоняться только тесты, в которых "что-то изменилось". Т.к. в подготовительных тестах очень редко когда что-то меняется, то они останутся закешированными и повторно прогоняться не будут.

С чего начать?

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

Для примера возьмем набор тестов, которые мы сделали в предыдущей части:

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

В конечном счете вы должны увидеть такой вывод:

C:\Users\Testo> testo run caching.testo --stop_on_fail --param ISO_DIR C:\iso
UP-TO-DATE TESTS:
ubuntu_installation
ubuntu_prepare
ubuntu_install_guest_additions
ubuntu_guest_additions_demo
PROCESSED TOTAL 4 TESTS IN 0h:0m:0s
UP-TO-DATE: 4
RUN SUCCESSFULLY: 0
FAILED: 0
C:\Users\Testo>

Теперь давайте попробуем поэкспериментировать с нашими тестовыми сценариями и посмотрим, что будет происходить с кешем.

Для начала давайте попробуем изменить тест ubuntu_guest_additions_demo и снова выполнить testo:

test ubuntu_guest_additions_demo: ubuntu_install_guest_additions {
    my_ubuntu {
        #Измененный скрипт
        exec bash """
            echo Modified Hello world
            echo from bash
        """
        #Двойные кавычки внутри скриптов необходимо экранировать
        exec python3 "print(\"Hello from python3!\")"
    }
}

Вывод будет следующим:

C:\Users\Testo> testo run caching.testo --stop_on_fail --param ISO_DIR C:\iso
Because of the cache loss, Testo is scheduled to run the following tests:
- ubuntu_guest_additions_demo
Do you confirm running them? [y/N]: y
UP-TO-DATE TESTS:
ubuntu_installation
ubuntu_prepare
ubuntu_install_guest_additions
TESTS TO RUN:
ubuntu_guest_additions_demo
[ 75%] Preparing the environment for test ubuntu_guest_additions_demo
[ 75%] Restoring snapshot ubuntu_install_guest_additions for virtual machine my_ubuntu
[ 75%] Running test ubuntu_guest_additions_demo
[ 75%] Executing bash command in virtual machine my_ubuntu with timeout 10m
+ echo Modified Hello world
Modified Hello world
+ echo from bash
from bash
[ 75%] Executing python3 command in virtual machine my_ubuntu with timeout 10m
Hello from python3!
[ 75%] Taking snapshot ubuntu_guest_additions_demo for virtual machine my_ubuntu
[100%] Test ubuntu_guest_additions_demo PASSED in 0h:0m:5s
PROCESSED TOTAL 4 TESTS IN 0h:0m:5s
UP-TO-DATE: 3
RUN SUCCESSFULLY: 1
FAILED: 0
C:\Users\Testo>

Ожидаемо, изменение тестового сценария привело к потере кеша в этом тесте. При этом можно заметить, что запустился только дочерний тест ubuntu_guest_additions_demo, причем для его проведения состояние виртуальной машины my_ubuntu было восстановлено из снепшота ubuntu_install_guest_additions, который создался ранее во время успешного прогона соответствующего теста.

При этом, добавление пустых строк, отступов и комментариев не влияет на целостность кеша. Попробуйте добавить или убрать несколько комментариев или пустых строк/оступов и убедитесь в этом сами.

Давайте теперь рассмотрим тест ubuntu_install_guest_additions. Давайте в этом тесте попробуем параметризировать строку с установкой deb-пакета

param guest_additions_pkg "*.deb"
test ubuntu_install_guest_additions: ubuntu_prepare {
    my_ubuntu {
        type "mount /dev/cdrom /media"; press Enter
        wait "mounting read-only"
        type "clear && dpkg -i /media/${guest_additions_pkg} && echo Result is $?"; press Enter;
        wait "Result is 0"
        type "clear && umount /media && echo Result is $?"; press Enter;
        wait "Result is 0"
        sleep 2s
        unplug dvd
    }
}

и снова выполним тестовый сценарий. Мы увидим следующий вывод

C:\Users\Testo> testo run caching.testo --stop_on_fail --param ISO_DIR C:\iso
UP-TO-DATE TESTS:
ubuntu_installation
ubuntu_prepare
ubuntu_install_guest_additions
ubuntu_guest_additions_demo
PROCESSED TOTAL 4 TESTS IN 0h:0m:0s
UP-TO-DATE: 4
RUN SUCCESSFULLY: 0
FAILED: 0
C:\Users\Testo>

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

Дело в том, что в платформе Testo при подсчете контрольных сумм комманд в тестах учитываются только итоговые значения всех строк уже после подстановки значений параметров в целевые строки. До применения параметра наше действие выглядело как type "dpkg -i /media/*.deb", и после применения параметра и подсчета итогового значения строки действие будет выглядеть точно так же. Поэтому кеш считается целостным, несмотря на изменение текста самого сценария. Аналогичная ситуация была и в предыдущем уроке.

Однако, давайте попробуем поменять значение параметра:

param guest_additions_pkg "testo-guest-additions.deb"
test ubuntu_install_guest_additions: ubuntu_prepare {
    my_ubuntu {
        ...
    }
}

И попробуем запустить сценарий. Если вы не хотите каждый раз подтверждать своё согласие с тем, что кеш теста был потерян, вы можете использовать аргумент --assume_yes:

C:\Users\Testo> testo run caching.testo --stop_on_fail --param ISO_DIR C:\iso --assume_yes
UP-TO-DATE TESTS:
ubuntu_installation
ubuntu_prepare
TESTS TO RUN:
ubuntu_install_guest_additions
ubuntu_guest_additions_demo
[ 50%] Preparing the environment for test ubuntu_install_guest_additions
[ 50%] Restoring snapshot ubuntu_prepare for virtual machine my_ubuntu
[ 50%] Running test ubuntu_install_guest_additions
[ 50%] Plugging dvd C:/iso/testo-guest-additions-hyperv.iso into virtual machine my_ubuntu
[ 50%] Typing "mount /dev/cdrom /media" with interval 30ms in virtual machine my_ubuntu
[ 50%] Pressing key ENTER in virtual machine my_ubuntu
[ 50%] Waiting "mounting read-only" for 1m with interval 1s in virtual machine my_ubuntu
[ 50%] Typing "clear && dpkg -i /media/testo-guest-additions.deb && echo Result is $?" with interval 30ms in virtual machine my_ubuntu
[ 50%] Pressing key ENTER in virtual machine my_ubuntu
[ 50%] Waiting "Result is 0" for 1m with interval 1s in virtual machine my_ubuntu
[ 50%] Typing "clear && umount /media && echo Result is $?" with interval 30ms in virtual machine my_ubuntu
[ 50%] Pressing key ENTER in virtual machine my_ubuntu
[ 50%] Waiting "Result is 0" for 1m with interval 1s in virtual machine my_ubuntu
[ 50%] Sleeping in virtual machine my_ubuntu for 2s
[ 50%] Unplugging dvd from virtual machine my_ubuntu
[ 50%] Taking snapshot ubuntu_install_guest_additions for virtual machine my_ubuntu
[ 75%] Test ubuntu_install_guest_additions PASSED in 0h:0m:20s
[ 75%] Preparing the environment for test ubuntu_guest_additions_demo
[ 75%] Running test ubuntu_guest_additions_demo
[ 75%] Executing bash command in virtual machine my_ubuntu with timeout 10m
+ echo Modified Hello world
Modified Hello world
+ echo from bash
from bash
[ 75%] Executing python3 command in virtual machine my_ubuntu with timeout 10m
Hello from python3!
[ 75%] Taking snapshot ubuntu_guest_additions_demo for virtual machine my_ubuntu
[100%] Test ubuntu_guest_additions_demo PASSED in 0h:0m:2s
PROCESSED TOTAL 4 TESTS IN 0h:0m:22s
UP-TO-DATE: 2
RUN SUCCESSFULLY: 2
FAILED: 0
C:\Users\Testo>

Очевидно, что наш тест ubuntu_install_guest_additions потерял свой кеш, т.к. значение строки с параметром guest_additions_pkg изменилось. Здесь примечательно то, что вместе с потерей кеша в тесте ubuntu_install_guest_additions автоматически был сброшен кеш производного теста ubuntu_guest_additions_demo, хотя никаких изменений в нем мы не проводили.

Целостность файлов в copyto и plug dvd

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

Допустим, в ходе тестового сценария нам необходимо передать небольшой текстовый файл внутрь виртуальной машины. Давайте создадим такой файл в той же папке, что и наш тестовый сценарий caching.testo.

Сам тестовый сценарий необходимо подкорректировать

test ubuntu_guest_additions_demo: ubuntu_install_guest_additions {
    my_ubuntu {
        #Измененный скрипт
        exec bash """
            echo Modified Hello world
            echo from bash
        """
        #Двойные кавычки внутри скриптов необходимо экранировать
        exec python3 "print(\"Hello from python3!\")"

        copyto ".\\testing_copyto.txt" "/tmp/testing_copyto.txt"
        exec bash "cat /tmp/testing_copyto.txt"
    }
}
C:\Users\Testo> echo "This should be copied inside my_ubuntu" > testing_copyto.txt
C:\Users\Testo> testo run caching.testo --stop_on_fail --param ISO_DIR C:\iso --assume_yes
UP-TO-DATE TESTS:
ubuntu_installation
ubuntu_prepare
ubuntu_install_guest_additions
TESTS TO RUN:
ubuntu_guest_additions_demo
[ 75%] Preparing the environment for test ubuntu_guest_additions_demo
[ 75%] Restoring snapshot ubuntu_install_guest_additions for virtual machine my_ubuntu
[ 75%] Running test ubuntu_guest_additions_demo
[ 75%] Executing bash command in virtual machine my_ubuntu with timeout 10m
+ echo Modified Hello world
Modified Hello world
+ echo from bash
from bash
[ 75%] Executing python3 command in virtual machine my_ubuntu with timeout 10m
Hello from python3!
[ 75%] Copying C:/Users/Testo/testing_copyto.txt to virtual machine my_ubuntu to destination /tmp/testing_copyto.txt with timeout 10m
[ 75%] Executing bash command in virtual machine my_ubuntu with timeout 10m
+ cat /tmp/testing_copyto.txt
[ 75%] Taking snapshot ubuntu_guest_additions_demo for virtual machine my_ubuntu
[100%] Test ubuntu_guest_additions_demo PASSED in 0h:0m:5s
PROCESSED TOTAL 4 TESTS IN 0h:0m:5s
UP-TO-DATE: 3
RUN SUCCESSFULLY: 1
FAILED: 0
C:\Users\Testo>

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

Попробуйте выполнить этот сценарий и убедитесь, что он закешировался.

Далее идёт важный момент. Как уже упоминалось, при рассчитывании кеша тестов во внимание принимается также целостность файлов, которые участвуют в тесте (в том числе в действии copyto). Причём целостность высчитывается по специальному алгоритму:

  1. Если копируемый файл размером меньше одного мегабайта, то высчитывается целостность содержимого этого файла;
  2. Если копируемый файл размером больше или равен одному мегабайту, то высчитывается целостность даты последнего изменения этого файла;
  3. Если копируется папка, то при первые два правила применяются к каждому файлу по отдельности, размер файлов внутри папки не суммируется.

Попробуйте в этом убедиться. Т.к. наш файл testing_copyto.txt меньше одного мегабайта, то к нему применяется первый шаг алгоритма. Попробуйте изменить дату последнего изменения файла testing_copyto.txt и убедитесь, что тест остался закешированным. И при этом изменение содержимого файла тут же приведет к сбросу кеша.

Можете также создать большой файл (больше одного мегабайта) и убедиться, что его целостность высчитывается только на основе даты последнего изменения.

Такое же поведение при подсчете целостности относится к проверке iso-образов в действии plug dvd, а также при загрузке папки на виртуальную флешку. Виртуальные флешки мы рассмотрим позднее

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

Существует возможность настраивать порог размера файлов, для которых подсчёт целостности учитывает содержимое, а не дату последнего изменения. Для этого существует аргумент командной строки --content_cksum_maxsize

Принудительный сброс кеша

Конечно, в платформе Testo предусмотрена возможность принудительно сбросить кеш у теста (или даже группы тестов). Для этого существует аргумент командной строки invalidate, который по своему формату совпадает с --test_spec, и позволяет указывать шаблон имён тех тестов, кеш которых надо сбросить.

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

C:\Users\Testo> testo run caching.testo --stop_on_fail --param ISO_DIR C:\iso --invalidate guest_additions*
UP-TO-DATE TESTS:
ubuntu_installation
ubuntu_prepare
TESTS TO RUN:
ubuntu_install_guest_additions
ubuntu_guest_additions_demo
[ 50%] Preparing the environment for test ubuntu_install_guest_additions
[ 50%] Restoring snapshot ubuntu_prepare for virtual machine my_ubuntu
[ 50%] Running test ubuntu_install_guest_additions
[ 50%] Plugging dvd C:/iso/testo-guest-additions-hyperv.iso into virtual machine my_ubuntu
[ 50%] Typing "mount /dev/cdrom /media" with interval 30ms in virtual machine my_ubuntu
[ 50%] Pressing key ENTER in virtual machine my_ubuntu
[ 50%] Waiting "mounting read-only" for 1m with interval 1s in virtual machine my_ubuntu
[ 50%] Typing "clear && dpkg -i /media/testo-guest-additions.deb && echo Result is $?" with interval 30ms in virtual machine my_ubuntu
[ 50%] Pressing key ENTER in virtual machine my_ubuntu
[ 50%] Waiting "Result is 0" for 1m with interval 1s in virtual machine my_ubuntu
[ 50%] Typing "clear && umount /media && echo Result is $?" with interval 30ms in virtual machine my_ubuntu
[ 50%] Pressing key ENTER in virtual machine my_ubuntu
[ 50%] Waiting "Result is 0" for 1m with interval 1s in virtual machine my_ubuntu
[ 50%] Sleeping in virtual machine my_ubuntu for 2s
[ 50%] Unplugging dvd from virtual machine my_ubuntu
[ 50%] Taking snapshot ubuntu_install_guest_additions for virtual machine my_ubuntu
[ 75%] Test ubuntu_install_guest_additions PASSED in 0h:0m:19s
[ 75%] Preparing the environment for test ubuntu_guest_additions_demo
[ 75%] Running test ubuntu_guest_additions_demo
[ 75%] Executing bash command in virtual machine my_ubuntu with timeout 10m
+ echo Modified Hello world
Modified Hello world
+ echo from bash
from bash
[ 75%] Executing python3 command in virtual machine my_ubuntu with timeout 10m
Hello from python3!
[ 75%] Copying C:/Users/Testo/testing_copyto.txt to virtual machine my_ubuntu to destination /tmp/testing_copyto.txt with timeout 10m
[ 75%] Executing bash command in virtual machine my_ubuntu with timeout 10m
+ cat /tmp/testing_copyto.txt
[ 75%] Taking snapshot ubuntu_guest_additions_demo for virtual machine my_ubuntu
[100%] Test ubuntu_guest_additions_demo PASSED in 0h:0m:2s
PROCESSED TOTAL 4 TESTS IN 0h:0m:22s
UP-TO-DATE: 2
RUN SUCCESSFULLY: 2
FAILED: 0
C:\Users\Testo>

Итоги

Кеширование является важным механизмом платформы Testo и позволяет существенно экономить время на повторных прогонах тестов. Кеширование позволяет вам запускать только те тесты, которые необходимо запустить в связи с какими-то значимыми изменениями.

Итоговый скрипт можно скачать здесь