История одного бага

Всё началось с баг репорта от одного из пользователей нашего фрэймворка JDI LightNullPointerException при WebPage.open(), а точнее WindowsManager.getWindows()

Максимально странное падение до 30% тестов разом с одной ошибкой. Причём либо падает сразу много, либо — не падает вообще.

Мы в JDI очень трепетно относимся к баг репортам пользователей, особенно такого фантастического качества — с подробным описанием и вот этим всем.

К расследованию немедленно приступил один из наших самых квалифицированных контрибьюторов — Владимир Клонин (кстати — один из победителей прошлогоднего хакатона автоматизаторов в Санк-Петербурге).

Это ненастоящее изображение Володи. На фото изображён Бенедик, наш, Камбербетч в образе Шерлока Холмса
Это ненастоящее изображение Володи. На фото изображён Бенедик, наш, Камбербетч в образе Шерлока Холмса

Не с первой попытки, но у Володи получилось воспроизвести проблему устойчиво на нашем CI/CD
Наша первоначальная идея была в том, что подобный регресс вызвало поднятие версии селениума — ну где-то в проекте сохранились зависимости на старую версию и это приводит к такому эффекту. Ведь падало то — что то в самом драйвере (нет). Что характерно — подобные зависимости — действительно были. Однако их исправление — ровным счётом ничего не поменяло.

Это ввергло нас в некоторое уныние т.к. диагностика ошибки — весьма скудная.

Расстановка же дополнительной диагностики — привела в удивительному результату!

Напомню как работает JDI Light — в случае, если драйвер на машине не найден, то он, используя webdrivermanager, развиваемый разработчиком Boni García, пытается его скачать:

            wdm.setup();             logger.info("Download driver: '" +  driverName + "' successfully");             driverDownloaded = true;             downloadedDriverInfo = format("%s:%s:%s", driverType, platform, version);             driverPath = wdm.getDownloadedDriverPath();

после чего запрашивает и получает директорию где он лежит.

Удивительное заключается в том, что несмотря на то, что команда сетап выполняется успешно и без ошибок — driverPath оказывается NULL !

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

Разумеется мы тут же зарепортали эту проблему. На что получили не менее удивительный ответ. Автор нам не поверил:

На его машите - всё работает.
На его машите — всё работает.

Более того — у него эта функциональность покрыта тестом (разумеется одним, и разумеется, гоняемым в один поток, ха!) — и тест проходит. Он попросил нас предоставить рабочий пример [который будучи запущенным на рандомной машине — гарантировано продемонстрирует проблему, а как вы хотели?]

Тут, конечно, мы немного загрустили.

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

Фотография музы, найденная на просторах интернета
Фотография музы, найденная на просторах интернета

Наташа придумала простую, но не очевидную вещь — сделала pr который превращает однопоточный прогон того теста — многопоточным, что, к счастью, приводит к падению.

Результат этого — оказался и вовсе неожиданным.

Бони нам не поверил. Теперь уже окончательно.

Ну вы знаете - эти браузеры - под ногами путаются, так и норовят зафризится, что бы обрушить тесты
Ну вы знаете — эти браузеры — под ногами путаются, так и норовят зафризится, что бы обрушить тесты

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

Но борьба с ними — это совсем другая история…


ссылка на оригинал статьи https://habr.com/ru/post/690998/

User Defined Type. Что это и как его использовать

Картинка: Designed by vectorjuice / Freepik

Кому будет полезна статья, по мнению автора:
начинающим программистам на языке VBA и тем, кто не работал ранее с оператором Type. Если вы используете этот оператор постоянно, можно сравнить свой вариант применения и вариант автора.

Большинство пользователей VBA прекрасно знают такую штуку как Type, он же User Defined Type (UDT). Кто-то, как я, использует его на повседневной основе. Кто-то, возможно, о нем слышал, но не мог понять как его применить.

Лично я помню, как не так давно смотрел на этот Type и пытался понять зачем он мне нужен, ведь он просто хранит в себе переменные, которые можно с тем же успехом объявить в функции/процедуре или на уровне модуля?

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

Вычисляем ошибки, чтобы их не допускать

Что же, для начала давайте обратимся к официальной документации:

(вольный перевод автора)
Оператор Type – используется на уровне модуля для объявления пользовательского типа данных, содержащего один или несколько элементов.Type можно использовать только на уровне модуля. После объявления пользовательского типа вы можете объявить переменную этого типа в любом месте в пределах области видимости. Для объявления переменной пользовательского типа используйте Dim, Private, Public, ReDim или Static… Номера и метки строк не допускаются внутри блоков Type…End Type.

Итак, исходя из документации мы можем выделить два основных момента:

  1. Оператор Type используется только на уровне модуля. Это значит, что его нельзя объявлять в процедурах/функциях/методах/свойствах.

  2. Номера и метки строк не допускаются внутри блоков.

Давайте протестируем оба утверждения:

В первом случае получаем ошибку компиляции «Недопустимая внутренняя процедура»,

ошибка компиляции при объявлении Type внутри процедуры
ошибка компиляции при объявлении Type внутри процедуры

во втором так же ошибка компиляции «Оператор (заявление/утверждение) недопустим внутри блока Type».

ошибка компиляции при объявлении Type с номером/меткой строки внутри блока
ошибка компиляции при объявлении Type с номером/меткой строки внутри блока

Не описано в официальной документации то, что объявленный в Class модуле Type может быть только Private, иначе мы снова получим ошибку компиляции, в этот раз «Нельзя объявлять публичный пользовательский тип в объектном модуле»:

ошибка компиляции при объявлении Public Type в Class модуле
ошибка компиляции при объявлении Public Type в Class модуле

Компилятор перестает ругаться только в случае Private Type в Class модуле, но здесь нужно помнить, что возвращать такой UDT можно только Private функцией, иначе:

ошибка компиляции при возврате приватного типа
ошибка компиляции при возврате приватного типа

мы снова получим ошибку компиляции, теперь это «Private перечисления и пользовательские типы, не могут использоваться в качестве параметров или возвращаемых типов для Public процедур, членов данных или полей пользовательских типов».
Кстати, как и обозначено в описании ошибки, в модуле класса нельзя создавать публичные поля или использовать параметры для публичных методов с приватным типом UDT. Ну оно и логично.

Постановка задачи

Итак, если я не ошибаюсь, с ошибками мы разобрались. Перейдем к использованию.

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

Решаем без UDT

Для начала разберемся с обычным модулем. Про использование UDT в Class модуле я напишу отдельную статью.

Как можно решить эту задачу стандартными средствами?

Что ж, первое что мы делаем – объявляем переменные, которые будут содержать адрес получателя и адрес адресата копии (простите за тавтологию), а так же тему письма, после чего присваиваем напрямую значения, чтобы не усложнять пример, и отправляем их как аргументы в функцию CreateLetter:

Sub Mailing()     Dim AddressTo As String: AddressTo = "exampleTo@test.vba"     Dim AddressCC As String: AddressCC = "exampleCC@test.vba"     Dim Subject   As String: Subject = "Тема письма"      CreateLetter AddressTo, AddressCC, Subject End Sub

Далее, пропишем функцию, которая создаст и отправит или сохранит письмо (это значение сделаем необязательным, по умолчанию установим в False):

заметьте как много параметров уже сейчас есть в этой функции
заметьте как много параметров уже сейчас есть в этой функции
Sub CreateLetter(ByVal AddressTo As String, _                  ByVal AddressCC As String, _                  ByVal Subject As String, _                  Optional ByVal Submit As Boolean = False)     Dim Outlook As Object     Set Outlook = CreateObject("Outlook.Application")      With Outlook.CreateItem(olMailItem)         .To = AddressTo         .CC = AddressCC         .Subject = Subject         If Submit Then .Send     End With End Sub

Итак, в целом все нормально. У нас есть данные, мы передаем их в функцию, функция их использует.

Но это всего лишь два адреса и тема.
А теперь представим, что нам нужно передавать еще текст тела письма и вложение.
А еще в параметрах можно указать нужно ли удалять письмо после отправки (свойство DeleteAfterSubmit), или указать нужно ли отметить неотправленное письмо (черновик) как прочитанное (свойство UnRead).
А еще, возможно нам потребуется создавать письмо из другой процедуры и тогда снова придется перечислять все переменные в объявлении и передавать их все в функцию.
И многое, многое другое…
Представьте на секунду насколько сильно разрастутся параметры функции.
Плюс, копия в письме может быть не всегда, как и вложение. Тогда придется делать все параметры Optional? Или прописать ParamArray? Это все не наглядно и может вызвать ошибки, в случае не верной передачи параметров.
Код становится менее читаемым и сумбурным, согласитесь. На таком небольшом примере все ок, ничего особо критичного. Но в реальном проекте это может стать большой проблемой.

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

Решаем с UDT

Для решения нам потребуется объявить Type на уровне модуля и поместить в него все наши переменные. Давайте назовем его TLetter:

Type TLetter     AddressTo As String     AddressCC As String     Subject   As String End Type

Далее, в процедуре Mailing создадим переменную Letter типа TLetter:

обратите внимание, что IDE уже предлагает нам автокомплит данного типа и это прекрасно!
обратите внимание, что IDE уже предлагает нам автокомплит данного типа и это прекрасно!
Sub Mailing()     Dim Letter As TLetter     Dim AddressTo As String: AddressTo = "exampleTo@test.vba"     Dim AddressCC As String: AddressCC = "exampleCC@test.vba"     Dim Subject   As String: Subject = "Тема письма"      CreateLetter AddressTo, AddressCC, Subject End Sub

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

и вновь автокомплит в действии
и вновь автокомплит в действии
Sub Mailing()     Dim Letter As TLetter     Letter.AddressTo = "exampleTo@test.vba"     Letter.AddressCC = "exampleCC@test.vba"     Letter.Subject = "Тема письма"      CreateLetter Letter End Sub

Ничего вам это не напоминает?😏

Если вы сказали «да это же как объект» – то вы совершенно правы. Взаимодействие с Type очень похоже на взаимодействие с объектами. Только мы объявляем его без ключевых слов New и Set, как в случае с объектами, а так же не сможем поместить в него функции/процедуры. Я бы даже назвал этот блок, скорее, своего рода, структурой.

Все что нам осталось сделать – заменить в процедуре CreateLetter три старых параметра на один новый и переписать присваивание параметров:

Sub CreateLetter(ByRef Letter As TLetter, _                  Optional ByVal Submit As Boolean = False)     Dim Outlook As Object     Set Outlook = CreateObject("Outlook.Application")        With Outlook.CreateItem(olMailItem)         .To = Letter.AddressTo         .CC = Letter.AddressCC         .Subject = Letter.Subject         If Submit Then .Send     End With End Sub

Кстати, в блоке Ошибки я забыл упомянуть еще одну небольшую особенность – UDT в параметры можно передавать только ByRef.

Так лучше, верно?

Не совсем. Давайте уберем последний опциональный параметр Submit из функции и пропишем его в нашей структуре как поле:

Option Explicit  Type TLetter     AddressTo As String     AddressCC As String     Subject   As String     Submit    As Boolean ' Переносим параметр в структуру. End Type  Sub Mailing()     Dim Letter As TLetter     Letter.AddressTo = "exampleTo@test.vba"     Letter.AddressCC = "exampleCC@test.vba"     Letter.Subject = "Тема письма"        CreateLetter Letter End Sub  Sub CreateLetter(ByRef Letter As TLetter)     Dim Outlook As Object     Set Outlook = CreateObject("Outlook.Application")      With Outlook.CreateItem(olMailItem)         .To = Letter.AddressTo         .CC = Letter.AddressCC         .Subject = Letter.Subject         If Letter.Submit Then .Send ' Передаем поле из структуры.     End With End Sub 

Вот теперь действительно лучше.
Обратите внимание, мы не присваиваем полю Submit значение в процедуре Mailing. Не присвоенное значение по умолчанию останется False:

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

Расширяем возможности

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

Допустим в функцию CreateLetter нам нужно дополнительно передавать параметр UnRead, а так же тело письма.

Для начала разделим все наши вводные на несколько блоков:

  1. Блок адресатов: получатель, копия.

  2. Блок письма: тема и тело.

  3. Блок параметров: отправлять или нет, помечать как прочитанное или нет.

Итого получаем три блока по две переменных в каждом.
Как это реализовать? Очень просто.

Для начала, под каждый блок создаем свой UDT:

Option Explicit  ' Блок адресатов Type TRecipient     To As String     CC As String End Type  ' Блок письма Type TMain     Subject As String     Body    As String End Type  ' Блок параметров Type TParameter     Submit As Boolean     UnRead As Boolean End Type

После чего снова создаем UDT TLetter, а уже в нем объявляем три переменных с ранее созданными блоками:

Type TLetter     Recipient  As TRecipient     Main       As TMain     Parameter  As TParameter End Type

Да, так можно было. 😁

Дальше, что называется, следите за руками.

В процедуре Mailing через уже знакомую переменную Letter присваиваем значения переменнным блока адресатов и блока письма:

параметр передаваемый в функцию CreateLetter остается неизменным, это важно
параметр передаваемый в функцию CreateLetter остается неизменным, это важно
Sub Mailing()     Dim Letter As TLetter     Letter.Recipient.To = "exampleTo@test.vba"     Letter.Recipient.CC = "exampleCC@test.vba"     Letter.Main.Subject = "Тема письма"     Letter.Main.Body = "Тело письма"      CreateLetter Letter End Sub

Немного корректируем функцию CreateLetter и добавляем новые параметры для создаваемого элемента письма (не функции):

Sub CreateLetter(ByRef Letter As TLetter)     Dim Outlook As Object     Set Outlook = CreateObject("Outlook.Application")      With Outlook.CreateItem(olMailItem)         .To = Letter.Recipient.To         .CC = Letter.Recipient.CC         .Subject = Letter.Main.Subject         .Body = Letter.Main.Body         .UnRead = Letter.Parameter.UnRead         If Letter.Parameter.Submit Then .Send     End With End Sub

И все! Да, так просто.

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

Что в итоге

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

А ведь это важные вещи, к которым мы все стремимся при написании кода.

Это не все, что я хотел рассказать про Type. В следующей статье рассмотрим еще один пример использования UDT в модуле, а так же увидим как его применять в Class модуле.

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

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Умели раньше пользоваться оператором Type?
25% Да, использую его так же как автор 1
25% Да, но использую его иначе (опишите, пожалуйста, как именно в комментариях) 1
0% Нет, но слышал о нем. Не вижу смысла применять 0
25% Нет, но слышал о нем. Возможно теперь буду применять 1
0% Нет, и не слышал. Не вижу смысла применять 0
25% Нет, и не слышал. Возможно теперь буду применять 1
Проголосовали 4 пользователя. Воздержавшихся нет.

ссылка на оригинал статьи https://habr.com/ru/post/691000/

Просто о сложном: Confidential Cloud Computing

Сегодня мы попробуем разложить по полочкам концепцию Confidential Cloud Computing и содержательно поговорить о конфиденциальных вычислениях в Web 3.

  • Облачные вычисления

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

Облако начало приобретать современные очертания только в начале 2000 года. Что произошло? До этого Интернет был в основном в руках нескольких энтузиастов. Затем произошла удивительная вещь: сотрудники Amazon (в то время интернет-магазина) не были удовлетворены скоростью, с которой они могли разрабатывать новые продукты и услуги. Проще говоря, они внедрили новый процесс для своих команд разработчиков и построили инфраструктуру с двумя ключевыми функциями:

  • позволить инженерам создавать новые сервисы быстрее и не затрачивать слишком много ресурсов на обслуживание;

  • обеспечить масштабирование и рост успешных услуг (тех, которые удовлетворяют спрос клиентов)

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

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

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

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

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

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

  • распределенная платформа без накладных расходов или других барьеров для входа/использования;

  • стек технологий, который позволяет разработчикам и не требует особого обслуживания;

  • открытая экосистема без единого владельца, в которую каждый может внести свой вклад.

Это видение нашло сегодня свое отражение в проектах Cloud Computing в WEB 3.

  • SCC: Конфиденциальные вычисления. В чем вся суть?

Прежде всего, что означают  слова Конфиденциальные вычисления (Confidential  computing)? В частности, разве не очевидно, что данные (имеющие в действительности что угодно: изображение, дату рождения, номер счета, его баланс или даже количество дней, прошедших с момента его активации) должны быть конфиденциальными и защищенными, так зачем делать акцент на «вычислениях»?

Иногда озвучивание очевидных вопросов может привести к интересным результата. В общем случае данные могут находиться в трех состояниях:

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

  • в движении: переносятся из точки А сети в точку Б

  • в использовании: данными каким-то образом манипулируют

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

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

Каждая точка этого пути имеет несколько потенциальных углов для хакерской атаки. Большинство усилий по защите данных были сосредоточены на двух состояниях: в покое и в движении. Конечно, часть «в использовании» не осталась без внимания, но только до последних достижений в области технологий стало возможным полностью защитить данные во всех трех состояниях.

Так появился термин «конфиденциальные вычисления»! Он указывает на определенный набор методов, направленных на защиту данных во время их использования (вычисления).

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

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

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

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

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

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

Вот тут-то и появляется Confidential Cloud Computing — это платформы, которые позволяют поставщикам конфиденциальных вычислений сделать их услуги более заметными и доступными для разработчиков.

  • Trusted Execution Environment: почему это важно для WEB 3.0?

Далее в статье мы рассмотрим более сложную тему Trusted Execution Environment или TEE: что это такое и как Web3 может извлечь выгоду от их использования.

Что такое TEE?

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

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

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

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

Что, если злоумышленнику каким-то образом удастся авторизовать свое приложение? Идеальный сценарий предполагает, что код каждого авторизованного приложения проверяется, и таким образом гарантируется, что оно не попытается сделать что-то подозрительное. Реальность часто разочаровывает, но не в этот раз. У авторизованного приложения есть ключ, который позволяет ему получить доступ только к определенным частям процессора, то есть даже с ключом оно не сможет получить доступ к другим его разделам и увидеть код или среду выполнения других приложений.

Метафора для лучшего понимания (и объяснения TEE на вечеринках): представьте, что вы живете в многоквартирном доме с большой стеной почтовых ящиков (по одному на жильца). Только у вас есть ключи; твой ключ подходит только к замку в вашем почтовом ящике. TEE работает так же. Ни один другой арендатор не может получить к нему доступ и прочитать вашу почту. Кроме того, любой, кто пишет вам, использует секретный код, который можете расшифровать только вы, поэтому, если почтальон неправильно прочитает цифры на ящике, а ваш сосед получит вашу почту — он не сможет ее прочитать!

Теперь давайте перейдем к тому, почему это столь необходимая функциональность для технологий Web3.

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

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

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

  • Аппаратное обеспечение для конфиденциальных вычислений: Intel SGX

Возможным TEE сделала инновационная технология Intel Software Guard Extensions (сокращенно SGX, хотя в оригинальной статье «Инновационные инструкции и программная модель для изолированного выполнения» кажется более содержательной).

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

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

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

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

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

Теперь мы подошли к моменту, когда становится очевидным, что даже один компьютер не должен быть скомпрометирован, если мы хотим обеспечить безопасность SLA высшего уровня для конечного пользователя. Будет ли достаточно использовать антивирус, следовать основным правилам кибербезопасности и надеяться, что механизмы защиты на сетевом уровне сделают все остальное? К сожалению нет. Лучшей защитой будет устранение любого потенциального уязвимого места.

Вот тут-то и появляется технология Intel SGX. Она была разработана с учетом всех моментов, упомянутых выше. Вопрос исследователей заключался в следующем: «Как мы можем гарантировать, что злоумышленник не сможет причинить вред, даже если он получит физический доступ к машине?»

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

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

Важный вопрос: можно ли пройти аттестацию удаленно безопасным способом? Да! Это означает, что мы можем удвоить безопасность, объединив TEE от доверенного поставщика со следующими уровнями сетевой безопасности и уровнем консенсуса.

Возможность подключать доверенных поставщиков TEE и проверять все, что происходит, является важной частью работы Confidential Cloud Computing.


ссылка на оригинал статьи https://habr.com/ru/post/690892/

Playwright или Selenium?

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

В частности, задача состояла в разработке тестов с помощью web-driver, преимущественно под Chrome. Язык и фреймворк можно выбирать на свое усмотрение, однако в компании активно ведется разработка на с# и typescript. В общем виде End2End тест должен был покрывать основной сценарий пользовательского взаимодействия, включая аутентификацию, если она потребуется. В реальности же, это означало, что требовалось проверить доступность и функциональность основных элементов управления и ввода информации, переходы по вкладкам и сценарии прохождения от разных функциональных ролей в системе.  

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

Рассмотрев несколько популярных существующих решений с открытым исходным кодом, мы решили остановиться на Selenium и Playwright. Selenium привлек наше внимание прежде всего своей известностью и надежностью, к тому же для него уже была создана платформа для запуска, а Playwright современностью и скоростью развития. 

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

  • Selenium

  • Playwright

  • Drag and drop

  • Shadow Dom

  • Итоги

Сравнительная статистика нескольких фреймворков, которые мы рассматривали представлена здесь.

Selenium

Selenium достаточно старый и наверное, самый надежный с точки зрения поиска популярных решений в интернете фреймворк. Он поддерживает достаточно много языков, которые подходят нам. К основным достоинствам можно отнести:

  • Невысокий порог вхождения

  • Есть возможность написания тестов на с#

  • Поддержка достаточно широкого стека браузеров (Chrome, Firefox, Edge, IE, Opera, Safari)

  • Достаточно подробная документация и множество рекомендаций по решению популярных проблем в интернете

  • Проверенный временем

  • Достаточно шустрый

  • Есть возможность параллельного запуска

К недостаткам использования Selenium можно отнести:

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

  • Есть проблемы с реализацией перетаскивания (об этом пойдет речь ниже)

  • Поиск элементов в shadow dom отделяется от поиска простых элементов, что впрочем, не является однозначным недостатком

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

Playwright

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

Есть возможность реализации как в c#, так и в ts. 

Достоинства:

  • Тесты выполняются в изолированной среде с чистого листа

  • Большое количество доработанных действий пользователя

  • Отлично работает перетаскивание

  • Поиск элементов в shadow dom ничем не отличается от обычного поиска элементов

  • Достаточно шустрый

  • Не нужно следить за драйвером

  • Параллельный запуск из коробки

  • Интеграция с докером

Недостатки:

  • Решение новое и современное и, как следствие, не слишком много сведений в интернете, а также компаний, которые используют такой подход

  • Нет поддержки Safari и IE

  • Входной порог несколько выше, чем в Selenium

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

Drag and drop

Перетаскивание элементов сейчас используется во многих рабочих проектах. Данную операцию поддерживают как Selenium, так и Playwright. Однако, здесь стоит уточнить, что Selenium собирает Drag and Drop из нескольких действий:

act.ClickAndHold(draggable)    .MoveToElement(droppable)    .Release()    .Build()    .Perform();

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

Полный аналогом этого кода:

act.DragAndDrop(draggable, droppable)    .Build()    .Perform();

Здесь используется функция DragAndDrop в отличии от прошлого, состоящего из группы событий.

Впрочем, и тот и другой код не будет работать, если атрибут перетаскивания (draggable=’true’) ставится динамически по нажатии на элемент. Так что не удивляйтесь, если перетаскивания в Selenium у вас не получится реализовать.

В отличии от Selenium Playwright реализует Drag and Drop даже с динамическим изменением свойств из коробки. 

await Page.DragAndDropAsync(".draggable", ".droppable");

Здесь перетаскивание элемента с классом «draggable» к элементу с классом «droppable» работает даже в динамике, то есть когда элемент становится перетаскиваемым после клика по нему. 

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

Shadow dom

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

