def test_cannot_retrieve_spdx_files_if_invalid_year_month_specified(self): # Edith wants to have SLM automatically retrieve and rename SPDX files, # but requests an invalid month format result = runcmd(self, slm.cli, "frotz", "set-config", "spdx-search-dir", self.spdxSearchDir.path) self.assertEqual(0, result.exit_code) result = runcmd(self, slm.cli, "frotz", "retrieve-spdx", "--month", "blah") # It fails and explains why self.assertEqual(1, result.exit_code) self.assertEqual( f"Invalid format for --month argument (blah): should be --month YYYY-MM\n", result.output) # She tries again but gets the format wrong, and mistakenly includes the day result = runcmd(self, slm.cli, "frotz", "retrieve-spdx", "--month", "2018-03-21") # It fails again and explains why self.assertEqual(1, result.exit_code) self.assertEqual( f"Invalid format for --month argument (2018-03-21): should be --month YYYY-MM\n", result.output)
def test_make_all_reports_does_not_recreate_existing_reports(self): # Edith creates a report with a standard path result = runcmd(self, slm.cli, "frotz", "create-report", "--scan_id", "1", "--report_format", "xlsx") # She checks to make sure, and indeed the report is there self.assertEqual(0, result.exit_code) p1 = os.path.join("projects", "frotz", "subprojects", "frotz-nuclear", "reports", "frotz-nuclear-2018-01-26.xlsx") checkForFileExists(self, self.slmhome, p1) # Now she wants to automatically have all types of reports created # for all currently-imported scans, for this project, but the # first report shouldn't be re-created result = runcmd(self, slm.cli, "frotz", "create-reports") # The output message tells her it succeeded and that only 3 reports # were created self.assertEqual(0, result.exit_code) self.assertEqual("3 reports successfully created\n", result.output) # She checks to make sure, and indeed the new reports are there checkForFileExists(self, self.slmhome, p1) p2 = os.path.join("projects", "frotz", "subprojects", "frotz-nuclear", "reports", "frotz-nuclear-2018-01-26.json") checkForFileExists(self, self.slmhome, p2) p3 = os.path.join("projects", "frotz", "subprojects", "frotz-dim", "reports", "frotz-dim-2018-02-06.xlsx") checkForFileExists(self, self.slmhome, p3) p4 = os.path.join("projects", "frotz", "subprojects", "frotz-dim", "reports", "frotz-dim-2018-02-06.json") checkForFileExists(self, self.slmhome, p4)
def test_can_get_desc_for_projects_when_listing_with_verbose_flag(self): # Edith wants to get descriptions too when she lists the projects # using the -v flag result = runcmd(self, slm.cli, None, "-v", "list") self.assertEqual(0, result.exit_code) self.assertIn("The FROTZ Project", result.output) # It also works with the --verbose flag result = runcmd(self, slm.cli, None, "--verbose", "list") self.assertEqual(0, result.exit_code) self.assertIn("The FROTZ Project", result.output)
def test_can_create_simple_json_file_without_summary(self): # Edith imports a very short SPDX file as a new scan in the frotz # subproject frotz-dim result = runcmd(self, slm.cli, "frotz", "--subproject", "frotz-dim", "import-scan", PATH_SIMPLE_SPDX, "--scan_date", "2017-05-05", "--desc", "frotz-dim initial scan") self.assertEqual(0, result.exit_code) # Now Edith wants to get a JSON version of the findings. # She configures it to omit empty categories and licenses result = runcmd(self, slm.cli, "frotz", "set-config", "analyze-exclude-empty-cats-and-lics", "yes") self.assertEqual(0, result.exit_code) # And she requests the report and specifies the target output path reportPath = self.reportDir.path + "/report.json" result = runcmd(self, slm.cli, "frotz", "--subproject", "frotz-dim", "create-report", "--scan_id", "3", "--report_format", "json", "--report_path", reportPath) # The output message tells her it succeeded self.assertEqual(0, result.exit_code) self.assertEqual(f"Report successfully created at {reportPath}.\n", result.output) # She confirms that the file was created successfully self.assertTrue(os.path.isfile(reportPath)) # Re-importing the JSON file, she sees that the expected values are present # in the expected format with open(reportPath, 'r') as f: rj = json.load(f) self.assertIsInstance(rj, list) self.assertEqual(len(rj), 2) cat1 = rj[0] self.assertEqual(cat1.get("name"), "Attribution") self.assertIsInstance(cat1.get("_id"), int) self.assertEqual(cat1.get("numFiles"), 1) cat1Lics = cat1.get("licenses") self.assertIsInstance(cat1Lics, list) self.assertEqual(len(cat1Lics), 1) lic1 = cat1Lics[0] self.assertEqual(lic1.get("name"), "MIT") self.assertIsInstance(lic1.get("_id"), int) self.assertEqual(lic1.get("numFiles"), 1) lic1Files = lic1.get("files") self.assertIsInstance(lic1Files, list) self.assertEqual(len(lic1Files), 1) file1 = lic1Files[0] self.assertEqual(file1.get("path"), "simple/file2.txt") self.assertIsInstance(file1.get("_id"), int) cat2 = rj[1] lic2 = cat2.get("licenses")[0] self.assertEqual(len(lic2.get("files")), 3)
def test_can_change_subproject_spdx_search_name(self): # Edith asks SLM to change a subproject's default spdx search term result = runcmd(self, slm.cli, "frotz", "--subproject", "frotz-dim", "edit-subproject", "--spdx_search", "fdim") # It works fine, and sets the project spdx search term to fdim self.assertEqual(0, result.exit_code) # ...which she confirms with a "list" call result = runcmd(self, slm.cli, "frotz", "-v", "list") self.assertEqual(0, result.exit_code) self.assertIn("fdim", result.output)
def test_project_with_no_desc_option_gets_NO_DESCRIPTION_text(self): # Edith asks SLM to create a new project, but accidentally omits the # "desc" option to the create-project command result = runcmd(self, slm.cli, None, "create-project", "nodesc") # It works fine, and sets the project description to NO DESCRIPTION self.assertEqual(0, result.exit_code) # ...which she confirms with a "list" call result = runcmd(self, slm.cli, None, "-v", "list") self.assertEqual(0, result.exit_code) self.assertIn("NO DESCRIPTION", result.output)
def test_cannot_add_a_duplicate_conversion(self): # Edith tries to add a new conversion, but accidentally specifies text # that matches an existing conversion runcmd(self, slm.cli, 'frotz', 'add-conversion', 'BSD-Simplified', 'BSD-2-Clause') result = runcmd(self, slm.cli, 'frotz', 'add-conversion', 'BSD-Simplified', 'MIT') # It fails and explains why self.assertEqual(1, result.exit_code) self.assertEqual(f"Conversion 'BSD-Simplified' already exists.\n", result.output)
def test_cannot_retrieve_spdx_files_if_no_month_specified(self): # Edith wants to have SLM automatically retrieve and rename SPDX files, # but mistakenly forgot to specify a month to search result = runcmd(self, slm.cli, "frotz", "set-config", "spdx-search-dir", self.spdxSearchDir.path) self.assertEqual(0, result.exit_code) result = runcmd(self, slm.cli, "frotz", "retrieve-spdx") # It fails and explains why self.assertEqual(1, result.exit_code) self.assertEqual(f"Missing argument: --month YYYY-MM\n", result.output)
def test_can_change_a_license_name(self): # Edith decides that the BSD-2-Clause license should have been called # BSD-Simplified instead result = runcmd(self, slm.cli, "frotz", "edit-license", "BSD-2-Clause", "--new-name", "BSD-Simplified") self.assertEqual(0, result.exit_code) # When listing the license, BSD-Simplified is now listed result = runcmd(self, slm.cli, "frotz", "list-licenses") self.assertEqual(0, result.exit_code) self.assertIn("BSD-Simplified", result.output) self.assertNotIn("BSD-2-Clause", result.output)
def test_can_list_projects_and_subprojects(self): # Edith wants to see which top-level projects she is currently tracking # in spdxLicenseManager. She asks for a list of projects result = runcmd(self, slm.cli, None, "list") self.assertEqual(0, result.exit_code) self.assertEqual("frotz\ngnusto\nrezrov\n", result.output) # She knows that frotz has multiple subprojects, so she asks for a list of # its subprojects result = runcmd(self, slm.cli, "frotz", "list") self.assertEqual(0, result.exit_code) self.assertEqual(result.output, "frotz/frotz-dim\nfrotz/frotz-nuclear\nfrotz/frotz-shiny\n")
def test_can_get_subproject_details_when_listing_with_verbose_flag(self): # Edith wants to get descriptions and SPDX search strings too when she # lists the subprojects using the -v flag result = runcmd(self, slm.cli, "frotz", "-v", "list") self.assertEqual(0, result.exit_code) self.assertIn("FROTZ with nuclear settings", result.output) self.assertIn("will search SPDX files for: frotz-nuclear", result.output) # It also works with the --verbose flag result = runcmd(self, slm.cli, "frotz", "--verbose", "list") self.assertEqual(0, result.exit_code) self.assertIn("FROTZ with nuclear settings", result.output) self.assertIn("will search SPDX files for: frotz-nuclear", result.output)
def test_cannot_change_a_conversion_to_a_nonexistent_license(self): # Edith assigned BSD-Simplified to BSD-2-Clause, and then accidentally # tries to change it to a nonexistent license runcmd(self, slm.cli, 'frotz', 'add-conversion', 'BSD-Simplified', 'BSD-2-Clause') result = runcmd(self, slm.cli, 'frotz', 'edit-conversion', 'BSD-Simplified', 'BSD-2-Clause-FreeBSD') # It fails and explains why self.assertEqual(1, result.exit_code) self.assertEqual( f"License 'BSD-2-Clause-FreeBSD' does not exist yet.\nDid you mean to call add-license first?\n", result.output)
def test_can_change_a_category_name(self): # Edith decides that the Attribution category should have been called # Permissive instead result = runcmd(self, slm.cli, "frotz", "edit-category", "Attribution", "--new-name", "Permissive") self.assertEqual(0, result.exit_code) # When listing the categories, Permissive is now listed result = runcmd(self, slm.cli, "frotz", "list-categories") self.assertEqual(0, result.exit_code) self.assertEqual( "Project Licenses\nCopyleft\nPermissive\nOther\nNo license found\n", result.output)
def test_can_add_and_retrieve_a_license(self): # Edith is creating a new license result = runcmd(self, slm.cli, "frotz", "add-license", "BSD-3-Clause", "Attribution") # It works correctly and lets her know self.assertEqual(0, result.exit_code) self.assertEqual("Created license: BSD-3-Clause\n", result.output) # She checks the list of licenses to make sure, and there it is result = runcmd(self, slm.cli, "frotz", "list-licenses") self.assertEqual(0, result.exit_code) self.assertIn("BSD-3-Clause", result.output)
def test_can_change_a_license_category(self): # Edith decides that the BSD-2-Clause license should have been in the # Copyleft category instead (for some reason) result = runcmd(self, slm.cli, "frotz", "edit-license", "BSD-2-Clause", "--new-cat", "Copyleft") self.assertEqual(0, result.exit_code) # When listing the license, BSD-2-Clause is now listed in Copyleft result = runcmd(self, slm.cli, "frotz", "list-licenses", "--by-category") self.assertEqual(0, result.exit_code) self.assertIn("Copyleft:\n BSD-2-Clause", result.output) self.assertNotIn("Attribution:\n BSD-2-Clause", result.output)
def test_can_move_a_category_from_higher_to_lower(self): # Edith decides that she wants the attribution category to show up before # the copyleft category. She edits the categories to reorder them result = runcmd(self, slm.cli, "frotz", "edit-category", "Attribution", "--sort-before", "Copyleft") self.assertEqual(0, result.exit_code) # When listing the categories, Attribution now shows up first result = runcmd(self, slm.cli, "frotz", "list-categories") self.assertEqual(0, result.exit_code) self.assertEqual( "Project Licenses\nAttribution\nCopyleft\nOther\nNo license found\n", result.output)
def test_can_overwrite_existing_report_file_with_force_flag(self): # Edith creates a report and then intentionally overwrites it # with a second call to save to the same path reportPath = self.reportDir.path + "/report.xlsx" result = runcmd(self, slm.cli, "frotz", "--subproject", "frotz-nuclear", "create-report", "--scan_id", "1", "--report_format", "xlsx", "--report_path", reportPath) result = runcmd(self, slm.cli, "frotz", "--subproject", "frotz-nuclear", "create-report", "--scan_id", "1", "--report_format", "xlsx", "--report_path", reportPath, "-f") # The output message tells her it succeeded self.assertEqual(0, result.exit_code) self.assertEqual(f"Report successfully created at {reportPath}.\n", result.output)
def test_cannot_overwrite_existing_report_file(self): # Edith creates a report and then accidentally tries to overwrite it # with a second call to save to the same path reportPath = self.reportDir.path + "/report.xlsx" result = runcmd(self, slm.cli, "frotz", "--subproject", "frotz-nuclear", "create-report", "--scan_id", "1", "--report_format", "xlsx", "--report_path", reportPath) result = runcmd(self, slm.cli, "frotz", "--subproject", "frotz-nuclear", "create-report", "--scan_id", "1", "--report_format", "xlsx", "--report_path", reportPath) # It fails and explains why self.assertEqual(1, result.exit_code) self.assertEqual(f"File already exists at {reportPath} (use -f to force overwrite)\n", result.output)
def test_can_create_and_retrieve_a_category(self): # Edith is creating a new category of licenses with Advertising Clauses result = runcmd(self, slm.cli, "frotz", "add-category", "Advertising Clauses") # It works correctly and lets her know self.assertEqual(0, result.exit_code) self.assertEqual("Created category: Advertising Clauses\n", result.output) # She checks the list of categories to make sure, and there it is result = runcmd(self, slm.cli, "frotz", "list-categories") self.assertEqual(0, result.exit_code) self.assertIn("Advertising Clauses", result.output)
def test_can_retrieve_spdx_files_and_move_to_subproject_folder(self): # Edith has set things correctly and asks SLM to retrieve, rename and move # the SPDX files for March 2018 result = runcmd(self, slm.cli, "frotz", "set-config", "spdx-search-dir", self.spdxSearchDir.path) self.assertEqual(0, result.exit_code) result = runcmd(self, slm.cli, "frotz", "retrieve-spdx", "--month", "2018-03") # It works and lets her know self.assertEqual(0, result.exit_code) newName = "frotz-dim-2018-03-21.spdx" self.assertEqual( f"Moved {SPDX_CORRECT_FILE} to frotz-dim (new name: {newName})\n", result.output) # She sees that the file is now present in the subproject's SPDX folder filePath = os.path.join(self.slmhome, "projects", "frotz", "subprojects", "frotz-dim", "spdx", newName) self.assertTrue(os.path.isfile(filePath)) # And she sees that the file's old name is not present in the subproject's # SPDX folder filePath = os.path.join(self.slmhome, "projects", "frotz", "subprojects", "frotz-dim", "spdx", SPDX_CORRECT_FILE) self.assertFalse(os.path.isfile(filePath)) # And she sees that the other two SPDX files with non-matching names are # not present in the subproject's SPDX folder filePath = os.path.join(self.slmhome, "projects", "frotz", "subprojects", "frotz-dim", "spdx", SPDX_NO_NAME) self.assertFalse(os.path.isfile(filePath)) filePath = os.path.join(self.slmhome, "projects", "frotz", "subprojects", "frotz-dim", "spdx", SPDX_NO_DATE) self.assertFalse(os.path.isfile(filePath)) # And she sees that it has been removed from the source search folder filePath = os.path.join(self.spdxSearchDir.path, SPDX_CORRECT_FILE) self.assertFalse(os.path.isfile(filePath)) # And she sees that the other two SPDX files with non-matching names are # still present in the source search folder filePath = os.path.join(self.spdxSearchDir.path, SPDX_NO_NAME) self.assertTrue(os.path.isfile(filePath)) filePath = os.path.join(self.spdxSearchDir.path, SPDX_NO_DATE) self.assertTrue(os.path.isfile(filePath))
def test_can_move_a_category_from_lower_to_higher(self): # Edith decides that she wants the project licenses category to show up # just before the attribution category. She edits the categories to # reorder them result = runcmd(self, slm.cli, "frotz", "edit-category", "Project Licenses", "--sort-before", "Attribution") self.assertEqual(0, result.exit_code) # Category listing should be updated correctly now result = runcmd(self, slm.cli, "frotz", "list-categories") self.assertEqual(0, result.exit_code) self.assertEqual( "Copyleft\nProject Licenses\nAttribution\nOther\nNo license found\n", result.output)
def test_can_create_new_project_and_subproject(self): # Edith is starting to manage licenses for a new project called yozozzo. # She asks SLM to create a new project result = runcmd(self, slm.cli, None, "create-project", "yozozzo", '--desc="The YOZOZZO Project"') self.assertEqual(0, result.exit_code) # She confirms that the SLM top-level configuration file has been updated # and now refers to yozozzo checkForTextInFile(self, self.slmhome, "slmconfig.json", "yozozzo") # She also confirms that the appropriate subdirectory and database have # been created checkForDirectoryExists(self, self.slmhome, "projects/yozozzo") checkForFileExists(self, self.slmhome, "projects/yozozzo/yozozzo.db") # And she confirms that a "reports/" subdirectory has been created for this # project checkForDirectoryExists(self, self.slmhome, "projects/yozozzo/reports") # And she confirms that a "subprojects/" subdirectory has been created for this # project checkForDirectoryExists(self, self.slmhome, "projects/yozozzo/subprojects") # And she confirms that a "list" command now includes yozozzo in the list result = runcmd(self, slm.cli, None, "list") self.assertEqual(0, result.exit_code) self.assertEqual("frotz\ngnusto\nrezrov\nyozozzo\n", result.output) # Now, she wants to create its first subproject, yozozzo-duck result = runcmd(self, slm.cli, "yozozzo", "create-subproject", "yozozzo-duck", '--desc="Duck transformation spell"') self.assertEqual(0, result.exit_code) # She confirms that the appropriate subproject subdirectories have # been created checkForDirectoryExists(self, self.slmhome, "projects/yozozzo/subprojects/yozozzo-duck") # And she confirms that the appropriate subdirectories have been created # for this subproject checkForDirectoryExists(self, self.slmhome, "projects/yozozzo/subprojects/yozozzo-duck/spdx") checkForDirectoryExists(self, self.slmhome, "projects/yozozzo/subprojects/yozozzo-duck/reports") # And she confirms that a "list" command now includes yozozzo-duck result = runcmd(self, slm.cli, "yozozzo", "list") self.assertEqual(0, result.exit_code) self.assertEqual("yozozzo/yozozzo-duck\n", result.output)
def test_can_list_categories(self): # Edith asks for a list of all current categories result = runcmd(self, slm.cli, "frotz", "list-categories") self.assertEqual(0, result.exit_code) self.assertEqual( "Project Licenses\nCopyleft\nAttribution\nOther\nNo license found\n", result.output)
def test_can_add_and_retrieve_a_conversion(self): # Edith is creating a new conversion result = runcmd(self, slm.cli, "frotz", "add-conversion", "BSD-Simplified", "BSD-2-Clause") # It works correctly and lets her know self.assertEqual(0, result.exit_code) self.assertEqual( "Created conversion: 'BSD-Simplified' => 'BSD-2-Clause'\n", result.output) # She retrieves the conversion to make sure, and there it is result = runcmd(self, slm.cli, "frotz", "get-conversion", 'BSD-Simplified') self.assertEqual(0, result.exit_code) self.assertIn("BSD-2-Clause", result.output)
def test_can_get_status_from_baseline(self): # Edith wants to know the current status of scanning for Feb. 2018, # as a tabulated report result = runcmd(self, slm.cli, None, "status", "2018-02") # It works and creates a status report self.assertEqual(0, result.exit_code) lines = result.output.splitlines() # There should be seven lines total: two for month header and blank line, # two for headers and header line, and one for each of three subprojects self.assertEqual(len(lines), 7) # The status report starts with the current month self.assertTrue(lines[0].startswith("Month: 2018-02")) # Project name should be repeated for each subproject. Subprojects should # be in alphabetical order sp_dim = lines[4].split() sp_nuclear = lines[5].split() sp_shiny = lines[6].split() self.assertEqual(sp_dim[0], "frotz") self.assertEqual(sp_dim[1], "frotz-dim") self.assertEqual(sp_nuclear[0], "frotz") self.assertEqual(sp_nuclear[1], "frotz-nuclear") self.assertEqual(sp_shiny[0], "frotz") self.assertEqual(sp_shiny[1], "frotz-shiny") # An asterisk is used to mark entries. There should be an imported scan # for frotz-dim, but nothing else for any subproject self.assertEqual(lines[4].count("*"), 1) self.assertEqual(lines[5].count("*"), 0) self.assertEqual(lines[6].count("*"), 0)
def test_cannot_list_results_without_scan_id(self): # Edith accidentally tries to list files and licenses for a scan but # forgets to provide a scan ID result = runcmd(self, slm.cli, "frotz", "list-scan-results") # It fails and explains why self.assertEqual(1, result.exit_code) self.assertEqual(f'Usage: slm list-scan-results --scan_id SCAN_ID\n\nError: "scan_id" not provided.\n', result.output)
def test_cannot_change_a_license_name_to_itself(self): # Edith accidentally tries to rename the MIT license to MIT result = runcmd(self, slm.cli, "frotz", "edit-license", "MIT", "--new-name", "MIT") # It fails and explains why self.assertEqual(1, result.exit_code) self.assertEqual("Cannot rename 'MIT' to itself.\n", result.output)
def test_can_list_licenses_within_one_category(self): # Edith wants to list just the licenses in the Copyleft category result = runcmd(self, slm.cli, "frotz", "list-licenses", "--in-category", "Copyleft") # they are sorted alphabetically self.assertEqual(0, result.exit_code) self.assertEqual("GPL-2.0-only\nGPL-2.0-or-later\n", result.output)
def test_cannot_create_new_project_with_duplicate_name(self): # Edith accidentally asks SLM to create a new project with an existing name result = runcmd(self, slm.cli, None, "create-project", "frotz", '--desc="oops"') # It doesn't work and tells her why self.assertEqual(1, result.exit_code) self.assertEqual(result.output, "Error: project frotz already exists\n")
def test_cannot_add_a_license_without_an_existing_category(self): # Edith accidentally tries to create a license with a non-existent category result = runcmd(self, slm.cli, 'frotz', 'add-license', 'CC0', 'Public Domain') # It fails and explains why self.assertEqual(1, result.exit_code) self.assertEqual(f"Category 'Public Domain' does not exist.\n", result.output)