mirror of
https://github.com/rs/zerolog
synced 2026-06-08 17:13:30 +00:00
f6fbd330be
* Test coverage improvements Implements #397 and #591, might help with #473 Test coverage for core is 97.6% with only real fringe cases remaining. Improve `Fields` `isNilValue()` portability. Added a new global handler `FatalExitFunc` to allow intercepting `Fatal()` messages. Fixed CBOR float constants (removed the CBOR prefix) Added tests for: - global `FatalExitFunc` to allow intercepting Fatal messages (both for testing and public use). - `Logger` - `DisableSampling` - `.With()` copying existing context if present. - `.With().Fields()` all forms of `ErrorStackMarshaler` returns. - `.WithLevel()` for `FatalLevel`, `PanicLevel`, and `DisabledLevel`. - `.Err()` with `nil` and non-`nil` `error` and test the resulting log level. - `.should()` covering `nil` writer. - `.Output()` gets context values. - `.UpdateContext()` on a disabled logger doesn't panic and is a nop. - `.With()` all forms of `ErrorStackMarshaler` returns. - with a `nil`writer. - `.Hook()` passing no hooks. - `Array` - `.MarshalZerologArray` is a nop that won't panic. - `Context` - ` .Err()` and `.AnErr()` for `nil` errors and all forms of `ErrorStackMarshaler` returns. - `Event` - `.Caller()` to ensure we don't panic or add invalid information if `runtime.Caller()` fails -` .Err()` and `.AnErr()` for `nil` errors and all forms of `ErrorStackMarshaler` returns. - `Fields` - ` .appendFields()` all forms of `ErrorStackMarshaler` returns. - `HookLevel` - `.Run()` methods. - `LevelSampler` - `.Sample() methods. - `Syslog` - `.Write()`, `.WriteLevel()`, and `.Close()` methods. - `.WriteLevel()` with an `InvalidLevel`. - `Writer` - `.Write()` short write and error cases. - `MultiLevelWriter` `.WriteLevel()` and for `.Write()` error and `.Close()` cases. - test of unmarshalling a level byte returns correct error. - CBOR decodeStream - `.decodeFloat()`, `.binaryFmt()`, `.DecodeIfBinaryToString()`, `.DecodeObjectToStr()`, `.DecodeIfBinaryToBytes()`, `.decodeTagData()`, and `.decodeSimpleFloat()` - handling of invalid UTF-8 sequences - handling of UTC times. - handling of timestamps - handling of various map lengths Restructure `Event` `.caller()` so we test for ok and eliminate untestable coverage hole. Restructure `Context` `.Err()` when the `ErrorStackMarshaler` returns a `nil` so there's code to cover. Inverted logic for`Event` `.Caller()`'s call to `runtime.Caller()` for simpler testing. Inverted logic for `Array` `.putArray()` and `Event` `.putEvent()` so there isn't uncoverable code. Restructure `Field` `.appendFieldList()` to early return when `ErrorStackMarshaler` returns a `nil` Added comments for things we can't get coverage on. Did a go fmt ./... Coverage of core is now 100% on `Array`, `Context`, `Ctx`, `Event`, `Field`, `Hook`, and `Syslog`. Coverage of `Globals`, `Log`, `Sampler`, and `Writer` is almost all except some real edge-cases. JSON encoder coverage is 100% CBOR encoder coverage is 96.3% with base, cbor, string, time and types at 100% and decode_stream (which is lacks coverage on some panic states, and two incorrect coverage-tool lapses) * Fix CBOR tests for StackMarshaler Forgot to use the `decodeIfBinaryToString()`
103 lines
2.9 KiB
Go
103 lines
2.9 KiB
Go
// Package cbor provides primitives for storing different data
|
|
// in the CBOR (binary) format. CBOR is defined in RFC7049.
|
|
package cbor
|
|
|
|
import "time"
|
|
|
|
const (
|
|
majorOffset = 5
|
|
additionalMax = 23
|
|
|
|
// Non Values.
|
|
additionalTypeBoolFalse byte = 20
|
|
additionalTypeBoolTrue byte = 21
|
|
additionalTypeNull byte = 22
|
|
|
|
// Integer (+ve and -ve) Sub-types.
|
|
additionalTypeIntUint8 byte = 24
|
|
additionalTypeIntUint16 byte = 25
|
|
additionalTypeIntUint32 byte = 26
|
|
additionalTypeIntUint64 byte = 27
|
|
|
|
// Float Sub-types.
|
|
additionalTypeFloat16 byte = 25
|
|
additionalTypeFloat32 byte = 26
|
|
additionalTypeFloat64 byte = 27
|
|
additionalTypeBreak byte = 31
|
|
|
|
// Tag Sub-types.
|
|
additionalTypeTimestamp byte = 01
|
|
additionalTypeEmbeddedCBOR byte = 63
|
|
|
|
// Extended Tags - from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
|
|
additionalTypeTagNetworkAddr uint16 = 260
|
|
additionalTypeTagNetworkPrefix uint16 = 261
|
|
additionalTypeEmbeddedJSON uint16 = 262
|
|
additionalTypeTagHexString uint16 = 263
|
|
|
|
// Unspecified number of elements.
|
|
additionalTypeInfiniteCount byte = 31
|
|
)
|
|
const (
|
|
majorTypeUnsignedInt byte = iota << majorOffset // Major type 0
|
|
majorTypeNegativeInt // Major type 1
|
|
majorTypeByteString // Major type 2
|
|
majorTypeUtf8String // Major type 3
|
|
majorTypeArray // Major type 4
|
|
majorTypeMap // Major type 5
|
|
majorTypeTags // Major type 6
|
|
majorTypeSimpleAndFloat // Major type 7
|
|
)
|
|
|
|
const (
|
|
maskOutAdditionalType byte = (7 << majorOffset)
|
|
maskOutMajorType byte = 31
|
|
)
|
|
|
|
const (
|
|
float32Nan = "\x7f\xc0\x00\x00"
|
|
float32PosInfinity = "\x7f\x80\x00\x00"
|
|
float32NegInfinity = "\xff\x80\x00\x00"
|
|
float64Nan = "\x7f\xf8\x00\x00\x00\x00\x00\x00"
|
|
float64PosInfinity = "\x7f\xf0\x00\x00\x00\x00\x00\x00"
|
|
float64NegInfinity = "\xff\xf0\x00\x00\x00\x00\x00\x00"
|
|
)
|
|
|
|
// IntegerTimeFieldFormat indicates the format of timestamp decoded
|
|
// from an integer (time in seconds).
|
|
var IntegerTimeFieldFormat = time.RFC3339
|
|
|
|
// NanoTimeFieldFormat indicates the format of timestamp decoded
|
|
// from a float value (time in seconds and nanoseconds).
|
|
var NanoTimeFieldFormat = time.RFC3339Nano
|
|
|
|
func appendCborTypePrefix(dst []byte, major byte, number uint64) []byte {
|
|
var byteCount int
|
|
var minor byte
|
|
switch {
|
|
case number < 256:
|
|
byteCount = 1
|
|
minor = additionalTypeIntUint8
|
|
|
|
case number < 65536:
|
|
byteCount = 2
|
|
minor = additionalTypeIntUint16
|
|
|
|
case number < 4294967296:
|
|
byteCount = 4
|
|
minor = additionalTypeIntUint32
|
|
|
|
default:
|
|
byteCount = 8
|
|
minor = additionalTypeIntUint64
|
|
|
|
}
|
|
|
|
dst = append(dst, major|minor)
|
|
byteCount--
|
|
for ; byteCount >= 0; byteCount-- {
|
|
dst = append(dst, byte(number>>(uint(byteCount)*8)))
|
|
}
|
|
return dst
|
|
}
|