blob: a4619bc1b13ff850893712d7c97dcf6a5034e6b3 [file] [log] [blame]
Tobin Ehlis35308dd2016-10-31 13:27:36 -06001#!/usr/bin/env python3
Dave Houltoncacef472018-05-29 13:00:42 -06002# Copyright (c) 2015-2018 The Khronos Group Inc.
3# Copyright (c) 2015-2018 Valve Corporation
4# Copyright (c) 2015-2018 LunarG, Inc.
5# Copyright (c) 2015-2018 Google Inc.
Tobin Ehlis35308dd2016-10-31 13:27:36 -06006#
7# Licensed under the Apache License, Version 2.0 (the "License");
8# you may not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
18#
19# Author: Tobin Ehlis <tobine@google.com>
Dave Houltoncacef472018-05-29 13:00:42 -060020# Author: Dave Houlton <daveh@lunarg.com>
Tobin Ehlis35308dd2016-10-31 13:27:36 -060021
22import argparse
23import os
24import sys
Dave Houltoncacef472018-05-29 13:00:42 -060025import operator
Tobin Ehlis35308dd2016-10-31 13:27:36 -060026import platform
Dave Houltoncacef472018-05-29 13:00:42 -060027import json
28import re
29import csv
30import html
31from collections import defaultdict
Tobin Ehlis35308dd2016-10-31 13:27:36 -060032
Dave Houltoncacef472018-05-29 13:00:42 -060033verbose_mode = False
34txt_db = False
35csv_db = False
36html_db = False
37txt_filename = "validation_error_database.txt"
38csv_filename = "validation_error_database.csv"
39html_filename = "validation_error_database.html"
Dave Houlton407df732018-08-06 17:58:24 -060040header_filename = "../layers/vk_validation_error_messages.h"
Dave Houltoncacef472018-05-29 13:00:42 -060041test_file = '../tests/layer_validation_tests.cpp'
42vuid_prefixes = ['VUID-', 'UNASSIGNED-']
Tobin Ehlis35308dd2016-10-31 13:27:36 -060043
Dave Houltoncacef472018-05-29 13:00:42 -060044# Hard-coded flags that could be command line args, if we decide that's useful
45# replace KHR vuids with non-KHR during consistency checking
46dealias_khr = True
47ignore_unassigned = True # These are not found in layer code unless they appear explicitly (most don't), so produce false positives
48
Mark Lobodzinski05849f02017-06-21 14:44:14 -060049generated_layer_source_directories = [
50'build',
51'dbuild',
52'release',
53]
54generated_layer_source_files = [
Mark Lobodzinskid4950072017-08-01 13:02:20 -060055'parameter_validation.cpp',
Mark Lobodzinski09fa2d42017-07-21 10:16:53 -060056'object_tracker.cpp',
Mark Lobodzinski05849f02017-06-21 14:44:14 -060057]
Tobin Ehlis35308dd2016-10-31 13:27:36 -060058layer_source_files = [
Mark Lobodzinskie3787b42017-06-21 13:41:00 -060059'../layers/core_validation.cpp',
60'../layers/descriptor_sets.cpp',
Mark Lobodzinskid4950072017-08-01 13:02:20 -060061'../layers/parameter_validation_utils.cpp',
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060062'../layers/object_tracker_utils.cpp',
Mark Lobodzinskie3787b42017-06-21 13:41:00 -060063'../layers/shader_validation.cpp',
64'../layers/buffer_validation.cpp',
Tobin Ehlis35308dd2016-10-31 13:27:36 -060065]
Tobin Ehlis35308dd2016-10-31 13:27:36 -060066
Dave Houlton407df732018-08-06 17:58:24 -060067# This needs to be updated as new extensions roll in
Dave Houltoncacef472018-05-29 13:00:42 -060068khr_aliases = {
69 'VUID-vkBindBufferMemory2KHR-device-parameter' : 'VUID-vkBindBufferMemory2-device-parameter',
70 'VUID-vkBindBufferMemory2KHR-pBindInfos-parameter' : 'VUID-vkBindBufferMemory2-pBindInfos-parameter',
71 'VUID-vkBindImageMemory2KHR-device-parameter' : 'VUID-vkBindImageMemory2-device-parameter',
72 'VUID-vkBindImageMemory2KHR-pBindInfos-parameter' : 'VUID-vkBindImageMemory2-pBindInfos-parameter',
73 'VUID-vkCmdDispatchBaseKHR-commandBuffer-parameter' : 'VUID-vkCmdDispatchBase-commandBuffer-parameter',
74 'VUID-vkCmdSetDeviceMaskKHR-commandBuffer-parameter' : 'VUID-vkCmdSetDeviceMask-commandBuffer-parameter',
75 'VUID-vkCreateDescriptorUpdateTemplateKHR-device-parameter' : 'VUID-vkCreateDescriptorUpdateTemplate-device-parameter',
76 'VUID-vkCreateDescriptorUpdateTemplateKHR-pDescriptorUpdateTemplate-parameter' : 'VUID-vkCreateDescriptorUpdateTemplate-pDescriptorUpdateTemplate-parameter',
77 'VUID-vkCreateSamplerYcbcrConversionKHR-device-parameter' : 'VUID-vkCreateSamplerYcbcrConversion-device-parameter',
78 'VUID-vkCreateSamplerYcbcrConversionKHR-pYcbcrConversion-parameter' : 'VUID-vkCreateSamplerYcbcrConversion-pYcbcrConversion-parameter',
79 'VUID-vkDestroyDescriptorUpdateTemplateKHR-descriptorUpdateTemplate-parameter' : 'VUID-vkDestroyDescriptorUpdateTemplate-descriptorUpdateTemplate-parameter',
80 'VUID-vkDestroyDescriptorUpdateTemplateKHR-descriptorUpdateTemplate-parent' : 'VUID-vkDestroyDescriptorUpdateTemplate-descriptorUpdateTemplate-parent',
81 'VUID-vkDestroyDescriptorUpdateTemplateKHR-device-parameter' : 'VUID-vkDestroyDescriptorUpdateTemplate-device-parameter',
82 'VUID-vkDestroySamplerYcbcrConversionKHR-device-parameter' : 'VUID-vkDestroySamplerYcbcrConversion-device-parameter',
83 'VUID-vkDestroySamplerYcbcrConversionKHR-ycbcrConversion-parameter' : 'VUID-vkDestroySamplerYcbcrConversion-ycbcrConversion-parameter',
84 'VUID-vkDestroySamplerYcbcrConversionKHR-ycbcrConversion-parent' : 'VUID-vkDestroySamplerYcbcrConversion-ycbcrConversion-parent',
85 'VUID-vkEnumeratePhysicalDeviceGroupsKHR-instance-parameter' : 'VUID-vkEnumeratePhysicalDeviceGroups-instance-parameter',
86 'VUID-vkEnumeratePhysicalDeviceGroupsKHR-pPhysicalDeviceGroupProperties-parameter' : 'VUID-vkEnumeratePhysicalDeviceGroups-pPhysicalDeviceGroupProperties-parameter',
87 'VUID-vkGetBufferMemoryRequirements2KHR-device-parameter' : 'VUID-vkGetBufferMemoryRequirements2-device-parameter',
88 'VUID-vkGetDescriptorSetLayoutSupportKHR-device-parameter' : 'VUID-vkGetDescriptorSetLayoutSupport-device-parameter',
89 'VUID-vkGetDeviceGroupPeerMemoryFeaturesKHR-device-parameter' : 'VUID-vkGetDeviceGroupPeerMemoryFeatures-device-parameter',
90 'VUID-vkGetDeviceGroupPeerMemoryFeaturesKHR-pPeerMemoryFeatures-parameter' : 'VUID-vkGetDeviceGroupPeerMemoryFeatures-pPeerMemoryFeatures-parameter',
91 'VUID-vkGetImageMemoryRequirements2KHR-device-parameter' : 'VUID-vkGetImageMemoryRequirements2-device-parameter',
92 'VUID-vkGetImageSparseMemoryRequirements2KHR-device-parameter' : 'VUID-vkGetImageSparseMemoryRequirements2-device-parameter',
93 'VUID-vkGetImageSparseMemoryRequirements2KHR-pSparseMemoryRequirements-parameter' : 'VUID-vkGetImageSparseMemoryRequirements2-pSparseMemoryRequirements-parameter',
94 'VUID-vkGetPhysicalDeviceExternalBufferPropertiesKHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceExternalBufferProperties-physicalDevice-parameter',
95 'VUID-vkGetPhysicalDeviceExternalFencePropertiesKHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceExternalFenceProperties-physicalDevice-parameter',
96 'VUID-vkGetPhysicalDeviceExternalSemaphorePropertiesKHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceExternalSemaphoreProperties-physicalDevice-parameter',
97 'VUID-vkGetPhysicalDeviceFeatures2KHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceFeatures2-physicalDevice-parameter',
98 'VUID-vkGetPhysicalDeviceFormatProperties2KHR-format-parameter' : 'VUID-vkGetPhysicalDeviceFormatProperties2-format-parameter',
99 'VUID-vkGetPhysicalDeviceFormatProperties2KHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceFormatProperties2-physicalDevice-parameter',
100 'VUID-vkGetPhysicalDeviceImageFormatProperties2KHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceImageFormatProperties2-physicalDevice-parameter',
101 'VUID-vkGetPhysicalDeviceMemoryProperties2KHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceMemoryProperties2-physicalDevice-parameter',
102 'VUID-vkGetPhysicalDeviceProperties2KHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceProperties2-physicalDevice-parameter',
103 'VUID-vkGetPhysicalDeviceQueueFamilyProperties2KHR-pQueueFamilyProperties-parameter' : 'VUID-vkGetPhysicalDeviceQueueFamilyProperties2-pQueueFamilyProperties-parameter',
104 'VUID-vkGetPhysicalDeviceSparseImageFormatProperties2KHR-pProperties-parameter' : 'VUID-vkGetPhysicalDeviceSparseImageFormatProperties2-pProperties-parameter',
105 'VUID-vkGetPhysicalDeviceSparseImageFormatProperties2KHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceSparseImageFormatProperties2-physicalDevice-parameter',
106 'VUID-vkTrimCommandPoolKHR-commandPool-parameter' : 'VUID-vkTrimCommandPool-commandPool-parameter',
107 'VUID-vkTrimCommandPoolKHR-commandPool-parent' : 'VUID-vkTrimCommandPool-commandPool-parent',
108 'VUID-vkTrimCommandPoolKHR-device-parameter' : 'VUID-vkTrimCommandPool-device-parameter',
109 'VUID-vkTrimCommandPoolKHR-flags-zerobitmask' : 'VUID-vkTrimCommandPool-flags-zerobitmask',
110 'VUID-vkUpdateDescriptorSetWithTemplateKHR-descriptorSet-parameter' : 'VUID-vkUpdateDescriptorSetWithTemplate-descriptorSet-parameter',
111 'VUID-vkUpdateDescriptorSetWithTemplateKHR-descriptorUpdateTemplate-parameter' : 'VUID-vkUpdateDescriptorSetWithTemplate-descriptorUpdateTemplate-parameter',
112 'VUID-vkUpdateDescriptorSetWithTemplateKHR-descriptorUpdateTemplate-parent' : 'VUID-vkUpdateDescriptorSetWithTemplate-descriptorUpdateTemplate-parent',
113 'VUID-vkUpdateDescriptorSetWithTemplateKHR-device-parameter' : 'VUID-vkUpdateDescriptorSetWithTemplate-device-parameter',
114 'VUID-vkCreateDescriptorUpdateTemplateKHR-pCreateInfo-parameter' : 'VUID-vkCreateDescriptorUpdateTemplate-pCreateInfo-parameter',
115 'VUID-vkCreateSamplerYcbcrConversionKHR-pCreateInfo-parameter' : 'VUID-vkCreateSamplerYcbcrConversion-pCreateInfo-parameter',
116 'VUID-vkGetBufferMemoryRequirements2KHR-pInfo-parameter' : 'VUID-vkGetBufferMemoryRequirements2-pInfo-parameter',
117 'VUID-vkGetBufferMemoryRequirements2KHR-pMemoryRequirements-parameter' : 'VUID-vkGetBufferMemoryRequirements2-pMemoryRequirements-parameter',
118 'VUID-vkGetDescriptorSetLayoutSupportKHR-pCreateInfo-parameter' : 'VUID-vkGetDescriptorSetLayoutSupport-pCreateInfo-parameter',
119 'VUID-vkGetDescriptorSetLayoutSupportKHR-pSupport-parameter' : 'VUID-vkGetDescriptorSetLayoutSupport-pSupport-parameter',
120 'VUID-vkGetImageMemoryRequirements2KHR-pInfo-parameter' : 'VUID-vkGetImageMemoryRequirements2-pInfo-parameter',
121 'VUID-vkGetImageMemoryRequirements2KHR-pMemoryRequirements-parameter' : 'VUID-vkGetImageMemoryRequirements2-pMemoryRequirements-parameter',
122 'VUID-vkGetImageSparseMemoryRequirements2KHR-pInfo-parameter' : 'VUID-vkGetImageSparseMemoryRequirements2-pInfo-parameter',
123 'VUID-vkGetPhysicalDeviceExternalBufferPropertiesKHR-pExternalBufferInfo-parameter' : 'VUID-vkGetPhysicalDeviceExternalBufferProperties-pExternalBufferInfo-parameter',
124 'VUID-vkGetPhysicalDeviceExternalBufferPropertiesKHR-pExternalBufferProperties-parameter' : 'VUID-vkGetPhysicalDeviceExternalBufferProperties-pExternalBufferProperties-parameter',
125 'VUID-vkGetPhysicalDeviceExternalFencePropertiesKHR-pExternalFenceInfo-parameter' : 'VUID-vkGetPhysicalDeviceExternalFenceProperties-pExternalFenceInfo-parameter',
126 'VUID-vkGetPhysicalDeviceExternalFencePropertiesKHR-pExternalFenceProperties-parameter' : 'VUID-vkGetPhysicalDeviceExternalFenceProperties-pExternalFenceProperties-parameter',
127 'VUID-vkGetPhysicalDeviceExternalSemaphorePropertiesKHR-pExternalSemaphoreInfo-parameter' : 'VUID-vkGetPhysicalDeviceExternalSemaphoreProperties-pExternalSemaphoreInfo-parameter',
128 'VUID-vkGetPhysicalDeviceExternalSemaphorePropertiesKHR-pExternalSemaphoreProperties-parameter' : 'VUID-vkGetPhysicalDeviceExternalSemaphoreProperties-pExternalSemaphoreProperties-parameter',
129 'VUID-vkGetPhysicalDeviceFeatures2KHR-pFeatures-parameter' : 'VUID-vkGetPhysicalDeviceFeatures2-pFeatures-parameter',
130 'VUID-vkGetPhysicalDeviceFormatProperties2KHR-pFormatProperties-parameter' : 'VUID-vkGetPhysicalDeviceFormatProperties2-pFormatProperties-parameter',
131 'VUID-vkGetPhysicalDeviceImageFormatProperties2KHR-pImageFormatInfo-parameter' : 'VUID-vkGetPhysicalDeviceImageFormatProperties2-pImageFormatInfo-parameter',
132 'VUID-vkGetPhysicalDeviceImageFormatProperties2KHR-pImageFormatProperties-parameter' : 'VUID-vkGetPhysicalDeviceImageFormatProperties2-pImageFormatProperties-parameter',
133 'VUID-vkGetPhysicalDeviceMemoryProperties2KHR-pMemoryProperties-parameter' : 'VUID-vkGetPhysicalDeviceMemoryProperties2-pMemoryProperties-parameter',
134 'VUID-vkGetPhysicalDeviceProperties2KHR-pProperties-parameter' : 'VUID-vkGetPhysicalDeviceProperties2-pProperties-parameter',
135 'VUID-vkGetPhysicalDeviceSparseImageFormatProperties2KHR-pFormatInfo-parameter' : 'VUID-vkGetPhysicalDeviceSparseImageFormatProperties2-pFormatInfo-parameter' }
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600136
Dave Houltoncacef472018-05-29 13:00:42 -0600137def printHelp():
138 print ("Usage:")
139 print (" python vk_validation_stats.py <json_file>")
140 print (" [ -c ]")
141 print (" [ -todo ]")
142 print (" [ -vuid <vuid_name> ]")
143 print (" [ -text [ <text_out_filename>] ]")
144 print (" [ -csv [ <csv_out_filename>] ]")
145 print (" [ -html [ <html_out_filename>] ]")
Dave Houlton407df732018-08-06 17:58:24 -0600146 print (" [ -export_header ]")
Dave Houltoncacef472018-05-29 13:00:42 -0600147 print (" [ -verbose ]")
148 print (" [ -help ]")
149 print ("\n The vk_validation_stats script parses validation layer source files to")
150 print (" determine the set of valid usage checks and tests currently implemented,")
151 print (" and generates coverage values by comparing against the full set of valid")
152 print (" usage identifiers in the Vulkan-Headers registry file 'validusage.json'")
153 print ("\nArguments: ")
154 print (" <json-file> (required) registry file 'validusage.json'")
155 print (" -c report consistency warnings")
156 print (" -todo report unimplemented VUIDs")
157 print (" -vuid <vuid_name> report status of individual VUID <vuid_name>")
158 print (" -text [filename] output the error database text to <text_database_filename>,")
159 print (" defaults to 'validation_error_database.txt'")
160 print (" -csv [filename] output the error database in csv to <csv_database_filename>,")
161 print (" defaults to 'validation_error_database.csv'")
162 print (" -html [filename] output the error database in html to <html_database_filename>,")
163 print (" defaults to 'validation_error_database.html'")
Dave Houlton407df732018-08-06 17:58:24 -0600164 print (" -export_header export a new VUID error text header file to <%s>" % header_filename)
Dave Houltoncacef472018-05-29 13:00:42 -0600165 print (" -verbose show your work (to stdout)")
166
167class ValidationJSON:
168 def __init__(self, filename):
169 self.filename = filename
170 self.explicit_vuids = set()
171 self.implicit_vuids = set()
172 self.all_vuids = set()
173 self.vuid_db = defaultdict(list) # Maps VUID string to list of json-data dicts
174 self.apiversion = ""
Dave Houltoncacef472018-05-29 13:00:42 -0600175 self.duplicate_vuids = set()
Dave Houlton407df732018-08-06 17:58:24 -0600176
177 # A set of specific regular expression substitutions needed to clean up VUID text
178 self.regex_dict = {}
179 self.regex_dict[re.compile('<.*?>|&(amp;)+lt;|&(amp;)+gt;')] = ""
180 self.regex_dict[re.compile(r'\\\(codeSize \\over 4\\\)')] = "(codeSize/4)"
181 self.regex_dict[re.compile(r'\\\(\\lceil\{\\mathit\{rasterizationSamples} \\over 32}\\rceil\\\)')] = "(rasterizationSamples/32)"
182 # Some fancy punctuation chars that break the Android build...
183 self.regex_dict[re.compile('&#8594;')] = "->" # Arrow char
184 self.regex_dict[re.compile('&#8217;')] = "'" # Left-slanting apostrophe to apostrophe
185 self.regex_dict[re.compile('&#822(0|1);')] = "'" # L/R-slanting quotes to apostrophe
Dave Houltoncacef472018-05-29 13:00:42 -0600186
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600187 def read(self):
Dave Houltoncacef472018-05-29 13:00:42 -0600188 self.json_dict = {}
189 if os.path.isfile(self.filename):
Dave Houlton407df732018-08-06 17:58:24 -0600190 json_file = open(self.filename, 'r', encoding='utf-8')
Dave Houltoncacef472018-05-29 13:00:42 -0600191 self.json_dict = json.load(json_file)
192 json_file.close()
193 if len(self.json_dict) == 0:
194 print("Error: Error loading validusage.json file <%s>" % self.filename)
195 sys.exit(-1)
196 try:
197 version = self.json_dict['version info']
198 validation = self.json_dict['validation']
199 self.apiversion = version['api version']
200 except:
201 print("Error: Failure parsing validusage.json object")
202 sys.exit(-1)
203
204 # Parse vuid from json into local databases
205 for apiname in validation.keys():
206 # print("entrypoint:%s"%apiname)
207 apidict = validation[apiname]
208 for ext in apidict.keys():
209 vlist = apidict[ext]
210 for ventry in vlist:
211 vuid_string = ventry['vuid']
212 if (vuid_string[-5:-1].isdecimal()):
213 self.explicit_vuids.add(vuid_string) # explicit end in 5 numeric chars
214 vtype = 'explicit'
215 else:
216 self.implicit_vuids.add(vuid_string) # otherwise, implicit
217 vtype = 'implicit'
218 vuid_text = ventry['text']
Dave Houlton407df732018-08-06 17:58:24 -0600219 for regex, replacement in self.regex_dict.items():
220 vuid_text = re.sub(regex, replacement, vuid_text) # do regex substitution
221 vuid_text = html.unescape(vuid_text) # anything missed by the regex
222 self.vuid_db[vuid_string].append({'api':apiname, 'ext':ext, 'type':vtype, 'text':vuid_text})
Dave Houltoncacef472018-05-29 13:00:42 -0600223 self.all_vuids = self.explicit_vuids | self.implicit_vuids
224 self.duplicate_vuids = set({v for v in self.vuid_db if len(self.vuid_db[v]) > 1})
Dave Houlton407df732018-08-06 17:58:24 -0600225 if len(self.duplicate_vuids) > 0:
226 print("Warning: duplicate VUIDs found in validusage.json")
227
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600228
229class ValidationSource:
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600230 def __init__(self, source_file_list, generated_source_file_list, generated_source_directories):
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600231 self.source_files = source_file_list
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600232 self.generated_source_files = generated_source_file_list
233 self.generated_source_dirs = generated_source_directories
Dave Houltoncacef472018-05-29 13:00:42 -0600234 self.vuid_count_dict = {} # dict of vuid values to the count of how much they're used, and location of where they're used
235 self.duplicated_checks = 0
236 self.explicit_vuids = set()
237 self.implicit_vuids = set()
238 self.unassigned_vuids = set()
239 self.all_vuids = set()
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600240
241 if len(self.generated_source_files) > 0:
242 qualified_paths = []
243 for source in self.generated_source_files:
244 for build_dir in self.generated_source_dirs:
245 filepath = '../%s/layers/%s' % (build_dir, source)
246 if os.path.isfile(filepath):
247 qualified_paths.append(filepath)
John Zulaufdde04c42018-01-16 15:32:45 -0700248 break
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600249 if len(self.generated_source_files) != len(qualified_paths):
Mark Lobodzinski2d193ac2017-06-27 09:38:15 -0600250 print("Error: Unable to locate one or more of the following source files in the %s directories" % (", ".join(generated_source_directories)))
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600251 print(self.generated_source_files)
Dave Houltoncacef472018-05-29 13:00:42 -0600252 print("Failed to locate one or more codegen files in layer source code - cannot proceed.")
John Zulaufdde04c42018-01-16 15:32:45 -0700253 exit(1)
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600254 else:
255 self.source_files.extend(qualified_paths)
256
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600257 def parse(self):
Dave Houltoncacef472018-05-29 13:00:42 -0600258 prepend = None
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600259 for sf in self.source_files:
Tobin Ehlis3d1f2bd2016-12-22 11:19:15 -0700260 line_num = 0
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600261 with open(sf) as f:
262 for line in f:
Tobin Ehlis3d1f2bd2016-12-22 11:19:15 -0700263 line_num = line_num + 1
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600264 if True in [line.strip().startswith(comment) for comment in ['//', '/*']]:
265 continue
Dave Houltoncacef472018-05-29 13:00:42 -0600266 # Find vuid strings
267 if prepend != None:
268 line = prepend[:-2] + line.lstrip().lstrip('"') # join lines skipping CR, whitespace and trailing/leading quote char
269 prepend = None
270 if any(prefix in line for prefix in vuid_prefixes):
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600271 line_list = line.split()
Dave Houltoncacef472018-05-29 13:00:42 -0600272
273 # A VUID string that has been broken by clang will start with a vuid prefix and end with -, and will be last in the list
274 broken_vuid = line_list[-1].strip('"')
275 if any(broken_vuid.startswith(prefix) for prefix in vuid_prefixes) and broken_vuid.endswith('-'):
276 prepend = line
277 continue
278
279 vuid_list = []
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600280 for str in line_list:
Dave Houltoncacef472018-05-29 13:00:42 -0600281 if any(prefix in str for prefix in vuid_prefixes):
282 vuid_list.append(str.strip(',);{}"'))
283 for vuid in vuid_list:
284 if vuid not in self.vuid_count_dict:
285 self.vuid_count_dict[vuid] = {}
286 self.vuid_count_dict[vuid]['count'] = 1
287 self.vuid_count_dict[vuid]['file_line'] = []
288 else:
289 if self.vuid_count_dict[vuid]['count'] == 1: # only count first time duplicated
290 self.duplicated_checks = self.duplicated_checks + 1
291 self.vuid_count_dict[vuid]['count'] = self.vuid_count_dict[vuid]['count'] + 1
292 self.vuid_count_dict[vuid]['file_line'].append('%s,%d' % (sf, line_num))
293 # Sort vuids by type
294 for vuid in self.vuid_count_dict.keys():
295 if (vuid.startswith('VUID-')):
296 if (vuid[-5:-1].isdecimal()):
297 self.explicit_vuids.add(vuid) # explicit end in 5 numeric chars
298 else:
299 self.implicit_vuids.add(vuid)
300 elif (vuid.startswith('UNASSIGNED-')):
301 self.unassigned_vuids.add(vuid)
302 else:
303 print("Unable to categorize VUID: %s" % vuid)
304 print("Confused while parsing VUIDs in layer source code - cannot proceed. (FIXME)")
305 exit(-1)
306 self.all_vuids = self.explicit_vuids | self.implicit_vuids | self.unassigned_vuids
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600307
308# Class to parse the validation layer test source and store testnames
Dave Houltoncacef472018-05-29 13:00:42 -0600309class ValidationTests:
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600310 def __init__(self, test_file_list, test_group_name=['VkLayerTest', 'VkPositiveLayerTest', 'VkWsiEnabledLayerTest']):
311 self.test_files = test_file_list
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600312 self.test_trigger_txt_list = []
313 for tg in test_group_name:
314 self.test_trigger_txt_list.append('TEST_F(%s' % tg)
Dave Houltoncacef472018-05-29 13:00:42 -0600315 self.explicit_vuids = set()
316 self.implicit_vuids = set()
317 self.unassigned_vuids = set()
318 self.all_vuids = set()
319 #self.test_to_vuids = {} # Map test name to VUIDs tested
320 self.vuid_to_tests = defaultdict(set) # Map VUIDs to set of test names where implemented
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600321
322 # Parse test files into internal data struct
323 def parse(self):
324 # For each test file, parse test names into set
325 grab_next_line = False # handle testname on separate line than wildcard
Tobin Ehlis9a68c982016-12-29 14:51:17 -0700326 testname = ''
Dave Houltoncacef472018-05-29 13:00:42 -0600327 prepend = None
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600328 for test_file in self.test_files:
329 with open(test_file) as tf:
330 for line in tf:
331 if True in [line.strip().startswith(comment) for comment in ['//', '/*']]:
332 continue
333
Dave Houltoncacef472018-05-29 13:00:42 -0600334 # if line ends in a broken VUID string, fix that before proceeding
335 if prepend != None:
336 line = prepend[:-2] + line.lstrip().lstrip('"') # join lines skipping CR, whitespace and trailing/leading quote char
337 prepend = None
338 if any(prefix in line for prefix in vuid_prefixes):
339 line_list = line.split()
340
341 # A VUID string that has been broken by clang will start with a vuid prefix and end with -, and will be last in the list
342 broken_vuid = line_list[-1].strip('"')
343 if any(broken_vuid.startswith(prefix) for prefix in vuid_prefixes) and broken_vuid.endswith('-'):
344 prepend = line
345 continue
346
347 if any(ttt in line for ttt in self.test_trigger_txt_list):
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600348 testname = line.split(',')[-1]
349 testname = testname.strip().strip(' {)')
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600350 if ('' == testname):
351 grab_next_line = True
352 continue
Dave Houltoncacef472018-05-29 13:00:42 -0600353 #self.test_to_vuids[testname] = []
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600354 if grab_next_line: # test name on its own line
355 grab_next_line = False
356 testname = testname.strip().strip(' {)')
Dave Houltoncacef472018-05-29 13:00:42 -0600357 #self.test_to_vuids[testname] = []
358 if any(prefix in line for prefix in vuid_prefixes):
359 line_list = re.split('[\s{}[\]()"]+',line)
Tobin Ehlis71f38c12017-01-12 14:26:56 -0700360 for sub_str in line_list:
Dave Houltoncacef472018-05-29 13:00:42 -0600361 if any(prefix in sub_str for prefix in vuid_prefixes):
362 vuid_str = sub_str.strip(',);:"')
363 self.vuid_to_tests[vuid_str].add(testname)
364 #self.test_to_vuids[testname].append(vuid_str)
365 if (vuid_str.startswith('VUID-')):
366 if (vuid_str[-5:-1].isdecimal()):
367 self.explicit_vuids.add(vuid_str) # explicit end in 5 numeric chars
368 else:
369 self.implicit_vuids.add(vuid_str)
370 elif (vuid_str.startswith('UNASSIGNED-')):
371 self.unassigned_vuids.add(vuid_str)
372 else:
373 print("Unable to categorize VUID: %s" % vuid_str)
374 print("Confused while parsing VUIDs in test code - cannot proceed. (FIXME)")
375 exit(-1)
376 self.all_vuids = self.explicit_vuids | self.implicit_vuids | self.unassigned_vuids
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600377
Dave Houltoncacef472018-05-29 13:00:42 -0600378# Class to do consistency checking
379#
380class Consistency:
381 def __init__(self, all_json, all_checks, all_tests):
382 self.valid = all_json
383 self.checks = all_checks
384 self.tests = all_tests
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600385
Dave Houltoncacef472018-05-29 13:00:42 -0600386 if (dealias_khr):
387 dk = set()
388 for vuid in self.checks:
389 if vuid in khr_aliases:
390 dk.add(khr_aliases[vuid])
391 else:
392 dk.add(vuid)
393 self.checks = dk
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600394
Dave Houltoncacef472018-05-29 13:00:42 -0600395 dk = set()
396 for vuid in self.tests:
397 if vuid in khr_aliases:
398 dk.add(khr_aliases[vuid])
399 else:
400 dk.add(vuid)
401 self.tests = dk
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600402
Dave Houltoncacef472018-05-29 13:00:42 -0600403 # Report undefined VUIDs in source code
404 def undef_vuids_in_layer_code(self):
405 undef_set = self.checks - self.valid
406 undef_set.discard('VUID-Undefined') # don't report Undefined
407 if ignore_unassigned:
408 unassigned = set({uv for uv in undef_set if uv.startswith('UNASSIGNED-')})
409 undef_set = undef_set - unassigned
410 if (len(undef_set) > 0):
411 print("\nFollowing VUIDs found in layer code are not defined in validusage.json (%d):" % len(undef_set))
412 undef = list(undef_set)
413 undef.sort()
414 for vuid in undef:
415 print(" %s" % vuid)
416 return False
417 return True
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600418
Dave Houltoncacef472018-05-29 13:00:42 -0600419 # Report undefined VUIDs in tests
420 def undef_vuids_in_tests(self):
421 undef_set = self.tests - self.valid
422 undef_set.discard('VUID-Undefined') # don't report Undefined
423 if ignore_unassigned:
424 unassigned = set({uv for uv in undef_set if uv.startswith('UNASSIGNED-')})
425 undef_set = undef_set - unassigned
426 if (len(undef_set) > 0):
427 ok = False
428 print("\nFollowing VUIDs found in layer tests are not defined in validusage.json (%d):" % len(undef_set))
429 undef = list(undef_set)
430 undef.sort()
431 for vuid in undef:
432 print(" %s" % vuid)
433 return False
434 return True
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600435
Dave Houltoncacef472018-05-29 13:00:42 -0600436 # Report vuids in tests that are not in source
437 def vuids_tested_not_checked(self):
438 undef_set = self.tests - self.checks
439 undef_set.discard('VUID-Undefined') # don't report Undefined
440 if ignore_unassigned:
441 unassigned = set()
442 for vuid in undef_set:
443 if vuid.startswith('UNASSIGNED-'):
444 unassigned.add(vuid)
445 undef_set = undef_set - unassigned
446 if (len(undef_set) > 0):
447 ok = False
448 print("\nFollowing VUIDs found in tests but are not checked in layer code (%d):" % len(undef_set))
449 undef = list(undef_set)
450 undef.sort()
451 for vuid in undef:
452 print(" %s" % vuid)
453 return False
454 return True
455
456 # TODO: Explicit checked VUIDs which have no test
457 # def explicit_vuids_checked_not_tested(self):
458
459
460# Class to output database in various flavors
461#
462class OutputDatabase:
463 def __init__(self, val_json, val_source, val_tests):
464 self.vj = val_json
465 self.vs = val_source
466 self.vt = val_tests
Dave Houlton407df732018-08-06 17:58:24 -0600467 self.header_preamble = """/* THIS FILE IS GENERATED. DO NOT EDIT. */
468/* (scripts/vk_validation_stats.py) */
469/*
470 * Vulkan
471 *
472 * Copyright (c) 2016-2018 Google Inc.
473 * Copyright (c) 2016-2018 LunarG, Inc.
474 *
475 * Licensed under the Apache License, Version 2.0 (the "License");
476 * you may not use this file except in compliance with the License.
477 * You may obtain a copy of the License at
478 *
479 * http://www.apache.org/licenses/LICENSE-2.0
480 *
481 * Unless required by applicable law or agreed to in writing, software
482 * distributed under the License is distributed on an "AS IS" BASIS,
483 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
484 * See the License for the specific language governing permissions and
485 * limitations under the License.
486 *
487 * Author: Tobin Ehlis <tobine@google.com>
488 * Author: Dave Houlton <daveh@lunarg.com>
489 */
490
491#pragma once
492
493// Disable auto-formatting for generated file
494// clang-format off
495
Dave Houlton407df732018-08-06 17:58:24 -0600496// Mapping from VUID string to the corresponding spec text
Dave Houlton4d9b2f82018-10-24 18:21:06 -0600497typedef struct _vuid_spec_text_pair {
498 const char * vuid;
499 const char * spec_text;
500} vuid_spec_text_pair;
501
502static const vuid_spec_text_pair vuid_spec_text[] = {
Dave Houlton407df732018-08-06 17:58:24 -0600503"""
504 self.header_postamble = """};
Dave Houlton4d9b2f82018-10-24 18:21:06 -0600505"""
Dave Houlton407df732018-08-06 17:58:24 -0600506 self.spec_url = "https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html"
Dave Houltoncacef472018-05-29 13:00:42 -0600507
508 def dump_txt(self):
509 print("\n Dumping database to text file: %s" % txt_filename)
510 with open (txt_filename, 'w') as txt:
511 txt.write("## VUID Database\n")
512 txt.write("## Format: VUID_NAME | CHECKED | TEST | TYPE | API/STRUCT | EXTENSION | VUID_TEXT\n##\n")
513 vuid_list = list(self.vj.all_vuids)
514 vuid_list.sort()
515 for vuid in vuid_list:
516 db_list = self.vj.vuid_db[vuid]
517 db_list.sort(key=operator.itemgetter('ext')) # sort list to ease diffs of output file
518 for db_entry in db_list:
519 checked = 'N'
520 if vuid in self.vs.all_vuids:
521 checked = 'Y'
522 test = 'None'
523 if vuid in self.vt.vuid_to_tests:
524 test_list = list(self.vt.vuid_to_tests[vuid])
525 test_list.sort() # sort tests, for diff-ability
526 sep = ', '
527 test = sep.join(test_list)
528
529 txt.write("%s | %s | %s | %s | %s | %s | %s\n" % (vuid, checked, test, db_entry['type'], db_entry['api'], db_entry['ext'], db_entry['text']))
530
531 def dump_csv(self):
532 print("\n Dumping database to csv file: %s" % csv_filename)
533 with open (csv_filename, 'w', newline='') as csvfile:
534 cw = csv.writer(csvfile)
535 cw.writerow(['VUID_NAME','CHECKED','TEST','TYPE','API/STRUCT','EXTENSION','VUID_TEXT'])
536 vuid_list = list(self.vj.all_vuids)
537 vuid_list.sort()
538 for vuid in vuid_list:
539 for db_entry in self.vj.vuid_db[vuid]:
540 row = [vuid]
541 if vuid in self.vs.all_vuids:
542 row.append('Y')
543 else:
544 row.append('N')
545 test = 'None'
546 if vuid in self.vt.vuid_to_tests:
547 sep = ', '
548 test = sep.join(self.vt.vuid_to_tests[vuid])
549 row.append(test)
550 row.append(db_entry['type'])
551 row.append(db_entry['api'])
552 row.append(db_entry['ext'])
553 row.append(db_entry['text'])
554 cw.writerow(row)
555
556 def dump_html(self):
557 print("\n Dumping database to html file: %s" % html_filename)
558 preamble = '<!DOCTYPE html>\n<html>\n<head>\n<style>\ntable, th, td {\n border: 1px solid black;\n border-collapse: collapse; \n}\n</style>\n<body>\n<h2>Valid Usage Database</h2>\n<font size="2" face="Arial">\n<table style="width:100%">\n'
559 headers = '<tr><th>VUID NAME</th><th>CHECKED</th><th>TEST</th><th>TYPE</th><th>API/STRUCT</th><th>EXTENSION</th><th>VUID TEXT</th></tr>\n'
560 with open (html_filename, 'w') as hfile:
561 hfile.write(preamble)
562 hfile.write(headers)
563 vuid_list = list(self.vj.all_vuids)
564 vuid_list.sort()
565 for vuid in vuid_list:
566 for db_entry in self.vj.vuid_db[vuid]:
567 hfile.write('<tr><th>%s</th>' % vuid)
568 checked = '<span style="color:red;">N</span>'
569 if vuid in self.vs.all_vuids:
570 checked = '<span style="color:limegreen;">Y</span>'
571 hfile.write('<th>%s</th>' % checked)
572 test = 'None'
573 if vuid in self.vt.vuid_to_tests:
574 sep = ', '
575 test = sep.join(self.vt.vuid_to_tests[vuid])
576 hfile.write('<th>%s</th>' % test)
577 hfile.write('<th>%s</th>' % db_entry['type'])
578 hfile.write('<th>%s</th>' % db_entry['api'])
579 hfile.write('<th>%s</th>' % db_entry['ext'])
580 hfile.write('<th>%s</th></tr>\n' % db_entry['text'])
581 hfile.write('</table>\n</body>\n</html>\n')
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600582
Dave Houlton407df732018-08-06 17:58:24 -0600583 def export_header(self):
584 print("\n Exporting header file to: %s" % header_filename)
585 with open (header_filename, 'w') as hfile:
586 hfile.write(self.header_preamble)
587 vuid_list = list(self.vj.all_vuids)
588 vuid_list.sort()
589 for vuid in vuid_list:
590 db_entry = self.vj.vuid_db[vuid][0]
591 hfile.write(' {"%s", "%s (%s#%s)"},\n' % (vuid, db_entry['text'].strip(' '), self.spec_url, vuid))
592 # For multiply-defined VUIDs, include versions with extension appended
593 if len(self.vj.vuid_db[vuid]) > 1:
594 for db_entry in self.vj.vuid_db[vuid]:
595 hfile.write(' {"%s[%s]", "%s (%s#%s)"},\n' % (vuid, db_entry['ext'].strip(' '), db_entry['text'].strip(' '), self.spec_url, vuid))
596 hfile.write(self.header_postamble)
597
Mark Lobodzinskib44c54a2017-06-12 12:02:38 -0600598def main(argv):
Dave Houltoncacef472018-05-29 13:00:42 -0600599 global verbose_mode
600 global txt_filename
601 global csv_filename
602 global html_filename
603
604 run_consistency = False
605 report_unimplemented = False
606 get_vuid_status = ''
607 txt_out = False
608 csv_out = False
609 html_out = False
Dave Houlton407df732018-08-06 17:58:24 -0600610 header_out = False
Dave Houltoncacef472018-05-29 13:00:42 -0600611
612 if (1 > len(argv)):
613 printHelp()
614 sys.exit()
615
616 # Parse script args
617 json_filename = argv[0]
618 i = 1
619 while (i < len(argv)):
620 arg = argv[i]
621 i = i + 1
622 if (arg == '-c'):
623 run_consistency = True
624 elif (arg == '-vuid'):
625 get_vuid_status = argv[i]
626 i = i + 1
627 elif (arg == '-todo'):
628 report_unimplemented = True
Karl Schultz49d66bb2018-07-09 16:24:46 -0600629 elif (arg == '-text'):
Dave Houltoncacef472018-05-29 13:00:42 -0600630 txt_out = True
631 # Set filename if supplied, else use default
632 if i < len(argv) and not argv[i].startswith('-'):
633 txt_filename = argv[i]
634 i = i + 1
635 elif (arg == '-csv'):
636 csv_out = True
637 # Set filename if supplied, else use default
638 if i < len(argv) and not argv[i].startswith('-'):
639 csv_filename = argv[i]
640 i = i + 1
641 elif (arg == '-html'):
642 html_out = True
643 # Set filename if supplied, else use default
644 if i < len(argv) and not argv[i].startswith('-'):
645 html_filename = argv[i]
646 i = i + 1
Dave Houlton407df732018-08-06 17:58:24 -0600647 elif (arg == '-export_header'):
648 header_out = True
Dave Houltoncacef472018-05-29 13:00:42 -0600649 elif (arg in ['-verbose']):
650 verbose_mode = True
651 elif (arg in ['-help', '-h']):
652 printHelp()
653 sys.exit()
654 else:
655 print("Unrecognized argument: %s\n" % arg)
656 printHelp()
657 sys.exit()
658
Tobin Ehlis20e32582016-12-05 14:50:03 -0700659 result = 0 # Non-zero result indicates an error case
Dave Houltoncacef472018-05-29 13:00:42 -0600660
661 # Parse validusage json
662 val_json = ValidationJSON(json_filename)
663 val_json.read()
664 exp_json = len(val_json.explicit_vuids)
665 imp_json = len(val_json.implicit_vuids)
666 all_json = len(val_json.all_vuids)
667 if verbose_mode:
668 print("Found %d unique error vuids in validusage.json file." % all_json)
669 print(" %d explicit" % exp_json)
670 print(" %d implicit" % imp_json)
671 if len(val_json.duplicate_vuids) > 0:
672 print("%d VUIDs appear in validusage.json more than once." % len(val_json.duplicate_vuids))
673 for vuid in val_json.duplicate_vuids:
674 print(" %s" % vuid)
675 for ext in val_json.vuid_db[vuid]:
676 print(" with extension: %s" % ext['ext'])
677
678 # Parse layer source files
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600679 val_source = ValidationSource(layer_source_files, generated_layer_source_files, generated_layer_source_directories)
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600680 val_source.parse()
Dave Houltoncacef472018-05-29 13:00:42 -0600681 exp_checks = len(val_source.explicit_vuids)
682 imp_checks = len(val_source.implicit_vuids)
683 all_checks = len(val_source.vuid_count_dict.keys())
684 if verbose_mode:
685 print("Found %d unique vuid checks in layer source code." % all_checks)
686 print(" %d explicit" % exp_checks)
687 print(" %d implicit" % imp_checks)
688 print(" %d unassigned" % len(val_source.unassigned_vuids))
689 print(" %d checks are implemented more that once" % val_source.duplicated_checks)
690
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600691 # Parse test files
Dave Houltoncacef472018-05-29 13:00:42 -0600692 val_tests = ValidationTests([test_file, ])
693 val_tests.parse()
694 exp_tests = len(val_tests.explicit_vuids)
695 imp_tests = len(val_tests.implicit_vuids)
696 all_tests = len(val_tests.all_vuids)
Mark Lobodzinski060a8e32018-01-08 09:08:06 -0700697 if verbose_mode:
Dave Houltoncacef472018-05-29 13:00:42 -0600698 print("Found %d unique error vuids in test file %s." % (all_tests, test_file))
699 print(" %d explicit" % exp_tests)
700 print(" %d implicit" % imp_tests)
701 print(" %d unassigned" % len(val_tests.unassigned_vuids))
Mike Weiblenfe186122017-02-03 12:44:53 -0700702
Dave Houltoncacef472018-05-29 13:00:42 -0600703 # Process stats
704 print("\nValidation Statistics (using validusage.json version %s)" % val_json.apiversion)
705 print(" VUIDs defined in JSON file: %04d explicit, %04d implicit, %04d total." % (exp_json, imp_json, all_json))
706 print(" VUIDs checked in layer code: %04d explicit, %04d implicit, %04d total." % (exp_checks, imp_checks, all_checks))
707 print(" VUIDs tested in layer tests: %04d explicit, %04d implicit, %04d total." % (exp_tests, imp_tests, all_tests))
708
709 print("\nVUID check coverage")
710 print(" Explicit VUIDs checked: %.1f%% (%d checked vs %d defined)" % ((100.0 * exp_checks / exp_json), exp_checks, exp_json))
711 print(" Implicit VUIDs checked: %.1f%% (%d checked vs %d defined)" % ((100.0 * imp_checks / imp_json), imp_checks, imp_json))
712 print(" Overall VUIDs checked: %.1f%% (%d checked vs %d defined)" % ((100.0 * all_checks / all_json), all_checks, all_json))
Mike Weiblenfe186122017-02-03 12:44:53 -0700713
Dave Houltoncacef472018-05-29 13:00:42 -0600714 print("\nVUID test coverage")
715 print(" Explicit VUIDs tested: %.1f%% (%d tested vs %d checks)" % ((100.0 * exp_tests / exp_checks), exp_tests, exp_checks))
716 print(" Implicit VUIDs tested: %.1f%% (%d tested vs %d checks)" % ((100.0 * imp_tests / imp_checks), imp_tests, imp_checks))
717 print(" Overall VUIDs tested: %.1f%% (%d tested vs %d checks)" % ((100.0 * all_tests / all_checks), all_tests, all_checks))
Mike Weiblenfe186122017-02-03 12:44:53 -0700718
Dave Houltoncacef472018-05-29 13:00:42 -0600719 # Report status of a single VUID
720 if len(get_vuid_status) > 1:
721 print("\n\nChecking status of <%s>" % get_vuid_status);
722 if get_vuid_status not in val_json.all_vuids:
723 print(' Not a valid VUID string.')
724 else:
725 if get_vuid_status in val_source.explicit_vuids:
726 print(' Implemented!')
727 line_list = val_source.vuid_count_dict[get_vuid_status]['file_line']
728 for line in line_list:
729 print(' => %s' % line)
Dave Houltonf93bbab2018-06-26 17:21:12 -0600730 elif get_vuid_status in val_source.implicit_vuids:
731 print(' Implemented! (Implicit)')
732 line_list = val_source.vuid_count_dict[get_vuid_status]['file_line']
733 for line in line_list:
734 print(' => %s' % line)
Tobin Ehlis9a68c982016-12-29 14:51:17 -0700735 else:
Dave Houltoncacef472018-05-29 13:00:42 -0600736 print(' Not implemented.')
Dave Houltonf93bbab2018-06-26 17:21:12 -0600737 if get_vuid_status in val_tests.all_vuids:
Dave Houltoncacef472018-05-29 13:00:42 -0600738 print(' Has a test!')
739 test_list = val_tests.vuid_to_tests[get_vuid_status]
740 for test in test_list:
741 print(' => %s' % test)
742 else:
743 print(' Not tested.')
Mike Weiblenfe186122017-02-03 12:44:53 -0700744
Dave Houltoncacef472018-05-29 13:00:42 -0600745 # Report unimplemented explicit VUIDs
746 if report_unimplemented:
747 unim_explicit = val_json.explicit_vuids - val_source.explicit_vuids
748 print("\n\n%d explicit VUID checks remain unimplemented:" % len(unim_explicit))
749 ulist = list(unim_explicit)
750 ulist.sort()
751 for vuid in ulist:
752 print(" => %s" % vuid)
753
754 # Consistency tests
755 if run_consistency:
756 print("\n\nRunning consistency tests...")
757 con = Consistency(val_json.all_vuids, val_source.all_vuids, val_tests.all_vuids)
758 ok = con.undef_vuids_in_layer_code()
759 ok &= con.undef_vuids_in_tests()
760 ok &= con.vuids_tested_not_checked()
761
762 if ok:
763 print(" OK! No inconsistencies found.")
764
765 # Output database in requested format(s)
766 db_out = OutputDatabase(val_json, val_source, val_tests)
767 if txt_out:
768 db_out.dump_txt()
769 if csv_out:
770 db_out.dump_csv()
771 if html_out:
772 db_out.dump_html()
Dave Houlton407df732018-08-06 17:58:24 -0600773 if header_out:
774 db_out.export_header()
Tobin Ehlis20e32582016-12-05 14:50:03 -0700775 return result
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600776
777if __name__ == "__main__":
Mark Lobodzinskib44c54a2017-06-12 12:02:38 -0600778 sys.exit(main(sys.argv[1:]))
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600779