Skip to content

Commit

Permalink
runtime: add tests for addrRanges.findSucc
Browse files Browse the repository at this point in the history
This change adds a test suite for addrRanges.findSucc so we can change
the implementation more safely.

For #40191.

Change-Id: I14a834b6d54836cbc676eb0edb292ba6176705cc
Reviewed-on: https://go-review.googlesource.com/c/go/+/242678
Trust: Michael Knyszek <[email protected]>
Run-TryBot: Michael Knyszek <[email protected]>
TryBot-Result: Go Bot <[email protected]>
Reviewed-by: Austin Clements <[email protected]>
Reviewed-by: Michael Pratt <[email protected]>
  • Loading branch information
mknyszek committed Oct 23, 2020
1 parent 9db7db5 commit e01a1c0
Show file tree
Hide file tree
Showing 2 changed files with 196 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/runtime/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,30 @@ func (a AddrRange) Equals(b AddrRange) bool {
return a == b
}

// AddrRanges is a wrapper around addrRanges for testing.
type AddrRanges struct {
addrRanges
}

// MakeAddrRanges creates a new addrRanges populated with
// the ranges in a.
func MakeAddrRanges(a ...AddrRange) AddrRanges {
// Methods that manipulate the backing store of addrRanges.ranges should
// not be used on the result from this function (e.g. add) since they may
// trigger reallocation.
ranges := make([]addrRange, 0, len(a))
for _, r := range a {
ranges = append(ranges, r.addrRange)
}
return AddrRanges{addrRanges{ranges: ranges, sysStat: new(uint64)}}
}

// FindSucc returns the successor to base. See addrRanges.findSucc
// for more details.
func (a *AddrRanges) FindSucc(base uintptr) int {
return a.findSucc(base)
}

// BitRange represents a range over a bitmap.
type BitRange struct {
I, N uint // bit index and length in bits
Expand Down
172 changes: 172 additions & 0 deletions src/runtime/mranges_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime_test

import (
. "runtime"
"testing"
)

func TestAddrRangesFindSucc(t *testing.T) {
var large []AddrRange
for i := 0; i < 100; i++ {
large = append(large, MakeAddrRange(5+uintptr(i)*5, 5+uintptr(i)*5+3))
}

type testt struct {
name string
base uintptr
expect int
ranges []AddrRange
}
tests := []testt{
{
name: "Empty",
base: 12,
expect: 0,
ranges: []AddrRange{},
},
{
name: "OneBefore",
base: 12,
expect: 0,
ranges: []AddrRange{
MakeAddrRange(14, 16),
},
},
{
name: "OneWithin",
base: 14,
expect: 1,
ranges: []AddrRange{
MakeAddrRange(14, 16),
},
},
{
name: "OneAfterLimit",
base: 16,
expect: 1,
ranges: []AddrRange{
MakeAddrRange(14, 16),
},
},
{
name: "OneAfter",
base: 17,
expect: 1,
ranges: []AddrRange{
MakeAddrRange(14, 16),
},
},
{
name: "ThreeBefore",
base: 3,
expect: 0,
ranges: []AddrRange{
MakeAddrRange(6, 10),
MakeAddrRange(12, 16),
MakeAddrRange(19, 22),
},
},
{
name: "ThreeAfter",
base: 24,
expect: 3,
ranges: []AddrRange{
MakeAddrRange(6, 10),
MakeAddrRange(12, 16),
MakeAddrRange(19, 22),
},
},
{
name: "ThreeBetween",
base: 11,
expect: 1,
ranges: []AddrRange{
MakeAddrRange(6, 10),
MakeAddrRange(12, 16),
MakeAddrRange(19, 22),
},
},
{
name: "ThreeWithin",
base: 9,
expect: 1,
ranges: []AddrRange{
MakeAddrRange(6, 10),
MakeAddrRange(12, 16),
MakeAddrRange(19, 22),
},
},
{
name: "Zero",
base: 0,
expect: 1,
ranges: []AddrRange{
MakeAddrRange(0, 10),
},
},
{
name: "Max",
base: ^uintptr(0),
expect: 1,
ranges: []AddrRange{
MakeAddrRange(^uintptr(0)-5, ^uintptr(0)),
},
},
{
name: "LargeBefore",
base: 2,
expect: 0,
ranges: large,
},
{
name: "LargeAfter",
base: 5 + uintptr(len(large))*5 + 30,
expect: len(large),
ranges: large,
},
{
name: "LargeBetweenLow",
base: 14,
expect: 2,
ranges: large,
},
{
name: "LargeBetweenHigh",
base: 249,
expect: 49,
ranges: large,
},
{
name: "LargeWithinLow",
base: 25,
expect: 5,
ranges: large,
},
{
name: "LargeWithinHigh",
base: 396,
expect: 79,
ranges: large,
},
{
name: "LargeWithinMiddle",
base: 250,
expect: 50,
ranges: large,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
a := MakeAddrRanges(test.ranges...)
i := a.FindSucc(test.base)
if i != test.expect {
t.Fatalf("expected %d, got %d", test.expect, i)
}
})
}
}

0 comments on commit e01a1c0

Please sign in to comment.