Class: Bcpm::Tests::Environment
- Inherits:
-
Object
- Object
- Bcpm::Tests::Environment
- Defined in:
- lib/bcpm/tests/environment.rb
Overview
A match run for simulation purposes.
Each test case is its own anonymous class.
Instance Attribute Summary collapse
-
#build_log ⇒ Object
readonly
The build log, if the build happened.
-
#player_name ⇒ Object
readonly
Name of the player container for the enviornment.
Class Method Summary collapse
-
.new_player_name ⇒ Object
A player name guaranteed to be unique across the systme.
Instance Method Summary collapse
-
#available? ⇒ Boolean
True if the environment has been setup and can be used to run tests.
-
#build ⇒ Object
Builds the binaries for the player in this environment.
-
#file_op(op) ⇒ Object
Queue an operation that adds a file.
-
#file_ops ⇒ Object
Copies files from the test suite to the environment.
-
#fragment_regexp(label) ⇒ Object
Regular expression matching a code fragment.
-
#initialize(prebuilt_name = nil) ⇒ Environment
constructor
Creates a new environment blueprint.
-
#java_class(class_name) ⇒ Object
Short class name for a Java class given its fully qualified name.
-
#java_package(class_name) ⇒ Object
Package for a Java class given its fully qualified name.
-
#java_path(package_path, class_name) ⇒ Object
Path to .java source for a class.
-
#patch_op(op) ⇒ Object
Queue an operation that patches all source files.
-
#patch_ops ⇒ Object
Applies the patch operations to the source code in the environment.
-
#setup(suite_path) ⇒ Object
Puts together an environment according to the blueprint.
-
#suite_map_path(map_name) ⇒ Object
Path to the maps in the test suite for the player.
-
#teardown ⇒ Object
Undoes the effects of setup.
Constructor Details
#initialize(prebuilt_name = nil) ⇒ Environment
Creates a new environment blueprint.
Args:
prebuilt_name:: if given, the created blueprint points to an already-built environment
25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/bcpm/tests/environment.rb', line 25 def initialize(prebuilt_name = nil) @file_ops = [] @patch_ops = [] @build_log = nil if prebuilt_name @player_name = prebuilt_name @available = true else @player_name = self.class.new_player_name @available = false end end |
Instance Attribute Details
#build_log ⇒ Object (readonly)
The build log, if the build happened.
19 20 21 |
# File 'lib/bcpm/tests/environment.rb', line 19 def build_log @build_log end |
#player_name ⇒ Object (readonly)
Name of the player container for the enviornment.
16 17 18 |
# File 'lib/bcpm/tests/environment.rb', line 16 def player_name @player_name end |
Class Method Details
.new_player_name ⇒ Object
A player name guaranteed to be unique across the systme.
243 244 245 246 247 248 249 250 251 |
# File 'lib/bcpm/tests/environment.rb', line 243 def self.new_player_name # NOTE: Java doesn't like .s in it package names :) host = Socket.hostname.gsub(/[^A-Za-z_]/, '_') @prefix ||= "bcpmtest_#{host}_#{(Time.now.to_f * 1000).to_i}_#{$PID}" @counter ||= 0 @counter += 1 "#{@prefix}_#{@counter}" end |
Instance Method Details
#available? ⇒ Boolean
True if the environment has been setup and can be used to run tests.
67 68 69 |
# File 'lib/bcpm/tests/environment.rb', line 67 def available? @available end |
#build ⇒ Object
Builds the binaries for the player in this environment.
Called by setup, uses its environment.
Returns true for success, false for failure.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/bcpm/tests/environment.rb', line 202 def build uid = "bcpmbuild_#{Socket.hostname}_#{(Time.now.to_f * 1000).to_i}_#{$PID}" tempdir = File. File.join(Dir.tmpdir, 'bcpm', uid) FileUtils.mkdir_p tempdir build_log = File.join tempdir, 'build.log' build_file = File.join tempdir, 'build.xml' Bcpm::Match.write_build build_file, 'bc.conf' Bcpm::Match.run_build_script tempdir, build_file, build_log, 'build' @build_log = File.exist?(build_log) ? File.open(build_log, 'rb') { |f| f.read } : '' FileUtils.rm_rf tempdir @build_log.index("\nBUILD SUCCESSFUL\n") ? true : false end |
#file_op(op) ⇒ Object
Queue an operation that adds a file.
84 85 86 |
# File 'lib/bcpm/tests/environment.rb', line 84 def file_op(op) @file_ops << op end |
#file_ops ⇒ Object
Copies files from the test suite to the environment.
Called by setup, uses its environment.
96 97 98 99 100 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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/bcpm/tests/environment.rb', line 96 def file_ops @file_ops.each do |op| op_type, target, source = *op if op_type == :fragment target, target_fragment = *target source, source_fragment = *source end target = "#{@player_name}.#{target}" source = "#{@player_name}.#{source}" file_path = java_path @player_src, source next unless File.exist? file_path source_contents = File.read file_path case op_type when :file contents = source_contents when :fragment next unless fragment_match = fragment_regexp(source_fragment).match(source_contents) contents = fragment_match[0] end source_pkg = java_package source target_pkg = java_package target unless source_pkg == target_pkg contents.gsub! /(^|[^A-Za-z0-9_.])#{source_pkg}([^A-Za-z0-9_]|$)/, "\\1#{target_pkg}\\2" end source_class = java_class source target_class = java_class target unless source_class == target_class contents.gsub! /(^|[^A-Za-z0-9_])#{source_class}([^A-Za-z0-9_]|$)/, "\\1#{target_class}\\2" end file_path = java_path @player_src, target case op_type when :file next unless File.exist?(File.dirname(file_path)) when :fragment next unless File.exist?(file_path) source_contents = File.read file_path # Not using a string because source code might contain \1 which would confuse gsub. source_contents.gsub! fragment_regexp(target_fragment) do |match| "#{$1}\n#{contents}\n#{$3}" end contents = source_contents end File.open(file_path, 'wb') { |f| f.write contents } end end |
#fragment_regexp(label) ⇒ Object
Regular expression matching a code fragment.
The expression captures three groups: the fragment start marker, the fragment, and the fragment end marker.
221 222 223 |
# File 'lib/bcpm/tests/environment.rb', line 221 def fragment_regexp(label) /^([ \t]*\/\/\$[ \t]*\+mark\:[ \t]*#{label}\s)(.*)(\n[ \t]*\/\/\$[ \t]*\-mark\:[ \t]*#{label}\s)/m end |
#java_class(class_name) ⇒ Object
Short class name for a Java class given its fully qualified name.
237 238 239 240 |
# File 'lib/bcpm/tests/environment.rb', line 237 def java_class(class_name) index = class_name.rindex '.' index ? class_name[index + 1, class_name.length - index - 1] : class_name end |
#java_package(class_name) ⇒ Object
Package for a Java class given its fully qualified name.
231 232 233 234 |
# File 'lib/bcpm/tests/environment.rb', line 231 def java_package(class_name) index = class_name.rindex '.' index ? class_name[0, index] : '' end |
#java_path(package_path, class_name) ⇒ Object
Path to .java source for a class.
226 227 228 |
# File 'lib/bcpm/tests/environment.rb', line 226 def java_path(package_path, class_name) File.join(File.dirname(package_path), class_name.gsub('.', '/') + '.java') end |
#patch_op(op) ⇒ Object
Queue an operation that patches all source files.
89 90 91 |
# File 'lib/bcpm/tests/environment.rb', line 89 def patch_op(op) @patch_ops << op end |
#patch_ops ⇒ Object
Applies the patch operations to the source code in the environment.
Called by setup, uses its environment.
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/bcpm/tests/environment.rb', line 154 def patch_ops return if @patch_ops.empty? Dir.glob(File.join(@player_src, '**', '*.java')).each do |file| old_contents = File.read file lines = old_contents.split("\n") stubs_enabled = true 0.upto(lines.count - 1) do |i| line = lines[i] if directive_match = /^\s*\/\/\$(.*)$/.match(line) directive = directive_match[1] case directive.strip.downcase when '+stubs', '-stubs' stubs_enabled = directive[0] == ?+ end else @patch_ops.each do |op| op_type, target, source = *op case op_type when :stub_member if stubs_enabled line.gsub!(/(^|[^A-Za-z0-9_.])([A-Za-z0-9_.]*\.)?#{source}\(/) do |match| arg = ($2.nil? || $2.empty?) ? 'this' : $2[0..-2] "#{$1}#{player_name}.#{target}(#{arg}, " end end when :stub_static if stubs_enabled line.gsub! /(^|[^A-Za-z0-9_.])([A-Za-z0-9_.]*\.)?#{source}\(/, "\\1#{player_name}.#{target}(" end end end end end contents = lines.join("\n") File.open(file, 'wb') { |f| f.write contents } unless contents == old_contents end end |
#setup(suite_path) ⇒ Object
Puts together an environment according to the blueprint.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/bcpm/tests/environment.rb', line 40 def setup(suite_path) return true if @available begin test_player = File.basename suite_path @player_path = Bcpm::Player.checkpoint test_player, 'master', player_name raise "Failed to checkpoint player at #{suite_path}" unless @player_path @player_src = Bcpm::Player.package_path(@player_path) file_ops patch_ops unless build print "Test environment build failed! Some tests will not run!\n" print "#{@build_log}\n" return false end rescue Exception => e print "Failed setting up test environment! Some tests will not run!\n" print "#{e.class.name}: #{e.to_s}\n#{e.backtrace.join("\n")}\n\n" return false end @available = true end |
#suite_map_path(map_name) ⇒ Object
Path to the maps in the test suite for the player.
78 79 80 81 |
# File 'lib/bcpm/tests/environment.rb', line 78 def suite_map_path(map_name) File.join Bcpm::Player.local_root, player_name, 'suite', 'maps', map_name + '.xml' end |