blob: 592c0e6af03d25525a1060ab494542c9f1f7760b [file] [log] [blame]
Tobias Klauserd6ba46b2019-06-21 14:15:26 +02001// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Russ Cox9a761022021-02-19 22:57:36 -05005//go:build darwin || dragonfly || freebsd || openbsd || netbsd
Yuval Pavel Zholkovera26fa112019-06-21 21:09:53 +03006// +build darwin dragonfly freebsd openbsd netbsd
Tobias Klauserd6ba46b2019-06-21 14:15:26 +02007
8package unix_test
9
10import (
11 "fmt"
12 "io/ioutil"
13 "os"
14 "path/filepath"
15 "sort"
16 "strings"
17 "testing"
Tobias Klauserd6ba46b2019-06-21 14:15:26 +020018
19 "golang.org/x/sys/unix"
20)
21
22func TestGetdirentries(t *testing.T) {
23 for _, count := range []int{10, 1000} {
24 t.Run(fmt.Sprintf("n=%d", count), func(t *testing.T) {
25 testGetdirentries(t, count)
26 })
27 }
28}
29func testGetdirentries(t *testing.T, count int) {
30 if count > 100 && testing.Short() && os.Getenv("GO_BUILDER_NAME") == "" {
31 t.Skip("skipping in -short mode")
32 }
33 d, err := ioutil.TempDir("", "getdirentries-test")
34 if err != nil {
35 t.Fatalf("Tempdir: %v", err)
36 }
37 defer os.RemoveAll(d)
38 var names []string
39 for i := 0; i < count; i++ {
40 names = append(names, fmt.Sprintf("file%03d", i))
41 }
42
43 // Make files in the temp directory
44 for _, name := range names {
45 err := ioutil.WriteFile(filepath.Join(d, name), []byte("data"), 0)
46 if err != nil {
47 t.Fatalf("WriteFile: %v", err)
48 }
49 }
50
51 // Read files using Getdirentries
Tobias Klauserd6ba46b2019-06-21 14:15:26 +020052 fd, err := unix.Open(d, unix.O_RDONLY, 0)
53 if err != nil {
54 t.Fatalf("Open: %v", err)
55 }
56 defer unix.Close(fd)
57 var base uintptr
58 var buf [2048]byte
Tobias Klausere93b9632019-06-24 10:12:38 +020059 names2 := make([]string, 0, count)
Tobias Klauserd6ba46b2019-06-21 14:15:26 +020060 for {
61 n, err := unix.Getdirentries(fd, buf[:], &base)
62 if err != nil {
63 t.Fatalf("Getdirentries: %v", err)
64 }
65 if n == 0 {
66 break
67 }
68 data := buf[:n]
69 for len(data) > 0 {
Tobias Klausere93b9632019-06-24 10:12:38 +020070 var bc int
71 bc, _, names2 = unix.ParseDirent(data, -1, names2)
72 if bc == 0 && len(data) > 0 {
73 t.Fatal("no progress")
Tobias Klauserd6ba46b2019-06-21 14:15:26 +020074 }
Tobias Klausere93b9632019-06-24 10:12:38 +020075 data = data[bc:]
Tobias Klauserd6ba46b2019-06-21 14:15:26 +020076 }
77 }
78
Tobias Klauserd6ba46b2019-06-21 14:15:26 +020079 sort.Strings(names)
80 sort.Strings(names2)
81 if strings.Join(names, ":") != strings.Join(names2, ":") {
82 t.Errorf("names don't match\n names: %q\nnames2: %q", names, names2)
83 }
84}