Преглед изворни кода

Removed regen package goconvey test dependency

Amir Khan пре 2 година
родитељ
комит
c3798fc020
3 измењених фајлова са 497 додато и 393 уклоњено
  1. 17 11
      psiphon/common/regen/generator_error_test.go
  2. 471 373
      psiphon/common/regen/regen_test.go
  3. 9 9
      psiphon/common/regen/rng_test.go

+ 17 - 11
psiphon/common/regen/generator_error_test.go

@@ -19,21 +19,27 @@ package regen
 import (
 import (
 	"errors"
 	"errors"
 	"testing"
 	"testing"
-
-	. "github.com/smartystreets/goconvey/convey"
 )
 )
 
 
 func TestGeneratorError(t *testing.T) {
 func TestGeneratorError(t *testing.T) {
-	Convey("GeneratorError", t, func() {
 
 
-		Convey("Handles nil cause", func() {
-			err := generatorError(nil, "msg")
-			So(err.Error(), ShouldEqual, "msg")
-		})
+	t.Run("Handles nil cause", func(t *testing.T) {
+		err := generatorError(nil, "msg")
+		if err == nil {
+			t.Fatal("Expected error, got nil")
+		}
+		if err.Error() != "msg" {
+			t.Fatalf("Expected error message 'msg', got '%s'", err.Error())
+		}
+	})
 
 
-		Convey("Formats", func() {
-			err := generatorError(errors.New("cause"), "msg %s", "arg")
-			So(err.Error(), ShouldEqual, "msg arg\ncaused by cause")
-		})
+	t.Run("Formats", func(t *testing.T) {
+		err := generatorError(errors.New("cause"), "msg %s", "arg")
+		if err == nil {
+			t.Fatal("Expected error, got nil")
+		}
+		if err.Error() != "msg arg\ncaused by cause" {
+			t.Fatalf("Expected error message 'msg arg\ncaused by cause', got '%s'", err.Error())
+		}
 	})
 	})
 }
 }

+ 471 - 373
psiphon/common/regen/regen_test.go

