Skip to content

Commit

Permalink
fix: break many symbols with one name
Browse files Browse the repository at this point in the history
  • Loading branch information
siyul-park committed Dec 21, 2024
1 parent c67b1e0 commit 258614a
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 91 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ DOCKERFILE = deployments/Dockerfile
CGO_ENABLED ?= 1

.PHONY: init generate build clean tidy update sync check test coverage benchmark lint fmt vet doc docker-build
all: lint test build

init:
@cp .go.work go.work
Expand Down
116 changes: 68 additions & 48 deletions cmd/pkg/cli/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"context"
"encoding/json"
"fmt"
"strconv"
"slices"
"strings"
"time"

Expand Down Expand Up @@ -43,13 +43,10 @@ type debugView interface {

// Various debug view types
type (
errDebugView struct{ err error }
frameDebugView struct{ frame *agent.Frame }
framesDebugView struct{ frames []*agent.Frame }
breakpointDebugView struct {
id int
breakpoint *debug.Breakpoint
}
errDebugView struct{ err error }
frameDebugView struct{ frame *agent.Frame }
framesDebugView struct{ frames []*agent.Frame }
breakpointDebugView struct{ breakpoint *debug.Breakpoint }
breakpointsDebugView struct{ breakpoints []*debug.Breakpoint }
symbolDebugView struct{ symbol *symbol.Symbol }
symbolsDebugView struct{ symbols []*symbol.Symbol }
Expand Down Expand Up @@ -143,38 +140,49 @@ func (m *debugModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case "quit", "q":
return m, tea.Quit
case "break", "b":
var sb *symbol.Symbol
if len(args) > 1 {
sb = m.findSymbol(args[1])
if sb == nil {
var bps []*debug.Breakpoint
if len(args) <= 1 {
bp := debug.NewBreakpoint()
m.debugger.AddBreakpoint(bp)

bps = append(bps, bp)
} else {
sbs := m.findSymbols(args[1])
if len(sbs) == 0 {
m.view = &errDebugView{err: fmt.Errorf("symbol '%s' not found", args[1])}
return m, nil
}
}

var inPort *port.InPort
var outPort *port.OutPort
if len(args) > 2 {
inPort, outPort = m.findPort(sb, args[2])
if inPort == nil && outPort == nil {
m.view = &errDebugView{err: fmt.Errorf("port '%s' not found on symbol '%s'", args[2], sb.Name())}
return m, nil
for _, sb := range sbs {
var inPort *port.InPort
var outPort *port.OutPort
if len(args) > 2 {
inPort, outPort = m.findPort(sb, args[2])
if inPort == nil && outPort == nil {
continue
}
}

bp := debug.NewBreakpoint(
debug.WithSymbol(sb),
debug.WithInPort(inPort),
debug.WithOutPort(outPort),
)
m.debugger.AddBreakpoint(bp)

bps = append(bps, bp)
}
}

bp := debug.NewBreakpoint(
debug.WithSymbol(sb),
debug.WithInPort(inPort),
debug.WithOutPort(outPort),
)
m.debugger.AddBreakpoint(bp)

bps := m.debugger.Breakpoints()
m.view = &breakpointDebugView{id: len(bps) - 1, breakpoint: bp}
if len(bps) == 1 {
m.view = &breakpointDebugView{breakpoint: bps[0]}
} else {
m.view = &breakpointsDebugView{breakpoints: bps}
}

return m, func() tea.Msg {
if m.debugger.Pause(context.Background()) {
if m.debugger.Breakpoint() == bp {
if slices.Contains(bps, m.debugger.Breakpoint()) {
return m.debugger.Frame()
}
}
Expand All @@ -190,12 +198,14 @@ func (m *debugModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return nil
}
case "delete", "d":
bps := m.debugger.Breakpoints()

var bp *debug.Breakpoint
if len(args) > 1 {
if i, err := strconv.Atoi(args[1]); err == nil && i < len(bps) {
bp = bps[i]
bps := m.debugger.Breakpoints()
for _, b := range bps {
if b.ID().String() == args[1] {
bp = b
break
}
}
} else {
bp = m.debugger.Breakpoint()
Expand All @@ -211,12 +221,14 @@ func (m *debugModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.view = &breakpointsDebugView{breakpoints: bps}
return m, nil
case "breakpoint", "bp":
bps := m.debugger.Breakpoints()

var bp *debug.Breakpoint
if len(args) > 1 {
if i, err := strconv.Atoi(args[1]); err == nil && i < len(bps) {
bp = bps[i]
bps := m.debugger.Breakpoints()
for _, b := range bps {
if b.ID().String() == args[1] {
bp = b
break
}
}
} else {
bp = m.debugger.Breakpoint()
Expand All @@ -230,14 +242,21 @@ func (m *debugModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.view = &symbolsDebugView{symbols: sbs}
return m, nil
case "symbol", "sb":
var sb *symbol.Symbol
var sbs []*symbol.Symbol
if len(args) > 1 {
sb = m.findSymbol(args[1])
sbs = m.findSymbols(args[1])
} else {
sbs = []*symbol.Symbol{m.debugger.Symbol()}
}

if len(sbs) == 0 {
m.view = &errDebugView{err: fmt.Errorf("symbol '%s' not found", args[1])}
} else if len(sbs) == 1 {
m.view = &symbolDebugView{symbol: sbs[0]}
} else {
sb = m.debugger.Symbol()
m.view = &symbolsDebugView{symbols: sbs}
}

m.view = &symbolDebugView{symbol: sb}
return m, nil
case "processes", "procs":
procs := m.agent.Processes()
Expand Down Expand Up @@ -299,13 +318,14 @@ func (m *debugModel) nextInput(msg tea.Msg) tea.Cmd {
return cmd
}

func (m *debugModel) findSymbol(key string) *symbol.Symbol {
func (m *debugModel) findSymbols(key string) []*symbol.Symbol {
var symbols []*symbol.Symbol
for _, sb := range m.agent.Symbols() {
if sb.ID().String() == key || sb.Name() == key {
return sb
symbols = append(symbols, sb)
}
}
return nil
return symbols
}

func (m *debugModel) findPort(sb *symbol.Symbol, name string) (*port.InPort, *port.OutPort) {
Expand Down Expand Up @@ -419,7 +439,7 @@ func (v *breakpointDebugView) Interface() map[string]any {
return nil
}

value := map[string]any{"id": v.id}
value := map[string]any{"id": v.breakpoint.ID()}

sb := v.breakpoint.Symbol()
if sb != nil {
Expand Down Expand Up @@ -450,8 +470,8 @@ func (v *breakpointsDebugView) View() string {
writer := resource.NewWriter(buffer)

values := make([]any, 0, len(v.breakpoints))
for i, b := range v.breakpoints {
value := (&breakpointDebugView{id: i, breakpoint: b}).Interface()
for _, b := range v.breakpoints {
value := (&breakpointDebugView{breakpoint: b}).Interface()
values = append(values, value)
}

Expand Down
41 changes: 37 additions & 4 deletions cmd/pkg/cli/debug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestNewDebugger(t *testing.T) {
}

func TestDebugModel_Update(t *testing.T) {
t.Run("break", func(t *testing.T) {
t.Run("break <symbol> <port>", func(t *testing.T) {
a := agent.New()
defer a.Close()

Expand Down Expand Up @@ -65,6 +65,39 @@ func TestDebugModel_Update(t *testing.T) {
assert.Len(t, d.Breakpoints(), 1)
})

t.Run("break", func(t *testing.T) {
a := agent.New()
defer a.Close()

d := debug.NewDebugger(a)
defer d.Close()

m := &debugModel{
input: textinput.New(),
agent: a,
debugger: d,
}

sb := &symbol.Symbol{
Spec: &spec.Meta{
ID: uuid.Must(uuid.NewV7()),
Kind: faker.UUIDHyphenated(),
Namespace: resource.DefaultNamespace,
Name: faker.UUIDHyphenated(),
},
Node: node.NewOneToOneNode(nil),
}
defer sb.Close()

m.agent.Load(sb)
defer m.agent.Unload(sb)

m.input.SetValue("break")
m.Update(tea.KeyMsg{Type: tea.KeyEnter})

assert.Len(t, d.Breakpoints(), 1)
})

t.Run("continue", func(t *testing.T) {
a := agent.New()
defer a.Close()
Expand Down Expand Up @@ -101,7 +134,7 @@ func TestDebugModel_Update(t *testing.T) {
// TODO: assert
})

t.Run("delete", func(t *testing.T) {
t.Run("delete <breakpoint>", func(t *testing.T) {
a := agent.New()
defer a.Close()

Expand Down Expand Up @@ -131,7 +164,7 @@ func TestDebugModel_Update(t *testing.T) {
m.input.SetValue(fmt.Sprintf("break %s %s", sb.Name(), node.PortIn))
m.Update(tea.KeyMsg{Type: tea.KeyEnter})

m.input.SetValue(fmt.Sprintf("delete %d", 0))
m.input.SetValue(fmt.Sprintf("delete %s", d.Breakpoints()[0].ID()))
m.Update(tea.KeyMsg{Type: tea.KeyEnter})

assert.Len(t, d.Breakpoints(), 0)
Expand Down Expand Up @@ -203,7 +236,7 @@ func TestDebugModel_Update(t *testing.T) {
m.input.SetValue(fmt.Sprintf("break %s %s", sb.Name(), node.PortIn))
m.Update(tea.KeyMsg{Type: tea.KeyEnter})

m.input.SetValue(fmt.Sprintf("breakpoint %d", 0))
m.input.SetValue(fmt.Sprintf("breakpoint %s", d.Breakpoints()[0].ID()))
m.Update(tea.KeyMsg{Type: tea.KeyEnter})

assert.Contains(t, m.View(), sb.Name())
Expand Down
20 changes: 15 additions & 5 deletions cmd/pkg/resource/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package resource
import (
"fmt"
"io"
"math"
"slices"
"strings"

Expand Down Expand Up @@ -61,13 +62,18 @@ func (w *Writer) Write(value any) error {
counts[key]++
}
}
sizes := map[string]int{}

scores := map[string]float64{}
for _, element := range elements {
for key, value := range element {
sizes[key] += len(fmt.Sprint(value))
for key, val := range element {
scores[key] += 1.0 / float64(len(fmt.Sprint(val)))
}
}

for key, score := range scores {
scores[key] = score/float64(counts[key]) + 1.0/float64(len(key))
}

var keys []string
for key, count := range counts {
if count >= len(elements)/2 {
Expand All @@ -79,8 +85,12 @@ func (w *Writer) Write(value any) error {
if diff := counts[y] - counts[x]; diff != 0 {
return diff
}
if diff := sizes[x] - sizes[y]; diff != 0 {
return diff
if diff := scores[y] - scores[x]; math.Abs(diff) > 0.1 {
if diff > 0 {
return 1
} else {
return -1
}
}
return strings.Compare(x, y)
})
Expand Down
12 changes: 6 additions & 6 deletions ext/pkg/network/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ const KindHTTP = "http"
// NewHTTPNodeCodec creates a new codec for HTTPNode.
func NewHTTPNodeCodec() scheme.Codec {
return scheme.CodecWithType(func(spec *HTTPNodeSpec) (node.Node, error) {
url, err := url.Parse(spec.URL)
parse, err := url.Parse(spec.URL)
if err != nil {
return nil, err
}

n := NewHTTPNode(url)
n := NewHTTPNode(parse)
n.SetTimeout(spec.Timeout)
return n, nil
})
Expand All @@ -67,7 +67,7 @@ func NewHTTPNodeCodec() scheme.Codec {
// NewHTTPNode creates a new HTTPNode instance.
func NewHTTPNode(url *url.URL) *HTTPNode {
transport := &http.Transport{}
http2.ConfigureTransport(transport)
_ = http2.ConfigureTransport(transport)

client := &http.Client{
Transport: transport,
Expand Down Expand Up @@ -176,10 +176,10 @@ func (n *HTTPNode) action(proc *process.Process, inPck *packet.Packet) (*packet.
}

// NewHTTPPayload creates a new HTTPPayload with the given HTTP status code and optional body.
func NewHTTPPayload(status int, bodys ...types.Value) *HTTPPayload {
func NewHTTPPayload(status int, bodies ...types.Value) *HTTPPayload {
var body types.Value = types.NewString(http.StatusText(status))
if len(bodys) > 0 {
body = bodys[0]
if len(bodies) > 0 {
body = bodies[0]
}
return &HTTPPayload{
Header: http.Header{},
Expand Down
4 changes: 2 additions & 2 deletions ext/pkg/network/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func NewListenNodeCodec() scheme.Codec {
n := NewHTTPListenNode(fmt.Sprintf("%s:%d", spec.Host, spec.Port))
if spec.Cert != "" || spec.Key != "" {
if err := n.TLS(spec.Cert, spec.Key); err != nil {
n.Close()
_ = n.Close()
return nil, err
}
}
Expand Down Expand Up @@ -226,7 +226,7 @@ func (n *HTTPListenNode) ServeHTTP(w http.ResponseWriter, r *http.Request) {

if w, ok := proc.LoadAndDelete(KeyHTTPResponseWriter).(http.ResponseWriter); ok {
n.negotiate(req, res)
n.write(w, res)
_ = n.write(w, res)
}
}

Expand Down
1 change: 0 additions & 1 deletion ext/pkg/network/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package network
import "github.com/pkg/errors"

const ProtocolHTTP = "http"
const ProtocolH2C = "h2c"
const ProtocolWebsocket = "websocket"

var ErrInvalidProtocol = errors.New("protocol is invalid")
Loading

0 comments on commit 258614a

Please sign in to comment.