From 805d4b148ae4b32657ed6a83e9a530b8b2c806ac Mon Sep 17 00:00:00 2001 From: Assaf Muller Date: Tue, 2 Jun 2015 12:21:11 -0400 Subject: [PATCH] Add devref that explains fullstack testing and its direction The goal of this doc is to communicate what are full stack tests, how they benefit you and when would you write such a test. Additionally I'd like to communicate the way forward, and gather feedback about any areas in the code that can benefit from full stack tests, and any additional thoughts! Change-Id: Ifd4ff9be0ed0184a49df6566d238c31a328cd23f --- doc/source/devref/fullstack_testing.rst | 93 ++++++++++++++++++ .../images/fullstack-multinode-simulation.png | Bin 0 -> 29718 bytes doc/source/devref/index.rst | 9 +- neutron/tests/fullstack/README | 1 + 4 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 doc/source/devref/fullstack_testing.rst create mode 100644 doc/source/devref/images/fullstack-multinode-simulation.png create mode 100644 neutron/tests/fullstack/README diff --git a/doc/source/devref/fullstack_testing.rst b/doc/source/devref/fullstack_testing.rst new file mode 100644 index 00000000000..b761e9bf401 --- /dev/null +++ b/doc/source/devref/fullstack_testing.rst @@ -0,0 +1,93 @@ +========================== +Neutron Full Stack Testing +========================== + +Why? +==== + +The idea behind "fullstack" testing is to fill a gap between unit + functional +tests and Tempest. Tempest tests are expensive to run, difficult to run in +a multi node environment, and are often very high level and provide little +indication to what is wrong, only that something is wrong. Developers further +benefit from full stack testing as it can sufficiently simulate a real +environment and provide a rapidly reproducible way to verify code as you're +still writing it. + +How? +==== + +Full stack tests set up their own Neutron processes (Server & agents). They +assume a working Rabbit and MySQL server before the run starts. Instructions +on how to run fullstack tests on a VM are available at TESTING.rst: +http://git.openstack.org/cgit/openstack/neutron/tree/TESTING.rst + +Each test defines its own topology (What and how many servers and agents should +be running). + +Since the test runs on the machine itself, full stack testing enables +"white box" testing. This means that you can, for example, create a router +through the API and then assert that a namespace was created for it. + +Full stack tests run in the Neutron tree with Neutron resources alone. You +may use the Neutron API (Keystone is set to NOAUTH so that it's out of the +picture). VMs may be simulated with a helper class that contains a container- +like object in its own namespace and IP address. It has helper methods to send +different kinds of traffic. The "VM" may be connected to br-int or br-ex, +to simulate internal or external traffic. + +Full stack testing can simulate multi node testing by starting an agent +multiple times. Specifically, each node would have its own copy of the +OVS/DHCP/L3 agents, all configured with the same "host" value. Each OVS agent +is connected to its own pair of br-int/br-ex, and those bridges are then +interconnected. + +.. image:: images/fullstack-multinode-simulation.png + +When? +===== + +1) You'd like to test the interaction between Neutron components (Server + and agents) and have already tested each component in isolation via unit or + functional tests. You should have many unit tests, fewer tests to test + a component and even fewer to test their interaction. Edge cases should + not be tested with full stack testing. +2) You'd like to increase coverage by testing features that require multi node + testing such as l2pop, L3 HA and DVR. +3) You'd like to test agent restarts. We've found bugs in the OVS, DHCP and + L3 agents and haven't found an effective way to test these scenarios. Full + stack testing can help here as the full stack infrastructure can restart an + agent during the test. + +Short Term Goals +================ + +* Multinode & Stability: + - Interconnect the internal and external bridges + - Convert the L3 HA failover functional test to a full stack test + - Write a test for DHCP HA / Multiple DHCP agents per network +* Write DVR tests +* Write L3 HA tests +* Write a test that validates L3 HA + l2pop integration after + https://bugs.launchpad.net/neutron/+bug/1365476 is fixed. +* Write a test that validates DVR + L3 HA integration after + https://bugs.launchpad.net/neutron/+bug/1365473 is fixed. + +None of these tasks currently have owners. Feel free to send patches! + +After these tests are merged, it should be fair to start asking contributors to +add full stack tests when appropriate in the patches themselves and not after +the fact as there will probably be something to copy/paste from. + +Long Term Goals +=============== + +* Currently we configure the OVS agent with VLANs segmentation (Only because + it's easier). This allows us to validate most functionality, but we might + need to support tunneling somehow. +* How do advanced services use the full stack testing infrastructure? I'd + assume we treat all of the infrastructure classes as a publicly consumed + API and have the XaaS repos import and use them. +* Currently we configure the Neutron server with the ML2 plugin and the OVS + mechanism driver. We may modularize the topology configuration further to + allow to rerun full stack tests against different Neutron plugins or ML2 + mechanism drivers. diff --git a/doc/source/devref/images/fullstack-multinode-simulation.png b/doc/source/devref/images/fullstack-multinode-simulation.png new file mode 100644 index 0000000000000000000000000000000000000000..c124e4311e3dc05194905b533b9798b453516013 GIT binary patch literal 29718 zcmcG$2UL^Wwl*wP5D*c>0D=_hAfZd>(xmsQG()c{1f&;fLICLz!+@x!Uv0`K-LvP*WheL4D)ewQD4bPh_>O zUBiX~|C;72>=HF@Bq0rFphV}CEpXpw{3zJ^UDMTw9)rT|olGbID9uw6Qo-(ly z&IunAFa+JQdpmy(4*YyffCa_;{kR=;^*J^Y_=q9MpBM9p0r$TYAppr3m&C-xETNK2 zkziu`RN6-`{E>G71BzW;T|G4O+xWy?9}0}r)k&p701J8QK4@**u1Aj^C122Vff2(K z3kz9wqT%l_cFi_mpj=H^g5h8EX2cBCazVE?Zvu_T0X|}wp#=)a=7!zMnUe-86$mF_ zkZpPcShS%adt4(5G&xM3j3LOz{T4XnRwU!&Ft_UrX2ip6j2I(84=_dmyMPglUBC#? zIgF7RTA*VXyBH%N8H^FYE?@*>7cc_!1Y-oS3m5_H{%Kq`zEJq-;g1yk^vZwVd+65|#=j0$6pg-*fvk7IH*T#uKqq}wX*PumDc4T(%nh^tiz=Ap! zTixWw{$m;_48{liO?>s*=1nN8dZx<3uer31nOaVf*V|^Q{5T23ZC;1JEG#S@i1?hi zYNKV3d6gXWbE;xz1)D18%vCIP4ErWv+~9%}$rs6mhKT<;?|t_I1z2rFgy7QM%V_J$9EZ z&|}59z1(Sn_IfiOAtNGP(18N=EE8?x<$#P9>lHom0bo@6Yjr0*>&&mOuRpSam=;01 zqnP`Wc<%3W^`D%a#5&H_<-_jA4XzAvhiTvb=vQ#!O~A$BwIQQ2{`%hM_g#Tz=7 zX5b2^NrWMPiPO2yC&WY%2N<&qs0pBGt}#WF;CD~S1N-?mfsoZ(%NDg{vYroqK2-FP=Jj0~xLV1lv-5#12hHnof^X6`Q21-dkXOoVc z=R9fdC3~}e3wc)krHcD$-BM?=*+cyP`MrC0c>BVi_ee(cX1fHL(a5WB&hMynCocfg z0&qBvdA|y6Nr={1%ol<5AAaMZ?`{PK$_egK!NRbaVO54?$-g_3<+xlUv$L~nerhS? z-SnDo_Q>r;<*HJn$zE_htwX$m=P-MgspRG8fyh;g`qBQA<;H0y%H1Vm;Z7D<2zmp{ z*$?JjMMdwq`PM^8@Pz0NTuo@I#$CSd?!$5+U*7OWJnRwPNa1)4oz!XZyg%FkBPn&B zORKPM*~%CE;Eij)*cqHlIXHg)`n%rwXGSf2uH`ozxrwl^U-Qrgts4x_RtTA3bkCc4 zI2)P6#!gS_Lvy!%RXkf;Z{k(xSvQtn>z65~7pElKeMd77OvMKog4}23WAYhop%q5@xjZ<~pX}~rQi9k>uG={`1zAX+a_S+z z;4L6lL!y^0NJ!U@2@v98RvpO>FJ6FmQ*OLIs}2`;_L-P)i923Ryv}_tO7u-I$hLcp zuG*~s`?GiYI#JuF3YGbloiLWMfK>L)JA<~1mG6c_u+ZF!NB zfXe2Tcz15O+#NG6p6PEm&JF}453cREJ83{Q#X3|ow+J9&HfWP-GZoDdF54sC(wj1% zzBJq)q4Zr_QP=y$F5`uqz9kb53AvU+IG)xA>Rs(1FnV~g40kLEv+e8d%fLf_4cu#y z{*}!sZq!=6Z<6%d4Tdd3n!nXDf_7z~mUV5vU;LE*(q+JPLl=MbIXHj!BwN}~lEW(o z*N}IWz?_TnPQ=_Sdc2h19Kq)Pwe`*7p~j)@@WXR%>KuL7eg%3}?2ansq1DqOn`iSM zIIqTM<{om7v+W5E4oEC6_E+y%7k=vzK?9qccY4L* z6N4+836@@)_mg%Io^UC!^_^+ttIHnlC$7+hpICHgQuUaY1Sp{VEKxk3AkKAihWD>u zvtz&K0`1<)SLBf!YFFTgc_W;5TlGDF0RV?+T<QUIQR^I>1-^qaB}US_$K1pVbu`&kmCUB+i468JbjA0^Au-440r+=(c#p4E}0 zvV>&$1gry77sHq|I8nH3XsK|>n%R8PrR|em*VOCw99{5oZgj1amktTsmMR!wag^*J z%AA(J8X#YNFJfu8^l_HsUC{2z7o#@_cnyW}qf-HOYO4bn5#|KRzWJsyNA`6`61ViN z!Dd|K%yr}$#L_6Y`()7dDTRj={;Esrv zUl}jEylGX&Px(|9bY;1JA!QSZhDEO#ALbGc+q!kxJ#zI-S_w=k}ZoGnK;?;k(hBZ>X^C z9Ly(w1AEQDmQ^MnNO)l)PqZ7NFhPfz=C&w;F}IeI}^` z{=98pN?;$1;>RVEUQ{Sx)l3wRxWux*`oW~qxbh*c93R(2O`#U3YRZ zGp1LvdZ={6cS>E^=+m`opcx~F-IAQ+)rqBFE0qQh*AIHCgoq9~&+m>q5}%w^Cz{%D zH}c6$wPW@bJ3hGWs^)M=^L}(y2(Ks=a_snIu%C;P!Qnb6?yO+eu-Y8vBl#)8GCb#V zdw~&%T;sTf3Cc1x07;^py5oN*LH}A@t)O;ON3xHw81ZKn{{&$V^Jdt3pP{NR-PN*9 z9b+ruk2SQA>tdn4$tR`B_koez!;9Pwb+9eA|1N|7z#oeUjuIR*;$t|S?T5%q6 z)`;!3)BLakdWiE-kLP&V3?Wu>l)eR`e?t4pIsYqW%$dvnPayd>K>dR*{~w~(F~P_m zz!o|hLe|wgGpa6`A+|rJ-NQd5CgWqKJN^AT{gwY!WMpJ)bHmI*6Am;~RM}+m08qrY z2!Cg8U~~WSs5@@fsfjy9+{^9NpvVdw{eZo-#|hmq!Dc} z77`k2>rDpiNRN3l9=&9o24GN?MNe#AVWBmJ4S=y&r$4@gzFPg7t(hePK*Ey~gkiNj zZN<>x;UVkOdMDK=T2Xlv;}wqxUju-%ZO!8kcRJ(WJIvNO_Wb_Yt(>9Uy>w?yFt2?56fb47(CX7OQ)?gB+S;nwE@0UkZ}B<&PEWaUQ>=EOTI4#U zP(4d6G#3M)R5Bp2F_@>9*XSgSmNxW?%M_I|eEcd6RkUa|FC&TcbB6}U>3;pT`tG(2N6bQl@TxVkItEOux6lWfr4#bAYaN89w zDw{fyIHO@C?tJNQF$CeUW1$twPjJ^a{(FV2AM;tazt(W88;(*ChLxmB*}*RK`STZ5 zxFfTf`8t80`PtceB!FSeW4odmk;_uUovsvyAiGB{07vNgHP=KnD2t(E*(XKhyKSk= zG?~WrPIJkN{XKE4`XT&ym466X2{zoR=hChKAR(y^(^brdA77YTEp31Ac%wt{7{ewa zCuDms?Gn{8#Zo4UzY8KpZAS~3OZ6+%4mPH{Ua(-w*yMztRV?=?&;VYPuzKV&U1izx z_3N#!l&kuk?jD7JxCLFRtx1ncLCp;;KvRk!}Qviey455lzPzn7?l)<>Pu1x z4HHanaNjZs3A=ip!MM`~(f4FA+(s<+2LuFItPExV{sh)W(2VMmAFNOS0X)DXqJ&co zrVBfpK+=n$e}+tsR`A%AT%n@%#E$w7&Aog5@Yhjr_^scvm`({QE%`CT`73{Cz7}yD z=&$;n#b4&Cu`k2Ucy#0`na96cK1wfUP$Pk1#s?e%F*w01pEfaY*#Ks@vcz6CDYL$* z4~)-tBu|re9iXt8-@JDRdRQfod&--(^c-vE951*p8xH5aMi1v8#jqAk&V-Bz-nofr9RP+$+<^y zPE#5Uum<*q(_c+-?ro=YJ$QGYflG!ZR?=N!4Xdq~>*w5_R+)E&5Nh5(KR;h<;SBWm z6CRYOgvh%DK0E=v^s89)KUHYScN6Bl|UG{Jol>CZcc0$Ww^m_Xhkj#s-Y+kbsLy;#EWJMUP! zX!8g>c_FmbDA#Z?b`vPnVn6H^_jIe}zRN)XX_-=ai@9Re#--1@ldvh#@|0OUj5Psi zvyHWtkl3zE7wRsh6n})a*#?uklTz!!R)v{?E&01EI@1oq2Ot#)v-9D?&4Hg-(5tQd z&o5V;7kG>hHwPH-pE8(V{_Cs2MDgb(2H_yVSHKt4<W4`ESkKcPcJlk((GOsvaZ`gd?N)XI-kJD z6Cle@Q5Rn%4)Xmr*a);(vtkH5J@ht!N6dyi5*SeE&pLr$IoeppY zOaM;!p*;EgF7&%S+A@hbZeg!Lv%>VCaMV8P=r13GCp2#1ApI-Vf-BdPTHCail}}G% z_lKO+nJf=lL)h`m-THwczk-&)&>7fo_E^`kuAKc|;*}8rTs&b5J~%WzEmZR0XD;9$G-RJuM1P=$%oILv0vt8X67B{L< zg059;Z)@dYp(EaNQ*RIV8>R`1>3#F5&D#T8g@@PRk)%kWmTfId{G5teFW>LOseNv{o9_9Rr=_!c zveqVq8olwV-GrU4tyAI`J$v`2LFD9ksmUJs(>yCrpypZ9ApX&1LZFXYvryc1f@Zsb*lO z!F2rBavLqZ>Bk`Q_RoX-z}~qh5h8zJd6R}iy|n0CrO_yItnt4#(!wa-YvmDf8cA zMF&hJ=ntv=@>_blRDMdQwy4;ZSerPIV*rW1{xCsirQV)1ODU!TQI$ftg!`=Go@mP1 zPJQ8si;19@6UqlGO)@l!e|yyQT(Y#kam6mjW}F(+gA`kqg*v|rUrPfGnb&t4#hMKY zoxueJ$!3b*^H!4~URdu24g0{>26Y#t-}pF;9!&kNz5$J4BZX38jh;Lc!Y$gJYdDC} zq^DlCTf02Slt|OHl1?upnmDYh7pC~6<8=9~BvR}u3P?)?4Ue*vj?2+@d-n0fi$HA4 zW1))T6_SXk)d9N<@vZhwDP7S$)<>oJ4%nh|ZM1jg^8~!@x7f83b*&;;(9TS+di*PA z%vCfq5Z@j|#1a}2PdoJ zfXl)>4u;#R5`)NXP$X?V^7%((IIi=_d_ZXVHwd;x;u0gnF)kYIc2%2 zMq^%(cFhneDrD<))v(3ChTs!L*;pP?oeY3MQ^DW@v6399?nN(-teZd@aVM4q-9d?XEMIRFJUM;-bEs8BEih-rs7+3u!yj$y#$!P z9=GniNwDfPsI|1GfCtOe`m&9fOun;wG)n=T-AE!Rz6{@e^HNs$akh~pMX@4|hfK-O z0AAzKA&@SvhJDPqi#s;vfG>iYA^P>C4MlV<%~i;lTC%Kb6CKYBC1_|LBZT3$=M}e3 z1R6RRt$?jlayK}mEBKJMPZ|e_z7Ca>dF{)l5tCwMrqYc{xgWI$)+=x@q}Npk#o3DU zD~|}T?#9tPS62Dvx?Hg_KwFUmHDwK~ zvva=%O#;P6zNiZ1mU?Oxd{M=6Yd7MTU4d0gUBVS=flwkXJcg;5lV_=o7W@0;yOI$$ zekuW)4$GD;=3KaK&X-3Cy}z!NWO*VgfK&ZGGMv&%H%e#Xs;Jb1ErYgJ{f~5pE#@jx z7S${X-T8Np*IVk62iK%k_Ko|D95E-UhJL5P{6&nq#BONu)}qEUelwM8@%6BGw0G5H zZE)eX+AmG5g=CAT3nJ&G?tw~4khmbjbzMSSikH3A;r0S>c636mZC$UGOlTFjvSl93 zLjKXH!6B^5#6E)X;7m`wcEgzvvnpYNa6*pfrG56R1Bs4bc^7la2mC9iUfr(yTEdgY zs2dr=n-T)!zOBFY*(snBiD<7duLH9x%J}=%9!_-@1CKeM5=3D0c7)UBKG7YPU)=ZS zHLdfk;9l-4^_p1n&taDCeHe{(Rg)N;owS!x%t-06heqK2^I3Q5@OLOje@`vn8*cU#z1c8mi#eJHQC}T6m(GPh!5*~z0 zO79O>iiP28&5fkt;@@Svxv|{ki$G69?GZkv}`gX5lkTe7z zIRk(Qd)867YTw-mpdP}BP4L7ZWv4+?!jQ8X-P5NC^1mQ*<2|H+#Vn%sGk}~C(^l2W z>kV~(0eCDZEHZq$(aMrC4-bPY19{t)jfMkj{)VW619ZnzqwLK#+`Mf|@~o3008s6T zx3Alax??Ls$<->?AbAt`xiS3#il%XV&dARuJuHJNjGbqEi< zsRYtJtMY9?8F_j68A{}~BjV{_Os^lp-4Y#HcX4r1Gl+lvdU13Z2`Q;Q%DU{NvZK1Q z4FC%O?PUQ{$!NsrI^0?=L(>`nQ38x(RM^PZdSg_WlrCBJAdq(b*Ao~%{5PVA9}_KO zdYl2URY>k2&`TTHB7QX7`g3&-=C50k1VA|kG#mmzGK`5L{>(cUsu{qz4TpUV)363U z1wI3eP?G_Lei|+=VCn>3%K>W3yaSW}Q&huxjB4n{Wx<~sZe7)V3kJ9yQ@5tI80X(L zNRLs0k=2j?G6KAgX(RfIOa}oC#Mr!Q*k8^3kDmTdHnV|Rk(mBmHSE9H1o|};4w3oG zU03D))gPQI?_ndAY=NXKj1BSI?R$Gbos;Z#@JEuHHw$2Op8Iy_+&t5I8u;Suk-PAb zFj@;lLr14Zd&53ze{Zkm-j^zBGHK?hZ#oNoqVMx$Po& zob{LjdCd0r*4+Ymy*7;_=F`4;Zk>blX69cGe5>1W2AKW9o{LP+;-yHW;McL2Fl_iD zk%9PGBdz&=a&pYX{D(~gix!xP7>-T=%;W!$4;CjeuK)@G44MCj-ve`d+x{%{-vs?3|5v1Z*cKB{_>1Y=q5bP`ZYo75ZJv%hk4$D> zp15;XkX-f+jZU^6?fmMsU%2?qDJZxnc{+4imJaRP<>R!UAYrhN<2)>aqoVlb zguT1uwhgNGu-VyAmE`}z0QhlMVffCueR=rFKVi1>5S;%Jy_HSy61%caV>hM>rmUvR7}i*TC^wl;evPJY%ECks{3}`7lVMYvARldy zRNXpYk54B?G#5TxIl)9CCe|CY2k(zgqz$wlG=|7f0Xse&vbE__KVgz(fA7Jm-+5CB z%?W2kruedvA-DiqDsp(&?Pj#db->wzXzK9J8TUfXcX?asmjPJ7$PWZo=DQ=Fu&AcS zH~&m+fV~Yd<~`++uN_!1ol5Kf=&8rIU)3ky^3Z@B7qf-+`BP2{?pBmGw*sJ8Z~TkB z&8URv`KCUcN-z9e>qaQm?nZ^vQ;gw+6|ScMmJczOX&rg;j8$PYF-cn52=5U z)A#Ic$s2e7YNG?Y{WM)L5n0Ih@#$G`T;R1@)z#z`UCvQ{sMvb;(+}q=m>`*QQP-Q) z{;EKL*tWvfh8JHIyV{Q0L$d$)OLyjA5HG2>WhjT>GuK}pEBRS#Evr9NKu=$deoy9G z5u z&Vaa;DjSG@Tgyp_*s1f|2NdU4Ddbf?mHPpeT;cQTg|qGK>m_{c)>7=??XDzZJEX)yq0%^Wo*N5h#zi>ubK8`j2yd038rN#0Wk_)Vu(Vx>vtE z_bT@qPny<(llXGA4?LRuP_SwH+W5nej@b)vuND|lvOZhc%M1)`P#`Z%?4%zEquh^M z$S2S>Da>XVaD6Z5yIc37*;vzTu_Sb}P~%Ba!UlCq-JIy%XA&O-H}l2p&IgpIXz5 zT9fRYpU!IY*^m=E$`l4xP`|@3Wc!jB^c#MTK);pE!i1PpI>g)4*C9kN)lXY6e>_* zdg2SrJ1$V^XMrFK)6}M4ULV0!4Q#z+oypSLDcQa2r_T3k4-CoRmDqkhfSe_U_cC1| zeT6lUAkcx045B?g5v4j_AXdwe*GMECS_VAsm3xr$7X z`4VCn&)LV=(Zt^%FY-RyQ~!t((fcL;$e2Gkk5%R*En=qDmbI;gx%@vsG3Fphp{#jeYqp zgA~PkzAJc=5yM@{nU?%|-w(lw^^>_gG+?2Z=3JZ{Rt2)h2nI<~sFIm83)~hYuqD>& zP^pMJ5Xeh1dtyE=|ImU6Aksm+B+`aU9GoTQTbxvqJm?rasE15K@6SpGrTdHY)`$iX zsHI-Rp@@O+91u!Ll}@g|NQ@fbV{X$Yg8H&2d3Gi5pmusWIh)pmF*CK#2)|QBCeAnH zIpwwmi6)1>l2np4U1D#ifo4^US(zSablbtiBLdyOGkI2Z7n>KgSgH948)*l=e_WN$ z-R5pO0k5e79H?X4M;}B_02jQA49|4@81`Y}11FJ~r8PL@t1dn={GjX}DcsU=3pF6a z4xVTQ1RHB_5!oF%tJ*14a0Y`~9Qg5RxZ&`v;t84E+55IOeBT%eF*7V7!hYs%uN6NM zLiW@Q2nO^~m(;w)TD%1qc?RN)bKS~%dmj)B0I;9F?odzlU(_$JHB-+az$#umeB2`@Q!CGqM zQnd#v;m)}f7IFp$DX{y&Mlpo1D;^kJIZZrykLBF~K>zaV_4eYoop~VKF>G&lG{SQ| z=cIS06cfodNLa2{o7rBo?rzsjsagV58U5cvI2^;Y8f+G;sM`%(%n>R-T1@9ZZ7Ca3 zBB^8A7oLEa0@}RH5H>BGDD~sdrlrA^^32=9w~=#X z#Mo?@F|1L-NYAYy5KtjC*aAKo6i?hE`Q!Y`?|m#rLHs<;!bb6i-^SGm$``_N zUXEv^&1Fx-j$vXyKVTxC-orH&`LI?G{-u%t-hqPM>R)I01MLRu`rjwP&nI4b(Dba!;fR#uw~25cAa>*?%;-3qCkCjPq5k&S4hDaI(lQF|K2a^&B70zRu+P zB?4bZx%zS}UYa39zy;PntQAk5@rcTc3I_Fwxbne|-!kuWiGn9gz*apZqo%H2ySwzXZiaxOC<+~#u0H+wDx zD?0;oTjmr^{m92zo6q*>IS-8B8)})T3Z{vhRr!WEEa6T|d@&q-^J)3xhPeH~``YId zI~l;j6efu)9!<0j_K|CuaPZ{Fz$yxhVKg@qH{r*PXz$4?q_Z5|P!%n_$k@;P1;i$e z9_AJ~K(biCQ?Yl9MsiZCZtQGOkEezRW5RX-g9$NJ*8p`jPGZLQzq68m$oT)i2LK`b z?=0Yox05)Q9nzM^~QjTvUd3&_UL zZJJ4)$$~nsxDdaE#KgY6TKQs+A*K6=hlMbqM~|NP#9uK`lg@%Nbjg)c1B=;#3asS z)Zt`r%~k~0rT`GFF!NjWKcRg1%;5DPMi&7TNElkL7@VA(6h=cJlYjuEsbo>t8WGht zqvkzV zw2ULc->rlxHAY<^L!8Du)_l%$Y7Y+q8G9=rT4?Ow<#_%cdaya0bm2FYDZX|&{x*2z zMO2O@`U{d@Y~~?JMR~=m_+Vbx2sU0s0pQjcv~D{yJy?=>VUiRlL57SsPMqix=acdR z4pvAjIZKAZMd=d_whq(8E%%(g+!A8AVMfqCTe7xK5iJ%bB*!8KrUuLGXw`sZ@^#o96`)6g+}+#TFHTa#)<7@=YpHc}d-bJ4N0>vIlA_mo-)H0{W%lU# zC&m|^#=d3HJC)(aqu#og6O||PY@M{e*Ilztd{{oMpk+$s>lF#cOT=~Zq&D46$6I9~&o-S-6YpG;~eh*%eyH9^|-q0$h;25TW+ zDcbkcmJtF8F%U&qd3Y~7 z8I?zU5xej0-Y%fw<7?+rp(Q`=ma4!{tE16g5x32%u zpE;h|2_{f!x`thn6Qvwk4+#W6w~Qe?mAm{A!DDrkrubQ_3CY*abVisKwm`;YS2Cm& zT(5?j6c5%6vAcZ~P=?MuX&Ql&yHQoe*y+ig9)s8l^-W);wnWQjk)A8B z?8iKa;3JxE-osG@+kgvpSH0f5ge-9HYL@z)wq?fA>!M@&{#m|gKT6rBSeFoUg9m&j2-RMDxt=Evhz!1W> zijg~!6(3$Z1mmvKwIampGv85u_C$zi_cT}Vlb z7$w-l8m>1h{F*ekVMh@w9wo<7MZWx)y1(agXJW2;%V^$$s+3%A$+bBuVQ7|=V3(+G zzyBn_^8J#_VwLx7h&l}(G*CUlmy`KD&8#NIR}Rm#WQqsnN$lsh-=CL6a*LXG(e~z7 z-eje;t-kZI`t|_{@_B<5i`>Ji5UH}Ck7%t!@%k9N-`JSYFZX}mAWZnq9#jo%zqa5LYxUEMJX7DQcBtD(?2#z z&9LmEGn^cLS-EaNr!s#&qjkrKw7>7wQBw_Xtev3#|5_lM}$#8VrPgXs@UwQ3NR z@4&?mAu)~vtwvw`3NyB#dmZqc97Dq6Sh@WE!{?GuTunOC&r~Iqo=;X%HF;=4 zeCAKnEHq8G?j{yhY#}bmEJY0I;;RzB5hT4XrbN2($W`5c>9O8?m4<0gZc3zfPoXyI z2sV=^!-~*D$qfqJD;ioBY(~H58lDSzzUSAGV$AyNA$>f3KZK?u!%ShA$7g=!UGbnm ze4b6pT-+v=O-6NvK8|#P94tGkSI_Bi7|5Mk4L^ppH@ZzL61E$hqe6R@NOyR}c>>@A zZd@F1PO$+IjS~Z!1p#)p^f#&> zQC-YM#hP+r(?)#cpiWED^7muHD2U6G@CG8qJt}L;ULBbO!mxp)7@< zX@3Dx+&dE~A&K!7&pn<}L#p<_guim%=09u7$X}G3)%wCRVBnN`VI0r#?=~3|lyh;d zQQz3q3sjb>;6Hx|3ao1?2O4#-NNW4Wtjqt_|1s_ z0ob{Nuk{En0rmHv#Mxg@ihLu(tdxrxI>J?}S&FM?&(tpe{71S9XvY&;D0vaX ziM5(S7mTt}z9VzL{^dm&hw*9b`v+^85)laC;O;*8%^o z#K(YC_v-p6z*w$Sy#SEL$d3@VcH$^*cKwRj$=OX0l4W{ z;BIgvJTY*kCS|T-5T59No>6HvW>~8CeZ|mxZuK7t?3khO1d!AFhaCXC;3D!b*#BRg z094?|1bhNy2!WK)mGbrPOd`NPfLlH;)G>2S?yRGQ>gt!2Ya7$mJ#~(=7=3O&3cbFr zJW=*EDIEeUu}5zJ+VP%Daj%k#Z;9MbM?60b&8#;P-F?V){tQsMCvpLJcWrZ1buxd% zy3d;jqNoscPjRdI35GfdIZVClPZ#0$kuM=1kCceUvyJqxuI^pxi>_MykeG9+C zDc{lxT#4L+2~N#vSf4l;g0u_s)s$${C9cC^58-8o)hyz_07{XYxs@*BqD5evbf0Gb zsQhk6GHpFsB>w(FOj?rsdoA^^7i9U6iN0W)7b@y`)=K2F4 zoqw#{^7mG}c$h^LdbaN|+orv6otEa*sl>anwKWT(C$o7mb8>T)4#uM-_yvbguFLfq z*ZF($^Lv1AKxk?Z=ZW{QM${_}3f+iJs>0RSB*<+!rn8r5`uN=CTs=r3>|XZqPLYi6 z^&Ha^%Fle-v|dGfiTbP%6WX|r;$A$A=PWxCGGC^ANv2o1pgMVHvMWjNI{4KZ=8G~3 z(JY-30q)(3EjJZR?lZ|sGIrV%b&BbD_GuHJ=(v%fIHHL$%M}}GL<~hI<1z%Yq295z zj*H22J7AJI6^i=Sk%e}eSXd@kc4@XE+ly*&jS8{LheNm1kMx$`wH5iQ+#j~~U zFq6KBCo4U_6fC>{%mm7=WRjI>9vCW;&}t{o^jE7kpW$E%?6FWkXmIBCI}Z@Kl;I~X zJ!^@}?i_4%P;>lB!K9$YnrNLJIRHj~1@hw1;q2y61)U7jzla!U9@`(_!8JK){dA_x ze(l1`EQarm=%tJeZ~=IYlzyu^JTQ1cS`{%|x#-@)X3fPSw}uAZ2iDO+<*!ULnfX@eM_hvR?BTYUqwzz6O!4qFeLy?`^*TcgfFIwxM& zfvAk!dt5cjm@+r~Y>CpJsNBE@yF_x;I+W+vdQRwO4yEXs{SI3lt@vrVsmuJjcjlJj zF6QlndB@+NrC{b=nO9K?@WgWv5pbn0L~-Z#{J69uKm|7~yyp{9pA4?Y+!6T@H9o&f z_JOO~8~mmc{OTGIRFczj6{HLxVLrNji~TmrrNiN-%KnkY?nga9=9 zHLtbeBw*|<{gt*IMhpKO>&e{b(PO`q(Dc0R`yHweDNyt443D%KU#Un0n3}EZn)W-q zR?y_7QR4;mp|1hqP_Cgi#}LOv0eJD37%7z)qvO2q{fS6$+gGsF1RwYyGn7~EZHsfL zmE=QeJZR!V!TqNmk~LSmy%|CgoS4w{!<=SH({y~mhE7Dqs{`X#zccbi*e-gKcgsnPdHd~D^MG{g=F5;yTgj1(i}$X)*GE^wuiMffv>mgH%X z!%3SILgjfySwNmzSDn`FC$_YO;Ns~VTp_OFpAM2L3xu}V{ty-viVc#zsPz>4=lPbO zAL^r>S$}V?*WU1TGeosHS0C~7rJp;r$JJ*>mesPy2Ctfv2KL5l1-u^;kbfcgATUHN&#*^g!(;H^@dCA}PTtD}Kc|YQO)J(b+m%Xsw z*vMn37xhfj>(=SRD@f69a91${5Ev%I;!B8NuYi~zaPN^c!eBlhWiws{;`}RuNBwFD zz#a@AvgO-$9s#NySgOO9Io4&)#?nbq$G@>wo^pORIS>?bMmgI)`n=QLON=uD1m-rm zNLV=(R6I;~9Q&xq;lbqB08oWNNh5sh(JC2kq0Gg7TLTGsB}wWG*|jkf5xe5 zvR1?WC;s?<6*K$?nK@$r3319>0$RU+&9-m{>aE zSpy&NMF?tqF!WeWRJcQLJbO>G$8Kz`{Ui$$6VsXp0GGC%fta!^lh*Bax6PRZAjZc6 zeB}Zij!~SaXKekRab`boS)^)j8P$Uc8-MdYHSUQ`!ylb|=)0Q_mB`&CCMM1s=9in; z27u?)z=p{`_zDCFwXdyvkkpAiG3LK)v;d^FX~ckJCholL!uZvZpW59S%teH_3hxz# zp44bxF^`pR$L#IX#}vle##s>94M_l1Tp>dnS^F$iB;+f#@s*5{zC8Yx#T(;-^}nJvPDuA5Wf{k zO@G!dEa=Js@O|W;&~OalXqXMl5}b;kLuxPckXsoeSs@Aj@Ks==_#QuJ*J&bG$}N6g z;QBUZtpRYjnQVCDiE{tshee`=Ghb~6uA0Iu8YNGj#*ep|M>mwufK&YH1c-d1Z@0TV zknm(|4oE;^E&~|dcrH=cPipM+?IYRWodhPNxR&n}fNwY&%#{k9uM-e$#zc!7r+73x z{~TWa3?Bz1Q9x1g^2Gz3fwOlOC~T;pqO>$#U^e#yjnknzz}Z6xLasrlh3#w$;}Clh)3Ll*PZ z7<;}o%$lr$$wLg)c^6Iw2iSi%S|drAv9}@>xZ~%^GkLf$HB7&3Z8!t5z*aqjtKGhu zGXji`oC&6fzgb5Y5}l^zNWd(k53w36n3WU1Tf4^oMPY2!Gelep_{5F@LAEi@^Exo1 zY;2*&%McqH=0<_Zm!N;hTLAY;*TkQB>~EA~^R~fae>np7p_RkrV;Vn@ zX_ij~S9B=WD}3&E(EhCkj{;WQU)6WYTWrm@*iKiZ_!%2#udFCs@*H>YT$IK~Ht#H` z8WZasmiFApsMEa-h#VEj0GUtrLkC&C3X_aPqi}^X=L0|u7H4{Kpws2= zfK1TOpPX&+684p6eT#VskVhJo)*tNWTUH!iU_x5L1L$wS%T?^d2?vT?t22 z84s=+oI_@tag!FJW4KhSsjLVxu(i(@ds>MOsJTb?1ugE1o}?WWQUq4Jnp&1bWY(}E z;|wO+Lme}bcnVx^abknd0n1(2+0?s1`=^*jq_1N238(VUiwxjjpO~Br&Bo+Y7>ienanm4psb@lO!rONY$?Ln?FtV8 zR3tq2%1eR!;s%@n<2B$;K?HRS@D(h1mKT5|OYk0$vqpuFdoj#>b!zajR1g>bXU!Oo zg&CyWiL_${jRs+Ji)Q1V%5Q0V%x0AO^ZuK^3@uc8b^zsi8KNRv$yupi^00ZAqx+fX z^wUwp_<ftn63z0^JDFnk+W zO;@uOI3yZo>YYuEmVqtR$piaxC*e>xO1B1KC^g}JoK;nW_pd1w8Ff!&sNxWmoP#8XAtw=#oCPIF&H|Ei4oXIloO2QoWdsHg z7;^rq0pH{K);V{ryVkuw=FjwWbx(D5)${CU?_C^ASeAo}<>5csz~tXrqkWJz%|6uM zAF8zsa^}BBT^^XUN0nJtOn%Kga1|(L@~dv!1iZ<4n>49d@4p`PPz$ZdQqesWkbiL* z>!TuOwasDvMw(ojh^`M0{%$Y;kCu7MZ)#Upqb};>O5Cg2K=ofqa?hUU91R%sn}B8R z;$LGTx3?+aYQNRgL0z(0F?9&7a;R3|2#;0SY?Vp=at87a7?AwFVC4gEb8iSq8Hp;t z8F`*2_P!+wn$0KH8o8hF+hb;C*5~{GzK6K5y1b%c$A!ezx~R=$@*BIk!RT@^6oc@V zlf&efFOU8jWhKf$XKmh6Cax~!3TT<~jxz`ul>>WJ;pi-KL-JScp`c&C<7BDH<-Z=C zdUmzrRvJ>}hZEN)TI29hvecYVZ$|e&_gZq{!K+`AedFWf1#00-`mbHK-QQnJ!h?eH#gHX9!>u>39}d#FG9%3)+(5$D$jkzi*yxQ z%bF59EHiKX>tgX^#Rf7CG|(b7F-&ceIcq2n z0?f4JM(O9l-1S?Wtl#_RZ2UdCYM;*7dp`}f?;S%uhEMpOoh7|4>9c9AO@&@4+4!2K zWo4wksg$ie{nu|4%D%mUxA5t<$cuzhUVvdj~EHv#LzR%7$A8>6h^PFTTItI50L)dJF9CtY~=RN{cQ zUB1Ch9acu|eW$kI)%|j(-SIvvLKrBa1}1=&@dUe@mo^%aX>jEwXCyEl)QT9JoNLQA zP-&x;C1?NfubZyWQqPbJLzK+SM_HPs(;9+Ulm&z0n-f%q<(&Ul2qzG>1oCdRY6lzSFBIe3in$+p zU}1ywx*v`M%7Z|GV9{P7AbOiW;#t2BD7&|3wJoQky3tO2`QBocX65Jp0rXOC_N9Hh zde2-E)Xfz}X^L{@?dWE*wMeP?o*)5=dn9_iEc_ej>gkGcEYR7$ck)X>dIvpzy0}KeAP7a> zV4^DW_P^RHLoY8w0Ky+efesNA=Ru(s$OxcHo|o&-6GB5B3}C#sPS;#QTC>+FeEd$^ z?BPI&bjpR`)_^d{g++jYPna72)@t7Ylw7E5gJJO3E%liiJvcuY8S&}iDP!XJ zzkIq@vKXl0nvW`Dr=Z7jWZ%0`}8@;<&JJ7;y3yVb?SgUJ1-|^NR7Ad;Fvq^*|8$( z#&nGZTrdw58z&i|oHg7Nb`6iZm~AJfr>EC>h_V|U92}aq?Xq==63nYfu@G;&&LtOT z)z>bSzP{sNVYN`bg-|teZ032D?DEYR){w5T3>q_5H7K>4e^~S@nWnj*4{}>D8&pH> zY>CBx3v*hU(*9D=m)7+;4r((Fw3(qBH`w1zOy_en%k3S`iw$@;$GoFsTnuI9fsR9_xzY5b^N0fK?l^)kb0xx|IGp5tk5v` z)}6x%3mR&mI?L~$3uxi3fWs?4zD=r~hMS#i<}jVAr-Kq~1vEnX<Bv=Tg?UJ30#T}Y`lie|?*ON;2OT|;$%DZC$uFj6AQb^CHP(AOcGy56Hij$_o z3s?uE*pk^Qqifmrq$dGgyUm38EZ~G(JC2*@caUr@3qB7eahDFo;>8!#Y)Jfh&Nk%~ z(#y*Uk8gHQ$>hav{eD{Av{>(VSNi(iw^wzlt&XcUTi-ryrQ}OhFBY|#(CqaIr{zP$ ztTq#zNOd%%%ei_Wy}j%keIqmG)p@dpSE{3(`_7{qHf)|~hjZx1ivz93va7xGNh=BsZAHe$n*1AfbSLglKvV#-3m><5LN{Yck+ zi*k1Qxx8Qd&z4n>+k=_NK%$kf4~~=e;SR?dfzr`oEtO0eVj1rSRqca$wh+`-{*^OC zkYK^Rknc;>Vv%s1mi@tWI)>GcFjGD$9b#a7$SV-Pp zQ?At*z1Xc^lZ+WfjYb>0)rcHyz%*(m1wtFzwReMwDiUlu6 zk8uZ$MpiF_8afrel4(Vi5y|pZ)=q=*Mk=? z>=!1`97+$O6a=r}c~P5A_QZOpx)nMp)WiwhaxEENUo1w;)aY*P0ZHalAYno2X3tf= zcz1|&lWFJ&(in|*UVz6-9Bxc7zE?x7-C4j3VqMB6C<1TQ+!FjymAZ_Xa=qZ_5CTa; zua9p>&p^5Ant%s!+yVd|;tsW&uLenilxlvVc7G`|rhTV6;Xq71?~00+64Ua|<>yh) zr(6+5sGZ2Z)^gu) z5PwolzszOhrAF=kUA%cNpOy$MUf(_YNFkokf4@h{5KVL@5WQ00t?m=&LZh`nRLmzu zGbrB`Eb}dI$T}eD>&q`$nld6_T$g7gU;Mtr( zE@OpVs*0q}+OJ&VXKrpwSkvk7<^qs!dLK=mLYF}tAaF7zy;_ZB>s%zqyD~L#l>Hnl z`t?K-gj4bVD#j^R*Ok0sz;&T`F=l6&ZqH>S)-bHCL4&AB@oso!Nbw5QdO*6g(q&i9 z1GD7sq>xx+N6pQH*#_pzK4R(b{xm0<6Q^bq?^VK0t2m042l%lk@|*Uo`Qd$Ebg4)3C`DU>VI15j)+!!S(e4n8+N zV%M>YMkbG_`^vY$bNBJdm1}A%%;4&mnPc1L+S3T0vpQ@6v@82svTL(W_hc;wJ^Iu4 z`{-ipNFODzVbSeyV_p0f_UXqh1+;1r=)!qCJ@kEYx_U) zWIxg;t6+EC=BtqWEI)T#H-ksBcRE$!{+qKMqF<(-XuD65@*CruOcn|qv6{Snz?-72 zpCK=#FA}EwUI2zT10-=2by23RQl70KmVE#2+Wdw<)QZR}PGQze!x(RL)}8U;&3!#Z z#b-x>@Y0CMs(sS_q~$7u4h|}ZjR(&YMr(>OllL|cOK=iB#E5-(jpG30djr%d##7%n z@sZmIM5tb?kD_A?G>Gc%V8c$F?&s`DD{AzXS8}zz3zuZAFpwB5?WoFb9N=&)==7~0 zSR2jLs^;5ZD*p22%iKaIXQc~}WRv~ARbhXKxNvvJoM$Ioow(L8qmKqLbrmY){&eHO zR#MiA()z?0`JK-Hy**4}J?lDBK`1It;n@>CYK9vM+}&-ISM&Bk<|0NMeXhq^X0x2E z&#mw`&@xFxyt##X0jwJ2$dht15goX!7A|FKLj$e}19u44?BUmYsE|~AYseNVj2XG% zr&u1uX5LnN4nfKd=JtF)9Z5?wx#66|r|k{v(4~C zb^DWkDs2L95~k=W+~gzIWNboclP;i+A?>mG=@ zK)B+RlHa>$#k~9Dve%%ca-F8ZMmCH48Vb;DO!qdagkY8_l5u9nMJJE!M`@2&?RqB^@s!=SIF_@Y~)lQ)f zk3!(CvAJF@aB1aD@r~@#0@F#S_ff>1zwb&A;54#Nk-$uHcB&qJv5Ppm+^GmI0c0@G zR!FrW{W~uSjD^p(iv5@S?e;~X1J*W&`Y1^*dY0Ca$ZDQ@%#_lS8Jp@L%2LKdP^Gc@ z`rG&a$hKc_+(EJH**6ECZ5k-wQ~N+glC4i8qLU+(*6319?*U^p+2$*g)*PK+ejyU> z^5P+k0}_i5(E$^XU8!VmrVR(R;yLw>7bYK(#3ne1i8BZ|%YaD~he=`|C%gUv11g$0 zeAgxcqc5)<`*3*+uVk9V=A#;Q(h_SBQtg>-#@fanQ`XuY^dfLph!%YPr4au3AZru3 zc@_x9M`Tk`*^QLJ5Ze#>bLuveY&;jbqF8YeRQMDp5K61|;HL_+ z$w#A1qFPb4AycVA2`&5fU(MK1ANwSXJ^xHCH>8e0>g0?mZLMt*`nxOlT2Z-7FcB;5 z?q$xJKF!Tm=4Bv;nMiAnP>M`;3zCJejtT%bP3qC06k@q1tKMVf1sFW~k9M#4`LZjW zM+`<`KJP!yfj6IzDfv+?lpY;bh+^AcNkR9|1{#(7t(v;y`Iid&Q@}s&<2M1944?_3 zdCbgJ{*XE+w}&Q{Cw(-8G7~dSyW^DPkh7C29y66vVHkT2=s0W=XU#;sJ#Hn;qP8k? zD4O<}_Z)ujl8kJ;C=P=J0|B^An4z6ZNh;Inu7aMZTd+-TK*puE=Mrvtp*N|!y|*nWLFe(}n2T!-|>gc4l< z(f`}GEQjz;3xyOELyvYcDEv3&YA$PQBlTr2t177ALB4Uh3lD02^m{q453&OLjDRTt z)=`go2Wfb0MdTX}VMR4^Gkj=dbX7AUpT^%?k&6$XG8bpRG(MJbft_CVoPm%FaQR8k zo*nnX30E42DJ9|OV~c;b%Ly!KM9azD^L&5`Lz;P$_}lRM@4zKW@jS8G`ErxqZ~^R? zcdys;BX(roZ0IWS?K1|2Hu3e-tyNuevw27>w<(LF_-8KxznhD63(jSf4c&}U+E-Aw z0F)c=!VyUki?(cEGmi;ISSaB+!5~!hZ@Oq&jov?VIegeEh~-vt=U7xWpe7L7P6Zd zifUNY#_5?J8#m8L@%6s$cyH2lm;zu#FyDI6baE?liv<^qEPhpv#(Yt{%XPKrs~d;u zi{tb#17xIsRQxAO7?AND>-&%Myc2o<|M381(f6NDfWGg&fQ#71f>4rE`+x*!06{+& z6(jPW1}W}8-g!<`P@)HNPAGeT($;^Doa+An`;k(nW3fxgTD|BvwaN9T$_GoA2H;;I zLnt$1#J2SUltdCQ@xVW>Bl|JoQE9#pU&F+E}x}ecG;@ze;=@Gl;4#_&DUz%4*^*~06|x*-$`|*2V*kW zKi{98d3&FT2VgBp7cz^bApq64CoTx%=e50GACwDPru)#jqwJ`v319ke^a&?9Z_ zDaNU5FqpXQ@??O;j}!1}g3iX&adT0EpHJ97bFRUg_$s~iIyTHC9-xMyBou4_A5k2z z1+te`z?74JC<4i7$O6QN7l1xS3TQQA02%I;q*fQeCK;Ys4g~~+!@6vGgA>zYouyMi6=D3B--O9xx!f7rDFz@lYaK7rr zQjIasAD$#mi)v2EM%tCgn0ND$H-j{-TIuF}=hR7!Y4g+tFC1tz1OT?+wQz%NG1qmm zRwWh9@LyEsV9c$r(XHd0@jKM&98U+uFLL9Xy2K{M zLF@qTf1GiqsI(nVcX|xz!Sm=U+LW5l+OWe^<3PjSJm#Greo<0%>i(76*2P$Db)w> zVE94Y204>RBSR?>(;Ur+JMfF)YpE?sfgVOUZ>+wyw4WHhX6Y?x0taHBn`Jn5N_f2u z+4^Fjs2+SJn*dBiHx+4&mNKEiv%Ek-mO5 z|BTKV#6Uz4>3dlQAnQfM@4 zJuoQE(`-7u6R)f=tI`*H{KmGwzzcOgGEC>R?Z-ADLk#_VNYK;1wmbWGPrEump^da} zOc6%Og>ocpt2Z1@jns8mZ;*ZnuFm_tNECfSLH1 zIN1BW(^)@YEls3APH_Xwz>o7K{LHd+uU)$)c@&_Flxmmz=D1vKG~mBmm&Gx@sCj`C z3=%y5Y7)f%cX#Y3|F?U({HG0P2I@o$Yior|A&zV2&jB!dF>makv-5fP9nz)alKSL~ z01W{jT6-QZ5g_<{B(dC^(n0-53B3kjdg971pau+qs#-#BvcaIR9%njIa1+!%fUXm~ zEC3KSts1L!b>#%=yLGBM7;_&q!2@^e0qvOtXb}T1Z-qKEvnKfE$cemlnB44e<50YP zz{u`;jP--%5b958zybya6zd;@vWdLjU@*U@3lu)IE3%xf*8}yD*1EcfMc{vMZ{2?8 zLrMdHfXr2u`hqSFgRT$jRSts7Ye?&vmSAo|`_>RTqjE}C)gbypQc_Zbu8Y7oJTvSW z7xh}n>*dL|!qOq5N%qw0PhcUE8&*7<=@<=mUQr)*5a#`AWFr8!_CZJQI0Vkm^(ME1 z+G{AXJtB3ur!<01`&dKx+BObsvyzM0un<&;6Pfkzgei^Mm}??{mTR8JW~qwPVg5rF z?u5a%{f>V8`UC3piU`GDz>I4BIrFD31EE*IuzK!+qD!U4V0pL^ct4FE%sB3v15yw@ zM1^9i?I~T)34fSxz>8?|ZzK9uG+R(Kdazv~H(GC?yOn4XRhvPwI2q?r+AoWjS6{)Sn1!V-4!a`Wf{mF8iV0(pYJ9w?f+2-z$9daoq_T zaW32T*zY25bPT^X%tE+3N36#S`b5oZ;ayg{ky=qo5EP$zAgqrQ3X|Lw4?#NtC1W_@ zC5}tqkm1cPPv+F^yQRsr))DZj&ZLTs!=>e0`lT*3P|ZT96$1U<(chsV&;lRN^drlAL;FxiN_dEqNg59hCBZ;B^H2LJ8R01xx(9iDlw$ zpQ8sgDJ^rh&zVP|Lg_93KC&9a9ZC0XWo(JFufi1+EvC7YuCRuLok3)+jc{%BWX<`z z%7Eu;-AOj%WZg4!>;B=IZ(Zhl0Y$VE2NvgcU$smu@127!uy0X6V;p*9&rkCfX_NJo zttPw}a%hh^T;-^@`WwtW;F0`m$K|18Ag$gZJYNeTr?tY&sgj5@KPNR4XE+<7%0pXY4a7Qkf4r;Q;@MV||2(kaPPzPacxB}x?nm~EX$DtG8qXOEu6twA zh=wV~ukh28t*>Mv>KEpYY6O@q2!eJCZ_2K(Tz*=&kf`2$C+v4CS~y3;3JPImeZEBT z<+Iuw67tuRH30x*RsMD-9}FIfiSU)>ZqHk~`Q^1k4Wfka(hWPeYs*({-zFVl9OIDT>Iz%Qf>FcJtbB4)7P=iPzBAkB^7%jCA_g2pgA}{#w zFzU-`1wE|81d%IscmVg9wBI)GtM-}TICpj?zISPhEmKI?TdIAZ)n#Sl&}t}B6MiUA zHCKb7e_)q!-pApf=QV56RZ%7cN^WA8=C-{}ww1=jZqdnO_tcRrXMkfK+!JD+#=gmR zPBy@)E0mTNj_C#al^6;;&Azh7(0YIkX;j}UFGhRyXy7;Po3?XacuHfxy0LguqFJw% zG`Z1x)ORL12Hrz0N6tnjdY8Fhn%}YFAs> z`lnlvyysMW$QI_>^PE%Pt583VuxG@`vDnB)*nL3ywvof(|NPVLl+3KoF!EOvIyEj0#1F3~Qicqwk(@&f&LM_9Xp8bC@M+0Hi!d}Pj2 zT_@TnCEanZMxX9~f{#E_?XiAj95>pQW-xi@TkyP8_4?v=%Tu`niaQJ!w6dvnSS=p- z(5~4`yVLOo*C}=u81e`yJv$hwcKm2`#{bQZ?O;r+%*B@W%h2NB4X_|tn8M`yJBn&U zMU-yri(wjGfuR{!&6mZx#?{yM>u5mUfKsr~b)n{kyw-Cqd!$RBNF}kt zdjnfTHP~9ayk737aE64SgnNkol&UgTRpZOBeyh7k%#!a+f{m8-vFG(;O&kPrGp%Hw z7M|@CuXJnk*}9)v#3-j|ob;rrtb4q6pybCNYt5Jl_6)kVerC|DWSINa&UHUHKJeE# z8^{^@ko%`huLR2XO>ikE`|Pszjp6seVfgiK7rDd~UFUD&SC^e9^bd4aLWHx;ovZ&0 zFxE2j&`9l2mi^x>pri)Um>A83kdydev#**@I2KpT$mSFKc+|{MOLV@lFq@| zdyHXgm&jg-s9cvs)crsWTb=)s%<3=UQhmqIu5rfT=dRMOpbm<-dFQ6wBfa}h6VmLz zYA-R%43Wm=oOy?^iH&^v{ZkIcW??y9a^|F;?|5@8eAq7tx3YHXb7Vc624I*Sr4F-D zqgt!#w)scTn!QXyb}~F^?@tFk|9lT+*ER))MLYdSnSy%hq;@yy0ihlbOZRZBTjz2H z+4!|;z|W7{rQ@{Dzb<4gSX&y7853A%emwt)v5#vbL1om2)Wx-Jgv^v5m=LQySqOL| z%xFF3lJVRHb_kOd+(v3B-kbDkSbk_naxm^HJad&<>~kO3{|LlMhew;g8%uOyzBqHf zS7=3$Uj9L=ZNvh01g*yEAH1zd2%fGLqkioS6`@E85D#7`iqMYEBR98PLL57Tgen8N z)pSh-IA!_6ST$_Too7EJG*hpCzNHZ-!ZWGyl88Qmys7WVxqfVL&{oiN&>^+E?=_;f z(_DA`Da`M~@Ni&Dt`J*duJ*p%ZZ+rL?(D|FmVN$U_#1EMAG;$1ls28TNn`)vj)jSdk-3S@XRM&v733ju#@YUYnp| zOx!ly4ZUW>R}uBIzh3ptEZ$Ewx4h*cJ8lR1nEML0P zwckbQ1`r`;@OGUEQL< zyq4MDyJpWnjTYDlmc>%tK9KL8c(WxCzZ90ZnWIpnP1s(!JhW(mSd5+69dba?L%=Y~Hv76I7Q6Z+J{jz7@X&}W6l8Qc9a WikFP;9JB){mIPe-N#0`}kN*K`(U#c& literal 0 HcmV?d00001 diff --git a/doc/source/devref/index.rst b/doc/source/devref/index.rst index 352d606a1f1..d2b263baa5f 100644 --- a/doc/source/devref/index.rst +++ b/doc/source/devref/index.rst @@ -21,7 +21,8 @@ Developer Guide In the Developer Guide, you will find information on Neutron's lower level programming APIs. There are sections that cover the core pieces of Neutron, including its database, message queue, and scheduler components. There are -also subsections that describe specific plugins inside Neutron. +also subsections that describe specific plugins inside Neutron. Finally, +the developer guide includes information about Neutron testing infrastructure. Programming HowTos and Tutorials @@ -51,6 +52,12 @@ Neutron Internals oslo-incubator callbacks +Testing +------- +.. toctree:: + :maxdepth: 3 + + fullstack_testing Module Reference ---------------- diff --git a/neutron/tests/fullstack/README b/neutron/tests/fullstack/README new file mode 100644 index 00000000000..adbbd70f275 --- /dev/null +++ b/neutron/tests/fullstack/README @@ -0,0 +1 @@ +Please see neutron/doc/source/devref/fullstack_testing.rst. \ No newline at end of file