@@ -43,11 +43,10 @@ import (
 	"os"
 	"os"
 	"regexp"
 	"regexp"
 	"regexp/syntax"
 	"regexp/syntax"
+	"strings"
 	"testing"
 	"testing"
 
 
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/prng"
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/prng"
-	. "github.com/smartystreets/goconvey/convey"
-	"github.com/stretchr/testify/assert"
 )
 )
 
 
 const (
 const (
@@ -164,528 +163,521 @@ func ExampleCaptureGroupHandler() {
 func TestGeneratorArgs(t *testing.T) {
 func TestGeneratorArgs(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("initialize", t, func() {
-		Convey("Handles empty struct", func() {
+	t.Run("Handle empty struct", func(t *testing.T) {
+		shouldNotPanic(t, func() {
 			args := GeneratorArgs{}
 			args := GeneratorArgs{}
 
 
-			var err error
-			So(func() { err = args.initialize() }, ShouldNotPanic)
-			So(err, ShouldBeNil)
+			err := args.initialize()
+			if err != nil {
+				t.Fatal(err)
+			}
 		})
 		})
+	})
 
 
-		Convey("Unicode groups not supported", func() {
-			args := &GeneratorArgs{
-				Flags: syntax.UnicodeGroups,
-			}
+	t.Run("Unicode groups not supported", func(t *testing.T) {
+		args := &GeneratorArgs{
+			Flags: syntax.UnicodeGroups,
+		}
 
 
-			err := args.initialize()
-			So(err, ShouldNotBeNil)
-			So(err.Error(), ShouldEqual, "UnicodeGroups not supported")
-		})
+		err := args.initialize()
+		if err == nil {
+			t.Fatal("expected error")
+		}
+		if err.Error() != "UnicodeGroups not supported" {
+			t.Fatalf("unexpected error: %v", err)
+		}
+	})
 
 
-		Convey("Panics if repeat bounds are invalid", func() {
-			args := &GeneratorArgs{
-				MinUnboundedRepeatCount: 2,
-				MaxUnboundedRepeatCount: 1,
-			}
+	t.Run("Panics if repeat bounds are invalid", func(t *testing.T) {
+		args := &GeneratorArgs{
+			MinUnboundedRepeatCount: 2,
+			MaxUnboundedRepeatCount: 1,
+		}
 
 
-			So(func() { args.initialize() },
-				ShouldPanicWith,
-				"MinUnboundedRepeatCount(2) > MaxUnboundedRepeatCount(1)")
-		})
+		shouldPanicWith(t, func() {
+			_ = args.initialize()
+		}, "MinUnboundedRepeatCount(2) > MaxUnboundedRepeatCount(1)")
+	})
 
 
-		Convey("Allows equal repeat bounds", func() {
-			args := &GeneratorArgs{
-				MinUnboundedRepeatCount: 1,
-				MaxUnboundedRepeatCount: 1,
-			}
+	t.Run("Allow equal repeat bounds", func(t *testing.T) {
+		args := &GeneratorArgs{
+			MinUnboundedRepeatCount: 1,
+			MaxUnboundedRepeatCount: 1,
+		}
 
 
-			var err error
-			So(func() { err = args.initialize() }, ShouldNotPanic)
-			So(err, ShouldBeNil)
+		shouldNotPanic(t, func() {
+			err := args.initialize()
+			if err != nil {
+				t.Fatal(err)
+			}
 		})
 		})
 	})
 	})
 
 
-	Convey("Rng", t, func() {
-		Convey("Panics if called before initialization", func() {
-			args := GeneratorArgs{}
-			So(func() { args.Rng() }, ShouldPanic)
+	t.Run("Rng", func(t *testing.T) {
+
+		t.Run("Panics if called before initialize", func(t *testing.T) {
+			args := &GeneratorArgs{}
+
+			shouldPanic(t, func() {
+				_ = args.Rng()
+			})
 		})
 		})
 
 
-		Convey("Non-nil after initialization", func() {
+		t.Run("Non-nil after initialize", func(t *testing.T) {
 			args := GeneratorArgs{}
 			args := GeneratorArgs{}
 			err := args.initialize()
 			err := args.initialize()
-			So(err, ShouldBeNil)
-			So(args.Rng(), ShouldNotBeNil)
+			if err != nil {
+				t.Fatal(err)
+			}
+			rng := args.Rng()
+			if rng == nil {
+				t.Fatal("expected non-nil")
+			}
 		})
 		})
+
 	})
 	})
 }
 }
 
 
 func TestNewGenerator(t *testing.T) {
 func TestNewGenerator(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("NewGenerator", t, func() {
-
-		Convey("Handles nil GeneratorArgs", func() {
-			generator, err := NewGenerator("", nil)
-			So(generator, ShouldNotBeNil)
-			So(err, ShouldBeNil)
-		})
+	t.Run("Handles nil GeneratorArgs", func(t *testing.T) {
+		generator, err := NewGenerator("", nil)
+		if generator == nil {
+			t.Fatal("expected non-nil")
+		}
+		if err != nil {
+			t.Fatal(err)
+		}
+	})
 
 
-		Convey("Handles empty GeneratorArgs", func() {
-			generator, err := NewGenerator("", &GeneratorArgs{})
-			So(generator, ShouldNotBeNil)
-			So(err, ShouldBeNil)
-		})
+	t.Run("Handles empty GeneratorArgs", func(t *testing.T) {
+		generator, err := NewGenerator("", &GeneratorArgs{})
+		if generator == nil {
+			t.Fatal("expected non-nil")
+		}
+		if err != nil {
+			t.Fatal(err)
+		}
+	})
 
 
-		Convey("Forwards errors from args initialization", func() {
-			args := &GeneratorArgs{
-				Flags: syntax.UnicodeGroups,
-			}
+	t.Run("Forwards errors from arsg initialization", func(t *testing.T) {
+		args := &GeneratorArgs{
+			Flags: syntax.UnicodeGroups,
+		}
 
 
-			_, err := NewGenerator("", args)
-			So(err, ShouldNotBeNil)
-		})
+		_, err := NewGenerator("", args)
+		if err == nil {
+			t.Fatal("expected error")
+		}
 	})
 	})
 }
 }
 
 
 func TestGenEmpty(t *testing.T) {
 func TestGenEmpty(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("Empty", t, func() {
-		args := &GeneratorArgs{
-			RngSource: rand.NewSource(0),
-		}
-		ConveyGeneratesStringMatching(args, "", "^$")
-	})
+	args := &GeneratorArgs{
+		RngSource: rand.NewSource(0),
+	}
+
+	testGeneratesStringMatching(t, args, "", "^$")
 }
 }
 
 
 func TestGenLiterals(t *testing.T) {
 func TestGenLiterals(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("Literals", t, func() {
-		ConveyGeneratesStringMatchingItself(nil,
-			"a",
-			"abc",
-		)
-	})
+	testGeneratesStringMatchingItself(t, nil,
+		"a",
+		"abc",
+	)
 }
 }
 
 
 func TestGenDotNotNl(t *testing.T) {
 func TestGenDotNotNl(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("DotNotNl", t, func() {
-		ConveyGeneratesStringMatchingItself(nil, ".")
+	t.Run("DotNotNl", func(t *testing.T) {
+		testGeneratesStringMatchingItself(t, nil, ".")
+	})
 
 
-		Convey("No newlines are generated", func() {
-			generator, _ := NewGenerator(".", nil)
+	t.Run("No newlines are generated", func(t *testing.T) {
+		generator, _ := NewGenerator(".", nil)
 
 
-			// Not a very strong assertion, but not sure how to do better. Exploring the entire
-			// generation space (2^32) takes far too long for a unit test.
-			for i := 0; i < SampleSize; i++ {
-				value, err := generator.Generate()
-				So(err, ShouldBeNil)
-				So(string(value), ShouldNotContainSubstring, "\n")
+		// Not a very strong assertion, but not sure how to do better. Exploring the entire
+		// generation space (2^32) takes far too long for a unit test.
+		for i := 0; i < SampleSize; i++ {
+			value, err := generator.Generate()
+			if err != nil {
+				t.Fatal(err)
 			}
 			}
-		})
+			if strings.Contains(string(value), "\n") {
+				t.Fatalf("unexpected newline in %q", value)
+			}
+		}
 	})
 	})
+
 }
 }
 
 
 func TestGenStringStartEnd(t *testing.T) {
 func TestGenStringStartEnd(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("String start/end", t, func() {
-		args := &GeneratorArgs{
-			RngSource: rand.NewSource(0),
-			Flags:     0,
-		}
+	args := &GeneratorArgs{
+		RngSource: rand.NewSource(0),
+		Flags:     0,
+	}
 
 
-		ConveyGeneratesStringMatching(args, `^abc$`, `^abc$`)
-		ConveyGeneratesStringMatching(args, `$abc^`, `^abc$`)
-		ConveyGeneratesStringMatching(args, `a^b$c`, `^abc$`)
-	})
+	testGeneratesStringMatching(t, args, "^abc$", "^abc$")
+	testGeneratesStringMatching(t, args, "$abc^", "^abc$")
+	testGeneratesStringMatching(t, args, "a^b$c", "^abc$")
 }
 }
 
 
 func TestGenQuestionMark(t *testing.T) {
 func TestGenQuestionMark(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("QuestionMark", t, func() {
-		ConveyGeneratesStringMatchingItself(nil,
-			"a?",
-			"(abc)?",
-			"[ab]?",
-			".?")
-	})
+	testGeneratesStringMatchingItself(t, nil,
+		"a?",
+		"(abc)?",
+		"[ab]?",
+		".?",
+	)
 }
 }
 
 
 func TestGenPlus(t *testing.T) {
 func TestGenPlus(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("Plus", t, func() {
-		ConveyGeneratesStringMatchingItself(nil, "a+")
-	})
+	testGeneratesStringMatchingItself(t, nil, "a+")
 }
 }
 
 
 func TestGenStar(t *testing.T) {
 func TestGenStar(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("Star", t, func() {
-		ConveyGeneratesStringMatchingItself(nil, "a*")
-
-		Convey("HitsDefaultMin", func() {
-			regexp := "a*"
-			args := &GeneratorArgs{
-				RngSource: rand.NewSource(0),
-			}
-			counts := generateLenHistogram(regexp, DefaultMaxUnboundedRepeatCount, args)
+	t.Run("HitsDefaultMin", func(t *testing.T) {
+		regexp := "a*"
+		args := &GeneratorArgs{
+			RngSource: rand.NewSource(0),
+		}
+		counts := generateLenHistogram(regexp, DefaultMaxUnboundedRepeatCount, args)
 
 
-			So(counts[0], ShouldBeGreaterThan, 0)
-		})
+		if counts[0] == 0 {
+			t.Fatalf("count should be > 0")
+		}
+	})
 
 
-		Convey("HitsCustomMin", func() {
-			regexp := "a*"
-			args := &GeneratorArgs{
-				RngSource:               rand.NewSource(0),
-				MinUnboundedRepeatCount: 200,
-			}
-			counts := generateLenHistogram(regexp, DefaultMaxUnboundedRepeatCount, args)
+	t.Run("HitsCustomMin", func(t *testing.T) {
+		regexp := "a*"
+		args := &GeneratorArgs{
+			RngSource:               rand.NewSource(0),
+			MinUnboundedRepeatCount: 200,
+		}
+		counts := generateLenHistogram(regexp, DefaultMaxUnboundedRepeatCount, args)
 
 
-			So(counts[200], ShouldBeGreaterThan, 0)
-			for i := 0; i < 200; i++ {
-				So(counts[i], ShouldEqual, 0)
+		if counts[200] == 0 {
+			t.Fatalf("count should be > 0")
+		}
+		for i := 0; i < 200; i++ {
+			if counts[i] != 0 {
+				t.Fatalf("count should be 0")
 			}
 			}
-		})
+		}
+	})
 
 
-		Convey("HitsDefaultMax", func() {
-			regexp := "a*"
-			args := &GeneratorArgs{
-				RngSource: rand.NewSource(0),
-			}
-			counts := generateLenHistogram(regexp, DefaultMaxUnboundedRepeatCount, args)
+	t.Run("HitsDefaultMax", func(t *testing.T) {
+		regexp := "a*"
+		args := &GeneratorArgs{
+			RngSource: rand.NewSource(0),
+		}
+		counts := generateLenHistogram(regexp, DefaultMaxUnboundedRepeatCount, args)
 
 
-			So(len(counts), ShouldEqual, DefaultMaxUnboundedRepeatCount+1)
-			So(counts[DefaultMaxUnboundedRepeatCount], ShouldBeGreaterThan, 0)
-		})
+		if len(counts) != DefaultMaxUnboundedRepeatCount+1 {
+			t.Fatalf("count should be %d", DefaultMaxUnboundedRepeatCount+1)
+		}
+		if counts[DefaultMaxUnboundedRepeatCount] == 0 {
+			t.Fatalf("count should be > 0")
+		}
+	})
 
 
-		Convey("HitsCustomMax", func() {
-			regexp := "a*"
-			args := &GeneratorArgs{
-				RngSource:               rand.NewSource(0),
-				MaxUnboundedRepeatCount: 200,
-			}
-			counts := generateLenHistogram(regexp, 200, args)
+	t.Run("HitsCustomMax", func(t *testing.T) {
+		regexp := "a*"
+		args := &GeneratorArgs{
+			RngSource:               rand.NewSource(0),
+			MaxUnboundedRepeatCount: 200,
+		}
+		counts := generateLenHistogram(regexp, 200, args)
 
 
-			So(len(counts), ShouldEqual, 200+1)
-			So(counts[200], ShouldBeGreaterThan, 0)
-		})
+		if len(counts) != 201 {
+			t.Fatalf("count should be 201")
+		}
+		if counts[200] == 0 {
+			t.Fatalf("count should be > 0")
+		}
 	})
 	})
 }
 }
 
 
 func TestGenCharClassNotNl(t *testing.T) {
 func TestGenCharClassNotNl(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("CharClassNotNl", t, func() {
-		ConveyGeneratesStringMatchingItself(nil,
-			"[a]",
-			"[abc]",
-			"[a-d]",
-			"[ac]",
-			"[0-9]",
-			"[a-z0-9]",
-		)
+	testGeneratesStringMatchingItself(t, nil,
+		"[a]",
+		"[abc]",
+		"[a-d]",
+		"[ac]",
+		"[0-9]",
+		"[a-z0-9]",
+	)
 
 
-		Convey("No newlines are generated", func() {
-			// Try to narrow down the generation space. Still not a very strong assertion.
-			generator, _ := NewGenerator("[^a-zA-Z0-9]", nil)
-			for i := 0; i < SampleSize; i++ {
-				value, err := generator.Generate()
-				if err != nil {
-					t.Fatal(err)
-				}
-				assert.NotEqual(t, "\n", string(value))
+	t.Run("No newlines are generated", func(t *testing.T) {
+
+		generator, _ := NewGenerator("[^a-zA-Z0-9]", nil)
+		for i := 0; i < SampleSize; i++ {
+			value, err := generator.Generate()
+			if err != nil {
+				t.Fatal(err)
 			}
 			}
-		})
+			if strings.Contains(string(value), "\n") {
+				t.Fatalf("unexpected newline in %q", value)
+			}
+		}
+
 	})
 	})
+
 }
 }
 
 
 func TestGenNegativeCharClass(t *testing.T) {
 func TestGenNegativeCharClass(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("NegativeCharClass", t, func() {
-		ConveyGeneratesStringMatchingItself(nil, "[^a-zA-Z0-9]")
-	})
+	testGeneratesStringMatchingItself(t, nil, "[^a-zA-Z0-9]")
 }
 }
 
 
-func TestGenAlternate(t *testing.T) {
+func TestGenAlternative(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("Alternate", t, func() {
-		ConveyGeneratesStringMatchingItself(nil,
-			"a|b",
-			"abc|def|ghi",
-			"[ab]|[cd]",
-			"foo|bar|baz", // rewrites to foo|ba[rz]
-		)
-	})
+	testGeneratesStringMatchingItself(t, nil,
+		"a|b",
+		"abc|def|ghi",
+		"[ab]|[cd]",
+		"foo|bar|baz", // rewrites to foo|ba[rz]
+	)
 }
 }
 
 
 func TestGenCapture(t *testing.T) {
 func TestGenCapture(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("Capture", t, func() {
-		ConveyGeneratesStringMatching(nil, "(abc)", "^abc$")
-		ConveyGeneratesStringMatching(nil, "()", "^$")
-	})
+	testGeneratesStringMatching(t, nil, "(abc)", "^abc$")
+	testGeneratesStringMatching(t, nil, "(a)(b)(c)", "^abc$")
+	testGeneratesStringMatching(t, nil, "()", "^$")
 }
 }
 
 
 func TestGenConcat(t *testing.T) {
 func TestGenConcat(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("Concat", t, func() {
-		ConveyGeneratesStringMatchingItself(nil, "[ab][cd]")
-	})
+	testGeneratesStringMatchingItself(t, nil, "[ab][cd]")
 }
 }
 
 
 func TestGenRepeat(t *testing.T) {
 func TestGenRepeat(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("Repeat", t, func() {
-
-		Convey("Unbounded", func() {
-			ConveyGeneratesStringMatchingItself(nil, `a{1,}`)
-
-			Convey("HitsDefaultMax", func() {
-				regexp := "a{0,}"
-				args := &GeneratorArgs{
-					RngSource: rand.NewSource(0),
-				}
-				counts := generateLenHistogram(regexp, DefaultMaxUnboundedRepeatCount, args)
-
-				So(len(counts), ShouldEqual, DefaultMaxUnboundedRepeatCount+1)
-				So(counts[DefaultMaxUnboundedRepeatCount], ShouldBeGreaterThan, 0)
-			})
-
-			Convey("HitsCustomMax", func() {
-				regexp := "a{0,}"
-				args := &GeneratorArgs{
-					RngSource:               rand.NewSource(0),
-					MaxUnboundedRepeatCount: 200,
-				}
-				counts := generateLenHistogram(regexp, 200, args)
-
-				So(len(counts), ShouldEqual, 200+1)
-				So(counts[200], ShouldBeGreaterThan, 0)
-			})
-		})
+	t.Run("Unbounded", func(t *testing.T) {
+		testGeneratesStringMatchingItself(t, nil, `a{1,}`)
 
 
-		Convey("HitsMin", func() {
-			regexp := "a{0,3}"
+		t.Run("HitsDefaultMax", func(t *testing.T) {
+			regexp := "a{0,}"
 			args := &GeneratorArgs{
 			args := &GeneratorArgs{
 				RngSource: rand.NewSource(0),
 				RngSource: rand.NewSource(0),
 			}
 			}
-			counts := generateLenHistogram(regexp, 3, args)
+			counts := generateLenHistogram(regexp, DefaultMaxUnboundedRepeatCount, args)
 
 
-			So(len(counts), ShouldEqual, 3+1)
-			So(counts[0], ShouldBeGreaterThan, 0)
+			if len(counts) != DefaultMaxUnboundedRepeatCount+1 {
+				t.Fatalf("count should be %d", DefaultMaxUnboundedRepeatCount+1)
+			}
+			if counts[DefaultMaxUnboundedRepeatCount] == 0 {
+				t.Fatalf("count should be > 0")
+			}
 		})
 		})
 
 
-		Convey("HitsMax", func() {
-			regexp := "a{0,3}"
+		t.Run("HitsCustomMax", func(t *testing.T) {
+			regexp := "a{0,}"
 			args := &GeneratorArgs{
 			args := &GeneratorArgs{
-				RngSource: rand.NewSource(0),
+				RngSource:               rand.NewSource(0),
+				MaxUnboundedRepeatCount: 200,
 			}
 			}
-			counts := generateLenHistogram(regexp, 3, args)
+			counts := generateLenHistogram(regexp, 200, args)
 
 
-			So(len(counts), ShouldEqual, 3+1)
-			So(counts[3], ShouldBeGreaterThan, 0)
+			if len(counts) != 201 {
+				t.Fatalf("count should be 201")
+			}
+			if counts[200] == 0 {
+				t.Fatalf("count should be > 0")
+			}
 		})
 		})
+	})
 
 
-		Convey("IsWithinBounds", func() {
-			regexp := "a{5,10}"
-			args := &GeneratorArgs{
-				RngSource: rand.NewSource(0),
-			}
-			counts := generateLenHistogram(regexp, 10, args)
+	t.Run("HitsMin", func(t *testing.T) {
+		regexp := "a{0,3}"
+		args := &GeneratorArgs{
+			RngSource: rand.NewSource(0),
+		}
+		counts := generateLenHistogram(regexp, 3, args)
+
+		if len(counts) != 4 {
+			t.Fatalf("count should be 4")
+		}
+		if counts[0] == 0 {
+			t.Fatalf("count should be > 0")
+		}
+	})
+
+	t.Run("HitsMax", func(t *testing.T) {
+		regexp := "a{0,3}"
+		args := &GeneratorArgs{
+			RngSource: rand.NewSource(0),
+		}
+		counts := generateLenHistogram(regexp, 3, args)
+
+		if len(counts) != 4 {
+			t.Fatalf("count should be 4")
+		}
+		if counts[3] == 0 {
+			t.Fatalf("count should be > 0")
+		}
+	})
+
+	t.Run("IsWithinBounds", func(t *testing.T) {
+		regexp := "a{5,10}"
+		args := &GeneratorArgs{
+			RngSource: rand.NewSource(0),
+		}
+		counts := generateLenHistogram(regexp, 10, args)
 
 
-			So(len(counts), ShouldEqual, 11)
+		if len(counts) != 11 {
+			t.Fatalf("count should be 11")
+		}
 
 
-			for i := 0; i < 11; i++ {
-				if i < 5 {
-					So(counts[i], ShouldEqual, 0)
-				} else if i < 11 {
-					So(counts[i], ShouldBeGreaterThan, 0)
+		for i := 0; i < 11; i++ {
+			if i < 5 {
+				if counts[i] != 0 {
+					t.Fatalf("count should be 0")
+				}
+			} else if i < 11 {
+				if counts[i] == 0 {
+					t.Fatalf("count should be > 0")
 				}
 				}
 			}
 			}
-		})
+		}
 	})
 	})
+
 }
 }
 
 
 func TestGenCharClasses(t *testing.T) {
 func TestGenCharClasses(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("CharClasses", t, func() {
-
-		Convey("Ascii", func() {
-			ConveyGeneratesStringMatchingItself(nil,
-				"[[:alnum:]]",
-				"[[:alpha:]]",
-				"[[:ascii:]]",
-				"[[:blank:]]",
-				"[[:cntrl:]]",
-				"[[:digit:]]",
-				"[[:graph:]]",
-				"[[:lower:]]",
-				"[[:print:]]",
-				"[[:punct:]]",
-				"[[:space:]]",
-				"[[:upper:]]",
-				"[[:word:]]",
-				"[[:xdigit:]]",
-				"[[:^alnum:]]",
-				"[[:^alpha:]]",
-				"[[:^ascii:]]",
-				"[[:^blank:]]",
-				"[[:^cntrl:]]",
-				"[[:^digit:]]",
-				"[[:^graph:]]",
-				"[[:^lower:]]",
-				"[[:^print:]]",
-				"[[:^punct:]]",
-				"[[:^space:]]",
-				"[[:^upper:]]",
-				"[[:^word:]]",
-				"[[:^xdigit:]]",
-			)
-		})
+	t.Run("Ascii", func(t *testing.T) {
+		testGeneratesStringMatchingItself(t, nil,
+			"[[:alnum:]]",
+			"[[:alpha:]]",
+			"[[:ascii:]]",
+			"[[:blank:]]",
+			"[[:cntrl:]]",
+			"[[:digit:]]",
+			"[[:graph:]]",
+			"[[:lower:]]",
+			"[[:print:]]",
+			"[[:punct:]]",
+			"[[:space:]]",
+			"[[:upper:]]",
+			"[[:word:]]",
+			"[[:xdigit:]]",
+			"[[:^alnum:]]",
+			"[[:^alpha:]]",
+			"[[:^ascii:]]",
+			"[[:^blank:]]",
+			"[[:^cntrl:]]",
+			"[[:^digit:]]",
+			"[[:^graph:]]",
+			"[[:^lower:]]",
+			"[[:^print:]]",
+			"[[:^punct:]]",
+			"[[:^space:]]",
+			"[[:^upper:]]",
+			"[[:^word:]]",
+			"[[:^xdigit:]]",
+		)
+	})
 
 
-		Convey("Perl", func() {
-			args := &GeneratorArgs{
-				Flags: syntax.Perl,
-			}
+	t.Run("Perl", func(t *testing.T) {
+		args := &GeneratorArgs{
+			Flags: syntax.Perl,
+		}
 
 
-			ConveyGeneratesStringMatchingItself(args,
-				`\d`,
-				`\s`,
-				`\w`,
-				`\D`,
-				`\S`,
-				`\W`,
-			)
-		})
+		testGeneratesStringMatchingItself(t, args,
+			`\d`,
+			`\s`,
+			`\w`,
+			`\D`,
+			`\S`,
+			`\W`,
+		)
 	})
 	})
 }
 }
 
 
 func TestCaptureGroupHandler(t *testing.T) {
 func TestCaptureGroupHandler(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 
 
-	Convey("CaptureGroupHandler", t, func() {
-		callCount := 0
+	callCount := 0
 
 
-		gen, err := NewGenerator(`(?:foo) (bar) (?P<name>baz)`, &GeneratorArgs{
-			Flags: syntax.PerlX,
-			CaptureGroupHandler: func(index int, name string, group *syntax.Regexp, generator Generator, args *GeneratorArgs) ([]byte, error) {
-				callCount++
+	gen, err := NewGenerator(`(?:foo) (bar) (?P<name>baz)`, &GeneratorArgs{
+		Flags: syntax.PerlX,
+		CaptureGroupHandler: func(index int, name string, group *syntax.Regexp, generator Generator, args *GeneratorArgs) ([]byte, error) {
+			callCount++
 
 
-				So(index, ShouldBeLessThan, 2)
+			if index >= 2 {
+				t.Fatalf("index should be < 2")
+			}
 
 
-				if index == 0 {
-					So(name, ShouldEqual, "")
-					So(group.String(), ShouldEqual, "bar")
-					value, err := generator.Generate()
-					So(err, ShouldBeNil)
-					So(string(value), ShouldEqual, "bar")
-					return []byte("one"), nil
+			if index == 0 {
+				if name != "" {
+					t.Fatalf("name should be empty")
+				}
+				if group.String() != "bar" {
+					t.Fatalf("group should be 'bar'")
 				}
 				}
-
-				// Index 1
-				So(name, ShouldEqual, "name")
-				So(group.String(), ShouldEqual, "baz")
 				value, err := generator.Generate()
 				value, err := generator.Generate()
-				So(err, ShouldBeNil)
-				So(string(value), ShouldEqual, "baz")
-				return []byte("two"), nil
-			},
-		})
-		So(err, ShouldBeNil)
-
-		value, _ := gen.Generate()
-		So(string(value), ShouldEqual, "foo one two")
-		So(callCount, ShouldEqual, 2)
-	})
-}
-
-func ConveyGeneratesStringMatchingItself(args *GeneratorArgs, patterns ...string) {
-	for _, pattern := range patterns {
-		Convey(fmt.Sprintf("String generated from /%s/ matches itself", pattern), func() {
-			So(pattern, ShouldGenerateStringMatching, pattern, args)
-		})
-	}
-}
+				if err != nil {
+					t.Fatalf("err should be nil")
+				}
+				if string(value) != "bar" {
+					t.Fatalf("value should be 'bar'")
+				}
+				return []byte("one"), nil
+			}
 
 
-func ConveyGeneratesStringMatching(args *GeneratorArgs, pattern string, expectedPattern string) {
-	Convey(fmt.Sprintf("String generated from /%s/ matches /%s/", pattern, expectedPattern), func() {
-		So(pattern, ShouldGenerateStringMatching, expectedPattern, args)
+			// Index 1
+			if name != "name" {
+				t.Fatalf("name should be 'name'")
+			}
+			if group.String() != "baz" {
+				t.Fatalf("group should be 'baz'")
+			}
+			value, err := generator.Generate()
+			if err != nil {
+				t.Fatalf("err should be nil")
+			}
+			if string(value) != "baz" {
+				t.Fatalf("value should be 'baz'")
+			}
+			return []byte("two"), nil
+		},
 	})
 	})
-}
-
-func ShouldGenerateStringMatching(actual interface{}, expected ...interface{}) string {
-	return ShouldGenerateStringMatchingTimes(actual, expected[0], expected[1], SampleSize)
-}
-
-func ShouldGenerateStringMatchingTimes(actual interface{}, expected ...interface{}) string {
-	pattern := actual.(string)
-	expectedPattern := expected[0].(string)
-	args := expected[1].(*GeneratorArgs)
-	times := expected[2].(int)
-
-	generator, err := NewGenerator(pattern, args)
 	if err != nil {
 	if err != nil {
-		panic(err)
-	}
-
-	for i := 0; i < times; i++ {
-		result, err := generator.Generate()
-		if err != nil {
-			panic(err)
-		}
-		matched, err := regexp.MatchString(expectedPattern, string(result))
-		if err != nil {
-			panic(err)
-		}
-		if !matched {
-			return fmt.Sprintf("string “%s” generated from /%s/ did not match /%s/.",
-				result, pattern, expectedPattern)
-		}
+		t.Fatalf("err should be nil")
 	}
 	}
 
 
-	return ""
-}
+	value, _ := gen.Generate()
 
 
-func generateLenHistogram(regexp string, maxLen int, args *GeneratorArgs) (counts []int) {
-	generator, err := NewGenerator(regexp, args)
-	if err != nil {
-		panic(err)
+	if string(value) != "foo one two" {
+		t.Fatalf("value should be 'foo one two'")
 	}
 	}
-
-	iterations := max(maxLen*4, SampleSize)
-
-	for i := 0; i < iterations; i++ {
-		value, err := generator.Generate()
-		if err != nil {
-			panic(err)
-		}
-		str := string(value)
-		// Grow the slice if necessary.
-		if len(str) >= len(counts) {
-			newCounts := make([]int, len(str)+1)
-			copy(newCounts, counts)
-			counts = newCounts
-		}
-
-		counts[len(str)]++
+	if callCount != 2 {
+		t.Fatalf("callCount should be 2")
 	}
 	}
-
-	return
 }
 }
 
 
 // Byte mode tests
 // Byte mode tests
@@ -813,6 +805,84 @@ func TestByteModeNegatedClasses(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func testGeneratesStringMatchingItself(t *testing.T, args *GeneratorArgs, patterns ...string) {
+	t.Helper()
+	for _, pattern := range patterns {
+		t.Run(fmt.Sprintf("String generated from /%s/ matches itself", pattern), func(t *testing.T) {
+			err := shouldGenerateStringMatching(pattern, pattern, args)
+			if err != nil {
+				t.Fatal(err)
+			}
+		})
+	}
+}
+
+func testGeneratesStringMatching(t *testing.T, args *GeneratorArgs, pattern, expectedPattern string) {
+	t.Helper()
+	t.Run(fmt.Sprintf("String generated from /%s/ matches /%s/", pattern, expectedPattern), func(t *testing.T) {
+		err := shouldGenerateStringMatching(pattern, expectedPattern, args)
+		if err != nil {
+			t.Fatal(err)
+		}
+	})
+}
+
+func shouldGenerateStringMatching(pattern, expectedPattern string, args *GeneratorArgs) error {
+	return shouldGenerateStringMatchingTimes(pattern, expectedPattern, args, SampleSize)
+}
+
+func shouldGenerateStringMatchingTimes(pattern, expectedPattern string, args *GeneratorArgs, times int) error {
+
+	generator, err := NewGenerator(pattern, args)
+	if err != nil {
+		panic(err)
+	}
+
+	for i := 0; i < times; i++ {
+		result, err := generator.Generate()
+		if err != nil {
+			panic(err)
+		}
+		matched, err := regexp.MatchString(expectedPattern, string(result))
+		if err != nil {
+			panic(err)
+		}
+		if !matched {
+			return fmt.Errorf("string “%s” generated from /%s/ did not match /%s/.",
+				result, pattern, expectedPattern)
+		}
+	}
+
+	return nil
+}
+
+func generateLenHistogram(regexp string, maxLen int, args *GeneratorArgs) (counts []int) {
+	generator, err := NewGenerator(regexp, args)
+	if err != nil {
+		panic(err)
+	}
+
+	iterations := max(maxLen*4, SampleSize)
+
+	for i := 0; i < iterations; i++ {
+		value, err := generator.Generate()
+		if err != nil {
+			panic(err)
+		}
+		str := string(value)
+		// Grow the slice if necessary.
+		if len(str) >= len(counts) {
+			newCounts := make([]int, len(str)+1)
+			copy(newCounts, counts)
+			counts = newCounts
+		}
+
+		counts[len(str)]++
+	}
+
+	return
+}
+
 // isUnifrom performs a chi-squared test with 0.025 significance.
 // isUnifrom performs a chi-squared test with 0.025 significance.
 // Each bucket in xs is compared against the expected_value.
 // Each bucket in xs is compared against the expected_value.
 func isUniform(xs []int, expected_value int) bool {
 func isUniform(xs []int, expected_value int) bool {
@@ -835,3 +905,31 @@ func max(values ...int) int {
 	}
 	}
 	return m
 	return m
 }
 }
+
+func shouldPanic(t *testing.T, f func()) {
+	t.Helper()
+	defer func() { _ = recover() }()
+	f()
+	t.Errorf("should have panicked")
+}
+
+func shouldPanicWith(t *testing.T, f func(), expected string) {
+	t.Helper()
+	defer func() {
+		if r := recover(); r != expected {
+			t.Errorf("expected panic %q, got %q", expected, r)
+		}
+	}()
+	f()
+	t.Errorf("should have panicked")
+}
+
+func shouldNotPanic(t *testing.T, f func()) {
+	t.Helper()
+	defer func() {
+		if r := recover(); r != nil {
+			t.Error("should not have panicked")
+		}
+	}()
+	f()
+}

+ 9 - 9
psiphon/common/regen/rng_test.go

@@ -16,23 +16,21 @@ limitations under the License.
 
 
 package regen
 package regen
 
 
-import (
-	"testing"
-
-	. "github.com/smartystreets/goconvey/convey"
-)
+import "testing"
 
 
 func TestXorShift64(t *testing.T) {
 func TestXorShift64(t *testing.T) {
-	Convey("Int63 should never return negative numbers.", t, func() {
+	t.Run("Int63 should never return negative numbers", func(t *testing.T) {
 		source := xorShift64Source(1)
 		source := xorShift64Source(1)
 		for i := 0; i < SampleSize; i++ {
 		for i := 0; i < SampleSize; i++ {
 			val := source.Int63()
 			val := source.Int63()
 
 
-			So(val, ShouldBeGreaterThanOrEqualTo, 0)
+			if val < 0 {
+				t.Fatal("Int63 returned a negative number")
+			}
 		}
 		}
 	})
 	})
 
 
-	Convey("Should not only return zeros", t, func() {
+	t.Run("Should not only return zeros", func(t *testing.T) {
 		source := xorShift64Source(0)
 		source := xorShift64Source(0)
 		nonZeroCount := 0
 		nonZeroCount := 0
 
 
@@ -42,6 +40,8 @@ func TestXorShift64(t *testing.T) {
 			}
 			}
 		}
 		}
 
 
-		So(nonZeroCount, ShouldBeGreaterThan, 0)
+		if nonZeroCount <= 0 {
+			t.Fatal("Int63 returned non-positive numbers")
+		}
 	})
 	})
 }
 }