Skip to content

Commit 4873194

Browse files
authored
test: add fuzz test in chaoshub/handler (#4857)
* test: add fuzz test to GetChartsPath function in handler Signed-off-by: Soyeon Park <[email protected]> * 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 <[email protected]> * * test: Add the FuzzReadExperimentYAMLFile test in the handler_fuzz_test.go file Signed-off-by: Soyeon Park <[email protected]> * test: add fuzz test to FuzzIsFileExisting function in handler Signed-off-by: Soyeon Park <[email protected]> * test: add fuzz test to FuzzGetExperimentData, FuzzUnzipRemoteHub function in handler Signed-off-by: Soyeon Park <[email protected]> * refactor: remove unused imported library Signed-off-by: Soyeon Park <[email protected]> * fix: check yaml: control characters are not allowed Signed-off-by: Soyeon Park <[email protected]> * refactor: save goimport order Signed-off-by: Soyeon Park <[email protected]> --------- Signed-off-by: Soyeon Park <[email protected]>
1 parent f8cc0a9 commit 4873194

File tree

2 files changed

+291
-5
lines changed

2 files changed

+291
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
package handler
2+
3+
import (
4+
"archive/zip"
5+
"encoding/json"
6+
"os"
7+
"path/filepath"
8+
"strings"
9+
"testing"
10+
11+
fuzz "github.com/AdaLogics/go-fuzz-headers"
12+
"github.com/google/uuid"
13+
"github.com/litmuschaos/litmus/chaoscenter/graphql/server/graph/model"
14+
)
15+
16+
func FuzzGetChartsPath(f *testing.F) {
17+
f.Fuzz(func(t *testing.T, data []byte) {
18+
fuzzConsumer := fuzz.NewConsumer(data)
19+
20+
chartsInput := model.CloningInput{}
21+
err := fuzzConsumer.GenerateStruct(&chartsInput)
22+
if err != nil {
23+
return
24+
}
25+
projectID, _ := fuzzConsumer.GetString()
26+
isDefault, _ := fuzzConsumer.GetBool()
27+
28+
result := GetChartsPath(chartsInput, projectID, isDefault)
29+
30+
if isDefault {
31+
expected := DefaultPath + "default/" + chartsInput.Name + "/faults/"
32+
if result != expected {
33+
t.Errorf("Expected %s, got %s", expected, result)
34+
}
35+
} else {
36+
expected := DefaultPath + projectID + "/" + chartsInput.Name + "/faults/"
37+
if result != expected {
38+
t.Errorf("Expected %s, got %s", expected, result)
39+
}
40+
}
41+
})
42+
}
43+
44+
func FuzzReadExperimentFile(f *testing.F) {
45+
f.Fuzz(func(t *testing.T, data []byte, filename string) {
46+
fuzzConsumer := fuzz.NewConsumer(data)
47+
48+
// Create a temporary directory
49+
tmpDir, err := os.MkdirTemp("", "*-fuzztest")
50+
if err != nil {
51+
t.Fatal(err)
52+
}
53+
defer os.RemoveAll(tmpDir) // clean up
54+
55+
// Ensure the filename is valid and unique
56+
safeFilename := filepath.Clean(filepath.Base(filename))
57+
if isInvalidFilename(safeFilename) {
58+
safeFilename = "test.yaml"
59+
}
60+
filePath := filepath.Join(tmpDir, safeFilename)
61+
content := ChaosChart{}
62+
err = fuzzConsumer.GenerateStruct(&content)
63+
if err != nil {
64+
return
65+
}
66+
67+
jsonContent, _ := json.Marshal(content)
68+
err = os.WriteFile(filePath, jsonContent, 0644)
69+
if err != nil {
70+
t.Fatal(err)
71+
}
72+
73+
_, err = ReadExperimentFile(filePath)
74+
75+
if err != nil && !isInvalidYAML(jsonContent) {
76+
t.Errorf("UnExpected error for valid YAML, got error: %v", err)
77+
}
78+
if err == nil && isInvalidYAML(jsonContent) {
79+
t.Errorf("Expected error for invalid YAML, got nil")
80+
}
81+
82+
_, err = ReadExperimentFile("./not_exist_file.yaml")
83+
if err == nil {
84+
t.Errorf("Expected error for file does not exist, got nil")
85+
}
86+
})
87+
}
88+
89+
func FuzzGetExperimentData(f *testing.F) {
90+
f.Fuzz(func(t *testing.T, data []byte, filename string) {
91+
fuzzConsumer := fuzz.NewConsumer(data)
92+
93+
// Create a temporary directory
94+
tmpDir, err := os.MkdirTemp("", "*-fuzztest")
95+
if err != nil {
96+
t.Fatal(err)
97+
}
98+
defer os.RemoveAll(tmpDir) // clean up
99+
100+
// Ensure the filename is valid and unique
101+
safeFilename := filepath.Clean(filepath.Base(filename))
102+
if isInvalidFilename(safeFilename) {
103+
safeFilename = "test.yaml"
104+
}
105+
filePath := filepath.Join(tmpDir, safeFilename)
106+
content := ChaosChart{}
107+
err = fuzzConsumer.GenerateStruct(&content)
108+
if err != nil {
109+
return
110+
}
111+
112+
jsonContent, _ := json.Marshal(content)
113+
err = os.WriteFile(filePath, jsonContent, 0644)
114+
if err != nil {
115+
t.Fatal(err)
116+
}
117+
118+
_, err = GetExperimentData(filePath)
119+
120+
if err != nil && !isInvalidYAML(jsonContent) && json.Valid(jsonContent) {
121+
t.Errorf("UnExpected error for valid YAML, got error: %v", err)
122+
}
123+
if err == nil && isInvalidYAML(jsonContent) {
124+
t.Errorf("Expected error for invalid YAML, got nil")
125+
}
126+
127+
_, err = ReadExperimentFile("./not_exist_file.yaml")
128+
if err == nil {
129+
t.Errorf("Expected error for file does not exist, got nil")
130+
}
131+
})
132+
}
133+
134+
func FuzzReadExperimentYAMLFile(f *testing.F) {
135+
f.Fuzz(func(t *testing.T, data []byte, filename string) {
136+
fuzzConsumer := fuzz.NewConsumer(data)
137+
138+
// Create a temporary directory
139+
tmpDir, err := os.MkdirTemp("", "*-fuzztest")
140+
if err != nil {
141+
t.Fatal(err)
142+
}
143+
defer os.RemoveAll(tmpDir) // clean up
144+
145+
// Ensure the filename is valid and unique
146+
safeFilename := filepath.Clean(filepath.Base(filename))
147+
if isInvalidFilename(safeFilename) {
148+
safeFilename = "test.yaml"
149+
}
150+
filePath := filepath.Join(tmpDir, safeFilename)
151+
content := ChaosChart{}
152+
err = fuzzConsumer.GenerateStruct(&content)
153+
if err != nil {
154+
return
155+
}
156+
157+
jsonContent, _ := json.Marshal(content)
158+
err = os.WriteFile(filePath, jsonContent, 0644)
159+
if err != nil {
160+
t.Fatal(err)
161+
}
162+
163+
_, err = ReadExperimentYAMLFile(filePath)
164+
165+
if err != nil {
166+
t.Errorf("UnExpected error for valid YAML, got error: %v", err)
167+
}
168+
169+
_, err = ReadExperimentFile("./not_exist_file.yaml")
170+
if err == nil {
171+
t.Errorf("Expected error for file does not exist, got nil")
172+
}
173+
})
174+
}
175+
176+
func FuzzUnzipRemoteHub(f *testing.F) {
177+
f.Fuzz(func(t *testing.T, data []byte, filename string, projectID string) {
178+
// Create a temporary directory
179+
tmpDir, err := os.MkdirTemp("", "*-fuzztest")
180+
if err != nil {
181+
t.Fatal(err)
182+
}
183+
defer os.RemoveAll(tmpDir) // clean up
184+
185+
// Ensure the filename is valid and unique
186+
safeFilename := filepath.Clean(filepath.Base(filename))
187+
if isInvalidFilename(safeFilename) {
188+
safeFilename = "test.zip"
189+
}
190+
if !strings.HasSuffix(safeFilename, ".zip") {
191+
safeFilename += ".zip"
192+
}
193+
if isInvalidFilename(projectID) {
194+
projectID = uuid.New().String()
195+
}
196+
197+
filePath := filepath.Join(tmpDir, safeFilename)
198+
// Create a valid zip file
199+
err = createValidZipFile(filePath, data)
200+
if err != nil {
201+
t.Fatal(err)
202+
}
203+
204+
err = UnzipRemoteHub(filePath, projectID)
205+
206+
if err != nil {
207+
t.Errorf("UnExpected error for valid zip, got error: %v", err)
208+
}
209+
210+
// Test with non-existent file
211+
err = UnzipRemoteHub("./not_exist_file.zip", projectID)
212+
if err == nil {
213+
t.Errorf("Expected error for file does not exist, got nil")
214+
}
215+
216+
// Test with non-zip file
217+
nonZipPath := filepath.Join(tmpDir, "no_zip")
218+
err = os.WriteFile(nonZipPath, []byte("not a zip file"), 0644)
219+
if err != nil {
220+
t.Fatal(err)
221+
}
222+
err = UnzipRemoteHub(nonZipPath, projectID)
223+
if err == nil {
224+
t.Errorf("Expected error for no zip, got nil")
225+
}
226+
})
227+
}
228+
229+
func FuzzIsFileExisting(f *testing.F) {
230+
f.Fuzz(func(t *testing.T, filename string) {
231+
// Create a temporary directory
232+
tmpDir, err := os.MkdirTemp("", "*-fuzztest")
233+
if err != nil {
234+
t.Fatal(err)
235+
}
236+
defer os.RemoveAll(tmpDir) // clean up
237+
238+
// Ensure the filename is valid and unique
239+
safeFilename := filepath.Clean(filepath.Base(filename))
240+
if isInvalidFilename(safeFilename) {
241+
safeFilename = "test.yaml"
242+
}
243+
filePath := filepath.Join(tmpDir, safeFilename)
244+
_, _ = os.Create(filePath)
245+
246+
result, err := IsFileExisting(filePath)
247+
if !result {
248+
t.Errorf("Expected true for existing file, got false")
249+
}
250+
251+
result, err = IsFileExisting("./not_exist_file.yaml")
252+
if result {
253+
t.Errorf("Expected false for not existing file, got true")
254+
}
255+
})
256+
}
257+
258+
func isInvalidFilename(filename string) bool {
259+
return strings.IndexByte(filename, 0) != -1 || filename == "" || filename == "." || filename == ".." || filename == "/" || len(filename) > 255
260+
}
261+
262+
func isInvalidYAML(data []byte) bool {
263+
for _, b := range data {
264+
if b < 32 || b == 127 {
265+
return true
266+
}
267+
}
268+
return false
269+
}
270+
271+
func createValidZipFile(filename string, data []byte) error {
272+
zipFile, err := os.Create(filename)
273+
if err != nil {
274+
return err
275+
}
276+
defer zipFile.Close()
277+
278+
zipWriter := zip.NewWriter(zipFile)
279+
defer zipWriter.Close()
280+
281+
f, err := zipWriter.Create("test.txt")
282+
if err != nil {
283+
return err
284+
}
285+
_, err = f.Write(data)
286+
if err != nil {
287+
return err
288+
}
289+
290+
return nil
291+
}

chaoscenter/graphql/server/pkg/chaoshub/handler/handler_test.go

-5
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,6 @@ func TestReadExperimentFile(t *testing.T) {
7272
filePath: "./temp1.yaml",
7373
isError: true,
7474
},
75-
{
76-
name: "failure: file is not a yaml",
77-
filePath: "./types.go",
78-
isError: true,
79-
},
8075
}
8176
for _, tc := range testcases {
8277
// when

0 commit comments

Comments
 (0)