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

ВступлениеПодготовка к запускуАрхитектура платформы 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

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

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

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

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

  1. Платформа Testo установлена.
  2. Установлен менеджер виртуальных машин virt-manager.
  3. Имеется установочный образ Ubuntu server 16.04 с расположением /opt/iso/ubuntu_server.iso. Местоположение и название установочного файла может быть другим, в этом случае нужно будет соответствующим образом поправить параметр ISO_DIR, передаваемый через командную строку во время запуска тестов.
  4. Имеется образ с гостевыми дополнениями Testo в одной папке с установочным образом Ubuntu.
  5. (Рекомендовано) Настроена подсветка синтаксиса Testo-lang в Sublime Text 3.
  6. (Рекомендовано) Проделаны шаги из четвертой части.

Вступление

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

user$ sudo testo run ~/testo/hello_world.testo --stop_on_fail --param ISO_DIR /opt/iso
UP-TO-DATE TESTS:
ubuntu_installation
guest_additions_installation
guest_additions_demo
PROCESSED TOTAL 3 TESTS IN 0h:0m:0s
UP-TO-DATE: 3
RUN SUCCESSFULLY: 0
FAILED: 0
user$

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

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

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

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

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

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

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

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

param guest_additions_pkg "*.deb"
test guest_additions_installation: ubuntu_installation {
    my_ubuntu {
        plug dvd "${ISO_DIR}/testo-guest-additions.iso"

        type "sudo su"; press Enter;
        #Обратите внимание, обращаться к параметрам можно в любом участке строки
        wait "password for ${login}"; type "${password}"; press Enter
        wait "root@${hostname}"

        type "mount /dev/cdrom /media"; press Enter
        wait "mounting read-only"; type "dpkg -i /media/${guest_additions_pkg}"; press Enter;
        wait "Setting up testo-guest-additions"
        type "umount /media"; press Enter;
        #Дадим немного времени для команды umount
        sleep 2s
        unplug dvd
    }
}

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

user$ sudo testo run ~/testo/hello_world.testo --stop_on_fail --param ISO_DIR /opt/iso
UP-TO-DATE TESTS:
ubuntu_installation
guest_additions_installation
guest_additions_demo
PROCESSED TOTAL 3 TESTS IN 0h:0m:0s
UP-TO-DATE: 3
RUN SUCCESSFULLY: 0
FAILED: 0
user$

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

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

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

param guest_additions_pkg "testo-guest-additions.deb"
test guest_additions_installation: ubuntu_installation {
    my_ubuntu {
        ...
    }
}

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

user$ sudo testo run ~/testo/hello_world.testo --stop_on_fail --param ISO_DIR /opt/iso --assume_yes
UP-TO-DATE TESTS:
ubuntu_installation
TESTS TO RUN:
guest_additions_installation
guest_additions_demo
[ 33%] Preparing the environment for test guest_additions_installation
[ 33%] Restoring snapshot ubuntu_installation for virtual machine my_ubuntu
[ 33%] Running test guest_additions_installation
[ 33%] Plugging dvd /opt/iso/testo-guest-additions.iso into virtual machine my_ubuntu
[ 33%] Typing "sudo su" with interval 30ms in virtual machine my_ubuntu
[ 33%] Pressing key ENTER on virtual machine my_ubuntu
[ 33%] Waiting password for my-ubuntu-login for 1m with interval 1s in virtual machine my_ubuntu
[ 33%] Typing "1111" with interval 30ms in virtual machine my_ubuntu
[ 33%] Pressing key ENTER on virtual machine my_ubuntu
[ 33%] Waiting root@my-ubuntu for 1m with interval 1s in virtual machine my_ubuntu
[ 33%] Typing "mount /dev/cdrom /media" with interval 30ms in virtual machine my_ubuntu
[ 33%] Pressing key ENTER on virtual machine my_ubuntu
[ 33%] Waiting mounting read-only for 1m with interval 1s in virtual machine my_ubuntu
[ 33%] Typing "dpkg -i /media/testo-guest-additions.deb" with interval 30ms in virtual machine my_ubuntu
[ 33%] Pressing key ENTER on virtual machine my_ubuntu
[ 33%] Waiting Setting up testo-guest-additions for 1m with interval 1s in virtual machine my_ubuntu
[ 33%] Typing "umount /media" with interval 30ms in virtual machine my_ubuntu
[ 33%] Pressing key ENTER on virtual machine my_ubuntu
[ 33%] Sleeping in virtual machine my_ubuntu for 2s
[ 33%] Unplugging dvd from virtual machine my_ubuntu
[ 33%] Taking snapshot guest_additions_installation for virtual machine my_ubuntu
[ 67%] Test guest_additions_installation PASSED in 0h:0m:17s
[ 67%] Preparing the environment for test guest_additions_demo
[ 67%] Running test guest_additions_demo
[ 67%] Executing bash command in virtual machine my_ubuntu with timeout 10m
+ echo Modified Hello world
Modified Hello world
+ echo from bash
from bash
[ 67%] Executing python3 command in virtual machine my_ubuntu with timeout 10m
Hello from python3!
[ 67%] Taking snapshot guest_additions_demo for virtual machine my_ubuntu
[100%] Test guest_additions_demo PASSED in 0h:0m:3s
PROCESSED TOTAL 3 TESTS IN 0h:0m:21s
UP-TO-DATE: 1
RUN SUCCESSFULLY: 2
FAILED: 0
user$

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

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

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

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

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

