github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/gnovm/stdlibs/testing/fuzz_test.gno (about) 1 package testing 2 3 import ( 4 "encoding/binary" 5 "strings" 6 "time" 7 ) 8 9 func TestMutate(t *T) { 10 originalValue := "Hello" 11 fuzzer := StringFuzzer{Value: originalValue} 12 13 newFuzzer := fuzzer.Mutate().(*StringFuzzer) 14 15 if newFuzzer.Value == originalValue { 16 t.Errorf("Mutate did not change the string: got %v, want different from %v", newFuzzer.Value, originalValue) 17 } 18 19 if len(newFuzzer.Value) != len(originalValue) { 20 t.Errorf("Mutated string has different length: got %s (len=%v), want %s (len=%v)", newFuzzer.Value, len(newFuzzer.Value), originalValue, len(originalValue)) 21 } 22 } 23 24 func TestSelection(t *T) { 25 tests := []struct { 26 name string 27 population []*Individual 28 }{ 29 { 30 name: "Empty population", 31 population: []*Individual{}, 32 }, 33 { 34 name: "Uniform fitness", 35 population: []*Individual{ 36 {Fitness: 10}, 37 {Fitness: 10}, 38 {Fitness: 10}, 39 }, 40 }, 41 { 42 name: "Different fitness", 43 population: []*Individual{ 44 {Fitness: 5}, 45 {Fitness: 15}, 46 {Fitness: 10}, 47 }, 48 }, 49 } 50 51 for _, tc := range tests { 52 t.Run(tc.name, func(t *T) { 53 selected := Selection(tc.population) 54 if len(selected) != len(tc.population) { 55 t.Errorf("Expected selected length to be %d, got %d", len(tc.population), len(selected)) 56 } 57 }) 58 } 59 } 60 61 func TestCrossover(t *T) { 62 parent1 := NewIndividual(&StringFuzzer{Value: "foobar"}) 63 parent2 := NewIndividual(&StringFuzzer{Value: "bazbiz"}) 64 65 var child1, child2 *Individual 66 for i := 0; i < 100; i++ { 67 child1, child2 = Crossover(parent1, parent2) 68 } 69 70 if child1.Fuzzer.String() == "foobar" || child2.Fuzzer.String() == "bazbiz" { 71 t.Errorf("Crossover did not modify children correctly, got %s and %s", child1.Fuzzer.String(), child2.Fuzzer.String()) 72 } 73 } 74 75 func Test_StringManipulation(t *T) { 76 f := &F{ 77 corpus: []string{"hello", "world", "foo", "bar"}, 78 } 79 80 f.evolve(30) 81 82 if len(f.corpus) != 4 { 83 t.Fatalf("corpus length is %d, want 4", len(f.corpus)) 84 } 85 86 for i, c := range f.corpus { 87 if c == "" { 88 t.Fatalf("corpus[%d] is empty", i) 89 } 90 91 if len(c) < 3 { 92 t.Fatalf("corpus[%d] is too short: %s", i, c) 93 } 94 95 if f.corpus[0] == "hello" { 96 t.Fatalf("corpus[0] is still the same: %s", f.corpus[0]) 97 } 98 99 if f.corpus[1] == "world" { 100 t.Fatalf("corpus[1] is still the same: %s", f.corpus[1]) 101 } 102 103 if f.corpus[2] == "foo" { 104 t.Fatalf("corpus[2] is still the same: %s", f.corpus[2]) 105 } 106 107 if f.corpus[3] == "bar" { 108 t.Fatalf("corpus[3] is still the same: %s", f.corpus[3]) 109 } 110 111 } 112 } 113 114 func TestFuzz(t *T) { 115 f := F{} 116 f.Add("hello", "world", "foo") 117 f.Fuzz(func(t *T, inputs ...interface{}) { 118 for _, input := range inputs { 119 strInput, ok := input.(string) 120 if !ok { 121 t.Errorf("Type mismatch, expected a string but got %T", input) 122 continue 123 } 124 125 words := strings.Fields(strInput) 126 if len(words) == 0 { 127 t.Errorf("Expected non-empty input") 128 } 129 } 130 }, 15) 131 132 if len(f.corpus) == 0 { 133 t.Fatalf("Fuzzing corpus is empty after testing") 134 } 135 136 if len(f.corpus) > 3 { 137 t.Fatalf("Fuzzing corpus has more than 3 elements: %v", f.corpus) 138 } 139 140 for _, c := range f.corpus { 141 if c == "hello" || c == "world" || c == "foo" { 142 t.Fatalf("Fuzzing corpus still contains the original elements: %v", f.corpus) 143 } 144 } 145 } 146 147 func TestF_Fail(t *T) { 148 f := F{} 149 f.Fail() 150 151 if !f.failed { 152 t.Errorf("Fail did not set the failed flag.") 153 } 154 } 155 156 func TestF_Fatal(t *T) { 157 f := F{} 158 testMessage := "test failure message" 159 f.Fatal(testMessage) 160 161 if !f.failed { 162 t.Errorf("Fatal did not set the failed flag.") 163 } 164 165 if len(f.msgs) != 1 { 166 t.Fatalf("Fatal did not set the message correctly: got %v, want %v", f.msgs, testMessage) 167 } 168 169 if !strings.Contains(f.msgs[0], testMessage) { 170 t.Errorf("Fatal did not set the message correctly: got %v, want %v", f.msgs[0], testMessage) 171 } 172 }