test

package
v0.0.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2025 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AllocationHeaderScenario = TestScenario{
	Name: "allocation header behavior",
	Code: `package main
import (
	"fmt"
	"time"
)

var (
	smallObj  *int64      // 8 bytes - no malloc header
	mediumObj *[16]int64  // 128 bytes - should have malloc header
	largeObj  *[100]int64 // 800 bytes - should have malloc header
)

func main() {
	// Small object (8 bytes) - typically no malloc header
	smallObj = new(int64)
	*smallObj = 12345

	// Medium object (128 bytes) - should include malloc header
	mediumObj = new([16]int64)
	for i := 0; i < 16; i++ {
		mediumObj[i] = int64(i * 10)
	}

	// Large object (800 bytes) - should include malloc header
	largeObj = new([100]int64)
	for i := 0; i < 100; i++ {
		largeObj[i] = int64(i)
	}

	fmt.Println("READY")
	time.Sleep(100 * time.Second)
}
`,
	Expected: &MemoryNode{
		Children: []*MemoryNode{
			{
				Name:  "main.smallObj",
				Size:  ExactValue(16),
				Count: ExactValue(1),
			},
			{
				Name:  "main.mediumObj",
				Size:  ExactValue(128),
				Count: ExactValue(1),
			},
			{
				Name:  "main.largeObj",
				Size:  ExactValue(896),
				Count: ExactValue(1),
			},
		},
	},
	Timeout: 30 * time.Second,
}

AllocationHeaderScenario tests allocation header behavior with different object sizes

View Source
var ChannelScenario = TestScenario{
	Name: "channel references",
	Code: `package main
import (
	"fmt"
	"time"
)

type Message struct {
	ID   int64
	Text string
}

var globalStringChan chan string
var globalMessageChan chan *Message

func main() {
	// Create channels and assign to globals to force heap allocation
	globalStringChan = make(chan string, 10)
	globalMessageChan = make(chan *Message, 5)

	// Create message objects
	msg1 := &Message{
		ID:   1001,
		Text: "Hello",
	}
	msg2 := &Message{
		ID:   1002,
		Text: "World",
	}

	// Send messages to channels
	go func() {
		globalStringChan <- "test string"
		globalMessageChan <- msg1
		globalMessageChan <- msg2
	}()

	fmt.Println("READY")
	time.Sleep(100 * time.Second)
}
`,
	Expected: &MemoryNode{
		Children: []*MemoryNode{
			{
				Name:  "main.globalStringChan",
				Size:  RangeValue(256, 272),
				Count: ExactValue(2),
			},
			{
				Name:  "main.globalMessageChan",
				Size:  RangeValue(144, 160),
				Count: ExactValue(2),
				Children: []*MemoryNode{
					{
						Name:  "[0]",
						Size:  ExactValue(24),
						Count: ExactValue(1),
						Type:  "*main.Message",
					},
					{
						Name:  "[1]",
						Size:  ExactValue(24),
						Count: ExactValue(1),
						Type:  "*main.Message",
					},
				},
			},
		},
	},
	Timeout: 30 * time.Second,
}

ChannelScenario tests channel references

View Source
var CircularReferenceScenario = TestScenario{
	Name: "circular reference behavior",
	Code: `package main
import (
	"fmt"
	"time"
)

type Node struct {
	ID   int
	Next *Node
}

var node1, node2 *Node

func main() {
	// Create two nodes that reference each other
	node1 = &Node{ID: 1}
	node2 = &Node{ID: 2}

	// Create simple circular reference
	node1.Next = node2
	node2.Next = node1

	fmt.Println("READY")
	time.Sleep(100 * time.Second)
}
`,
	Expected: &MemoryNode{
		Children: []*MemoryNode{
			{
				Name:  "main.node1",
				Size:  ExactValue(16),
				Count: ExactValue(1),
				Children: []*MemoryNode{
					{
						Name:  "Next",
						Size:  ExactValue(16),
						Count: ExactValue(1),
						Type:  "*main.Node",
					},
				},
			},
		},
	},
	Timeout: 30 * time.Second,
}

CircularReferenceScenario tests circular reference behavior

View Source
var ClosureScenario = TestScenario{
	Name: "closure variable capture",
	Code: `package main
import (
	"fmt"
	"time"
)

func main() {
	// Create a variable that will be captured by closure
	capturedValue := 42

	// Create closure that captures the variable
	globalClosure := func() {
		fmt.Printf("Captured value: %d\n", capturedValue)
	}

	fmt.Println("READY")
	time.Sleep(100 * time.Second)

	// Call the closure to prevent optimization
	go globalClosure()
}
`,
	Expected: &MemoryNode{
		Children: []*MemoryNode{
			{
				Name:  "main.main.globalClosure",
				Size:  ExactValue(16),
				Count: ExactValue(1),
			},
		},
	},
	Timeout: 30 * time.Second,
}

ClosureScenario tests closure variable capture and memory references

View Source
var FieldLockScenario = TestScenario{
	Name: "field reference locking",
	Code: `package main
import (
	"fmt"
	"time"
)

type LargeStruct struct {
	ID     int
	Name   string
	Data   [100]byte
	Flag   bool
}

var fieldPtr *int

func main() {
	// Create a large struct
	localStruct := &LargeStruct{
		ID:   123,
		Name: "large struct",
	}
	for i := 0; i < 100; i++ {
		localStruct.Data[i] = byte(i)
	}

	// Create a pointer to a field, which should lock the entire struct
	fieldPtr = &localStruct.ID

	fmt.Println("READY")
	time.Sleep(100 * time.Second)
}
`,
	Expected: &MemoryNode{
		Children: []*MemoryNode{
			{
				Name:  "main.fieldPtr",
				Size:  ExactValue(128),
				Count: ExactValue(1),
			},
		},
	},
	Timeout: 30 * time.Second,
}

FieldLockScenario tests field reference locking entire struct

View Source
var FinalizerScenario = TestScenario{
	Name: "finalizer function references",
	Code: `package main
import (
	"fmt"
	"runtime"
	"time"
)

type ToFin struct {
	data [100]int64
	next *ToFin
}

func main() {
	// Create object with finalizer
	obj := &ToFin{
		data: [100]int64{1, 2, 3, 4, 5},
	}

	// Create a separate object for finalizer to reference
	finTarget := &ToFin{
		data: [100]int64{9, 8, 7, 6, 5},
	}

	// Set finalizer that references finTarget
	runtime.SetFinalizer(obj, func(*ToFin) {
		// Reference finTarget to prevent optimization
		_ = finTarget.data[0]
		fmt.Printf("Finalizer called\n")
	})

	fmt.Println("READY")
	time.Sleep(100 * time.Second)

	// Keep objects alive
	runtime.KeepAlive(obj)
	runtime.KeepAlive(finTarget)
}
`,
	Expected: &MemoryNode{
		Children: []*MemoryNode{
			{
				Name:  "main.main.finTarget",
				Size:  ExactValue(896),
				Count: ExactValue(1),
			},
			{
				Name:  "main.main.obj",
				Size:  ExactValue(896),
				Count: ExactValue(1),
			},
		},
	},
	Timeout: 30 * time.Second,
}

FinalizerScenario tests finalizer function references

View Source
var GlobalMapScenario = TestScenario{
	Name: "global map",
	Code: `package main
import (
	"fmt"
	"time"
)

var globalMap map[string]string

func main() {
	// Initialize global map in main to ensure heap allocation
	globalMap = make(map[string]string)
	globalMap[time.Now().String()] = time.Now().String()
	globalMap[time.Now().String()] = time.Now().String()
	globalMap[time.Now().String()] = time.Now().String()

	fmt.Println("READY")
	time.Sleep(100 * time.Second)
}
`,
	Expected: &MemoryNode{
		Children: []*MemoryNode{
			{
				Name:  "main.globalMap",
				Size:  ExactValue(336),
				Count: ExactValue(2),
				Children: []*MemoryNode{
					{
						Name:  "$mapkey",
						Type:  "string",
						Size:  ExactValue(192),
						Count: ExactValue(3),
					},
					{
						Name:  "$mapval",
						Type:  "string",
						Size:  ExactValue(192),
						Count: ExactValue(3),
					},
				},
			},
		},
	},
	Timeout: 30 * time.Second,
}

GlobalMapScenario tests global map and its key/value internal fields

View Source
var GlobalSliceScenario = TestScenario{
	Name: "global slice",
	Code: `package main
import (
	"fmt"
	"time"
)

var globalSlice []int
var globalArray *[5]int

func main() {
	// Initialize global slice in main to ensure heap allocation
	globalSlice = make([]int, 5)

	// Initialize global array pointer in main to ensure heap allocation
	globalArray = new([5]int)

	fmt.Println("READY")
	time.Sleep(100 * time.Second)
}
`,
	Expected: &MemoryNode{
		Children: []*MemoryNode{
			{
				Name:  "main.globalSlice",
				Size:  ExactValue(48),
				Count: ExactValue(1),
			},
			{
				Name:  "main.globalArray",
				Size:  ExactValue(48),
				Count: ExactValue(1),
			},
		},
	},
	Timeout: 30 * time.Second,
}

