forked from litmuschaos/litmus
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add fuzz test in chaoshub/handler (litmuschaos#4857)
* test: add fuzz test to GetChartsPath function in handler Signed-off-by: Soyeon Park <sypark9646@gmail.com> * test: add fuzz test to FuzzReadExperimentFile function in handler * Removed the ./types.go example in unit test handler_test.go/TestReadExperimentFile because it returns a file does not exist error, not the file is not a yaml error that the test is intended to return. Signed-off-by: Soyeon Park <sypark9646@gmail.com> * * test: Add the FuzzReadExperimentYAMLFile test in the handler_fuzz_test.go file Signed-off-by: Soyeon Park <sypark9646@gmail.com> * test: add fuzz test to FuzzIsFileExisting function in handler Signed-off-by: Soyeon Park <sypark9646@gmail.com> * test: add fuzz test to FuzzGetExperimentData, FuzzUnzipRemoteHub function in handler Signed-off-by: Soyeon Park <sypark9646@gmail.com> * refactor: remove unused imported library Signed-off-by: Soyeon Park <sypark9646@gmail.com> * fix: check yaml: control characters are not allowed Signed-off-by: Soyeon Park <sypark9646@gmail.com> * refactor: save goimport order Signed-off-by: Soyeon Park <sypark9646@gmail.com> --------- Signed-off-by: Soyeon Park <sypark9646@gmail.com> Signed-off-by: andoriyaprashant <prashantandoriya@gmail.com>
- Loading branch information
1 parent
af2c7e5
commit c98cfc0
Showing
2 changed files
with
291 additions
and
5 deletions.
There are no files selected for viewing
291 changes: 291 additions & 0 deletions
291
chaoscenter/graphql/server/pkg/chaoshub/handler/handler_fuzz_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,291 @@ | ||
package handler | ||
|
||
import ( | ||
"archive/zip" | ||
"encoding/json" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
"testing" | ||
|
||
fuzz "github.com/AdaLogics/go-fuzz-headers" | ||
"github.com/google/uuid" | ||
"github.com/litmuschaos/litmus/chaoscenter/graphql/server/graph/model" | ||
) | ||
|
||
func FuzzGetChartsPath(f *testing.F) { | ||
f.Fuzz(func(t *testing.T, data []byte) { | ||
fuzzConsumer := fuzz.NewConsumer(data) | ||
|
||
chartsInput := model.CloningInput{} | ||
err := fuzzConsumer.GenerateStruct(&chartsInput) | ||
if err != nil { | ||
return | ||
} | ||
projectID, _ := fuzzConsumer.GetString() | ||
isDefault, _ := fuzzConsumer.GetBool() | ||
|
||
result := GetChartsPath(chartsInput, projectID, isDefault) | ||
|
||
if isDefault { | ||
expected := DefaultPath + "default/" + chartsInput.Name + "/faults/" | ||
if result != expected { | ||
t.Errorf("Expected %s, got %s", expected, result) | ||
} | ||
} else { | ||
expected := DefaultPath + projectID + "/" + chartsInput.Name + "/faults/" | ||
if result != expected { | ||
t.Errorf("Expected %s, got %s", expected, result) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
func FuzzReadExperimentFile(f *testing.F) { | ||
f.Fuzz(func(t *testing.T, data []byte, filename string) { | ||
fuzzConsumer := fuzz.NewConsumer(data) | ||
|
||
// Create a temporary directory | ||
tmpDir, err := os.MkdirTemp("", "*-fuzztest") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.RemoveAll(tmpDir) // clean up | ||
|
||
// Ensure the filename is valid and unique | ||
safeFilename := filepath.Clean(filepath.Base(filename)) | ||
if isInvalidFilename(safeFilename) { | ||
safeFilename = "test.yaml" | ||
} | ||
filePath := filepath.Join(tmpDir, safeFilename) | ||
content := ChaosChart{} | ||
err = fuzzConsumer.GenerateStruct(&content) | ||
if err != nil { | ||
return | ||
} | ||
|
||
jsonContent, _ := json.Marshal(content) | ||
err = os.WriteFile(filePath, jsonContent, 0644) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
_, err = ReadExperimentFile(filePath) | ||
|
||
if err != nil && !isInvalidYAML(jsonContent) { | ||
t.Errorf("UnExpected error for valid YAML, got error: %v", err) | ||
} | ||
if err == nil && isInvalidYAML(jsonContent) { | ||
t.Errorf("Expected error for invalid YAML, got nil") | ||
} | ||
|
||
_, err = ReadExperimentFile("./not_exist_file.yaml") | ||
if err == nil { | ||
t.Errorf("Expected error for file does not exist, got nil") | ||
} | ||
}) | ||
} | ||
|
||
func FuzzGetExperimentData(f *testing.F) { | ||
f.Fuzz(func(t *testing.T, data []byte, filename string) { | ||
fuzzConsumer := fuzz.NewConsumer(data) | ||
|
||
// Create a temporary directory | ||
tmpDir, err := os.MkdirTemp("", "*-fuzztest") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.RemoveAll(tmpDir) // clean up | ||
|
||
// Ensure the filename is valid and unique | ||
safeFilename := filepath.Clean(filepath.Base(filename)) | ||
if isInvalidFilename(safeFilename) { | ||
safeFilename = "test.yaml" | ||
} | ||
filePath := filepath.Join(tmpDir, safeFilename) | ||
content := ChaosChart{} | ||
err = fuzzConsumer.GenerateStruct(&content) | ||
if err != nil { | ||
return | ||
} | ||
|
||
jsonContent, _ := json.Marshal(content) | ||
err = os.WriteFile(filePath, jsonContent, 0644) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
_, err = GetExperimentData(filePath) | ||
|
||
if err != nil && !isInvalidYAML(jsonContent) && json.Valid(jsonContent) { | ||
t.Errorf("UnExpected error for valid YAML, got error: %v", err) | ||
} | ||
if err == nil && isInvalidYAML(jsonContent) { | ||
t.Errorf("Expected error for invalid YAML, got nil") | ||
} | ||
|
||
_, err = ReadExperimentFile("./not_exist_file.yaml") | ||
if err == nil { | ||
t.Errorf("Expected error for file does not exist, got nil") | ||
} | ||
}) | ||
} | ||
|
||
func FuzzReadExperimentYAMLFile(f *testing.F) { | ||
f.Fuzz(func(t *testing.T, data []byte, filename string) { | ||
fuzzConsumer := fuzz.NewConsumer(data) | ||
|
||
// Create a temporary directory | ||
tmpDir, err := os.MkdirTemp("", "*-fuzztest") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.RemoveAll(tmpDir) // clean up | ||
|
||
// Ensure the filename is valid and unique | ||
safeFilename := filepath.Clean(filepath.Base(filename)) | ||
if isInvalidFilename(safeFilename) { | ||
safeFilename = "test.yaml" | ||
} | ||
filePath := filepath.Join(tmpDir, safeFilename) | ||
content := ChaosChart{} | ||
err = fuzzConsumer.GenerateStruct(&content) | ||
if err != nil { | ||
return | ||
} | ||
|
||
jsonContent, _ := json.Marshal(content) | ||
err = os.WriteFile(filePath, jsonContent, 0644) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
_, err = ReadExperimentYAMLFile(filePath) | ||
|
||
if err != nil { | ||
t.Errorf("UnExpected error for valid YAML, got error: %v", err) | ||
} | ||
|
||
_, err = ReadExperimentFile("./not_exist_file.yaml") | ||
if err == nil { | ||
t.Errorf("Expected error for file does not exist, got nil") | ||
} | ||
}) | ||
} | ||
|
||
func FuzzUnzipRemoteHub(f *testing.F) { | ||
f.Fuzz(func(t *testing.T, data []byte, filename string, projectID string) { | ||
// Create a temporary directory | ||
tmpDir, err := os.MkdirTemp("", "*-fuzztest") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.RemoveAll(tmpDir) // clean up | ||
|
||
// Ensure the filename is valid and unique | ||
safeFilename := filepath.Clean(filepath.Base(filename)) | ||
if isInvalidFilename(safeFilename) { | ||
safeFilename = "test.zip" | ||
} | ||
if !strings.HasSuffix(safeFilename, ".zip") { | ||
safeFilename += ".zip" | ||
} | ||
if isInvalidFilename(projectID) { | ||
projectID = uuid.New().String() | ||
} | ||
|
||
filePath := filepath.Join(tmpDir, safeFilename) | ||
// Create a valid zip file | ||
err = createValidZipFile(filePath, data) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
err = UnzipRemoteHub(filePath, projectID) | ||
|
||
if err != nil { | ||
t.Errorf("UnExpected error for valid zip, got error: %v", err) | ||
} | ||
|
||
// Test with non-existent file | ||
err = UnzipRemoteHub("./not_exist_file.zip", projectID) | ||
if err == nil { | ||
t.Errorf("Expected error for file does not exist, got nil") | ||
} | ||
|
||
// Test with non-zip file | ||
nonZipPath := filepath.Join(tmpDir, "no_zip") | ||
err = os.WriteFile(nonZipPath, []byte("not a zip file"), 0644) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
err = UnzipRemoteHub(nonZipPath, projectID) | ||
if err == nil { | ||
t.Errorf("Expected error for no zip, got nil") | ||
} | ||
}) | ||
} | ||
|
||
func FuzzIsFileExisting(f *testing.F) { | ||
f.Fuzz(func(t *testing.T, filename string) { | ||
// Create a temporary directory | ||
tmpDir, err := os.MkdirTemp("", "*-fuzztest") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.RemoveAll(tmpDir) // clean up | ||
|
||
// Ensure the filename is valid and unique | ||
safeFilename := filepath.Clean(filepath.Base(filename)) | ||
if isInvalidFilename(safeFilename) { | ||
safeFilename = "test.yaml" | ||
} | ||
filePath := filepath.Join(tmpDir, safeFilename) | ||
_, _ = os.Create(filePath) | ||
|
||
result, err := IsFileExisting(filePath) | ||
if !result { | ||
t.Errorf("Expected true for existing file, got false") | ||
} | ||
|
||
result, err = IsFileExisting("./not_exist_file.yaml") | ||
if result { | ||
t.Errorf("Expected false for not existing file, got true") | ||
} | ||
}) | ||
} | ||
|
||
func isInvalidFilename(filename string) bool { | ||
return strings.IndexByte(filename, 0) != -1 || filename == "" || filename == "." || filename == ".." || filename == "/" || len(filename) > 255 | ||
} | ||
|
||
func isInvalidYAML(data []byte) bool { | ||
for _, b := range data { | ||
if b < 32 || b == 127 { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
func createValidZipFile(filename string, data []byte) error { | ||
zipFile, err := os.Create(filename) | ||
if err != nil { | ||
return err | ||
} | ||
defer zipFile.Close() | ||
|
||
zipWriter := zip.NewWriter(zipFile) | ||
defer zipWriter.Close() | ||
|
||
f, err := zipWriter.Create("test.txt") | ||
if err != nil { | ||
return err | ||
} | ||
_, err = f.Write(data) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters