dhcp_test_lib.sh.in 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. # Copyright (C) 2014-2015,2017 Internet Systems Consortium, Inc. ("ISC")
  2. #
  3. # This Source Code Form is subject to the terms of the Mozilla Public
  4. # License, v. 2.0. If a copy of the MPL was not distributed with this
  5. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. # A list of Kea processes, mainly used by the cleanup functions.
  7. KEA_PROCS="kea-dhcp4 kea-dhcp6 kea-dhcp-ddns kea-ctrl-agent"
  8. ### Logging functions ###
  9. # Prints error message.
  10. test_lib_error() {
  11. local s=${1} # Error message.
  12. local no_new_line=${2} # If specified, the message not terminated with
  13. # new line.
  14. printf "ERROR/test_lib: %s" "${s}"
  15. if [ -z ${no_new_line} ]; then
  16. printf "%s" "\n"
  17. fi
  18. }
  19. # Prints info message.
  20. test_lib_info() {
  21. local s=${1} # Info message.
  22. local no_new_line=${2} # If specified, the message is not terminated with
  23. # new line.
  24. printf "INFO/test_lib: %s" "${s}"
  25. if [ -z ${no_new_line} ]; then
  26. printf "%s" "\n"
  27. fi
  28. }
  29. ### Assertions ###
  30. # Assertion that checks if two numbers are equal.
  31. # If numbers are not equal, the mismatched values are presented and the
  32. # detailed error is printed. The detailed error must use the printf
  33. # formatting like this:
  34. # "Expected that some value 1 %d is equal to some other value %d".
  35. assert_eq() {
  36. val1=${1} # Reference value
  37. val2=${2} # Tested value
  38. detailed_err=${3} # Detailed error format string
  39. # If nothing found, present an error an exit.
  40. if [ ${val1} -ne ${val2} ]; then
  41. printf "Assertion failure: ${val1} != ${val2}, for val1=${val1}, val2=${val2}\n"
  42. printf "${detailed_err}\n" ${val1} ${val2}
  43. clean_exit 1
  44. fi
  45. }
  46. # Assertion that checks if two strings are equal.
  47. # If numbers are not equal, the mismatched values are presented and the
  48. # detailed error is printed. The detailed error must use the printf
  49. # formatting like this:
  50. # "Expected that some value 1 %d is equal to some other value %d".
  51. assert_str_eq() {
  52. val1=${1} # Reference value
  53. val2=${2} # Tested value
  54. detailed_err=${3} # Detailed error format string
  55. # If nothing found, present an error an exit.
  56. if [ "${val1}" != "${val2}" ]; then
  57. printf "Assertion failure: ${val1} != ${val2}, for val1=${val1}, val2=${val2}\n"
  58. printf "${detailed_err}\n" ${val1} ${val2}
  59. clean_exit 1
  60. fi
  61. }
  62. # Assertion that checks if one string contains another string.
  63. # If assertion fails, both strings are displayed and the detailed
  64. # error is printed. The detailed error must use the printf formatting
  65. # like this:
  66. # "Expected some string to contain this string: %s".
  67. assert_string_contains() {
  68. pattern="${1}" # Substring or awk pattern
  69. text="${2}" # Text to be searched for substring
  70. detailed_err="${3}" # Detailed error format string
  71. # Search for a pattern
  72. match=$( printf "%s" "${text}" | awk /"${pattern}"/ )
  73. # If nothing found, present an error and exit.
  74. if [ -z "${match}" ]; then
  75. printf "Assertion failure: \n\"%s\"\n\ndoesn't contain pattern:\n
  76. \"%s\"\n\n" "${text}" "${pattern}"
  77. printf "${detailed_err}\n" "\"${pattern}\""
  78. clean_exit 1
  79. fi
  80. }
  81. # Begins a test by prining its name.
  82. test_start() {
  83. TEST_NAME=${1}
  84. if [ -z ${TEST_NAME} ]; then
  85. test_lib_error "test_start requires test name as an argument"
  86. clean_exit 1
  87. fi
  88. printf "\nSTART TEST ${TEST_NAME}\n"
  89. }
  90. # Prints test result an cleans up after the test.
  91. test_finish() {
  92. local exit_code=${1} # Exit code to be returned by the exit function.
  93. if [ ${exit_code} -eq 0 ]; then
  94. cleanup
  95. printf "PASSED ${TEST_NAME}\n\n"
  96. else
  97. # Dump log file for debugging purposes if specified and exists.
  98. # Otherwise the code below would simply call cat.
  99. if [ -n "${LOG_FILE}" -a -s "${LOG_FILE}" ]; then
  100. printf "Log file dump:\n"
  101. cat ${LOG_FILE}
  102. fi
  103. cleanup
  104. printf "FAILED ${TEST_NAME}\n\n"
  105. fi
  106. }
  107. # Stores the configuration specified as a parameter in the configuration
  108. # file which name has been set in the ${CFG_FILE} variable.
  109. create_config() {
  110. local cfg="${1}" # Configuration string.
  111. if [ -z ${CFG_FILE} ]; then
  112. test_lib_error "create_config requires CFG_FILE variable be set"
  113. clean_exit 1
  114. elif [ -z "${cfg}" ]; then
  115. test_lib_error "create_config requires argument holding a configuration"
  116. clean_exit 1
  117. fi
  118. printf "Creating Kea configuration file: %s.\n" ${CFG_FILE}
  119. printf "%b" ${cfg} > ${CFG_FILE}
  120. }
  121. # Stores the keactrl configuration specified as a parameter in the
  122. # configuration file which name has been set in the ${KEACTRL_CFG_FILE}
  123. # variable.
  124. create_keactrl_config() {
  125. local cfg="${1}" # Configuration string.
  126. if [ -z ${KEACTRL_CFG_FILE} ]; then
  127. test_lib_error "create_keactrl_config requires KEACTRL_CFG_FILE \
  128. variable be set"
  129. clean_exit 1
  130. elif [ -z "${cfg}" ]; then
  131. test_lib_error "create_keactrl_config requires argument holding a \
  132. configuration"
  133. clean_exit 1
  134. fi
  135. printf "Creating keactrl configuration file: %s.\n" ${KEACTRL_CFG_FILE}
  136. printf "%b" ${cfg} > ${KEACTRL_CFG_FILE}
  137. }
  138. # Sets Kea logger to write to the file specified by the global value
  139. # ${LOG_FILE}.
  140. set_logger() {
  141. if [ -z ${LOG_FILE} ]; then
  142. test_lib_error "set_logger requies LOG_FILE variable be set"
  143. clean_exit 1
  144. fi
  145. printf "Kea log will be stored in %s.\n" ${LOG_FILE}
  146. export KEA_LOGGER_DESTINATION=${LOG_FILE}
  147. }
  148. # PID file path is by default <kea-install-dir>/var/kea, but can be
  149. # overridden by the environmental variable.
  150. PID_FILE_PATH=@localstatedir@/@PACKAGE@/
  151. if [ ! -z ${KEA_PIDFILE_DIR} ]; then
  152. PID_FILE_PATH="${KEA_PIDFILE_DIR}"
  153. fi
  154. # Checks if specified process is running.
  155. #
  156. # This function uses PID file to obtain the PID and then calls
  157. # 'kill -0 <pid>' to check if the process is alive.
  158. # The PID files are expected to be located in the ${PID_FILE_PATH},
  159. # and their names should match the following pattern:
  160. # <cfg_file_name>.<proc_name>.pid. If the <cfg_file_name> is not
  161. # specified a 'test_config' is used by default.
  162. #
  163. # Return value:
  164. # _GET_PID: holds a PID if process is running
  165. # _GET_PIDS_NUM: holds 1 if process is running, 0 otherwise
  166. get_pid() {
  167. local proc_name=${1} # Process name
  168. local cfg_file_name=${2} # Configuration file name without extension.
  169. # PID file name includes process name. The process name is required.
  170. if [ -z ${proc_name} ]; then
  171. test_lib_error "get_pid requires process name"
  172. clean_exit 1
  173. fi
  174. # PID file name includes server configuration file name. For most of
  175. # the tests it is 'test-config' (excluding .json extension). It is
  176. # possible to specify custom name if required.
  177. if [ -z ${cfg_file_name} ]; then
  178. cfg_file_name="test_config"
  179. fi
  180. # Get the absolute location of the PID file for the specified process
  181. # name.
  182. abs_pidfile_path="${PID_FILE_PATH}/${cfg_file_name}.${proc_name}.pid"
  183. _GET_PID=0
  184. _GET_PIDS_NUM=0
  185. # If the PID file exists, get the PID and see if the process is alive.
  186. if [ -e ${abs_pidfile_path} ]; then
  187. pid=$( cat $abs_pidfile_path )
  188. kill -0 ${pid} > /dev/null 2>&1
  189. if [ $? -eq 0 ]; then
  190. _GET_PID=${pid}
  191. _GET_PIDS_NUM=1
  192. fi
  193. fi
  194. }
  195. # Kills processes specified by name.
  196. #
  197. # This function kills all processes having a specified name.
  198. # It uses 'pgrep' to obtain pids of those processes.
  199. # This function should be used when identifying process by
  200. # the value in its PID file is not relevant.
  201. kill_processes_by_name() {
  202. local proc_name=${1} # Process name
  203. if [ -z ${proc_name} ]; then
  204. test_lib_error "get_pids requires process name"
  205. clean_exit 1
  206. fi
  207. # Obtain PIDs of running processes.
  208. local pids=$( pgrep ${proc_name} )
  209. # For each PID found, send kill signal.
  210. for pid in ${pids}
  211. do
  212. printf "Shutting down Kea process ${proc_name} having pid %d.\n" ${pid}
  213. kill -9 ${pid}
  214. done
  215. }
  216. # Returns the number of occurrences of the Kea log message in the log file.
  217. # Return value:
  218. # _GET_LOG_MESSAGES: number of log message occurrences.
  219. get_log_messages() {
  220. local msg="${1}" # Message id, e.g. DHCP6_SHUTDOWN
  221. if [ -z ${msg} ]; then
  222. test_lib_error "get_log_messages require message identifier"
  223. clean_exit 1
  224. fi
  225. _GET_LOG_MESSAGES=0
  226. # If log file is not present, the number of occurrences is 0.
  227. if [ -s ${LOG_FILE} ]; then
  228. # Grep log file for the logger message occurrences and remove
  229. # whitespaces, if any.
  230. _GET_LOG_MESSAGES=$( grep -o ${msg} ${LOG_FILE} | wc -w | tr -d " ")
  231. fi
  232. }
  233. # Returns the number of server configurations performed so far. Also
  234. # returns the number of configuration errors.
  235. # Return values:
  236. # _GET_RECONFIGS: number of configurations so far.
  237. # _GET_RECONFIG_ERRORS: number of configuration errors.
  238. get_reconfigs() {
  239. # Grep log file for CONFIG_COMPLETE occurrences. There should
  240. # be one occurrence per (re)configuration.
  241. _GET_RECONFIGS=$( grep -o CONFIG_COMPLETE ${LOG_FILE} | wc -w )
  242. # Grep log file for CONFIG_LOAD_FAIL to check for configuration
  243. # failures.
  244. _GET_RECONFIG_ERRORS=$( grep -o CONFIG_LOAD_FAIL ${LOG_FILE} | wc -w )
  245. # Remove whitespaces
  246. ${_GET_RECONFIGS##*[! ]}
  247. ${_GET_RECONFIG_ERRORS##*[! ]}
  248. }
  249. # Performs cleanup after test.
  250. # It shuts down running Kea processes and removes temporary files.
  251. # The location of the log file and the configuration files should be set
  252. # in the ${LOG_FILE}, ${CFG_FILE} and ${KEACTRL_CFG_FILE} variables
  253. # recpectively, prior to calling this function.
  254. cleanup() {
  255. # If there is no KEA_PROCS set, just return
  256. if [ -z "${KEA_PROCS}" ]; then
  257. return
  258. fi
  259. # KEA_PROCS holds the name of all Kea processes. Shut down each
  260. # of them if running.
  261. for proc_name in ${KEA_PROCS}
  262. do
  263. get_pid ${proc_name}
  264. # Shut down running Kea process.
  265. if [ ${_GET_PIDS_NUM} -ne 0 ]; then
  266. printf "Shutting down Kea proccess having pid %d.\n" ${_GET_PID}
  267. kill -9 ${_GET_PID}
  268. fi
  269. done
  270. # Kill any running LFC processes. Even though 'kea-lfc' creates PID
  271. # file we rather want to use 'pgrep' to find the process PID, because
  272. # kea-lfc execution is not controlled from the test and thus there
  273. # is possibility that process is already/still running but the PID
  274. # file doesn't exist for it. As a result, the process will not
  275. # be killed. This is not a problem for other processes because
  276. # tests control launching them and monitor when they are shut down.
  277. kill_processes_by_name "kea-lfc"
  278. # Remove temporary files.
  279. rm -rf ${LOG_FILE}
  280. # Use asterisk to remove all files starting with the given name,
  281. # in case the LFC has been run. LFC creates files with postfixes
  282. # appended to the lease file name.
  283. if [ ! -z "${LEASE_FILE}" ]; then
  284. rm -rf ${LEASE_FILE}*
  285. fi
  286. rm -rf ${CFG_FILE}
  287. rm -rf ${KEACTRL_CFG_FILE}
  288. }
  289. # Exists the test in the clean way.
  290. # It performs the cleanup and prints whether the test has passed or failed.
  291. # If a test fails, the Kea log is dumped.
  292. clean_exit() {
  293. exit_code=${1} # Exit code to be returned by the exit function.
  294. case ${exit_code} in
  295. ''|*[!0-9]*)
  296. test_lib_error "argument passed to clean_exit must be a number" ;;
  297. esac
  298. # Print test result and perform a cleanup
  299. test_finish ${exit_code}
  300. exit ${exit_code}
  301. }
  302. # Starts Kea process in background using a configuration file specified
  303. # in the global variable ${CFG_FILE}.
  304. start_kea() {
  305. local bin=${1}
  306. if [ -z ${bin} ]; then
  307. test_lib_error "binary name must be specified for start_kea"
  308. clean_exit 1
  309. fi
  310. printf "Running command %s.\n" "\"${bin} -c ${CFG_FILE}\""
  311. ${bin} -c ${CFG_FILE} &
  312. }
  313. # Waits with timeout for Kea to start.
  314. # This function repeatedly checks if the Kea log file has been created
  315. # and is non-empty. If it is, the function assumes that Kea has started.
  316. # It doesn't check the contents of the log file though.
  317. # If the log file doesn't exist the function sleeps for a second and
  318. # checks again. This is repeated until timeout is reached or non-empty
  319. # log file is found. If timeout is reached, the function reports an
  320. # error.
  321. # Return value:
  322. # _WAIT_FOR_KEA: 0 if Kea hasn't started, 1 otherwise
  323. wait_for_kea() {
  324. local timeout=${1} # Desired timeout in seconds.
  325. case ${timeout} in
  326. ''|*[!0-9]*)
  327. test_lib_error "argument passed to wait_for_kea must be a number"
  328. clean_exit 1 ;;
  329. esac
  330. local loops=0 # Loops counter
  331. _WAIT_FOR_KEA=0
  332. test_lib_info "wait_for_kea " "skip-new-line"
  333. while [ ! -s ${LOG_FILE} ] && [ ${loops} -le ${timeout} ]; do
  334. printf "."
  335. sleep 1
  336. loops=$( expr $loops + 1 )
  337. done
  338. printf "\n"
  339. if [ ${loops} -le ${timeout} ]; then
  340. _WAIT_FOR_KEA=1
  341. fi
  342. }
  343. # Waits for a specific message to occur in the Kea log file.
  344. # This function is called when the test expects specific message
  345. # to show up in the log file as a result of some action that has
  346. # been taken. Typically, the test expects that the message
  347. # is logged when the SIGHUP or SIGTERM signal has been sent to the
  348. # Kea process.
  349. # This function waits a specified number of seconds for the number
  350. # of message occurrences to show up. If the expected number of
  351. # message doesn't occur, the error status is returned.
  352. # Return value:
  353. # _WAIT_FOR_MESSAGE: 0 if the message hasn't occurred, 1 otherwise.
  354. wait_for_message() {
  355. local timeout=${1} # Expected timeout value in seconds.
  356. local message="${2}" # Expected message id.
  357. local occurrences=${3} # Number of expected occurrences.
  358. # Validate timeout
  359. case ${timeout} in
  360. ''|*[!0-9]*)
  361. test_lib_error "argument timeout passed to wait_for_message must \
  362. be a number"
  363. clean_exit 1 ;;
  364. esac
  365. # Validate message
  366. if [ -z ${message} ]; then
  367. test_lib_error "message id is a required argument for wait_for_message"
  368. clean_exit 1
  369. fi
  370. # Validate occurrences
  371. case ${occurrences} in
  372. ''|*[!0-9]*)
  373. test_lib_error "argument occurrences passed to wait_for_message \
  374. must be a number"
  375. clean_exit 1 ;;
  376. esac
  377. local loops=0 # Number of loops performed so far.
  378. _WAIT_FOR_MESSAGE=0
  379. test_lib_info "wait_for_message ${message}: " "skip-new-line"
  380. # Check if log file exists and if we reached timeout.
  381. while [ ${loops} -le ${timeout} ]; do
  382. printf "."
  383. # Check if the message has been logged.
  384. get_log_messages ${message}
  385. if [ ${_GET_LOG_MESSAGES} -ge ${occurrences} ]; then
  386. printf "\n"
  387. _WAIT_FOR_MESSAGE=1
  388. return
  389. fi
  390. # Message not recorded. Keep going.
  391. sleep 1
  392. loops=$( expr ${loops} + 1 )
  393. done
  394. printf "\n"
  395. # Timeout.
  396. }
  397. # Waits for server to be down.
  398. # Return value:
  399. # _WAIT_FOR_SERVER_DOWN: 1 if server is down, 0 if timeout occurred and the
  400. # server is still running.
  401. wait_for_server_down() {
  402. local timeout=${1} # Timeout specified in seconds.
  403. local proc_name=${2} # Server process name.
  404. case ${timeout} in
  405. ''|*[!0-9]*)
  406. test_lib_error "argument passed to wait_for_server_down must be a number"
  407. clean_exit 1 ;;
  408. esac
  409. local loops=0 # Loops counter
  410. _WAIT_FOR_SERVER_DOWN=0
  411. test_lib_info "wait_for_server_down ${proc_name}: " "skip-new-line"
  412. while [ ${loops} -le ${timeout} ]; do
  413. printf "."
  414. get_pid ${proc_name}
  415. if [ ${_GET_PIDS_NUM} -eq 0 ]; then
  416. printf "\n"
  417. _WAIT_FOR_SERVER_DOWN=1
  418. return
  419. fi
  420. sleep 1
  421. loops=$( expr $loops + 1 )
  422. done
  423. printf "\n"
  424. }
  425. # Sends specified signal to the Kea process.
  426. send_signal() {
  427. local sig=${1} # Signal number.
  428. local proc_name=${2} # Process name
  429. # Validate signal
  430. case ${sig} in
  431. ''|*[!0-9]*)
  432. test_lib_error "signal number passed to send_signal \
  433. must be a number"
  434. clean_exit 1 ;;
  435. esac
  436. # Validate process name
  437. if [ -z ${proc_name} ]; then
  438. test_lib_error "send_signal requires process name be passed as argument"
  439. clean_exit 1
  440. fi
  441. # Get Kea pid.
  442. get_pid ${proc_name}
  443. if [ ${_GET_PIDS_NUM} -ne 1 ]; then
  444. printf "ERROR: expected one Kea process to be started.\
  445. Found %d processes started.\n" ${_GET_PIDS_NUM}
  446. clean_exit 1
  447. fi
  448. printf "Sending signal ${sig} to Kea process (pid=%s).\n" ${_GET_PID}
  449. # Actually send a signal.
  450. kill -${sig} ${_GET_PID}
  451. }
  452. # Verifies that a server is up running by its PID file
  453. # The PID file is constructed from the given config file name and
  454. # binary name. If it exists and the PID it contains refers to a
  455. # live process it sets _SERVER_PID_FILE and _SERVER_PID to the
  456. # corresponding values. Otherwise, it emits an error and exits.
  457. verify_server_pid() {
  458. local bin_name="${1}" # binary name of the server
  459. local cfg_file="${2}" # config file name
  460. # We will construct the PID file name based on the server config
  461. # and binary name
  462. if [ -z ${bin_name} ]; then
  463. test_lib_error "verify_server_pid requires binary name"
  464. clean_exit 1
  465. fi
  466. if [ -z ${cfg_file} ]; then
  467. test_lib_error "verify_server_pid requires config file name"
  468. clean_exit 1
  469. fi
  470. # Only the file name portion of the config file is used, try and
  471. # extract it. NOTE if this "algorithm" changes this code will need
  472. # to be updated.
  473. fname=`basename ${cfg_file}`
  474. fname=`echo $fname | cut -f1 -d'.'`
  475. if [ -z ${fname} ]; then
  476. test_lib_error "verify_server_pid could not extract config name"
  477. clean_exit 1
  478. fi
  479. # Now we can build the name:
  480. pid_file="$KEA_PIDFILE_DIR/$fname.$bin_name.pid"
  481. if [ ! -e ${pid_file} ]; then
  482. printf "ERROR: PID file:[%s] does not exist\n" ${pid_file}
  483. clean_exit 1
  484. fi
  485. # File exists, does its PID point to a live process?
  486. pid=`cat ${pid_file}`
  487. kill -0 ${pid}
  488. if [ $? -ne 0 ]; then
  489. printf "ERROR: PID file:[%s] exists but PID:[%d] does not\n" \
  490. ${pid_file} ${pid}
  491. clean_exit 1
  492. fi
  493. # Make the values accessible to the caller
  494. _SERVER_PID="${pid}"
  495. _SERVER_PID_FILE="${pid_file}"
  496. }
  497. # This test verifies that the binary is reporting its version properly.
  498. version_test() {
  499. test_name=${1} # Test name
  500. # Log the start of the test and print test name.
  501. test_start ${test_name}
  502. # Remove dangling Kea instances and remove log files.
  503. cleanup
  504. REPORTED_VERSION="`${bin_path}/${bin} -v`"
  505. if test "${REPORTED_VERSION}" == "${EXPECTED_VERSION}"; then
  506. test_finish 0
  507. else
  508. printf "ERROR: Expected version ${EXPECTED_VERSION}, got ${REPORTED_VERSION}\n"
  509. test_finish 1
  510. fi
  511. }
  512. # This test verifies that the server is using logger variable
  513. # KEA_LOCKFILE_DIR properly (it should be used to point out to the directory,
  514. # where lockfile should be created. Also, "none" value means to not create
  515. # the lockfile at all).
  516. logger_vars_test() {
  517. test_name=${1} # Test name
  518. # Log the start of the test and print test name.
  519. test_start ${test_name}
  520. # Remove dangling Kea instances and remove log files.
  521. cleanup
  522. # Create bogus configuration file. We don't really want the server to start,
  523. # just want it to log something and die. Empty config is an easy way to
  524. # enforce that behavior.
  525. create_config "{ }"
  526. printf "Please ignore any config error messages.\n"
  527. # Remember old KEA_LOCKFILE_DIR
  528. KEA_LOCKFILE_DIR_OLD=${KEA_LOCKFILE_DIR}
  529. # Set lockfile directory to current directory.
  530. KEA_LOCKFILE_DIR=.
  531. # Start Kea.
  532. start_kea ${bin_path}/${bin}
  533. # Wait for Kea to process the invalid configuration and die.
  534. sleep 1
  535. # Check if it is still running. It should have terminated.
  536. get_pid ${bin}
  537. if [ ${_GET_PIDS_NUM} -ne 0 ]; then
  538. printf "ERROR: expected Kea process to not start. Found %d processes"
  539. printf " running.\n" ${_GET_PIDS_NUM}
  540. # Revert to the old KEA_LOCKFILE_DIR value
  541. KEA_LOCKFILE_DIR=${KEA_LOCKFILE_DIR_OLD}
  542. clean_exit 1
  543. fi
  544. if [ ! -f "./logger_lockfile" ]; then
  545. printf "ERROR: Expect ${bin} to create logger_lockfile in the\n"
  546. printf "current directory, but no such file exists.\n"
  547. # Revert to the old KEA_LOCKFILE_DIR value
  548. KEA_LOCKFILE_DIR=${KEA_LOCKFILE_DIR__OLD}
  549. clean_exit 1
  550. fi
  551. # Remove the lock file
  552. rm -f ./logger_lockfile
  553. # Tell Kea to NOT create logfiles at all
  554. KEA_LOCKFILE_DIR="none"
  555. # Start Kea.
  556. start_kea ${bin_path}/${bin}
  557. # Wait for Kea to process the invalid configuration and die.
  558. sleep 1
  559. # Check if it is still running. It should have terminated.
  560. get_pid ${bin}
  561. if [ ${_GET_PIDS_NUM} -ne 0 ]; then
  562. printf "ERROR: expected Kea process to not start. Found %d processes"
  563. printf " running.\n" ${_GET_PIDS_NUM}
  564. # Revert to the old KEA_LOCKFILE_DIR value
  565. KEA_LOCKFILE_DIR=${KEA_LOCKFILE_DIR_OLD}
  566. clean_exit 1
  567. fi
  568. if [ -f "./logger_lockfile" ]; then
  569. printf "ERROR: Expect ${bin} to NOT create logger_lockfile in the\n"
  570. printf "current directory, but the file exists."
  571. # Revert to the old KEA_LOCKFILE_DIR value
  572. KEA_LOCKFILE_DIR=${KEA_LOCKFILE_DIR_OLD}
  573. clean_exit 1
  574. fi
  575. # Revert to the old KEA_LOCKFILE_DIR value
  576. printf "Reverting KEA_LOCKFILE_DIR to ${KEA_LOCKFILE_DIR_OLD}\n"
  577. KEA_LOCKFILE_DIR=${KEA_LOCKFILE_DIR_OLD}
  578. test_finish 0
  579. }
  580. # This test verifies server PID file management
  581. # 1. It verifies that upon startup, the server creates a PID file
  582. # 2. It verifies the an attempt to start a second instance fails
  583. # due to pre-existing PID File/PID detection
  584. server_pid_file_test() {
  585. local server_cfg="${1}"
  586. local log_id="${2}"
  587. # Log the start of the test and print test name.
  588. test_start "${bin}.server_pid_file_test"
  589. # Remove dangling DHCP4 instances and remove log files.
  590. cleanup
  591. # Create new configuration file.
  592. create_config "${CONFIG}"
  593. # Instruct server to log to the specific file.
  594. set_logger
  595. # Start server
  596. start_kea ${bin_path}/${bin}
  597. # Wait up to 20s for server to start.
  598. wait_for_kea 20
  599. if [ ${_WAIT_FOR_KEA} -eq 0 ]; then
  600. printf "ERROR: timeout waiting for %s to start.\n" ${bin}
  601. clean_exit 1
  602. fi
  603. # Verify server is still running
  604. verify_server_pid ${bin} ${CFG_FILE}
  605. printf "PID file is [%s], PID is [%d]" ${_SERVER_PID_FILE} ${_SERVER_PID}
  606. # Now try to start a second one
  607. start_kea ${bin_path}/${bin}
  608. wait_for_message 10 "${log_id}" 1
  609. if [ ${_WAIT_FOR_MESSAGE} -eq 0 ]; then
  610. printf "ERROR: Second %s instance started? PID conflict not reported.\n" ${bin}
  611. clean_exit 1
  612. fi
  613. # Verify server is still running
  614. verify_server_pid ${bin} ${CFG_FILE}
  615. # All ok. Shut down the server and exit.
  616. test_finish 0
  617. }