@@ -4,6 +4,7 @@ var fs = require('fs');
44var path = require ( 'path' ) ;
55var doesNotExist = __filename + '__this_should_not_exist' ;
66var readOnlyFile = path . join ( common . tmpDir , 'read_only_file' ) ;
7+ var readWriteFile = path . join ( common . tmpDir , 'read_write_file' ) ;
78
89var removeFile = function ( file ) {
910 try {
@@ -13,13 +14,47 @@ var removeFile = function(file) {
1314 }
1415} ;
1516
16- var createReadOnlyFile = function ( file ) {
17+ var createFileWithPerms = function ( file , mode ) {
1718 removeFile ( file ) ;
1819 fs . writeFileSync ( file , '' ) ;
19- fs . chmodSync ( file , 0444 ) ;
20+ fs . chmodSync ( file , mode ) ;
2021} ;
2122
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+ }
2358
2459assert ( typeof fs . F_OK === 'number' ) ;
2560assert ( typeof fs . R_OK === 'number' ) ;
@@ -45,8 +80,12 @@ fs.access(readOnlyFile, fs.F_OK | fs.R_OK, function(err) {
4580} ) ;
4681
4782fs . 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+ }
5089} ) ;
5190
5291assert . throws ( function ( ) {
@@ -68,7 +107,7 @@ assert.doesNotThrow(function() {
68107assert . doesNotThrow ( function ( ) {
69108 var mode = fs . F_OK | fs . R_OK | fs . W_OK ;
70109
71- fs . accessSync ( __filename , mode ) ;
110+ fs . accessSync ( readWriteFile , mode ) ;
72111} ) ;
73112
74113assert . throws ( function ( ) {
@@ -79,4 +118,5 @@ assert.throws(function() {
79118
80119process . on ( 'exit' , function ( ) {
81120 removeFile ( readOnlyFile ) ;
121+ removeFile ( readWriteFile ) ;
82122} ) ;
0 commit comments