Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spawn EXTBSY error #224

Closed
DanielRuf opened this issue Mar 28, 2020 · 12 comments · Fixed by #242
Closed

spawn EXTBSY error #224

DanielRuf opened this issue Mar 28, 2020 · 12 comments · Fixed by #242

Comments

@DanielRuf
Copy link

We are getting the following error:

Using config: /__w/foundation-sites/foundation-sites/browserstack.json
internal/child_process.js:405
    throw errnoException(err, 'spawn');
    ^

Error: spawn ETXTBSY
    at ChildProcess.spawn (internal/child_process.js:405:11)
    at spawn (child_process.js:548:9)
    at execFile (child_process.js:232:17)
    at tunnelLauncher (/__w/foundation-sites/foundation-sites/node_modules/browserstack-runner/lib/local.js:23:22)
    at Timeout._onTimeout (/__w/foundation-sites/foundation-sites/node_modules/browserstack-runner/lib/local.js:191:11)
    at listOnTimeout (internal/timers.js:549:17)
    at processTimers (internal/timers.js:492:7) {
  errno: -26,
  code: 'ETXTBSY',
  syscall: 'spawn'
}

Related: browserstack/browserstack-local-nodejs#19

@DanielRuf
Copy link
Author

Still the same. It seems there is a lack of support from browserstack which is not great.

@DanielRuf
Copy link
Author

It seems the logic in Nodejs changed a bit in the latest version(s).
This finally works for us: https://github.com/foundation/foundation-sites/blob/develop/patches/browserstack-runner%2B0.9.2.patch

@DanielRuf
Copy link
Author

diff --git a/node_modules/browserstack-runner/lib/local.js b/node_modules/browserstack-runner/lib/local.js
index 15b147c..4f15a49 100644
--- a/node_modules/browserstack-runner/lib/local.js
+++ b/node_modules/browserstack-runner/lib/local.js
@@ -180,16 +180,16 @@ var Tunnel = function Tunnel(key, port, uniqueIdentifier, config, callback) {
     }
     logger.debug('Downloading BrowserStack Local to "%s"', localBinary);
 
-    var file = fs.createWriteStream(localBinary);
+    var file = fs.createWriteStream(localBinary, {emitClose: true});
     https.get('https://s3.amazonaws.com/browserStack/browserstack-local/BrowserStackLocal' + (windows ? '.exe' : '-' + process.platform + '-' + process.arch),
     function(response) {
       response.pipe(file);
 
       response.on('end', function() {
-        fs.chmodSync(localBinary, 0700);
-        setTimeout(function() {
+        file.on('close', function () {
+          fs.chmodSync(localBinary, 0700);
           tunnelLauncher();
-        }, 100);
+        })
       }).on('error', function(e) {
         logger.info('Got error while downloading binary: ' + e.message);
         throw new Error('Got error while downloading binary: ' + e.message);

@RangerMauve
Copy link

Getting this too. 😅 Does it work with older node versions or something?

@RangerMauve
Copy link

I tried applying @DanielRuf 's patch but I'm still getting the error.

This is with node v12.16.2 and browserstack-runner 0.9.3 (with and without the patch)

Error: ETXTBSY: text file is busy, open '/home/mauve/programming/sodium-javascript/node_modules/browserstack-runner/lib/BrowserStackLocal'
Emitted 'error' event on WriteStream instance at:
    at internal/fs/streams.js:321:12
    at FSReqCallback.oncomplete (fs.js:155:23) {
  errno: -26,
  code: 'ETXTBSY',
  syscall: 'open',
  path: '/home/mauve/programming/sodium-javascript/node_modules/browserstack-runner/lib/BrowserStackLocal'
}

@DanielRuf
Copy link
Author

DanielRuf commented Aug 9, 2020

For older versions you might want to try the PR which switched the end and close events (#225).

Or this one: #217

@RangerMauve
Copy link

@DanielRuf Was there a particular version that worked for you?

I found that deleting the BrowserLocal binary before running the tests helped. (though this seems a bit inefficient).

@DanielRuf
Copy link
Author

We use browsertack-runner 0.9.2 and Node 14.7.0

@DanielRuf
Copy link
Author

Closing as there seems to be no further interest to resolve this.

@wati123321
Copy link

Hey, your statement on 2nd Aug mentions that the issue was resolved using the latest version of NodeJS, are you still facing any errors?

@DanielRuf
Copy link
Author

@wati123321 it works with my own patch / changes.

that the issue was resolved using the latest version of NodeJS

No, not in the original project without the patch by me.
It broke on newer Node versions.

@MrSwitch
Copy link

MrSwitch commented Mar 20, 2021

I was able to resolve this by deleting package-lock.json prior to running npm i.

You can see it failing here with the above error.

But then passing here when i add the run: rm package-lock.json step prior to npm i.

I'm still curious as to why removing package-lock should work. Since browserstack-runner works on Mac locally perhaps some post install operations of the dependencies install something architecture specific.

Krinkle added a commit to Krinkle/browserstack-runner that referenced this issue Apr 11, 2021
Currently after installing browserstack-runner you can run one test.
After that, the command is broken. There are numerous symptoms
from this:

* BrowserStackLocal gets re-downloaded every single time.
* an ETXTBSY error appears because the previous file is still busy.

Here is what happens on later runs:

* `fs.exists(localBinary)` finds the binary.
* `runTunnelCmd(['-version'])` gets the following output:

```
$ node_modules/browserstack-runner/lib/BrowserStackLocal -version
Sun Apr 11 2021 20:59:41 GMT+0000 (UTC) -- BrowserStackLocal v8.1

Sun Apr 11 2021 20:59:41 GMT+0000 (UTC) -- Container runtime environment detected
Sun Apr 11 2021 20:59:41 GMT+0000 (UTC) -- Attaching services to public interface
BrowserStack Local version 8.1
```

* Only the first line of data is checked by `subProcess.stdout.on('data')`.
* The line does not match `/version\s+(\d)/`. It reports:  `Tunnel binary: found version null`.
* The script invokes `callbackOnce()` and will try to kill the process. This may succeed, but it is not immediate as there are additional output lines still in the data buffer which must be processed first, which is not possible since we are still indirectly in the call stack of the first `data` stdout callback.
* The re-download begins, but the operating system does not permit writing to a currently executing binary, since it will not shutdown until a few milliseconds later.
* We fail with `Error: ETXTBSY: text file is busy`.

All of this happens only because `-version` is interpreted as both `-v` for verbose and `--version` at the same time, the verbose output comes first and does not match the regex. Changing it to `--version` solves the problem.

This code should also be changed so that it actually waits for this subprocess to exit. Perhaps falling back to unlinking the file if we can't close it so that at least the redownload will work. But, that is another issue and will not be a problem in most cases.

Fixes browserstack#224.
Krinkle added a commit to qunitjs/browserstack-runner that referenced this issue Apr 11, 2021
Currently after installing browserstack-runner you can run one test.
After that, the command is broken. There are numerous symptoms
from this:

* BrowserStackLocal gets re-downloaded every single time.
* an ETXTBSY error appears because the previous file is still busy.

Here is what happens on later runs:

* `fs.exists(localBinary)` finds the binary.
* `runTunnelCmd(['-version'])` gets the following output:

```
$ node_modules/browserstack-runner/lib/BrowserStackLocal -version
Sun Apr 11 2021 20:59:41 GMT+0000 (UTC) -- BrowserStackLocal v8.1

Sun Apr 11 2021 20:59:41 GMT+0000 (UTC) -- Container runtime environment detected
Sun Apr 11 2021 20:59:41 GMT+0000 (UTC) -- Attaching services to public interface
BrowserStack Local version 8.1
```

* Only the first line of data is checked by `subProcess.stdout.on('data')`.
* The line does not match `/version\s+(\d)/`. It reports:  `Tunnel binary: found version null`.
* The script invokes `callbackOnce()` and will try to kill the process. This may succeed, but it is not immediate as there are additional output lines still in the data buffer which must be processed first, which is not possible since we are still indirectly in the call stack of the first `data` stdout callback.
* The re-download begins, but the operating system does not permit writing to a currently executing binary, since it will not shutdown until a few milliseconds later.
* We fail with `Error: ETXTBSY: text file is busy`.

All of this happens only because `-version` is interpreted as both `-v` for verbose and `--version` at the same time, the verbose output comes first and does not match the regex. Changing it to `--version` solves the problem.

This code should also be changed so that it actually waits for this subprocess to exit. Perhaps falling back to unlinking the file if we can't close it so that at least the redownload will work. But, that is another issue and will not be a problem in most cases.

Fixes browserstack#224.
Ref browserstack#242.
francisf pushed a commit that referenced this issue Apr 19, 2021
Currently after installing browserstack-runner you can run one test.
After that, the command is broken. There are numerous symptoms
from this:

* BrowserStackLocal gets re-downloaded every single time.
* an ETXTBSY error appears because the previous file is still busy.

Here is what happens on later runs:

* `fs.exists(localBinary)` finds the binary.
* `runTunnelCmd(['-version'])` gets the following output:

```
$ node_modules/browserstack-runner/lib/BrowserStackLocal -version
Sun Apr 11 2021 20:59:41 GMT+0000 (UTC) -- BrowserStackLocal v8.1

Sun Apr 11 2021 20:59:41 GMT+0000 (UTC) -- Container runtime environment detected
Sun Apr 11 2021 20:59:41 GMT+0000 (UTC) -- Attaching services to public interface
BrowserStack Local version 8.1
```

* Only the first line of data is checked by `subProcess.stdout.on('data')`.
* The line does not match `/version\s+(\d)/`. It reports:  `Tunnel binary: found version null`.
* The script invokes `callbackOnce()` and will try to kill the process. This may succeed, but it is not immediate as there are additional output lines still in the data buffer which must be processed first, which is not possible since we are still indirectly in the call stack of the first `data` stdout callback.
* The re-download begins, but the operating system does not permit writing to a currently executing binary, since it will not shutdown until a few milliseconds later.
* We fail with `Error: ETXTBSY: text file is busy`.

All of this happens only because `-version` is interpreted as both `-v` for verbose and `--version` at the same time, the verbose output comes first and does not match the regex. Changing it to `--version` solves the problem.

This code should also be changed so that it actually waits for this subprocess to exit. Perhaps falling back to unlinking the file if we can't close it so that at least the redownload will work. But, that is another issue and will not be a problem in most cases.

Fixes #224.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants