You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rspamd.robot 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. *** Settings ***
  2. Library Collections
  3. Library OperatingSystem
  4. Library Process
  5. *** Keywords ***
  6. Check Controller Errors
  7. @{result} = HTTP GET ${RSPAMD_LOCAL_ADDR} ${RSPAMD_PORT_CONTROLLER} /errors
  8. Should Be Equal As Integers ${result}[0] 200
  9. Log ${result}[1]
  10. Check Pidfile
  11. [Arguments] ${pidfile} ${timeout}=1 min
  12. Wait Until Created ${pidfile} timeout=${timeout}
  13. ${size} = Get File Size ${pidfile}
  14. Should Not Be Equal As Integers ${size} 0
  15. Check Rspamc
  16. [Arguments] ${result} @{args} &{kwargs}
  17. Run Keyword If ${result.rc} != 0 Log ${result.stderr}
  18. ${has_rc} = Evaluate 'rc' in $kwargs
  19. ${inverse} = Evaluate 'inverse' in $kwargs
  20. ${re} = Evaluate 're' in $kwargs
  21. ${rc} = Set Variable If ${has_rc} == True ${kwargs}[rc] 0
  22. FOR ${i} IN @{args}
  23. Run Keyword If ${re} == True Check Rspamc Match Regexp ${result.stdout} ${i} ${inverse}
  24. ... ELSE Check Rspamc Match String ${result.stdout} ${i} ${inverse}
  25. END
  26. Run Keyword If @{args} == @{EMPTY} Check Rspamc Match Default ${result.stdout} ${inverse}
  27. Should Be Equal As Integers ${result.rc} ${rc}
  28. Check Rspamc Match Default
  29. [Arguments] ${subject} ${inverse}
  30. Run Keyword If ${inverse} == False Should Contain ${subject} success = true
  31. ... ELSE Should Not Contain ${subject} success = true
  32. Check Rspamc Match Regexp
  33. [Arguments] ${subject} ${re} ${inverse}
  34. Run Keyword If ${inverse} == False Should Match Regexp ${subject} ${re}
  35. ... ELSE Should Not Match Regexp ${subject} ${re}
  36. Check Rspamc Match String
  37. [Arguments] ${subject} ${str} ${inverse}
  38. Run Keyword If ${inverse} == False Should Contain ${subject} ${str}
  39. ... ELSE Should Not Contain ${subject} ${str}
  40. Do Not Expect Symbol
  41. [Arguments] ${symbol}
  42. Dictionary Should Not Contain Key ${SCAN_RESULT}[symbols] ${symbol}
  43. ... msg=Symbol ${symbol} was not expected to be found in result
  44. Do Not Expect Symbols
  45. [Arguments] @{symbols}
  46. FOR ${symbol} IN @{symbols}
  47. Dictionary Should Not Contain Key ${SCAN_RESULT}[symbols] ${symbol}
  48. ... msg=Symbol ${symbol} was not expected to be found in result
  49. END
  50. Expect Action
  51. [Arguments] ${action}
  52. Should Be Equal ${SCAN_RESULT}[action] ${action}
  53. Expect Email
  54. [Arguments] ${email}
  55. List Should Contain Value ${SCAN_RESULT}[emails] ${email}
  56. Expect Required Score
  57. [Arguments] ${required_score}
  58. Should Be Equal As Numbers ${SCAN_RESULT}[required_score] ${required_score}
  59. Expect Required Score To Be Null
  60. Should Be Equal ${SCAN_RESULT}[required_score] ${NONE}
  61. Expect Score
  62. [Arguments] ${score}
  63. Should Be Equal As Numbers ${SCAN_RESULT}[score] ${score}
  64. Expect Symbol
  65. [Arguments] ${symbol}
  66. Dictionary Should Contain Key ${SCAN_RESULT}[symbols] ${symbol}
  67. ... msg=Symbol ${symbol} wasn't found in result
  68. Expect URL
  69. [Arguments] ${url}
  70. List Should Contain Value ${SCAN_RESULT}[urls] ${url}
  71. Expect Extended URL
  72. [Arguments] ${url}
  73. ${found_url} = Set Variable ${FALSE}
  74. ${url_list} = Convert To List ${SCAN_RESULT}[urls]
  75. FOR ${item} IN @{url_list}
  76. ${d} = Convert To Dictionary ${item}
  77. ${found_url} = Evaluate "${d}[url]" == "${url}"
  78. Exit For Loop If ${found_url} == ${TRUE}
  79. END
  80. Should Be True ${found_url} msg="Expected URL was not found: ${url}"
  81. Expect Symbol With Exact Options
  82. [Arguments] ${symbol} @{options}
  83. Expect Symbol ${symbol}
  84. ${have_options} = Convert To List ${SCAN_RESULT}[symbols][${symbol}][options]
  85. Lists Should Be Equal ${have_options} ${options} ignore_order=True
  86. ... msg="Symbol ${symbol} has options ${SCAN_RESULT}[symbols][${symbol}][options] but expected ${options}"
  87. Expect Symbol With Option
  88. [Arguments] ${symbol} ${option}
  89. Expect Symbol ${symbol}
  90. ${have_options} = Convert To List ${SCAN_RESULT}[symbols][${symbol}][options]
  91. Should Contain ${have_options} ${option}
  92. ... msg="Options for symbol ${symbol} ${SCAN_RESULT}[symbols][${symbol}][options] doesn't contain ${option}"
  93. Expect Symbol With Score
  94. [Arguments] ${symbol} ${score}
  95. Dictionary Should Contain Key ${SCAN_RESULT}[symbols] ${symbol}
  96. ... msg=Symbol ${symbol} wasn't found in result
  97. Should Be Equal As Numbers ${SCAN_RESULT}[symbols][${symbol}][score] ${score}
  98. ... msg="Symbol ${symbol} has score of ${SCAN_RESULT}[symbols][${symbol}][score] but expected ${score}"
  99. Expect Symbols
  100. [Arguments] @{symbols}
  101. FOR ${symbol} IN @{symbols}
  102. Dictionary Should Contain Key ${SCAN_RESULT}[symbols] ${symbol}
  103. ... msg=Symbol ${symbol} wasn't found in result
  104. END
  105. Expect Symbols With Scores
  106. [Arguments] &{symscores}
  107. FOR ${key} ${value} IN &{symscores}
  108. Dictionary Should Contain Key ${SCAN_RESULT}[symbols] ${key}
  109. ... msg=Symbol ${key} wasn't found in result
  110. Should Be Equal As Numbers ${SCAN_RESULT}[symbols][${key}][score] ${value}
  111. ... msg="Symbol ${key} has score of ${SCAN_RESULT}[symbols][${key}][score] but expected ${value}"
  112. END
  113. Expect Symbol With Score And Exact Options
  114. [Arguments] ${symbol} ${score} @{options}
  115. Expect Symbol With Exact Options ${symbol} @{options}
  116. Expect Symbol With Score ${symbol} ${score}
  117. Export Rspamd Variables To Environment
  118. &{all_vars} = Get Variables no_decoration=True
  119. FOR ${k} ${v} IN &{all_vars}
  120. Run Keyword If '${k}'.startswith("RSPAMD_") Set Environment Variable ${k} ${v}
  121. END
  122. Export Scoped Variables
  123. [Arguments] ${scope} &{vars}
  124. FOR ${k} ${v} IN &{vars}
  125. Run Keyword If '${scope}' == 'Test' Set Test Variable ${${k}} ${v}
  126. ... ELSE IF '${scope}' == 'Suite' Set Suite Variable ${${k}} ${v}
  127. ... ELSE IF '${scope}' == 'Global' Set Global Variable ${${k}} ${v}
  128. ... ELSE Fail message="Don't know what to do with scope: ${scope}"
  129. END
  130. Log does not contain segfault record
  131. ${log} = Get File ${RSPAMD_TMPDIR}/rspamd.log encoding_errors=ignore
  132. Should not contain ${log} (Segmentation fault) msg=Segmentation fault detected
  133. Redis HSET
  134. [Arguments] ${hash} ${key} ${value}
  135. ${result} = Run Process redis-cli -h ${RSPAMD_REDIS_ADDR} -p ${RSPAMD_REDIS_PORT}
  136. ... HSET ${hash} ${key} ${value}
  137. Run Keyword If ${result.rc} != 0 Log ${result.stderr}
  138. Log ${result.stdout}
  139. Should Be Equal As Integers ${result.rc} 0
  140. Redis SET
  141. [Arguments] ${key} ${value}
  142. ${result} = Run Process redis-cli -h ${RSPAMD_REDIS_ADDR} -p ${RSPAMD_REDIS_PORT}
  143. ... SET ${key} ${value}
  144. Run Keyword If ${result.rc} != 0 Log ${result.stderr}
  145. Log ${result.stdout}
  146. Should Be Equal As Integers ${result.rc} 0
  147. Redis Teardown
  148. ${redis_pid} = Get Variable Value ${REDIS_PID}
  149. Shutdown Process With Children ${redis_pid}
  150. Cleanup Temporary Directory ${REDIS_TMPDIR}
  151. Rspamd Setup
  152. # Create and chown temporary directory
  153. ${RSPAMD_TMPDIR} = Make Temporary Directory
  154. Set Directory Ownership ${RSPAMD_TMPDIR} ${RSPAMD_USER} ${RSPAMD_GROUP}
  155. # Export ${RSPAMD_TMPDIR} to appropriate scope according to ${RSPAMD_SCOPE}
  156. Export Scoped Variables ${RSPAMD_SCOPE} RSPAMD_TMPDIR=${RSPAMD_TMPDIR}
  157. Run Rspamd
  158. Rspamd Redis Setup
  159. Run Redis
  160. Rspamd Setup
  161. Rspamd Teardown
  162. # Robot Framework 4.0
  163. #Run Keyword If '${CONTROLLER_ERRORS}' == 'True' Run Keyword And Warn On Failure Check Controller Errors
  164. Run Keyword If '${CONTROLLER_ERRORS}' == 'True' Check Controller Errors
  165. Shutdown Process With Children ${RSPAMD_PID}
  166. Save Run Results ${RSPAMD_TMPDIR} configdump.stdout configdump.stderr rspamd.stderr rspamd.stdout rspamd.conf rspamd.log redis.log clickhouse-config.xml
  167. Log does not contain segfault record
  168. Collect Lua Coverage
  169. Cleanup Temporary Directory ${RSPAMD_TMPDIR}
  170. Rspamd Redis Teardown
  171. Rspamd Teardown
  172. Redis Teardown
  173. Run Redis
  174. ${RSPAMD_TMPDIR} = Make Temporary Directory
  175. ${template} = Get File ${RSPAMD_TESTDIR}/configs/redis-server.conf
  176. ${config} = Replace Variables ${template}
  177. Create File ${RSPAMD_TMPDIR}/redis-server.conf ${config}
  178. Log ${config}
  179. ${result} = Run Process redis-server ${RSPAMD_TMPDIR}/redis-server.conf
  180. Run Keyword If ${result.rc} != 0 Log ${result.stderr}
  181. Should Be Equal As Integers ${result.rc} 0
  182. Wait Until Keyword Succeeds 5x 1 sec Check Pidfile ${RSPAMD_TMPDIR}/redis.pid timeout=0.5s
  183. Wait Until Keyword Succeeds 5x 1 sec Redis Check ${RSPAMD_REDIS_ADDR} ${RSPAMD_REDIS_PORT}
  184. ${REDIS_PID} = Get File ${RSPAMD_TMPDIR}/redis.pid
  185. ${REDIS_PID} = Convert To Number ${REDIS_PID}
  186. Export Scoped Variables ${REDIS_SCOPE} REDIS_PID=${REDIS_PID} REDIS_TMPDIR=${RSPAMD_TMPDIR}
  187. ${redis_log} = Get File ${RSPAMD_TMPDIR}/redis.log
  188. Log ${redis_log}
  189. Run Rspamd
  190. Export Rspamd Variables To Environment
  191. # Dump templated config or errors to log
  192. ${result} = Run Process ${RSPAMADM}
  193. ... --var\=TMPDIR\=${RSPAMD_TMPDIR}
  194. ... --var\=DBDIR\=${RSPAMD_TMPDIR}
  195. ... --var\=LOCAL_CONFDIR\=/non-existent
  196. ... --var\=CONFDIR\=${RSPAMD_TESTDIR}/../../conf/
  197. ... configdump -c ${CONFIG}
  198. ... env:RSPAMD_LOCAL_CONFDIR=/non-existent
  199. ... env:RSPAMD_TMPDIR=${RSPAMD_TMPDIR}
  200. ... env:RSPAMD_CONFDIR=${RSPAMD_TESTDIR}/../../conf/
  201. ... env:LD_LIBRARY_PATH=${RSPAMD_TESTDIR}/../../contrib/aho-corasick
  202. ... env:RSPAMD_NO_CLEANUP=1
  203. ... env:ASAN_OPTIONS=quarantine_size_mb=2048:malloc_context_size=20:fast_unwind_on_malloc=0:log_path=${RSPAMD_TMPDIR}/rspamd-asan
  204. # We need to send output to files (or discard output) to avoid hanging Robot
  205. ... stdout=${RSPAMD_TMPDIR}/configdump.stdout stderr=${RSPAMD_TMPDIR}/configdump.stderr
  206. ${configdump} = Run Keyword If ${result.rc} == 0 Get File ${RSPAMD_TMPDIR}/configdump.stdout
  207. ... ELSE Get File ${RSPAMD_TMPDIR}/configdump.stderr
  208. Log ${configdump}
  209. # Fix directory ownership (maybe do this somewhere else)
  210. Set Directory Ownership ${RSPAMD_TMPDIR} ${RSPAMD_USER} ${RSPAMD_GROUP}
  211. # Run Rspamd
  212. ${result} = Run Process ${RSPAMD} -u ${RSPAMD_USER} -g ${RSPAMD_GROUP}
  213. ... -c ${CONFIG}
  214. ... --var\=TMPDIR\=${RSPAMD_TMPDIR}
  215. ... --var\=DBDIR\=${RSPAMD_TMPDIR}
  216. ... --var\=LOCAL_CONFDIR\=/non-existent
  217. ... --var\=CONFDIR\=${RSPAMD_TESTDIR}/../../conf/
  218. ... env:RSPAMD_LOCAL_CONFDIR=/non-existent
  219. ... env:RSPAMD_TMPDIR=${RSPAMD_TMPDIR}
  220. ... env:RSPAMD_CONFDIR=${RSPAMD_TESTDIR}/../../conf/
  221. ... env:LD_LIBRARY_PATH=${RSPAMD_TESTDIR}/../../contrib/aho-corasick
  222. ... env:RSPAMD_NO_CLEANUP=1
  223. ... env:ASAN_OPTIONS=quarantine_size_mb=2048:malloc_context_size=20:fast_unwind_on_malloc=0:log_path=${RSPAMD_TMPDIR}/rspamd-asan
  224. ... stdout=${RSPAMD_TMPDIR}/rspamd.stdout stderr=${RSPAMD_TMPDIR}/rspamd.stderr
  225. # Log stdout/stderr
  226. ${rspamd_stdout} = Get File ${RSPAMD_TMPDIR}/rspamd.stdout
  227. ${rspamd_stderror} = Get File ${RSPAMD_TMPDIR}/rspamd.stderr
  228. Log ${rspamd_stdout}
  229. Log ${rspamd_stderror}
  230. # Abort if it failed
  231. Should Be Equal As Integers ${result.rc} 0
  232. # Wait for pid file to be written
  233. Wait Until Keyword Succeeds 10x 1 sec Check Pidfile ${RSPAMD_TMPDIR}/rspamd.pid timeout=0.5s
  234. # Confirm worker is reachable
  235. Wait Until Keyword Succeeds 5x 1 sec Ping Rspamd ${RSPAMD_LOCAL_ADDR} ${RSPAMD_PORT_NORMAL}
  236. # Read PID from PIDfile and export it to appropriate scope as ${RSPAMD_PID}
  237. ${RSPAMD_PID} = Get File ${RSPAMD_TMPDIR}/rspamd.pid
  238. Export Scoped Variables ${RSPAMD_SCOPE} RSPAMD_PID=${RSPAMD_PID}
  239. Run Nginx
  240. ${template} = Get File ${RSPAMD_TESTDIR}/configs/nginx.conf
  241. ${config} = Replace Variables ${template}
  242. Create File ${RSPAMD_TMPDIR}/nginx.conf ${config}
  243. Log ${config}
  244. ${result} = Run Process nginx -c ${RSPAMD_TMPDIR}/nginx.conf
  245. Run Keyword If ${result.rc} != 0 Log ${result.stderr}
  246. Should Be Equal As Integers ${result.rc} 0
  247. Wait Until Keyword Succeeds 10x 1 sec Check Pidfile ${RSPAMD_TMPDIR}/nginx.pid timeout=0.5s
  248. Wait Until Keyword Succeeds 5x 1 sec TCP Connect ${NGINX_ADDR} ${NGINX_PORT}
  249. ${NGINX_PID} = Get File ${RSPAMD_TMPDIR}/nginx.pid
  250. Run Keyword If '${NGINX_SCOPE}' == 'Test' Set Test Variable ${NGINX_PID}
  251. ... ELSE IF '${NGINX_SCOPE}' == 'Suite' Set Suite Variable ${NGINX_PID}
  252. ${nginx_log} = Get File ${RSPAMD_TMPDIR}/nginx.log
  253. Log ${nginx_log}
  254. Run Rspamc
  255. [Arguments] @{args}
  256. ${result} = Run Process ${RSPAMC} -t 60 --header Queue-ID\=${TEST NAME}
  257. ... @{args} env:LD_LIBRARY_PATH=${RSPAMD_TESTDIR}/../../contrib/aho-corasick
  258. Log ${result.stdout}
  259. [Return] ${result}
  260. Scan File By Reference
  261. [Arguments] ${filename} &{headers}
  262. Set To Dictionary ${headers} File=${filename}
  263. ${result} = Scan File /dev/null &{headers}
  264. [Return] ${result}
  265. Scan Message With Rspamc
  266. [Arguments] ${msg_file} @{vargs}
  267. ${result} = Run Rspamc -p -h ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_NORMAL} @{vargs} ${msg_file}
  268. [Return] ${result}
  269. Sync Fuzzy Storage
  270. [Arguments] @{vargs}
  271. ${len} = Get Length ${vargs}
  272. ${result} = Run Keyword If $len == 0 Run Process ${RSPAMADM} control -s
  273. ... ${RSPAMD_TMPDIR}/rspamd.sock fuzzy_sync
  274. ... ELSE Run Process ${RSPAMADM} control -s ${vargs}[0]/rspamd.sock
  275. ... fuzzy_sync
  276. Log ${result.stdout}
  277. Sleep 0.1s Try give fuzzy storage time to sync
  278. Run Dummy Http
  279. ${fileExists} = File Exists /tmp/dummy_http.pid
  280. ${http_pid} = Run Keyword If ${fileExists} is True Get File /tmp/dummy_http.pid
  281. Run Keyword If ${fileExists} is True Shutdown Process With Children ${http_pid}
  282. ${result} = Start Process ${RSPAMD_TESTDIR}/util/dummy_http.py -pf /tmp/dummy_http.pid
  283. Wait Until Created /tmp/dummy_http.pid timeout=2 second
  284. Run Dummy Https
  285. ${fileExists} = File Exists /tmp/dummy_https.pid
  286. ${http_pid} = Run Keyword If ${fileExists} is True Get File /tmp/dummy_https.pid
  287. Run Keyword If ${fileExists} is True Shutdown Process With Children ${http_pid}
  288. ${result} = Start Process ${RSPAMD_TESTDIR}/util/dummy_http.py
  289. ... -c ${RSPAMD_TESTDIR}/util/server.pem -k ${RSPAMD_TESTDIR}/util/server.pem
  290. ... -pf /tmp/dummy_https.pid -p 18081
  291. Wait Until Created /tmp/dummy_https.pid timeout=2 second
  292. Dummy Http Teardown
  293. ${http_pid} = Get File /tmp/dummy_http.pid
  294. Shutdown Process With Children ${http_pid}
  295. Dummy Https Teardown
  296. ${https_pid} = Get File /tmp/dummy_https.pid
  297. Shutdown Process With Children ${https_pid}