• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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