ISSN 0236-235X (P)
ISSN 2311-2735 (E)

Journal influence

Higher Attestation Commission (VAK) - К1 quartile
Russian Science Citation Index (RSCI)

Bookmark

Next issue

1
Publication date:
24 December 2024

The article was published in issue no. № 4, 1998
Abstract:
Аннотация:
Authors: () - , () -
Ключевое слово:
Page views: 9173
Print version
Full issue in PDF (1.35Mb)

Font size:       Font:

Факт наличия проблемы отладки и тестирования встраиваемых операционных систем (ОС) общеизвестен [1-6]. Качественное системное тестирование встраиваемой ОС представляет собой сложную и трудоемкую задачу. Разделяют два типа затрат на системное тестирование – затраты на создание тестового комплекта (составление плана и процедуры системного тестирования, разработка и отладка тестов и тестового комплекта в целом) и затраты на исполнение собственно тестов, входящих в состав тестового комплекта (исполнение тестов, регистрация дефектов и составление отчетов о системном тестировании).

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

По опыту работы ИДУ, трудоемкость системного тестирования составляет 29 % от трудоемкости создания ОС в целом, а трудоемкость создания тестовых комплектов составляет до 70 % от трудоемкости системного тестирования [7]. Задача сокращения трудоемкости создания тестовых комплектов является актуальной, ее решение можно осуществить за счет применения специальных языков программирования и специализированных инструментальных средств, а также за счет создания и использования эффективных методов построения тестов.

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

Простейший вариант построения плоских схем базируется на следующих предположениях (сохраняется повторяемость порядка выполнения тестов):

a) для разработки тестов можно использовать только малое количество простых утилит (например менее 10 единиц);

б) каждая базовая функция ОС и каждая тестовая утилита может иметь ограниченное число параметров (например не более двух);

в) тест может включать в себя только операторы вызова сервисов ОС и тестовых утилит;

г) различные задачи, выполняемые тестом, должны иметь различные приоритеты;

д) осуществляется только статическое распределение приоритетов и генерация всех задач, входящих в тест.

В соответствии с приведенными предположениями информация о каждом шаге теста может быть описана при помощи структуры данных (пример 1).

Пример 1

typedef struct Test_Step {

int TaskId;

void (* UtilServ) ( );

StepArg Arg_1;

StepArg Arg_2;

};

Пример 2

union StepArg {

int IntArg;

char* StringArg;

void (* FunArg) ( );

//........

};

В структуре данных поле TaskId содержит номер, идентифицирующий тестовую задачу. Поле UtilServ содержит указатель на функцию, выполняемую на данном шаге теста. Подобная функция либо выполняет некоторые действия с переменными теста (процедура из библиотеки утилит тестирования), либо выполняет вызов базовой функции ОС (процедура вызова сервиса ОС). Поля Arg_1 и Arg_2 используются для представления параметров утилиты тестирования или базовой функции ОС. Поскольку тип аргументов может изменяться от одного оператора к другому, типы аргументов должны задаваться объединением (пример 2).

Здесь следует перечислить все типы аргументов, использующиеся при вызовах утилит тестирования или сервисов ОС.

Организация тестов в виде процессов, управляемых данными

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

TestStep* CurrentStep;.

Тогда i-й экземпляр интерпретатора будет выполнять только те строки плоской схемы, которые относятся к i-й задаче, а все другие строки будут пропускаться, поскольку они выполняются другими экземплярами интерпретатора.

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

Организация теста в виде процессов, управляемых данными, обусловливает важное свойство. В этом случае существует только одна точка, вызывающая в тесте тестируемую ОС – точка, в которой экземпляр интерпретатора вызывает сервисную процедуру или утилиту, указанную в выполняемой строке плоской схемы. Это свойство позволяет существенно упростить разработку измерительных тестов.

Использование плоских схем для разработки тестов и метода управления данными сокращает сроки разработки тестового комплекта и повышает его мобильность (упрощает адаптацию тестового комплекта к различным версиям ОС и платформам, на которые ОС ориентирована), а плата за это невелика. По реальным данным ИДУ размер кода тела интерпретатора плоских схем вместе с библиотекой утилит составляет не более 10 % от размера кода всего тестового комплекта.

Замечание 1. Средства программирования на языке Си не всегда доступны при разработке пользовательских приложений для встроенных ОС реального времени. Часто доступны только средства ассемблера. Если встраиваемая ОС и пользовательские  приложения написаны на ассемблере, то и тестовый комплект целесообразно создавать на ассемблере. Это обстоятельство не является препятствием для использования плоских схем, описания которых могут строиться для языка ассемблера с тем же успехом, что и для языка Си.

Замечание 2. Исходная строчная форма представления теста не пригодна для интерпретации в реальном времени. Для устранения этого недостатка следует применить методику, аналогичную Fort-технологии [4]. Представление теста должно быть преобразовано из строчной формы в форму регулярного массива (стандартных макросредств), в котором его элементы должны содержать номер задачи, указатель на вызываемую процедуру и аргументы этой процедуры.

Построение сценарных тестов

В соответствии с требованием направленности функциональных тестов каждый функциональный тест должен проверять конкретное свойство встраиваемой ОС в определенных условиях. Поэтому полноценный тестовый комплект должен включать набор сценарных тестов, характер которых был бы приближен к характеру реальных  пользовательских приложений, а каждый сценарный тест должен реализовывать последовательность действий, которая использует ОС в режиме, приближенном к реальному режиму функционирования. Для построения сценарных тестов может с успехом использоваться метод плоских схем.

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

Пример 4

TestStep      MessQueue[ ] = {

// --- Очередь из 10 сообщений формируется для задачи Task_2

0,&LoopStart,&cycle_var,10,

1,&CallPutMessage,Task_2,&mes1_ptr,       /* Повтор посылки сообщения */

0,&LoopEnd,&cycle_var,0,

1,&CallTaskEnd,0,0,                        /* Задача Task_1 завершается */

// --- Очередь из 10 сообщений исчерпывается задачей Task_2

      0,&LoopStart,&cycle_var,10,

      2,&CallGetMessage,&mes2_ptr,0,          /* Повтор получения сообщения */

      0,&LoopEnd,&cycle_var,0,

      0,&End_of_scheme,0,0

}

Отрицательное число в поле TaskId соответствует оператору, который должен выполняться обработчиком прерываний. В этом случае абсолютное значение TaskId не указывает на какой-то конкретный обработчик прерываний, а задает уровень вложенности прерываний, на котором выполняется данная строка плоской схемы.

Тест MessTravel разработан для проверки разновидности механизма передачи сообщений, обеспечивающего передачу указателя на сообщение из обработчика прерываний в задачу или из одной задачи в другую. Переменные mes1_ptr, mes2_ptr, mes3_ptr в примере используются как указатели сообщений. Значение константы TEST_MESSAGE является указателем на некоторый инициализированный экземпляр сообщений.

Сценарий пересылок сообщений между задачами состоит из следующих событий:

задача Task_1 пытается получить сообщение и приостанавливается ввиду его отсутствия (Шаг_01);

обработчик прерываний посылает сообщение TEST_MESSAGE задаче Task_3, которая в этот момент еще не готова его принять (Шаг_02, Шаг_03);

задача Task_2 пытается получить сообщение и приостанавливается ввиду его отсутствия (Шаг_04);

задача Task_3 получает сообщение TEST_MESSAGE (посланное ранее обработчиком прерываний) и пересылает его задаче Task_1, приостановленной до момента его поступления (Шаг_05, Шаг_06);

задача Task_1 пересылает сообщение задаче Task_2 и освобождает процессор выполнением сервисной процедуры CallTaskEnd( ) (Шаг_07, Шаг_08);

после завершения задачи Task_1 сообщение, принятое задачей Task_2, сравнивается с TEST_MESSAGE (Шаг_09), сравниваемые указатели сообщений должны быть идентичны).

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

Организация циклов в плоских схемах

Пример 3

TestStep MessTravel [ ] = {

    1,&CallGetMessage,&mes1_ptr,0,                   // Сообщений нет, Task_1 ждет

        2,&ResumeIsr,0,0,                                // Моделирование прерывания

    -1,&CallPutMessage,TASK_3,TEST_MESSAGE,     // Сообщение для Task_3

        2,&CallGetMessage,&mes2_ptr,0,                     // Сообщений нет, Task_2 ждет

            3,&CallGetMessage,&mes3_ptr,0,                 // Task_3 получает сообщение

       3,&CallPutMessage,TASK_1,&mes3_ptr, // Активация задачи Task_1

    1,&CallPutMessage,TASK_2,&mes1_ptr,       // Task_2 готова продолжаться

    1,&CallTaskEnd,0,0,                          // Процессор отдается Task_2

      2,&CheckEqual,&mes2_ptr,TEST_MESSAGE,   // Совпадают ли указатели ?

        2,&End_of_Test,0,0,                            //TEST_MESSAGE

        0,&End_of_scheme,0,0                               //

}

Для построения плоских схем введены вспомогательные элементы. В примере 3 был использован один из таких вспомогательных элементов – разделитель End_of_scheme. Еще одна полезная разновидность вспомогательных элементов – это разделитель циклов. Механизм организации циклов введен в плоские схемы для предотвращения появления длинных схем с повторяющимися фрагментами.

В примере 4 показан тест (MessQueue), который проверяет очередь сообщений. Очередь из 10 сообщений в представленном примере формируется для задачи Task_2, затем задача Task_2 потребляет эти сообщения из очереди одно за другим.

Переменная cycle_var в этом примере используется как переменная цикла. Можно построить вложенные циклы, каждый со своей переменной цикла (например cycle 1_var для внешнего цикла и cycle2_var для внутреннего).

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

Разработка тестов для проверки обработки ошибок

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

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

Пример 5

TestStep      MemReqErr[ ] = {

// ------ Шаги с Step_01 до Step_i исчерпывают ресурс памяти

      1,&GetMemory,30,&mem_ptr,      // Шаг Step_i+1  

      0,&CheckErrData,NO_MEMORY,0,

// ------ Последующие шаги схемы

      0,&End_of_scheme,0,0

}

Задача Task_1 в этом примере требует 30 блоков памяти, что приводит к возникновению ошибки ввиду недостатка ресурса памяти. Техника тестирования базовой функции обработки ошибок аналогична технике моделирования прерываний с помощью утилиты ResumeIsr( ). Ошибка должна вызывать специальный поток действий со входом в тело интерпретатора плоской схемы. Интерпретатор находит вспомогательную строку схемы и выполняет утилиту CheckErrData( ). Предполагается, что ОС передает код ошибки NO_MEMORY в блок обработки ошибок.

Организация автоматизированных сеансов тестирования

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

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

Существуют, по крайней мере, еще две причины, которые приводят к необходимости автоматизации сеансов тестирования встраиваемых ОС – это перспективы модернизации ОС и перспективы их переноса на новые процессоры (микроконтроллеры).

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

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

Измерение покрытия тестовым комплектом программного кода ОС

Общепринятая техника измерения покрытия тестовым комплектом кода тестируемой ОС основывается на непосредственном отслеживании передачи управления в коде ОС. Техника непосредственного отслеживания отвечает требованию невмешательства и поддерживается специальными программно-аппаратными средствами. Аппаратную часть составляет механизм трассировочных прерываний со специально выделенным вектором (TRAP-прерывания). Программную часть составляет обработчик пошаговых прерываний, выполняющий в этом случае роль программы-трассировщика. Выполнение каждой инструкции ОС предваряется прерыванием по TRAP-вектору, что приводит к очередному запуску обработчика пошаговых прерываний.

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

Более подходящая техника измерения покрытия кода тестируемой ОС для встроенных пользовательских приложений базируется на механизме использования кодов запрещенных команд. Для реализации этого механизма также используются специально выделенный вектор прерываний (вектор прерываний по запрещенной команде). Роль программы-трассировщика здесь выполняет обработчик прерываний по запрещенной команде. Процесс измерения покрытия в таком случае состоит из следующих шагов.

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

Шаг 2. Выполняется тест. Поскольку область памяти, отведенная под тело ОС, занята кодами запрещенных команд, при обращении к ОС возникает программное прерывание по запрещенной команде.

Шаг 3. В результате прерывания выполняется программа-трассировщик, которая восстанавливает (из специального массива) необходимый код инструкции ОС и передает управление на восстановленную инструкцию.

Шаг 4. Выполняется восстановленная инструкция ОС.

Шаг 5. Если после выполнения восстановленной инструкции ОС счетчик команд указывает адрес очередной инструкции из тела ОС, то возможен один из двух вариантов: очередная инструкция еще не восстановлена или она уже восстановлена. В первом случае очередной раз срабатывает прерывание по запрещенной команде с восстановлением еще одной инструкции из тела ОС.

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

Техника измерения покрытия по кодам запрещенных команд уменьшает (по сравнению с техникой непосредственного отслеживания) время выполнения теста при измерении покрытия. Каждой инструкции ОС соответствует не более одного обращения к программе-трассировщику. В результате темп выполнения теста в режиме измерения покрытия становится более приближен к темпу выполнения встроенного пользовательского приложения в обычном режиме (без программы-трассировщика).

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

Шаг 1. В теле ОС выбирается единственная инструкция, относительно которой необходимо выяснить, покрывается ли она тестом. Лишь эта инструкция замещается кодом запрещенной команды.

Шаг 2. Тест выполняется с начала до конца. Если по завершении теста инструкция не восстановлена, то она не покрывается данным тестом.

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

В заключение выделим наиболее важные свойства метода плоских схем.

1. Применение метода плоских схем обусловливает повышение эффективности разработки и исполнения тестовых комплектов для встраиваемых ОС.

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

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

4. Плоские схемы пригодны не только для построения функциональных тестов, их применение эффективно также для локальных и глобальных измерений времени, для измерения характеристик реактивности ОС.

5. На основе плоских схем могут быть построены стандартные тестовые комплекты для тестирования базовых функций встраиваемых ОС.

Список литературы

1. Kazara E.J. Real-time debugging with embedded operating systems. Embedded Systems Programming, vol.7, no.8, Aug 1994, pp.24-32.

2. Liband J., Blakeslee T.R. Technique for real-time debugging. Proc. of the Fifth Annual Embedded Systems Conference, Santa Clara, CA, USA, 5-8 Oct 1993 (San Francisco, CA, USA: Miller Freeman, 1993), v.2, pp. 121 - 138.

3. Mandrioli D., Morasca S., Morzenti A. Functional test case generation for real-time systems. Dependable Computing for real-time applications 3, Mondello, Italy, 14-16 Sept 1992 (Wien, Austria: Springer-Verlag 1993), pp.29-61.

4. Schach S. Testing: principles and practice. ACM Computer Survey, vol. 28, no. 1, Mar 1996 pp.277-279.

5. Myers G.J. The art of software testing. NY, USA, John Wiley & Sons, 1979,  177 p.

6. Watkins A. The automatic generation of test data using genetic algorithms. Proc. of the 4th Software Quality Conference, Dundee, UK, 4-5 July 1995 (Dundee, UK: University of Abertay Dundee, 1995),  v.1.

7. Баранов С.Н., Домарацкий А.Н., Ласточкин Н.К., Mорозов В.П. Предотвращение дефектов при создании программных изделий. //Программные продукты и системы. – 1998. – №2. - С.2-6.


Permanent link:
http://swsys.ru/index.php?id=1009&lang=en&page=article
Print version
Full issue in PDF (1.35Mb)
The article was published in issue no. № 4, 1998

Perhaps, you might be interested in the following articles of similar topics: