github.com/CycloneDX/sbom-utility@v0.16.0/cmd/validate_custom_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 /* 3 * Licensed to the Apache Software Foundation (ASF) under one or more 4 * contributor license agreements. See the NOTICE file distributed with 5 * this work for additional information regarding copyright ownership. 6 * The ASF licenses this file to You under the Apache License, Version 2.0 7 * (the "License"); you may not use this file except in compliance with 8 * the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package cmd 20 21 import ( 22 "testing" 23 24 "github.com/CycloneDX/sbom-utility/schema" 25 "github.com/CycloneDX/sbom-utility/utils" 26 "github.com/xeipuuv/gojsonschema" 27 ) 28 29 // Custom JSON schema files for testing 30 const ( 31 TEST_SCHEMA_CDX_1_3_CUSTOM = "resources/schema/test/bom-1.3-custom.schema.json" 32 TEST_SCHEMA_CDX_1_4_CUSTOM = "resources/schema/test/bom-1.4-custom.schema.json" 33 ) 34 35 // Custom-specific test files 36 const ( 37 // Metadata tests 38 TEST_CUSTOM_CDX_1_4_METADATA_PROPS_DISCLAIMER_INVALID = "test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json" 39 TEST_CUSTOM_CDX_1_4_METADATA_PROPS_DISCLAIMER_MISSING = "test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-missing.json" 40 TEST_CUSTOM_CDX_1_4_METADATA_PROPS_DISCLAIMER_UNIQUE = "test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-unique.json" 41 TEST_CUSTOM_CDX_1_4_METADATA_PROPS_CLASSIFICATION_INVALID = "test/custom/cdx-1-4-test-custom-metadata-property-classification-invalid.json" 42 TEST_CUSTOM_CDX_1_4_METADATA_PROPS_CLASSIFICATION_MISSING = "test/custom/cdx-1-4-test-custom-metadata-property-classification-missing.json" 43 TEST_CUSTOM_CDX_1_4_METADATA_PROPS_CLASSIFICATION_UNIQUE = "test/custom/cdx-1-4-test-custom-metadata-property-classification-unique.json" 44 45 // License tests 46 // Note: The "invalid" tests below is also used in "list" command tests 47 // which tests for a "none found" warning messages being displayed to stdout 48 TEST_CUSTOM_CDX_1_4_INVALID_LICENSES_NOT_FOUND = TEST_LICENSE_LIST_CDX_1_4_NONE_FOUND 49 50 // Composition 51 TEST_CUSTOM_CDX_1_3_INVALID_COMPOSITION_COMPONENTS = "test/custom/cdx-1-3-test-custom-invalid-composition-components.json" 52 TEST_CUSTOM_CDX_1_3_INVALID_COMPOSITION_METADATA_COMPONENT = "test/custom/cdx-1-3-test-custom-invalid-composition-metadata-component.json" 53 ) 54 55 // ------------------------------------------- 56 // Test wrappers 57 // ------------------------------------------- 58 59 func innerTestValidateCustom(t *testing.T, vti ValidateTestInfo) (document *schema.BOM, schemaErrors []gojsonschema.ResultError, actualError error) { 60 utils.GlobalFlags.ValidateFlags.CustomValidation = true 61 document, schemaErrors, actualError = innerTestValidate(t, vti) 62 utils.GlobalFlags.ValidateFlags.CustomValidation = false 63 return 64 } 65 66 func innerTestValidateCustomInvalidSBOMInnerError(t *testing.T, filename string, variant string, innerError error) (document *schema.BOM, schemaErrors []gojsonschema.ResultError, actualError error) { 67 utils.GlobalFlags.ValidateFlags.CustomValidation = true 68 document, schemaErrors, actualError = innerValidateInvalidSBOMInnerError(t, filename, variant, innerError) 69 utils.GlobalFlags.ValidateFlags.CustomValidation = false 70 return 71 } 72 73 // ------------------------------------------- 74 // Command & flag tests 75 // ------------------------------------------- 76 77 // Test format unsupported (SPDX) for "--custom" flag 78 func TestValidateCustomFormatUnsupportedSPDX(t *testing.T) { 79 vti := NewValidateTestInfo(TEST_SPDX_2_2_MIN_REQUIRED, FORMAT_ANY, SCHEMA_VARIANT_NONE, &schema.UnsupportedFormatError{}) 80 innerTestValidateCustom(t, *vti) 81 } 82 83 // ------------------------------------------- 84 // Schema: cross-document tests 85 // ------------------------------------------- 86 87 // Error if no licenses found in entirety of SBOM (variant none) 88 func TestValidateCustomErrorCdx14NoLicensesFound(t *testing.T) { 89 vti := NewValidateTestInfo(TEST_CUSTOM_CDX_1_4_INVALID_LICENSES_NOT_FOUND, FORMAT_ANY, SCHEMA_VARIANT_NONE, &InvalidSBOMError{}) 90 document, results, _ := innerTestValidateCustom(t, *vti) 91 getLogger().Debugf("filename: `%s`, results:\n%v", document.GetFilename(), results) 92 } 93 94 // ------------------------------------------- 95 // Schema: metadata tests 96 // ------------------------------------------- 97 98 func TestValidateCustomCdx14MetadataPropsMissingDisclaimer(t *testing.T) { 99 vti := NewValidateTestInfo(TEST_CUSTOM_CDX_1_4_METADATA_PROPS_DISCLAIMER_MISSING, FORMAT_TEXT, SCHEMA_VARIANT_CUSTOM, &InvalidSBOMError{}) 100 document, results, _ := innerTestValidate(t, *vti) 101 getLogger().Debugf("filename: `%s`, results:\n%v", document.GetFilename(), results) 102 } 103 104 func TestValidateCustomCdx14MetadataPropsMissingClassification(t *testing.T) { 105 vti := NewValidateTestInfo(TEST_CUSTOM_CDX_1_4_METADATA_PROPS_CLASSIFICATION_MISSING, FORMAT_TEXT, SCHEMA_VARIANT_CUSTOM, &InvalidSBOMError{}) 106 document, results, _ := innerTestValidate(t, *vti) 107 getLogger().Debugf("filename: `%s`, results:\n%v", document.GetFilename(), results) 108 } 109 110 func TestValidateCustomCdx14MetadataPropsInvalidDisclaimer(t *testing.T) { 111 // disclaimer property 112 SCHEMA_ERROR_TYPE := "contains" 113 SCHEMA_ERROR_FIELD := "metadata.properties" 114 SCHEMA_ERROR_VALUE := "" 115 116 innerTestSchemaErrorAndErrorResults(t, 117 TEST_CUSTOM_CDX_1_4_METADATA_PROPS_DISCLAIMER_INVALID, 118 SCHEMA_VARIANT_CUSTOM, 119 SCHEMA_ERROR_TYPE, 120 SCHEMA_ERROR_FIELD, 121 SCHEMA_ERROR_VALUE) 122 123 SCHEMA_ERROR_TYPE = "const" 124 SCHEMA_ERROR_FIELD = "metadata.properties.0.value" 125 SCHEMA_ERROR_VALUE = "" 126 127 innerTestSchemaErrorAndErrorResults(t, 128 TEST_CUSTOM_CDX_1_4_METADATA_PROPS_DISCLAIMER_INVALID, 129 SCHEMA_VARIANT_CUSTOM, 130 SCHEMA_ERROR_TYPE, 131 SCHEMA_ERROR_FIELD, 132 SCHEMA_ERROR_VALUE) 133 } 134 135 func TestValidateCustomCdx14MetadataPropsInvalidClassification(t *testing.T) { 136 137 SCHEMA_ERROR_TYPE := "contains" 138 SCHEMA_ERROR_FIELD := "metadata.properties" 139 SCHEMA_ERROR_VALUE := "" 140 141 innerTestSchemaErrorAndErrorResults(t, 142 TEST_CUSTOM_CDX_1_4_METADATA_PROPS_CLASSIFICATION_INVALID, 143 SCHEMA_VARIANT_CUSTOM, 144 SCHEMA_ERROR_TYPE, 145 SCHEMA_ERROR_FIELD, 146 SCHEMA_ERROR_VALUE) 147 148 SCHEMA_ERROR_TYPE = "const" 149 SCHEMA_ERROR_FIELD = "metadata.properties.1.value" 150 SCHEMA_ERROR_VALUE = "" 151 152 innerTestSchemaErrorAndErrorResults(t, 153 TEST_CUSTOM_CDX_1_4_METADATA_PROPS_CLASSIFICATION_INVALID, 154 SCHEMA_VARIANT_CUSTOM, 155 SCHEMA_ERROR_TYPE, 156 SCHEMA_ERROR_FIELD, 157 SCHEMA_ERROR_VALUE) 158 } 159 160 // ------------------------------------------- 161 // Property uniqueness tests 162 // ------------------------------------------- 163 // Note: The "uniqueness" constraint for objects is not supported in JSON schema v7 164 165 func TestValidateCustomCdx14MetadataPropertyUniqueDisclaimer(t *testing.T) { 166 document, results, _ := innerTestValidateCustomInvalidSBOMInnerError(t, 167 TEST_CUSTOM_CDX_1_4_METADATA_PROPS_DISCLAIMER_UNIQUE, 168 SCHEMA_VARIANT_NONE, 169 &SBOMMetadataPropertyError{}) 170 getLogger().Debugf("filename: `%s`, results:\n%v", document.GetFilename(), results) 171 } 172 173 func TestValidateCustomCdx14MetadataPropertyUniqueClassification(t *testing.T) { 174 document, results, _ := innerTestValidateCustomInvalidSBOMInnerError(t, 175 TEST_CUSTOM_CDX_1_4_METADATA_PROPS_DISCLAIMER_UNIQUE, 176 SCHEMA_VARIANT_NONE, 177 &SBOMMetadataPropertyError{}) 178 getLogger().Debugf("filename: `%s`, results:\n%v", document.GetFilename(), results) 179 } 180 181 // ------------------------------------------- 182 // Composition tests 183 // ------------------------------------------- 184 185 // Error if hierarchical components found in top-level "metadata.component" object 186 func TestValidateCustomErrorCdx13InvalidCompositionMetadataComponent(t *testing.T) { 187 innerTestValidateCustomInvalidSBOMInnerError(t, 188 TEST_CUSTOM_CDX_1_3_INVALID_COMPOSITION_METADATA_COMPONENT, 189 SCHEMA_VARIANT_NONE, 190 &SBOMCompositionError{}) 191 } 192 193 // Error if hierarchical components in top-level "components" array 194 func TestValidateCustomErrorCdx13InvalidCompositionComponents(t *testing.T) { 195 innerTestValidateCustomInvalidSBOMInnerError(t, 196 TEST_CUSTOM_CDX_1_3_INVALID_COMPOSITION_METADATA_COMPONENT, 197 SCHEMA_VARIANT_NONE, 198 &SBOMCompositionError{}) 199 } 200 201 // Make sure we can List all components in an SBOM, including those in hierarchical compositions 202 // TODO: Actually verify one or more of the hierarchical comps. appear in list results 203 // func TestValidateCustomCompositionHierarchicalComponentList(t *testing.T) { 204 // innerCustomValidateError(t, 205 // TEST_CUSTOM_CDX_1_4_COMPOSITION_HIERARCHICAL_COMPONENTS, 206 // SCHEMA_VARIANT_NONE, 207 // nil) 208 // }