Module: Bucky::TestEquipment::Verifications::StatusChecker

Includes:
Utils::Requests, Test::Unit::Assertions
Included in:
TestCase::LinkstatusTestCase
Defined in:
lib/bucky/test_equipment/verifications/status_checker.rb

Constant Summary

Constants included from Utils::Requests

Utils::Requests::USER_AGENT_STRING

Instance Method Summary collapse

Methods included from Utils::Requests

#get_response

Instance Method Details

#exclude(links, exclude_urls) ⇒ Object

Exclude non test target url



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/bucky/test_equipment/verifications/status_checker.rb', line 129

def exclude(links, exclude_urls)
  return links if exclude_urls.nil?

  excluded_links = links - exclude_urls

  # Exclude url if it has "*" in the last of it
  exclude_urls.each do |ex_url|
    if ex_url.end_with?('*')
      excluded_links.delete_if { |l| l.start_with?(ex_url.delete('*')) }
    elsif ex_url.start_with?('/') && ex_url.end_with?('/')
      ex_url.delete_prefix!('/').delete_suffix!('/')
      excluded_links.delete_if { |l| l.match(/#{ex_url}/) }
    end
  end

  excluded_links
end

#http_status_check(args) ⇒ String

Check http status code

Parameters:

  • url (String)

Returns:

  • (String)

    message



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/bucky/test_equipment/verifications/status_checker.rb', line 26

def http_status_check(args)
  url = args[:url]
  device = args[:device]
  link_check_max_times = args[:link_check_max_times]
  url_log = args[:url_log]
  redirect_count = args[:redirect_count]
  redirect_url_list = args[:redirect_url_list]

  # If number of requests is over redirect limit
  return { error_message: "\n[Redirect Error] #{url} is redirected more than #{REDIRECT_LIMIT}" } if redirect_count > REDIRECT_LIMIT

  begin
    check_result = check_log_and_get_response(url, device, link_check_max_times, url_log)
  rescue Net::ReadTimeout => e
    return { error_message: "#{e.message} Please check this url: #{url}" }
  end
  # If result include response continue to check, else return result
  !check_result.key?(:response) ? (return check_result) : response = check_result[:response]

  # Store original url
  redirect_url_list << url
  case response.code
  when /2[0-9]{2}/
    url_log[url][:entity] = response.entity
    puts "  #{url} ...  [#{response.code}:OK]"
    { entity: response.entity }
  when /3[0-9]{2}/
    http_status_check_args = { url: url, device: device, link_check_max_times: link_check_max_times, url_log: url_log, redirect_count: redirect_count + 1, redirect_url_list: redirect_url_list }
    redirect_and_http_status_check(response, http_status_check_args)
  when /(4|5)[0-9]{2}/
    url_log[url][:error_message] = "[Status Error] http status returned #{response.code}.\ncheck this url: #{redirect_url_list.join(' -> ')}"
    puts "  #{url} ...  [#{response.code}:NG]"
    { error_message: url_log[url][:error_message] }
  else
    url_log[url][:error_message] = "[Status Code Invalid Error] Status Code is Invalid. \n Status:#{response.code}"
    { error_message: url_log[url][:error_message] }
  end
end

#linkstatus_check(args) ⇒ Object

Raises:

  • (Test::Unit::AssertionFailedError)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/bucky/test_equipment/verifications/status_checker.rb', line 65

def linkstatus_check(args)
  url = args[:url]
  device = args[:device]
  exclude_urls = args[:exclude_urls]
  link_check_max_times = args[:link_check_max_times]
  url_log = args[:url_log]
  only_same_fqdn = args[:only_same_fqdn] ||= true

  # Extract base url and check if it is valid
  url_reg = %r{^(https?://([a-zA-Z0-9\-_.]+))}
  url_obj = url.match(url_reg)
  raise "Invalid URL #{url}" unless url_obj

  base_url  = url_obj[1]
  base_fqdn = url_obj[2]

  # Check base url
  http_status_check_args = { url: url, device: device, link_check_max_times: link_check_max_times, url_log: url_log, redirect_count: 0, redirect_url_list: [] }
  base_response = http_status_check(http_status_check_args)
  raise Test::Unit::AssertionFailedError, "Response of base URL is incorrect.\n#{base_response[:error_message]}" unless base_response[:error_message].nil?

  # Collect links
  links_args = { base_url: base_url, base_fqdn: base_fqdn, url_reg: url_reg, only_same_fqdn: only_same_fqdn, entity: base_response[:entity] }
  links = make_target_links(links_args)
  links = exclude(links, exclude_urls)

  errors = []
  Parallel.each(links.uniq, in_threads: Bucky::Utils::Config.instance[:linkstatus_thread_num]) do |link|
    http_status_check_args[:url] = link
    http_status_check_args[:redirect_url_list] = []
    link_response = http_status_check(http_status_check_args)
    errors << link_response[:error_message] if link_response[:error_message]
  end
  raise Test::Unit::AssertionFailedError, errors.join("\n") unless errors.empty?
end


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/bucky/test_equipment/verifications/status_checker.rb', line 101

def make_target_links(args)
  base_url = args[:base_url]
  base_fqdn = args[:base_fqdn]
  url_reg = args[:url_reg]
  # TODO: Add an option that can handle the check if href's fqdn is not same with base fqdn
  # only_same_fqdn = args[:only_same_fqdn]
  entity = args[:entity]
  doc = Nokogiri::HTML.parse(entity)
  links = []
  doc.xpath('//a').each do |node|
    href = node.attr('href')&.split(' ')&.first # Patch for nokogiri's bug
    next if exclude_href?(href)

    # Add fqdn if href doesn't include fqdn
    unless url_reg.match?(href)
      links << format_href(base_url, href)
      next
    end

    href_fqdn = href.match(url_reg)[2]
    # TODO: Enable after only_same_fqdn can be handle
    # links << href if only_same_fqdn == false || base_fqdn == href_fqdn
    links << href if base_fqdn == href_fqdn
  end
  links
end