GlobalSliceScenario tests global slice and its internal fields

View Source
var GlobalStructScenario = TestScenario{
	Name: "global struct",
	Code: `package main
import (
	"fmt"
	"time"
)

type Data struct {
	ID   int
	Name string
	Ptr  *int
}

var globalStruct *Data

func main() {
	// Initialize global struct in main to ensure heap allocation
	globalStruct = &Data{
		ID:   123,
		Name: "test",
	}
	globalStruct.Ptr = new(int)
	*globalStruct.Ptr = 456

	fmt.Println("READY")
	time.Sleep(100 * time.Second)
}
`,
	Expected: &MemoryNode{
		Children: []*MemoryNode{
			{
				Name:  "main.globalStruct",
				Size:  ExactValue(32),
				Count: ExactValue(1),
				Children: []*MemoryNode{
					{
						Name:  "Ptr",
						Size:  ExactValue(16),
						Count: ExactValue(1),
						Type:  "*int",
					},
				},
			},
		},
	},
	Timeout: 30 * time.Second,
}

GlobalStructScenario tests global struct and field-level references

View Source
var InterfaceScenario = TestScenario{
	Name: "interface variable references",
	Code: `package main
import (
	"fmt"
	"time"
)

type Data struct {
	ID   int64
	Name string
}

type Writer interface {
	Write(data string) error
}

type FileWriter struct {
	fileData *Data
}

func (fw *FileWriter) Write(data string) error {
	// Simulate writing to file
	return nil
}

var globalWriter Writer

func main() {
	// Create interface variable and assign to global to force heap allocation
	globalWriter = &FileWriter{}

	// Create data objects
	data := &Data{
		ID:   12345,
		Name: "test data 1",
	}

	// Store interface reference to data
	globalWriter.(*FileWriter).fileData = data

	fmt.Println("READY")
	time.Sleep(100 * time.Second)
}
`,
	Expected: &MemoryNode{
		Children: []*MemoryNode{
			{
				Name:  "main.globalWriter",
				Size:  ExactValue(8),
				Count: ExactValue(1),
				Children: []*MemoryNode{
					{
						Name:  "fileData",
						Size:  ExactValue(24),
						Count: ExactValue(1),
						Type:  "*main.Data",
					},
				},
			},
		},
	},
	Timeout: 30 * time.Second,
}

InterfaceScenario tests interface variable references

View Source
var LocalSliceAllocationScenario = TestScenario{
	Name: "local slice allocation",
	Code: `package main
import (
	"fmt"
	"time"
	"runtime"
)
func main() {
	globalSlice := []int{1, 2, 3, 4, 5, 6}

	fmt.Println("READY")

	time.Sleep(100 * time.Second)

	go func() {
		runtime.KeepAlive(globalSlice)
	}()
}
`,
	Expected: &MemoryNode{
		Children: []*MemoryNode{
			{
				Name:  "main.main.globalSlice",
				Size:  ExactValue(48),
				Count: ExactValue(1),
			},
		},
	},
	Timeout: 30 * time.Second,
}

LocalSliceAllocationScenario tests local slice allocation

View Source
var LocalStringScenario = TestScenario{
	Name: "local string allocation",
	Code: `package main
import (
	"fmt"
	"time"
	"runtime"
)

func main() {
	localString := new(string)
	*localString = time.Now().String()

	fmt.Println("READY")
	time.Sleep(100 * time.Second)

	go func() {
		runtime.KeepAlive(localString)
	}()
}
`,
	Expected: &MemoryNode{
		Children: []*MemoryNode{
			{
				Name:  "main.main.localString",
				Size:  ExactValue(80),
				Count: ExactValue(2),
			},
		},
	},
	Timeout: 30 * time.Second,
}

LocalStringScenario tests local string allocation

View Source
var NestedStructScenario = TestScenario{
	Name: "nested struct field references",
	Code: `package main
import (
	"fmt"
	"time"
)

type InnerData struct {
	ID   int64
	Name string
}

type MiddleStruct struct {
	Inner     *InnerData
	Count     int
	Timestamp int64
}

type OuterStruct struct {
	Middle    *MiddleStruct
	Version   string
	IsActive  bool
}

var globalOuter *OuterStruct

func main() {
	// Create deeply nested struct
	globalOuter = &OuterStruct{
		Middle: &MiddleStruct{
			Inner: &InnerData{
				ID:   12345,
				Name: "nested data",
			},
			Count:     999,
			Timestamp: time.Now().Unix(),
		},
		Version:  "v1.0.0",
		IsActive: true,
	}

	fmt.Println("READY")
	time.Sleep(100 * time.Second)
}
`,
	Expected: &MemoryNode{
		Children: []*MemoryNode{
			{
				Name:  "main.globalOuter",
				Size:  ExactValue(32),
				Count: ExactValue(1),
				Children: []*MemoryNode{
					{
						Name:  "Middle",
						Size:  ExactValue(24),
						Count: ExactValue(1),
						Type:  "*main.MiddleStruct",
						Children: []*MemoryNode{
							{
								Name:  "Inner",
								Size:  ExactValue(24),
								Count: ExactValue(1),
								Type:  "*main.InnerData",
							},
						},
					},
				},
			},
		},
	},
	Timeout: 30 * time.Second,
}

NestedStructScenario tests deeply nested struct field references

Functions

This section is empty.

Types

type MemoryNode

type MemoryNode struct {
	Name     string        `json:"name,omitempty"`     // Node name (e.g., "main.globalSlice", "main.globalSlice[0]")
	Type     string        `json:"type,omitempty"`     // Type information (e.g., "[]int", "*main.Data")
	Size     *ValueRange   `json:"size,omitempty"`     // Memory size in bytes with flexible validation
	Count    *ValueRange   `json:"count,omitempty"`    // Number of objects with flexible validation
	Children []*MemoryNode `json:"children,omitempty"` // Child nodes
}

MemoryNode represents a node in the memory reference tree

type ProfileNodeInterface

type ProfileNodeInterface interface {
	GetCount() int64
	GetSize() int64
}

ProfileNodeInterface defines the interface for accessing profile node data

type TestFramework

type TestFramework struct {
	// contains filtered or unexported fields
}

TestFramework manages integration test execution

func NewTestFramework

func NewTestFramework(t *testing.T) *TestFramework

NewTestFramework creates a new test framework instance

func (*TestFramework) AddScenario

func (tf *TestFramework) AddScenario(scenario TestScenario)

AddScenario adds a test scenario to the framework

func (*TestFramework) RunAll

func (tf *TestFramework) RunAll()

RunAll runs all registered test scenarios

type TestProgram

type TestProgram struct {
	Name      string
	Binary    string
	Cmd       *exec.Cmd
	ReadyChan chan struct{}
}

TestProgram represents a test program instance

func (*TestProgram) GetPID

func (tp *TestProgram) GetPID() int

GetPID returns the process ID

func (*TestProgram) Start

func (tp *TestProgram) Start() error

Start starts the test program

func (*TestProgram) Stop

func (tp *TestProgram) Stop() error

Stop stops the test program

func (*TestProgram) WaitForReady

func (tp *TestProgram) WaitForReady() error

WaitForReady waits for the program to be ready for attach

type TestScenario

type TestScenario struct {
	Name     string
	Code     string
	Expected *MemoryNode
	Timeout  time.Duration
}

TestScenario defines a complete test scenario

type ValueRange

type ValueRange struct {
	Exact  *int64 // Exact value match (for backward compatibility)
	Min    *int64 // Minimum value (inclusive)
	Max    *int64 // Maximum value (inclusive)
	Approx *int64 // Approximate value with ±10% tolerance
}

ValueRange represents a value that can be validated against different criteria

func ApproxValue

func ApproxValue(expected int64) *ValueRange

ApproxValue creates a ValueRange that accepts values within ±10% of expected

func ExactValue

func ExactValue(value int64) *ValueRange

ExactValue creates a ValueRange that requires exact match

func MinValue

func MinValue(min int64) *ValueRange

MinValue creates a ValueRange that accepts values >= min

func RangeValue

func RangeValue(min, max int64) *ValueRange

RangeValue creates a ValueRange that accepts values in [min, max] range

func (*ValueRange) Matches

func (vr *ValueRange) Matches(actual int64) bool

Matches checks if the actual value matches the criteria defined in ValueRange

func (*ValueRange) String

func (vr *ValueRange) String() string

String returns a human-readable representation of the ValueRange

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL