File: marSuccessPartialWhileBackgroundTaskRunning.js

package info (click to toggle)
firefox 147.0.4-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,683,532 kB
  • sloc: cpp: 7,607,356; javascript: 6,533,348; ansic: 3,775,236; python: 1,415,508; xml: 634,561; asm: 438,949; java: 186,241; sh: 62,760; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (130 lines) | stat: -rw-r--r-- 4,721 bytes parent folder | download | duplicates (14)
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
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/* General Partial MAR File Patch Apply Test */

const { setTimeout } = ChromeUtils.importESModule(
  "resource://gre/modules/Timer.sys.mjs"
);

const { BackgroundTasksTestUtils } = ChromeUtils.importESModule(
  "resource://testing-common/BackgroundTasksTestUtils.sys.mjs"
);
BackgroundTasksTestUtils.init(this);
const do_backgroundtask = BackgroundTasksTestUtils.do_backgroundtask.bind(
  BackgroundTasksTestUtils
);

async function run_test() {
  // Without omnijars, the background task apparatus will fail to find task
  // definitions.
  {
    let omniJa = Services.dirsvc.get("XCurProcD", Ci.nsIFile);
    omniJa.append("omni.ja");
    if (!omniJa.exists()) {
      Assert.ok(
        false,
        "This test requires a packaged build, " +
          "run 'mach package' and then use 'mach xpcshell-test --xre-path=...'"
      );
      return;
    }
  }

  if (!setupTestCommon()) {
    return;
  }

  // `channel-prefs.js` (or `ChannelPrefs.framework/ChannelPrefs on macOS`) is
  // required for Firefox to launch, including in background task mode. The
  // testing partial MAR updates `channel-prefs.js` to have contents
  // `FromPartial`, which is not a valid prefs file and causes Firefox to crash.
  //  However, `channel-prefs.js` is listed as `add-if-not
  // "defaults/pref/channel-prefs.js" "defaults/pref/channel-prefs.js"`, so it
  // won't be updated if it already exists. The manipulations below arrange a)
  // for the file to exist and b) for the comparison afterward to succeed.
  gTestFiles = gTestFilesPartialSuccess;
  let channelPrefs = getTestFileByName(FILE_CHANNEL_PREFS);
  let f = gGREDirOrig.clone();
  if (AppConstants.platform == "macosx") {
    f = f.parent;
    f.append("Frameworks");
    f.append("ChannelPrefs.framework");
    f.append("ChannelPrefs");
  } else {
    f.append("defaults");
    f.append("pref");
    f.append("channel-prefs.js");
  }

  // `originalFile` is a relative path, so we can't just point to the one in the
  // original GRE directory.
  channelPrefs.originalFile = null;
  channelPrefs.originalContents = readFile(f);
  channelPrefs.compareContents = channelPrefs.originalContents;

  gTestDirs = gTestDirsPartialSuccess;
  // The third parameter will test that a relative path that contains a
  // directory traversal to the post update binary doesn't execute.
  await setupUpdaterTest(FILE_PARTIAL_MAR, false, "test/../", true, {
    // We need packaged JavaScript to run background tasks.
    requiresOmnijar: true,
  });

  // `0/00/00text2` is just a random file in the testing partial MAR that does
  // not exist before the update and is always written by the update.
  let exitCode;
  exitCode = await do_backgroundtask("file_exists", {
    extraArgs: [getApplyDirFile(DIR_RESOURCES + "0/00/00text2").path],
  });
  // Before updating, file doesn't exist.
  Assert.equal(11, exitCode);

  // This task will wait 10 seconds before exiting, which should overlap with
  // the update below.  We wait for some output from the wait background task,
  // so that there is meaningful overlap.
  let taskStarted = Promise.withResolvers();
  let p = do_backgroundtask("wait", {
    onStdoutLine: (line, proc) => {
      // This sentinel seems pretty safe: it's printed by the task itself and so
      // there should be a straight line between future test failures and
      // logging changes.
      if (line.includes("runBackgroundTask: wait")) {
        taskStarted.resolve(proc);
      }
    },
  });
  let proc = await taskStarted.promise;

  runUpdate(STATE_SUCCEEDED, false, 0, true);

  checkAppBundleModTime();
  await testPostUpdateProcessing();
  checkPostUpdateRunningFile(false);
  checkFilesAfterUpdateSuccess(getApplyDirFile);
  checkUpdateLogContents(LOG_PARTIAL_SUCCESS);
  await waitForUpdateXMLFiles();
  await checkUpdateManager(STATE_NONE, false, STATE_SUCCEEDED, 0, 1);

  // Once we've seen what we want, there's no need to let the task wait complete.
  await proc.kill();

  Assert.ok("Waiting for background task to die after kill()");
  exitCode = await p;

  // Windows does not support killing processes gracefully, so they will
  // always exit with -9 there.
  let retVal = AppConstants.platform == "win" ? -9 : -15;
  Assert.equal(retVal, exitCode);

  exitCode = await do_backgroundtask("file_exists", {
    extraArgs: [getApplyDirFile(DIR_RESOURCES + "0/00/00text2").path],
  });
  // After updating, file exists.
  Assert.equal(0, exitCode);

  // This finishes the test, so must be last.
  checkCallbackLog();
}