Repository: flox/flox
Pull request #3000: fix: flaky daemon service test
Author: login: zmitchell
Labels: name: team-cli
description: Tickets relevant to the flox CLI team
Created: 2025-04-25T00:28:34Z | Merged: 2025-04-29T01:12:53Z

## Proposed Changes

<!-- Describe the changes proposed in this pull request. -->
<!-- Please provide links to any issue(s) which are expected to be resolved. -->
This test was flaking because for some reason this test would take longer than 2 seconds to run `overmind status`. This was primarily on x86_64-darwin, but did happen on other systems from time to time. I've replaced overmind with a daemonized sleep command to try to cut out as much logic as possible.

## Release Notes

<!-- Describe any user facing changes. Use "N/A" if not applicable. -->
N/A

<!-- Many thanks! -->



Diff:
diff --git a/cli/tests/services.bats b/cli/tests/services.bats
index 43bf9d09a0..cc2f088588 100644
--- a/cli/tests/services.bats
+++ b/cli/tests/services.bats
@@ -1398,35 +1398,25 @@ EOF
     version = 1
 
     [install]
-    overmind.pkg-path = "overmind"
+    daemonize.pkg-path = "daemonize"
 
-    [services.overmind]
-    command = "overmind start -D"
+    [services.daemonized_sleep]
+    command = '''
+      daemonize -p "$FLOX_ENV_PROJECT/pidfile" "$(which sleep)" 999999
+    '''
     is-daemon = true
-    shutdown.command = "overmind quit"
+    shutdown.command = '''
+      kill -9 "$(cat $(pwd)/pidfile)"
+    '''
 EOF
 )"
 
   "$FLOX_BIN" init
-  export _FLOX_USE_CATALOG_MOCK="$GENERATED_DATA/resolve/overmind.json"
+  export _FLOX_USE_CATALOG_MOCK="$GENERATED_DATA/resolve/daemonize.json"
   echo "$MANIFEST_CONTENTS" | "$FLOX_BIN" edit -f -
-  echo "sleep: sleep 999999" > ./Procfile
 
-  SCRIPT="$(cat << "EOF"
-    # The timeout below has timed out,
-    # but it is hard to reproduce,
-    # so add set -x for more info in the future.
-    set -euxo pipefail
-
-    timeout 2 bash -c "set -x; while ! overmind status; do sleep .1; done"
-
-    "$FLOX_BIN" services status
-    "$FLOX_BIN" services stop
-EOF
-  )"
-
-  "$FLOX_BIN" activate -s -- bash -c "$SCRIPT"
-  timeout 2 bash -c "while [ -e "$PWD/overmind.sock" ]; do sleep .1; done"
+  run "$FLOX_BIN" activate -s -- bash "${TESTS_DIR}/services/check_daemon_process.sh"
+  assert_success
 }
 
 @test "activate: picks up changes after environment modification when all services have stopped" {
diff --git a/cli/tests/services/check_daemon_process.sh b/cli/tests/services/check_daemon_process.sh
new file mode 100644
index 0000000000..df03352f56
--- /dev/null
+++ b/cli/tests/services/check_daemon_process.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+set -euxo pipefail
+
+timeout 2 bash -c 'set -x; while [ ! -e "$(pwd)/pidfile" ]; do sleep .1; done'
+
+"$FLOX_BIN" services status
+"$FLOX_BIN" services stop
+
+timeout 2 bash -c 'set -x; while kill -0 "$(cat "$(pwd)/pidfile")"; do sleep .1; done'
diff --git a/shells/default/default.nix b/shells/default/default.nix
index fb927c6bd1..37e3c1b0eb 100644
--- a/shells/default/default.nix
+++ b/shells/default/default.nix
@@ -15,6 +15,7 @@
   podman,
   mitmproxy,
   cargo-nextest,
+  daemonize,
   flox-cli,
   flox-cli-tests,
   flox-activations,
@@ -42,6 +43,7 @@ let
       procps
       pstree
       podman
+      daemonize
       flox-cli-tests
     ]
     ++ lib.optionals stdenv.isLinux [
diff --git a/test_data/config.toml b/test_data/config.toml
index 4dc24108dd..947901ece7 100644
--- a/test_data/config.toml
+++ b/test_data/config.toml
@@ -91,6 +91,10 @@ ignore_cmd_errors = true # build will fail on macos, that's fine
 pre_cmd = "flox init"
 cmd = "flox install influxdb2"
 
+[resolve.daemonize]
+pre_cmd = "flox init"
+cmd = "flox install daemonize"
+
 # This is used to trigger the "only install for some systems" code path
 [resolve.darwin_ps_all]
 pre_cmd = '''
@@ -202,10 +206,6 @@ pre_cmd = "flox init"
 cmd = "flox install nodejs@14.16.1"
 ignore_cmd_errors = true
 
-[resolve.overmind]
-pre_cmd = "flox init"
-cmd = "flox install overmind"
-
 # Try to install a package that doesn't exist, but that *does* have suggestions
 [resolve.package_suggestions]
 pre_cmd = "flox init"
diff --git a/test_data/generated/resolve/daemonize.json b/test_data/generated/resolve/daemonize.json
new file mode 100644
index 0000000000..8708e62191
--- /dev/null
+++ b/test_data/generated/resolve/daemonize.json
@@ -0,0 +1,152 @@
+[
+  [
+    {
+      "msgs": [],
+      "name": "toplevel",
+      "page": {
+        "complete": true,
+        "msgs": [],
+        "packages": [
+          {
+            "attr_path": "daemonize",
+            "broken": false,
+            "catalog": "nixpkgs",
+            "derivation": "/nix/store/wjzjhxs8x0mp4kf15301a9rlg80llj8h-daemonize-1.7.8.drv",
+            "description": "Runs a command as a Unix daemon",
+            "insecure": false,
+            "install_id": "daemonize",
+            "license": "BSD-3-Clause",
+            "locked_url": "https://github.com/flox/nixpkgs?rev=c11863f1e964833214b767f4a369c6e6a7aba141",
+            "missing_builds": false,
+            "name": "daemonize-1.7.8",
+            "outputs": [
+              {
+                "name": "out",
+                "store_path": "/nix/store/6a2zm244k5hpiv1hblapkyj6bpvxhjix-daemonize-1.7.8"
+              }
+            ],
+            "outputs_to_install": [
+              "out"
+            ],
+            "pkg_path": "daemonize",
+            "pname": "daemonize",
+            "rev": "c11863f1e964833214b767f4a369c6e6a7aba141",
+            "rev_count": 787278,
+            "rev_date": "2025-04-21T11:18:05Z",
+            "scrape_date": "2025-04-23T04:18:47.489612Z",
+            "stabilities": [
+              "unstable"
+            ],
+            "system": "aarch64-darwin",
+            "unfree": false,
+            "version": "1.7.8"
+          },
+          {
+            "attr_path": "daemonize",
+            "broken": false,
+            "catalog": "nixpkgs",
+            "derivation": "/nix/store/070pda5skxxvm9c5c7qsv09xx7gz6c24-daemonize-1.7.8.drv",
+            "description": "Runs a command as a Unix daemon",
+            "insecure": false,
+            "install_id": "daemonize",
+            "license": "BSD-3-Clause",
+            "locked_url": "https://github.com/flox/nixpkgs?rev=c11863f1e964833214b767f4a369c6e6a7aba141",
+            "missing_builds": false,
+            "name": "daemonize-1.7.8",
+            "outputs": [
+              {
+                "name": "out",
+                "store_path": "/nix/store/7vd67kv1a5vh5wa6d0ydfwzcc9mhd3la-daemonize-1.7.8"
+              }
+            ],
+            "outputs_to_install": [
+              "out"
+            ],
+            "pkg_path": "daemonize",
+            "pname": "daemonize",
+            "rev": "c11863f1e964833214b767f4a369c6e6a7aba141",
+            "rev_count": 787278,
+            "rev_date": "2025-04-21T11:18:05Z",
+            "scrape_date": "2025-04-23T04:36:52.376633Z",
+            "stabilities": [
+              "unstable"
+            ],
+            "system": "aarch64-linux",
+            "unfree": false,
+            "version": "1.7.8"
+          },
+          {
+            "attr_path": "daemonize",
+            "broken": false,
+            "catalog": "nixpkgs",
+            "derivation": "/nix/store/mli1zpdmh3x0nlkm1iw02m39wiw01xsn-daemonize-1.7.8.drv",
+            "description": "Runs a command as a Unix daemon",
+            "insecure": false,
+            "install_id": "daemonize",
+            "license": "BSD-3-Clause",
+            "locked_url": "https://github.com/flox/nixpkgs?rev=c11863f1e964833214b767f4a369c6e6a7aba141",
+            "missing_builds": false,
+            "name": "daemonize-1.7.8",
+            "outputs": [
+              {
+                "name": "out",
+                "store_path": "/nix/store/z5x09z4bajv2vg8s3g4hak7n0bj7my9w-daemonize-1.7.8"
+              }
+            ],
+            "outputs_to_install": [
+              "out"
+            ],
+            "pkg_path": "daemonize",
+            "pname": "daemonize",
+            "rev": "c11863f1e964833214b767f4a369c6e6a7aba141",
+            "rev_count": 787278,
+            "rev_date": "2025-04-21T11:18:05Z",
+            "scrape_date": "2025-04-23T04:54:04.177957Z",
+            "stabilities": [
+              "unstable"
+            ],
+            "system": "x86_64-darwin",
+            "unfree": false,
+            "version": "1.7.8"
+          },
+          {
+            "attr_path": "daemonize",
+            "broken": false,
+            "catalog": "nixpkgs",
+            "derivation": "/nix/store/l8v7lkabqzwwy7i7nsaiwswp5f1qrhnq-daemonize-1.7.8.drv",
+            "description": "Runs a command as a Unix daemon",
+            "insecure": false,
+            "install_id": "daemonize",
+            "license": "BSD-3-Clause",
+            "locked_url": "https://github.com/flox/nixpkgs?rev=c11863f1e964833214b767f4a369c6e6a7aba141",
+            "missing_builds": false,
+            "name": "daemonize-1.7.8",
+            "outputs": [
+              {
+                "name": "out",
+                "store_path": "/nix/store/03g086p0na3q4d9gil6myf0kn6p63gr3-daemonize-1.7.8"
+              }
+            ],
+            "outputs_to_install": [
+              "out"
+            ],
+            "pkg_path": "daemonize",
+            "pname": "daemonize",
+            "rev": "c11863f1e964833214b767f4a369c6e6a7aba141",
+            "rev_count": 787278,
+            "rev_date": "2025-04-21T11:18:05Z",
+            "scrape_date": "2025-04-23T05:15:24.938331Z",
+            "stabilities": [
+              "unstable"
+            ],
+            "system": "x86_64-linux",
+            "unfree": false,
+            "version": "1.7.8"
+          }
+        ],
+        "page": 787278,
+        "url": ""
+      }
+    }
+  ]
+]
diff --git a/test_data/generated/resolve/overmind.json b/test_data/generated/resolve/overmind.json
deleted file mode 100644
index 9edc19083b..0000000000
--- a/test_data/generated/resolve/overmind.json
+++ /dev/null
@@ -1,152 +0,0 @@
-[
-  [
-    {
-      "msgs": [],
-      "name": "toplevel",
-      "page": {
-        "complete": true,
-        "msgs": [],
-        "packages": [
-          {
-            "attr_path": "overmind",
-            "broken": false,
-            "catalog": "nixpkgs",
-            "derivation": "/nix/store/2ai4jyp3mvxklk8g5hdmg9rcsvr02kwd-overmind-2.5.1.drv",
-            "description": "Process manager for Procfile-based applications and tmux",
-            "insecure": false,
-            "install_id": "overmind",
-            "license": "[ MIT ]",
-            "locked_url": "https://github.com/flox/nixpkgs?rev=2631b0b7abcea6e640ce31cd78ea58910d31e650",
-            "missing_builds": false,
-            "name": "overmind-2.5.1",
-            "outputs": [
-              {
-                "name": "out",
-                "store_path": "/nix/store/c73fxxgb71kzjm7gbi6v5sp32mwcnd9w-overmind-2.5.1"
-              }
-            ],
-            "outputs_to_install": [
-              "out"
-            ],
-            "pkg_path": "overmind",
-            "pname": "overmind",
-            "rev": "2631b0b7abcea6e640ce31cd78ea58910d31e650",
-            "rev_count": 782401,
-            "rev_date": "2025-04-12T13:19:24Z",
-            "scrape_date": "2025-04-14T01:11:28.367589Z",
-            "stabilities": [
-              "unstable"
-            ],
-            "system": "aarch64-darwin",
-            "unfree": false,
-            "version": "2.5.1"
-          },
-          {
-            "attr_path": "overmind",
-            "broken": false,
-            "catalog": "nixpkgs",
-            "derivation": "/nix/store/4l1cfh0pb1xpycm0qlqg9nxyli7m8ngg-overmind-2.5.1.drv",
-            "description": "Process manager for Procfile-based applications and tmux",
-            "insecure": false,
-            "install_id": "overmind",
-            "license": "[ MIT ]",
-            "locked_url": "https://github.com/flox/nixpkgs?rev=2631b0b7abcea6e640ce31cd78ea58910d31e650",
-            "missing_builds": false,
-            "name": "overmind-2.5.1",
-            "outputs": [
-              {
-                "name": "out",
-                "store_path": "/nix/store/f95k5v5lbqh8dmi8w5b7zb68x1s7zand-overmind-2.5.1"
-              }
-            ],
-            "outputs_to_install": [
-              "out"
-            ],
-            "pkg_path": "overmind",
-            "pname": "overmind",
-            "rev": "2631b0b7abcea6e640ce31cd78ea58910d31e650",
-            "rev_count": 782401,
-            "rev_date": "2025-04-12T13:19:24Z",
-            "scrape_date": "2025-04-14T01:28:15.026001Z",
-            "stabilities": [
-              "unstable"
-            ],
-            "system": "aarch64-linux",
-            "unfree": false,
-            "version": "2.5.1"
-          },
-          {
-            "attr_path": "overmind",
-            "broken": false,
-            "catalog": "nixpkgs",
-            "derivation": "/nix/store/qja606wqfxisskiiazs7m5nra2gcl677-overmind-2.5.1.drv",
-            "description": "Process manager for Procfile-based applications and tmux",
-            "insecure": false,
-            "install_id": "overmind",
-            "license": "[ MIT ]",
-            "locked_url": "https://github.com/flox/nixpkgs?rev=2631b0b7abcea6e640ce31cd78ea58910d31e650",
-            "missing_builds": false,
-            "name": "overmind-2.5.1",
-            "outputs": [
-              {
-                "name": "out",
-                "store_path": "/nix/store/jx1v1w1vgzmmbq803rf6haakvkjk4zq6-overmind-2.5.1"
-              }
-            ],
-            "outputs_to_install": [
-              "out"
-            ],
-            "pkg_path": "overmind",
-            "pname": "overmind",
-            "rev": "2631b0b7abcea6e640ce31cd78ea58910d31e650",
-            "rev_count": 782401,
-            "rev_date": "2025-04-12T13:19:24Z",
-            "scrape_date": "2025-04-14T01:43:39.531504Z",
-            "stabilities": [
-              "unstable"
-            ],
-            "system": "x86_64-darwin",
-            "unfree": false,
-            "version": "2.5.1"
-          },
-          {
-            "attr_path": "overmind",
-            "broken": false,
-            "catalog": "nixpkgs",
-            "derivation": "/nix/store/0v07073dyl01grbahswznbs6zcndnjw6-overmind-2.5.1.drv",
-            "description": "Process manager for Procfile-based applications and tmux",
-            "insecure": false,
-            "install_id": "overmind",
-            "license": "[ MIT ]",
-            "locked_url": "https://github.com/flox/nixpkgs?rev=2631b0b7abcea6e640ce31cd78ea58910d31e650",
-            "missing_builds": false,
-            "name": "overmind-2.5.1",
-            "outputs": [
-              {
-                "name": "out",
-                "store_path": "/nix/store/8fsmxd6gx9572gqmwxv7n0yrdbkrk2rw-overmind-2.5.1"
-              }
-            ],
-            "outputs_to_install": [
-              "out"
-            ],
-            "pkg_path": "overmind",
-            "pname": "overmind",
-            "rev": "2631b0b7abcea6e640ce31cd78ea58910d31e650",
-            "rev_count": 782401,
-            "rev_date": "2025-04-12T13:19:24Z",
-            "scrape_date": "2025-04-14T02:02:05.949010Z",
-            "stabilities": [
-              "unstable"
-            ],
-            "system": "x86_64-linux",
-            "unfree": false,
-            "version": "2.5.1"
-          }
-        ],
-        "page": 782401,
-        "url": ""
-      }
-    }
-  ]
-]


Reviews:
user: login: dcarley
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T11:36:14Z
user: login: zmitchell
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T15:28:44Z
user: login: zmitchell
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T15:30:15Z
user: login: zmitchell
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T15:30:36Z

Review comments:
diff_hunk: @@ -15,6 +15,7 @@
   podman,
   mitmproxy,
   cargo-nextest,
+  daemonize,
path: shells/default/default.nix
user: login: dcarley
body: Why do we provide the package here and in `flox-cli-tests` when it's used from a Flox environment?
created_at: 2025-04-28T11:22:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1398,35 +1398,25 @@ EOF
     version = 1
 
     [install]
-    overmind.pkg-path = "overmind"
+    daemonize.pkg-path = "daemonize"
 
-    [services.overmind]
-    command = "overmind start -D"
+    [services.daemonized_sleep]
+    command = '''
+      daemonize -p "$FLOX_ENV_PROJECT/pidfile" "$(which sleep)" 999999
+    '''
     is-daemon = true
-    shutdown.command = "overmind quit"
+    shutdown.command = '''
+      kill -9 "$(cat $(pwd)/pidfile)"
+    '''
 EOF
 )"
 
   "$FLOX_BIN" init
-  export _FLOX_USE_CATALOG_MOCK="$GENERATED_DATA/resolve/overmind.json"
+  export _FLOX_USE_CATALOG_MOCK="$GENERATED_DATA/resolve/daemonize.json"
   echo "$MANIFEST_CONTENTS" | "$FLOX_BIN" edit -f -
-  echo "sleep: sleep 999999" > ./Procfile
 
-  SCRIPT="$(cat << "EOF"
-    # The timeout below has timed out,
-    # but it is hard to reproduce,
-    # so add set -x for more info in the future.
-    set -euxo pipefail
-
-    timeout 2 bash -c "set -x; while ! overmind status; do sleep .1; done"
-
-    "$FLOX_BIN" services status
-    "$FLOX_BIN" services stop
-EOF
-  )"
-
-  "$FLOX_BIN" activate -s -- bash -c "$SCRIPT"
-  timeout 2 bash -c "while [ -e "$PWD/overmind.sock" ]; do sleep .1; done"
+  run "$FLOX_BIN" activate -s -- bash "${TESTS_DIR}/services/check_daemon_process.sh" >&3-
path: cli/tests/services.bats
user: login: dcarley
body: Was only for debugging while writing the test?
```suggestion
  run "$FLOX_BIN" activate -s -- bash "${TESTS_DIR}/services/check_daemon_process.sh"
```

It makes output noisy and look like a failure:
```
✓ kills daemon process [1320]
+ timeout 2 bash -c 'set -x; while [ ! -e "$(pwd)/pidfile" ]; do sleep .1; done'
++ pwd
+ '[' '!' -e /var/folders/8q/spckhr654cv4xrcv0fxsrlvc0000gn/T/nix-shell.DLf1Jj/bats-run-GXm30l/test/1/test/pidfile ']'
+ /Users/dcarley/projects/flox/flox/cli/target/debug/flox services status
NAME             STATUS        PID
daemonized_sleep Launched    70269

+ /Users/dcarley/projects/flox/flox/cli/target/debug/flox services stop
✅ Service 'daemonized_sleep' stopped
+ timeout 2 bash -c 'set -x; while kill -0 "$(cat "$(pwd)/pidfile")"; do sleep .1; done'
+++ pwd
++ cat /var/folders/8q/spckhr654cv4xrcv0fxsrlvc0000gn/T/nix-shell.DLf1Jj/bats-run-GXm30l/test/1/test/pidfile
+ kill -0 70275
bash: line 1: kill: (70275) - No such process
```
created_at: 2025-04-28T11:36:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1398,35 +1398,25 @@ EOF
     version = 1
 
     [install]
-    overmind.pkg-path = "overmind"
+    daemonize.pkg-path = "daemonize"
 
-    [services.overmind]
-    command = "overmind start -D"
+    [services.daemonized_sleep]
+    command = '''
+      daemonize -p "$FLOX_ENV_PROJECT/pidfile" "$(which sleep)" 999999
+    '''
     is-daemon = true
-    shutdown.command = "overmind quit"
+    shutdown.command = '''
+      kill -9 "$(cat $(pwd)/pidfile)"
+    '''
 EOF
 )"
 
   "$FLOX_BIN" init
-  export _FLOX_USE_CATALOG_MOCK="$GENERATED_DATA/resolve/overmind.json"
+  export _FLOX_USE_CATALOG_MOCK="$GENERATED_DATA/resolve/daemonize.json"
   echo "$MANIFEST_CONTENTS" | "$FLOX_BIN" edit -f -
-  echo "sleep: sleep 999999" > ./Procfile
 
-  SCRIPT="$(cat << "EOF"
-    # The timeout below has timed out,
-    # but it is hard to reproduce,
-    # so add set -x for more info in the future.
-    set -euxo pipefail
-
-    timeout 2 bash -c "set -x; while ! overmind status; do sleep .1; done"
-
-    "$FLOX_BIN" services status
-    "$FLOX_BIN" services stop
-EOF
-  )"
-
-  "$FLOX_BIN" activate -s -- bash -c "$SCRIPT"
-  timeout 2 bash -c "while [ -e "$PWD/overmind.sock" ]; do sleep .1; done"
+  run "$FLOX_BIN" activate -s -- bash "${TESTS_DIR}/services/check_daemon_process.sh" >&3-
path: cli/tests/services.bats
user: login: zmitchell
body: Leftover while debugging the CI failure
created_at: 2025-04-28T15:28:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -15,6 +15,7 @@
   podman,
   mitmproxy,
   cargo-nextest,
+  daemonize,
path: shells/default/default.nix
user: login: zmitchell
body: Just adding it to `flox-cli-tests` doesn't make it available in your devshell if you want to play around with it or test something interactively. Not strictly necessary, but helpful when writing tests that use it.
created_at: 2025-04-28T15:30:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -15,6 +15,7 @@
   podman,
   mitmproxy,
   cargo-nextest,
+  daemonize,
path: shells/default/default.nix
user: login: zmitchell
body: Doesn't strictly need to be added to `flox-cli-tests` anymore though.
created_at: 2025-04-28T15:30:36Z
author_association: CONTRIBUTOR

PR comments:
user: login: zmitchell
created_at: 2025-04-25T01:57:53Z
body: Those failures bode well
author_association: CONTRIBUTOR
user: login: zmitchell
created_at: 2025-04-25T18:01:26Z
body: Actually the failure appears to be an infrastructure issue similar to these:
- https://github.com/flox/flox/actions/runs/14664200799/job/41159214516?pr=3002
- https://github.com/flox/flox/actions/runs/14653909962/job/41125745146?pr=2999
author_association: CONTRIBUTOR