blob: 8617231b03225574c7c3aa1d0dfb0d75b6d02611 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package com.google.devtools.build.lib.unix;
15
Ulf Adams795895a2015-03-06 15:58:35 +000016import static com.google.common.truth.Truth.assertThat;
ajmichaelad32f622018-02-09 10:19:29 -080017import static java.nio.charset.StandardCharsets.UTF_8;
michajlo660d17f2020-03-27 09:01:57 -070018import static org.junit.Assert.assertThrows;
Philipp Wollermann1d503752015-06-30 16:36:01 +000019import static org.junit.Assert.fail;
ajmichaelad32f622018-02-09 10:19:29 -080020import static org.junit.Assume.assumeTrue;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010021
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010022import com.google.devtools.build.lib.testutil.TestUtils;
ajmichaelad32f622018-02-09 10:19:29 -080023import com.google.devtools.build.lib.util.OS;
ccalvarin87943082018-08-20 06:56:54 -070024import com.google.devtools.build.lib.vfs.DigestHashFunction;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010025import com.google.devtools.build.lib.vfs.FileSystem;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010026import com.google.devtools.build.lib.vfs.Path;
Philipp Wollermanne219a242016-08-18 14:39:37 +000027import java.io.File;
28import java.io.FileNotFoundException;
29import java.io.IOException;
ajmichaelad32f622018-02-09 10:19:29 -080030import java.nio.file.Files;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010031import org.junit.Before;
32import org.junit.Test;
33import org.junit.runner.RunWith;
34import org.junit.runners.JUnit4;
35
Benjamin Petersonbe9fbec2019-03-27 05:25:18 -070036/** Tests for the {@link NativePosixFiles} class. */
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010037@RunWith(JUnit4.class)
Lukacs Berki7ecb2ce2016-01-26 15:40:42 +000038public class NativePosixFilesTest {
Ed Schouten05650ff2020-09-17 10:01:25 -070039
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010040 private Path workingDir;
41 private Path testFile;
42
43 @Before
Florian Weikertc4975fa2015-12-03 10:27:10 +000044 public final void createFileSystem() throws Exception {
Ed Schouten05650ff2020-09-17 10:01:25 -070045 FileSystem testFS = new UnixFileSystem(DigestHashFunction.SHA256, /*hashAttributeName=*/ "");
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010046 workingDir = testFS.getPath(new File(TestUtils.tmpDir()).getCanonicalPath());
47 testFile = workingDir.getRelative("test");
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010048 }
49
Philipp Wollermann1d503752015-06-30 16:36:01 +000050 @Test
51 public void throwsFileNotFoundException() throws Exception {
jcater6cfebc92019-05-01 12:40:08 -070052 FileNotFoundException e =
53 assertThrows(
Googler541f0562019-10-10 13:41:38 -070054 FileNotFoundException.class, () -> NativePosixFiles.stat(testFile.getPathString()));
jcater6cfebc92019-05-01 12:40:08 -070055 assertThat(e).hasMessageThat().isEqualTo(testFile + " (No such file or directory)");
Philipp Wollermann1d503752015-06-30 16:36:01 +000056 }
57
58 @Test
59 public void throwsFilePermissionException() throws Exception {
60 File foo = new File("/bin");
61 try {
jmmv8d24345c2019-04-09 09:41:21 -070062 NativePosixFiles.chmod(
63 foo.getPath(),
64 NativePosixFiles.lstat(foo.getPath()).getPermissions() | FileStatus.S_IWUSR);
Philipp Wollermanne219a242016-08-18 14:39:37 +000065 fail("Expected FilePermissionException or IOException, but wasn't thrown.");
Philipp Wollermannc3228f42015-06-30 16:54:55 +000066 } catch (FilePermissionException e) {
diamondmad04da62019-03-19 09:54:50 -070067 assertThat(e).hasMessageThat().isEqualTo(foo + " (Operation not permitted)");
Philipp Wollermanne219a242016-08-18 14:39:37 +000068 } catch (IOException e) {
69 // When running in a sandbox, /bin might actually be a read-only file system.
diamondmad04da62019-03-19 09:54:50 -070070 assertThat(e).hasMessageThat().isEqualTo(foo + " (Read-only file system)");
Philipp Wollermann1d503752015-06-30 16:36:01 +000071 }
72 }
ajmichaelad32f622018-02-09 10:19:29 -080073
74 /** Skips the test if the file system does not support extended attributes. */
75 private static void assumeXattrsSupported() throws Exception {
76 // The standard file systems on macOS support extended attributes by default, so we can assume
77 // that the test will work on that platform. For other systems, we currently don't have a
78 // mechanism to validate this so the tests are skipped unconditionally.
79 assumeTrue(OS.getCurrent() == OS.DARWIN);
80 }
81
82 @Test
jmmvbfbd95f2020-08-31 13:12:38 -070083 public void testGetxattr_attributeFound() throws Exception {
ajmichaelad32f622018-02-09 10:19:29 -080084 assumeXattrsSupported();
85
86 String myfile = Files.createTempFile("getxattrtest", null).toString();
arostovtsev0212f182020-04-29 14:07:26 -070087 assertThat(new ProcessBuilder("xattr", "-w", "foo", "bar", myfile).start().waitFor())
88 .isEqualTo(0);
ajmichaelad32f622018-02-09 10:19:29 -080089
90 assertThat(new String(NativePosixFiles.getxattr(myfile, "foo"), UTF_8)).isEqualTo("bar");
91 assertThat(new String(NativePosixFiles.lgetxattr(myfile, "foo"), UTF_8)).isEqualTo("bar");
92 }
93
94 @Test
jmmvbfbd95f2020-08-31 13:12:38 -070095 public void testGetxattr_attributeNotFoundReturnsNull() throws Exception {
ajmichaelad32f622018-02-09 10:19:29 -080096 assumeXattrsSupported();
97
98 String myfile = Files.createTempFile("getxattrtest", null).toString();
99
100 assertThat(NativePosixFiles.getxattr(myfile, "foo")).isNull();
101 assertThat(NativePosixFiles.lgetxattr(myfile, "foo")).isNull();
102 }
103
104 @Test
jmmvbfbd95f2020-08-31 13:12:38 -0700105 public void testGetxattr_fileNotFound() throws Exception {
ajmichaelad32f622018-02-09 10:19:29 -0800106 String nonexistentFile = workingDir.getChild("nonexistent").toString();
107
108 assertThrows(
109 FileNotFoundException.class, () -> NativePosixFiles.getxattr(nonexistentFile, "foo"));
110 assertThrows(
111 FileNotFoundException.class, () -> NativePosixFiles.lgetxattr(nonexistentFile, "foo"));
112 }
Benjamin Petersonbe9fbec2019-03-27 05:25:18 -0700113
114 @Test
115 public void writing() throws Exception {
116 java.nio.file.Path myfile = Files.createTempFile("myfile", null);
117 int fd1 = NativePosixFiles.openWrite(myfile.toString(), false);
118 assertThrows(
119 IndexOutOfBoundsException.class,
120 () -> NativePosixFiles.write(fd1, new byte[] {0, 1, 2, 3}, 5, 1));
121 assertThrows(
122 IndexOutOfBoundsException.class,
123 () -> NativePosixFiles.write(fd1, new byte[] {0, 1, 2, 3}, -1, 1));
124 assertThrows(
125 IndexOutOfBoundsException.class,
126 () -> NativePosixFiles.write(fd1, new byte[] {0, 1, 2, 3}, 0, -1));
127 assertThrows(
128 IndexOutOfBoundsException.class,
129 () -> NativePosixFiles.write(fd1, new byte[] {0, 1, 2, 3}, 0, 5));
130 NativePosixFiles.write(fd1, new byte[] {0, 1, 2, 3}, 0, 4);
131 NativePosixFiles.close(fd1, null);
132 assertThat(Files.readAllBytes(myfile)).isEqualTo(new byte[] {0, 1, 2, 3});
133 // Try appending.
134 int fd2 = NativePosixFiles.openWrite(myfile.toString(), true);
135 NativePosixFiles.write(fd2, new byte[] {5, 6, 7, 8, 9}, 1, 3);
136 NativePosixFiles.close(fd2, null);
137 assertThat(Files.readAllBytes(myfile)).isEqualTo(new byte[] {0, 1, 2, 3, 6, 7, 8});
138 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100139}