Интернет Вещей Там, Где Вы Не Ожидали (Часть 3). Построение Имитационной Модели

Как я уже сказал в Последняя часть , при разработке IoT-проекта протоколы взаимодействия с устройствами были достаточно нестабильными, и шансы потерять связь с тестовыми устройствами после обновления прошивки были достаточно высоки.

В разработке участвовало несколько команд, и было жесткое требование — не потерять возможность протестировать бизнес-уровень приложения, даже если перепрошивка устройств нарушит весь поток работы с датчиками.



Интернет вещей там, где вы не ожидали (часть 3).
</p><p>
 Построение имитационной модели

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

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

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

И никто не будет спешить покупать 10 000 датчиков, чтобы проверить свою гипотезу.



Разработка имитационной модели

Сама имитационная модель выглядела так:

Интернет вещей там, где вы не ожидали (часть 3).
</p><p>
 Построение имитационной модели

Состояние и поведение мусорного бака описывается обычным конечным автоматом.

Сначала мы инициализируем конечный автомат состоянием `EMPTY (level = 0)` и можем совершать над ним какие-то действия, то есть выбрасывать мусор в контейнер.

Теперь нам нужно решить, остается ли контейнер пустым `(level? MAX_LEVEL)` или заполнен `(level > = MAX_LEVEL)`.

Если последнее, то состояние меняется на «FULL».

Кто-то может выгрузить мусор из полного контейнера, или дворник пришел навести порядок, и нам нужно решить, в какое состояние перейти.

За выбор действия отвечает состояние `CHOICE` — в терминологии конечного автомата это что-то похожее на блок if. Контейнер также может сгореть, и тогда состояние конечного автомата изменится на `FIRE`.

Также контейнер может упасть и его состояние станет `ПАДЕНИЕ` (в докладе я рассказывал о том, какие неожиданные причины могут привести к падению контейнеров).

Но есть еще одно состояние «LOST», которое действует из любого другого состояния — оно устанавливается при потере соединения.

Такой конечный автомат описывает практически все поведение контейнера и датчика на нем.

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

  • перевозчики не работают в ночное время;
  • люди выбрасывают больше мусора в определенное время (утром перед работой и вечером).

Таким образом, мы предоставили команде BI возможность настраивать поведение моделирования.

Можно было установить вероятность того или иного события в определенное время суток.



Простой и понятный стресс-тест

Моделирование само по себе имеет множество преимуществ, и одно из них — недорогое нагрузочное тестирование.

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

Таким образом, симуляция бэкенда ничем не отличается от реального датчика.

А если нам нужно запустить 1000 датчиков — запускаем 1000 потоков и работаем.

Кроме того, моделирование обладает высокой масштабируемостью.



Интернет вещей там, где вы не ожидали (часть 3).
</p><p>
 Построение имитационной модели

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

И не забывайте о талантливых китайских разработчиках, которые проигнорировали стандартные протоколы вроде MQTT и написали собственный протокол поверх сокетов.

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

Такой сервер должен был быть многопоточным, так как входных датчиков много.

и эту часть тоже нужно тестировать отдельно, используя тесты производительности.

Вы можете взять JMeter (написать типовой тестовый скрипт), JMH/JCStress (тестировать изолированные части и сделать более точный тест) или что-то свое.

Когда вы принимаете решение в такой ситуации, советую прислушаться к профессионалам, например, Алексею Шипилеву.

На JPoint 2017 он очень крутой рассказал об этом , как тестировать разные вещи и о чем нужно помнить при тестировании производительности.

Мы выбрали вариант сделать что-то свое, так как в проекте был нетипичный подход к QA — у нас нет отдельной команды тестировщиков, а бэкенд-команда сама тестировала функционал.

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

У нас был небольшой инструмент, который позволял быстро описать сценарий загрузки и запустить его в необходимом количестве параллельных потоков:

   

StressTestRunner.test() .

mode(ExecutionMode.EXECUTOR_MODE) .

threads(THREADS_COUNT) .

iterations(MESSAGES_COUNT) .

timeout(5, TimeUnit.SECONDS) .

run(() -> sensor.send(MESSAGE)); Awaitility.await() .

atMost(5, TimeUnit.SECONDS) .

untilAsserted(() -> verifyReceived(MESSAGES_COUNT) );

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

Любой бэкенд-разработчик мог написать всего несколько строк кода.



Ээмуляция сетевых проблем

С помощью моделирования нам удалось смоделировать как некачественную, так и специфическую работу с сокетами.

GSM SIM-карты в датчиках не имеют «белых» IP-адресов, и мы могли получать данные с разных IP-адресов 50 раз в течение суток.

И часто случалось, что открывалось соединение, мы начинали передавать данные, потом менялся IP-адрес, и сервер открывал новое соединение, не закрывая старое.

Если бы мы не учли это, то уже через пару дней у нас бы закончились свободные порты на сервере.



Интернет вещей там, где вы не ожидали (часть 3).
</p><p>
 Построение имитационной модели

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

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

В симуляции подобную ситуацию легко смоделировать с помощью пауз.



Интернет вещей там, где вы не ожидали (часть 3).
</p><p>
 Построение имитационной модели

Это лишь некоторые из сценариев, которые могут быть включены в модель.



выводы

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

Поведение устройств моделировать проще, чем поведение людей.

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

Потому что поведение устройств логически легче описать, чем поведение людей, и тестировать систему становится проще.

Мы рассмотрели довольно много различных аспектов разработки Интернета вещей.



Интернет вещей там, где вы не ожидали (часть 3).
</p><p>
 Построение имитационной модели

Если вы пропустили предыдущие две части этой статьи, вы можете найти их здесь: Интернет вещей там, где не ждали (часть 1) – Предметная область и проблемы Интернет вещей там, где вы не ожидали (часть 2) — Архитектура приложений и тестирование особенностей IoT Github с обсуждаемыми инструментами тестирования.

Немного рекламы.

Как видите, на конференции по тестированию Heisenbug очень разные доклады, например, как мой о разработке и тестировании IoT. Надеюсь, вам было интересно! В этой статье я также упомянул конференцию JPoint, где видел доклады по нагрузочному тестированию.

В этот раз можно купить билет и на Heisenbug, и на JPoint, и еще на 6 конференций сразу.

Увидимся онлайн!

#йот
Вместе с данным постом часто просматривают: