что такое лсп тестирование
Влияние протокола языкового сервера (LSP) на будущее IDE
С момента своего появления Visual Studio Code в одиночку так сильно повлиял на экосистему разработчиков, что возврата назад уже не будет. Это общедоступный бесплатный инструмент с открытым исходным кодом и это очень мощный инструмент.
Что такое Протокол языкового сервера?
Это взаимодействие происходит с помощью набора правил, заданных протоколом. Протокол языкового сервера можно рассматривать как урезанную модификацию HTTP взаимодействующую только по JSON-RPC протоколу.
Зачем нужен LSP?
Вы заметили, что в VSCode постоянно появляются изобретательные сообщения об ошибках и предложения автоподстановок? И как же легко, просто установив расширение из магазина VSCode, вы получаете всю мощь IntelliSense для совершенно разных языков, таких как C, Python, Java и т.д.? Все это происходит благодаря LSP.
Поддержка автозавершения и IntelliSense для HTML/CSS/JavaScript идет сразу вместе с VSCode (так же, как PyCharm идет сразу с поддержкой Python). Однако такая же поддержка других языков может быть реализована с помощью протокола LSP для этих языков.
Что такое JSON-RPC?
Это простой пример для JSON-RPC:
В этом примере мы посылаем запрос в кодировке JSON в соответствии со спецификацией RPC. Если сервер настроен на корректную работу с JSON-RPC, то он выполнит метод runThisFunction с переданными параметрами и вернет результат в том виде, как показано выше.
LSP + JSON-RPC
LSP использует JSON-RPC для связи с удаленным сервером. Для этого используется следующий формат:
Почему все это так важно?
С введением формального протокола LSP, Microsoft свела знаменитую проблему M x N к проблеме M + N.
M = Различные языки (C, C++, PHP, Python, Node, Swift, Go и т.д.).
N = Различные редакторы кода (VSCode, Eclipse, Notepad++, Sublime Text и т.д.).
Раньше для того, чтобы M редакторов поддерживали N языков, вам нужно было иметь M*N решений. То есть каждый редактор кода должен был реализовать поддержку каждого языка самостоятельно.
С появлением LSP в редактор оставалось лишь внедрить поддержку протокола языкового сервера. После этого любой, кто делает языковой сервер (следуя стандартам LSP), может легко интегрироваться в редактор кода, при этом редактор никогда не будет «знать», с каким языком он работает!
Будущее IDE
По мере того, как языковые сервера реализуются для различных языков программирования, у разработчиков появляется возможность выбирать редактор на свой вкус. Без привязки к конкретному языку. Нет больше необходимости ограничивать себя, например только XCode для разработки на Swift или PyCharm для Python. И не только это, LSP можно внедрить прямо в JavaScript для поддержки IntelliSense в браузере! Настало потрясающее время для программистов!
Компьютерные сети
You are here
Тестирование путей LSP
В протоколе LSP Ping для тестирования состояния LSP применяется техника, близкая к механизму работы утилиты ping протокола IP. Она заключается в том, что протокол LSP Ping отправляет вдоль тестируемого пути LSP сообщение Echo Request. Если такое сообщение доходит до устройства LER, которое является конечным узлом тестируемого пути LSP, оно отвечает сообщением Echo Replay. Получение исходным узлом такого сообщения означает, что путь LSP работоспособен.
Описанная схема работы аналогична схеме работы утилиты ping протокола IP, однако она имеет свои особенности, которые мы поясним на примере сети, изображенной на рис. 1.
Наши партнеры:
— Возможно эта информация Вас заинтересует:
— Посмотрите интересные ссылочки вот тут:
Рис. 1. Тестирование LSP с помощью протокола LSP Ping
В этом примере устройство LSR1 тестирует состояние пути LSP1, который заканчивается на устройстве LSR8 (для этого пути оно является устройством LER).
Для тестирования пути LSP1 устройство LSR1 отправляет MPLS-пакет с меткой 105 — эта метка соответствует пути LSP1 на линии между устройствами LSR1 и LSR4. Сообщение Echo Request вкладывается в UDP-сообщение, которое, в свою очередь, вкладывается в IP-пакет. На рис. 20.12 показаны только значимые для изучения протокола LSP Ping поля: метка MPLS-кадра, IP-адрес источника (SA), IP-адрес назначения (DA), а также поле FEC, которое идентифицирует тестируемый путь LSP. В нашем примере это IP-адрес сети 105.0.0.0, к которой ведет путь LSP1.
Адрес назначения в IP-пакете, который переносит сообщение Echo Request, равен 127.0.0.1, то есть является адресом обратной петли стека протоколов IP каждого узла. О причине использования такого необычного адреса назначения (а не, скажем, IP-адреса интерфейса конечного узла тестируемого пути LSP) мы расскажем позже, а пока заметим, что адрес 127.0.0.1 должен работать правильно, так как в процессе передачи запроса по сети для его продвижения используются MPLS-метки, а не IP-адрес назначения. При приходе на конечный узел IP-пакет освобождается от заголовка MPLS (это также может произойти на предыдущем хопе, если применяется техника PHP) и обрабатывается на основе IP-адреса. Так как адрес 127.0.0.1 указывает на собственный узел, то пакет передается собственному стеку TCP/IP, где он распознается как UDP-пакет протокола LSP Ping и обрабатывается соответственно.
Поле FEC посылается в запросе Echo Request для того, чтобы конечный узел пути мог сравнить указанное в пакете значение FEC со значением из его собственной базы данных для пути, по которому пришел кадр запроса. Такой механизм позволяет отслеживать ситуации, когда запрос вследствие каких-то ошибок приходит не по тому пути, который тестируется.
В том случае, когда запрос благополучно доходит до конечного узла пути, и тот убеждается, что полученный запрос пришел по нужному пути (то есть полученное значение FEC совпадает со значением FEC из базы данных конечного узла), он отправляет ответ Echo Replay узлу, выполнившему запрос. В нашем случае узел LSR8 отправляет ответ Echo Replay узлу LSR1. Сообщение Echo Replay посылается уже не по пути LSP, а как обычное UDP-сообщение, вложенное в IP-пакет. Если вспомнить, что пути LSP являются однонаправленными, станет понятно, что это единственное гарантированное решение, так как обратного пути от LSR8 к LSR1 может и не существовать.
Теперь посмотрим, что происходит в том случае, когда по какой-то причине путь LSP поврежден. На рис. 2 представлен именно такой случай, когда путь поврежден на последнем своем участке (между устройствами LSR7 и LSR8).
Рис. 1. Тестирование неисправного пути LSPc помощью протокола LSP Ping
В этой ситуации LSR7 не может отправить MPLS-кадр по назначению, как того требует метка 177, а отбрасывает заголовок MPLS и старается обработать кадр как IP-пакет. Как и в случае исправного пути, адрес 127.0.0.1 требует передачи пакета локальному стеку TCP/IP. Именно этого эффекта и добивались разработчики протокола LSP Ping, выбирая в качестве адреса назначения этот специальный адрес. Узел LSR7 обрабатывает сообщение Echo Request и отправляет сообщение Echo Replay узлу LSR1 с информацией об обнаруженной ошибке.
Как протокол языкового сервера LSP влияет на будущее IDE
В 2016 году компания Microsoft сделала две очень важные для разработчиков вещи — выпустила редактор Visual Studio Code, который разом изменил всю экосистему для программистов, а также представила протокол языкового сервера LSP. Мы перевели статью сервиса FreeCodeCamp — о том, как LSP меняет будущее IDE, в том числе и Visual Studio Code, и почему этого никто не замечает.
Что такое LSP?
Протокол языкового сервера (LSP) — это способ (или протокол) общения с языковыми серверами, такой же как HTTP или FTP. Языковые серверы — это специальные программы, которые работают на обычных серверах. Они принимают мета-состояние редактора, в котором пишется код: например, где находится курсор в редакторе и на что он наведён прямо сейчас. После анализа они возвращают набор инструкций, какое действие можно выполнить на текущем токене, если пользователь использует специальные сочетания клавиш.
Эта связь происходит с использованием набора правил, определенных протоколом. Протокол языкового сервера можно рассматривать как урезанную версию HTTP, который обменивается данными только через JSON-RPC.
Зачем нужен LSP?
Вы постоянно видите сообщения об ошибках и автопредложения для изменения кода, которые появляются в VSCode? Как так получается, что просто добавив расширение из магазина VSCode, вы получите всю мощь технологии автодополнения IntelliSense для совершенно другого языка, такого как C, Python, Java? Как раз это и происходит из-за LSP.
Поддержка автозаполнения и IntelliSense для HTML/CSS/JavaScript поставляется с VSCode (так же, как PyCharm поставляется с поддержкой Python). Однако такая же поддержка других языков может быть реализована с использованием протокола языкового сервера для этих языков.
Что такое JSON-RPC?
JSON-RPC означает удаленный вызов процедуры JSON. Эта архитектура аналогична архитектуре REST, в которой основной единицей является вызов процедуры, а не конечная точка API, как в случае с REST.
В этом примере мы отправляем полезные данные в кодировке JSON в соответствии со спецификацией RPC. Если сервер корректно настроен для обработки JSON-RPC, он выполнит метод runThisFunction с переданными параметрами, после чего вернет результат, как показано в примере выше.
LSP + JSON-RPC
LSP использует JSON-RPC для связи с удаленным сервером. Это должно соответствовать такому формату:
Почему это вообще важно?
С введением протокола LSP компания Microsoft свела знаменитую M*N проблему к M+N проблеме.
M — это разные языки (C, C ++, PHP, Python, Node, Swift, Go и т. д.)
N — разные редакторы (VSCode, Eclipse, Notepad ++, Sublime Text и т. д.)
Раньше, чтобы редакторы M поддерживали N-языки, нужно было реализовать M*N решений. При этом поддержка языков должна была быть нативной. Сделав это однажды, кто угодно сможет интегрировать поддержку своего языка в редактор кода, даже если тот его «не знает». При этом во время работы с LSP редактор даже не будет знать, с каким языком сейчас работает пользователь.
Будущее IDE
По мере того, как все больше и больше языков переходят на свои языковые серверы, люди получат большое количество редакторов и смогут выбрать наилучший для себя
В будущем пользователям больше не придется использовать только XCode для разработки на Swift, или PyCharm для Python. И не только это, ведь LSP может быть реализован на JavaScript для поддержки прямо в браузере! Прекрасное будущее уже почти наступило!
Как тестировать сайты
Допустим, вы сделали сайт, но у вас нет тестировщика, который может всё проверить. Вот короткая инструкция, на что смотреть, чтобы с большой вероятностью после запуска всё было в порядке.
Когда тестирование полезно
В больших компаниях каждым пунктом из этой статьи могут заниматься целые отделы, сотрудники которых досконально проверяют каждую мелочь — руками или автоматически. Но представим, что сейчас под рукой нет IT-департамента. Что можно сделать самостоятельно и быстро, чтобы проверить, что всё работает как задумано.
Предупреждение: статья не претендует на академическую полноту, но точно поможет что-нибудь не упустить.
Всё посмотреть и прокликать
Сначала нужно проверить, что всё выглядит, как задумано заказчиком — сайт совпадает с макетом, кнопки работают и ссылки ведут, куда нужно.
Что проверять:
Иногда используют автоматические тесты, которые сравниваются отрендеренный результат кода аля интерфейс с рендер-версией приложения. Фактически, это сравнение скриншотов. Конечно, автотесты можно подготовить и для тестирования интерактивных элементов.
Фрагмент реального сайта о том, что тестирование полезно
Инструменты:
Ошибки JavaScript
Если в коде есть ошибки, их будет видно в консоли разработчика. Также там можно обратить внимание на запросы (время и коды ответов) и посмотреть размер загружаемых файлов. И если размер большой, обсудить с разработчиками оптимизацию кода на JavaScript, шрифтов и изображений.
Валидность кода
Нужно убедиться, что код удовлетворяет стандартам HTML/CSS, для этого есть специальные валидаторы. Узнайте, как проверить валидность HTML.
Веб-формы
Формы — кладезь пользовательских данных и одновременно потенциальный источник уязвимостей. Формы должны быть удобными для пользователя и безопасными для сайта.
Что проверять:
Неправильные ссылки
Проверьте, что все ссылки ведут на настоящие сайты и не ведут на 404. Для этого тоже есть несколько инструментов. На главной не должно быть ссылки на главную.
Уберите ссылку на главную с главной
Локализация
Если пользователи сайта говорят на разных языках, сайт локализуют — готовят тексты на разных языках и добавляют переключалку с флагами.
Но недостаточно проверить перевод текстов в интерфейсе, ошибок и документации — есть ещё ряд нюансов. Например, нужно проверить представление дат и времени, поддерживает ли шрифт локальные символы, и есть ли режим RTL для стран, где текст читается справа налево.
Производительность сайта
Пользователи уходят, если сайт грузится медленно. Поэтому нужно проверить, что ваш сайт не такой.
Что проверять
Иногда скорость загрузки зависит от контента, который используется на странице. Вот советы, как его оптимизировать.
Критерии качества
На курсах HTML Academy сайты верстают и готовят к публикации на основе критериев качества — длинного списка правил, который нужен, чтобы делать сразу хорошо. Критерии включают не только то, что написано в этой статье — там гораздо больше мелочей, которые должен знать хороший фронтенд-разработчик.
Делать сразу хорошие сайты
Всё, что нужно фронтендеру — на курсах HTML Academy. Научитесь всему, чтобы у тестировщиков закончилась работа.
Деконструкция LSP
Здравствуйте, меня зовут Дмитрий Карловский. А вы на канале Core Dump, где мы берём разные темы из компьютерной науки и деконструируем их по полочкам. А на этот раз мы начнём деконструировать принципы SOLID начиная с наиболее конкретного.
В далёком 1987 году Барбара Лисков сформулировала принцип разработки имени себя.
Он позволяет понять правильно вы написали полиморфный код или нет. Но прежде чем его сформулировать нам надо разобраться с некоторыми понятиями, которые входят в определение..
Отношение «супертип-подтип»
Все данные в нашей программе принадлежат тому или иному типу. Тип определяет множество возможных значений и их семантику. Один тип может полностью включать в себя другой. В таком случае второй тип является подтипом первого. Таким образом типы могу образовывать иерархию. Рассмотрим пример с числами..
Как тип целых так и тип положительных чисел по отдельности являются частными случаями типа вещественных чисел, а значит являются его подтипами. В то же время целые не включают в себя все положительные. А положительные не включают в себя все целые. Поэтому эти типы не состоят друг с другом в отношении «супертип-подтип». А вот натуральные числа являются одновременно и целыми и положительными, поэтому тип натуральных чисел является подтипом обоих этих типов.
Отношение «супертип-подтип» является транзитивным, то есть если один тип является подтипом другого, а другой — третьего, то и первый является подтипом третьего.
Сильная и слабая типизация
Тут правда необходимо иметь ввиду специфику представления значения разных типов в памяти. Например, эквивалентные значения целочисленного и вещественного типов обычно представляются разной последовательностью бит. Так что в некоторых языках эти типы не будут находиться в родственных отношениях. Однако, есть языки, умеющие автоматически преобразовывать значения из одного представления в другое — в них более узкий тип является подтипом более широкого, который позволяет хранить большее число вариантов значений.
На иллюстрации мы видим систему числовых типов в слабо типизированном языке, который умеет неявно производить преобразование типа, если это не приводит к потере информации.
Полиморфизм
Полиморфизм — это способность одного и того же кода работать с аргументами разных типов.
В данном примере, процедура draw у нас принимает на вход произвольную фигуру. И какую бы фигуру мы ей ни передали — процедура её всё равно нарисует.
Суть LSP — повсеместная ковариантность
Наконец, теперь мы можем сформулировать принцип подстановки Барбары Лисков: «любые функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом и не нарушая желаемых свойств программы».
Например, если функция принимает на вход питомца, то передать ей можно хоть кошечку, хоть собачку, а вот дикую лису нельзя, иначе откусит палец. Говоря современным языком, принцип LSP гласит: все параметры всех функций должны быть ковариантными, то есть ограничивающими дерево типов сверху относительно задекларированного для данного параметра.
Звучит вроде бы логично, однако.
Контравариантность не вписывается в LSP
Давайте рассмотрим функцию, которая принимает на вход коробку для питомца и засовывает в неё какого-то, нам не известного, питомца.
Если мы позволим передавать в неё клетку для собак, то вскоре можем столкнуться с абсурдной ситуацией, когда вытащим оттуда казалось бы собаку и скажем «Апорт», а она замяукает и нассыт вам в тапки. То есть подтип передавать в эту функцию нельзя. А вот супертип очень даже можно, ведь в клетку для животных можно засовывать хоть домашнего, хоть дикого животного. Получается своего рода инверсия LSP. То есть иерархия типов ограничивается не сверху, а снизу. Такое ограничение имеет название «контравариантность».
Виды вариантностей
Получается, что возможность подстановки одного типа вместо другого зависит не столько от типа параметра, сколько от того, что функция с этим параметром делает. И тут могут быть самые разные ограничения..
То есть, если мы хотим писать корректные программы, то мы вынуждены явно нарушать LSP во многих случаях.
Применимость LSP
Все эти разные вариантности появляются лишь когда мы изменяем какое-то состояние. Но если мы работаем лишь с чистыми функциями, которые ничего не изменяют, то ковариантность всех параметров и, как следствие, LSP мы получаем автоматически. Хотим мы того или нет — от нас это не зависит.
С другой стороны, любая небесполезная функциональная программа содержит не только чистую, но и грязную часть, где вопросы вариантности встают в полный рост.
Правильный LSP
Ладно, давайте пофантазируем и попробуем сформулировать LSP здорового человека, учитывающего все озвученные ранее нюансы.
«Функция может не знать конкретный передаваемый ей тип, но она обязана ограничить множество принимаемых типов так, чтобы ей нельзя было передать такой тип, который сломает ожидаемое поведение программы».
Звучит с одной стороны всё ещё так же размыто, как и оригинальная формулировка, а с другой — самоочевидно. Понятное дело, что если есть возможность правильно написать типы, то стоит это делать правильно.
Следовать ли LSP?
Как было показано ранее, если мы хотим писать корректные программы, то не можем следовать LSP. Ведь это принцип, а не, например, паттерн. Принципа либо придерживаются во всём, либо придерживаются чего-то другого, что лишь иногда соответствует тому принципу. Принципу нельзя придерживаться частично, так же как нельзя быть немножко беременной.
LSP, на текущий момент, — это устаревшая концепция, не учитывающая многие случаи. Поэтому применять её как руководство к действию ни в коем случае нельзя. А важно понимать вариантность ваших параметров и то, как конкретный язык программирования работает с типами.
Что ещё почитать о вариантности?
Для лучшего понимания вопроса вариантности рекомендую свою статью на эту тему. Там я доступным языком рассказываю всю эту сложную теорию, и привожу примеры кода на разных языках программирования, иллюстрирующие разные типы вариантности.
К сожалению, в современных языках поддержка вариантности находится в зачаточном состоянии. Где-то она не поддерживается вообще. Где-то вариантности жёстко захардкожены. Где-то есть куцые механизмы явного указания вариантности. И в совсем редких языках можно встретить не только автоматическое выведение типов параметров, но и выведение их вариантности, что очень круто, так как ручное разруливание вариантности порой слишком многословно.
Продолжение следует..
Если данный разбор показался вам полезным, то дайте мне об этом знать посредством лайка. А так же поделитесь ссылкой на него со своими коллегами.
Если же вы не согласны с какой-либо мыслью или, наоборот, чувствуете какую-то недосказанность и хотите дополнить своими идеями, то жду ваших комментариев.
Если вы не боитесь подискутировать со мной в прямом эфире или даже готовы стать соавтором будущих разборов, то пишите телеграмы.
Наконец, подписывайтесь на канал, чтобы не пропустить дальнейшие разборы. Нам ещё много чего с вами нужно будет обсудить.
На этом пока что всё. С вами был немножко программер Дмитрий Карловский.