Skip to content

Commit 2d1bfcb

Browse files
jbaeric
authored andcommitted
log/slog: rename and remove files
- Remove the norace_test.go files, moving their contents elsewhere. - Rename the internal/testutil package to internal/slogtest. - Remove value_unsafe.go, moving its contents to value.go. Updates golang#56345. Change-Id: I2a24ace5aea47f7a3067cd671f606c4fb279d744 Reviewed-on: https://go-review.googlesource.com/c/go/+/478197 Run-TryBot: Jonathan Amsterdam <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent ed25a8e commit 2d1bfcb

11 files changed

+118
-155
lines changed

Diff for: src/go/build/deps_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ var depsRules = `
386386
log/slog/internal, log/slog/internal/buffer,
387387
slices
388388
< log/slog
389-
< log/slog/internal/testutil;
389+
< log/slog/internal/slogtest;
390390
391391
NET, log
392392
< net/mail;

Diff for: src/log/slog/example_level_handler_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ package slog_test
77
import (
88
"context"
99
"log/slog"
10-
"log/slog/internal/testutil"
10+
"log/slog/internal/slogtest"
1111
"os"
1212
)
1313

@@ -63,7 +63,7 @@ func (h *LevelHandler) Handler() slog.Handler {
6363
// Another typical use would be to decrease the log level (to LevelDebug, say)
6464
// during a part of the program that was suspected of containing a bug.
6565
func ExampleHandler_levelHandler() {
66-
th := slog.HandlerOptions{ReplaceAttr: testutil.RemoveTime}.NewTextHandler(os.Stdout)
66+
th := slog.HandlerOptions{ReplaceAttr: slogtest.RemoveTime}.NewTextHandler(os.Stdout)
6767
logger := slog.New(NewLevelHandler(slog.LevelWarn, th))
6868
logger.Info("not printed")
6969
logger.Warn("printed")

Diff for: src/log/slog/example_logvaluer_secret_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package slog_test
66

77
import (
88
"log/slog"
9-
"log/slog/internal/testutil"
9+
"log/slog/internal/slogtest"
1010
"os"
1111
)
1212

@@ -23,7 +23,7 @@ func (Token) LogValue() slog.Value {
2323
// with an alternative representation to avoid revealing secrets.
2424
func ExampleLogValuer_secret() {
2525
t := Token("shhhh!")
26-
logger := slog.New(slog.HandlerOptions{ReplaceAttr: testutil.RemoveTime}.
26+
logger := slog.New(slog.HandlerOptions{ReplaceAttr: slogtest.RemoveTime}.
2727
NewTextHandler(os.Stdout))
2828
logger.Info("permission granted", "user", "Perry", "token", t)
2929

Diff for: src/log/slog/example_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package slog_test
66

77
import (
88
"log/slog"
9-
"log/slog/internal/testutil"
9+
"log/slog/internal/slogtest"
1010
"net/http"
1111
"os"
1212
"time"
@@ -16,7 +16,7 @@ func ExampleGroup() {
1616
r, _ := http.NewRequest("GET", "localhost", nil)
1717
// ...
1818

19-
logger := slog.New(slog.HandlerOptions{ReplaceAttr: testutil.RemoveTime}.NewTextHandler(os.Stdout))
19+
logger := slog.New(slog.HandlerOptions{ReplaceAttr: slogtest.RemoveTime}.NewTextHandler(os.Stdout))
2020
slog.SetDefault(logger)
2121

2222
slog.Info("finished",

Diff for: src/log/slog/internal/buffer/buffer_test.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44

55
package buffer
66

7-
import "testing"
7+
import (
8+
"internal/race"
9+
"internal/testenv"
10+
"testing"
11+
)
812

913
func Test(t *testing.T) {
1014
b := New()
@@ -20,3 +24,18 @@ func Test(t *testing.T) {
2024
t.Errorf("got %q, want %q", got, want)
2125
}
2226
}
27+
28+
func TestAlloc(t *testing.T) {
29+
if race.Enabled {
30+
t.Skip("skipping test in race mode")
31+
}
32+
testenv.SkipIfOptimizationOff(t)
33+
got := int(testing.AllocsPerRun(5, func() {
34+
b := New()
35+
defer b.Free()
36+
b.WriteString("not 1K worth of bytes")
37+
}))
38+
if got != 0 {
39+
t.Errorf("got %d allocs, want 0", got)
40+
}
41+
}

Diff for: src/log/slog/internal/buffer/norace_test.go

-26
This file was deleted.

Diff for: src/log/slog/internal/testutil/testutil.go renamed to src/log/slog/internal/slogtest/slogtest.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// Package testutil contains support functions for testing.
6-
package testutil
5+
// Package slogtest contains support functions for testing slog.
6+
package slogtest
77

88
import "log/slog"
99

Diff for: src/log/slog/logger_test.go

+14
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ package slog
77
import (
88
"bytes"
99
"context"
10+
"internal/race"
11+
"internal/testenv"
1012
"io"
1113
"log"
1214
"path/filepath"
@@ -509,3 +511,15 @@ func callerPC(depth int) uintptr {
509511
runtime.Callers(depth, pcs[:])
510512
return pcs[0]
511513
}
514+
515+
func wantAllocs(t *testing.T, want int, f func()) {
516+
if race.Enabled {
517+
t.Skip("skipping test in race mode")
518+
}
519+
testenv.SkipIfOptimizationOff(t)
520+
t.Helper()
521+
got := int(testing.AllocsPerRun(5, f))
522+
if got != want {
523+
t.Errorf("got %d allocs, want %d", got, want)
524+
}
525+
}

Diff for: src/log/slog/norace_test.go

-23
This file was deleted.

Diff for: src/log/slog/value.go

+75-6
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,32 @@ import (
1010
"slices"
1111
"strconv"
1212
"time"
13+
"unsafe"
1314
)
1415

15-
// Definitions for Value.
16-
// The Value type itself can be found in value_{safe,unsafe}.go.
16+
// A Value can represent any Go value, but unlike type any,
17+
// it can represent most small values without an allocation.
18+
// The zero Value corresponds to nil.
19+
type Value struct {
20+
// num holds the value for Kinds Int64, Uint64, Float64, Bool and Duration,
21+
// the string length for KindString, and nanoseconds since the epoch for KindTime.
22+
num uint64
23+
// If any is of type Kind, then the value is in num as described above.
24+
// If any is of type *time.Location, then the Kind is Time and time.Time value
25+
// can be constructed from the Unix nanos in num and the location (monotonic time
26+
// is not preserved).
27+
// If any is of type stringptr, then the Kind is String and the string value
28+
// consists of the length in num and the pointer in any.
29+
// Otherwise, the Kind is Any and any is the value.
30+
// (This implies that Attrs cannot store values of type Kind, *time.Location
31+
// or stringptr.)
32+
any any
33+
}
34+
35+
type (
36+
stringptr *byte // used in Value.any when the Value is a string
37+
groupptr *Attr // used in Value.any when the Value is a []Attr
38+
)
1739

1840
// Kind is the kind of a Value.
1941
type Kind int
@@ -58,8 +80,33 @@ func (k Kind) String() string {
5880
// (No user-provided value has this type.)
5981
type kind Kind
6082

83+
// Kind returns v's Kind.
84+
func (v Value) Kind() Kind {
85+
switch x := v.any.(type) {
86+
case Kind:
87+
return x
88+
case stringptr:
89+
return KindString
90+
case timeLocation:
91+
return KindTime
92+
case groupptr:
93+
return KindGroup
94+
case LogValuer:
95+
return KindLogValuer
96+
case kind: // a kind is just a wrapper for a Kind
97+
return KindAny
98+
default:
99+
return KindAny
100+
}
101+
}
102+
61103
//////////////// Constructors
62104

105+
// StringValue returns a new Value for a string.
106+
func StringValue(value string) Value {
107+
return Value{num: uint64(len(value)), any: stringptr(unsafe.StringData(value))}
108+
}
109+
63110
// IntValue returns a Value for an int.
64111
func IntValue(v int) Value {
65112
return Int64Value(int64(v))
@@ -114,7 +161,7 @@ func DurationValue(v time.Duration) Value {
114161
// GroupValue returns a new Value for a list of Attrs.
115162
// The caller must not subsequently mutate the argument slice.
116163
func GroupValue(as ...Attr) Value {
117-
return groupValue(as)
164+
return Value{num: uint64(len(as)), any: groupptr(unsafe.SliceData(as))}
118165
}
119166

120167
// AnyValue returns a Value for the supplied value.
@@ -192,7 +239,7 @@ func (v Value) Any() any {
192239
case KindLogValuer:
193240
return v.any
194241
case KindGroup:
195-
return v.uncheckedGroup()
242+
return v.group()
196243
case KindInt64:
197244
return int64(v.num)
198245
case KindUint64:
@@ -212,6 +259,21 @@ func (v Value) Any() any {
212259
}
213260
}
214261

262+
// String returns Value's value as a string, formatted like fmt.Sprint. Unlike
263+
// the methods Int64, Float64, and so on, which panic if v is of the
264+
// wrong kind, String never panics.
265+
func (v Value) String() string {
266+
if sp, ok := v.any.(stringptr); ok {
267+
return unsafe.String(sp, v.num)
268+
}
269+
var buf []byte
270+
return string(v.append(buf))
271+
}
272+
273+
func (v Value) str() string {
274+
return unsafe.String(v.any.(stringptr), v.num)
275+
}
276+
215277
// Int64 returns v's value as an int64. It panics
216278
// if v is not a signed integer.
217279
func (v Value) Int64() int64 {
@@ -297,7 +359,14 @@ func (v Value) LogValuer() LogValuer {
297359
// Group returns v's value as a []Attr.
298360
// It panics if v's Kind is not KindGroup.
299361
func (v Value) Group() []Attr {
300-
return v.group()
362+
if sp, ok := v.any.(groupptr); ok {
363+
return unsafe.Slice((*Attr)(sp), v.num)
364+
}
365+
panic("Group: bad kind")
366+
}
367+
368+
func (v Value) group() []Attr {
369+
return unsafe.Slice((*Attr)(v.any.(groupptr)), v.num)
301370
}
302371

303372
//////////////// Other
@@ -321,7 +390,7 @@ func (v Value) Equal(w Value) bool {
321390
case KindAny, KindLogValuer:
322391
return v.any == w.any // may panic if non-comparable
323392
case KindGroup:
324-
return slices.EqualFunc(v.uncheckedGroup(), w.uncheckedGroup(), Attr.Equal)
393+
return slices.EqualFunc(v.group(), w.group(), Attr.Equal)
325394
default:
326395
panic(fmt.Sprintf("bad kind: %s", k1))
327396
}

0 commit comments

Comments
 (0)