diff --git a/internal/rule/rulefunction/library_test.go b/internal/rule/rulefunction/library_test.go index 91a670b57..e36a0300a 100644 --- a/internal/rule/rulefunction/library_test.go +++ b/internal/rule/rulefunction/library_test.go @@ -18,8 +18,10 @@ package rulefunction import ( "fmt" + "net/http" "os" "regexp" + "strings" "testing" "time" @@ -27,7 +29,9 @@ import ( "github.com/arduino/arduino-lint/internal/project/projectdata" "github.com/arduino/arduino-lint/internal/project/projecttype" "github.com/arduino/arduino-lint/internal/rule/ruleresult" + "github.com/arduino/arduino-lint/internal/util/test" "github.com/arduino/go-paths-helper" + "github.com/arduino/go-properties-orderedmap" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing/object" "github.com/stretchr/testify/assert" @@ -780,11 +784,75 @@ func TestLibraryPropertiesUrlFieldDeadLink(t *testing.T) { {"Unable to load", "InvalidLibraryProperties", ruleresult.NotRun, ""}, {"Not defined", "MissingFields", ruleresult.NotRun, ""}, {"Bad URL", "BadURL", ruleresult.Fail, "^Head \"http://invalid/\": dial tcp: lookup invalid"}, - {"HTTP error 404", "URL404", ruleresult.Fail, "^404 Not Found$"}, - {"Good URL", "Recursive", ruleresult.Pass, ""}, } checkLibraryRuleFunction(LibraryPropertiesURLFieldDeadLink, testTables, t) + + /* + In order to avoid a dependency on an external site, a test HTTP server is used for the tests covering handling of + various HTTP response status codes. For this reason, the following tests can't be performed via the + checkLibraryRuleFunction function. + */ + statusTestTables := []struct { + testName string + serverStatus int + expectedRuleResult ruleresult.Type + expectedOutputQuery string + }{ + {"HTTP error 404", http.StatusNotFound, ruleresult.Fail, "^404 Not Found$"}, + {"Good URL", http.StatusOK, ruleresult.Pass, ""}, + } + + var propertiesMap = map[string]string{ + "name": "WebServer", + "version": "1.0.0", + "author": "Cristian Maglie , Pippo Pluto ", + "maintainer": "Cristian Maglie ", + "sentence": "A library that makes coding a Webserver a breeze.", + "paragraph": "Supports HTTP1.1 and you can do GET and POST.", + "category": "Communication", + "architectures": "avr", + } + + libraryProperties := properties.NewFromHashmap(propertiesMap) + + for _, testTable := range statusTestTables { + // Create an HTTP server that will return the desired status. + server := test.StatusServer(testTable.serverStatus) + defer server.Close() + + libraryProperties.Set("url", server.URL) + // AsSlice is the closest thing to a []byte output function provided by + // `github.com/arduino/go-properties-orderedmap`. + propertiesBytes := []byte(strings.Join(libraryProperties.AsSlice(), "\n")) + + // Generate the test data library. + sourcePath := librariesTestDataPath.Join("TestLibraryPropertiesUrlFieldDeadLink") + tempPath, err := paths.MkTempDir("", "TestLibraryPropertiesUrlFieldDeadLink") + defer tempPath.RemoveAll() // Clean up after the test. + require.NoError(t, err) + libraryPath := tempPath.Join("TestLibraryPropertiesUrlFieldDeadLink") + err = sourcePath.CopyDirTo(libraryPath) + require.NoError(t, err) + err = libraryPath.Join("library.properties").WriteFile(propertiesBytes) + require.NoError(t, err) + + testProject := project.Type{ + Path: libraryPath, + ProjectType: projecttype.Library, + SuperprojectType: projecttype.Library, + } + projectdata.Initialize(testProject) + + result, output := LibraryPropertiesURLFieldDeadLink() + assert.Equal(t, testTable.expectedRuleResult, result, testTable.testName) + expectedOutputRegexp := regexp.MustCompile(testTable.expectedOutputQuery) + assert.True( + t, + expectedOutputRegexp.MatchString(output), + fmt.Sprintf("%s (output: %s, assertion regex: %s)", testTable.testName, output, testTable.expectedOutputQuery), + ) + } } func TestLibraryPropertiesArchitecturesFieldMissing(t *testing.T) { diff --git a/internal/rule/rulefunction/packageindex_test.go b/internal/rule/rulefunction/packageindex_test.go index 4cd1c7ea5..a955872fb 100644 --- a/internal/rule/rulefunction/packageindex_test.go +++ b/internal/rule/rulefunction/packageindex_test.go @@ -17,7 +17,9 @@ package rulefunction import ( + "encoding/json" "fmt" + "net/http" "regexp" "testing" @@ -25,12 +27,69 @@ import ( "github.com/arduino/arduino-lint/internal/project/projectdata" "github.com/arduino/arduino-lint/internal/project/projecttype" "github.com/arduino/arduino-lint/internal/rule/ruleresult" + "github.com/arduino/arduino-lint/internal/util/test" "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var packageIndexesTestDataPath *paths.Path +// Help is the type of the `packages[*].help` and `packages[*].platforms[*].help` package index keys. +type Help struct { + Online string `json:"online"` +} + +// Help is the type of the elements of the `packages[*].platforms[*].toolsDependencies` package index key. +type ToolDependency struct{} + +// Platform is the type of the elements of the `packages[*].platforms` package index key. +type Platform struct { + Architecture string `json:"architecture"` + ArchiveFileName string `json:"archiveFileName"` + Boards []string `json:"boards"` + Category string `json:"category"` + Checksum string `json:"checksum"` + Help Help `json:"help"` + Name string `json:"name"` + Size string `json:"size"` + ToolsDependencies []ToolDependency `json:"toolsDependencies"` + URL string `json:"url"` + Version string `json:"version"` +} + +// System is the type of the elements of the `packages[*].tools[*].systems` package index key. +type System struct { + ArchiveFileName string `json:"archiveFileName"` + Checksum string `json:"checksum"` + Host string `json:"host"` + Size string `json:"size"` + URL string `json:"url"` +} + +// Tool is the type of the elements of the `packages[*].tools` package index key. +type Tool struct { + Name string `json:"name"` + Systems []System `json:"systems"` + Version string `json:"version"` +} + +// Package is the type of the elements of the `packages` package index key. +type Package struct { + Email string `json:"email"` + Help Help `json:"help"` + Maintainer string `json:"maintainer"` + Name string `json:"name"` + Platforms []Platform `json:"platforms"` + Tools []Tool `json:"tools"` + WebsiteURL string `json:"websiteURL"` +} + +// Package is the type of the package index data. +type Index struct { + Packages []Package `json:"packages"` +} + func init() { workingDirectory, _ := paths.Getwd() packageIndexesTestDataPath = workingDirectory.Join("testdata", "packageindexes") @@ -43,22 +102,54 @@ type packageIndexRuleFunctionTestTable struct { expectedOutputQuery string } +// checkPackageIndexRuleFunction tests the given rule function according to the given test tables. func checkPackageIndexRuleFunction(ruleFunction Type, testTables []packageIndexRuleFunctionTestTable, t *testing.T) { for _, testTable := range testTables { - expectedOutputRegexp := regexp.MustCompile(testTable.expectedOutputQuery) + indexFolder := packageIndexesTestDataPath.Join(testTable.packageIndexFolderName) + checkPackageIndexRuleFunctionForPath(indexFolder, ruleFunction, testTable, t) + } +} - testProject := project.Type{ - Path: packageIndexesTestDataPath.Join(testTable.packageIndexFolderName), - ProjectType: projecttype.PackageIndex, - SuperprojectType: projecttype.PackageIndex, - } +// checkPackageIndexRuleFunctionForPath tests the given rule function on the given path against the given assertions. +// This may be called directly from the test in cases where the test data is generated and thus not in the static test +// data folder. +func checkPackageIndexRuleFunctionForPath( + indexFolder *paths.Path, + ruleFunction Type, + testTable packageIndexRuleFunctionTestTable, + t *testing.T, +) { + expectedOutputRegexp := regexp.MustCompile(testTable.expectedOutputQuery) + + testProject := project.Type{ + Path: indexFolder, + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.PackageIndex, + } - projectdata.Initialize(testProject) + projectdata.Initialize(testProject) - result, output := ruleFunction() - assert.Equal(t, testTable.expectedRuleResult, result, testTable.testName) - assert.True(t, expectedOutputRegexp.MatchString(output), fmt.Sprintf("%s (output: %s, assertion regex: %s)", testTable.testName, output, testTable.expectedOutputQuery)) + result, output := ruleFunction() + assert.Equal(t, testTable.expectedRuleResult, result, testTable.testName) + assert.True( + t, + expectedOutputRegexp.MatchString(output), + fmt.Sprintf("%s (output: %s, assertion regex: %s)", testTable.testName, output, testTable.expectedOutputQuery), + ) +} + +// makeIndex generates a package index file from the given data. +func makeIndex(folder *paths.Path, data Index) error { + indexData, err := json.Marshal(data) + if err != nil { + return err + } + + if err := folder.Join("package_foo_index.json").WriteFile(indexData); err != nil { + return err } + + return nil } func TestPackageIndexMissing(t *testing.T) { @@ -265,12 +356,82 @@ func TestPackageIndexPackagesWebsiteURLInvalidFormat(t *testing.T) { func TestPackageIndexPackagesWebsiteURLDeadLink(t *testing.T) { testTables := []packageIndexRuleFunctionTestTable{ {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, - {"Dead URLs", "packages-websiteurl-dead", ruleresult.Fail, "^foopackager1, foopackager2$"}, {"Invalid URL", "packages-websiteurl-invalid", ruleresult.Fail, "^foopackager$"}, - {"Valid URL", "valid-package-index", ruleresult.Pass, ""}, } checkPackageIndexRuleFunction(PackageIndexPackagesWebsiteURLDeadLink, testTables, t) + + /* + In order to avoid a dependency on an external site, a test HTTP server is used for the tests covering handling of + various HTTP response status codes. For this reason, the following tests can't be performed via the + checkPackageIndexRuleFunction function. + */ + statusTestTables := []struct { + serverStatuses []int + testTable packageIndexRuleFunctionTestTable + }{ + { + []int{http.StatusNotFound, http.StatusForbidden}, + packageIndexRuleFunctionTestTable{ + "Dead URLs", + "", + ruleresult.Fail, + "^foopackager1, foopackager2$", + }, + }, + { + []int{http.StatusOK, http.StatusOK}, + packageIndexRuleFunctionTestTable{ + "Valid URL", + "", + ruleresult.Pass, + "", + }, + }, + } + + index := Index{ + Packages: []Package{ + { + Email: "jane@example.com", + Help: Help{ + Online: "http://example.com", + }, + Maintainer: "Jane Developer", + Name: "foopackager1", + }, + { + Email: "jane@example.com", + Help: Help{ + Online: "http://example.com", + }, + Maintainer: "Jane Developer", + Name: "foopackager2", + }, + }, + } + + for _, statusTestTable := range statusTestTables { + // Create HTTP servers that will return the desired statuses. + for packageIndex, status := range statusTestTable.serverStatuses { + server := test.StatusServer(status) + defer server.Close() + index.Packages[packageIndex].WebsiteURL = server.URL + } + + // Generate the test package index file. + indexFolder, err := paths.MkTempDir("", "TestPackageIndexPackagesWebsiteURLDeadLink") + defer indexFolder.RemoveAll() // Clean up after the test. + err = makeIndex(indexFolder, index) + require.NoError(t, err) + + checkPackageIndexRuleFunctionForPath( + indexFolder, + PackageIndexPackagesWebsiteURLDeadLink, + statusTestTable.testTable, + t, + ) + } } func TestPackageIndexPackagesEmailMissing(t *testing.T) { @@ -346,11 +507,77 @@ func TestPackageIndexPackagesHelpOnlineInvalidFormat(t *testing.T) { func TestPackageIndexPackagesHelpOnlineDeadLink(t *testing.T) { testTables := []packageIndexRuleFunctionTestTable{ {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, - {"Dead URLs", "packages-help-online-dead", ruleresult.Fail, "^foopackager1, foopackager2$"}, - {"Valid URL", "valid-package-index", ruleresult.Pass, ""}, } checkPackageIndexRuleFunction(PackageIndexPackagesHelpOnlineDeadLink, testTables, t) + + /* + In order to avoid a dependency on an external site, a test HTTP server is used for the tests covering handling of + various HTTP response status codes. For this reason, the following tests can't be performed via the + checkPackageIndexRuleFunction function. + */ + statusTestTables := []struct { + serverStatuses []int + testTable packageIndexRuleFunctionTestTable + }{ + { + []int{http.StatusNotFound, http.StatusForbidden}, + packageIndexRuleFunctionTestTable{ + "Dead URLs", + "", + ruleresult.Fail, + "^foopackager1, foopackager2$", + }, + }, + { + []int{http.StatusOK, http.StatusOK}, + packageIndexRuleFunctionTestTable{ + "Valid URL", + "", + ruleresult.Pass, + "", + }, + }, + } + + index := Index{ + Packages: []Package{ + { + Email: "jane@example.com", + Maintainer: "Jane Developer", + Name: "foopackager1", + WebsiteURL: "http://example.com", + }, + { + Email: "jane@example.com", + Maintainer: "Jane Developer", + Name: "foopackager2", + WebsiteURL: "http://example.com", + }, + }, + } + + for _, statusTestTable := range statusTestTables { + // Create HTTP servers that will return the desired statuses. + for packageIndex, status := range statusTestTable.serverStatuses { + server := test.StatusServer(status) + defer server.Close() + index.Packages[packageIndex].Help.Online = server.URL + } + + // Generate the test package index file. + indexFolder, err := paths.MkTempDir("", "TestPackageIndexPackagesHelpOnlineDeadLink") + defer indexFolder.RemoveAll() // Clean up after the test. + err = makeIndex(indexFolder, index) + require.NoError(t, err) + + checkPackageIndexRuleFunctionForPath( + indexFolder, + PackageIndexPackagesHelpOnlineDeadLink, + statusTestTable.testTable, + t, + ) + } } func TestPackageIndexPackagesPlatformsMissing(t *testing.T) { @@ -586,11 +813,96 @@ func TestPackageIndexPackagesPlatformsHelpOnlineInvalidFormat(t *testing.T) { func TestPackageIndexPackagesPlatformsHelpOnlineDeadLink(t *testing.T) { testTables := []packageIndexRuleFunctionTestTable{ {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, - {"Dead URLs", "packages-platforms-help-online-dead", ruleresult.Fail, "^" + brokenOutputListIndent + "foopackager:avr@1\\.0\\.0\n" + brokenOutputListIndent + "foopackager:samd@1\\.0\\.0$"}, - {"Valid URL", "valid-package-index", ruleresult.Pass, ""}, } checkPackageIndexRuleFunction(PackageIndexPackagesPlatformsHelpOnlineDeadLink, testTables, t) + + /* + In order to avoid a dependency on an external site, a test HTTP server is used for the tests covering handling of + various HTTP response status codes. For this reason, the following tests can't be performed via the + checkPackageIndexRuleFunction function. + */ + statusTestTables := []struct { + serverStatuses []int + testTable packageIndexRuleFunctionTestTable + }{ + { + []int{http.StatusNotFound, http.StatusForbidden}, + packageIndexRuleFunctionTestTable{ + "Dead URLs", + "", + ruleresult.Fail, + "^" + brokenOutputListIndent + "foopackager:avr@1\\.0\\.0\n" + brokenOutputListIndent + "foopackager:samd@1\\.0\\.0$", + }, + }, + { + []int{http.StatusOK, http.StatusOK}, + packageIndexRuleFunctionTestTable{ + "Valid URL", + "", + ruleresult.Pass, + "", + }, + }, + } + + index := Index{ + Packages: []Package{ + { + Email: "jane@example.com", + Help: Help{ + Online: "http://example.com", + }, + Maintainer: "Jane Developer", + Name: "foopackager", + Platforms: []Platform{ + { + Architecture: "avr", + ArchiveFileName: "myboard-1.0.0.zip", + Category: "Contributed", + Checksum: "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", + Name: "My AVR Board", + Size: "15005", + URL: "https://janedeveloper.github.io/myboard/myboard-1.0.0.zip", + Version: "1.0.0", + }, + { + Architecture: "samd", + ArchiveFileName: "myboard-1.0.0.zip", + Category: "Contributed", + Checksum: "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", + Name: "My AVR Board", + Size: "15005", + URL: "https://janedeveloper.github.io/myboard/myboard-1.0.0.zip", + Version: "1.0.0", + }, + }, + WebsiteURL: "http://example.com", + }, + }, + } + + for _, statusTestTable := range statusTestTables { + // Create HTTP servers that will return the desired statuses. + for platformIndex, status := range statusTestTable.serverStatuses { + server := test.StatusServer(status) + defer server.Close() + index.Packages[0].Platforms[platformIndex].Help.Online = server.URL + } + + // Generate the test package index file. + indexFolder, err := paths.MkTempDir("", "TestPackageIndexPackagesPlatformsHelpOnlineDeadLink") + defer indexFolder.RemoveAll() // Clean up after the test. + err = makeIndex(indexFolder, index) + require.NoError(t, err) + + checkPackageIndexRuleFunctionForPath( + indexFolder, + PackageIndexPackagesPlatformsHelpOnlineDeadLink, + statusTestTable.testTable, + t, + ) + } } func TestPackageIndexPackagesPlatformsUrlMissing(t *testing.T) { @@ -626,11 +938,100 @@ func TestPackageIndexPackagesPlatformsUrlInvalidFormat(t *testing.T) { func TestPackageIndexPackagesPlatformsURLDeadLink(t *testing.T) { testTables := []packageIndexRuleFunctionTestTable{ {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, - {"Dead URLs", "packages-platforms-url-dead", ruleresult.Fail, "^" + brokenOutputListIndent + "foopackager:avr@1\\.0\\.0\n" + brokenOutputListIndent + "foopackager:samd@1\\.0\\.0$"}, - {"Valid URL", "valid-package-index", ruleresult.Pass, ""}, } checkPackageIndexRuleFunction(PackageIndexPackagesPlatformsURLDeadLink, testTables, t) + + /* + In order to avoid a dependency on an external site, a test HTTP server is used for the tests covering handling of + various HTTP response status codes. For this reason, the following tests can't be performed via the + checkPackageIndexRuleFunction function. + */ + statusTestTables := []struct { + serverStatuses []int + testTable packageIndexRuleFunctionTestTable + }{ + { + []int{http.StatusNotFound, http.StatusForbidden}, + packageIndexRuleFunctionTestTable{ + "Dead URLs", + "", + ruleresult.Fail, + "^" + brokenOutputListIndent + "foopackager:avr@1\\.0\\.0\n" + brokenOutputListIndent + "foopackager:samd@1\\.0\\.0$", + }, + }, + { + []int{http.StatusOK, http.StatusOK}, + packageIndexRuleFunctionTestTable{ + "Valid URL", + "", + ruleresult.Pass, + "", + }, + }, + } + + index := Index{ + Packages: []Package{ + { + Email: "jane@example.com", + Help: Help{ + Online: "http://example.com", + }, + Maintainer: "Jane Developer", + Name: "foopackager", + Platforms: []Platform{ + { + Architecture: "avr", + ArchiveFileName: "myboard-1.0.0.zip", + Category: "Contributed", + Checksum: "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", + Help: Help{ + Online: "http://example.com", + }, + Name: "My AVR Board", + Size: "15005", + Version: "1.0.0", + }, + { + Architecture: "samd", + ArchiveFileName: "myboard-1.0.0.zip", + Category: "Contributed", + Checksum: "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", + Help: Help{ + Online: "http://example.com", + }, + Name: "My AVR Board", + Size: "15005", + Version: "1.0.0", + }, + }, + WebsiteURL: "http://example.com", + }, + }, + } + + for _, statusTestTable := range statusTestTables { + // Create HTTP servers that will return the desired statuses. + for platformIndex, status := range statusTestTable.serverStatuses { + server := test.StatusServer(status) + defer server.Close() + index.Packages[0].Platforms[platformIndex].URL = server.URL + } + + // Generate the test package index file. + indexFolder, err := paths.MkTempDir("", "TestPackageIndexPackagesPlatformsURLDeadLink") + defer indexFolder.RemoveAll() // Clean up after the test. + err = makeIndex(indexFolder, index) + require.NoError(t, err) + + checkPackageIndexRuleFunctionForPath( + indexFolder, + PackageIndexPackagesPlatformsURLDeadLink, + statusTestTable.testTable, + t, + ) + } } func TestPackageIndexPackagesPlatformsArchiveFileNameMissing(t *testing.T) { @@ -1286,11 +1687,94 @@ func TestPackageIndexPackagesToolsSystemsUrlInvalidFormat(t *testing.T) { func TestPackageIndexPackagesToolsSystemsURLDeadLink(t *testing.T) { testTables := []packageIndexRuleFunctionTestTable{ {"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""}, - {"Dead URLs", "packages-tools-systems-url-dead", ruleresult.Fail, "^" + brokenOutputListIndent + "foopackager:CMSIS@4\\.0\\.0-atmel >> arm-linux-gnueabihf\n" + brokenOutputListIndent + "foopackager:CMSIS@4\\.0\\.0-atmel >> i686-mingw32$"}, - {"Valid URL", "valid-package-index", ruleresult.Pass, ""}, } checkPackageIndexRuleFunction(PackageIndexPackagesToolsSystemsURLDeadLink, testTables, t) + + /* + In order to avoid a dependency on an external site, a test HTTP server is used for the tests covering handling of + various HTTP response status codes. For this reason, the following tests can't be performed via the + checkPackageIndexRuleFunction function. + */ + statusTestTables := []struct { + serverStatuses []int + testTable packageIndexRuleFunctionTestTable + }{ + { + []int{http.StatusNotFound, http.StatusForbidden}, + packageIndexRuleFunctionTestTable{ + "Dead URLs", + "", + ruleresult.Fail, + "^" + brokenOutputListIndent + "foopackager:CMSIS@4\\.0\\.0-atmel >> arm-linux-gnueabihf\n" + brokenOutputListIndent + "foopackager:CMSIS@4\\.0\\.0-atmel >> i686-mingw32$", + }, + }, + { + []int{http.StatusOK, http.StatusOK}, + packageIndexRuleFunctionTestTable{ + "Valid URL", + "", + ruleresult.Pass, + "", + }, + }, + } + + index := Index{ + Packages: []Package{ + { + Email: "jane@example.com", + Help: Help{ + Online: "http://example.com", + }, + Maintainer: "Jane Developer", + Name: "foopackager", + WebsiteURL: "http://example.com", + Tools: []Tool{ + { + Name: "CMSIS", + Systems: []System{ + { + ArchiveFileName: "CMSIS-4.0.0.tar.bz2", + Checksum: "SHA-256:7d637d2d7a0c6bacc22065848a201db2fff124268e4a56868260d0f472b4bbb7", + Host: "arm-linux-gnueabihf", + Size: "17642623", + }, + { + ArchiveFileName: "CMSIS-4.0.0.tar.bz2", + Checksum: "SHA-256:7d637d2d7a0c6bacc22065848a201db2fff124268e4a56868260d0f472b4bbb7", + Host: "i686-mingw32", + Size: "17642623", + }, + }, + Version: "4.0.0-atmel", + }, + }, + }, + }, + } + + for _, statusTestTable := range statusTestTables { + // Create HTTP servers that will return the desired statuses. + for systemIndex, status := range statusTestTable.serverStatuses { + server := test.StatusServer(status) + defer server.Close() + index.Packages[0].Tools[0].Systems[systemIndex].URL = server.URL + } + + // Generate the test package index file. + indexFolder, err := paths.MkTempDir("", "TestPackageIndexPackagesToolsSystemsURLDeadLink") + defer indexFolder.RemoveAll() // Clean up after the test. + err = makeIndex(indexFolder, index) + require.NoError(t, err) + + checkPackageIndexRuleFunctionForPath( + indexFolder, + PackageIndexPackagesToolsSystemsURLDeadLink, + statusTestTable.testTable, + t, + ) + } } func TestPackageIndexPackagesToolsSystemsArchiveFileNameMissing(t *testing.T) { diff --git a/internal/rule/rulefunction/testdata/libraries/URL404/src/URL404.h b/internal/rule/rulefunction/testdata/libraries/TestLibraryPropertiesUrlFieldDeadLink/src/TestLibraryPropertiesUrlFieldDeadLink.h similarity index 100% rename from internal/rule/rulefunction/testdata/libraries/URL404/src/URL404.h rename to internal/rule/rulefunction/testdata/libraries/TestLibraryPropertiesUrlFieldDeadLink/src/TestLibraryPropertiesUrlFieldDeadLink.h diff --git a/internal/rule/rulefunction/testdata/libraries/URL404/library.properties b/internal/rule/rulefunction/testdata/libraries/URL404/library.properties deleted file mode 100644 index 2789ab18e..000000000 --- a/internal/rule/rulefunction/testdata/libraries/URL404/library.properties +++ /dev/null @@ -1,9 +0,0 @@ -name=URL404 -version=1.0.0 -author=Cristian Maglie , Pippo Pluto -maintainer=Cristian Maglie -sentence=A library that makes coding a web server a breeze. -paragraph=Supports HTTP1.1 and you can do GET and POST. -category=Communication -url=http://httpstat.us/404 -architectures=avr diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-help-online-dead/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-help-online-dead/package_foo_index.json deleted file mode 100644 index 9f282cda5..000000000 --- a/internal/rule/rulefunction/testdata/packageindexes/packages-help-online-dead/package_foo_index.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "packages": [ - { - "name": "foopackager1", - "maintainer": "Jane Developer", - "websiteURL": "http://example.com", - "email": "jane@example.com", - "help": { - "online": "http://httpstat.us/403" - }, - "platforms": [], - "tools": [] - }, - { - "name": "foopackager2", - "maintainer": "Jane Developer", - "websiteURL": "http://example.com", - "email": "jane@example.com", - "help": { - "online": "http://httpstat.us/404" - }, - "platforms": [], - "tools": [] - } - ] -} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-platforms-help-online-dead/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-platforms-help-online-dead/package_foo_index.json deleted file mode 100644 index 4755ba1e2..000000000 --- a/internal/rule/rulefunction/testdata/packageindexes/packages-platforms-help-online-dead/package_foo_index.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "packages": [ - { - "name": "foopackager", - "maintainer": "Jane Developer", - "websiteURL": "http://example.com", - "email": "jane@example.com", - "help": { - "online": "http://example.com" - }, - "platforms": [ - { - "name": "My AVR Board", - "architecture": "avr", - "version": "1.0.0", - "category": "Contributed", - "help": { - "online": "http://httpstat.us/403" - }, - "url": "https://janedeveloper.github.io/myboard/myboard-1.0.0.zip", - "archiveFileName": "myboard-1.0.0.zip", - "checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", - "size": "15005", - "boards": [], - "toolsDependencies": [] - }, - { - "name": "My SAMD Board", - "architecture": "samd", - "version": "1.0.0", - "category": "Contributed", - "help": { - "online": "http://httpstat.us/404" - }, - "url": "https://janedeveloper.github.io/myboard/myboard-1.0.0.zip", - "archiveFileName": "myboard-1.0.0.zip", - "checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", - "size": "15005", - "boards": [], - "toolsDependencies": [] - } - ], - "tools": [] - } - ] -} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-platforms-url-dead/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-platforms-url-dead/package_foo_index.json deleted file mode 100644 index 7e881273b..000000000 --- a/internal/rule/rulefunction/testdata/packageindexes/packages-platforms-url-dead/package_foo_index.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "packages": [ - { - "name": "foopackager", - "maintainer": "Jane Developer", - "websiteURL": "http://example.com", - "email": "jane@example.com", - "help": { - "online": "http://example.com" - }, - "platforms": [ - { - "name": "My AVR Board", - "architecture": "avr", - "version": "1.0.0", - "category": "Contributed", - "help": { - "online": "http://example.com" - }, - "url": "http://httpstat.us/403", - "archiveFileName": "myboard-1.0.0.zip", - "checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", - "size": "15005", - "boards": [], - "toolsDependencies": [] - }, - { - "name": "My SAMD Board", - "architecture": "samd", - "version": "1.0.0", - "category": "Contributed", - "help": { - "online": "http://example.com" - }, - "url": "http://httpstat.us/404", - "archiveFileName": "myboard-1.0.0.zip", - "checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", - "size": "15005", - "boards": [], - "toolsDependencies": [] - } - ], - "tools": [] - } - ] -} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-tools-systems-url-dead/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-tools-systems-url-dead/package_foo_index.json deleted file mode 100644 index f44e64e31..000000000 --- a/internal/rule/rulefunction/testdata/packageindexes/packages-tools-systems-url-dead/package_foo_index.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "packages": [ - { - "name": "foopackager", - "maintainer": "Jane Developer", - "websiteURL": "http://httpstat.us/404", - "email": "jane@example.com", - "help": { - "online": "http://example.com" - }, - "platforms": [], - "tools": [ - { - "name": "CMSIS", - "version": "4.0.0-atmel", - "systems": [ - { - "host": "arm-linux-gnueabihf", - "url": "http://httpstat.us/403", - "archiveFileName": "CMSIS-4.0.0.tar.bz2", - "checksum": "SHA-256:7d637d2d7a0c6bacc22065848a201db2fff124268e4a56868260d0f472b4bbb7", - "size": "17642623" - }, - { - "host": "i686-mingw32", - "url": "http://httpstat.us/404", - "archiveFileName": "CMSIS-4.0.0.tar.bz2", - "checksum": "SHA-256:7d637d2d7a0c6bacc22065848a201db2fff124268e4a56868260d0f472b4bbb7", - "size": "17642623" - } - ] - } - ] - } - ] -} diff --git a/internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-dead/package_foo_index.json b/internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-dead/package_foo_index.json deleted file mode 100644 index f731b359f..000000000 --- a/internal/rule/rulefunction/testdata/packageindexes/packages-websiteurl-dead/package_foo_index.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "packages": [ - { - "name": "foopackager1", - "maintainer": "Jane Developer", - "websiteURL": "http://httpstat.us/403", - "email": "jane@example.com", - "help": { - "online": "http://example.com/forum/myboard" - }, - "platforms": [], - "tools": [] - }, - { - "name": "foopackager2", - "maintainer": "Jane Developer", - "websiteURL": "http://httpstat.us/404", - "email": "jane@example.com", - "help": { - "online": "http://example.com/forum/myboard" - }, - "platforms": [], - "tools": [] - } - ] -} diff --git a/internal/util/test/test.go b/internal/util/test/test.go index 1beeb72bd..71d16f560 100644 --- a/internal/util/test/test.go +++ b/internal/util/test/test.go @@ -17,7 +17,12 @@ // Package test provides resources for testing arduino-lint. package test -import "github.com/spf13/pflag" +import ( + "net/http" + "net/http/httptest" + + "github.com/spf13/pflag" +) // ConfigurationFlags returns a set of the flags used for command line configuration of arduino-lint. func ConfigurationFlags() *pflag.FlagSet { @@ -35,3 +40,13 @@ func ConfigurationFlags() *pflag.FlagSet { return flags } + +// StatusServer returns an HTTP test server that will respond with the given status code. +func StatusServer(status int) *httptest.Server { + handler := func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(status) + } + server := httptest.NewServer(http.HandlerFunc(handler)) + + return server +}