@@ -4,6 +4,7 @@ var fs = require('fs');
4
4
var path = require ( 'path' ) ;
5
5
var doesNotExist = __filename + '__this_should_not_exist' ;
6
6
var readOnlyFile = path . join ( common . tmpDir , 'read_only_file' ) ;
7
+ var readWriteFile = path . join ( common . tmpDir , 'read_write_file' ) ;
7
8
8
9
var removeFile = function ( file ) {
9
10
try {
@@ -13,13 +14,47 @@ var removeFile = function(file) {
13
14
}
14
15
} ;
15
16
16
- var createReadOnlyFile = function ( file ) {
17
+ var createFileWithPerms = function ( file , mode ) {
17
18
removeFile ( file ) ;
18
19
fs . writeFileSync ( file , '' ) ;
19
- fs . chmodSync ( file , 0444 ) ;
20
+ fs . chmodSync ( file , mode ) ;
20
21
} ;
21
22
22
- createReadOnlyFile ( readOnlyFile ) ;
23
+ createFileWithPerms ( readOnlyFile , 0444 ) ;
24
+ createFileWithPerms ( readWriteFile , 0666 ) ;
25
+
26
+ /*
27
+ * On non-Windows supported platforms, fs.access(readOnlyFile, W_OK, ...)
28
+ * always succeeds if node runs as the super user, which is sometimes the
29
+ * case for tests running on our continuous testing platform agents.
30
+ *
31
+ * In this case, this test tries to change its process user id to a
32
+ * non-superuser user so that the test that checks for write access to a
33
+ * read-only file can be more meaningful.
34
+ *
35
+ * The change of user id is done after creating the fixtures files for the same
36
+ * reason: the test may be run as the superuser within a directory in which
37
+ * only the superuser can create files, and thus it may need superuser
38
+ * priviledges to create them.
39
+ *
40
+ * There's not really any point in resetting the process' user id to 0 after
41
+ * changing it to 'nobody', since in the case that the test runs without
42
+ * superuser priviledge, it is not possible to change its process user id to
43
+ * superuser.
44
+ *
45
+ * It can prevent the test from removing files created before the change of user
46
+ * id, but that's fine. In this case, it is the responsability of the
47
+ * continuous integration platform to take care of that.
48
+ */
49
+ var hasWriteAccessForReadonlyFile = false ;
50
+ if ( process . platform !== 'win32' && process . getuid ( ) === 0 ) {
51
+ hasWriteAccessForReadonlyFile = true ;
52
+ try {
53
+ process . setuid ( 'nobody' ) ;
54
+ hasWriteAccessForReadonlyFile = false ;
55
+ } catch ( err ) {
56
+ }
57
+ }
23
58
24
59
assert ( typeof fs . F_OK === 'number' ) ;
25
60
assert ( typeof fs . R_OK === 'number' ) ;
@@ -45,8 +80,12 @@ fs.access(readOnlyFile, fs.F_OK | fs.R_OK, function(err) {
45
80
} ) ;
46
81
47
82
fs . access ( readOnlyFile , fs . W_OK , function ( err ) {
48
- assert . notEqual ( err , null , 'error should exist' ) ;
49
- assert . strictEqual ( err . path , readOnlyFile ) ;
83
+ if ( hasWriteAccessForReadonlyFile ) {
84
+ assert . equal ( err , null , 'error should not exist' ) ;
85
+ } else {
86
+ assert . notEqual ( err , null , 'error should exist' ) ;
87
+ assert . strictEqual ( err . path , readOnlyFile ) ;
88
+ }
50
89
} ) ;
51
90
52
91
assert . throws ( function ( ) {
@@ -68,7 +107,7 @@ assert.doesNotThrow(function() {
68
107
assert . doesNotThrow ( function ( ) {
69
108
var mode = fs . F_OK | fs . R_OK | fs . W_OK ;
70
109
71
- fs . accessSync ( __filename , mode ) ;
110
+ fs . accessSync ( readWriteFile , mode ) ;
72
111
} ) ;
73
112
74
113
assert . throws ( function ( ) {
@@ -79,4 +118,5 @@ assert.throws(function() {
79
118
80
119
process . on ( 'exit' , function ( ) {
81
120
removeFile ( readOnlyFile ) ;
121
+ removeFile ( readWriteFile ) ;
82
122
} ) ;
0 commit comments