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 14# frozen_string_literal: true 15 16module Generator 17 class Parser 18 def initialize(data, output, src_dir, skip_header) 19 @data = data 20 @output = output 21 @src_dir = src_dir 22 23 # TODO: add validation of input YAML to avoid additional checking in code 24 25 LOG.info 'Generator created' 26 LOG.debug "@data first 3 keys are: '#{data.keys.first(3)}'" 27 28 # data - YAML: 29 # tests: Generator::TESTS 30 # definitions: Generator::DEFINITIONS 31 32 # Tests definitions 33 @tests = @data[Generator::TESTS] 34 # some predefined templates as headers, prefixes, postfixes, etc. 35 raise "'#{Generator::DEFINITIONS}' is not found in main yaml" unless @data.key? Generator::DEFINITIONS 36 @predefined = Definitions.new @data[Generator::DEFINITIONS] 37 @skip_header = skip_header 38 end 39 40 def parse(skip) 41 start_time = Time.now 42 updated_tests = @tests.flat_map do |test| 43 if test.key? Generator::TESTS_INCLUDE 44 file_name = test[Generator::TESTS_INCLUDE] 45 included_data = YAML.load_file("#{@src_dir}/#{file_name}") 46 if !skip 47 res = JSON::Validator.fully_validate("#{@src_dir}/yaml-schema.json", included_data) 48 unless res.empty? 49 puts "Template '#{file_name}' contains several errors:" 50 puts res 51 raise "Schema validation error, please update template '#{file_name}' to match schema to generate tests" 52 end 53 end 54 55 # Add definitions to each test group from file. 56 included_data[Generator::TESTS].map do |single_test| 57 single_test[Generator::DEFINITIONS] = included_data[Generator::DEFINITIONS] 58 single_test 59 end 60 included_data[Generator::TESTS] 61 else 62 test 63 end 64 end 65 66 @tests = updated_tests 67 68 test_has_only_key = false 69 command_has_only_key = false 70 @tests.each do |raw_test| 71 test_has_only_key ||= raw_test.key?(Generator::TEST_ONLY) && raw_test[Generator::TEST_ONLY] 72 raw_test[Generator::TEST_COMMANDS].each do |command| 73 command_has_only_key ||= command.key?(Generator::TEST_COMMAND_ONLY) && command[Generator::TEST_COMMAND_ONLY] 74 end 75 end 76 LOG.debug "test_has_only_key = #{test_has_only_key}" 77 LOG.debug "command_has_only_key = #{command_has_only_key}" 78 options = { test_has_only_key: test_has_only_key, command_has_only_key: command_has_only_key } 79 80 LOG.debug options 81 82 # Generated test directory 83 FileUtils.rm_rf @output if File.exist? @output 84 FileUtils.mkdir_p @output unless File.exist? @output 85 iterate_tests options 86 LOG.info "Tests generation done in #{Time.now - start_time} sec" 87 end 88 89 def iterate_tests(options) 90 LOG.debug('Iterate over all tests') 91 @tests.each do |raw_test| 92 if options[:test_has_only_key] 93 process = raw_test.key?(Generator::TEST_ONLY) && raw_test[Generator::TEST_ONLY] || options[:command_has_only_key] 94 LOG.debug "'only:' is defined for some test, process current: #{process}" 95 if process 96 # Process all commands 97 test = Test.new raw_test, @predefined, options[:command_has_only_key], @output, @skip_header 98 test.parse 99 end 100 else 101 LOG.debug "'only:' is not defined for test, process current: true" 102 # Process commands, if it has only, to only them should be processed 103 test = Test.new raw_test, @predefined, options[:command_has_only_key], @output, @skip_header 104 test.parse 105 end 106 107 end 108 end 109 end 110end 111