From 27466143f9715b5f3c3e3a4ca40b443dbd8bac7d Mon Sep 17 00:00:00 2001 From: Lee Yang Date: Fri, 6 Sep 2024 16:41:18 -0700 Subject: [PATCH 1/2] Add documentation for qualx plugins (#1337) Signed-off-by: Lee Yang --- user_tools/docs/qualx.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/user_tools/docs/qualx.md b/user_tools/docs/qualx.md index c580cd903..814625d1a 100644 --- a/user_tools/docs/qualx.md +++ b/user_tools/docs/qualx.md @@ -135,6 +135,7 @@ spark_rapids train \ Once satisfied with the model, just supply the path to this model in the `--custom_model_file` argument for prediction. +### Training (Advanced) #### Fine-tuning / Incremental Training To continue training an existing pre-trained model on new data, just set up the new dataset per above and then @@ -178,3 +179,42 @@ df.to_csv('features/features_with_label.csv', index=False) Then, train a custom model with the `--features_csv_dir features` argument. Once satisfied with the model, just supply the path to this model in the `--custom_model_file` argument for prediction. + +#### Dataset-specific Plugins + +In certain situations, a dataset may require custom handling. For these cases, we provide a plugin mechanism +for custom code that can be attached to that dataset. The plugin implementation is just a python file that defines +any of the following functions: +```python +import pandas as pd + +def load_profiles_hook(profile_df: pd.DataFrame) -> pd.DataFrame: + """Custom post processing on the load_profiles dataframe.""" + # Insert custom code to modify the profile_df as needed. + # Note: profile_df contains "raw" features extracted from the Profiler tool's output CSV files. + return profile_df + + +def split_function(cpu_aug_tbl: pd.DataFrame) -> pd.DataFrame: + """Custom train/test/val split function.""" + # Insert custom code to set cpu_aug_tbl['split'] to 'train', 'test', or 'val'. + # Note: the default split function randomly splits the data by ratios of 60/20/20. + return cpu_aug_tbl +``` + +In order to use a custom plugin, just reference it in the associated dataset JSON file: +``` +# datasets/onprem/my_custom_dataset.json +{ + "my_custom_dataset": { + "eventlogs": [ + "/path/to/eventlogs" + ], + "app_meta": { + ... + }, + "load_profiles_hook": "/path/to/custom_plugin.py", + "split_function": "/path/to/custom_plugin.py" + } +} +``` \ No newline at end of file From 71601e13de68821a3e6829dec73f82135b28cad3 Mon Sep 17 00:00:00 2001 From: Partho Sarthi Date: Tue, 10 Sep 2024 16:12:05 -0400 Subject: [PATCH 2/2] Add end-to-end behavioural tests for the python CLI (#1313) * Add python e2e tests with behave Signed-off-by: Partho Sarthi * Add e2e test for HDFS platform Signed-off-by: Partho Sarthi * Updates tests, docs and fix styling Signed-off-by: Partho Sarthi * Remove unused subprocess Signed-off-by: Partho Sarthi * Remove separate tox env for github actions Signed-off-by: Partho Sarthi * Update docs Signed-off-by: Partho Sarthi * Refactor feature files Signed-off-by: Partho Sarthi * Address review comments Signed-off-by: Partho Sarthi * Improve current file path calculation Signed-off-by: Partho Sarthi * Address review feedbacks - Add E2E_TOOLS prefix - Fail if HDFS already running - Add verbose output - Move util functions to class Signed-off-by: Partho Sarthi * Update docs about verbose mode Signed-off-by: Partho Sarthi * Fix logger Signed-off-by: Partho Sarthi * Fix flake8 Signed-off-by: Partho Sarthi * Address review comments Signed-off-by: Partho Sarthi --------- Signed-off-by: Partho Sarthi --- scripts/header-check.sh | 3 +- .../docs/resources/debug-behave-intellij.png | Bin 0 -> 41370 bytes user_tools/docs/tools_e2e_tests.md | 172 +++++++++++++ user_tools/pyproject.toml | 2 +- .../features/environment.py | 119 +++++++++ .../features/event_log_processing.feature | 43 ++++ .../features/hdfs_storage.feature | 88 +++++++ .../features/installation_checks.feature | 44 ++++ .../features/steps/e2e_utils.py | 225 ++++++++++++++++++ .../features/steps/test_steps.py | 172 +++++++++++++ .../resources/event_logs/gpu_eventlog.zstd | Bin 0 -> 24489 bytes .../incorrect_app_status_eventlog.zstd | Bin 0 -> 21951 bytes .../event_logs/join_agg_on_yarn_eventlog.zstd | Bin 0 -> 53749 bytes .../resources/event_logs/photon_eventlog.zstd | Bin 0 -> 59430 bytes .../event_logs/streaming_eventlog.zstd | Bin 0 -> 22591 bytes .../resources/scripts/common.sh | 24 ++ .../resources/scripts/hdfs/cleanup_hdfs.sh | 52 ++++ .../resources/scripts/hdfs/setup_hdfs.sh | 195 +++++++++++++++ .../scripts/hdfs/templates/core-site.xml | 26 ++ .../scripts/hdfs/templates/hdfs-site.xml | 30 +++ .../resources/scripts/setup_env.sh | 66 +++++ user_tools/tox.ini | 30 ++- 22 files changed, 1285 insertions(+), 6 deletions(-) create mode 100644 user_tools/docs/resources/debug-behave-intellij.png create mode 100644 user_tools/docs/tools_e2e_tests.md create mode 100644 user_tools/tests/spark_rapids_tools_e2e/features/environment.py create mode 100644 user_tools/tests/spark_rapids_tools_e2e/features/event_log_processing.feature create mode 100644 user_tools/tests/spark_rapids_tools_e2e/features/hdfs_storage.feature create mode 100644 user_tools/tests/spark_rapids_tools_e2e/features/installation_checks.feature create mode 100644 user_tools/tests/spark_rapids_tools_e2e/features/steps/e2e_utils.py create mode 100644 user_tools/tests/spark_rapids_tools_e2e/features/steps/test_steps.py create mode 100644 user_tools/tests/spark_rapids_tools_e2e/resources/event_logs/gpu_eventlog.zstd create mode 100644 user_tools/tests/spark_rapids_tools_e2e/resources/event_logs/incorrect_app_status_eventlog.zstd create mode 100644 user_tools/tests/spark_rapids_tools_e2e/resources/event_logs/join_agg_on_yarn_eventlog.zstd create mode 100644 user_tools/tests/spark_rapids_tools_e2e/resources/event_logs/photon_eventlog.zstd create mode 100644 user_tools/tests/spark_rapids_tools_e2e/resources/event_logs/streaming_eventlog.zstd create mode 100755 user_tools/tests/spark_rapids_tools_e2e/resources/scripts/common.sh create mode 100755 user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/cleanup_hdfs.sh create mode 100755 user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/setup_hdfs.sh create mode 100644 user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/templates/core-site.xml create mode 100644 user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/templates/hdfs-site.xml create mode 100755 user_tools/tests/spark_rapids_tools_e2e/resources/scripts/setup_env.sh diff --git a/scripts/header-check.sh b/scripts/header-check.sh index 22a1847fc..b9c7d2325 100755 --- a/scripts/header-check.sh +++ b/scripts/header-check.sh @@ -26,9 +26,10 @@ EXCLUDE_PATTERNS=( "core/src/main/resources/*" "core/src/test/resources/*" "user_tools/src/spark_rapids_pytools/resources/*" - "user_tools/docs/resources/*" + "user_tools/docs/*" "user_tools/tests/spark_rapids_tools_ut/resources/*" "*.csv" + "*.zstd" ) # Create the grep exclude options (--exclude=*csv --exclude=core/src/test/resources/*) diff --git a/user_tools/docs/resources/debug-behave-intellij.png b/user_tools/docs/resources/debug-behave-intellij.png new file mode 100644 index 0000000000000000000000000000000000000000..a21c6958726b99ef21da54b0b1674c420a10fd20 GIT binary patch literal 41370 zcmd?QXH-*d+bzmt1!;CVhz;oh=~d(rL;@(iV?;!xm(T-BRcR^$p^HE;^j<;$B?3x- z2nnHs5CTG^C4`=22YtVNzP-<%{p*Z9#uL*IlkM=e*Xd`^Ng5r}$5?u&{6% z-2K;-h2^*z3(G$VtS6XPdKpLRSy-O482qba9_;vgYO%xO&fMDW{;zG>$z2gxq#oc! zjP3y6Ro1&)5+5%=0X$bNfL`z)_{SgbrCa8Sx13mYf`%9&wg+;97Y+J%aWzWdXC>ex zKF=}H+oazX4MUEg{DzKJ%L+#Ilm5MGgxOx}GwS$G5H$;|=m2(832O_*sD#C}E?dzY zMWv%~Bnn{h_sY9c05I*(@81=j;xN1R*BJZ=%KSfO zOFtjpDrA~0B41wVafvtlH(QO_ey#oCh@U}F2?JAY)!#1*oq5v_W~;A|x|g`wFXjmj zjMu9IGnK9!P-gYPcGpqFofUw{LeuxGZhBp){RdpFC%gH?f2Cw#j?vz z^LHm_^IDeMo(r7XzNNCVd2_jYDqk-kk!yRhRq}Uph-=kW0rOdlAcv1%6an}JB{<*B zXeA7^c3#VH6pl*~v`~(4viD!1`qE=cGwcIHnp~zsMl^jh*-acxl^t%9Or}nkv<0KD zF`oim)5HCWWbhn{&%NY3HxCCBw(!+w3Og$uwnrAUA>F^LcaiLK?&%K69aVxMn{puH za>F2VVPCmmT?dwIF#}Z1&~;xh_AYZJ_<0YPZuw-)qmY-O`$9qZxDX@uKEJH#hg#y7 zt`@b0Ph4m?y*ll%4Q98rs&KSYhFsZK0}?guA^qT~Mw3$(A>7VACZ*Xh<%NDH-bI7Y z8c!x;Moo8O3Q(x;2_|Fi(x9?Sca7I_FT&ps@~2UAl^~W=JBK@Xg6nXn_H=|{e(I`U z98OVgm3?a6hAv@ zTV#D>1cfI@aONa-rkSu{tw(y$T{sbi#i-mIAgqS1a!ynsB~BE$X-!l$%j10ow9${- zY-H9F(p!+2dckf1ZC^j@c0X``(hl ztORwh^tL~ovNpDroxbV7oyd=ESQ|UJM9Wo(d@$Nb>)o05ZmuCgVE478Gay;rAfZt! z92SvQDe!c~@P7ZEj6>t2DzK&~(*uMg{%))b^d8@=gD~vu_(mwIyY3ML$w}J|y{)#l z4MZJ#c8biFCpX9bVN7fs4`1D_$vF*>b#0ZlK}hxGXex7g zx6Rk82$TG=$#%~uhLF~?_ORLm#fhgI?_3%HX`Tj#)=>*du6aUe*3`1{pjL?9PL_#o z@IBVtI5vH3I9oKEIR%gg(P4jtQ2v%-_$?rbF}~KT+=uQz%*PBIIBqf^%`#@hKFmS-^JQRReqZ1hd*(_=4V{vUjVY0G;wv$L z6b*I0o7DqJunyjEYF)*7N$aplxG84Fi2<`r+0EF9&9q$0BzW450{d0~_3Nxq!>*k7 zvfG`^-d@i%uZd(M$uTTV)=oC%Sxb%9d;s#&a>jeO6k{3l5g+t5C2s=3i52mYV zfcN@rHD7qx%B&^b%AsW~vti6m_eXq;Rd_m_gMYxBr|H^Zgk(;1eGNac`U~ItmL=KO z6rg|WyANOAa3}6CA{ZL}+uM90XJW@$^6LP|w#{_r2C#qMqS)n`@ac3`T{GxC^mm1n zI%UsfmzbuNP8^QP5-fsSoONueF#Yu%N%8Y)5m5&D{bpC<=D}*1HL=CKizyKY=E}Jn zmzO9?pq4Cm13}Nys9sGN(@)=n-T00Th2&SOE|VT9Uf`&3U=|QS!FiXP?P?#|bn5jkqTyQ07sdj#&PTStOeE$e>@#t_GXg z7o^*;Vbe)ByW;!S|7}}(0co|;cCtyRV>U4kn@O471v7m(?(3y7@M9Us1s#33RxJEj z>h95u>Qx+;pmNL|&ai+PH9fz{Nqe~fft`H^vwV9=<0{e+g`29S;KzNQsb<>xD4BXm zdPR4v?g_Y4Hz}EW0WP_w!C9RajZV{^ommYeXNc2(j#^s5_0iS$gOL(VOC|WPZXLpb zUk4iiS)K-;9OB>sq&IOP+HU#P6;IRbWSTh4u)5!@U60`ED}q@q+GP(@D>V^RdewmT z@P}N_NT=4`_acwSJy2V|igRpdLOR1jKbvu|Msj~sXt7400^bH@8-X-LL-CH5{=G2JYBRw`Z=T4^+Rq;u58#MV!GQVJn5$MV7CYJi}tGtuUASjmuEO4IYcE2JO zzn%i9E=Tu>mdj*JSZUg<+-R z7bZF*bo`xvr0V?G^Zu;Eke0rTj+Tz`gC{)iwuDf)i#yNfP|v61!oX%So?!0dC$D$jfz9B%%(6K_!bps*)y zm$Il|*ppaMw#Lq!TWN%fChd0uh+vaV>Mc`o$F|JET^&D3X8bYstmv7e-2MLC4i!P) zO*t@e1;B|-C#qEoh8_I)B()~1&#k4@m#eNU$c!mxs!nohReB+(mo1?8f`j|P%J?*= zAXKu?i01Z4n#d>SNVJ`ij#$a6_V!BTYxl}l@o)w~7EJtm4wKCLB~M6rO~|54OVw5e zqf^)ybHYHu2j5*$B=2?suMSFH_4<4{$q$0fi=-~7Hf+o-+@FPjjs=29Is(PmuS z#_&Y$D$$EqXZ7=0c|2R{y|N^d)g$imYJ(mrgl+xynX5k2fG7~-N^ybb`J$J?K3ah! zW@j-Sbj@=oozxBBe&l6-Eb2&%)*LTi5KL9F2;+VIFUZ#2>mq03o7 zp~$wMZFKN8a&R!I>30g=9Y&BJ_cgzg)4ihL5VRZz@TPxkj>K1LYvLp6MCI8n^|gxZ z%3M^6;Q57tT%I^i5k6hqmmXm!<$({*$qC>@RI|RI;wP`1(oi87o!k`p>N}N9H-4m7 zfSHBDtn9&_D%8!J?k+{sJoe!Ryy_8tqxHK{yq8S%&duD!XeoQNJhq$6+zsc|q9xWn zdYZ{~&{nY=e{O<6Fr+7aNAhwp{}{{}Yl0J7=igtbNd}}LOtkjp z2Ns(m55jhKuo%MDhdfWzcM~B3gtn3b>MCuhNp`ZF4p}Q4_tQ(_6X|K8Cbv$={J)k@ z0z33DNs5@~z>Vu=U2Wf6i1#5R+o3*omBi=^he;f)W2@xyd+o}HZX|Vk@OZbCPiQRm z*_{?>82siraltB{C^_<#oVQ?+mdIaL}a2B;DZ@ZZ~*JkF4KUDq_FaZGxINT+EB~9gQG1Y=B$13^OVcGqG_=t|Ptp+)%yX z{V8tLNfC%W`he^PGtR$IiCBn(hShLeXT0Zzfu&HmK+@a9-@F&D1Ak9vtTM4An{#(^ zLU8WLpc?q=w+CPfymSP#e3V=BVl?8UNCeU{FCHFK?v126PToD1cmUblD0wtBnR>B% zHif=vBYo@Y`NxGf4@lk&el7ZD!g%=DKWhPaImc5M%pTqq`p3Clm{!c(AJSL0@B5FS zm0YX<)oN9171iAfG11WgN*$)-R8>1YP%s0Kw%tIY$2&v&zWlqMX*}+lA10pn6X*ML zz3e-LTjMNA#b?Yi=Ld%qxSuLFzwp(&$^K7l3V2wWWyN7`ab)mGDbVn)e&FU;GtBVt zEJDDGYbJs*0)@Y+`{8+w7?T6sp5oT-v0rTCrkk@1fA{`o^DUA$-p!V1QEaKo=f&LY zO1*$wir9pxlcWIu922y0MIP*6He_78iJH}U^?N|-ymlX9KR@DC$bEavw$^LHyMh|Q z^o)hfcxX&p{hW(^;}@rPx|Y4qAbz~LUczWCqr4=NCJ=@cR<->&@Cs5Sd?7xCA2;l}{4JRo%gjF96Djpy=wpjcfqS>vT2!HM z*vJ48BTn&RyT@t00uBayE)xWRjtJ`5YmT~t z%=Dk>M>FF!&PWVlj=#8K6vemj@G+ejx@9rUE!KFlz=c0gCB$}8W-=>stWlB>CJI@E z%oR^n^_+|MRpnFtoO#{IY#c)z0!2{M}y8(^vN(r~H)aq8|n zxwj(Hb~S2TC4Dz4T!kO`S>3EKTW6DS>1*cw2ty=4D0F7GaP-fP9DChR zvUeUv&RS3Yn)$wU(37r^24mZ(>sa#$G#|HC7&ao*6!OV(p5vcJQnq%oCZ-J#W;ebW zi#iWW_$h=d4duO>S^iBz=zLwUhRIgJ1Lc>!We_Psj!DJ&PD8 zeyB|Dw@bT>^_2YXqX|bDAY^r93TFbov zYOSYLm*BNXt^um@wBS+8C{uE_#=*bdLLE4=+&Hr_@s(_*pU0d)&swQB788z2 z0CN>xBPL&AG`3Bf0BM^!Ka<~VVzn99PCR!w`JE3ez@FHnlM$!-!z|U=@tjKfm!AU@ ztEF~LbaN`|)rt;fUZF4gQ*dO?Qw8?{?(_3Bjrvn&*gynjb^jUIyN#mL1fV9~#Jmz= zZCwq!F(5`$8}e%TldG0Kn=4lFehNMNGClOBbQ9XComL9foC+DKw6=_c&)Xj>*$t>i zUbPc-c6&dwd9~_UTIvIn^!oh*4=WQ$=N}D)W`G|ZkTnPQ($(|WQqbUgdy+uUCg$1T{xorb1&H2I&x*br3%~js z>9)7_7^*xm0Z7Z;?{%LF(pzSKyFatV;?m$(|<4R z@&pCByPWE5UUVE4a>@Wbd-gs(Pm25Y1G0>*lTxpD=sT;1-tW9H#p}`!*&<}8Lqj}f zd!w^@cTcAe-BwbB9aTL$b)@JJp=zRCf2~hr9R_z-sFU~dXCVD*#rWp=0C=%isWzd{ zs3G3!ZG0N~y9KA&M1}s+^AHw`F@5oqR|GD_!c#Oi0yOR#+q6q4mBElrAc@>PKX� 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 literal 0 HcmV?d00001 diff --git a/user_tools/docs/tools_e2e_tests.md b/user_tools/docs/tools_e2e_tests.md new file mode 100644 index 000000000..6cd9a4d93 --- /dev/null +++ b/user_tools/docs/tools_e2e_tests.md @@ -0,0 +1,172 @@ +# Spark Rapids Tools End-to-End Behavior Tests + +This document outlines the end-to-end tests for Spark Rapids tools, designed to cover scenarios such as missing +dependencies, handling different types of event logs, and interacting with HDFS. + +## Directory Structure +```commandline +user_tools/tests/spark_rapids_tools_e2e/ +├── features # Contains test scenarios and environment setup. +│ ├── environment.py # Setup and teardown procedures for the tests. +│ ├── steps # Step definitions for the tests. +│ └── *.feature # Feature files defining test scenarios. +└── resources # Resources used in the tests. + ├── event_logs + └── scripts # Scripts used in the tests. +``` +Configurations for `behave` tests are defined in `user_tools/tox.ini` file. + +## Setup + +From the `/user_tools` directory, run the following command to install the required dependencies: + + +```sh +pip install behave +# or +pip install .[test] +``` + + +## Running Tests +Tests can be run using 'behave' cmd or using 'tox' cmd. + +**Basic Usage:** + +```sh +behave +# or +tox -e behave -- +``` + +**Run All Tests:** + +```sh +behave +# or +tox -e behave +``` + +### Common Options + +**Run Specific Tests by Tag** + +See the [Tags Format](#tags-format) section for more information on tags. + +```sh +behave --tags +# or +tox -e behave -- --tags +``` + +**Run Specific Tests by Name** + +```sh +behave --name +# or +tox -e behave -- --name +``` + +**Skip Tests by Tag** + +```sh +behave --tags ~ +# or +tox -e behave -- --tags ~ +``` + +**Custom Arguments** +- Custom arguments can be passed to the behave tests using the `-D` flag. +- Example: Skip building the Tools jar during setup. + +```sh +behave -D build_jar=false # Skip building the Tools jar during setup (default: true) +# or +tox -e behave -- -D build_jar=false +``` + +**Verbose Mode** +- When verbose mode is enabled, `STDOUT` and `STDERR` from all subprocesses executed during the test run are shown in the console. +```sh +behave -v +# or +tox -e behave -- -v +``` + +## Notes + +### Tags Format +Tags are used to uniquely identify test scenarios and are defined in the following format: `@test_id__<00xx>`. +- ``: Acronym for the feature file being tested. Examples: + - `ELP` for `event_log_processing.feature` + - `IC` for `installation_checks.feature` +- `<00xx>`: Unique 4-digit identifier for the test scenario. Examples: `0001`, `0002`. + +Tags Example: `@test_id_ELP_0001`, `@test_id_IC_0002`. + +### Built-in Setup Steps + +The tests include the following setup steps: + +1. Build Spark Rapids Tools JAR: + - By default, the JAR is built before running the tests. + - To skip this step (e.g., if the JAR is already built), use the argument -D build_jar=false. +2. Build the Python Package. + +The test warns the user that initial setup may take a few minutes. + +### Built-in HDFS Cluster Setup + +- Some of the tests include configuring a local HDFS cluster. Step: `HDFS is "{status}"` +- This step downloads Hadoop binaries and sets up the cluster. + - The download occurs only once per machine but cluster setup is done for each test run. + - Download step may take a few minutes. +- Tests involving HDFS are tagged with `@long_running` and can be skipped using `--tags ~@long_running` + +#### HDFS Configuration: +- Replication factor: 1 +- Disk Space Quota: 2GB +- Temp Directory: `/tmp/spark_rapids_tools_e2e_tests` + - Temp Directory can be changed using the argument `-D e2e_tests_tmp_dir=` during test run. + +#### Cleanup +- Step `HDFS is "{status}"` sets an after scenario hook to stop up the HDFS cluster and remove the temporary directories. +- It does not clean up the Hadoop binaries downloaded during the setup. +- Cleanup can be done manually using the below script: +```sh +/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/cleanup_hdfs.sh +``` + +## Debugging Tests in IDE: + +- Ensure the Python interpreter is set to the correct virtual environment and `JAVA_HOME` is set. + +**IntelliJ** +- Add a Python run configuration with module name: `behave` and working directory: `/user_tools`. +- Add required arguments in `Script parameters` field. + +Sample Run Configuration: +![resources/debug-behave-intellij.png](resources/debug-behave-intellij.png) + +**VS Code** +- Open or create the `.vscode/launch.json` file. Add the following configuration with required arguments: +```json +{ + "configurations": [ + { + "name": "Python: Spark Rapids Tools E2E Tests", + "type": "debugpy", + "request": "launch", + "module": "behave", + "args": [], + "python": "${command:python.interpreterPath}", + "cwd": "${workspaceFolder}/user_tools" + } + ] +} +``` + + +## Guidelines for Writing Tests + +TODO: Add guidelines and conventions for writing tests. diff --git a/user_tools/pyproject.toml b/user_tools/pyproject.toml index b4fdf1ed7..39d46ebfe 100644 --- a/user_tools/pyproject.toml +++ b/user_tools/pyproject.toml @@ -76,7 +76,7 @@ version = {attr = "spark_rapids_pytools.__version__"} repository = "https://github.com/NVIDIA/spark-rapids-tools/tree/main" [project.optional-dependencies] test = [ - "tox", 'pytest', 'cli_test_helpers' + "tox", 'pytest', 'cli_test_helpers', 'behave' ] qualx = [ "holoviews", diff --git a/user_tools/tests/spark_rapids_tools_e2e/features/environment.py b/user_tools/tests/spark_rapids_tools_e2e/features/environment.py new file mode 100644 index 000000000..228f3e2dd --- /dev/null +++ b/user_tools/tests/spark_rapids_tools_e2e/features/environment.py @@ -0,0 +1,119 @@ +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +This module defines environment setup and teardown functions for the end-to-end tests using behave. +""" + +import os +import shutil +import tempfile + +from spark_rapids_tools.utils import Utilities +from steps.e2e_utils import E2ETestUtils + +""" Define behave hooks for the tests. These hooks are automatically called by behave. """ + +logger = E2ETestUtils.get_logger() + + +def before_all(context) -> None: + """ + Set up the environment for the tests. This function is automatically called before all the tests. + """ + context.temp_dir = tempfile.mkdtemp() + _set_environment_variables(context) + _set_verbose_mode(context) + _setup_env(context) + + +def after_all(context) -> None: + """ + Clean up the environment after the tests. This function is automatically called after all the tests. + """ + _clear_environment_variables() + shutil.rmtree(context.temp_dir) + + +def before_scenario(context, scenario) -> None: + if "skip" in scenario.effective_tags: + scenario.skip("Marked with @skip") + return + + +def after_scenario(context, scenario) -> None: + """ + Clean up the environment after each scenario. This function is automatically called after each scenario. + Steps must set the callback function using set_after_scenario_fn() to perform any cleanup. + """ + if hasattr(context, 'after_scenario_fn'): + context.after_scenario_fn() + + +def _set_verbose_mode(context) -> None: + verbose_enabled = getattr(context.config, 'verbose', False) + if verbose_enabled: + context.config.stdout_capture = False + context.config.stderr_capture = False + os.environ['E2E_TEST_VERBOSE_MODE'] = str(verbose_enabled).lower() + + +def _set_environment_variables(context) -> None: + """ + Set environment variables needed for the virtual environment setup. + """ + tools_version = Utilities.get_base_release() + scala_version = context.config.userdata.get('scala_version') + venv_name = context.config.userdata.get('venv_name') + jar_filename = f'rapids-4-spark-tools_{scala_version}-{tools_version}-SNAPSHOT.jar' + build_jar_value = context.config.userdata.get('build_jar') + build_jar = build_jar_value.lower() in ['true', '1', 'yes'] + + os.environ['E2E_TEST_TOOLS_DIR'] = E2ETestUtils.get_tools_root_path() + os.environ['E2E_TEST_SCRIPTS_DIR'] = os.path.join(E2ETestUtils.get_e2e_tests_resource_path(), 'scripts') + os.environ['E2E_TEST_TOOLS_JAR_PATH'] = os.path.join(os.environ['E2E_TEST_TOOLS_DIR'], + f'core/target/{jar_filename}') + os.environ['E2E_TEST_VENV_DIR'] = os.path.join(context.temp_dir, venv_name) + os.environ['E2E_TEST_BUILD_JAR'] = 'true' if build_jar else 'false' + os.environ['E2E_TEST_SPARK_BUILD_VERSION'] = context.config.userdata.get('buildver') + os.environ['E2E_TEST_HADOOP_VERSION'] = context.config.userdata.get('hadoop.version') + os.environ['E2E_TEST_TMP_DIR'] = context.config.userdata.get('e2e_tests_tmp_dir') + + +def _setup_env(context) -> None: + """ + Build the JAR and set up the virtual environment for the tests. + """ + script_file_name = context.config.userdata.get('setup_script_file') + script = os.path.join(os.environ['E2E_TEST_SCRIPTS_DIR'], script_file_name) + try: + warning_msg = "Setting up the virtual environment for the tests. This may take a while." + if os.environ.get('BUILD_JAR') == 'true': + warning_msg = f'Building JAR and {warning_msg}' + logger.warning(warning_msg) + result = E2ETestUtils.run_sys_cmd([script]) + E2ETestUtils.assert_sys_cmd_return_code(result, + exp_return_code=0, + error_msg="Failed to create virtual environment") + except Exception as e: # pylint: disable=broad-except + raise RuntimeError(f"Failed to create virtual environment. Reason: {str(e)}") from e + + +def _clear_environment_variables() -> None: + """ + Clear environment variables set for the virtual environment setup. + """ + env_vars = ['SCRIPTS_DIR', 'VENV_DIR', 'TOOLS_JAR_PATH'] + for key in env_vars: + os.environ.pop(key, None) diff --git a/user_tools/tests/spark_rapids_tools_e2e/features/event_log_processing.feature b/user_tools/tests/spark_rapids_tools_e2e/features/event_log_processing.feature new file mode 100644 index 000000000..6a3f97cb0 --- /dev/null +++ b/user_tools/tests/spark_rapids_tools_e2e/features/event_log_processing.feature @@ -0,0 +1,43 @@ +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Feature: Event Log Processing + + @test_id_ELP_0001 + Scenario Outline: Tool spark_rapids runs with different types of event logs + When spark-rapids tool is executed with "" eventlogs + Then stderr contains the following + """ + + """ + And processed applications is "0" + And return code is "0" + + Examples: + | event_logs | expected_stderr | + | invalid_path_eventlog | process.failure.count = 1;invalid_path_eventlog not found, skipping! | + | gpu_eventlog.zstd | process.skipped.count = 1;GpuEventLogException: Cannot parse event logs from GPU run: skipping this file | + | photon_eventlog.zstd | process.skipped.count = 1;PhotonEventLogException: Encountered Databricks Photon event log: skipping this file! | + | streaming_eventlog.zstd | process.skipped.count = 1;StreamingEventLogException: Encountered Spark Structured Streaming Job: skipping this file! | + | incorrect_app_status_eventlog.zstd | process.NA.count = 1;IncorrectAppStatusException: Application status is incorrect. Missing AppInfo | + + @test_id_ELP_0002 + Scenario: Qualification tool JAR crashes + Given thread to crash qualification tool has started + When spark-rapids tool is executed with "join_agg_on_yarn_eventlog.zstd" eventlogs + Then stderr contains the following + """ + Qualification. Raised an error in phase [Execution] + """ + And return code is "1" diff --git a/user_tools/tests/spark_rapids_tools_e2e/features/hdfs_storage.feature b/user_tools/tests/spark_rapids_tools_e2e/features/hdfs_storage.feature new file mode 100644 index 000000000..714ddfc2b --- /dev/null +++ b/user_tools/tests/spark_rapids_tools_e2e/features/hdfs_storage.feature @@ -0,0 +1,88 @@ +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +@long_running +Feature: HDFS Event Log Storage + + @test_id_HDFS_0001 + Scenario Outline: Eventlogs are stored in HDFS - Platform specified + Given platform is "" + And HDFS is "running" + And HDFS has "" eventlogs + When spark-rapids tool is executed with "hdfs:///" eventlogs + Then processed applications is "1" + And return code is "0" + + Examples: + | platform | eventlog | + | onprem | join_agg_on_yarn_eventlog.zstd | + | dataproc | join_agg_on_yarn_eventlog.zstd | + + @test_id_HDFS_0002 + Scenario Outline: Eventlogs are stored in HDFS - Platform not specified + Given HDFS is "running" + And HDFS has "" eventlogs + When spark-rapids tool is executed with "hdfs:///" eventlogs + Then processed applications is "1" + And return code is "0" + + Examples: + | eventlog | + | join_agg_on_yarn_eventlog.zstd | + + @test_id_HDFS_0003 + Scenario Outline: Eventlogs are stored in HDFS - HDFS installed but not running + Given HDFS is "not running" + When spark-rapids tool is executed with "hdfs:///" eventlogs + Then stderr contains the following + """ + EventLogPathProcessor: Unexpected exception occurred reading hdfs:///, skipping! + """ + And processed applications is "0" + And return code is "0" + + Examples: + | eventlog | + | join_agg_on_yarn_eventlog.zstd | + + @test_id_HDFS_0004 + Scenario Outline: Eventlogs are stored in HDFS - HDFS not installed, Platform specified + Given platform is "onprem" + And HDFS is "not installed" + When spark-rapids tool is executed with "hdfs:///" eventlogs + Then stderr contains the following + """ + EventLogPathProcessor: Unexpected exception occurred reading hdfs:///, skipping!;Incomplete HDFS URI + """ + And processed applications is "0" + And return code is "0" + + Examples: + | eventlog | + | join_agg_on_yarn_eventlog.zstd | + + @test_id_HDFS_0005 + Scenario Outline: Eventlogs are stored in HDFS - HDFS not installed, Platform not specified + Given HDFS is "not installed" + When spark-rapids tool is executed with "hdfs:///" eventlogs + Then stderr contains the following + """ + EventLogPathProcessor: Unexpected exception occurred reading hdfs:///, skipping!;Incomplete HDFS URI + """ + And processed applications is "0" + And return code is "0" + + Examples: + | eventlog | + | join_agg_on_yarn_eventlog.zstd | diff --git a/user_tools/tests/spark_rapids_tools_e2e/features/installation_checks.feature b/user_tools/tests/spark_rapids_tools_e2e/features/installation_checks.feature new file mode 100644 index 000000000..3edce082f --- /dev/null +++ b/user_tools/tests/spark_rapids_tools_e2e/features/installation_checks.feature @@ -0,0 +1,44 @@ +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Feature: Tool Installation Checks + + @test_id_IC_0001 + Scenario Outline: Environment has missing CLI and spark_rapids tool processes eventlogs + Given platform is "" + And "" is not installed + When spark-rapids tool is executed with "join_agg_on_yarn_eventlog.zstd" eventlogs + Then stdout contains the following + """ + + """ + And processed applications is "1" + And return code is "0" + + Examples: + | platform | cli | expected_stdout | + | dataproc | gcloud | 2 x n1-standard-16 (4 T4 each) | + | emr | aws | 10 x g5.xlarge | + | databricks-aws | aws | 10 x g5.xlarge | + | databricks-azure | az | 2 x Standard_NC64as_T4_v3 | + + @test_id_IC_0002 + Scenario: Environment has missing java + Given "java" is not installed + When spark-rapids tool is executed with "join_agg_on_yarn_eventlog.zstd" eventlogs + Then stderr contains the following + """ + RuntimeError: Error invoking CMD + """ + And return code is "1" diff --git a/user_tools/tests/spark_rapids_tools_e2e/features/steps/e2e_utils.py b/user_tools/tests/spark_rapids_tools_e2e/features/steps/e2e_utils.py new file mode 100644 index 000000000..4468c0050 --- /dev/null +++ b/user_tools/tests/spark_rapids_tools_e2e/features/steps/e2e_utils.py @@ -0,0 +1,225 @@ +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +This module defines utility functions used by the end-to-end tests using behave. +""" + +import logging +import os +import subprocess +from attr import dataclass +from enum import auto +from pathlib import Path +from typing import List +from urllib.parse import urlparse + +from spark_rapids_tools import EnumeratedType + + +@dataclass +class E2ETestUtils: + + @staticmethod + def get_cmd_output_str(cmd_result: subprocess.CompletedProcess) -> str: + """ + Get the output of a command as a string (stdout and stderr). + """ + dash_line = '-' * 50 + cmd_sections = [("COMMAND", ' '.join(cmd_result.args)), + ("STDOUT", cmd_result.stdout), + ("STDERR", cmd_result.stderr)] + output_sections = [] + for label, content in cmd_sections: + content = content.strip() if content else "No output" + output_sections.append(f"{dash_line}\n{label}\n{dash_line}\n{content}\n{dash_line}") + return '\n'.join(output_sections).strip() + '\n' + + @classmethod + def run_sys_cmd(cls, cmd: list) -> subprocess.CompletedProcess: + """ + Run a system command and return the result. + If verbose mode is enabled by the behave config, print the command and its output + """ + cmd_result = subprocess.run(cmd, capture_output=True, text=True) + if cls.is_verbose_mode(): + print(cls.get_cmd_output_str(cmd_result)) + return cmd_result + + @classmethod + def assert_sys_cmd_return_code(cls, + cmd_result: subprocess.CompletedProcess, + exp_return_code: int = 0, + error_msg: str = None) -> None: + assert cmd_result.returncode == exp_return_code, \ + f"{error_msg}\n{cls.get_cmd_output_str(cmd_result)}" + + @classmethod + def create_spark_rapids_cmd(cls, + event_logs: List[str], + output_dir: str, + platform: str = 'onprem', + filter_apps: str = 'all') -> List[str]: + """ + Create the command to run the Spark Rapids qualification tool. + TODO: We can add more options to the command as needed. + """ + return [ + cls.get_spark_rapids_cli(), + 'qualification', + '--platform', platform, + '--eventlogs', ','.join(event_logs), + '-o', output_dir, + '--tools_jar', cls.get_tools_jar_file(), + '--verbose', + '--filter_apps', filter_apps + ] + + # Utility getter functions + @staticmethod + def get_tools_root_path() -> str: + return str(Path(__file__).parents[5]) + + @staticmethod + def get_e2e_tests_root_path() -> str: + return str(Path(__file__).parents[2]) + + @classmethod + def get_e2e_tests_config_file(cls) -> str: + return os.path.join(cls.get_e2e_tests_root_path(), 'behave.ini') + + @classmethod + def get_e2e_tests_resource_path(cls) -> str: + return os.path.join(cls.get_e2e_tests_root_path(), 'resources') + + @classmethod + def get_local_event_logs_dir(cls) -> str: + return os.path.join(cls.get_e2e_tests_resource_path(), 'event_logs') + + @staticmethod + def get_spark_rapids_cli() -> str: + return os.path.join(os.environ['E2E_TEST_VENV_DIR'], 'bin', 'spark_rapids') + + @staticmethod + def get_tools_jar_file() -> str: + return os.environ['E2E_TEST_TOOLS_JAR_PATH'] + + @staticmethod + def is_verbose_mode() -> bool: + return os.environ['E2E_TEST_VERBOSE_MODE'].lower() == 'true' + + @classmethod + def resolve_event_logs(cls, event_logs: List[str]) -> List[str]: + """ + Get the full path of the event logs if they are local files. + """ + # Base directory can be modified (i.e. separate for local and CICD runs) + fs = urlparse(event_logs[0]).scheme + if not fs or fs == 'file': + event_logs_dir = cls.get_local_event_logs_dir() + return [os.path.join(event_logs_dir, event_log) for event_log in event_logs] + return event_logs + + @classmethod + def replace_cli_with_mock(cls, cli_name: str, temp_dir: str) -> None: + """ + Replace the specified CLI in the PATH environment variable with a mock version that simulates the + command not being found. + + :param cli_name: The name of the CLI command to replace in the PATH. + :param temp_dir: The temporary directory where the mock CLI will be created. + """ + mock_cli_path = os.path.join(temp_dir, cli_name) + with open(mock_cli_path, "w") as f: + f.write("#!/bin/bash\n") + f.write(f"echo '{cli_name}: command not found'\n") + f.write("exit 1\n") + os.chmod(mock_cli_path, 0o755) + os.environ['PATH'] = temp_dir + ":" + os.environ['PATH'] + + # verify the CLI is not in the PATH + cmd_result = cls.run_sys_cmd([cli_name]) + cls.assert_sys_cmd_return_code(cmd_result, exp_return_code=1, error_msg=f"{cli_name} is still in the PATH") + + @staticmethod + def get_logger() -> logging.Logger: + """ + Create a logger for the module. + """ + logging.basicConfig( + level=logging.INFO, + format='%(levelname)s: %(message)s' + ) + return logging.getLogger(__name__) + + +class HdfsStatus(EnumeratedType): + RUNNING = auto() + NOT_RUNNING = auto() + NOT_INSTALLED = auto() + + @classmethod + def fromstring(cls, value: str) -> 'EnumeratedType': + return super().fromstring(value.replace(' ', '_')) + + +class HdfsTestUtils: + + @staticmethod + def setup_hdfs(should_run: bool) -> None: + """ + Sets up the HDFS environment. + + Executes a shell script to set up HDFS and configures the environment variables + required for HDFS. Depending on the `should_run` parameter, it either starts HDFS or simply + configures the environment without starting it. + :param should_run: Boolean flag to indicate whether to start HDFS. + """ + try: + hdfs_setup_script = os.path.join(os.environ['E2E_TEST_SCRIPTS_DIR'], 'hdfs', 'setup_hdfs.sh') + args = ["--run" if should_run else "--no-run"] + cmd_result = E2ETestUtils.run_sys_cmd([hdfs_setup_script] + args) + E2ETestUtils.assert_sys_cmd_return_code(cmd_result, exp_return_code=0, error_msg="Failed to setup HDFS") + hadoop_home = cmd_result.stdout.splitlines()[-1] + hadoop_conf_dir = os.path.join(hadoop_home, 'etc', 'hadoop') + assert os.path.exists(hadoop_home), f"HADOOP_HOME: {hadoop_home} does not exist" + os.environ['HADOOP_HOME'] = hadoop_home + if not should_run: + os.environ['HADOOP_CONF_DIR'] = hadoop_conf_dir + os.environ['PATH'] = f"{hadoop_home}/bin:{hadoop_home}/sbin:{os.environ['PATH']}" + except Exception as e: # pylint: disable=broad-except + raise RuntimeError(f"Failed to setup HDFS.\nReason: {e}") from e + + @staticmethod + def cleanup_hdfs() -> None: + """ + Stops the HDFS and cleans up the environment. + """ + hdfs_cleanup_script = os.path.join(os.environ['E2E_TEST_SCRIPTS_DIR'], 'hdfs', 'cleanup_hdfs.sh') + try: + cmd_result = E2ETestUtils.run_sys_cmd([hdfs_cleanup_script]) + E2ETestUtils.assert_sys_cmd_return_code(cmd_result, exp_return_code=0, error_msg="Failed to stop HDFS") + except Exception as e: # pylint: disable=broad-except + raise RuntimeError(f"Failed to stop HDFS.\nReason: {e}") from e + + @staticmethod + def hdfs_is_active() -> bool: + """ + Check if HDFS is already active. + """ + try: + output = subprocess.check_output(['jps'], text=True) + return 'NameNode' in output + except (subprocess.CalledProcessError, FileNotFoundError) as e: + raise RuntimeError("Failed to check if HDFS is running.") from e diff --git a/user_tools/tests/spark_rapids_tools_e2e/features/steps/test_steps.py b/user_tools/tests/spark_rapids_tools_e2e/features/steps/test_steps.py new file mode 100644 index 000000000..e1bd83933 --- /dev/null +++ b/user_tools/tests/spark_rapids_tools_e2e/features/steps/test_steps.py @@ -0,0 +1,172 @@ +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +This module defines steps to be used by the end-to-end tests using behave. +""" + +import os +import shutil +import tempfile +import threading +from time import sleep +from typing import Callable + +from behave import given, when, then + +from e2e_utils import E2ETestUtils, HdfsTestUtils, HdfsStatus + +logger = E2ETestUtils.get_logger() + + +def set_after_scenario_fn(context, fn: Callable) -> None: + """ + Set the callback function to be called after each scenario. + + See also: + user_tools.tests.spark_rapids_tools_e2e.features.environment.after_scenario() + """ + context.after_scenario_fn = fn + + +@given('platform is "{platform}"') +def step_set_platform(context, platform) -> None: + context.platform = platform + + +@given('"{cli}" is not installed') +def step_replace_cli_with_mock(context, cli) -> None: + original_path = os.environ["PATH"] + tempdir = tempfile.mkdtemp() + + E2ETestUtils.replace_cli_with_mock(cli, tempdir) + + def after_scenario_fn(): + os.environ.update({"PATH": original_path}) + shutil.rmtree(tempdir) + + set_after_scenario_fn(context, after_scenario_fn) + + +def _start_qualification_tool_crash_thread_internal(_stop_event: threading.Event) -> None: + """ + Start a thread to crash the qualification tool after 1s of it starting. + :param _stop_event: Event to stop the thread + """ + qual_tool_class_path = 'com.nvidia.spark.rapids.tool.qualification.QualificationMain' + + def is_qual_tool_running() -> bool: + return E2ETestUtils.run_sys_cmd(["pgrep", "-f", f"java.*{qual_tool_class_path}"]).returncode == 0 + + while not _stop_event.is_set() and not is_qual_tool_running(): + sleep(1) + + if is_qual_tool_running(): + cmd_result = E2ETestUtils.run_sys_cmd(["pkill", "-f", f"java.*{qual_tool_class_path}"]) + E2ETestUtils.assert_sys_cmd_return_code(cmd_result, + exp_return_code=0, + error_msg="Failed to kill the qualification tool.") + + +@given('thread to crash qualification tool has started') +def step_start_qualification_tool_crash_thread(context) -> None: + stop_event = threading.Event() + qual_tool_thread = threading.Thread(target=_start_qualification_tool_crash_thread_internal, args=(stop_event,)) + qual_tool_thread.start() + + def after_scenario_fn(): + stop_event.set() + qual_tool_thread.join() + stop_event.clear() + + set_after_scenario_fn(context, after_scenario_fn) + + +@given('HDFS is "{status}"') +def step_setup_hdfs(context, status) -> None: + if HdfsTestUtils.hdfs_is_active(): + raise RuntimeError('HDFS is already active. Please stop it before running the tests.') + + test_hdfs_status = HdfsStatus.fromstring(status) + if test_hdfs_status == HdfsStatus.NOT_INSTALLED: + # Do nothing if HDFS should not be installed + return + if test_hdfs_status == HdfsStatus.RUNNING: + # Set up HDFS and start it + logger.warning('Setting up and starting HDFS. This may take a while.') + should_run = True + elif test_hdfs_status == HdfsStatus.NOT_RUNNING: + # Set up HDFS but do not start it + logger.warning('Setting up HDFS without starting it. This may take a while.') + should_run = False + else: + raise ValueError(f"HDFS status '{status}' is not valid.") + + set_after_scenario_fn(context, HdfsTestUtils.cleanup_hdfs) + HdfsTestUtils.setup_hdfs(should_run) + + +@given('HDFS has "{event_logs}" eventlogs') +def step_hdfs_has_eventlogs(context, event_logs) -> None: + event_logs_list = E2ETestUtils.resolve_event_logs(event_logs.split(",")) + hdfs_event_logs_dir = '/' + for event_log in event_logs_list: + hdfs_copy_cmd = ['hdfs', 'dfs', '-copyFromLocal', '-f', event_log, hdfs_event_logs_dir] + cmd_result = E2ETestUtils.run_sys_cmd(hdfs_copy_cmd) + E2ETestUtils.assert_sys_cmd_return_code(cmd_result, exp_return_code=0, + error_msg="Failed to copy event logs to HDFS") + + +@when('spark-rapids tool is executed with "{event_logs}" eventlogs') +def step_execute_spark_rapids_tool(context, event_logs) -> None: + event_logs_list = E2ETestUtils.resolve_event_logs(event_logs.split(",")) + if hasattr(context, 'platform'): + cmd = E2ETestUtils.create_spark_rapids_cmd(event_logs_list, context.temp_dir, context.platform) + else: + cmd = E2ETestUtils.create_spark_rapids_cmd(event_logs_list, context.temp_dir) + context.result = E2ETestUtils.run_sys_cmd(cmd) + + +@then('stderr contains the following') +def step_verify_stderr(context) -> None: + expected_stderr_list = context.text.strip().split(";") + for stderr_line in expected_stderr_list: + assert stderr_line in context.result.stderr, \ + (f"Expected stderr line '{stderr_line}' not found\n" + + E2ETestUtils.get_cmd_output_str(context.result)) + + +@then('stdout contains the following') +def step_verify_stdout(context) -> None: + expected_stdout_list = context.text.strip().split(";") + for stdout_line in expected_stdout_list: + assert stdout_line in context.result.stdout, \ + (f"Expected stdout line '{stdout_line}' not found\n" + + E2ETestUtils.get_cmd_output_str(context.result)) + + +@then('processed applications is "{expected_num_apps}"') +def step_verify_num_apps(context, expected_num_apps) -> None: + actual_num_apps = -1 + for stdout_line in context.result.stdout.splitlines(): + if "Processed applications" in stdout_line: + actual_num_apps = int(stdout_line.split()[-1]) + assert actual_num_apps == int(expected_num_apps), \ + f"Expected: {expected_num_apps}, Actual: {actual_num_apps}" + + +@then('return code is "{return_code:d}"') +def step_verify_return_code(context, return_code) -> None: + assert context.result.returncode == return_code, \ + f"Expected return code: {return_code}, Actual return code: {context.result.returncode}" diff --git a/user_tools/tests/spark_rapids_tools_e2e/resources/event_logs/gpu_eventlog.zstd b/user_tools/tests/spark_rapids_tools_e2e/resources/event_logs/gpu_eventlog.zstd new file mode 100644 index 0000000000000000000000000000000000000000..31ff77c93bef572f9f76fb2ad80d11c2a5e65c34 GIT binary patch literal 24489 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 WfeZbn&cuzKnw#uZJO2SR@yG>PMGb@i literal 0 HcmV?d00001 diff --git a/user_tools/tests/spark_rapids_tools_e2e/resources/event_logs/join_agg_on_yarn_eventlog.zstd b/user_tools/tests/spark_rapids_tools_e2e/resources/event_logs/join_agg_on_yarn_eventlog.zstd new file mode 100644 index 0000000000000000000000000000000000000000..8cfba577a8706ca0b7ac098606a50d49c952dff5 GIT binary patch literal 53749 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 Gh~Ev#pf*ha literal 0 HcmV?d00001 diff --git a/user_tools/tests/spark_rapids_tools_e2e/resources/event_logs/photon_eventlog.zstd b/user_tools/tests/spark_rapids_tools_e2e/resources/event_logs/photon_eventlog.zstd new file mode 100644 index 0000000000000000000000000000000000000000..2ff810859be40f48b859d8bf0c06ce6d2e61cddc GIT binary patch literal 59430 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 + exit 1 +} diff --git a/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/cleanup_hdfs.sh b/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/cleanup_hdfs.sh new file mode 100755 index 000000000..f2b0476ef --- /dev/null +++ b/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/cleanup_hdfs.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This script stops any running HDFS services and removes the HDFS directories. +# Usage: ./cleanup_hdfs.sh + +readonly CURRENT_FILE_PATH=$(realpath "${0}") + +load_common_scripts() { + local scripts_dir=$(dirname "$(dirname "${CURRENT_FILE_PATH}")") + source "${scripts_dir}/common.sh" +} + +# Stop HDFS services +stop_hdfs_services() { + if jps | grep -q "NameNode\|DataNode"; then + echo "Stopping HDFS..." + local hadoop_home="${E2E_TEST_HDFS_DIR}/hadoop-${E2E_TEST_HADOOP_VERSION}" + local hdfs_bin="${hadoop_home}/bin/hdfs" + [ ! -f "${hdfs_bin}" ] && err "HDFS binary not found at ${hdfs_bin}. However, HDFS services are running." + ${hdfs_bin} --daemon stop namenode + ${hdfs_bin} --daemon stop datanode + else + echo "HDFS is not running." + fi +} + +cleanup_hdfs_dir() { + rm -rf "${E2E_TEST_HDFS_DIR}" + echo "Removed HDFS directories." +} + +main() { + load_common_scripts + stop_hdfs_services + cleanup_hdfs_dir +} + +main diff --git a/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/setup_hdfs.sh b/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/setup_hdfs.sh new file mode 100755 index 000000000..10e979bf9 --- /dev/null +++ b/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/setup_hdfs.sh @@ -0,0 +1,195 @@ +#!/bin/bash + +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This script sets up and configures Hadoop HDFS. It optionally starts HDFS services +# based on the provided HDFS_SHOULD_RUN flag. +# +# HDFS Configuration: +# - Replication factor: 1 +# - Disk Space Quota: 2GB +# - Temp Directory: /tmp/spark_rapids_tools_e2e_tests +# +# Usage: ./setup_hdfs.sh --run|--no-run +# Options: +# --run Run HDFS services (default) +# --no-run Do not run HDFS + +set -e + +usage() { + echo "Usage: $0 --run|--no-run" >&2 + echo "Options:" + echo " --run Run HDFS services (default)" >&2 + echo " --no-run Do not run HDFS" >&2 + exit 1 +} + +if [ $# -eq 0 ]; then + usage +fi + +# Parse arguments +while [[ $# -gt 0 ]]; do + case "$1" in + --run) + readonly HDFS_SHOULD_RUN=true + shift + ;; + --no-run) + readonly HDFS_SHOULD_RUN=false + shift + ;; + *) + echo "Invalid option: $1" >&2 + usage + ;; + esac +done + +echo "HDFS_SHOULD_RUN: ${HDFS_SHOULD_RUN}" +readonly DEFAULT_CORE_SITE_XML="core-site.xml" +readonly DEFAULT_HDFS_SITE_XML="hdfs-site.xml" +readonly HDFS_SPACE_QUOTA="2g" +readonly CURRENT_FILE_PATH=$(realpath "${0}") +readonly HDFS_SCRIPTS_DIR=$(dirname "${CURRENT_FILE_PATH}") +readonly VERIFY_HDFS_SERVICES_MAX_RETRY=3 +readonly VERIFY_HDFS_SERVICES_SLEEP_SEC=5 + +load_common_scripts() { + local scripts_dir=$(dirname "${HDFS_SCRIPTS_DIR}") + source "${scripts_dir}/common.sh" +} + +# Validate environment variables and dependencies +validate_env() { + [ -z "${JAVA_HOME}" ] && err "JAVA_HOME is not set. Please set JAVA_HOME." + [ -z "${E2E_TEST_HADOOP_VERSION}" ] && err "E2E_TEST_HADOOP_VERSION is not set. Please set E2E_TEST_HADOOP_VERSION." + [ -z "${E2E_TEST_TMP_DIR}" ] && err "E2E_TEST_TMP_DIR is not set. Please set E2E_TEST_TMP_DIR (e.g. /tmp/spark_rapids_tools_e2e_tests)." + command -v jps >/dev/null || err "jps is not available. Please install JDK or add JDK bin directory to PATH." +} + +# Set up HDFS directories +setup_hdfs_dirs() { + echo "Setting up HDFS directories..." + readonly E2E_TEST_NAME_NODE_DIR="${E2E_TEST_HDFS_DIR}/namenode" + readonly E2E_TEST_DATA_NODE_DIR="${E2E_TEST_HDFS_DIR}/datanode" + rm -rf "${E2E_TEST_HDFS_DIR}" "${E2E_TEST_NAME_NODE_DIR}" "${E2E_TEST_DATA_NODE_DIR}" + mkdir -p "${E2E_TEST_HDFS_DIR}" "${E2E_TEST_NAME_NODE_DIR}" "${E2E_TEST_DATA_NODE_DIR}" + export E2E_TEST_NAME_NODE_DIR E2E_TEST_DATA_NODE_DIR +} + +# Function to verify checksum +verify_checksum() { + echo "Verifying checksum..." + if [ $# -ne 2 ]; then + err "verify_checksum requires two arguments: file and checksum_file." + fi + local file="$1" + local checksum_file="$2" + local expected_checksum=$(awk '{print $4}' "${checksum_file}") + local actual_checksum=$(shasum -a 512 "${file}" | awk '{print $1}') + [ "${expected_checksum}" != "${actual_checksum}" ] && return 1 || return 0 +} + +# Function to download and extract Hadoop +download_and_extract_hadoop() { + echo "Downloading and extracting Hadoop..." + local hadoop_url="https://dlcdn.apache.org/hadoop/common/hadoop-${E2E_TEST_HADOOP_VERSION}/hadoop-${E2E_TEST_HADOOP_VERSION}.tar.gz" + local hadoop_tar_file="${E2E_TEST_TMP_DIR}/hadoop-${E2E_TEST_HADOOP_VERSION}.tar.gz" + local checksum_url="${hadoop_url}.sha512" + local checksum_file="${hadoop_tar_file}.sha512" + + if [ ! -f "${hadoop_tar_file}" ]; then + wget -O "${hadoop_tar_file}" "${hadoop_url}" || err "Failed to download Hadoop tarball." + fi + + # Verify checksum and re-download if needed + wget -O "${checksum_file}" "${checksum_url}" || err "Failed to download checksum file." + if ! verify_checksum "${hadoop_tar_file}" "${checksum_file}"; then + wget -O "${hadoop_tar_file}" "${hadoop_url}" || err "Failed to download Hadoop tarball." + if ! verify_checksum "${hadoop_tar_file}" "${checksum_file}"; then + err "Checksum verification failed after re-downloading. Exiting..." + fi + fi + + tar -xzf "${hadoop_tar_file}" -C "${E2E_TEST_HDFS_DIR}" || err "Failed to extract Hadoop tarball." +} + +# Configure Hadoop +configure_hadoop() { + echo "Configuring Hadoop..." + readonly HADOOP_HOME="${E2E_TEST_HDFS_DIR}/hadoop-${E2E_TEST_HADOOP_VERSION}" + readonly HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop + export HADOOP_HOME HADOOP_CONF_DIR + export PATH="${PATH}:${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin" + envsubst < "${HDFS_SCRIPTS_DIR}/templates/${DEFAULT_CORE_SITE_XML}" > "${HADOOP_HOME}/etc/hadoop/core-site.xml" + envsubst < "${HDFS_SCRIPTS_DIR}/templates/${DEFAULT_HDFS_SITE_XML}" > "${HADOOP_HOME}/etc/hadoop/hdfs-site.xml" +} + +# Format the Namenode +format_namenode() { + echo "Formatting the Namenode..." + yes | hdfs namenode -format || err "Failed to format Namenode." +} + +# Start HDFS services +start_hdfs_services() { + echo "Starting HDFS services..." + hdfs --daemon start namenode + hdfs --daemon start datanode +} + +# Verify that HDFS services are running +verify_hdfs_services() { + echo "Verifying HDFS services..." + jps | grep -q "NameNode" || err "Namenode is not running." + jps | grep -q "DataNode" || err "Datanode is not running." + hdfs dfs -ls / || err "Failed to list HDFS root directory." + hdfs dfsadmin -setSpaceQuota "${HDFS_SPACE_QUOTA}" / || err "Failed to set space quota of ${HDFS_SPACE_QUOTA}" + hdfs dfsadmin -report || err "Failed to get HDFS report." +} + +verify_hdfs_services_with_retry() { + local max_retry=$1 + local count=1 + while [[ ${count} -le ${max_retry} ]]; do + echo "Attempt ${count} of ${max_retry}..." + if verify_hdfs_services; then + echo "HDFS services are running." + return 0 + fi + echo "HDFS services verification failed. Retrying in ${VERIFY_HDFS_SERVICES_SLEEP_SEC} seconds..." + sleep ${VERIFY_HDFS_SERVICES_SLEEP_SEC} + ((count++)) + done + return 1 +} + +main() { + load_common_scripts + validate_env + setup_hdfs_dirs + download_and_extract_hadoop + configure_hadoop + if [ "${HDFS_SHOULD_RUN}" = true ]; then + format_namenode + start_hdfs_services + verify_hdfs_services_with_retry ${VERIFY_HDFS_SERVICES_MAX_RETRY} || err "Failed to start HDFS services after ${VERIFY_HDFS_SERVICES_MAX_RETRY} attempts." + fi + echo "${HADOOP_HOME}" +} + +main diff --git a/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/templates/core-site.xml b/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/templates/core-site.xml new file mode 100644 index 000000000..04958b67e --- /dev/null +++ b/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/templates/core-site.xml @@ -0,0 +1,26 @@ + + + + + fs.defaultFS + hdfs://localhost:9000 + + + hadoop.tmp.dir + ${E2E_TEST_DATA_NODE_DIR} + + diff --git a/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/templates/hdfs-site.xml b/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/templates/hdfs-site.xml new file mode 100644 index 000000000..d68093caa --- /dev/null +++ b/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/hdfs/templates/hdfs-site.xml @@ -0,0 +1,30 @@ + + + + + dfs.replication + 1 + + + dfs.namenode.name.dir + file:${E2E_TEST_NAME_NODE_DIR} + + + dfs.datanode.data.dir + file:${E2E_TEST_DATA_NODE_DIR} + + diff --git a/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/setup_env.sh b/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/setup_env.sh new file mode 100755 index 000000000..c8c523213 --- /dev/null +++ b/user_tools/tests/spark_rapids_tools_e2e/resources/scripts/setup_env.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +err () { + echo "ERROR: $1" >&2 + exit 1 +} + +if [ -z "$E2E_TEST_TOOLS_DIR" ]; then + err "Please set E2E_TEST_TOOLS_DIR to the root directory of the spark-rapids-tools repository. Exiting script." +fi + +if [ -z "$E2E_TEST_SPARK_BUILD_VERSION" ]; then + err "Please set E2E_TEST_SPARK_BUILD_VERSION to the version of Spark used for building Tools JAR. Exiting script." +fi + +if [ -z "$E2E_TEST_HADOOP_VERSION" ]; then + err "Please set E2E_TEST_HADOOP_VERSION to the version of Hadoop used for building Tools JAR. Exiting script." +fi + +build_jar() { + local jar_tools_dir="$E2E_TEST_TOOLS_DIR/core" + echo "Building Spark RAPIDS Tools JAR file" + pushd "$jar_tools_dir" + mvn package -DskipTests -Dbuildver="$E2E_TEST_SPARK_BUILD_VERSION" -Dhadoop.version="$E2E_TEST_HADOOP_VERSION" + popd +} + +install_python_package() { + if [ -z "$E2E_TEST_VENV_DIR" ]; then + err "Please set E2E_TEST_VENV_DIR to the name of the virtual environment. Exiting script." + fi + + echo "Setting up Python environment in $E2E_TEST_VENV_DIR" + local python_tools_dir="$E2E_TEST_TOOLS_DIR/user_tools" + python -m venv "$E2E_TEST_VENV_DIR" + source "$E2E_TEST_VENV_DIR"/bin/activate + + echo "Installing Spark RAPIDS Tools Python package" + pushd "$python_tools_dir" + pip install --upgrade pip setuptools wheel + pip install . + popd +} + +# Check if the Tools JAR file exists or if the user wants to build it +if [ ! -f "$E2E_TEST_TOOLS_JAR_PATH" ] || [ "$E2E_TEST_BUILD_JAR" = "true" ]; then + build_jar +fi + +install_python_package diff --git a/user_tools/tox.ini b/user_tools/tox.ini index 835cfb999..b7a766d98 100644 --- a/user_tools/tox.ini +++ b/user_tools/tox.ini @@ -9,20 +9,22 @@ envlist = coverage pylint flake8 + behave isolated_build = True [gh-actions] python = - 3.8: python3.8, pylint, flake8 - 3.9: python3.9, pylint, flake8 - 3.10: python3.10, pylint, flake8 - 3.11: python3.11, pylint, flake8 + 3.8: python3.8, pylint, flake8, behave + 3.9: python3.9, pylint, flake8, behave + 3.10: python3.10, pylint, flake8, behave + 3.11: python3.11, pylint, flake8, behave [testenv] deps = pytest pytest-cov cli_test_helpers + behave setenv = COVERAGE_FILE = {env:COVERAGE_FILE:{toxworkdir}/.coverage.{envname}} commands = @@ -63,3 +65,23 @@ commands = flake8 \ extend-ignore = E501, exclude = .tox,build,dist + +[testenv:behave] +deps = behave +passenv = JAVA_HOME +commands = behave {posargs} + +[behave] +paths = tests/spark_rapids_tools_e2e/features +stderr_capture = false + +[behave.userdata] +# Default maven arguments for building the Tools JAR +buildver = 350 +hadoop.version = 3.3.6 +# Default arguments for the behave tests +scala_version = 2.12 +venv_name = spark_rapids_tools_e2e_tests_venv +setup_script_file = setup_env.sh +build_jar = true +e2e_tests_tmp_dir = /tmp/spark_rapids_tools_e2e_tests