DO - 178C Проект включает среду в качестве примера, показывает, как можно разработать задания сборки Дженкинса, которые используют непрерывное интегрирование (CI), чтобы полностью автоматизировать выполнение действий верификации программного обеспечения. Среда Дженкинса СИ поставляется с готовым к запуску заданием, которое выполняет эти задачи:
Генерирует отчет требования от каждого набора требования в папке DO_02_Requirements.
Генерирует отчет описания разработки системы из каждой модели в папке DO_03_Design.
Проверяет каждую модель по высокоуровневым требованиям к программному обеспечению, которые она реализует.
Проверки каждая модель для соответствия к Стандартам Модели ПО (DO_01_Planning>standards>MB_11_23_SMS>MB_11_23_SMS.docx
).
Анализирует каждую модель для поиска ошибок проектирования.
Генерирует код из каждой модели.
Смотрит сгенерированный код.
Проверки, которым сгенерированный код приспосабливает Стандартам Программного кода (DO_01_Planning>standards>MB_11_08_SCS>MB_11_08_SCS.docx
).
Анализирует сгенерированный код для дефектов программного обеспечения.
Проверяет сгенерированный код по высокоуровневым требованиям к программному обеспечению, которые он реализует.
Генерирует низкоуровневые тесты из каждой модели, когда покрытие высокоуровневых тестов является неполным.
Проверяет сгенерированный код по низкоуровневым требованиям к программному обеспечению, которые не покрыты высокоуровневыми тестами.
Оценивает полное покрытие тестов, которые используются, чтобы проверить сгенерированный код.
Примечание
Если вы хотите запустить CI на нескольких хостах или в облаке, свяжитесь с командой MathWorks CI. Продукты компилятора и продукты преобразования, такие как Embedded Coder®, Simulink® Design Verifier™, и Simulink Code Inspector™, могут потребовать Лицензий на клиентский доступ (CAL).
Для получения дополнительной информации об использовании среды CI Jenkins™ в DO - 178C проект, см.:
Шаблон DO-178C и демонстрационный проект обеспечивают готовый к использованию файл типа "build" задания Дженкинса, DODemoTask.m
, то, что можно использовать, чтобы выполнить действия верификации и валидации в рабочем процессе Модельно-ориентированного проектирования. При помощи файла задания сборки существующего Дженкинса можно легко настроить действия верификации и валидации для проекта.
Создание сделанного на заказ задания требует вас к:
В continuous_integation>job
папка, DODemoTask.m
файл задает задачи задания, которые выполняются сборкой Дженкинса. Вы также используете этот файл, чтобы задать ваш DO - 178C проект и модели, против которых выполняются задачи задания.
Метод setupJob()
, то, которое выполняется вначале и конец каждой задачи задания, выполняет следующие функции:
Функция loadProject()
загружает проект.
Функция getModelNames()
получает путь для модели (моделей), против которой выполняются задачи задания.
Использует дополнительные функции, чтобы выполнить фоновые задачи, такие как регистрация директории задания сборки, задачи и очистки задания и очистки кэша.
methods function setupJob(this) % Equivalent to (TestClassSetup) of matlab.unittest.TestCase. this.JobDir = fileparts(mfilename('fullpath')); this.ReportDir = regexprep(this.JobDir, 'job$', 'reports'); addpath(this.JobDir); this.clearCache(); this.loadProject(); this.getModelNames(); end function setupTask(this) % Equivalent to (TestMethodSetup) of matlab.unittest.TestCase. end function cleanupTask(this) % Equivalent to (TestMethodTeardown) of matlab.unittest.TestCase. end function cleanupJob(this) % Equivalent to (TestClassTeardown) of matlab.unittest.TestCase. this.closeProject(); this.restoreDir(); end end methods % For use by setupJob. function clearCache(this) % The MATLAB Compiler Runtime (MCR) cache can cause errors with % Polyspace in certain installations. Delete the entire cache % to avoid running into this problem. cacheDir = fullfile(tempdir, getenv('username')); if exist(cacheDir, 'dir') rmdir(cacheDir, 's'); end end function loadProject(this) prj = dir(fullfile(this.JobDir, '..', '..', '*.prj')); this.ProjectDir = prj.folder; this.ProjectName = prj.name; this.Project = matlab.project.loadProject(fullfile(this.ProjectDir, this.ProjectName)); end function getModelNames(this) this.ModelNames = find_mdlrefs('Flight_Control'); end end methods % For use by setupTask. end methods % For use by cleanupTask. end methods % For use by cleanupJob. function closeProject(this) this.Project.close(); end function restoreDir(this) cd(this.JobDir); end end
Можно использовать функциональный getModelNames()
получать имена модели или из модели верхнего уровня или из определенных папок проекта.
Получать имена модели из модели верхнего уровня:
Все модели в вашем проекте обработаны как модели, на которые ссылаются, если вы не указываете их как топ-модели. Найдите isTopModel
и введите имя модели верхнего уровня в проекте. Обратите внимание на то, что модель верхнего уровня может быть:
Ссылаемый только одной моделью проекта.
Модель, на которую ссылаются, в тестовой обвязке.
В этом примере, Flight_Control
задан как модель верхнего уровня.
methods function result = isTopModel(this, model) allTopModels = {'Flight_Control'}; result = any(strcmpi(allTopModels, model)); end end
Найдите функциональный getModelNames()
и для find_mdlrefs
, введите имя модели верхнего уровня. Обратите внимание на то, что модель верхнего уровня соответствует, это предусмотрело isTopModel
.
function getModelNames(this) this.ModelNames = find_mdlrefs('Flight_Control'); end
Задание сборки Дженкинса выполняет задачи задания на всех моделях в модели верхнего уровня.
Получать имена модели из папки каталога проекта:
В функциональном getModelNames()
, введите имя папки проекта, где модели сохранены. В этом примере имена модели получены из папки DO_03_Design
.
function getModelNames(this) designDir = fullfile(this.ProjectDir, 'DO_03_Design'); dirList = dir(designDir); end
Задание сборки Дженкинса выполняет задачи задания на всех моделях в папке каталога проекта.
Можно также принять решение исключить извлечение имен модели от определенных папок проекта, а также имен модели, которые содержат определенные символы, такие как ".
"и ".svn
". В этом примере функция не возвращает имена модели в папках common
проекта и
sample_model
или имена модели, которые содержат ".
".
function getModelNames(this) %Ignore common, sample_model, and names that are not a folder such as ".", "..", and ".svn". ignoreDir = arrayfun(@(x) (x.isdir == 0) || strcmpi(x.name, 'sample_model') || strcmpi(x.name, 'common') || contains(x.name, '.'), dirList); dirList = dirList(~ignoreDir); this.ModelNames = arrayfun(@(x) (x.name), dirList, 'UniformOutput', false); end
TaskSequence
свойство DODemoTasks
класс задает задачи задания верификации и валидации и порядок, в котором они выполняются во время задания сборки Дженкинса. Можно добавить и удалить задачи задания и изменить порядок, в котором выполняются задачи задания. Успешное выполнение задачи задания зависит от вашего лицензирования продукта. Ошибка происходит, когда у вас нет лицензии на продукты.
Чтобы настроить Дженкинса создают задание, чтобы выполнить подмножество задач задания:
Найдите TaskSequence
свойство, которое задает задачи задания и порядок, в котором они выполняются во время задания сборки. В этом примере, taskGenReqReport
выполняется сначала и taskMergeCodeCoverage
выполняется в последний раз.
properties TaskSequence = ["taskGenReqReport" "taskGenSDD" "taskVerifyModel2Reqs" "taskCheckModelStds" "taskDetectDesignErrs" "taskGenSrcCode" "taskVerifySrcCode2Model" "taskCheckCodeStds" "taskProveCodeQuality" "taskVerifyObjCode2Reqs" "taskGenLowLevelTests" "taskVerifyObjCode2LowLevelTests" "taskMergeCodeCoverage"]; end
Задачи задания в TaskSequence
свойство соответствует этим методам задачи:
taskGenReqReport()
taskGenSDD()
taskVerifyModel2Reqs()
taskCheckModelStds()
taskDetectDesignErrs()
taskGenSrcCode()
taskVerifySrcCode2Model()
taskCheckCodeStds()
taskProveCodeQuality()
taskVerifyObjCode2Reqs()
taskGenLowLevelTests()
taskVerifyObjCode2LowLevelTests()
taskMergeCodeCoverage()
При желании измените TaskSequence
свойство так, чтобы только эти задачи задания остались:
taskVerifyModel2Reqs
— Симуляция запусков, чтобы проверить модели по требованиям. Требует Simulink Test™ и Simulink Coverage™.
taskGenSrcCode
— Генерирует код из моделей.
taskVerifyObjCode2Reqs
— Программное обеспечение запусков в цикле (SIL) и процессоре в цикле (PIL) симуляции, чтобы проверить сгенерированный код по требованиям.
properties TaskSequence = ["taskVerifyModel2Reqs" "taskGenSrcCode" "taskVerifyObjCode2Reqs"]; end
(Необязательно) Найдите и удалите эти методы задачи:
taskGenReqReport()
taskGenSDD()
taskCheckModelStds()
taskDetectDesignErrs()
taskVerifySrcCode2Model()
taskCheckCodeStds()
taskProveCodeQuality()
taskGenLowLevelTests()
taskVerifyObjCode2LowLevelTests()
taskMergeCodeCoverage()
Рассмотрите остающиеся методы задачи, которые соответствуют задачам, заданным в TaskSequence
свойство. Эти задачи выполняются для каждой модели в проекте.
taskVerifyModel2Reqs ()
Проверяет каждую зарегистрированную модель по высокоуровневым требованиям к программному обеспечению, которые она реализует путем вызова также:
Все модели в образце модели
verifyModel2Reqs('MODEL', [], [], 'CI')
Все модели в модели верхнего уровня
verifyModel2Reqs('MODEL', 'TreatAsTopMdl', [], 'CI')
Результат каждой итерации определяется на основе возвращенных результатов верификации и Simulink Test и отчетов Покрытия модели Simulink Coverage:
Результатом является -1
(СБОЙ), когда тест имеет ошибку или отказ, 0
(WARN), когда тест имеет предупреждение или 1
(ПЕРЕДАЧА).
Полным результатом является -1
(СБОЙ), когда или отчет Simulink Test или отчет Покрытия модели успешно не сгенерированы. В противном случае это - 1
(ПЕРЕДАЧА).
function taskVerifyModel2Reqs(this) % This test point checks if Simulink Test and Model Coverage % Reports generated from models are successfully created by % "verifyModel2Reqs". outcome = 1; exception = ''; counter = 0; try % Test generation of Simulink Test and Model Coverage % Reports (for HLR Simulation Tests) from models in the % project. title = 'HLR Simulation Tests'; headers = {'Model Name', 'Num Pass', 'Num Warn', 'Num Fail', 'Outcome'}; data = {}; for i = 1:numel(this.ModelNames) if exist(fullfile(this.ProjectDir, 'DO_03_Design', this.ModelNames{i}, 'test_cases', 'HLR', [this.ModelNames{i}, '_REQ_Based_Test.mldatx']), 'file') if this.isTopModel(this.ModelNames{i}) res = verifyModel2Reqs(this.ModelNames{i}, 'TreatAsTopMdl', [], 'CI'); else res = verifyModel2Reqs(this.ModelNames{i}, [], [], 'CI'); end data(i,:) = {this.ModelNames{i}, res.NumPass, res.NumWarn, res.NumFail, res.Outcome}; msg = ['One or more high-level tests failed on ', this.ModelNames{i}, '.']; [outcome, exception, counter] = this.verifyOutcome (res.Outcome, msg, exception, outcome, counter); file = fullfile(this.ProjectDir, 'DO_03_Design', this.ModelNames{i}, 'verification_results', 'simulation_results', 'HLR', [this.ModelNames{i}, '_REQ_Based_Test_Report.pdf']); msg = ['Simulation Test Report not created: ', this.ModelNames{i}, '_REQ_Based_Test_Report.pdf.']; [outcome, exception, counter] = this.verifyFile(file, msg, exception, outcome, counter); file = fullfile(this.ProjectDir, 'DO_03_Design', this.ModelNames{i}, 'verification_results', 'model_coverages', 'HLR', [this.ModelNames{i}, '_REQ_Based_Model_Coverage_Report.html']); msg = ['Model Coverage Report not created: ', this.ModelNames{i}, '_REQ_Based_Model_Coverage_Report.html.']; [outcome, exception, counter] = this.verifyFile(file, msg, exception, outcome, counter); else data(i,:) = {this.ModelNames{i}, [], [], [], []}; end end % Capture summary table data. this.TaskResults('taskVerifyModel2Reqs') = {title, headers, data}; % Capture task execution outcome. this.TaskOutcomes('taskVerifyModel2Reqs') = outcome; this.TaskExceptions('taskVerifyModel2Reqs') = exception; catch ME % Throw exception if an error occurs. rethrow(ME); end end
taskGenSrcCode ()
Генерирует код из каждой зарегистрированной модели путем вызова также:
Все модели в образце модели
genSrcCode('MODEL')
Все модели в модели верхнего уровня
genSrcCode('MODEL', 'TreatAsTopMdl')
Результатом каждой итерации является -1
(СБОЙ), если отчет Генерации кода успешно не сгенерирован. В противном случае это - 1
(ПЕРЕДАЧА).
function taskGenSrcCode(this) % This test point checks if Code Generation Reports generated % from models are successfully created by "genSrcCode". outcome = 1; exception = ''; counter = 0; try % Test generation of Code Generation Reports from models in % the project. for i = 1:numel(this.ModelNames) if this.isTopModel(this.ModelNames{i}) genSrcCode(this.ModelNames{i}, 'TreatAsTopMdl'); file = fullfile(this.ProjectDir, 'DO_04_Code', 'specification', [this.ModelNames{i}, '_ert_rtw'], 'html', [this.ModelNames{i}, '_codegen_rpt.html']); else genSrcCode(this.ModelNames{i}); file = fullfile(this.ProjectDir, 'DO_04_Code', 'specification', 'slprj', 'ert', this.ModelNames{i}, 'html', [this.ModelNames{i}, '_codegen_rpt.html']); end msg = ['Code Generation Report not created: ', this.ModelNames{i}, '_codegen_rpt.html.']; [outcome, exception, counter] = this.verifyFile (file, msg, exception, outcome, counter); end % Capture execution outcome. this.TaskOutcomes('taskGenSrcCode') = outcome; this.TaskExceptions('taskGenSrcCode') = exception; catch ME % Throw exception if an error occurs. rethrow(ME); end end
taskVerifyObjCode2Reqs ()
Проверяет код, сгенерированный из каждой зарегистрированной модели против высокоуровневых требований к программному обеспечению, которые это реализует путем вызова также:
Все модели в образце модели
verifyObjCode2Reqs('MODEL', 'SIL', [], [], [], 'CI')
Все модели в модели верхнего уровня
verifyObjCode2Reqs('MODEL', 'SIL', [], 'TreatAsTopMdl', [], 'CI')
Результат каждой итерации определяется на основе возвращенных результатов верификации и Simulink Test и отчетов Покрытия модели Simulink Coverage:
Результатом является -1
(СБОЙ), когда тест имеет ошибку или отказ, 0
(WARN), когда тест имеет предупреждение или 1
(ПЕРЕДАЧА).
Полным результатом является -1
(СБОЙ), когда или отчет Simulink Test или отчет Покрытия модели успешно не сгенерированы. В противном случае это - 1
(ПЕРЕДАЧА).
function taskVerifyObjCode2Reqs(this) % This test point checks if Simulink Test and Code Coverage % Reports generated from models are successfully created by % "verifyObjCode2Reqs". outcome = 1; exception = ''; counter = 0; try % Test generation of Simulink Test and Code Coverage % Reports (for HLR EOC Tests) from models in the project. title = 'HLR SIL Tests'; headers = {'Model Name', 'Num Pass', 'Num Warn', 'Num Fail', 'Outcome'}; data = {}; for i = 1:numel(this.ModelNames) if exist(fullfile(this.ProjectDir, 'DO_03_Design', this.ModelNames{i}, 'test_cases', 'HLR', [this.ModelNames{i}, '_REQ_Based_Test.mldatx']), 'file') if this.isTopModel(this.ModelNames{i}) res = verifyObjCode2Reqs(this.ModelNames{i}, 'SIL', [], 'TreatAsTopMdl', [], 'CI'); else res = verifyObjCode2Reqs(this.ModelNames{i}, 'SIL', [], [], [], 'CI'); end data(i,:) = {this.ModelNames{i}, res.NumPass, res.NumWarn, res.NumFail, res.Outcome}; msg = ['High-level SIL test cases failed on ', this.ModelNames{i}, '.']; [outcome, exception, counter] = this.verifyOutcome (res.Outcome, msg, exception, outcome, counter); file = fullfile(this.ProjectDir, 'DO_04_Code', 'verification_results', 'eoc_test_results', this.ModelNames{i}, 'host', 'HLR', 'instrumented', [this.ModelNames{i}, '_INSTR_SIL_REQ_Based_Test_Report.pdf']); msg = ['EOC Test Report not created: ', this.ModelNames{i}, '_INSTR_SIL_REQ_Based_Test_Report.pdf.']; [outcome, exception, counter] = this.verifyFile (file, msg, exception, outcome, counter); file = fullfile(this.ProjectDir, 'DO_04_Code', 'verification_results', 'code_coverages', this.ModelNames{i}, 'host', 'HLR', [this.ModelNames{i}, '_REQ_Based_Code_Coverage_Report.html']); msg = ['Code Coverage Report not created: ', this.ModelNames{i}, '_REQ_Based_Code_Coverage_Report.html.']; [outcome, exception, counter] = this.verifyFile (file, msg, exception, outcome, counter); else data(i,:) = {this.ModelNames{i}, [], [], [], []}; end end % Capture summary table data. this.TaskResults('taskVerifyObjCode2Reqs') = {title, headers, data}; % Capture execution outcome. this.TaskOutcomes('taskVerifyObjCode2Reqs') = outcome; this.TaskExceptions('taskVerifyObjCode2Reqs') = exception; catch ME % Throw exception if an error occurs. rethrow(ME); end end
Чтобы задать новый метод задачи, рекомендуется, чтобы вы изменили существующую задачу в DODemoTasks.m
достигнуть намеченной цели задания. При создании новой задачи важно что вы:
Обеспечьте уникальное имя для задачи задания. Например:
function taskCustomNamingStandards(this)
Получите результат анализа при помощи:
TaskResults
для результатов каждой итерации задачи.
TaskOutcomes
для полных результатов выполнения, когда применимо.
TaskExceptions
для исключений, когда ошибка происходит.
% Capture summary table data. this.TaskResults('taskCustomNamingStandards') = {title, headers, data}; % Capture execution outcome. this.TaskOutcomes('taskCustomNamingStandards') = outcome; this.TaskExceptions('taskCustomNamingStandards') = exception; catch ME % Throw exception if an error occurs. rethrow(ME); end end
Добавьте новую задачу в TaskSequence
свойство.
properties TaskSequence = ["taskVerifyModel2Reqs" "taskCheckModelStds" "taskGenSrcCode" "taskVerifyObjCode2Reqs" "taskCustomNamingStandards"]; end
После того, как вы настроили файл задания сборки, важно, чтобы вы протестировали задание перед подготовкой проекта сборки в Дженкинсе. В этом примере вы используете runJob()
протестировать сборку.
Протестировать целое задание сборки, в командной строке MATLAB®, введите:
runJob(DODemoTasks)
Чтобы протестировать одну задачу в задании сборки, включайте имя задачи как вход к runJob()
. Например, чтобы протестировать VerifyModel2Reqs()
, в командной строке MATLAB войдите:
runJob(DODemoTasks, 'taskVerifyModel2Reqs')
Результаты задания сборки отображены в окне команды MATLAB. Проверьте, что задание выполняется успешно.
Можно теперь установить Дженкинса, создать Дженкинса, разрабатывают проект, выполняют сборку в Дженкинсе и рассматривают результаты.
Используя среду CI в вашем DO - 178C проект требует Дженкинса. Устанавливать Дженкинса:
В вашем веб-браузере перейдите к www.jenkins.io и запустите загруженного установщика. Следуйте инструкциям по мастеру установки, чтобы завершить установку.
На Инструментальной панели Дженкинса откройте Manage Jenkins> Manage Plugins.
Во вкладке Available выберите и установите эти плагины, характерные для MathWorks:
MATLAB
Итоговое отображение
Дженкинс устанавливает как сервис Windows®. По умолчанию, сервисные запуски Дженкинса с помощью локальной системной учетной записи, которая не имеет разрешения запустить MATLAB. Необходимо перезапустить сервис Дженкинса использовать учетную запись, которая имеет соответствующие привилегии. Начинать сервис Дженкинса с необходимых полномочий:
Откройте Приложение Windows Services и найдите сервис Дженкинса.
Щелкните правой кнопкой по Jenkins и выберите Properties.
В диалоговом окне Jenkins Properties откройте вкладку Log On и выберите This account.
Введите свою информацию об учетной записи пользователя. В зависимости от вашей системной настройки вы, возможно, только должны обеспечить свой пароль.
Нажмите OK. Закройте диалоговое окно Jenkins Properties и перезапустите свой компьютер.
Можно теперь создать Дженкинса, разрабатывают проект.
Когда вы создаете проект Дженкинса, применимые данные должны быть управляемыми при помощи в системе управления конфигурацией. Работа с вашим системным администратором, чтобы интегрировать файлы проекта в вашу систему управления конфигурацией.
Создать проект Дженкинса запустить задание сборки:
Убедитесь, что проект добавляется к вашей системе управления конфигурацией.
Откройте Инструментальную панель Дженкинса и нажмите New Item. В поле Enter an item name обеспечьте имя проекта. В данном примере введите DODemoTasks
.
Выберите Freestyle project и нажмите OK.
(Необязательно) Во вкладке General, предоставьте описание проекта.
Во вкладке Source Code Management выберите Subversion и выполните следующее:
В поле Repository URL обеспечьте местоположение репозитория системы контроля версий. Можно получить эту информацию из DO - 178C проект путем нажатия на вкладку Project и рассмотрения содержимого Source Control. Например, если вы использовали Apache Subversion™ в качестве вашей системы управления конфигурацией, нажмите SVN Details, чтобы получить репозиторий subversion URL.
(Необязательно) В случае необходимости используйте Credentials, чтобы добавить пользователей, которые могут получить доступ к репозиторию subversion.
В поле Local module directory проверяйте, что значением является ".
"– не включают цитаты. Это значение проверяет проект непосредственно в рабочую область Дженкинса.
(Необязательно) Используют опции во вкладке Build Triggers , чтобы задать, как вы хотите запустить задание сборки. В данном примере не выбирайте опцию, потому что вы вручную выполняете задание. Если вы не выбираете одну из опций, необходимо вручную запустить задание сборки.
Откройте вкладку Build Environment и выбор:
Delete workspace before build starts
Add timestamps to the Console Output
Use MATLAB version. Для MATLAB root обеспечьте полный путь папки установки MATLAB. Определить путь, в командной строке MATLAB, введите:
matlabroot()
Откройте вкладку Build и выберите Add build step> Run MATLAB Command. В поле Command, введите:
cd('.\continuous_integration\job'); runJob(DODemoTasks);
Если применимо замените DODemoTasks
с именем вашего Дженкинса создают задание.
Откройте вкладку Post-build Actions и задайте эти действия постсборки:
Чтобы заархивировать артефакты, выберите Add post-build action> Archive the artifacts. В поле Files to archive, введите:
**\*.slxc, continuous_integration\reports\*.xml
Чтобы опубликовать сводные отчеты XML, нажмите Add post-build action> Publish XML Summary Reports. В поле Files to parse, введите:
continuous_integration\reports\*.xml
Нажмите Save. DODemoTasks
проект перечислен на вашей Инструментальной панели Дженкинса. Чтобы внести изменения в проект, выберите проект и нажмите Configure.
Можно теперь выполнить сборку в Дженкинсе и рассмотреть результаты.
Выполнить задание сборки и рассмотреть результаты:
На Инструментальной панели Дженкинса нажмите DODemoTasks
проект.
Нажмите кнопку Build Now, чтобы вручную выполнить задание.
Завершенные задания добавляются к панели Build History. Выберите сборку, которую вы только выполнили, и рассмотрите результаты.
Результаты сохранены в continuous_integration>reports
папка проекта:
Сводные данные сборки — Полные результаты для каждой задачи Дженкинса создают задание.
Сводные данные Результата верификации — Результаты для отдельных итераций задач, перечисленными результатами в табличном формате.
Непрерывное интегрирование для верификации моделей Simulink | Разработайте и интегрируйте программное обеспечение с непрерывным интегрированием | Непрерывный рабочий процесс интегрирования (Simulink Check)