Module: Beaker::LoggerJunit

Defined in:
lib/beaker/logger_junit.rb

Overview

The Beaker JUnit Logger class This module handles message reporting from Beaker to the JUnit format

There is a specific pattern for using this class. Here’s a list of example usages:

Class Method Summary collapse

Class Method Details

.copy_stylesheet_into_xml_dir(stylesheet, xml_file) ⇒ Object

copies given stylesheet into the directory of the xml file given

Parameters:

  • stylesheet (String)

    Path to the stylesheet file

  • xml_file (String)

    Path to the xml file

Returns:

  • nil



69
70
71
72
73
# File 'lib/beaker/logger_junit.rb', line 69

def self.copy_stylesheet_into_xml_dir(stylesheet, xml_file)
  if not File.file?(File.join(File.dirname(xml_file), File.basename(stylesheet)))
    FileUtils.copy(stylesheet, File.join(File.dirname(xml_file), File.basename(stylesheet)))
  end
end

.escape_invalid_xml_chars(string) ⇒ String

Escape invalid XML UTF-8 codes from provided string, see www.w3.org/TR/xml/#charsets for valid character specification

Parameters:

  • string (String)

    The string to remove invalid codes from

Returns:

  • (String)

    Properly escaped string



130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/beaker/logger_junit.rb', line 130

def self.escape_invalid_xml_chars string
  escaped_string = ""
  string.chars.each do |i|
    char_as_codestring = i.unpack("U*").join
    if self.is_valid_xml(char_as_codestring.to_i)
      escaped_string << i
    else
      escaped_string << "\\#{char_as_codestring}"
    end
  end
  escaped_string
end

.finish(doc, xml_file) ⇒ Object

writes out xml content for a doc

Parameters:

  • doc (Nokogiri::XML)

    Nokogiri doc containing content to write

  • xml_file (String)

    Path to the xml file to write

Returns:

  • nil



41
42
43
44
45
# File 'lib/beaker/logger_junit.rb', line 41

def self.finish(doc, xml_file)
  # junit/name.xml will be created in a directory relative to the CWD
  # --  JLS 2/12
  File.open(xml_file, 'w') { |fh| fh.write(doc.to_xml) }
end

.format_cdata(string) ⇒ String

Remove color codes and invalid XML characters from provided string

Parameters:

  • string (String)

    The string to format

Returns:

  • (String)

    the correctly formatted cdata



122
123
124
# File 'lib/beaker/logger_junit.rb', line 122

def self.format_cdata string
  self.escape_invalid_xml_chars(Logger.strip_color_codes(string))
end

.get_doc_for_filename(filename, stylesheet, already_exists) ⇒ Nokogiri::XML

gives the document object for a particular file

Parameters:

  • filename (String)

    Path to the file that you’re opening

  • stylesheet (String)

    Path to the stylesheet for this doc

  • already_exists (Boolean)

    Whether or not the file already exists

Returns:

  • (Nokogiri::XML)

    Doc that you want to write in



106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/beaker/logger_junit.rb', line 106

def self.get_doc_for_filename(filename, stylesheet, already_exists)
  if already_exists
    doc           = Nokogiri::XML(File.open(filename, 'r'))
  else
    #no existing file, create a new one
    doc           = Nokogiri::XML::Document.new()
    doc.encoding  = 'UTF-8'
    pi            = Nokogiri::XML::ProcessingInstruction.new(doc, "xml-stylesheet", "type=\"text/xsl\" href=\"#{File.basename(stylesheet)}\"")
    pi.parent     = doc
  end
  return doc
end

.get_testsuites_from_doc(doc, name, already_existed) ⇒ Nokogiri::XML::Node

sets up doc & gives us the suites for the testsuite named

Parameters:

  • doc (Nokogiri::XML)

    Doc that you’re getting suites from

  • name (String)

    Testsuite node name

  • already_existed (Boolean)

    Whether or not the doc already existed

Returns:

  • (Nokogiri::XML::Node)

    testsuites



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/beaker/logger_junit.rb', line 82

def self.get_testsuites_from_doc(doc, name, already_existed)
  #check to see if an output file already exists, if it does add or replace test suite data
  if already_existed
    suites = doc.at_xpath('testsuites')
    #remove old data
    doc.search("//testsuite").each do |node|
      if node['name'] =~ /#{name}/
        node.unlink
      end
    end
  else
    suites        = Nokogiri::XML::Node.new('testsuites', doc)
    suites.parent = doc
  end
  return suites
end

.get_xml_contents(xml_file, name, stylesheet) ⇒ Nokogiri::XML, Nokogiri::XML::Node

gets the xml doc & suites in order to build your xml output on top of

Parameters:

  • xml_file (String)

    Path to the xml file

  • name (String)

    Name of the testsuite you’re writing

  • stylesheet (String)

    Path to the stylesheet file

Returns:

  • (Nokogiri::XML)

    doc to use for your xml content

  • (Nokogiri::XML::Node)

    suites to add your content to



55
56
57
58
59
60
61
# File 'lib/beaker/logger_junit.rb', line 55

def self.get_xml_contents(xml_file, name, stylesheet)
  self.copy_stylesheet_into_xml_dir(stylesheet, xml_file)
  xml_file_already_exists = File.file?(xml_file)
  doc = self.get_doc_for_filename(xml_file, stylesheet, xml_file_already_exists)
  suites = self.get_testsuites_from_doc(doc, name, xml_file_already_exists)
  return doc, suites
end

.is_valid_xml(int) ⇒ Boolean

Determine if the provided number falls in the range of accepted xml unicode values See www.w3.org/TR/xml/#charsets for valid for valid character specifications.

Parameters:

  • int (Integer)

    The number to check against

Returns:

  • (Boolean)

    True, if the number corresponds to a valid xml unicode character, otherwise false



147
148
149
150
151
152
153
154
# File 'lib/beaker/logger_junit.rb', line 147

def self.is_valid_xml(int)
  return ( int == 0x9 or
    int == 0xA or
    ( int >= 0x0020 and int <= 0xD7FF ) or
    ( int >= 0xE000 and int <= 0xFFFD ) or
    ( int >= 0x100000 and int <= 0x10FFFF )
  )
end

.write_xml(xml_file, stylesheet, &block) ⇒ Object

writes the xml created in the block to the xml file given

Note: Error Recovery should take place in the caller of this method in order to recover gracefully

Parameters:

  • xml_file (String)

    Path to the xml file

  • stylesheet (String)

    Path to the stylesheet file

  • block (Proc)

    XML message construction block

Returns:

  • nil



20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/beaker/logger_junit.rb', line 20

def self.write_xml(xml_file, stylesheet, &block)
  doc, suites = self.get_xml_contents(xml_file, name, stylesheet)

  if block_given?
    case block.arity
    when 2
      yield doc, suites
    else
      raise ArgumentError.new "write_xml block takes 2 arguments, not #{block.arity}"
    end
  end

  self.finish(doc, xml_file)
end