spec/build/graph/graph_spec.rb in build-graph-1.2.0 vs spec/build/graph/graph_spec.rb in build-graph-1.2.1

- old
+ new

@@ -19,160 +19,156 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'process_graph' -module Build::Graph::GraphSpec - include ProcessGraph +RSpec.describe Build::Graph do + let(:group) {Process::Group.new} - RSpec.describe Build::Graph do - let(:group) {Process::Group.new} + let(:logger) {Logger.new($stderr).tap{|logger| logger.level = Logger::DEBUG}} + + it "shouldn't update mtime" do + test_glob = Build::Files::Glob.new(__dir__, "*.rb") + listing_output = Build::Files::Paths.directory(__dir__, ["listing.txt"]) - let(:logger) {Logger.new($stderr).tap{|logger| logger.level = Logger::DEBUG}} + FileUtils.rm_f listing_output.to_a - it "shouldn't update mtime" do - test_glob = Glob.new(__dir__, "*.rb") - listing_output = Paths.directory(__dir__, ["listing.txt"]) - - FileUtils.rm_f listing_output.to_a - - walker = Walker.for(ProcessTask, group) - - top = ProcessNode.top do - process test_glob, listing_output do - run("ls", "-la", *inputs, :out => outputs.first.for_writing) - end + walker = Build::Graph::Walker.for(ProcessTask, group) + + top = ProcessNode.top do + process test_glob, listing_output do + run("ls", "-la", *inputs, :out => outputs.first.for_writing) end - - group.wait do - walker.update(top) - end - - first_modified_time = listing_output.first.modified_time - - group.wait do - walker.update(top) - end - - # The output file shouldn't have been changed because already exists and the input files haven't changed either: - second_modified_time = listing_output.first.modified_time - - # The granularity of mtime on some systems is a bit weird: - expect(second_modified_time.to_f).to be_within(0.001).of(first_modified_time.to_f) - - FileUtils.rm_f listing_output.to_a - walker.monitor.update(listing_output.roots) - - # The granularity of modification times isn't that great, so we use >= below. - # sleep 1 - - group.wait do - walker.update(top) - end - - expect(listing_output.first.modified_time).to be >= first_modified_time - - FileUtils.rm_f listing_output.to_a end - it "should compile program and respond to changes in source code" do - program_root = Path.join(__dir__, "program") - code_glob = Glob.new(program_root, "*.cpp") - program_path = Path.join(program_root, "dictionary-sort") - - walker = Walker.for(ProcessTask, group) - - #FileUtils.touch(code_glob.first) - - top = ProcessNode.top do - process code_glob, program_path do - object_files = inputs.with(extension: ".o") do |input_path, output_path| - depfile_path = input_path + ".d" + group.wait do + walker.update(top) + end + + first_modified_time = listing_output.first.modified_time + + group.wait do + walker.update(top) + end + + # The output file shouldn't have been changed because already exists and the input files haven't changed either: + second_modified_time = listing_output.first.modified_time + + # The granularity of mtime on some systems is a bit weird: + expect(second_modified_time.to_f).to be_within(0.001).of(first_modified_time.to_f) + + FileUtils.rm_f listing_output.to_a + walker.monitor.update(listing_output.roots) + + # The granularity of modification times isn't that great, so we use >= below. + # sleep 1 + + group.wait do + walker.update(top) + end + + expect(listing_output.first.modified_time).to be >= first_modified_time + + FileUtils.rm_f listing_output.to_a + end + + it "should compile program and respond to changes in source code" do + program_root = Build::Files::Path.join(__dir__, "program") + code_glob = Build::Files::Glob.new(program_root, "*.cpp") + program_path = Build::Files::Path.join(program_root, "dictionary-sort") + + walker = Build::Graph::Walker.for(ProcessTask, group) + + #FileUtils.touch(code_glob.first) + + top = ProcessNode.top do + process code_glob, program_path do + object_files = inputs.with(extension: ".o") do |input_path, output_path| + depfile_path = input_path + ".d" + + dependencies = Build::Files::Paths.new(input_path) + + if File.exist? depfile_path + depfile = Build::Makefile.load_file(depfile_path) - dependencies = Paths.new(input_path) - - if File.exist? depfile_path - depfile = Build::Makefile.load_file(depfile_path) - - dependencies = depfile[output_path] || dependencies - end - - process dependencies, output_path do - run("clang++", "-MMD", "-O3", - "-o", output_path.shortest_path(input_path.root), - "-c", input_path.relative_path, "-std=c++11", - chdir: input_path.root - ) - end + dependencies = depfile[output_path] || dependencies end - process object_files, program_path do - run("clang++", "-O3", "-o", program_path, *object_files.to_a, "-lm", "-pthread") + process dependencies, output_path do + run("clang++", "-MMD", "-O3", + "-o", output_path.shortest_path(input_path.root), + "-c", input_path.relative_path, "-std=c++11", + chdir: input_path.root + ) end end - process program_path do - run("./" + program_path.relative_path, chdir: program_path.root) + process object_files, program_path do + run("clang++", "-O3", "-o", program_path, *object_files.to_a, "-lm", "-pthread") end end - group.wait do - walker.update(top) + process program_path do + run("./" + program_path.relative_path, chdir: program_path.root) end - - expect(program_path).to be_exist - expect(code_glob.first.modified_time).to be <= program_path.modified_time end - it "should copy files incrementally" do - program_root = Path.join(__dir__, "program") - files = Glob.new(program_root, "*.cpp") - destination = Path.new(__dir__) + "tmp" + group.wait do + walker.update(top) + end + + expect(program_path).to be_exist + expect(code_glob.first.modified_time).to be <= program_path.modified_time + end + + it "should copy files incrementally" do + program_root = Build::Files::Path.join(__dir__, "program") + files = Build::Files::Glob.new(program_root, "*.cpp") + destination = Build::Files::Path.new(__dir__) + "tmp" + + walker = Build::Graph::Walker.for(ProcessTask, group) + + top = ProcessNode.top files do + mkpath destination - walker = Walker.for(ProcessTask, group) - - top = ProcessNode.top files do - mkpath destination + inputs.each do |source_path| + destination_path = source_path.rebase(destination) - inputs.each do |source_path| - destination_path = source_path.rebase(destination) - - process source_path, destination_path do - $stderr.puts "Copying #{inputs.first} -> #{outputs.first}" - install inputs.first, outputs.first - end + process source_path, destination_path do + $stderr.puts "Copying #{inputs.first} -> #{outputs.first}" + install inputs.first, outputs.first end end + end + + mutex = Mutex.new + files_deleted = false + + thread = Thread.new do + sleep 1 - mutex = Mutex.new - files_deleted = false - - thread = Thread.new do - sleep 1 + mutex.synchronize do + destination.glob("*.cpp").delete - mutex.synchronize do - destination.glob("*.cpp").delete - - files_deleted = true - end + files_deleted = true end - - walker.run do - mutex.synchronize do - group.wait do - walker.update(top) - end + end + + walker.run do + mutex.synchronize do + group.wait do + walker.update(top) end - - break if files_deleted end - thread.join - - expect(destination).to be_exist - # This line failed, may still be a race condition: - expect(destination.glob("*.cpp").count).to be == 2 - - destination.delete + break if files_deleted end + + thread.join + + expect(destination).to be_exist + # This line failed, may still be a race condition: + expect(destination.glob("*.cpp").count).to be == 2 + + destination.delete end end