Skip to content

Commit

Permalink
tests: add integration tests
Browse files Browse the repository at this point in the history
to reproduce crash on teardown when using JACK as audio driver.

Test is not done yet. It works properly on non-zero exit codes but not on crashes (which is what we encounter here)
  • Loading branch information
theGreatWhiteShark committed Jan 2, 2024
1 parent 2aec080 commit 8b738b6
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Unit test of Hydrogen's core library. Not to be confused with our [integration tests](../../tests/).

These tests are executed in our **AppVeyor** build pipeline as well as when calling
our [build.sh](../build.sh) script with `t` as argument.
6 changes: 6 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Integration tests used to check more complex use-cases we can not cover using
our [unit tests](../src/tests/).

They are not routinely executed without our **AppVeyor** build pipeline or when
calling our [build.sh](../build.sh) script with `t` as argument. But they are,
nevertheless, designed to exit with code `0` on success and with `1` on failure.
18 changes: 18 additions & 0 deletions tests/jackTearDown/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Integration test to check whether Hydrogen does properly exit without crashing
when using the JACK audio driver.

## Requirements

- `hydrogen` - the system-wide installation is used
- `Go` >= 1.20
- `JACK`

The code is written and tested on **Linux** Devuan. But since the `OSC` package
is written in pure `Go` and all other packages used are part of the standard
library the code _should_ run on **macOS** and **Windows** as well.

## Usage

``` bash
go run main.go
```
5 changes: 5 additions & 0 deletions tests/jackTearDown/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module hydrogen/integrationTests/jackTearDown

go 1.20

require github.com/hypebeast/go-osc v0.0.0-20220308234300-cec5a8a1e5f5
2 changes: 2 additions & 0 deletions tests/jackTearDown/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/hypebeast/go-osc v0.0.0-20220308234300-cec5a8a1e5f5 h1:fqwINudmUrvGCuw+e3tedZ2UJ0hklSw6t8UPomctKyQ=
github.com/hypebeast/go-osc v0.0.0-20220308234300-cec5a8a1e5f5/go.mod h1:lqMjoCs0y0GoRRujSPZRBaGb4c5ER6TfkFKSClxkMbY=
89 changes: 89 additions & 0 deletions tests/jackTearDown/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package main

import (
"fmt"
"log"
"os/exec"
"time"

"github.com/hypebeast/go-osc/osc"
)

// How many times the test should be repeated.
const numberOfTestRuns = 100
const oscHydrogenPort = 9000

// hydrogenStartupTime gives an upper limit for the time Hydrogen requires to
// start up in milliseconds.
const hydrogenStartupTime = 3000

// hydrogenStartupChan is used by startHydrogen() to indicate that Hydrogen was
// started.
var hydrogenStartupChan chan bool

// Integration test checking for errors/crashes when closing Hydrogen while
// using the JACK driver (on Linux).
func main() {
var err error

_, err = exec.LookPath("hydrogen")
if err != nil {
log.Fatalf("[hydrogen] executable could not be found: %v", err.Error())
}

oscClient := osc.NewClient("localhost", oscHydrogenPort)

hydrogenStartupChan = make(chan bool, 1)

for ii := 0; ii < numberOfTestRuns; ii++ {

go killHydrogen(oscClient)

err = startHydrogen()

if err != nil {
log.Fatalf("Hydrogen exited with non-zero code: %v",
err.Error())
}
log.Printf("Instance [%v] terminated without error\n", ii)
}
}

// Start up Hydrogen using the JACK driver and with a configuration that both
// enables OSC and uses a specific port unlikely used by another Hydrogen
// instance (in case another one is already running).
func startHydrogen() error {
hydrogenStartupChan <- true

cmd := exec.Command("hydrogen", "--driver", "jack", "--nosplash")
output, err := cmd.Output()
if err != nil {
return fmt.Errorf("[startHydrogen] Exited with error [%v]:\n%v\n\n",
err, string(output))
}

return nil
}

func killHydrogen(client *osc.Client) {
for {
select {
case <-hydrogenStartupChan:
// Give Hydrogen some time to start up properly
time.Sleep(hydrogenStartupTime * time.Millisecond)

// Hydrogen is ready. Let's shut it down.
msg := osc.NewMessage("/Hydrogen/QUIT")
err := client.Send(msg)
if err != nil {
log.Fatalf("[killHydrogen] Unable to send OSC message: %v",
err.Error())
}
return

default:
time.Sleep(100 * time.Millisecond)
continue
}
}
}

0 comments on commit 8b738b6

Please sign in to comment.