test guest_additions_demo: guest_additions_installation {
    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"
    }
}
user$ echo "This should be copied inside my_ubuntu" > ~/testo/testing_copyto.txt
user$ sudo testo run ~/testo/hello_world.testo --stop_on_fail --param ISO_DIR /opt/iso --assume_yes
UP-TO-DATE TESTS:
ubuntu_installation
guest_additions_installation
TESTS TO RUN:
guest_additions_demo
[ 67%] Preparing the environment for test guest_additions_demo
[ 67%] Restoring snapshot guest_additions_installation for virtual machine my_ubuntu
[ 67%] Running test guest_additions_demo
[ 67%] Executing bash command in virtual machine my_ubuntu with timeout 10m
+ echo Modified Hello world
Modified Hello world
+ echo from bash
from bash
[ 67%] Executing python3 command in virtual machine my_ubuntu with timeout 10m
Hello from python3!
[ 67%] Copying ./testing_copyto.txt to virtual machine my_ubuntu to destination /tmp/testing_copyto.txt with timeout 10m
[ 67%] Executing bash command in virtual machine my_ubuntu with timeout 10m
+ cat /tmp/testing_copyto.txt
This should be copied inside my_ubuntu
[ 67%] Taking snapshot guest_additions_demo for virtual machine my_ubuntu
[100%] Test guest_additions_demo PASSED in 0h:0m:5s
PROCESSED TOTAL 3 TESTS IN 0h:0m:5s
UP-TO-DATE: 2
RUN SUCCESSFULLY: 1
FAILED: 0
user$

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

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

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

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

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

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

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

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

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

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

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

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

user$ sudo testo run ~/testo/hello_world.testo --stop_on_fail --param ISO_DIR /opt/iso --invalidate \*guest_additions*
UP-TO-DATE TESTS:
ubuntu_installation
TESTS TO RUN:
guest_additions_installation
guest_additions_demo
[ 33%] Preparing the environment for test guest_additions_installation
[ 33%] Restoring snapshot ubuntu_installation for virtual machine my_ubuntu
[ 33%] Running test guest_additions_installation
[ 33%] Plugging dvd /opt/iso/testo-guest-additions.iso into virtual machine my_ubuntu
[ 33%] Typing "sudo su" with interval 30ms in virtual machine my_ubuntu
[ 33%] Pressing key ENTER on virtual machine my_ubuntu
[ 33%] Waiting password for my-ubuntu-login for 1m with interval 1s in virtual machine my_ubuntu
[ 33%] Typing "1111" with interval 30ms in virtual machine my_ubuntu
[ 33%] Pressing key ENTER on virtual machine my_ubuntu
[ 33%] Waiting root@my-ubuntu for 1m with interval 1s in virtual machine my_ubuntu
[ 33%] Typing "mount /dev/cdrom /media" with interval 30ms in virtual machine my_ubuntu
[ 33%] Pressing key ENTER on virtual machine my_ubuntu
[ 33%] Waiting mounting read-only for 1m with interval 1s in virtual machine my_ubuntu
[ 33%] Typing "dpkg -i /media/testo-guest-additions*" with interval 30ms in virtual machine my_ubuntu
[ 33%] Pressing key ENTER on virtual machine my_ubuntu
[ 33%] Waiting Setting up testo-guest-additions for 1m with interval 1s in virtual machine my_ubuntu
[ 33%] Typing "umount /media" with interval 30ms in virtual machine my_ubuntu
[ 33%] Pressing key ENTER on virtual machine my_ubuntu
[ 33%] Sleeping in virtual machine my_ubuntu for 2s
[ 33%] Unplugging dvd from virtual machine my_ubuntu
[ 33%] Taking snapshot guest_additions_installation for virtual machine my_ubuntu
[ 67%] Test guest_additions_installation PASSED in 0h:0m:17s
[ 67%] Preparing the environment for test guest_additions_demo
[ 67%] Running test guest_additions_demo
[ 67%] Executing bash command in virtual machine my_ubuntu with timeout 10m
+ echo Modified Hello world
Modified Hello world
+ echo from bash
from bash
[ 67%] Executing python3 command in virtual machine my_ubuntu with timeout 10m
Hello from python3!
[ 67%] Copying ./testing_copyto.txt to virtual machine my_ubuntu to destination /tmp/testing_copyto.txt with timeout 10m
[ 67%] Executing bash command in virtual machine my_ubuntu with timeout 10m
+ cat /tmp/testing_copyto.txt
This should be copied inside my_ubuntu
[ 67%] Taking snapshot guest_additions_demo for virtual machine my_ubuntu
[100%] Test guest_additions_demo PASSED in 0h:0m:4s
PROCESSED TOTAL 3 TESTS IN 0h:0m:21s
UP-TO-DATE: 1
RUN SUCCESSFULLY: 2
FAILED: 0
user$

Итоги

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

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