diff --git a/lib/datadog/ci/git/local_repository.rb b/lib/datadog/ci/git/local_repository.rb index fe67a493..cbd71e7f 100644 --- a/lib/datadog/ci/git/local_repository.rb +++ b/lib/datadog/ci/git/local_repository.rb @@ -30,6 +30,8 @@ def self.root @root = git_root || Dir.pwd end + # ATTENTION: this function is running in a hot path + # and should be optimized for performance def self.relative_to_root(path) return "" if path.nil? @@ -37,14 +39,17 @@ def self.relative_to_root(path) return path if root_path.nil? if File.absolute_path?(path) + # prefix_index is where the root path ends in the given path prefix_index = root_path.size - # impossible case + # impossible case - absolute paths are returned from code coverage tool that always checks + # that root is a prefix of the path return "" if path.size < prefix_index prefix_index += 1 if path[prefix_index] == File::SEPARATOR res = path[prefix_index..] else + # prefix_to_root is a difference between the root path and the given path if @prefix_to_root == "" return path elsif @prefix_to_root diff --git a/spec/datadog/ci/test_optimisation/coverage/event_spec.rb b/spec/datadog/ci/test_optimisation/coverage/event_spec.rb index ec1dc6e6..238dd66b 100644 --- a/spec/datadog/ci/test_optimisation/coverage/event_spec.rb +++ b/spec/datadog/ci/test_optimisation/coverage/event_spec.rb @@ -104,6 +104,41 @@ end end + context "when file paths are relative" do + before do + Datadog::CI::Git::LocalRepository.remove_instance_variable(:@prefix_to_root) + + allow(Datadog::CI::Git::LocalRepository).to receive(:root).and_return( + Dir.pwd.gsub("/datadog-ci-rb", "") + ) + end + + after do + Datadog::CI::Git::LocalRepository.remove_instance_variable(:@prefix_to_root) + end + + let(:coverage) do + { + "project/file.rb" => true, + "project/file2.rb" => true + } + end + + it "converts all file paths to relative to the git root" do + expect(msgpack_json).to eq( + { + "test_session_id" => 3, + "test_suite_id" => 2, + "span_id" => 1, + "files" => [ + {"filename" => "datadog-ci-rb/project/file.rb"}, + {"filename" => "datadog-ci-rb/project/file2.rb"} + ] + } + ) + end + end + context "coverage in lines format" do let(:coverage) { {"file.rb" => {1 => true, 2 => true, 3 => true}} }