Как стать автором
Обновить
148.77
Рейтинг

IBM System i (aka AS/400) — Как мы делали автотесты приложений зеленого экрана

Блог компании Альфа-Банк Тестирование IT-систем *C++ *История IT
Привет! Меня зовут Антон Воробьев, я отвечаю в Альфа-Банке за разработку приложений для централизованной банковской системы.

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



Платформа AS/400 (Application System/400) появилась на свет в 1988 году. Первой ОС для данной платформы является OS/400, позже переименованная в i5/OS и еще позже в IBM i. Не так давно она отметила свое тридцатилетие.

Погружаясь в мир разработки под операционной системой IBM i, понимаешь, что это никакой на самом деле не «legacy» в классическом понимании этого слова. Это другая, совершенно иная среда, которая мало схожа с привычными Windows или Unix-системами. Главная задача этой ОС — быть максимально производительной на аппаратуре, с которой работает, а не быть удобной пользователю.

ИМХО, эта ОС может свести с ума от того, насколько привычные подходы к написанию кода на С++ неэффективны на ней (до десятков раз потери CPU), что некоторые демонстрируемые в учебниках антипаттерны являются best-practice эффективного кода, а исходники с датой написания за 1978 год не просто собираются без проблем, но и работают как было спроектировано! Все это заставляет по-новому взглянуть на современные подходы к разработке ПО.

Введение


Вопрос повышения качества разрабатываемого программного обеспечения волнует умы каждой команды разработки. Не обошел данный момент и одну из наших кредитных команд, чья задача состоит в разработке и развития Back части модуля для автоматизированной банковской системы Misys Equation. Особенность этой АБС в том, что:

  • первые версии АБС работали под предшественником AS/400 – платформой IBM System/38 (появилась в 1978 году) под ОС CPF – «Control Program Facility»;
  • она разрабатывается с 70-х годов двадцатого века, и вы можете встретить код, написанный до вашего рождения (очень много старого кода);
  • особенности работы с АБС обусловлены тесной интеграцией с IBM i, причем из-за колоссальной обратной совместимости последней кажется, что ты работаешь археологом на раскопках Великой пирамиды.



IBM i (логотип)

Разработку приложений для данной АБС (опций АБС) мы ведем в соответствии со стандартом пакета разработчика Misys ITP – Integrator’s Technical Package, в котором регламентируется, что опция должна состоять из интерактивной программы для терминального взаимодействия с конечным пользователем и реализовывать API по установленному интерфейсу для фонового выполнения.

Такие интерактивные программы, разрабатываемые под операционной системой IBM i, исторически называются приложениями зеленого экрана и являются единственным UI, с которым взаимодействует пользователь данной АБС.

Что такое приложение зеленого экрана?


Простой ответ — это приложение, которое выглядит следующим образом:



Или так:



Зачем нужны приложения зеленого экрана?


Исторически единственными интерактивными приложениями, выполняющихся на low и mid-range системах семейства AS/400 и других меинфреймах IBM, и которые позволяли запрашивать какой-либо пользовательский ввод, являются приложения зеленого экрана. Инсталляция, администрирование, конфигурирование и разработка на операционной системе IBM i (и ее предшественниках i5/OS и AS400) велись (а где-то до сих пор ведутся) исключительно с помощью приложений зеленого экрана.

Изображение приложений зеленого экрана имеет два размера – 24x80 и 27x132 символов и 16 возможных цветов. В пределах данных масштабов выполняется большая часть работы разработчиков и пользователей данной операционной системы.

Такие размеры экранов являются результатом эволюции «рабочих станций», которые подключались к прародителям AS400 из low-end и mid-range сегмента бизнес — компьютеров IBM System/32, System/34, System/36 и System/38. Эти рабочие станции назывались терминалами и представляли из себя экран в металлическом корпусе с клавиатурой и дополнительным оборудованием в виде светового пера. Изначально поддерживалось только два цвета экрана – это зеленый и ярко-зеленый, отчего пошло устоявшееся словосочетание «приложение зеленого экрана» (green screen application в англоязычной литературе). В 1970-х годах количество поддерживаемых цветов увеличилось до 16.


5251 Display Station Model 11

Самыми распространенными вариантами терминалов являлись 5251 Display Station Model 1 (960 символов на экране) и Model 11 (1920 символов на экране) с габаритами Ширина/Глубина/Высота равными 530/400/400 мм соответственно и весом в 34 кг. Разрешение экрана Model 1 было 12x80, Model 11 – 24x80. Подключение терминала выполнялось напрямую к хостовой системе.

Также были достаточно распространены терминалы 5251 Display Station Model 2 (960 символов на экране) и Model 12 (1920 символов на экране) с большими габаритами и весом в 45 кг. Их отличает от Model 1 и Model 11 наличие возможности «проброса» upstream-соединения через себя к хостовой машине от более дешевых клиентов в виде терминалов Model 1 (или 11) с настольными принтерами или отдельно напольного принтера. Таким образом, модели 2 и 12 выступали в роли хаба, проксирующего соединение до хоста от устройств, требующих прямого подключения к хостовой машине, и стоили существенно дороже.

Необычным современному обывателю покажутся также терминалы серии 5252 Dual Display Station.


Рекламное изображение из брошюры IBM System/38 Equipment and Programs (5252 Dual Display Station)

Цена одного комплекта терминала с подключаемым к нему принтером могла достигать нескольких тысяч долларов США.

Подключение терминалов выполнялось по твинаксиальному кабелю до хостовой машины с топологией по типу «шина» в полудуплексом режиме со скоростью передачи до 1 Мбит/с. Максимально по твинаксиалу поддерживается подключение до 6 терминалов, причем максимально удаленный от хоста терминал должен располагаться на расстоянии не более 1500 метров.

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

По мере развития Desktop-систем и сетей доступа громоздкие терминалы вытеснялись рабочими станциями, где в качестве средств доступа к хостовой машине использовались различные платы расширения сторонних компаний, поддерживающие непосредственное подключение через твинаксиал. После разработки IBM технологии Token Ring в 1984 году появились программные решения доступа к машине в том числе через данный интерфейс.


Адаптер 5250 на шину ISA (производитель неизвестен)


Blackbox 5250 Adapter Cards (PC470C, PC471C, PC472C, PC473C, PC478C)

Появляются эмуляторы под MS-DOS и MS Windows как от IBM, так и от сторонних производителей, в том числе и OpenSource-реализации (например, tn5250j.sourceforge.net).В середине 90-х годов стек TCP/IP приходит в мир mid-range и low-end бизнес-машин. Для поддержки доступа к хостовым машинам по новому протоколу IBM разрабатывает программные эмуляторы терминалов серий 5250.

С целью создания протокола обмена с хостовой системой, IBM разрабатывает
расширения Telnet-протокола (RFC 854, RFC 855, RFC 856, RFC 860, RFC 885, RFC 1091, RFC 1205, RFC 1572, RFC 2877), в совокупности обозначающиеся как Telnet5250 (TN5250), в которых описывается процесс приема и передачи потоков данных 5250 (5250 data streams) поверх стандартного Telnet-протокола.


Инсталлятор IBM Client Access/400 for Windows 3.1

Что особенного в IBM 5250?


Особенностью терминалов IBM 5250 (и соответственно протокола TN5250) является его блочноориентированность в отличие от привычных *nix-терминалов, которые являются символьноориентированными. Это означает, что потоки данных 5250, которыми хост общается с терминалом, передаются блоками данных, и отдельно стоящий символ в нем без контекста передаваемого блока не имеет смысла.

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


Экран входа на IBM i хостера RZKH.de (pub400.com)

Далее задача эмулятора терминала в том, чтобы интерпретировать блок данных от машины и сформировать пользователю экран ввода, где в разрешенные поля ему предоставляется возможность ввести какую-либо информацию. Также в задачи эмулятора терминала входит реакция на пользовательские действия. Клавиши F1-F24 (F13-F24 имитируются через SHIFT+Fx), Enter, Home, End, PageUp, PageDn и некоторые другие специальные клавиши, отсутствующие на современных клавиатурах, считаются хостовыми клавишами. Это значит, что по нажатию данной клавиши буфер потока с информацией из полей ввода и позицией курсора на экране, предварительно заполненный эмулятором терминала, будет отправлен хосту на обработку.


WIreshark 5250 Data Stream дамп попытки входа в систему на pub400.com

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

Зачем вообще здесь автотестирование


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

Особой болью, с которой столкнулась команда, было практически полное отсутствие на 2017 год средств автотестирования зеленых экранов, кроме проприетарного решения UIPath. Даже сегодня подобных решений не так много, автору известны Automate от HelpSystems и расширение JMeter для BlazeMeter (буду рад информации о других аналогичных продуктах).

Первые исследования по задаче


Штатным эмулятором терминала TN5250, установленного на рабочих местах в банке, является решение IBM Personal Communications for Windows 6.0 (PCOMM 6.0). Коллеги обнаружили, что данный продукт имеет штатные средства автоматизации управления им в виде разнообразного API, а именно:

  1. High-level Language Application Program Interface (HLLAPI);
  2. Enhanced HLLAPI;
  3. Windows HLLAPI;
  4. Host Access Client Library (HACL).

Первые три интерфейса являются наиболее старыми и поддерживаются со времен DOS-а и 16-разрядных версий Windows. Работа по интерфейсу EHLLAPI реализуется через вызов одной единственной функции по следующему прототипу:

long hllapi (LPWORD, LPSTR, LPWORD, LPWORD);

где первый параметр есть указатель на числовой номер выполняемой функции, два остальных – контекстно-зависимые от вызываемой функции ее аргументы, а последний – результат работы функции. То есть, чтобы запросить статус соединения ‘A’ (сессии в эмуляторе нумеруются латинской буквой диапазона от ‘A’ до ‘Z’), необходимо выполнить следующий код (взят из документации IBM):

 #include "hapi_c.h"
    struct HLDQuerySessionStatus QueryData;
    int    Func, Len, Rc;
    long   Rc;
 
    memset(QueryData, 0, sizeof(QueryData)); // Init buffer
    QueryData.qsst_shortname = 'A';          // Session to query
    Func = HA_QUERY_SESSION_STATUS;          // Function number
    Len  = sizeof(QueryData);                // Len of buffer
    Rc   = 0;                                // Unused on input
 
    hllapi(&Func, (char *)&QueryData, &Len, &Rc);  // Call EHLLAPI
    if (Rc != 0) {                            // Check return code
      // ...Error handling
    }


Количество доступных подобным образом функций для вызова — около 60.

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

Интерфейс Host Access Client Library (HACL) показался более дружелюбным для работы, потому что, в отличие от вызова «функции одного имени», предоставлялся вариант объектно-ориентированной иерархии классов, позволяющих полностью имитировать любое пользовательское действие.


Иерархия классов Emulator Class Library из состава HACL (C++)

Имеются реализации HACL для С++, Java, LotusScript и сервера автоматизации COM для Windows (удобно для Visual Basic и .NET).

Первый прототип


Из-за огромной сложности в протоколе потока данных 5250 и крайне скудной информации о его внутреннем устройстве с отсылками на закрытую платную литературу от IBM стало очевидно, что разработка собственного эмулятора — дело крайне нетривиальное и затратное по времени. В связи с этим возникла идея использовать middleware-слой, который позволит управлять эмулятором терминала в рамках минимально требуемого функционала, в частности «ввести в поле значение», «сверить часть экрана с эталоном» или «нажать хостовую клавишу F22».

Коллеги, использовавшие ранее интерфейсы HACL, утверждали (а поиск по StackOverflow подтвердил), что COM-объект имеет проблемы со стабильностью и мог зависать после выполнения определенного количества команд. Помогал только перезапуск процесса сервера автоматизации. Беглый анализ Java-версии показал, что используется Wrapper над интерфейсом C++ через JNI. Поэтому выбор пал на интерфейс С++. Соответствующие заголовочные файлы и .lib файлы оказались в наличии в установочном каталоге самого Personal Communications For Windows.

Первый прототип базировался на Qt5, где была возможность выполнить JavaScript-код через QtScript. В окружении исполняемого скрипта выполнялась регистрация объекта с небольшим количеством методов, позволяющих выполнять команды в эмуляторе терминала так, будто бы их выполняет человек (ввод в поле, нажатие хостовых клавиш, ожидание появления строки на экране). Мы продемонстрировали живое «демо», где скриптовали пользовательский кейс по запуску приложения зеленого экрана из АБС Equation с проверкой реакции приложения на некорректный ввод в поля. Демонстрация показала, что прототип успешен и можно двигаться дальше.

Появление соседа


Одновременно с демонстрацией первого прототипа коллеги из другого отдела собрали связку Ruby + Cucumber + Quick3270 + Ruby module (cheeze/te3270). В предлагаемом варианте используется Ruby-модуль, который взаимодействует с эмулятором терминала Quick3270 от DN-Computing через его специализированные COM-объекты (несовместимы по интерфейсам с HACL). Это было полноценное решение для автотестирования приложений зеленого экрана в стиле BDD, с небольшим количеством предварительно описанных шагов. Однако в предлагаемом решении нас настораживало следующее:

  1. Использовался сторонний платный эмулятор не от IBM (все эмуляторы работают немного по-разному, а нам нужно проверять работу именно на штатно используемых в банке, цена ошибки невероятно высока);
  2. Реализации шагов Cucumber-а для Quick3270 использовали большое количество sleep-ов для ожидания ответа от машины;
  3. Очень низкая производительность работы Quick3270 через интерфейс автоматизации (работа с HACL в прототипе через С++ интерфейс выглядела куда более динамичной).


Эмулятор терминала Quick3270

Мы решили на основе прототипа попробовать реализовать собственный сервер автоматизации, чтобы соединить Cucumber с Personal Communications for Windows и разработать шаги таким образом, чтобы время простоя между действиями на экране эмулятора было минимальным.

Лирическое отступление. Несмотря на тот факт, что вокруг якобы «legacy» IBM существует огромное количество технических задач, которые, казалось бы, уже должны были быть решены для систем уровня среднего и enterprise-бизнеса, актуальность адаптации и переноса существующих технических решений очень высока попросту из-за их отсутствия на платформе. Зачастую отсутствие связано с самими особенностями работы этой ОС, которая в корне отличается от современных *nix, Windows или MacOS X, что требует значимой оптимизации софта для данного стека.

Собственное решение


В качестве собственного решения мы создали сервер автоматизации как развитие ранее демонстрируемого прототипа. Данный сервер выполняет команды по автоматизации взаимодействия от потребителей через RPC сервер (Qt5 WebSocket). Он взаимодействует с Personal Communications for Windows, входящим в образ корпоративной ОС Windows, и позволяет:

  • запускать/останавливать сессии эмулятора терминала;
  • выполнять Screen Scraping зеленого экрана;
  • искать поля ввода на экране;
  • управлять курсором и имитировать нажатия клавиш (в т.ч. хостовых);
  • и др.


Запуск сервера автоматизации

Однако при всех достоинствах HACL API, у него есть один недостаток – он совершенно не умеет работать со встроенной в ОС СУБД DB2 for i и не позволяет выполнять команды, которые жизненно необходимы для построения mock-окружения, где бы выполнялся тестовый сценарий. Если DB2-клиент для Ruby существует от IBM, то клиент для сервера удаленного выполнения команд «Remote command and distributed program call server» есть только для Java в виде библиотеки JTOpen: The Open Source Version of the IBM Toolbox for Java (также известная как jt400). Решение данной проблемы мы «подсмотрели» у самого IBM путем анализа поведения его продуктов со схожей функциональностью (в частности, Personal Communications for Windows Data Transfer, iSeries to PC / PC to iSeries Transfer и др). Оказалось, что эти продукты по своей реализации запускают IBM JRE 6 или 8, в зависимости от версии приложения, и используют библиотеку jt400.

Для сервера автоматизации мы решили поступить аналогичным образом. Через JNI запускается IBM JVM, поставляемая вместе с Personal Communications for Windows. Используя специальные методы-обертки, исполняются приходящие извне команды RPC-сервера с помощью их проксирования в вызовы необходимого функционала jt400. Так как последний также содержит JDBC-драйвер для DB2, решено было использовать его же для доступа к СУБД на IBM i.

