К сожалению любая разработка, даже если она ведётся просто по фану, рано или поздно сталкивается с необходимостью формализовать процессы и подходы. С этой проблемой столкнулись и мы. Сравнение производительности уже трёх прототипов вылилось в проблемы, громадные полотна обсуждений, споров, попыток унифицировать тесты и конфигурации стендов. А где унификация тестов, там и их автоматизация. Скорость доступа к файлам по сети. Подход - подрубаем одно или несколько устройств к NAS по стабильной сети (желательно гигабитный эзернет), и начинаем писать/читать.  Скорость чтения/записи на сами диски. То есть мы убираем сеть и проверяем только диски. CPU. Какие операции нужно производить на CPU?  Строго говоря, проанализировав список различных тестов, мы пришли к выводу, что гонять бенчмарки особого смысла нет. По крайней мере в первое время.Правильнее было бы провести тесты скорости работы целевых сценариев использования NAS и параллельно собирать статистику по загрузке IO, сети и CPU. Ну и провести базовые тесты работы UI у OMV. Условно, дымное тестирование. Так что первый этап задачи - составить список целевых сценариев! Сценарий “хранить свои данные” слишком пространен. Есть несколько подходов к тому, как мы загружаем данные, делаем ли какую-то обработку и как к этим данным обращаемся. Базово, сначала обратимся к тому, как именно мы получаем доступ к файлам на NAS. OMV предлагает следующий набор сервисов: FTP - один из самых очевидных сценариев использования NAS (доступен через использование плагина openmediavault-ftp). NFS - менее очевидный сценарий, но при использовании исключительно внутри локальной сети вполне годится. RSync - сценарий понятный и нужный, но не очень ясно, какие требования нужно предъявлять к его производительности. Решили оставить на второй этап. SMB/CIFS - отличное решение для большинства пользователей. Конечно добавляем в список на тестирование. SSH - работать с файлами с помощью SCP или WinSCP не так удобно, но зато конфигурация требуется минимальная. Добавляем в список тестов. Для первого этапа тестирования хватить. На второй этап мы перенесли RSync. Помимо этого напрашивается применение в виде бекапера для флешек. За основу попробуем взять плагин “openmediavault-usbbackup 6.0.2-1”. Нужно уважить истинных параноиков и проверить средства шифрования файлов. В набор плагинов OMV входит “openmediavault-luksencryption 6.0”, интегрирующий утилиту LUKS, который мы и решили взять для наших тестов. Тестирование прямой скорости чтения/записи интересует нас для сравнения различных вариантов архитектуры устройства и для упрощения диагностики проблем. Для этих целей мы планируем использовать утилиту fio.  Ну и на сладкое было бы интересно, как установленные сервисы повлияют на возможность производить бекапы и восстанавливаться из них. Для разработки тестов я не стал использовать наши реальные прототипы, а для большей гибкости решил настроить себе локальное тестовое окружение.  Для этого я создал виртуалку в VirtualBox 7.0.6 (не стал делать это в Докере, так как не очень отдавал себе отчёт, как получится в нём настроить сеть и диски). Поставил образ openmediavault версии 6.0.24-1 (Shaitan) с официального сайта. К виртуалке с OMV примонтировал 3 диска: один на 50 Гигов, на котором у меня живёт основная система, и 2 диска по 10 Гигов, которые объединил RAID1.  Кроме этого создал пользователя vkovalev и несколько директорий. На хосте у меня стоит Windows 11, а выполнять тесты мы будем на линукс. Так что нам понадобится ещё одна виртуалка. В качестве ОС я выбрал Debian. Для организации сети я решил использовать Nat Network в Virtual Box. Такой подход даёт доступ с виртуалок в интернет (а мне это нужно для установки пакетов), и при этом обе виртуалки всегда находятся в рамках одной изолированной подсети и доступны друг другу. Они не светят порты наружу, и я спокойно могу работать из аэропортов, кофеен, вокзалов, отелей через открытые сети, и не бояться, что кто то будет пытаться напакостить. Да, некоторые сервисы хочется выставить наружу, но это решается пробросом портов на хостовый интерфейс. Для начала мне достаточно иметь доступ к веб морде OMV и ssh у обоих машин. Здесь 192.168.56.1 - это виртуальный интерфейс на хосте, который также не виден извне. FTP сервер настраивал через интерфейс OMV. Никаких специфичных конфигов, просто поставил флажок Enable, сохранил настройки и ребутнулся - FTP сервер запущен. В этом можно убедиться, взглянув на дашборд: Далее нужно расшарить директории в FTP и выдать права тестовому пользователю на хотя бы на одну директорию. Директории в FTP мы добавляем через Services->FTP->Shares: Права доступа можно настроить через User Management->Users->Shared folder privileges: После чего сделать простой тест с debian-виртуалки: Странно, но директории Music, которую я определённо добавлял, нигде нету. Ну да с этим разберёмся чуть позже. Кажется нужно будет курить мануалы и спецификации FTP ещё не один вечер. Под капотом у OMV бежит proftpd, а значит с информацией в интернете проблем не будет. Ну, тут всё ещё проще. Протокол не новый, простой как дверь и через OMV в конфиге предлагает одинокую галочку Enable, которую мы и выставили: после чего пошли шарить директории в Services->NFS->Shares и… почувствовали в первый раз на себе смысл фразы “блеск и нищета опенсорса”: Как пробелы прокрались в путь имени - загадка. Тем не менее удалить их не сложно: После чего всё удалось расшарить директории без проблем: Вот только дашборт показывал, что сервер не поднялся. Получить вменяемых логов из диагностики для nfs-server мне не удалось, ребут не помог - пришлось идти в консоль: Ну, собственно, проблема ясна. OMV от чего то создал дублирующую запись в конфиге nfs, но в GUI её не отобразил: Поломанный конфиг выглядел так: После нехитрого фикса: и ребута сервис поднялся: и я без проблем смог примонтировать директорию на тестовой виртуалке: Проблему с пробелом мы смогли воспроизвести, а вот проблему с поломанным конфигом для NFS воспроизвести так и не вышло. В любом случае сходим на форум OMV и попробуем разобраться. Следующий по порядку пункт - это SMB-CIFS. Главным преимуществом этого сценария является удобство и гибкость. Расшаренные директории появятся во вкладке “Сеть” в Проводнике у пользователей Windows. К тому же протокол позволяет гибко настроить права доступа разным пользователям, которые опять же подхватываются компьютерами на базе Windows без лишних телодвижений (в теории). Но так как на нашем тестовом хосте стоит debian, некоторое количество лишних телодвижений совершить придётся. На стороне OMV включаем сервис: и добавляем тестовую директорию в список расшаренных с максимальным доступом и минимальными конфигурациями: кроме того нужно убедиться, что у пользователя есть доступ к выбранной директории: и что сервис запустился (снова на дашборде): Ставим smbclient и проверяем подключение: SSH у нас и так включен. Сложностей никаких не было. Стоит отметить, что если пользователь создавался через интерфейс OMV, ему будет запрещено подключаться по ssh по-умолчанию. Требуется явно добавить пользователя в группу ssh: после чего можно работать с файлами через ssh. В первый этап тестирования мы включили максимально упрощённый набор сценариев, которые, по факту, представляют собой обмен файлами между NAS и другим устройством по сети. И мы хотим не столько убедиться в том, что этот обмен вообще работает, сколько собрать статистику по производительности.То есть нас интересует, насколько быстро будут выполняться операции пользователя. А значит нужно составить список интересующих нас операций. Начнём с простого: Скачать небольшой файл с NAS; Загрузить небольшой файл на NAS; Время выполнения каждой операции запоминается. В идеале тест нужно повторить хотя бы сотню раз для получения надёжных статистических данных. К чуть более “сложным” сценариям имеет смысл отнести загрузку/скачивание файлов побольше и нескольких файлов за раз. В качестве инструментов для реализации этих тестов решили взять родимый и хорошо знакомый pytest. Причин несколько: Инструмент знакомый и понятный (честно говоря, тут можно остановить перечисление, но для имитации профессионального подхода мы сочинили ещё несколько причин); Легко реализовать многократное выполнение тестов через модуль pytest-repeat; Легко реализовать централизованный сбор статистики с помощью фикстур. Причём как сбор информации о выполнении конкретного сценария, так и сбор статистики по загрузке CPU, сети, памяти, а также получение логов с непосредственно NAS. Обожаю фикстуры! Pytest будет перехватывать все вылетающие исключения, и нам не понадобится разруливать их вручную; Плагины от pytest позволяют выставлять, например, таймауты для тестов. А это крайне полезно для работы с сетью. Обязательно что то будет зависеть, и вылавливание подобных косяков растянется надолго. Но это не заблокирует наши тесты. Ну и не стоит забывать, что мы ставим целью для себя не точнейшее измерение производительности как таковой, а оценку деградации производительности относительно. А значит для нас важнее обеспечить стабильное и неизменное тестовое окружение, и мы можем просто использовать модуль time для измерения времени, не прибегая к тяжёлой артиллерии. Я решил накинуть ещё несколько требований к тестам: Каждый отдельный тест должен быть независимым и самодостаточным. А значит тест на скачивание файла не должен надеяться, что этот файл кто то заботливо положил на NAS. Тесты “прибираются” после себя. Мы собираем статистику централизованно. Более того, в случае, если тестовый прогон прервался, при его следующем запуске статистика из предыдущего запуска сохраниться. Мы должны проверять успешность выполнения операций. Собранную телеметрию с NAS хочется уметь легко сопоставить с выполнением конкретного теста. OMV из коробки собирает статистику по загрузке системы: Все интересующие нас параметры здесь представлены. А значит нужно понять, как OMV собирает эти данные, как их получить нашим тестам и можно ли тюнить для своих нужд. Покопались и выяснили, что статистика собирается сервисом collectd. Собираемые параметры настраиваются через добавление плагинов. Так же обстоят дела и с настройкой выходного формата данных. А значит следует разобраться, какие же плагины включены в OMV:  Из этого списка нас в первую очередь интересует плагин rrdcached. В данном конфиге за сохранение и ротацию статистики отвечает именно он. Из строки запуска демона так же можно узнать, где базы данных хранятся: /var/lib/rrdcached/db/. Выглядит хранилище так: Проще всего будет не копировать rrd файлы, а распечатать их текстом с помощью rrdtool fetch в текстовом формате, а затем перекладывать в нашу sqlite базу (о которой скажу ниже). Причина тут в том, что я плохо знаком с rrd базами и не понимаю, насколько велика вероятность утащить файл в процессе записи и в результате получить поломанную базу в артифактах. А так мы будем использовать стандартные средства для работы с rrd на удалённом хосте, а локально уже переложим только интересующие нас записи в хранилище статистики. Пожалуй даже не обязательно это делать для каждого теста отдельно. Мы будем дампить в конце тестового прогона. Выглядит дамп примерно так: Что удобно - можно взять только данные за интересующий нас период, легко сопоставить с конкретным тестом, так как у каждой записи есть таймстемп. Вопрос - как всю эту информацию мы будем использовать? На самом деле хотелось бы оставить данное решение на попозже, а пока все собранные данные просто хранить. Для этих целей я бы обошёлся без экзотики и сложил собранные данные в sqlite базу. Так как один тестовый сервер мы можем использовать для проверки разных конфигураций NAS, в этой базе следует хранить не только статистику и результаты тестов, но и версию конфига. Накидал вот такую схему базы данных: Всё предельно просто. OperationTime - это время выполнения операции копирования/скачивания определённого файла по определённому протоколу. NAS_Configuration - это описание сетапа в свободной форме, без попыток загнать всё в один формат. Остальные таблицы - показатели нагрузки системы на определённый момент времени. Запись в OperationTime будем делать после каждого прогнанного теста. Статистику будем заносить в конце прогона, и пусть лежит там до лучших времён. Конфигурацию устройства же будем записывать в конфигурационном файле, о чём ниже. Ну и напоследок нужно решить проблему гибкой конфигурации. Лучше сделать это сразу и не хардкодить значения. Как хранить конфиги - дело вкуса. Рассуждения на эту тему можно почитать, например, тут. А мы без лишних объяснений просто будем использовать встроенный в python модуль configparser и ini файл. Для удобства сделаем версию конфига “по-умолчанию”, чтобы тесты хоть как-то запускались без лишних танцев с бубном. В статье постарался описать, как именно мы обычно размышляем, планируем и проектируем тестовые системы. Сначала нужно исследовать объект тестирования, а также выделить сценарии, которые хотелось бы проверять и автоматизировать. Затем выполнить часть операций вручную, и уже после можно начинать проектировать тестовую систему. На мой взгляд важно держать себя в руках и не бояться: Оставить некоторые операции не автоматизированными. Отложить решение сложных проблем на потом. Собирать гигабайты статистики и логов, не углубляясь в оптимизацию. Переписать всё заново, когда позже станет ясно, что тесты спроектированы неправильно. Вооружившись этими принципами мы продолжим разрабатывать нашу тестовую систему в следующих статьях.  QA инженер