Үздіксіз интеграция үшін Docker-те микросервистерді автоматтандырылған тестілеу

Микросервис архитектурасын дамытуға қатысты жобаларда CI/CD жағымды мүмкіндік санатынан шұғыл қажеттілік санатына ауысады. Автоматтандырылған тестілеу үздіксіз интеграцияның құрамдас бөлігі болып табылады, оған құзыретті тәсіл командаға отбасымен және достарымен көптеген жағымды кештер сыйлай алады. Әйтпесе, жоба ешқашан аяқталмау қаупі бар.

Жалған нысандармен бірлік сынақтарымен бүкіл микросервис кодын қамтуға болады, бірақ бұл мәселені ішінара ғана шешеді және көптеген сұрақтар мен қиындықтарды қалдырады, әсіресе деректермен жұмысты тестілеу кезінде. Әдеттегідей, ең өзектілері реляциялық дерекқордағы деректердің сәйкестігін тексеру, бұлттық қызметтермен жұмысты тексеру және жалған нысандарды жазу кезінде қате болжамдар жасау.

Осының барлығын және тағы басқаларын Docker контейнерінде бүкіл микросервисті сынау арқылы шешуге болады. Сынақтардың жарамдылығын қамтамасыз етудің сөзсіз артықшылығы - өндіріске кіретін бірдей Docker кескіндері сынақтан өтеді.

Бұл тәсілді автоматтандыру бірқатар проблемаларды ұсынады, олардың шешімі төменде сипатталады:

  • бір докер хостындағы параллель тапсырмалардың қақтығыстары;
  • тест итерациялары кезінде дерекқордағы идентификатор қайшылықтары;
  • микросервистердің дайын болуын күту;
  • журналдарды сыртқы жүйелерге біріктіру және шығару;
  • шығыс HTTP сұрауларын тексеру;
  • веб-розетканы тестілеу (SignalR көмегімен);
  • OAuth аутентификациясын және авторизациясын сынау.

Бұл мақалаға негізделген менің сөзім SECR 2019. Сондықтан оқуға тым жалқаулар үшін, міне сөйлеген сөзінің жазбасы.

Үздіксіз интеграция үшін Docker-те микросервистерді автоматтандырылған тестілеу

Бұл мақалада мен Docker жүйесінде сынақтан өтіп жатқан қызметті, дерекқорды және Amazon AWS қызметтерін іске қосу үшін сценарийді қалай пайдалану керектігін, содан кейін Postman жүйесіндегі сынақтарды және олар аяқталғаннан кейін жасалған контейнерлерді тоқтату және жою туралы айтып беремін. Тесттер код өзгерген сайын орындалады. Осылайша, біз әрбір нұсқаның AWS дерекқорымен және қызметтерімен дұрыс жұмыс істейтініне көз жеткіземіз.

Бірдей сценарийді әзірлеушілердің өздері Windows жұмыс үстелінде де, Linux астындағы Gitlab CI серверінде де басқарады.

Негізді болу үшін жаңа сынақтарды енгізу қосымша құралдарды әзірлеушінің компьютерінде немесе тестілеу орындалатын серверде орнатуды қажет етпеуі керек.Docker бұл мәселені шешеді.

Сынақ келесі себептерге байланысты жергілікті серверде орындалуы керек:

  • Желі ешқашан толық сенімді бола алмайды. Мың сұраудың біреуі орындалмауы мүмкін;
    Бұл жағдайда автоматты сынақ жұмыс істемейді, жұмыс тоқтатылады және журналдардан себебін іздеуге тура келеді;
  • Кейбір үшінші тарап қызметтері тым жиі сұрауларға рұқсат бермейді.

Сонымен қатар, стендті пайдалану қажет емес, себебі:

  • Стенд тек ондағы қате кодпен ғана емес, сонымен қатар дұрыс код өңдей алмайтын деректермен де бұзылуы мүмкін;
  • Сынақтың өзі кезінде сынақ жасаған барлық өзгерістерді қайтаруға қанша тырысқанымызбен, бірдеңе дұрыс емес болуы мүмкін (әйтпесе, не үшін сынақ керек?).

Жоба және процесті ұйымдастыру туралы

Біздің компания Amazon AWS бұлтында Docker жүйесінде жұмыс істейтін микросервис веб-қосымшасын әзірледі. Жобада бірлік сынақтары қолданылған, бірақ бірлік сынақтары анықтамайтын қателер жиі орын алды. Дерекқормен және Amazon қызметтерімен бірге тұтас микросервисті сынау қажет болды.

Жоба стандартты үздіксіз интеграциялау процесін пайдаланады, ол микросервисті әрбір міндеттемемен сынауды қамтиды. Тапсырманы тағайындағаннан кейін әзірлеуші ​​микросервиске өзгерістер енгізеді, оны қолмен тексереді және барлық қолжетімді автоматтандырылған сынақтарды іске қосады. Қажет болса, әзірлеуші ​​сынақтарды өзгертеді. Мәселелер табылмаса, осы мәселенің филиалына міндеттеме беріледі. Әрбір тапсырмадан кейін сынақтар серверде автоматты түрде іске қосылады. Жалпы филиалға біріктіру және оған автоматты сынақтарды іске қосу сәтті шолудан кейін орын алады. Ортақ филиалдағы сынақтар өтсе, қызмет Amazon Elastic Container Service (орындық) сынақ ортасында автоматты түрде жаңартылады. Стенд барлық әзірлеушілер мен тестерлер үшін қажет және оны бұзу ұсынылмайды. Бұл ортадағы сынақшылар қолмен сынақтарды орындау арқылы түзетуді немесе жаңа мүмкіндікті тексереді.

Жоба архитектурасы

Үздіксіз интеграция үшін Docker-те микросервистерді автоматтандырылған тестілеу

Қолданба оннан астам қызметтен тұрады. Олардың кейбіреулері .NET Core жүйесінде, ал кейбіреулері NodeJs жүйесінде жазылған. Әрбір қызмет Amazon Elastic Container Service ішіндегі Docker контейнерінде жұмыс істейді. Олардың әрқайсысында Postgres дерекқоры бар, ал кейбіреулерінде Redis бар. Жалпы мәліметтер базасы жоқ. Егер бірнеше қызметке бірдей деректер қажет болса, онда бұл деректер өзгерген кезде осы қызметтердің әрқайсысына SNS (Simple Notification Service) және SQS (Amazon Simple Queue Service) арқылы жіберіледі және қызметтер оны өздерінің жеке дерекқорларында сақтайды.

SQS және SNS

SQS HTTPS протоколы арқылы хабарламаларды кезекке қоюға және кезектен хабарларды оқуға мүмкіндік береді.

Бірнеше қызмет бір кезекті оқыса, әрбір хабарлама тек біреуіне келеді. Бұл олардың арасында жүктемені бөлу үшін бір қызметтің бірнеше данасын іске қосқанда пайдалы.

Әрбір хабардың бірнеше қызметтерге жеткізілуін қаласаңыз, әрбір алушының өз кезегі болуы керек және SNS хабарларды бірнеше кезекке көшіру үшін қажет.

SNS жүйесінде сіз тақырыпты жасайсыз және оған жазыласыз, мысалы, SQS кезегі. Тақырыпқа хабарлама жіберуге болады. Бұл жағдайда хабарлама осы тақырыпқа жазылған әрбір кезекке жіберіледі. SNS хабарламаларды оқу әдісі жоқ. Түзету немесе тестілеу кезінде SNS-ге не жіберілгенін білу қажет болса, SQS кезегін жасап, оны қалаған тақырыпқа жазып, кезекті оқуға болады.

Үздіксіз интеграция үшін Docker-те микросервистерді автоматтандырылған тестілеу

API шлюзі

Көптеген қызметтерге Интернеттен тікелей қол жеткізу мүмкін емес. Қол жеткізу рұқсат құқықтарын тексеретін API шлюзі арқылы жүзеге асырылады. Бұл да біздің қызметіміз және ол үшін де сынақтар бар.

Уведомления в реальном времени