public static IEnumerable<IWebElement> FindShadowRootElements(this IWebElement shadowHost, By by)  {      var shadowRoot = shadowHost.GetShadowRoot();      return shadowRoot.FindElements(by);  }

Здесь получаем свойство shadowRoot у элемента и ищем по его содержимому. Также можно написать метод расширения, который совмещает поиски.

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

В Playwright поиск в теневом доме ничем не отличается от поиска в обычном доме. Так например,

await Page.Locator(“#shadowIdElement”).WaitForAsync();

Здесь ждем загрузки элемента с идентификатором shadowIdElement если даже этот элемент находится в shadowDom Playwright его найдет. Поиск элементов через css или text в Playwright производится сначала в обычном доме, а затем в shadowDow. Однако, на случай если нам не требуется поиск внутри shadowDom можно записать выражение так:

await Page.Locator(":light(#elId)").WaitForAsync();

Здесь поиск элемента с id = ‘elId’ ограничивается только обычным или светлым домом. 

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

Итоги

Несмотря на то, что данные фреймворки реализуют похожий функционал в некоторых случаях их можно комбинировать, в рамках одного проекта или даже теста могут сочетаться подходы Selenium и Playwright. Однако подобное сочетание может привести к беспорядку в коде и усложнению логики, а также разрастанию “зоопарка фреймворков”.

В целом же если вам нужно реализовать UI тесты для вашего сервиса и у вас нет четких требований поддерживать Safari и IE и у в вашей компании нет тонн кода на Selenium, Playwright отличная современная быстро развивающаяся альтернатива, которая дает некоторые современные приятные функциональные “плюшки” прямо из коробки. К тому же Playwright более современный и быстро развивающийся framework, идущий в ровень с развитием современных фронтовых фреймворков.

В рамках написания тестов мы остановились на версии Playwright.net.Данная версия достаточно просто стыкуется с известными фреймворками заточенными под модульное тестирование такие как NUnit или Ms Test. Поскольку уже существовали Ms Test выбор был сделан именно в его пользу.  


ссылка на оригинал статьи https://habr.com/ru/post/691012/

От пятикратного падения выручки к возвращению в плюс: опыт CyberBrain в 2022 году

Команда акселератора Спринт регулярно общается с выпускниками разных потоков. 26 сентября мы встретились с участником 4-го Спринта — проектом CyberBrain и его руководителем Никитой Лисицыным.

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

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

Про решение CyberBrain

Крупные рекламодатели с миллионными бюджетами зачастую не могут оценивать результативность рекламных кампаний на разных площадках. До 35% бюджета расходуется вслепую, а 70% рабочего времени уходит на запуск кампаний, а не на их оптимизацию. Как результат — затраты на рекламу растут, а её эффективность снижается.

Решение CyberBrain позволяет сократить расходы рекламодателей, объединяя в себе инструменты аналитики, оптимизации и повышения результативности digital-рекламы.

Состояние перед программой

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

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

В марте мы остались с нулём предложений. Одновременно с этим наша выручка упала в пять раз и «откатилась» к уровню февраля 2021, когда мы только стартовали.

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

К старту акселератора в мае 2022 мы были в ситуации, когда:

  • Большинство корпоративных клиентов заморозили свои R&D-программы и «открытые инновации». Для стартапа подразделения инноваций — это основная точка входа в крупные корпорации, и практически все они с марта 2022 года остановили поиск партнёров и запуск новых пилотов. 

  • Все клиенты сократили бюджеты на рекламу. Зарубежные клиенты исчезли в один день, а российские клиенты резко сократили затраты на рекламу: в моменте снижение достигало 80%.

  • Многие ключевые ЛПР ушли на майские и летние отпуска. На отдых ушли многие сотрудники, которые могли «разблокировать» работу департаментов инноваций.

Работать с корпоративными клиентами стало сложнее: партнёры шли на контакт, но процесс никуда не двигался. Нам говорили: «приходите позже», но стартап не может ждать — нам нужно было зарабатывать деньги на собственное развитие.

Из-за этого к началу программы мы подошли «закомплексованными»: команда опасалась пробовать новое и не понимала, с чего начать. Выйти из этого состояния помогли регулярные встречи с трекерами и экспертами ФРИИ.

Что и как поменяли во время программы

До того, как начать что-то менять в бизнесе, мы проработали разные сценарии: апокалиптичный, плохой, нормальный, хороший и ультрахороший. Мы разобрали все сценарии с трекерами, отбросили самые «светлые» и самые «тёмные», и тогда нам стало понятно, что имеющихся средств нам хватает для привлечения новых сотрудников и развития маркетинга, PR и продаж. 

С самого основания мы действуем из расчёта, что у нас есть запас денег на 6 месяцев работы. Сейчас (спойлер!), когда мы снова стали прибыльными, мы действуем так же: даже если нам в один день перестанут платить вообще все клиенты, у нас есть запасы на несколько месяцев спокойной работы.

Мы подумали: какой объём выручки мы хотим увидеть через три месяца акселерации? Нам надо было максимально стабилизироваться и вернуться в рост. Вместе с трекерами мы проработали несколько направлений:

  • Коммерческие предложения и механизм привлечения клиентов

  • Системная проверка гипотез для роста выручки

  • Запуск «холодных» продаж нашего решения

  • Расширение штата для ускорения проверки гипотез и продаж

Одним из первых действий в акселераторе стало превращение сайта CyberBrain из «визитки» в полноценный источник заказов. Раньше задачу привлечения мы решали в одной зарубежной социальной сети, но после запрета активность пользователей понизилась, поэтому мы переключились на развитие сайта.

Основные результаты акселерации мы показали в презентации для Демо-дня. Главный успех — это контракт на 6 млн рублей, который стал результатом изменений в системе продаж:

Оглядываясь назад: этот результат был закономерным. Через ФРИИ получилось найти нужную экспертизу, у экспертов и трекеров был прикладной опыт в нашей сфере, а нетворкинг сильно сократил путь к потенциальным клиентам и партнёрам.

Продолжая тему пользы акселератора, советуем всем участникам нацеливаться на Демо-день — туда точно надо попасть. Короткий понятный питч ускоряет знакомство и помогает увеличить осведомлённость о продукте: после нашего выступления с нами связались несколько компаний, и с одной из них мы обсуждаем инвестиции.

Советы и рекомендации

Если вы ищете инвестиции, то сейчас мы видим два возможных пути развития для стартапов:

Если вы собираетесь работать на рынках России и СНГ — рассмотрите гранты, а не инвестиции. Сейчас инвестиционная активность низкая, и даже в случае интереса условия могут быть невыгодными. Поэтому если вам нужны средства на развитие — подавайте на гранты. Информации об этом очень много, а сами процедуры не такие уж и сложные: мы подали заявку на грант РФРИТ и получили очень подробный список правок. Также можно рассмотреть гранты ФСИ и Сколково.

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

В заключение поделюсь некоторыми советами из нашего опыта: 

  • В акселераторе нужно работать. У команды должен быть ресурс на вовлечение в программу и проверку гипотез. Нет смысла встречаться с трекерами «для галочки», нужно все три месяца работать вместе.

  • Демо-день — это ваше всё. Чем больше о вас слышат, тем лучше — всегда можно переслать запись питча инвесторам или представителям корпораций. Нам это помогло сразу после выступления.  

  • Начните продавать. Окупаемость — это хорошо, а прибыльность — ещё круче, поэтому если вы не занимались «холодными» продажами, задумайтесь об этом прямо сейчас. 

  • Используйте разные каналы для найма сотрудников. Не обязательно сидеть на HH или обращаться в агентство. Ищите через знакомых, в социальных сетях или попробуйте обратиться в HR-стартапы, которые специализируются на найме.

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

CyberBrain прошёл 4-й поток акселератора Спринт. Последний в 2022 году приём заявок завершился 27 сентября, а сама программа стартует в январе 2023 года. Тогда же начнётся приём заявок в следующий акселератор. Все подробности — на официальном сайте https://sprint.iidf.ru

Что ещё почитать


ссылка на оригинал статьи https://habr.com/ru/company/sprint_iidf/blog/691018/