Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Диплом Voldem@r / Оно / ПЗ_release.doc
Скачиваний:
49
Добавлен:
16.04.2013
Размер:
1.6 Mб
Скачать

1.2.9. Проверка отказоустойчивости программы

Среди требований, предъявляемых к программному комплексу в соответствии с пунктами 4.1, 4.2 и 4.4. технического задания на дипломный проект, наиболее важными являются требования, относящиеся к надёжному функционированию комплекса. Именно поэтому основное внимание я уделил рассмотрению выполнения этих требований. Все остальные требования проверялись параллельно (например, нельзя проверить работу комплекса при некорректном формате входного файла, если не реализована функция загрузки файлов и не проверена её работоспособность на файлах «правильного» формата). И, несомненно, центральное место занимает правильная работа комплекса, т.е. получение верных ответов для тех задач, решение которых уже известно. В качестве таких контрольных (тестовых) задач выступали как простые задачи (например, максимум функции одной переменной), так и достаточно специфические, применяющиеся специально для тестирования работы генетических алгоритмов.

Проверка работы комплекса при некорректных входных данных

Этот параграф посвящён методике, применённой для отладки комплекса при нарушенном формате входного файла с описанием модели. Формат такого файла был подробно описан в параграфе 1.2.2.1. В нём же были описаны некоторые защитные механизмы, применённые в программе. Контроль работы комплекса при некорректном формате загружаемого файла был направлен на верификацию правильной реализации всех необходимых проверок.

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

Рис. 1.14 Пример сообщения при некорректном входном файле

Аналогично поведение программы и при значении поля magic структуры SFileHeader, отличном от 20330 (0х4F6A), а также, если в поле productName записана строка, не равная «ГЕНератор».

При проверки версии программы, создавшей файл (т.е. поля version), в случае старшей версии (т.е. в данной реализации 1.0) выводится сообщение «Файл был создан программой более поздней версии».

Эти проверки являются предварительными и не могут обеспечить надёжную защиту приложения от сбоев. Следующий тип проверок основан на проверке правильности длин и смещений в файле, записанных в нём и вычисленных по различным параметрам. Например, значение поля systemInfoOffset всегда должно быть равно размеру структуры SFileHeader, а длина файла – componentInfoOffset + SFileHeader::componentsCount * sizeof(struct SComponentInfo). В случае обнаружения каких-либо несоответствий, пользователю выводится сообщение, «Файл повреждён» и загрузка прекращается. Такая проверка хороша тем, что кроме размера файла проверяет и частично его внутреннюю структуру. Для проверки правильной обработки таких ситуаций осуществлялись попытки загрузить в систему файлы с моделями, сохранёнными этой же программой, но с изменёнными вручную значениями (например, subsystemCount). Программа корректно обработала все тестовые файлы.

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

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

Самым сложным для проверки является проверка связи различных элементов модели между собой. Здесь могут возникнуть несколько ситуаций: объект имеет несколько «родителей» (что невозможно в древовидной структуре), объект-потомок или родитель ещё не создан, либо вовсе отсутствует в системе (напомню, что мы рассматриваем файлы с некорректным форматом), у объекта вообще не оказалось родителей или потомков. Для обработки таких ситуаций, связи между объектами строятся уже после загрузки всех элементов. В процессе загрузки информация о потенциальных связях заносится в таблицу. При этом сразу проверяется ситуация «двух родителей», и в случае её обнаружения загрузка прекращается. Остальные варианты будут проверяться модулем обхода дерева модели.

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

Проверка работы комплекса при неверной модели системы

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

  • одно или несколько выражений для одного или нескольких элементов модели содержат синтаксические ошибки (простейший пример – лишняя или отсутствующая скобка);

  • значение функции какого-либо промежуточного узла (подсистемы) или системы зависят не только от переменных нижнего уровня, непосредственно примыкающего к нему;

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

  • возможные значения компонентов с общим «родителем» на некотором наборе образуют «цикл», т.е. переменная $a зависит от значения переменной $b, которое зависит от значения переменной $a;

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

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

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

  1. проверка синтаксиса выражений;

  2. проверка уникальности имени переменной;

  3. проверка уникальности имён компонентов нижнего уровня;

  4. поиск «недостающих» переменных (т.е. тех, от которых функция подсистемы зависит, но которых нет в системе) и «лишних» (тех, от которых ничего не зависит);

  5. обнаружение циклических зависимостей в значениях компонентов.

Поиск ошибок ведётся до обнаружения первой неустранимой ошибки (т.е. кроме ошибки наличия «лишних» переменных). Пользователь уведомляется о месте, в котором была обнаружена ошибка, и может её устранить. Кроме того, в отладочной версии для проверки работоспособности был предусмотрен вывод сообщения о том, что система корректна. На рис. 1.15 – 1.18 приведены некоторые возможные сообщения, которые комплекс выдаёт пользователю, а на рис 1.19 б) – результат тестирования при ошибке типа «недостающая переменная».

Рис 1.15 Ошибка типа «цикл»

Рис 1.16 Сообщение о корректности

Рис 1.17 Синтаксическая ошибка

Рис 1.18 Повторяющиеся имена

а)

б)

Рис 1.19 Зависимости в модели (а) и результат проверки (б)

Проверка обработки недопустимых арифметических операций

Под некорректными арифметическими операциями понимаются операции деления на 0, извлечение корня чётной степени из отрицательных чисел, вычисление логарифмов из отрицательных чисел. а также операции, результат которых приводит к переполнению. Ошибки или, скорее, неточности, такого рода можно отловить только в процессе поиска оптимального решения, т.к. именно на этом этапе происходит вычисление значений выражений. Конечно, можно попытаться проанализировать все возможные значения выражений (например, явное деление на 0), однако это требует немалых вычислительных затрат и к тому же не может полностью гарантировать отсутствие таких ошибок. Поэтому ошибки отлавливаются на этапе вычисления. Для обнаружения таких ошибок используется механизм исключительных ситуаций и классы исключений, встроенные в Microsoft Visual C++ 6.0, которые можно вызывать вручную. В результате часть кода, отвечающая за вычисление значения выражения на конкретном наборе переменных, помещается в защищённый блок try-catch, и все возникшие исключительные ситуации обрабатываются [8]. Пользователь при этом уведомляется об ошибке, процесс вычислений прекращается, а все ресурсы, занятые для вычисления, освобождаются.

Проверка отказоустойчивости к данному типу ошибок проводилась в три этапа: на первом этапе неправильная запись (например, log(-1)) помещалась в выражение для функции приспособленности системы; на втором функция строилась так, чтобы была в её выражении переменная, значение которой сразу же вызывает исключение (например, $a/$b, где $b имеет единственное значение, равное 0); на третьем этапе только одно из возможных значений какой-либо переменной должно было приводить к возникновению ошибки. Т.к. механизм исключительных ситуаций является давно и хорошо отлаженным, то никаких проблем при обработке ошибок не возникло. Стоит отметить одну особенность: в некоторых случаях при тестировании работы по третьему этапу комплекс отрабатывал корректно, без возникновения ошибок. Это связано с тем, что генетические алгоритмы носят вероятностный характер и поэтому некоторые из возможных значений могут не попасть в рассморение, если сгенерированная начальная популяция уже обеспечивает близкий к оптимуму результат.

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

Рис. 1.20 Пример сообщения при недопустимых арифметических операциях

Соседние файлы в папке Оно