Қолданба пайдаланады SignalRпайдаланушыға нақты уақыттағы хабарландыруларды көрсету. Бұл хабарландыру қызметінде жүзеге асырылады. Ол Интернеттен тікелей қол жетімді және өзі OAuth-пен жұмыс істейді, өйткені OAuth және хабарландыру қызметін біріктірумен салыстырғанда, Gateway ішіне веб-розеткаларға қолдау көрсету мүмкін емес болып шықты.

Белгілі тестілеу тәсілі

Бірлік сынақтары дерекқор сияқты нәрселерді жалған нысандармен ауыстырады. Егер микросервис, мысалы, сыртқы кілті бар кестеде жазба жасауға әрекеттенсе және сол кілт сілтеме жасаған жазба жоқ болса, онда сұрауды аяқтау мүмкін емес. Бірлік сынақтары мұны анықтай алмайды.

В Microsoft мақаласы Жадтағы мәліметтер базасын пайдалану және жалған объектілерді енгізу ұсынылады.

Жадтағы дерекқор - Entity Framework қолдайтын ДҚБЖ бірі. Ол тестілеу үшін арнайы жасалған. Мұндай дерекқордағы деректер оны пайдалану процесі аяқталғанша ғана сақталады. Ол кестелерді құруды қажет етпейді және деректердің тұтастығын тексермейді.

Жалған нысандар сынақ әзірлеушісі оның қалай жұмыс істейтінін түсінетін дәрежеде ғана ауыстыратын сыныпты үлгілейді.

Сынақты іске қосу кезінде Postgres-ті автоматты түрде іске қосу және тасымалдауды орындау жолы Microsoft мақаласында көрсетілмеген. Менің шешімім мұны жасайды және оған қоса, микросервистің өзіне сынақтар үшін арнайы код қосылмайды.

Шешімге көшейік

Әзірлеу барысында бірлік сынақтары барлық мәселелерді дер кезінде табу үшін жеткіліксіз екендігі белгілі болды, сондықтан бұл мәселеге басқа қырынан қарау туралы шешім қабылданды.

Сынақ ортасын орнату

Бірінші тапсырма - сынақ ортасын орналастыру. Микросервисті іске қосу үшін қажетті қадамдар:

  • Жергілікті орта үшін сыналатын қызметті теңшеңіз, орта айнымалы мәндерінде дерекқорға және AWS-ке қосылу мәліметтерін көрсетіңіз;
  • Postgres бағдарламасын іске қосыңыз және Liquibase іске қосу арқылы тасымалдауды орындаңыз.
    Реляциялық ДҚБЖ-да мәліметтер базасына деректерді жазбас бұрын деректер схемасын, басқаша айтқанда, кестелерді құру керек. Қолданбаны жаңарту кезінде кестелерді жаңа нұсқа пайдаланатын пішінге және жақсырақ деректерді жоғалтпай әкелу керек. Бұл миграция деп аталады. Бастапқыда бос дерекқорда кестелер жасау көшірудің ерекше жағдайы болып табылады. Көшіру қолданбаның өзіне енгізілуі мүмкін. .NET және NodeJS екеуінде де тасымалдау құрылымдары бар. Біздің жағдайда, қауіпсіздік мақсатында микросервистер деректер схемасын өзгерту құқығынан айырылады және тасымалдау Liquibase көмегімен жүзеге асырылады.
  • Amazon LocalStack іске қосыңыз. Бұл үйде іске қосу үшін AWS қызметтерін іске асыру. Docker Hub жүйесінде LocalStack үшін дайын кескін бар.
  • LocalStack бағдарламасында қажетті нысандарды жасау үшін сценарийді іске қосыңыз. Shell сценарийлері AWS CLI пайдаланады.

Жобада тестілеу үшін қолданылады почташы. Ол бұрын болған, бірақ ол қолмен іске қосылды және стендте орнатылған қолданбаны сынады. Бұл құрал ерікті HTTP(S) сұрауларын жасауға және жауаптардың күтуге сәйкес келетінін тексеруге мүмкіндік береді. Сұраулар жинаққа біріктіріліп, бүкіл жинақты іске қосуға болады.

Үздіксіз интеграция үшін Docker-те микросервистерді автоматтандырылған тестілеу

Автоматты сынақ қалай жұмыс істейді?

