mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Reduce run time for //test/syscalls:socket_inet_loopback_test_runsc_ptrace.
* Tests are picked for a shard differently. It now picks one test from each block, instead of picking the whole block. This makes the same kind of tests spreads across different shards. * Reduce the number of connect() calls in TCPListenClose. PiperOrigin-RevId: 293019281
This commit is contained in:
+29
-32
@@ -434,43 +434,40 @@ func IsStatic(filename string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// TestBoundsForShard calculates the beginning and end indices for the test
|
||||
// based on the TEST_SHARD_INDEX and TEST_TOTAL_SHARDS environment vars. The
|
||||
// returned ints are the beginning (inclusive) and end (exclusive) of the
|
||||
// subslice corresponding to the shard. If either of the env vars are not
|
||||
// present, then the function will return bounds that include all tests. If
|
||||
// there are more shards than there are tests, then the returned list may be
|
||||
// empty.
|
||||
func TestBoundsForShard(numTests int) (int, int, error) {
|
||||
// TestIndicesForShard returns indices for this test shard based on the
|
||||
// TEST_SHARD_INDEX and TEST_TOTAL_SHARDS environment vars.
|
||||
//
|
||||
// If either of the env vars are not present, then the function will return all
|
||||
// tests. If there are more shards than there are tests, then the returned list
|
||||
// may be empty.
|
||||
func TestIndicesForShard(numTests int) ([]int, error) {
|
||||
var (
|
||||
begin = 0
|
||||
end = numTests
|
||||
shardIndex = 0
|
||||
shardTotal = 1
|
||||
)
|
||||
indexStr, totalStr := os.Getenv("TEST_SHARD_INDEX"), os.Getenv("TEST_TOTAL_SHARDS")
|
||||
if indexStr == "" || totalStr == "" {
|
||||
return begin, end, nil
|
||||
}
|
||||
|
||||
// Parse index and total to ints.
|
||||
shardIndex, err := strconv.Atoi(indexStr)
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("invalid TEST_SHARD_INDEX %q: %v", indexStr, err)
|
||||
}
|
||||
shardTotal, err := strconv.Atoi(totalStr)
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("invalid TEST_TOTAL_SHARDS %q: %v", totalStr, err)
|
||||
indexStr, totalStr := os.Getenv("TEST_SHARD_INDEX"), os.Getenv("TEST_TOTAL_SHARDS")
|
||||
if indexStr != "" && totalStr != "" {
|
||||
// Parse index and total to ints.
|
||||
var err error
|
||||
shardIndex, err = strconv.Atoi(indexStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid TEST_SHARD_INDEX %q: %v", indexStr, err)
|
||||
}
|
||||
shardTotal, err = strconv.Atoi(totalStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid TEST_TOTAL_SHARDS %q: %v", totalStr, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate!
|
||||
shardSize := int(math.Ceil(float64(numTests) / float64(shardTotal)))
|
||||
begin = shardIndex * shardSize
|
||||
end = ((shardIndex + 1) * shardSize)
|
||||
if begin > numTests {
|
||||
// Nothing to run.
|
||||
return 0, 0, nil
|
||||
var indices []int
|
||||
numBlocks := int(math.Ceil(float64(numTests) / float64(shardTotal)))
|
||||
for i := 0; i < numBlocks; i++ {
|
||||
pick := i*shardTotal + shardIndex
|
||||
if pick < numTests {
|
||||
indices = append(indices, pick)
|
||||
}
|
||||
}
|
||||
if end > numTests {
|
||||
end = numTests
|
||||
}
|
||||
return begin, end, nil
|
||||
return indices, nil
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -101,17 +100,15 @@ func getTests(d dockerutil.Docker, blacklist map[string]struct{}) ([]testing.Int
|
||||
// shard.
|
||||
tests := strings.Fields(list)
|
||||
sort.Strings(tests)
|
||||
begin, end, err := testutil.TestBoundsForShard(len(tests))
|
||||
indices, err := testutil.TestIndicesForShard(len(tests))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("TestsForShard() failed: %v", err)
|
||||
}
|
||||
log.Printf("Got bounds [%d:%d) for shard out of %d total tests", begin, end, len(tests))
|
||||
tests = tests[begin:end]
|
||||
|
||||
var itests []testing.InternalTest
|
||||
for _, tc := range tests {
|
||||
for _, tci := range indices {
|
||||
// Capture tc in this scope.
|
||||
tc := tc
|
||||
tc := tests[tci]
|
||||
itests = append(itests, testing.InternalTest{
|
||||
Name: tc,
|
||||
F: func(t *testing.T) {
|
||||
|
||||
@@ -325,6 +325,12 @@ TEST_P(SocketInetLoopbackTest, TCPListenClose) {
|
||||
TestAddress const& listener = param.listener;
|
||||
TestAddress const& connector = param.connector;
|
||||
|
||||
constexpr int kAcceptCount = 32;
|
||||
constexpr int kBacklog = kAcceptCount * 2;
|
||||
constexpr int kFDs = 128;
|
||||
constexpr int kThreadCount = 4;
|
||||
constexpr int kFDsPerThread = kFDs / kThreadCount;
|
||||
|
||||
// Create the listening socket.
|
||||
FileDescriptor listen_fd = ASSERT_NO_ERRNO_AND_VALUE(
|
||||
Socket(listener.family(), SOCK_STREAM, IPPROTO_TCP));
|
||||
@@ -332,7 +338,7 @@ TEST_P(SocketInetLoopbackTest, TCPListenClose) {
|
||||
ASSERT_THAT(bind(listen_fd.get(), reinterpret_cast<sockaddr*>(&listen_addr),
|
||||
listener.addr_len),
|
||||
SyscallSucceeds());
|
||||
ASSERT_THAT(listen(listen_fd.get(), 1001), SyscallSucceeds());
|
||||
ASSERT_THAT(listen(listen_fd.get(), kBacklog), SyscallSucceeds());
|
||||
|
||||
// Get the port bound by the listening socket.
|
||||
socklen_t addrlen = listener.addr_len;
|
||||
@@ -345,9 +351,6 @@ TEST_P(SocketInetLoopbackTest, TCPListenClose) {
|
||||
DisableSave ds; // Too many system calls.
|
||||
sockaddr_storage conn_addr = connector.addr;
|
||||
ASSERT_NO_ERRNO(SetAddrPort(connector.family(), &conn_addr, port));
|
||||
constexpr int kFDs = 2048;
|
||||
constexpr int kThreadCount = 4;
|
||||
constexpr int kFDsPerThread = kFDs / kThreadCount;
|
||||
FileDescriptor clients[kFDs];
|
||||
std::unique_ptr<ScopedThread> threads[kThreadCount];
|
||||
for (int i = 0; i < kFDs; i++) {
|
||||
@@ -371,7 +374,7 @@ TEST_P(SocketInetLoopbackTest, TCPListenClose) {
|
||||
for (int i = 0; i < kThreadCount; i++) {
|
||||
threads[i]->Join();
|
||||
}
|
||||
for (int i = 0; i < 32; i++) {
|
||||
for (int i = 0; i < kAcceptCount; i++) {
|
||||
auto accepted =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Accept(listen_fd.get(), nullptr, nullptr));
|
||||
}
|
||||
|
||||
@@ -450,17 +450,16 @@ func main() {
|
||||
}
|
||||
|
||||
// Get subset of tests corresponding to shard.
|
||||
begin, end, err := testutil.TestBoundsForShard(len(testCases))
|
||||
indices, err := testutil.TestIndicesForShard(len(testCases))
|
||||
if err != nil {
|
||||
fatalf("TestsForShard() failed: %v", err)
|
||||
}
|
||||
testCases = testCases[begin:end]
|
||||
|
||||
// Run the tests.
|
||||
var tests []testing.InternalTest
|
||||
for _, tc := range testCases {
|
||||
for _, tci := range indices {
|
||||
// Capture tc.
|
||||
tc := tc
|
||||
tc := testCases[tci]
|
||||
testName := fmt.Sprintf("%s_%s", tc.Suite, tc.Name)
|
||||
tests = append(tests, testing.InternalTest{
|
||||
Name: testName,
|
||||
|
||||
Reference in New Issue
Block a user