-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add term execution count and sleep tests
Signed-off-by: Ramil Mirhasanov <[email protected]> Signed-off-by: Prasad Chandrasekaran <[email protected]> Co-authored-by: Marek Siarkowicz <[email protected]> Co-authored-by: Benjamin Wang <[email protected]>
- Loading branch information
Showing
4 changed files
with
182 additions
and
8 deletions.
There are no files selected for viewing
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
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
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
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,158 @@ | ||
package runtime_test | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
|
||
"go.etcd.io/gofail/runtime" | ||
) | ||
|
||
// This variable mimics the code generated by gofail code package. | ||
// This works in tandem with exampleFunc function. | ||
var __fp_ExampleString *runtime.Failpoint //nolint:stylecheck | ||
|
||
// check if failpoint is initialized as gofail | ||
// tests can clear global variables of runtime packages | ||
func initFP() { | ||
fps := runtime.List() | ||
if fps != nil { | ||
s_fps := strings.Join(fps, " ") | ||
if strings.Contains(s_fps, "ExampleString") { | ||
return | ||
} | ||
} | ||
__fp_ExampleString = runtime.NewFailpoint("ExampleString") //nolint:stylecheck | ||
} | ||
|
||
func TestTermsCounter(t *testing.T) { | ||
testcases := []struct { | ||
name string | ||
fp string | ||
failpointTerm string | ||
runBeforeEnabling int | ||
runAfterEnabling int | ||
wantCount int | ||
}{ | ||
{ | ||
name: "Terms limit Failpoint", | ||
fp: "ExampleString", | ||
failpointTerm: `10*sleep(10)->1*return("abc")`, | ||
runAfterEnabling: 12, | ||
// This example tests mods which allows users to restrict the | ||
// number of failpoint actions as against their callsite executions. | ||
// This is the reason why wantCount < runAfterEnabling | ||
// In a real world example you can hit a code spot a million times but | ||
// using mods restrict the associated fallpoint actions to run twice. | ||
wantCount: 11, | ||
}, | ||
{ | ||
name: "Inbetween Enabling Failpoint", | ||
fp: "ExampleString", | ||
failpointTerm: `10*sleep(10)->1*return("abc")`, | ||
runBeforeEnabling: 2, | ||
runAfterEnabling: 3, | ||
wantCount: 3, | ||
}, | ||
{ | ||
name: "Before Enabling Failpoint", | ||
fp: "ExampleString", | ||
failpointTerm: `10*sleep(10)->1*return("abc")`, | ||
runBeforeEnabling: 2, | ||
runAfterEnabling: 0, | ||
wantCount: 0, | ||
}, | ||
} | ||
|
||
initFP() | ||
for _, tc := range testcases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
|
||
for i := 0; i < tc.runBeforeEnabling; i++ { | ||
exampleFunc() | ||
} | ||
|
||
err := runtime.Enable(tc.fp, tc.failpointTerm) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer runtime.Disable(tc.fp) | ||
for i := 0; i < tc.runAfterEnabling; i++ { | ||
exampleFunc() | ||
} | ||
_, count, err := runtime.Status(tc.fp) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
if tc.wantCount != count { | ||
t.Fatal("counter is not properly incremented") | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestEnablingNewTermResetsCount(t *testing.T) { | ||
testcases := []struct { | ||
name string | ||
fp string | ||
oldTerm string | ||
newTerm string | ||
runOldTerm int | ||
runNewTerm int | ||
wantCount int | ||
}{ | ||
{ | ||
name: "Change and Reset Counter", | ||
fp: "ExampleString", | ||
oldTerm: `10*sleep(10)->1*return("abc")`, | ||
newTerm: "sleep(10)", | ||
runOldTerm: 2, | ||
runNewTerm: 3, | ||
wantCount: 3, | ||
}, | ||
} | ||
|
||
initFP() | ||
for _, tc := range testcases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
err := runtime.Enable(tc.fp, tc.oldTerm) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
for i := 0; i < tc.runOldTerm; i++ { | ||
exampleFunc() | ||
} | ||
err = runtime.Enable(tc.fp, tc.newTerm) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer runtime.Disable(tc.fp) | ||
|
||
for i := 0; i < tc.runNewTerm; i++ { | ||
exampleFunc() | ||
} | ||
_, count, err := runtime.Status(tc.fp) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
if tc.wantCount != count { | ||
t.Fatal("counter is not properly incremented") | ||
} | ||
}) | ||
} | ||
|
||
} | ||
|
||
// This function mimics a customized code that is generated by gofail code package. | ||
func exampleFunc() string { | ||
if vExampleString, __fpErr := __fp_ExampleString.Acquire(); __fpErr == nil { //nolint:stylecheck | ||
ExampleString, __fpTypeOK := vExampleString.(string) //nolint:stylecheck | ||
if !__fpTypeOK { //nolint:stylecheck | ||
goto __badTypeExampleString //nolint:stylecheck | ||
} | ||
return ExampleString | ||
__badTypeExampleString: //nolint:stylecheck | ||
__fp_ExampleString.BadType(vExampleString, "string") //nolint:stylecheck | ||
} | ||
return "example" | ||
} |