1# Copyright (c) 2021-2022 Huawei Device Co., Ltd. 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13 14require 'pathname' 15require 'json' 16require 'securerandom' 17require 'digest/md5' 18require_relative 'string_logger' 19require_relative 'base_test_reporter' 20 21module TestRunner 22 class AllureTestReporter < BaseTestReporter 23 def time_now_millisec 24 (Time.now.to_f * 1000).to_i 25 end 26 27 def set_failure(message) 28 @status = 'failed' 29 @report['statusDetails'] = { 30 'known' => false, 'muted' => false, 'flaky' => false, 31 'message' => message, 'trace' => @output 32 } 33 end 34 35 def initialize(root_dir, pa_file, report_dir) 36 root = Pathname.new(root_dir) 37 file = Pathname.new(pa_file) # path to file 38 actual_file = file.relative_path_from(root) 39 report_dir = Pathname.new(report_dir) 40 actual_file = root.basename if root.file? 41 pa_file = actual_file.to_s 42 # Making it 'flat': all json files in same dir 43 report_file = report_dir + Pathname.new( 44 pa_file.gsub('/', '_').gsub(/.pa$/, '-result.json') 45 ) 46 report_file.dirname.mkpath 47 FileUtils.rm report_file if report_file.exist? 48 @logger = Reporters::SeparateFileLogger.new(report_file) 49 @status = 'failed' 50 @output = '' 51 feature = TestRunner.target 52 @report = { 53 'name' => pa_file, 54 'status' => 'failed', 55 'stage' => 'finished', 56 'description' => pa_file, 57 'start' => time_now_millisec, 58 'uuid' => SecureRandom.uuid, 59 'historyId' => Digest::MD5.hexdigest(actual_file.to_s), 60 'fullName' => actual_file, 61 'labels' => [ 62 { 'name' => 'suite', 'value' => 'CTS' }, 63 { 'name' => 'feature', 'value' => "CTS #{feature}" } 64 ], 65 'links' => [] 66 } 67 end 68 69 def prologue; end 70 71 def epilogue 72 @report['stop'] = time_now_millisec 73 @report['status'] = @status 74 @logger.log 1, JSON[@report] 75 @logger.close 76 end 77 78 def log_exclusion 79 @status = 'skipped' 80 end 81 82 def log_skip_include 83 @status = 'skipped' 84 end 85 86 def log_skip_bugid 87 @status = 'skipped' 88 end 89 90 def log_skip_ignore 91 @status = 'skipped' 92 end 93 94 def log_skip_only_ignore 95 @status = 'skipped' 96 end 97 98 def log_ignore_ignored; end 99 100 def log_start_command(cmd) 101 @output << "\ncommand = #{cmd}" 102 end 103 104 def log_failed_compilation(output) 105 @output << "\n" << output 106 set_failure('Failed to compile.') 107 end 108 109 def log_negative_passed_compilation(output) 110 @output << "\n" << output 111 set_failure('Test is compiled, but should be rejected.') 112 end 113 114 def log_failed_negative_compilation(output) 115 @status = 'passed' 116 @output << "\n" << output 117 end 118 119 def log_compilation_passed(output) 120 @status = 'passed' 121 @output << "\n" << output 122 end 123 124 def log_run_negative_failure(output, status) 125 @output << "\n" << output 126 set_failure("Exit code: #{status}, but expected failure.") 127 end 128 129 def log_verifier_negative_failure(output, status) 130 @output << "\n" << output 131 set_failure("Verifier exit code: #{status}, but expected failure.") 132 end 133 134 def log_run_failure(output, status, core) 135 @output << "\nCore dump was created." if core 136 @output << "\n" << output 137 set_failure("Exit code: #{status}.") 138 end 139 140 def log_verifier_failure(output, status, core) 141 @output << "\nCore dump was created." if core 142 @output << "\n" << output 143 set_failure("Verifier exit code: #{status}.") 144 end 145 146 def log_passed(output, _status) 147 @status = 'passed' 148 @output << "\n" << output 149 end 150 151 def log_excluded 152 @status = 'skipped' 153 end 154 155 def verbose_log(status) 156 @output << "\n" << status 157 end 158 159 def log_bugids(bugids) 160 @report['links'] = bugids.map do |x| 161 { 162 'name' => x, 'type' => 'issue', 163 'url': 'https://rnd-gitlab-msc.huawei.com/rus-os-team/virtual-machines-and-tools/panda/-/issues' 164 } 165 end 166 end 167 168 def log_repro_commands(_cmds); end 169 end 170end 171