File: times_linux_test.go

package info (click to toggle)
golang-github-djherbis-times 1.6.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 184 kB
  • sloc: sh: 10; makefile: 3
file content (130 lines) | stat: -rw-r--r-- 2,974 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package times

import (
	"errors"
	"os"
	"sync/atomic"
	"testing"
	"time"

	"golang.org/x/sys/unix"
)

func timeToStatx(t time.Time) unix.StatxTimestamp {
	nsec := time.Duration(t.UnixNano()) * time.Nanosecond
	nsec -= time.Duration(t.Unix()) * time.Second
	return unix.StatxTimestamp{Sec: t.Unix(), Nsec: uint32(nsec)}
}

func statxT(t time.Time, hasBtime bool) *unix.Statx_t {
	var statx unix.Statx_t

	statxt := timeToStatx(t)

	statx.Atime = statxt
	statx.Mtime = statxt
	statx.Ctime = statxt

	if hasBtime {
		statx.Mask = unix.STATX_BTIME
		statx.Btime = statxt
	}

	return &statx
}

type statxFuncTyp func(dirfd int, path string, flags int, mask int, stat *unix.Statx_t) (err error)

func unsupportedStatx(dirfd int, path string, flags int, mask int, stat *unix.Statx_t) (err error) {
	return unix.ENOSYS
}

var errBadStatx = errors.New("bad")

func badStatx(dirfd int, path string, flags int, mask int, stat *unix.Statx_t) (err error) {
	return errBadStatx
}

func fakeSupportedStatx(ts *unix.Statx_t) statxFuncTyp {
	return func(dirfd int, path string, flags int, mask int, stat *unix.Statx_t) (err error) {
		*stat = *ts
		return nil
	}
}

func setStatx(fn statxFuncTyp) func() {
	atomic.StoreInt32(&supportsStatx, 1)
	restoreStatx := statxFunc
	statxFunc = fn
	return func() { statxFunc = restoreStatx }
}

func TestStatx(t *testing.T) {
	tests := []struct {
		name    string
		statx   statxFuncTyp
		wantErr error
	}{
		{name: "unsupported", statx: unsupportedStatx},
		{name: "fake supported with btime", statx: fakeSupportedStatx(statxT(time.Now(), true))},
		{name: "fake supported without btime", statx: fakeSupportedStatx(statxT(time.Now(), false))},
		{name: "bad stat", statx: badStatx, wantErr: errBadStatx},
	}
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			t.Run("stat", func(t *testing.T) {
				restore := setStatx(test.statx)
				defer restore()

				fileAndDirTest(t, func(name string) {
					ts, err := Stat(name)
					if err != nil {
						if err == test.wantErr {
							return
						}
						t.Fatal(err.Error())
					}
					timespecTest(ts, newInterval(time.Now(), time.Second), t)
				})
			})

			t.Run("statFile", func(t *testing.T) {
				restore := setStatx(test.statx)
				defer restore()

				fileAndDirTest(t, func(name string) {
					fi, err := os.Open(name)
					if err != nil {
						t.Fatal(err.Error())
					}
					defer fi.Close()

					ts, err := StatFile(fi)
					if err != nil {
						if err == test.wantErr {
							return
						}
						t.Fatal(err.Error())
					}
					timespecTest(ts, newInterval(time.Now(), time.Second), t)
				})
			})

			t.Run("lstat", func(t *testing.T) {
				restore := setStatx(test.statx)
				defer restore()

				fileAndDirTest(t, func(name string) {
					ts, err := Lstat(name)
					if err != nil {
						if err == test.wantErr {
							return
						}
						t.Fatal(err.Error())
					}
					timespecTest(ts, newInterval(time.Now(), time.Second), t)
				})
			})
		})
	}
}