Тестілеу кезінде Docker-те барлығы жұмыс істейді: сыналған қызмет, Postgres, тасымалдау құралы және Postman, дәлірек айтқанда оның консольдық нұсқасы - Ньюман.

Docker бірқатар мәселелерді шешеді:

  • Хост конфигурациясынан тәуелсіздік;
  • Тәуелділіктерді орнату: Docker кескіндерді Docker Hub жүйесінен жүктейді;
  • Жүйені бастапқы күйіне қайтару: жай ғана контейнерлерді алып тастау.

Docker-құрастыру контейнерлерді интернеттен оқшауланған виртуалды желіге біріктіреді, онда контейнерлер бір-бірін домен атаулары бойынша табады.

Сынақ қабық сценарийімен басқарылады. Windows жүйесінде сынақты орындау үшін git-bash қолданамыз. Осылайша, Windows және Linux үшін бір сценарий жеткілікті. Git және Docker-ті жобадағы барлық әзірлеушілер орнатады. Windows жүйесіне Git орнату кезінде git-bash орнатылады, сондықтан барлығында да бар.

Сценарий келесі қадамдарды орындайды:

  • Докер кескіндерін құру
    docker-compose build
  • Деректер базасын және LocalStack іске қосу
    docker-compose up -d <контейнер>
  • Деректер базасын көшіру және LocalStack дайындау
    docker-compose run <контейнер>
  • Сынақтағы қызметті іске қосу
    docker-compose up -d <сервис>
  • Тестті орындау (Ньюман)
  • Барлық контейнерлерді тоқтату
    docker-compose down
  • Нәтижелерді Slack ішінде жариялау
    Бізде жасыл құсбелгі немесе қызыл крест және журналға сілтеме бар хабарламалар өтетін чат бар.

Келесі Docker кескіндері осы қадамдарға қатысады:

  • Тексерілетін қызмет өндіріске арналған кескінмен бірдей. Сынақ үшін конфигурация орта айнымалылары арқылы жасалады.
  • Postgres, Redis және LocalStack үшін Docker Hub-дан дайын кескіндер пайдаланылады. Сондай-ақ Liquibase және Newman үшін дайын суреттер бар. Біз өз файлдарымызды олардың қаңқасына салып, сол жерге файлдарымызды қосамыз.
  • LocalStack дайындау үшін сіз дайын AWS CLI кескінін пайдаланасыз және оның негізінде сценарийі бар кескінді жасайсыз.

Пайдалану көлемі, контейнерге файлдарды қосу үшін ғана Docker кескінін жасаудың қажеті жоқ. Дегенмен, көлемдер біздің ортамызға сәйкес келмейді, себебі Gitlab CI тапсырмаларының өзі контейнерлерде орындалады. Docker-ті осындай контейнерден басқара аласыз, бірақ томдар басқа контейнерден емес, тек хост жүйесіндегі қалталарды орнатуға болады.

Сіз кездесуі мүмкін мәселелер

Дайындықты күту

Қызметі бар контейнер жұмыс істеп тұрғанда, бұл оның қосылымдарды қабылдауға дайын екенін білдірмейді. Байланыстың жалғасуын күтуіңіз керек.

Бұл мәселе кейде сценарий арқылы шешіледі wait-for-it.sh, ол TCP қосылымын орнату мүмкіндігін күтеді. Дегенмен, LocalStack 502 Bad Gateway қатесін жіберуі мүмкін. Сонымен қатар, ол көптеген қызметтерден тұрады және олардың біреуі дайын болса, бұл басқалары туралы ештеңе айтпайды.

шешім: SQS және SNS екеуінен де 200 жауапты күтетін LocalStack дайындау сценарийлері.

Параллель тапсырма қақтығыстары

Бірнеше сынақтар бір Docker хостында бір уақытта жұмыс істей алады, сондықтан контейнер мен желі атаулары бірегей болуы керек. Сонымен қатар, бір қызметтің әртүрлі филиалдарының сынақтары да бір уақытта жұмыс істей алады, сондықтан олардың атын әрбір құрастыру файлына жазу жеткіліксіз.

шешім: Сценарий COMPOSE_PROJECT_NAME айнымалы мәнін бірегей мәнге орнатады.

