Авторы: А.В. Чернышова, Р.А. Мазалов
Источник: III Международная научно-практическая конференция Программная инженерия: методы и технологии разработки информационно-вычислительных систем
(ПИИВС-2020). — Донецк: ДонНТУ, 2020.
Чернышова А.В., Мазалов Р.А. Интегрируемый статический анализ для программного проекта с использованием архитектурного стиля REST. В статье рассмотрен подход к статическому анализу программного проекта с использованием архитектурного стиля REST. Представлены требования к сервису анализа для императивных языков программирования и его архитектура. Перспективами развития является добавление возможностей статического анализа для языков программирования с поддержкой других парадигм.
Программное обеспечение можно анализировать с двух перспектив: статической и динамической. Статический анализ программного кода производится без реального выполнения исследуемых программ. Динамический анализ наоборот проводится при помощи выполнения программного кода.
Т.к. статический анализ не требует реального выполнения программы, это позволяет его легко интегрировать с существующим программным проектом. Для интеграции такого типа анализа достаточно только использовать код программного проекта. То есть, весь процесс интеграции сводится только к проблеме получения исходного кода проекта инструментами статического анализа.
В настоящее время существует множество способов хранения исходного кода проекта: веб-сервисы для хостинга программных проектов, частные (закрытые) репозитории, собственный хостинг репозиториев и т.д. Самым популярным среди таких подходов являются веб-сервисы для хостинга проектов. Данные веб-сервисы основаны на разных системах контроля версий, из-за чего они обладают всеми возможностями систем контроля версий и также дополнительными возможностями, уникальными для этих сервисов.
Наличие возможностей СКВ [1] у данных сервисов, позволяет им хранить код проекта удаленно. В связи с популярностью подобных веб-сервисов и наличия у них возможности хранения кода, актуально рассмотреть интегрирование статического анализа с веб-сервисами для хостинга программных проектов.
Для проведения статического анализа по исходному коду, хранящимуся на репозитории веб-сервиса, необходим инструмент, который будет интегрироваться с данным веб-сервисом для получения кода с репозитория. Однако возникает вопрос о том, какой программной системой должен быть данный инструмент: веб-сервис, отдельное (standalone) приложение и т.д. По аналогии с веб-сервисами для хостинга программных проектов и в связи растущей популярностью продолжительной интеграции (CI) [2] и продолжительного развертывания (CD) [3], выбор подхода с веб-сервисом имеет больший смысл. Веб-сервис проще интегрируется с другими инструментами сборки, развертывания и тестирования проекта. Также веб-сервис позволяет сделать систему статического анализа кода кросс-платформенной. Использование веб-сервиса снизит нагрузку на систему, в которую интегригруется серсис для статического анализа кода.
Интеграцию веб-сервиса статического анализа с веб-сервисом хостинга проекта можно выполнить при наличии REST [4] интерфейса у обоих веб-сервисов. Все популярные веб-сервисы для хостинга проекта (например, Github [5], Gitlab [6]) обладают REST API. То есть, веб-сервис статического анализа должен быть спроектирован с использования принципов архитектурного стиля REST.
Помимо выбора архитектуры веб-сервиса статического анализа, необходимо определиться с формами и подходами статического анализа, проводимым данным веб-сервисом.
Существует следующие основные формы статического анализа программного обеспечения:
Разные авторы рассматривают различные метрики для программного обеспечения. Данная работа рассматривает метрики только для императивных языков программирования, но даже для императивных языков есть множество метрик.
Морис Холстед предложил полноценный набор метрик ПО, который отображает характеристики существующей программы. [7] Данные метрики не полагаются на традиционный подсчет строк кода (LOC), а на подсчет количества операндов и операторов. Набор метрик делится на: базовые показатели, различные метрики объема программы, уровня качества, трудоемкости и затрат.
Томас Мак-Кейб описал метрику цикломатической сложности программы. [8] Метрика основана на анализе потока передачи управления от одного оператора к другому. Такой подход позволяет учесть логику программы. Программа представляется в виде управляющего ориентированного графа, такой граф называют графом управления, управляющего потока или управляющим графом программы. Метрика Мак-Кейба является цикломатическим числом графа управления, сумма количества ребер и вершин графа. Для данной метрики существуют модификации, предложенные разными авторами, две самые известные — Майерса и Хансена. [9]
Виктор Базили и Ричард Сэлби рассмотрели различные стратегии тестирования. [10] Работа показывает, что существует широкий диапазон стратегий тестирования. Из-за такого широкого диапазона стратегий тестирования, полезно использовать метрики, которые подсчитывают количество тестовых случаев требуемых для каждой стратегии для заданной программы, например, метрика Мак-Кейба может измерить количество тестовых случаев требуемых для структурного тестирования.
Большинство современных языков поддерживают модульность. Одним из намерений при разбиении программы на модули — предотвратить влияние изменения одного модуля на другой. Для того, чтобы измерить подобную связь Норман Фэнтон предложил классифицировать модули на 6 классов сцепления. [11] В дальнейшем сцепление для программы может быть построен граф модели сцепления. Граф модели сцепления может предоставить хороший метод визуализации сцеплений между модулями.
Обычно модульные программы состоят из модулей с данными, протекающими через них способом называемым информационным потоком. Информационные потоки могут показать сложные взаимодействия и сложное алгоритмическое поведение в программе. Сэлли Гэнри и Дэннис Кафура предложил метрику для модулей, подсчитывающее кол-во таких потоков завершающихся в модуле и происходящих из модуля. [12] Данная метрика позволяет определить влияние модулей на информационный поток программы, и таким образом выявить, что делает изменения и тестирования в программе более сложным.
Помимо возможности вычисления метрик, в сервисе должна присутствовать возможность визуализации метрик. Рассмотрим разные подходы к визуализации, предлагаемые разными авторами.
Диана Сидаркевичуте утверждает, что самыми часто используемыми инструментами визуализации являются просмотрщики кода. [13] Просмотрщики предоставляют фиксированный набор графических представлений ввода программы: графовые структуры, прямые и обратные слайсеры, дайсеры, просмотр “мертвого” кода (недостижимый код).
Но в связи с огромным размером современных программ, использование графовых структур или различного вида просмотра кода не всегда находит свое применение, в процессе визуализации представления могут стать сильно загроможденными.
Янг П. и Манро М. описали визуализацию, основанную на трехмерных геометрических формах, таких как кубы и цилиндры [14]. Их система состоит из двух частей, CallStax и FileVis, которые можно объединить в одну систему визуализации. Есть и другие виды визуализаций с использованием абстрактных структур:
Как уже говорилось в предыдущих разделах, веб-сервис должен обладать REST интерфейсом. Это позволяет интегрировать сервис с другими сервисами, другими утилитами статического анализа кода. Подход с использованием веб-сервиса и с наличием REST API снижает нагрузку на систему, в которую интегрируется сервис для статического анализа кода.
Доступ к проектам, импортированным в систему должен быть аутентифицирован. То есть, в системе должна быть возможность создания аккаунтов для пользователей. Процесс создания аккаунта можно выполнить при помощи REST интерфейса, однако его проще выполнить с использованием графического интерфейса или интерфейса командной строки. Для сервиса лучше всего использовать веб-интерфейс в качестве графического интерфейса, поэтому сервис должен обладать данным видом интерфейса. Также возможно добавление интерфейса командной строки при дальнейшей разработке сервиса.
Веб-интерфейс должен обладать минимальными возможностями для создания и управления аккаунтами, генерации и получения секретных ключей для пользования REST API сервиса. Остальные возможности сервиса могут быть добавлены в интерфейс при дальнейшей разработке.
Сервис должен поддерживать вычисление метрик, перечисленных ранее. Также помимо возможности вычисления метрик, должна присутствовать возможность визуализации метрик с использованием подходов, описанных в предыдущем разделе.
Система спроектирована с использованием архитектуры микросервисов и архитектурного стиля REST. Микросервисы — это большие независимые компоненты приложения, выполняющие определенную функцию. Совместив микросервисы с клиентами (фронт-энд сервиса) и другими промежуточными слоями, получим микросервсиную архитектуру. [15]
Рассмотрим микросервисы, которые присутствуют в системе. Первый микросервис отвечает за вычисление метрик ПО. Второй микросервис отвечает за визуализации ПО и метрик, он взаимодействует с первым микросервисом.
Архитектура спроектирована с использованием паттерна, при котором клиенты общаются с шлюзом, который впоследствии взаимодействует с микросервисами. Данный шлюз является публичным для выполнения запросов, также он отвечает за безопасность запросов, аутентифицирует запросы и отвечает за управление аккаунтами. Микросервисы, в свою очередь, закрыты и с ними может взаимодействовать только шлюз. Также взаимодействия между шлюзом, микросервисами и клиентами происходят через REST API.
На рис. 1 показана общая архитектура системы статического анализа.
При использовании такого подхода решаются следующие проблемы:
Запросы к REST-интерфейсу сервиса можно разделить на 2 типа: чтения и записи. К запросам типа чтения относятся запросы, которые получают информацию о проекте и вычисленных метриках для файлов или проекта в целом. Запросы типа записи могут создавать проекты или изменять их содержимое.
Основная идея микросервиса вычисления метрик проекта заключается в том, что в основном все расчеты производятся при выполнении запросов записи. В дальнейшем клиент просто получает информацию о вычисленных метриках при помощи запросов чтения.
Клиент получает данную информацию, используя представления проекта, файлов, директорий, метрик или визуализаций, к которым можно получить доступ через определенный ресурс. Эти ресурсы, к которым обращаются при запросах, могут быть вложенными друг в друга. В итоге все доступные ресурсы REST интерфейса образуют древовидную структуру. Данная структура показана на рис. 2.
Запросы сервиса обращаются к различным ресурсам, корневым ресурсом для всех запросов по взаимодействию с проектом является URI [16] с именем пользователя владельца проектов. То есть URI следующего вида «/:имя_пользователя».
Запросы сервиса принимают разные параметры, существует 2 способа передачи параметров: параметры запроса или в теле запроса. Параметры, которые передаются в теле запроса, обычно сложно представить в параметрах запроса, например, HTTP [17] ссылка на другой ресурс. Тело запроса описывается в JSON [18] формате, параметры внутри тела представляются в виде ключ-значение (поле-значение) JSON объекта.
Ресурс “/contents” позволяет получить доступ к представлениям файлов и директорий проекта. После получения структуры директорий проекта, можно получать представления метрик проекта (используя ресурс /metrics) или визуализаций проекта (/visualization).
В запросах используются следующие методы HTTP: GET, PUT, POST. Метод POST используется при создании представления или ресурса, например, запрос на создание проекта. При запросе на создание проекта, клиент обращается к ресурсу /:имя_пользователя/:название_проекта с использованием метода POST и передает параметры необходимые для создания проекта. Для получения представлений используется метод GET, клиенту при обращении к ресурсу с использованием данного метода возвращается JSON объект (представление ресурса). В случае если клиенту необходимо только внести изменения в существующий ресурс, то он проделывает тот же протокол действий как и в случае с методом POST, только использует метод PUT.
Корень REST API содержит только ресурс для создания аккаунтов пользователей “/register”, для изменения настроек аккаунта и генерации новых секретных ключей необходимо использовать ресурс “/:имя_пользователя/settings”.
С микросервисами вычисления метрик проекта и визуализации взаимодействует шлюз.
При обращении к шлюзу не все клиенты должны иметь права на выполнение запросов типа записи, только владелец проекта или доверенные клиенты (разработчики, которые могут делать изменения в проекте).
Для того, чтобы разграничить права среди клиентов, запросы типа записи следует аутентифицировать. REST запросы можно подписывать HMAC [19]. Для доверенных клиентов следует сгенерировать секретные ключи, сервис и данные клиенты должны разделять эти ключи. Для данной цели также можно использовать алгоритмы электронно-цифровой подписи, но для того, чтобы аутентифицировать запросы, сервисам потребуется хранить открытые ключи доверенных клиентов, и клиенту потребуется передавать данный ключ сервису. При первом подходе процесс упрощается, и ключ генерирует сразу сервис, поэтому сервис должен обладать возможностями аутентификации запросов с использованием алгоритма HMAC.
Запросы типа записи должны быть аутентифицированы, поэтому в запросе должно быть поле для передачи HMAC запроса. Если запрос не был аутентифицирован, то запрос должен вернуть ответ 403 Forbidden.
Рассмотренный подход к статическому анализу программного проекта делает процесс анализа более гибким. Позволяет сократить нагрузку на систему, в которой выполняется анализ проекта. Применение REST интерфейса при анализе делает сам сервис кросс-платформенным, позволяет интегрировать сервис с различными сервисами-хранилищами кода, другими утилитами сборки, развертывания и тестирования проекта. Таким образом упрощаются и процессы продолжительной интеграции (CI) и продолжительного развертывания (CD). Также у рассмотренного подхода есть еще одно преимущество — нагрузка снижается не только на систему, где выполняется анализ, но и на сам сервис. Т.к. все вычисления производятся только при записи в проект, в остальных случаях происходит только считывание уже вычисленных результатов.
Требования к сервису статического анализа ПО рассмотрены только для императивных языков программирования. Перспективами развития данного подхода статического анализа являются расширение поддержки для языков программирования других парадигм.