Важно отметить, что при использовании HACL нельзя использовать Oracle JVM. Если вы запустили сессию эмулятора терминала, то попытка создать экземпляр виртуальной машины приведет к падению. Аналогично, если запустить Oracle JVM в адресном пространстве процесса, взаимодействующего с HACL, то последний зависает без объяснения причин.

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

  1. Эпизодические зависания терминала;
  2. Невозможность работы на регрессионном стенде вследствие того, что эмулятор терминала отказывался запускаться, если рабочий стол пользователя, под которым запускается эмулятор, заблокирован или неактивна его RDP-сессия;
  3. Windows-only;
  4. Сложная процедура установки, настройки и обновления инструментария (через msi-пакет);
  5. Наш цикл регресса на 130 автотестов (около 4000 шагов) стал занимать 7-8 часов.

Нужно что-то делать…


Путем анализа журналов трассировок многочисленных запусков автотестов, поиска узких мест в производительности выполнения часто используемых шагов, общее время выполнения регресса удалось снизить до 4-5 часов. Но было понятно, что использование middleware-слоя в виде RPC-сервера автоматизации совместно с интерфейсом HACL, который в том числе имеет «плавающие» ошибки, накапливаемые с продолжительностью работы всей системы, не поможет в улучшении характеристик решения.

С другой стороны, в качестве альтернативы IBM Personal Communications for Windows вендор предоставляет кроссплатформенное решение под названием IBM i Access — Client Solutions.


IBM i Access — Client Solutions

Анализ его внутреннего устройства по субботним и воскресным утрам за чашками кофе показал, что его кодовая база построена на базе другого продукта от IBM, который называется IBM Host on-Demand (IBM HOD). Это полноценное решение для доступа к IBM i, разработанное на Java 6, которое не только имеет в себе полную реализацию разнообразных протоколов коммуникаций, используемых в машинах IBM (TN3270, TN5250, VTxxx и др), но и высокоуровневые java-swing UI-компоненты, используемые для построения собственных эмуляторов терминалов в виде конструктора, который можно собрать по скудной документации IBM. Более детальное изучение IBM HOD показало, что UI-компоненты построены на базе Java-реализации интерфейса HACL, чья документация открыта. Их поведение совпадает лишь с небольшими отличиями от С++ HACL-документации.


IBM Host On-Demand (логотип)

Далее мы создали Java-библиотеку для внутреннего пользования, в которой реализуется такой же интерфейс как у С++ RPC-сервера автоматизации, но внутри полностью использующий IBM HOD. Для уменьшения накладных расходов при выполнении шагов автотеста мы мигрировали с Ruby Cucumber на cucumber-jvm с реимплементацией всех шагов аналогично Ruby-вариантам. При наличии схожего с RPC-сервером программного интерфейса это не составило большого труда, особенно с учетом того, что мы старались сдерживать бесконтрольный рост числа самих шагов и у нас это значение находилось в районе 30 единиц.

Что в итоге


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

Уже существующие 180 автотестов с более чем 16000 шагов при установленной задержке в 60 мс между шагами стали выполняться порядка 30 минут против 5 часов 30 минут, что соответствует одиннадцатикратному увеличению производительности регрессионного стенда.

Результаты превзошли все ожидания. Мы вплотную подошли к физическим пределам протокола TN5250.

На сегодняшний день решение опубликовано на весь банк, а к совершенствованию подключились коллеги из других городов. Из последних изменений коллеги выполняют интеграцию решения с Jenkins-ом, в тестовом варианте завершена апробация запуска на Linux-сервере с Xvfb и начинается стадия пилотной эксплуатации запуска автотестов на нем.

Спасибо, что дочитали до конца!
Всем успехов!

P.S. В декабре 2018 года состоялась очередная Конференция разработчиков IBMi, на которой в том числе был сделан доклад на тему этой статьи.

До сих пор мы ежегодно проводили Конференцию только для сотрудников Банка. С 2019 года мы будем приглашать участников из других компаний. Очень интересно расширить круг профессионального и личного общения, поделиться эмоциями, знаниями и опытом.
Теги:
Хабы:
Всего голосов 43: ↑43 и ↓0 +43
Просмотры 21K
Комментарии Комментарии 75

Информация

Дата основания
1990
Местоположение
Россия
Сайт
alfabank.ru
Численность
5 001–10 000 человек
Дата регистрации
Представитель
Алексей