Windows мүмкіндіктері

Windows жүйесінде Docker қолданбасын пайдаланған кезде мен бірнеше нәрсені атап өткім келеді, себебі бұл тәжірибелер қателердің неліктен орын алғанын түсіну үшін маңызды.

  1. Контейнердегі қабық сценарийлерінің Linux жолының соңы болуы керек.
    Қабық CR таңбасы синтаксистік қате болып табылады. Қате туралы хабардан бұл жағдай екенін айту қиын. Windows жүйесінде мұндай сценарийлерді өңдеу кезінде сізге тиісті мәтіндік редактор қажет. Бұған қоса, нұсқаны басқару жүйесі дұрыс конфигурациялануы керек.

git осылай конфигурацияланады:

git config core.autocrlf input

  1. Git-bash стандартты Linux қалталарын эмуляциялайды және exe файлын (соның ішінде docker.exe) шақырған кезде абсолютті Linux жолдарын Windows жолдарымен ауыстырады. Дегенмен, бұл жергілікті құрылғыда емес жолдар үшін (немесе контейнердегі жолдар) мағынасы жоқ. Бұл әрекетті өшіру мүмкін емес.

шешім: жолдың басына қосымша қиғаш сызықты қосыңыз: //bin орнына /bin. Linux мұндай жолдарды түсінеді; ол үшін бірнеше қиғаш сызықтар біреумен бірдей. Бірақ git-bash мұндай жолдарды танымайды және оларды түрлендіруге тырыспайды.

Журнал шығысы

Сынақтарды іске қосқан кезде мен Ньюманның журналдарын да, тексерілетін қызметтен де көргім келеді. Бұл журналдардың оқиғалары өзара байланысты болғандықтан, оларды бір консольде біріктіру екі бөлек файлға қарағанда әлдеқайда ыңғайлы. Ньюман арқылы іске қосылады докер-құрастыруды іске қосу, сондықтан оның шығысы консольде аяқталады. Қызметтің нәтижесі де сол жаққа кететініне көз жеткізу ғана қалады.

Бастапқы шешім жасау болды доккер-құрастыру жалауы жоқ -d, бірақ қабық мүмкіндіктерін пайдаланып, бұл процесті фондық режимге жіберіңіз:

docker-compose up <service> &

Бұл Docker журналдарын үшінші тарап қызметіне жіберу қажет болғанша жұмыс істеді. доккер-құрастыру журналдарды консольге шығаруды тоқтатты. Дегенмен, команда жұмыс істеді доккер бекітіңіз.

шешім:

docker attach --no-stdin ${COMPOSE_PROJECT_NAME}_<сервис>_1 &

Сынақ итерациялары кезінде идентификатор қайшылығы

Тесттер бірнеше итерацияда орындалады. Деректер базасы тазартылмаған. Дерекқордағы жазбалардың бірегей идентификаторлары болады. Сұранымдардағы нақты идентификаторларды жазсақ, біз екінші итерацияда қайшылық аламыз.

Оны болдырмау үшін идентификаторлар бірегей болуы керек немесе сынақ арқылы жасалған барлық нысандар жойылуы керек. Кейбір нысандарды талаптарға байланысты жою мүмкін емес.

шешім: Postman сценарийлерін пайдаланып GUID жасау.

var uuid = require('uuid');
var myid = uuid.v4();
pm.environment.set('myUUID', myid);

Содан кейін сұраудағы таңбаны пайдаланыңыз {{myUUID}}, ол айнымалының мәнімен ауыстырылады.

LocalStack арқылы бірлесіп жұмыс істеу

Егер тексерілетін қызмет SQS кезегін оқитын немесе жазатын болса, оны тексеру үшін сынақтың өзі де осы кезекпен жұмыс істеуі керек.

шешім: пошташыдан LocalStack-қа сұраулар.

AWS қызметтерінің API құжатталған, бұл сұрауларды SDKсіз жасауға мүмкіндік береді.

Егер қызмет кезекке жазса, біз оны оқып, хабарламаның мазмұнын тексереміз.

Егер қызмет SNS хабарларын жіберсе, дайындық кезеңінде LocalStack де кезек жасайды және осы SNS тақырыбына жазылады. Содан кейін бәрі жоғарыда сипатталғанға түседі.

Егер қызметке кезектен хабарды оқу қажет болса, онда алдыңғы сынақ қадамында біз бұл хабарламаны кезекке жазамыз.

Тексеріліп жатқан микросервистен алынған HTTP сұрауларын сынау

Кейбір қызметтер HTTP арқылы AWS емес басқа нәрсемен жұмыс істейді, ал кейбір AWS мүмкіндіктері LocalStack ішінде іске асырылмайды.

шешім: бұл жағдайларда ол көмектесе алады MockServer, оның ішінде дайын кескіні бар Докер хабы. Күтілетін сұраулар мен оларға жауаптар HTTP сұрауы арқылы конфигурацияланады. API құжатталған, сондықтан біз пошташыдан сұраулар жасаймыз.

OAuth аутентификациясын және авторизациясын сынау

Біз OAuth және пайдаланамыз JSON веб-токендері (JWT). Сынақ үшін жергілікті түрде іске қоса алатын OAuth провайдері қажет.

Қызмет пен OAuth провайдері арасындағы барлық өзара әрекеттестік екі сұрауға түседі: біріншіден, конфигурация сұралады. /.жақсы белгілі/openid-конфигурация, содан кейін конфигурациядағы мекенжайда ашық кілт (JWKS) сұралады. Мұның бәрі статикалық мазмұн.

шешім: Біздің сынақ OAuth провайдері – статикалық мазмұн сервері және ондағы екі файл. Токен бір рет жасалады және Git-ке бекітіледі.

SignalR тестілеуінің мүмкіндіктері

Пошташы веб-розеткалармен жұмыс істемейді. SignalR сынау үшін арнайы құрал жасалды.

SignalR клиенті шолғыштан көп болуы мүмкін. Ол үшін .NET Core астында клиент кітапханасы бар. .NET Core жүйесінде жазылған клиент қосылымды орнатады, түпнұсқалығы расталады және хабарлардың белгілі бір тізбегін күтеді. Егер күтпеген хабарлама алынса немесе қосылым жоғалса, клиент 1 кодымен шығады. Егер соңғы күтілетін хабарлама алынса, клиент 0 кодымен шығады.

Ньюман клиентпен бір уақытта жұмыс істейді. Хабарламалар қажет болғандардың барлығына жеткізілуін тексеру үшін бірнеше клиенттер іске қосылады.

Үздіксіз интеграция үшін Docker-те микросервистерді автоматтандырылған тестілеу

Бірнеше клиентті іске қосу үшін опцияны пайдаланыңыз --масштаб docker-compose пәрмен жолында.

Іске қосу алдында Postman сценарийі барлық клиенттердің қосылымдарды орнатуын күтеді.
Біз қосылымды күту мәселесіне тап болдық. Бірақ серверлер болды, міне, клиент. Басқа көзқарас қажет.

шешім: контейнердегі клиент механизмді пайдаланады Денсаулықхосттағы сценарийге оның күйі туралы хабарлау. Байланыс орнатылған бойда клиент белгілі бір жолда файл жасайды, айталық /healthcheck. Docker файлындағы HealthCheck сценарийі келесідей көрінеді:

HEALTHCHECK --interval=3s CMD if [ ! -e /healthcheck ]; then false; fi

команда докер тексереді Контейнердің қалыпты күйін, денсаулық күйін және шығу кодын көрсетеді.

Ньюман аяқтағаннан кейін сценарий 0 коды бар клиенті бар барлық контейнерлердің тоқтатылғанын тексереді.

Бақыт бар

Жоғарыда сипатталған қиындықтарды жеңгеннен кейін бізде тұрақты жұмыс сынақтары болды. Сынақтарда әрбір қызмет дерекқормен және Amazon LocalStack-пен өзара әрекеттесетін бір бірлік ретінде жұмыс істейді.

Бұл сынақтар 30+ әзірлеушілер тобын жиі қолданылатын 10+ микросервистердің күрделі өзара әрекеттесуі бар қолданбадағы қателерден қорғайды.

Ақпарат көзі: www.habr.com

пікір қалдыру