snapshot of https://github.com/grpc/grpc-go.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
codecov / upload (push) Failing after 13m59s
CodeQL / Analyze (push) Failing after 1s
Testing / vet-proto (push) Failing after 1s
Testing / tests (arm, latest) (push) Waiting to run
Testing / extras (latest) (push) Failing after 1s
Testing / static checks (latest-1) (push) Failing after 1s
Testing / tests (-race, latest) (push) Failing after 1s
Testing / tests (i386, latest) (push) Failing after 1s
Testing / tests (latest) (push) Failing after 1s
Testing / tests (latest-1) (push) Failing after 1s
Lock Threads / lock (push) Failing after 1s
govulncheck / govulncheck (.) (push) Failing after 1s
govulncheck / govulncheck (./cmd/protoc-gen-go-grpc) (push) Failing after 1s
govulncheck / govulncheck (./gcp/observability) (push) Failing after 1s
govulncheck / govulncheck (./security/advancedtls) (push) Failing after 1s
govulncheck / govulncheck (./stats/opencensus) (push) Failing after 1s
Stale bot / stale (push) Failing after 1s
Some checks failed
codecov / upload (push) Failing after 13m59s
CodeQL / Analyze (push) Failing after 1s
Testing / vet-proto (push) Failing after 1s
Testing / tests (arm, latest) (push) Waiting to run
Testing / extras (latest) (push) Failing after 1s
Testing / static checks (latest-1) (push) Failing after 1s
Testing / tests (-race, latest) (push) Failing after 1s
Testing / tests (i386, latest) (push) Failing after 1s
Testing / tests (latest) (push) Failing after 1s
Testing / tests (latest-1) (push) Failing after 1s
Lock Threads / lock (push) Failing after 1s
govulncheck / govulncheck (.) (push) Failing after 1s
govulncheck / govulncheck (./cmd/protoc-gen-go-grpc) (push) Failing after 1s
govulncheck / govulncheck (./gcp/observability) (push) Failing after 1s
govulncheck / govulncheck (./security/advancedtls) (push) Failing after 1s
govulncheck / govulncheck (./stats/opencensus) (push) Failing after 1s
Stale bot / stale (push) Failing after 1s
This commit is contained in:
61
internal/grpctest/example_test.go
Normal file
61
internal/grpctest/example_test.go
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package grpctest_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"google.golang.org/grpc/internal/grpctest"
|
||||
)
|
||||
|
||||
type s struct {
|
||||
i int
|
||||
}
|
||||
|
||||
func (s *s) Setup(t *testing.T) {
|
||||
t.Log("Per-test setup code")
|
||||
s.i = 5
|
||||
}
|
||||
|
||||
func (s *s) TestSomething(t *testing.T) {
|
||||
t.Log("TestSomething")
|
||||
if s.i != 5 {
|
||||
t.Errorf("s.i = %v; want 5", s.i)
|
||||
}
|
||||
s.i = 3
|
||||
}
|
||||
|
||||
func (s *s) TestSomethingElse(t *testing.T) {
|
||||
t.Log("TestSomethingElse")
|
||||
if got, want := s.i%4, 1; got != want {
|
||||
t.Errorf("s.i %% 4 = %v; want %v", got, want)
|
||||
}
|
||||
s.i = 3
|
||||
}
|
||||
|
||||
func (s *s) Teardown(t *testing.T) {
|
||||
t.Log("Per-test teardown code")
|
||||
if s.i != 3 {
|
||||
t.Fatalf("s.i = %v; want 3", s.i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExample(t *testing.T) {
|
||||
grpctest.RunSubTests(t, &s{})
|
||||
}
|
||||
135
internal/grpctest/grpctest.go
Normal file
135
internal/grpctest/grpctest.go
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2018 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
// Package grpctest implements testing helpers.
|
||||
package grpctest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc/internal/leakcheck"
|
||||
)
|
||||
|
||||
var lcFailed uint32
|
||||
|
||||
type logger struct {
|
||||
t *testing.T
|
||||
}
|
||||
|
||||
func (e logger) Logf(format string, args ...any) {
|
||||
e.t.Logf(format, args...)
|
||||
}
|
||||
|
||||
func (e logger) Errorf(format string, args ...any) {
|
||||
atomic.StoreUint32(&lcFailed, 1)
|
||||
e.t.Errorf(format, args...)
|
||||
}
|
||||
|
||||
// Tester is an implementation of the x interface parameter to
|
||||
// grpctest.RunSubTests with default Setup and Teardown behavior. Setup updates
|
||||
// the tlogger and Teardown performs a leak check. Embed in a struct with tests
|
||||
// defined to use.
|
||||
type Tester struct{}
|
||||
|
||||
// Setup updates the tlogger.
|
||||
func (Tester) Setup(t *testing.T) {
|
||||
tLogr.update(t)
|
||||
// TODO: There is one final leak around closing connections without completely
|
||||
// draining the recvBuffer that has yet to be resolved. All other leaks have been
|
||||
// completely addressed, and this can be turned back on as soon as this issue is
|
||||
// fixed.
|
||||
leakcheck.SetTrackingBufferPool(logger{t: t})
|
||||
leakcheck.TrackTimers()
|
||||
leakcheck.TrackAsyncReporters()
|
||||
}
|
||||
|
||||
// Teardown performs a leak check.
|
||||
func (Tester) Teardown(t *testing.T) {
|
||||
leakcheck.CheckTrackingBufferPool()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
leakcheck.CheckTimers(ctx, logger{t: t})
|
||||
if atomic.LoadUint32(&lcFailed) == 1 {
|
||||
return
|
||||
}
|
||||
leakcheck.CheckGoroutines(ctx, logger{t: t})
|
||||
if atomic.LoadUint32(&lcFailed) == 1 {
|
||||
t.Log("Goroutine leak check disabled for future tests")
|
||||
}
|
||||
leakcheck.CheckAsyncReporters(logger{t: t})
|
||||
if atomic.LoadUint32(&lcFailed) == 1 {
|
||||
return
|
||||
}
|
||||
tLogr.endTest(t)
|
||||
}
|
||||
|
||||
// Interface defines Tester's methods for use in this package.
|
||||
type Interface interface {
|
||||
Setup(*testing.T)
|
||||
Teardown(*testing.T)
|
||||
}
|
||||
|
||||
func getTestFunc(t *testing.T, xv reflect.Value, name string) func(*testing.T) {
|
||||
if m := xv.MethodByName(name); m.IsValid() {
|
||||
if f, ok := m.Interface().(func(*testing.T)); ok {
|
||||
return f
|
||||
}
|
||||
// Method exists but has the wrong type signature.
|
||||
t.Fatalf("grpctest: function %v has unexpected signature (%T)", name, m.Interface())
|
||||
}
|
||||
return func(*testing.T) {}
|
||||
}
|
||||
|
||||
// RunSubTests runs all "Test___" functions that are methods of x as subtests
|
||||
// of the current test. Setup is run before the test function and Teardown is
|
||||
// run after.
|
||||
//
|
||||
// For example usage, see example_test.go. Run it using:
|
||||
//
|
||||
// $ go test -v -run TestExample .
|
||||
//
|
||||
// To run a specific test/subtest:
|
||||
//
|
||||
// $ go test -v -run 'TestExample/^Something$' .
|
||||
func RunSubTests(t *testing.T, x Interface) {
|
||||
xt := reflect.TypeOf(x)
|
||||
xv := reflect.ValueOf(x)
|
||||
|
||||
for i := 0; i < xt.NumMethod(); i++ {
|
||||
methodName := xt.Method(i).Name
|
||||
if !strings.HasPrefix(methodName, "Test") {
|
||||
continue
|
||||
}
|
||||
tfunc := getTestFunc(t, xv, methodName)
|
||||
t.Run(strings.TrimPrefix(methodName, "Test"), func(t *testing.T) {
|
||||
// Run leakcheck in t.Cleanup() to guarantee it is run even if tfunc
|
||||
// or setup uses t.Fatal().
|
||||
//
|
||||
// Note that a defer would run before t.Cleanup, so if a goroutine
|
||||
// is closed by a test's t.Cleanup, a deferred leakcheck would fail.
|
||||
t.Cleanup(func() { x.Teardown(t) })
|
||||
x.Setup(t)
|
||||
tfunc(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
46
internal/grpctest/grpctest_test.go
Normal file
46
internal/grpctest/grpctest_test.go
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2018 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package grpctest
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type tRunST struct {
|
||||
setup, test, teardown bool
|
||||
}
|
||||
|
||||
func (t *tRunST) Setup(*testing.T) {
|
||||
t.setup = true
|
||||
}
|
||||
func (t *tRunST) TestSubTest(*testing.T) {
|
||||
t.test = true
|
||||
}
|
||||
func (t *tRunST) Teardown(*testing.T) {
|
||||
t.teardown = true
|
||||
}
|
||||
|
||||
func TestRunSubTests(t *testing.T) {
|
||||
x := &tRunST{}
|
||||
RunSubTests(t, x)
|
||||
if want := (&tRunST{setup: true, test: true, teardown: true}); !reflect.DeepEqual(x, want) {
|
||||
t.Fatalf("x = %v; want all fields true", x)
|
||||
}
|
||||
}
|
||||
300
internal/grpctest/tlogger.go
Normal file
300
internal/grpctest/tlogger.go
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2020 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package grpctest
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
// tLogr serves as the grpclog logger and is the interface through which
|
||||
// expected errors are declared in tests.
|
||||
var tLogr *tLogger
|
||||
|
||||
const callingFrame = 4
|
||||
|
||||
type logType int
|
||||
|
||||
func (l logType) String() string {
|
||||
switch l {
|
||||
case infoLog:
|
||||
return "INFO"
|
||||
case warningLog:
|
||||
return "WARNING"
|
||||
case errorLog:
|
||||
return "ERROR"
|
||||
case fatalLog:
|
||||
return "FATAL"
|
||||
}
|
||||
return "UNKNOWN"
|
||||
}
|
||||
|
||||
const (
|
||||
infoLog logType = iota
|
||||
warningLog
|
||||
errorLog
|
||||
fatalLog
|
||||
)
|
||||
|
||||
type tLogger struct {
|
||||
v int
|
||||
initialized bool
|
||||
|
||||
mu sync.Mutex
|
||||
t *testing.T
|
||||
start time.Time
|
||||
logs map[logType]map[*regexp.Regexp]int
|
||||
}
|
||||
|
||||
func init() {
|
||||
vLevel := 0 // Default verbosity level
|
||||
|
||||
if vLevelEnv, found := os.LookupEnv("GRPC_GO_LOG_VERBOSITY_LEVEL"); found {
|
||||
// If found, attempt to convert. If conversion is successful, update vLevel.
|
||||
// If conversion fails, log a warning, but vLevel remains its default of 0.
|
||||
if val, err := strconv.Atoi(vLevelEnv); err == nil {
|
||||
vLevel = val
|
||||
} else {
|
||||
// Log the error if the environment variable is not a valid integer.
|
||||
fmt.Printf("Warning: GRPC_GO_LOG_VERBOSITY_LEVEL environment variable '%s' is not a valid integer. "+
|
||||
"Using default verbosity level 0. Error: %v\n", vLevelEnv, err)
|
||||
}
|
||||
}
|
||||
// Initialize tLogr with the determined verbosity level.
|
||||
logsMap := map[logType]map[*regexp.Regexp]int{
|
||||
errorLog: {},
|
||||
warningLog: {},
|
||||
}
|
||||
tLogr = &tLogger{logs: logsMap, v: vLevel}
|
||||
}
|
||||
|
||||
// getCallingPrefix returns the <file:line> at the given depth from the stack.
|
||||
func getCallingPrefix(depth int) (string, error) {
|
||||
_, file, line, ok := runtime.Caller(depth)
|
||||
if !ok {
|
||||
return "", errors.New("frame request out-of-bounds")
|
||||
}
|
||||
return fmt.Sprintf("%s:%d", path.Base(file), line), nil
|
||||
}
|
||||
|
||||
// log logs the message with the specified parameters to the tLogger.
|
||||
func (tl *tLogger) log(ltype logType, depth int, format string, args ...any) {
|
||||
tl.mu.Lock()
|
||||
defer tl.mu.Unlock()
|
||||
prefix, err := getCallingPrefix(callingFrame + depth)
|
||||
if err != nil {
|
||||
tl.t.Error(err)
|
||||
return
|
||||
}
|
||||
args = append([]any{ltype.String() + " " + prefix}, args...)
|
||||
args = append(args, fmt.Sprintf(" (t=+%s)", time.Since(tl.start)))
|
||||
|
||||
if format == "" {
|
||||
switch ltype {
|
||||
case errorLog:
|
||||
// fmt.Sprintln is used rather than fmt.Sprint because tl.Log uses fmt.Sprintln behavior.
|
||||
if tl.expected(fmt.Sprintln(args...), errorLog) {
|
||||
tl.t.Log(args...)
|
||||
} else {
|
||||
tl.t.Error(args...)
|
||||
}
|
||||
case warningLog:
|
||||
tl.expected(fmt.Sprintln(args...), warningLog)
|
||||
tl.t.Log(args...)
|
||||
case fatalLog:
|
||||
panic(fmt.Sprint(args...))
|
||||
default:
|
||||
tl.t.Log(args...)
|
||||
}
|
||||
} else {
|
||||
// Add formatting directives for the callingPrefix and timeSuffix.
|
||||
format = "%v " + format + "%s"
|
||||
switch ltype {
|
||||
case errorLog:
|
||||
if tl.expected(fmt.Sprintf(format, args...), errorLog) {
|
||||
tl.t.Logf(format, args...)
|
||||
} else {
|
||||
tl.t.Errorf(format, args...)
|
||||
}
|
||||
case warningLog:
|
||||
tl.expected(fmt.Sprintln(args...), warningLog)
|
||||
tl.t.Log(args...)
|
||||
case fatalLog:
|
||||
panic(fmt.Sprintf(format, args...))
|
||||
default:
|
||||
tl.t.Logf(format, args...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update updates the testing.T that the testing logger logs to. Should be done
|
||||
// before every test. It also initializes the tLogger if it has not already.
|
||||
func (tl *tLogger) update(t *testing.T) {
|
||||
tl.mu.Lock()
|
||||
defer tl.mu.Unlock()
|
||||
if !tl.initialized {
|
||||
grpclog.SetLoggerV2(tl)
|
||||
tl.initialized = true
|
||||
}
|
||||
tl.t = t
|
||||
tl.start = time.Now()
|
||||
tl.logs[errorLog] = map[*regexp.Regexp]int{}
|
||||
tl.logs[warningLog] = map[*regexp.Regexp]int{}
|
||||
}
|
||||
|
||||
// ExpectError declares an error to be expected. For the next test, the first
|
||||
// error log matching the expression (using FindString) will not cause the test
|
||||
// to fail. "For the next test" includes all the time until the next call to
|
||||
// Update(). Note that if an expected error is not encountered, this will cause
|
||||
// the test to fail.
|
||||
func ExpectError(expr string) {
|
||||
expectLogsN(expr, 1, errorLog)
|
||||
}
|
||||
|
||||
// ExpectErrorN declares an error to be expected n times.
|
||||
func ExpectErrorN(expr string, n int) {
|
||||
expectLogsN(expr, n, errorLog)
|
||||
}
|
||||
|
||||
// ExpectWarning declares a warning to be expected.
|
||||
func ExpectWarning(expr string) {
|
||||
expectLogsN(expr, 1, warningLog)
|
||||
}
|
||||
|
||||
func expectLogsN(expr string, n int, logType logType) {
|
||||
tLogr.mu.Lock()
|
||||
defer tLogr.mu.Unlock()
|
||||
re, err := regexp.Compile(expr)
|
||||
if err != nil {
|
||||
tLogr.t.Error(err)
|
||||
return
|
||||
}
|
||||
tLogr.logs[logType][re] += n
|
||||
}
|
||||
|
||||
// endTest checks if expected errors were not encountered.
|
||||
func (tl *tLogger) endTest(t *testing.T) {
|
||||
tl.mu.Lock()
|
||||
defer tl.mu.Unlock()
|
||||
for re, count := range tl.logs[errorLog] {
|
||||
if count > 0 {
|
||||
t.Errorf("Expected error '%v' not encountered", re.String())
|
||||
}
|
||||
}
|
||||
for re, count := range tl.logs[warningLog] {
|
||||
if count > 0 {
|
||||
t.Errorf("Expected warning '%v' not encountered", re.String())
|
||||
}
|
||||
}
|
||||
tl.logs[errorLog] = map[*regexp.Regexp]int{}
|
||||
tl.logs[warningLog] = map[*regexp.Regexp]int{}
|
||||
}
|
||||
|
||||
// expected determines if the log string of the particular type is protected or
|
||||
// not.
|
||||
func (tl *tLogger) expected(s string, logType logType) bool {
|
||||
for re, count := range tl.logs[logType] {
|
||||
if re.FindStringIndex(s) != nil {
|
||||
tl.logs[logType][re]--
|
||||
if count <= 1 {
|
||||
delete(tl.logs[logType], re)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (tl *tLogger) Info(args ...any) {
|
||||
tl.log(infoLog, 0, "", args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) Infoln(args ...any) {
|
||||
tl.log(infoLog, 0, "", args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) Infof(format string, args ...any) {
|
||||
tl.log(infoLog, 0, format, args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) InfoDepth(depth int, args ...any) {
|
||||
tl.log(infoLog, depth, "", args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) Warning(args ...any) {
|
||||
tl.log(warningLog, 0, "", args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) Warningln(args ...any) {
|
||||
tl.log(warningLog, 0, "", args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) Warningf(format string, args ...any) {
|
||||
tl.log(warningLog, 0, format, args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) WarningDepth(depth int, args ...any) {
|
||||
tl.log(warningLog, depth, "", args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) Error(args ...any) {
|
||||
tl.log(errorLog, 0, "", args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) Errorln(args ...any) {
|
||||
tl.log(errorLog, 0, "", args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) Errorf(format string, args ...any) {
|
||||
tl.log(errorLog, 0, format, args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) ErrorDepth(depth int, args ...any) {
|
||||
tl.log(errorLog, depth, "", args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) Fatal(args ...any) {
|
||||
tl.log(fatalLog, 0, "", args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) Fatalln(args ...any) {
|
||||
tl.log(fatalLog, 0, "", args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) Fatalf(format string, args ...any) {
|
||||
tl.log(fatalLog, 0, format, args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) FatalDepth(depth int, args ...any) {
|
||||
tl.log(fatalLog, depth, "", args...)
|
||||
}
|
||||
|
||||
func (tl *tLogger) V(l int) bool {
|
||||
return l <= tl.v
|
||||
}
|
||||
79
internal/grpctest/tlogger_test.go
Normal file
79
internal/grpctest/tlogger_test.go
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2020 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package grpctest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
type s struct {
|
||||
Tester
|
||||
}
|
||||
|
||||
func Test(t *testing.T) {
|
||||
RunSubTests(t, s{})
|
||||
}
|
||||
|
||||
func (s) TestInfo(*testing.T) {
|
||||
grpclog.Info("Info", "message.")
|
||||
}
|
||||
|
||||
func (s) TestInfoln(*testing.T) {
|
||||
grpclog.Infoln("Info", "message.")
|
||||
}
|
||||
|
||||
func (s) TestInfof(*testing.T) {
|
||||
grpclog.Infof("%v %v.", "Info", "message")
|
||||
}
|
||||
|
||||
func (s) TestInfoDepth(*testing.T) {
|
||||
grpclog.InfoDepth(0, "Info", "depth", "message.")
|
||||
}
|
||||
|
||||
func (s) TestWarning(*testing.T) {
|
||||
grpclog.Warning("Warning", "message.")
|
||||
}
|
||||
|
||||
func (s) TestWarningln(*testing.T) {
|
||||
grpclog.Warningln("Warning", "message.")
|
||||
}
|
||||
|
||||
func (s) TestWarningf(*testing.T) {
|
||||
grpclog.Warningf("%v %v.", "Warning", "message")
|
||||
}
|
||||
|
||||
func (s) TestWarningDepth(*testing.T) {
|
||||
grpclog.WarningDepth(0, "Warning", "depth", "message.")
|
||||
}
|
||||
|
||||
func (s) TestError(*testing.T) {
|
||||
const numErrors = 10
|
||||
ExpectError("Expected error")
|
||||
ExpectError("Expected ln error")
|
||||
ExpectError("Expected formatted error")
|
||||
ExpectErrorN("Expected repeated error", numErrors)
|
||||
grpclog.Error("Expected", "error")
|
||||
grpclog.Errorln("Expected", "ln", "error")
|
||||
grpclog.Errorf("%v %v %v", "Expected", "formatted", "error")
|
||||
for i := 0; i < numErrors; i++ {
|
||||
grpclog.Error("Expected repeated error")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user