PageRenderTime 47ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/test/unit/unsafe_mysql_functions_test.rb

https://github.com/alphagov/whitehall
Ruby | 56 lines | 43 code | 5 blank | 8 comment | 2 complexity | 92917a9469ed97962238c7d6e5c4104b MD5 | raw file
  1. require "test_helper"
  2. class UnsafeMySQLFunctionsTest < ActiveSupport::TestCase
  3. def unsafe_functions
  4. %w[
  5. FOUND_ROWS()
  6. GET_LOCK()
  7. IS_FREE_LOCK()
  8. IS_USED_LOCK()
  9. LOAD_FILE()
  10. MASTER_POS_WAIT()
  11. RAND()
  12. RELEASE_LOCK()
  13. ROW_COUNT()
  14. SESSION_USER()
  15. SLEEP()
  16. SYSDATE()
  17. SYSTEM_USER()
  18. USER()
  19. UUID()
  20. UUID_SHORT()
  21. ]
  22. end
  23. def unsafe_function_regex
  24. escaped_functions = unsafe_functions.map { |function| Regexp.escape(function) }
  25. Regexp.new(
  26. "(#{escaped_functions.join('|')})",
  27. Regexp::IGNORECASE,
  28. )
  29. end
  30. test "no (suspected) uses of MySQL functions which are unsafe with statement-based replication" do
  31. files = Dir.glob(Rails.root.join("**/*.rb"))
  32. bad_files = files.select do |filename|
  33. next if filename == File.expand_path(__FILE__)
  34. match = false
  35. File.open(filename) do |file|
  36. match = file.grep(unsafe_function_regex).any?
  37. end
  38. match
  39. end
  40. # This test is case insensitive so has the potential to return false
  41. # positives. If it does return a false positive, you might:
  42. #
  43. # * remove the parentheses from the Ruby method call
  44. # * tweak this test - eg we're unlikely to call MySQL's USER() function,
  45. # but we might call current_user() in our code
  46. #
  47. # For more details: http://dev.mysql.com/doc/refman/5.5/en/replication-rbr-safe-unsafe.html
  48. message = "Found suspected calls to MySQL functions which are unsafe with statement-based replication."
  49. assert_equal [], bad_files, message
  50. end
  51. end