summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/ext/disklayout/inode_test.go
diff options
context:
space:
mode:
authorAyush Ranjan <ayushranjan@google.com>2019-07-11 15:04:23 -0700
committergVisor bot <gvisor-bot@google.com>2019-07-11 15:05:36 -0700
commit5242face2eea968f5e3f367f7edfebdd3ae60430 (patch)
treed9f257d50b35fa179542300e8b9c98634952ac54 /pkg/sentry/fs/ext/disklayout/inode_test.go
parenta018b229b57dff92ca0d99079180aa556dacbabc (diff)
ext: boilerplate code.
Renamed ext4 to ext since we are targeting ext(2/3/4). Removed fs.go since we are targeting VFS2. Added ext.go with filesystem struct. PiperOrigin-RevId: 257689775
Diffstat (limited to 'pkg/sentry/fs/ext/disklayout/inode_test.go')
-rw-r--r--pkg/sentry/fs/ext/disklayout/inode_test.go222
1 files changed, 222 insertions, 0 deletions
diff --git a/pkg/sentry/fs/ext/disklayout/inode_test.go b/pkg/sentry/fs/ext/disklayout/inode_test.go
new file mode 100644
index 000000000..9cae9e4f0
--- /dev/null
+++ b/pkg/sentry/fs/ext/disklayout/inode_test.go
@@ -0,0 +1,222 @@
+// Copyright 2019 The gVisor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package disklayout
+
+import (
+ "fmt"
+ "strconv"
+ "testing"
+
+ "gvisor.dev/gvisor/pkg/sentry/kernel/time"
+)
+
+// TestInodeSize tests that the inode structs are of the correct size.
+func TestInodeSize(t *testing.T) {
+ assertSize(t, InodeOld{}, oldInodeSize)
+
+ // This was updated from 156 bytes to 160 bytes in Oct 2015.
+ assertSize(t, InodeNew{}, 160)
+}
+
+// TestTimestampSeconds tests that the seconds part of [a/c/m] timestamps in
+// ext4 inode structs are decoded correctly.
+//
+// These tests are derived from the table under https://www.kernel.org/doc/html/latest/filesystems/ext4/dynamic.html#inode-timestamps.
+func TestTimestampSeconds(t *testing.T) {
+ type timestampTest struct {
+ // msbSet tells if the most significant bit of InodeOld.[X]TimeRaw is set.
+ // If this is set then the 32-bit time is negative.
+ msbSet bool
+
+ // lowerBound tells if we should take the lowest possible value of
+ // InodeOld.[X]TimeRaw while satisfying test.msbSet condition. If set to
+ // false it tells to take the highest possible value.
+ lowerBound bool
+
+ // extraBits is InodeNew.[X]TimeExtra.
+ extraBits uint32
+
+ // want is the kernel time struct that is expected.
+ want time.Time
+ }
+
+ tests := []timestampTest{
+ // 1901-12-13
+ {
+ msbSet: true,
+ lowerBound: true,
+ extraBits: 0,
+ want: time.FromUnix(int64(-0x80000000), 0),
+ },
+
+ // 1969-12-31
+ {
+ msbSet: true,
+ lowerBound: false,
+ extraBits: 0,
+ want: time.FromUnix(int64(-1), 0),
+ },
+
+ // 1970-01-01
+ {
+ msbSet: false,
+ lowerBound: true,
+ extraBits: 0,
+ want: time.FromUnix(int64(0), 0),
+ },
+
+ // 2038-01-19
+ {
+ msbSet: false,
+ lowerBound: false,
+ extraBits: 0,
+ want: time.FromUnix(int64(0x7fffffff), 0),
+ },
+
+ // 2038-01-19
+ {
+ msbSet: true,
+ lowerBound: true,
+ extraBits: 1,
+ want: time.FromUnix(int64(0x80000000), 0),
+ },
+
+ // 2106-02-07
+ {
+ msbSet: true,
+ lowerBound: false,
+ extraBits: 1,
+ want: time.FromUnix(int64(0xffffffff), 0),
+ },
+
+ // 2106-02-07
+ {
+ msbSet: false,
+ lowerBound: true,
+ extraBits: 1,
+ want: time.FromUnix(int64(0x100000000), 0),
+ },
+
+ // 2174-02-25
+ {
+ msbSet: false,
+ lowerBound: false,
+ extraBits: 1,
+ want: time.FromUnix(int64(0x17fffffff), 0),
+ },
+
+ // 2174-02-25
+ {
+ msbSet: true,
+ lowerBound: true,
+ extraBits: 2,
+ want: time.FromUnix(int64(0x180000000), 0),
+ },
+
+ // 2242-03-16
+ {
+ msbSet: true,
+ lowerBound: false,
+ extraBits: 2,
+ want: time.FromUnix(int64(0x1ffffffff), 0),
+ },
+
+ // 2242-03-16
+ {
+ msbSet: false,
+ lowerBound: true,
+ extraBits: 2,
+ want: time.FromUnix(int64(0x200000000), 0),
+ },
+
+ // 2310-04-04
+ {
+ msbSet: false,
+ lowerBound: false,
+ extraBits: 2,
+ want: time.FromUnix(int64(0x27fffffff), 0),
+ },
+
+ // 2310-04-04
+ {
+ msbSet: true,
+ lowerBound: true,
+ extraBits: 3,
+ want: time.FromUnix(int64(0x280000000), 0),
+ },
+
+ // 2378-04-22
+ {
+ msbSet: true,
+ lowerBound: false,
+ extraBits: 3,
+ want: time.FromUnix(int64(0x2ffffffff), 0),
+ },
+
+ // 2378-04-22
+ {
+ msbSet: false,
+ lowerBound: true,
+ extraBits: 3,
+ want: time.FromUnix(int64(0x300000000), 0),
+ },
+
+ // 2446-05-10
+ {
+ msbSet: false,
+ lowerBound: false,
+ extraBits: 3,
+ want: time.FromUnix(int64(0x37fffffff), 0),
+ },
+ }
+
+ lowerMSB0 := int32(0) // binary: 00000000 00000000 00000000 00000000
+ upperMSB0 := int32(0x7fffffff) // binary: 01111111 11111111 11111111 11111111
+ lowerMSB1 := int32(-0x80000000) // binary: 10000000 00000000 00000000 00000000
+ upperMSB1 := int32(-1) // binary: 11111111 11111111 11111111 11111111
+
+ get32BitTime := func(test timestampTest) int32 {
+ if test.msbSet {
+ if test.lowerBound {
+ return lowerMSB1
+ }
+
+ return upperMSB1
+ }
+
+ if test.lowerBound {
+ return lowerMSB0
+ }
+
+ return upperMSB0
+ }
+
+ getTestName := func(test timestampTest) string {
+ return fmt.Sprintf(
+ "Tests time decoding with epoch bits 0b%s and 32-bit raw time: MSB set=%t, lower bound=%t",
+ strconv.FormatInt(int64(test.extraBits), 2),
+ test.msbSet,
+ test.lowerBound,
+ )
+ }
+
+ for _, test := range tests {
+ t.Run(getTestName(test), func(t *testing.T) {
+ if got := fromExtraTime(get32BitTime(test), test.extraBits); got != test.want {
+ t.Errorf("Expected: %v, Got: %v", test.want, got)
+ }
+ })
+ }
+}