summaryrefslogtreecommitdiffstats
path: root/dom/system/tests/ioutils/test_ioutils_stat_set_modification_time.html
blob: 8f8328bd81307a7bc5844380ee3a1aee82a85fb7 (plain)
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<!DOCTYPE HTML>
<html>

<head>
  <meta charset="utf-8">
  <title>Test the IOUtils file I/O API</title>
  <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
  <script src="file_ioutils_test_fixtures.js"></script>
  <script>
    "use strict";

    const { Assert } = ChromeUtils.import("resource://testing-common/Assert.jsm");
    const { ObjectUtils } = ChromeUtils.import("resource://gre/modules/ObjectUtils.jsm");

    add_task(async function test_stat() {
      info("Test attempt to stat a regular empty file");

      const emptyFileName = PathUtils.join(PathUtils.tempDir, "test_stat_empty.tmp");
      await createFile(emptyFileName);

      const emptyFileInfo = await IOUtils.stat(emptyFileName);
      is(emptyFileInfo.size, 0, "IOUtils::stat can get correct (empty) file size");
      is(emptyFileInfo.path, emptyFileName, "IOUtils::stat result contains the path");
      is(emptyFileInfo.type, "regular", "IOUtils::stat can stat regular (empty) files");
      Assert.less(
        (emptyFileInfo.lastModified - new Date().valueOf()),
        1000, // Allow for 1 second deviation in case of slow tests.
        "IOUtils::stat can get the last modification date for a regular file"
      );

      info("Test attempt to stat a regular binary file");
      const tempFileName = PathUtils.join(PathUtils.tempDir, "test_stat_binary.tmp");
      const bytes = Uint8Array.of(...new Array(50).keys());
      await createFile(tempFileName, bytes);

      const fileInfo = await IOUtils.stat(tempFileName);
      is(fileInfo.size, 50, "IOUtils::stat can get correct file size");
      is(fileInfo.path, tempFileName, "IOUtils::stat result contains the path");
      is(fileInfo.type, "regular", "IOUtils::stat can stat regular files");
      Assert.less(
        (fileInfo.lastModified - new Date().valueOf()),
        1000, // Allow for 1 second deviation in case of slow tests.
        "IOUtils::stat can get the last modification date for a regular file"
      );

      info("Test attempt to stat a directory");
      const tempDirName = PathUtils.join(PathUtils.tempDir, "test_stat_dir.tmp.d");
      await IOUtils.makeDirectory(tempDirName);

      const dirInfo = await IOUtils.stat(tempDirName);
      is(dirInfo.size, -1, "IOUtils::stat reports -1 size for directories")
      is(fileInfo.path, tempFileName, "IOUtils::stat result contains the path");
      is(fileInfo.type, "regular", "IOUtils::stat can stat directories");
      Assert.less(
        (fileInfo.lastModified - new Date().valueOf()),
        1000, // Allow for 1 second deviation in case of slow tests.
        "IOUtils::stat can get the last modification date for a regular file"
      );
      Assert.less(
        (fileInfo.lastAccessed - new Date().valueOf()),
        1000,
        "IOUtils::stat can get the last access date for a regular file"
      );

      await cleanup(emptyFileName, tempFileName, tempDirName)
    });

    add_task(async function test_stat_failures() {
      info("Test attempt to stat a non-existing file");

      const notExistsFile = PathUtils.join(PathUtils.tempDir, "test_stat_not_exists.tmp");

      await Assert.rejects(
        IOUtils.stat(notExistsFile),
        /Could not stat file\(.*\) because it does not exist/,
        "IOUtils::stat throws if the target file does not exist"
      );
    });

    add_task(async function test_setModificationTime_and_stat() {
      const tmpFileName = PathUtils.join(PathUtils.tempDir, "test_setModificationTime_and_stat.tmp");
      {
        info("Test attempt to setModificationTime a file");
        await createFile(tmpFileName);

        const oldFileInfo = await IOUtils.stat(tmpFileName);
        await sleep(500);

        // Now update the time stamp.
        const stamp = await IOUtils.setModificationTime(tmpFileName);
        const newFileInfo = await IOUtils.stat(tmpFileName);

        ok(
          newFileInfo.lastModified > oldFileInfo.lastModified,
          "IOUtils::setModificationTime can update the lastModified time stamp on the file system"
        );
        is(
          stamp,
          newFileInfo.lastModified,
          "IOUtils::setModificationTime returns the updated time stamp."
        );
        is(
          newFileInfo.lastAccessed,
          oldFileInfo.lastAccessed,
          "IOUtils::setModificationTime does not change lastAccessed"
        );

        await sleep(500);

        const newerStamp = await IOUtils.setAccessTime(tmpFileName);
        const newerFileInfo = await IOUtils.stat(tmpFileName);

        ok(
          newerFileInfo.lastAccessed > newFileInfo.lastAccessed,
          "IOUtils::setAccessTime can update the lastAccessed time stamp on the file system"
        );
        is(
          newerStamp,
          newerFileInfo.lastAccessed,
          "IOUtils::setAccessTime returns the updated time stamp."
        );
        is(
          newerFileInfo.lastModified,
          newFileInfo.lastModified,
          "IOUtils::setAccessTime does not change lastModified"
        );
      }

      const tmpDirName = PathUtils.join(PathUtils.tempDir, "test_setModificationTime_and_stat.tmp.d");
      {
        info("Test attempt to setModificationTime a directory");
        await createDir(tmpDirName);

        const oldFileInfo = await IOUtils.stat(tmpDirName);
        await sleep(500);

        const stamp = await IOUtils.setModificationTime(tmpDirName);
        const newFileInfo = await IOUtils.stat(tmpDirName);

        ok(
          newFileInfo.lastModified > oldFileInfo.lastModified,
          "IOUtils::setModificationTime can update the lastModified time stamp on a directory"
        );
        is(
          stamp,
          newFileInfo.lastModified,
          "IOUtils::setModificationTime returns the updated time stamp on a directory"
        );
      }

      await cleanup(tmpFileName, tmpDirName);
    });

    add_task(async function test_setModificationTime_custom_mod_time() {
      const tempFileName = PathUtils.join(PathUtils.tempDir, "test_setModificationTime_custom_mod_time.tmp");
      await createFile(tempFileName);
      const originalInfo = await IOUtils.stat(tempFileName);
      const now = originalInfo.lastModified;

      const oneMinute = 60 * 1000; // milliseconds

      info("Test attempt to set modification time to the future");
      const future = now + oneMinute;
      let newModTime = await IOUtils.setModificationTime(tempFileName, future);
      const futureInfo = await IOUtils.stat(tempFileName);
      Assert.less(originalInfo.lastModified, futureInfo.lastModified, "IOUtils::setModificationTime can set a future modification time for the file");

      is(newModTime, futureInfo.lastModified, "IOUtils::setModificationTime returns the updated time stamp");
      is(newModTime, future, "IOUtils::setModificationTime return value matches the argument value exactly");

      info("Test attempt to set modification time to the past");
      const past = now - 2 * oneMinute;
      newModTime = await IOUtils.setModificationTime(tempFileName, past);
      const pastInfo = await IOUtils.stat(tempFileName);
      Assert.greater(originalInfo.lastModified, pastInfo.lastModified, "IOUtils::setModificationTime can set a past modification time for the file");

      is(newModTime, pastInfo.lastModified, "IOUtils::setModificationTime returns the updated time stamp");
      is(newModTime, past, "IOUtils::setModificationTime return value matches the argument value exactly");

      await cleanup(tempFileName);
    });

    add_task(async function test_stat_btime() {
      if (["Darwin", "WINNT"].includes(Services.appinfo.OS)) {
        const tempFileName = PathUtils.join(PathUtils.tempDir, "test_stat_btime.tmp");
        await createFile(tempFileName);
        const originalInfo = await IOUtils.stat(tempFileName);

        const future = originalInfo.lastModified + 6000;
        await IOUtils.setModificationTime(tempFileName, future);
        const futureInfo = await IOUtils.stat(tempFileName);

        ok(originalInfo.hasOwnProperty("creationTime"), "originalInfo has creationTime field");
        ok(originalInfo.creationTime !== undefined && originalInfo.creationTime !== null, "originalInfo has non-null creationTime");

        ok(futureInfo.hasOwnProperty("creationTime"), "futureInfo has creationTime field");
        ok(futureInfo.creationTime !== undefined && futureInfo.creationTime !== null, "futureInfo has non-null creationTime");

        is(originalInfo.creationTime, futureInfo.creationTime, "creationTime matches");

        await cleanup(tempFileName);
      } else {
        ok(true, `skipping test_stat_btime() on unsupported platform ${Services.appinfo.OS}`);
      }
    });

    add_task(async function test_setModificationTime_failures() {
      info("Test attempt to setModificationTime a non-existing file");
      const notExistsFile = PathUtils.join(PathUtils.tempDir, "test_setModificationTime_not_exists.tmp");

      await Assert.rejects(
        IOUtils.setModificationTime(notExistsFile),
        /Could not set modification time of file\(.*\) because it does not exist/,
        "IOUtils::setModificationTime throws if the target file does not exist"
      );

      info("Test attempt to set modification time to Epoch");
      const tempFileName = PathUtils.join(PathUtils.tempDir, "test_setModificationTime_epoch.tmp");
      await createFile(tempFileName);

      await Assert.rejects(
        IOUtils.setModificationTime(tempFileName, 0),
        /Refusing to set the modification time of file\(.*\) to 0/,
        "IOUtils::setModificationTime cannot set the file modification time to Epoch"
      );

      await cleanup(tempFileName);
    });
  </script>
</head>

<body>
  <p id="display"></p>
  <div id="content" style="display: none"></div>
  <pre id="test"></pre>
</body>

</html>