system/dbus: print incomplete string in buffer
All checks were successful
Test / Create distribution (push) Successful in 1m8s
Test / Sandbox (push) Successful in 3m43s
Test / Hakurei (push) Successful in 5m27s
Test / Sandbox (race detector) (push) Successful in 6m17s
Test / Hpkg (push) Successful in 7m36s
Test / Hakurei (race detector) (push) Successful in 7m44s
Test / Flake checks (push) Successful in 2m29s

Not sure if this will ever be reached, but nice to have nonetheless.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-09-06 15:48:57 +09:00
parent 05db06c87b
commit ac81cfbedc
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
2 changed files with 34 additions and 26 deletions

View File

@ -7,7 +7,6 @@ import (
"fmt" "fmt"
"log" "log"
"reflect" "reflect"
"strconv"
"strings" "strings"
"sync" "sync"
"syscall" "syscall"
@ -170,9 +169,11 @@ func (s *linePrefixWriter) write(p []byte, a int) (int, error) {
return a + n, nil return a + n, nil
} else { } else {
n, _ := s.buf.Write(p[:i]) n, _ := s.buf.Write(p[:i])
s.n += n + 1
v := s.buf.String() v := s.buf.String()
if strings.HasPrefix(v, "init: ") { if strings.HasPrefix(v, "init: ") {
s.n -= len(v) + 1
// pass through container init messages // pass through container init messages
s.println(s.prefix + v) s.println(s.prefix + v)
} else { } else {
@ -180,22 +181,20 @@ func (s *linePrefixWriter) write(p []byte, a int) (int, error) {
} }
s.buf.Reset() s.buf.Reset()
s.n += n + 1
return s.write(p[i+1:], a+n+1) return s.write(p[i+1:], a+n+1)
} }
} }
func (s *linePrefixWriter) Dump() { func (s *linePrefixWriter) Dump() {
s.mu.RLock() s.mu.RLock()
// the final write might go past the threshold,
// and the buffer might still contain data
var n int
for _, m := range s.msg { for _, m := range s.msg {
n += len(m)
s.println(s.prefix + m) s.println(s.prefix + m)
} }
if s.n > lpwSizeThreshold { if s.buf != nil && s.buf.Len() != 0 {
s.println(s.prefix + "dropped " + strconv.Itoa(s.n-n) + " bytes of output") s.println("*" + s.prefix + s.buf.String())
}
if s.n >= lpwSizeThreshold {
s.println("+" + s.prefix + "write threshold reached, output may be incomplete")
} }
s.mu.RUnlock() s.mu.RUnlock()
} }

View File

@ -392,10 +392,11 @@ func TestLinePrefixWriter(t *testing.T) {
}{ }{
{"nop", "(nop) ", func(func(string)) {}, nil, nil, nil, nil, ""}, {"nop", "(nop) ", func(func(string)) {}, nil, nil, nil, nil, ""},
{"partial", "(break) ", func(w func(string)) { {"partial", "(partial) ", func(w func(string)) {
w("C-65533: -> ") w("C-65533: -> ")
}, nil, nil, nil, nil, }, nil, nil, nil, []string{
"C-65533: -> "}, "*(partial) C-65533: -> ",
}, "C-65533: -> "},
{"break", "(break) ", func(w func(string)) { {"break", "(break) ", func(w func(string)) {
w("C-65533: -> ") w("C-65533: -> ")
@ -414,8 +415,10 @@ func TestLinePrefixWriter(t *testing.T) {
{"threshold", "(threshold) ", func(w func(s string)) { {"threshold", "(threshold) ", func(w func(s string)) {
w(string(make([]byte, lpwSizeThreshold))) w(string(make([]byte, lpwSizeThreshold)))
w("\n") w("\n")
}, []error{nil, syscall.ENOMEM}, nil, nil, nil, }, []error{nil, syscall.ENOMEM}, nil, nil, []string{
string(make([]byte, lpwSizeThreshold))}, "*(threshold) " + string(make([]byte, lpwSizeThreshold)),
"+(threshold) write threshold reached, output may be incomplete",
}, string(make([]byte, lpwSizeThreshold))},
{"threshold multi", "(threshold multi) ", func(w func(s string)) { {"threshold multi", "(threshold multi) ", func(w func(s string)) {
w(":3\n") w(":3\n")
@ -423,15 +426,20 @@ func TestLinePrefixWriter(t *testing.T) {
w("\n") w("\n")
}, []error{nil, nil, syscall.ENOMEM}, nil, []string{ }, []error{nil, nil, syscall.ENOMEM}, nil, []string{
":3", ":3",
}, nil, string(make([]byte, lpwSizeThreshold-3))}, }, []string{
"*(threshold multi) " + string(make([]byte, lpwSizeThreshold-3)),
"+(threshold multi) write threshold reached, output may be incomplete",
}, string(make([]byte, lpwSizeThreshold-3))},
{"threshold multi partial", "(threshold multi partial) ", func(w func(s string)) { {"threshold multi partial", "(threshold multi partial) ", func(w func(s string)) {
w(":3\n") w(":3\n")
w(string(make([]byte, lpwSizeThreshold-2))) w(string(make([]byte, lpwSizeThreshold-2)))
}, []error{nil, syscall.ENOMEM}, nil, []string{ w("dropped\n")
}, []error{nil, nil, syscall.ENOMEM}, nil, []string{
":3", ":3",
}, []string{ }, []string{
"dropped 16777215 bytes of output", "*(threshold multi partial) " + string(make([]byte, lpwSizeThreshold-2)),
"+(threshold multi partial) write threshold reached, output may be incomplete",
}, string(make([]byte, lpwSizeThreshold-2))}, }, string(make([]byte, lpwSizeThreshold-2))},
{"threshold exact", "(threshold exact) ", func(w func(s string)) { {"threshold exact", "(threshold exact) ", func(w func(s string)) {
@ -439,7 +447,9 @@ func TestLinePrefixWriter(t *testing.T) {
w("\n") w("\n")
}, nil, nil, []string{ }, nil, nil, []string{
string(make([]byte, lpwSizeThreshold-1)), string(make([]byte, lpwSizeThreshold-1)),
}, nil, ""}, }, []string{
"+(threshold exact) write threshold reached, output may be incomplete",
}, ""},
{"sample", "(dbus) ", func(w func(s string)) { {"sample", "(dbus) ", func(w func(s string)) {
w("init: received setup parameters\n") w("init: received setup parameters\n")
@ -595,16 +605,15 @@ func TestLinePrefixWriter(t *testing.T) {
var pos int var pos int
tc.f(func(s string) { tc.f(func(s string) {
if _, err := out.Write([]byte(s)); err != nil { _, err := out.Write([]byte(s))
if tc.wantErr != nil { if tc.wantErr != nil {
if !reflect.DeepEqual(err, tc.wantErr[pos]) { if !reflect.DeepEqual(err, tc.wantErr[pos]) {
t.Fatalf("Write: error = %v, want %v", err, tc.wantErr[pos]) t.Fatalf("Write: error = %v, want %v", err, tc.wantErr[pos])
} }
} else { } else if err != nil {
t.Fatalf("Write: unexpected error: %v", err) t.Fatalf("Write: unexpected error: %v", err)
return return
} }
}
pos++ pos++
}) })
@ -629,7 +638,7 @@ func TestLinePrefixWriter(t *testing.T) {
wantDump[i] = tc.prefix + m wantDump[i] = tc.prefix + m
} }
for i, m := range tc.wantExt { for i, m := range tc.wantExt {
wantDump[len(tc.want)+i] = tc.prefix + m wantDump[len(tc.want)+i] = m
} }
t.Run("dump", func(t *testing.T) { t.Run("dump", func(t *testing.T) {
got := make([]string, 0, len(wantDump)) got := make([]string, 0, len(wantDump))