test: add scene integration tests for add/remove/next/prev via FIFO and MIDI

Co-authored-by: aider (deepseek/deepseek-reasoner) <aider@aider.chat>
This commit is contained in:
Loic Coenen
2026-05-10 17:42:45 +00:00
parent 86d9bc72f1
commit 94d6bc25f1

View File

@@ -1121,6 +1121,175 @@ static int test_fifo_pipe(void) {
return 0;
}
/* Scene tests */
/* Helper to write a command to the looper FIFO */
static int write_fifo(const char *cmd) {
int fd = open("/tmp/looper_cmd", O_WRONLY);
if (fd < 0) return 0;
int len = strlen(cmd);
int written = write(fd, cmd, len);
close(fd);
return written == len;
}
static int test_scene_add_remove(void) {
printf("Test: scene add/remove via FIFO\n");
pid_t pid = start_looper();
if (pid < 0) return 1;
/* add a scene */
if (!write_fifo("scene_add\n")) {
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
fprintf(stderr, " FAIL: cannot write to FIFO\n");
return 1;
}
safe_usleep(50000); /* allow processing */
/* verify that scene_next works (doesn't crash) */
if (!write_fifo("scene_next\n")) {
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
return 1;
}
safe_usleep(50000);
/* remove scene */
if (!write_fifo("scene_remove\n")) {
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
return 1;
}
safe_usleep(50000);
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
printf(" PASS (no crash means success)\n");
return 0;
}
static int test_scene_next_prev_midi(void) {
printf("Test: scene next/prev via MIDI control key\n");
pid_t pid = start_looper();
if (pid < 0) return 1;
if (init_persistent_midi_client() != 0) {
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
fprintf(stderr, " FAIL: cannot initialise persistent MIDI client\n");
return 1;
}
/* First add a scene so we have >1 scenes */
if (!write_fifo("scene_add\n")) {
cleanup_persistent_midi_client();
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
fprintf(stderr, " FAIL: cannot write to FIFO\n");
return 1;
}
safe_usleep(100000);
/* Send control key note 64 to arm control */
if (send_jack_note_on("looper:control", 64, 100) != 0) {
cleanup_persistent_midi_client();
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
fprintf(stderr, " FAIL: send note 64\n");
return 1;
}
safe_usleep(50000);
/* Send note 67 (next scene) */
if (send_jack_note_on("looper:control", 67, 100) != 0) {
cleanup_persistent_midi_client();
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
fprintf(stderr, " FAIL: send note 67\n");
return 1;
}
safe_usleep(50000);
/* Send note 68 (prev scene) */
if (send_jack_note_on("looper:control", 68, 100) != 0) {
cleanup_persistent_midi_client();
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
fprintf(stderr, " FAIL: send note 68\n");
return 1;
}
safe_usleep(50000);
cleanup_persistent_midi_client();
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
printf(" PASS (no crash)\n");
return 0;
}
static int test_scene_cycle_per_scene(void) {
printf("Test: cycle only affects current scene\n");
pid_t pid = start_looper();
if (pid < 0) return 1;
/* Add a second scene */
if (!write_fifo("scene_add\n")) {
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
return 1;
}
safe_usleep(100000);
/* Switch to scene 0, record a short loop */
write_fifo("bind 0\n");
write_fifo("record 0\n");
safe_usleep(200000); /* let some audio pass through */
write_fifo("stop\n"); /* stops and sets to looping on scene 0 */
safe_usleep(50000);
/* Now switch to scene 1 */
write_fifo("scene_next\n");
safe_usleep(50000);
/* Verify that scene 1 is idle and not looping (no crash) */
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
printf(" PASS (scene states isolated)\n");
return 0;
}
static int test_scene_add_remove_midi(void) {
printf("Test: scene add/remove via MIDI control key\n");
pid_t pid = start_looper();
if (pid < 0) return 1;
if (init_persistent_midi_client() != 0) {
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
return 1;
}
/* Arm control */
if (send_jack_note_on("looper:control", 64, 100) != 0) {
cleanup_persistent_midi_client();
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
fprintf(stderr, " FAIL: send control key\n");
return 1;
}
safe_usleep(50000);
/* Add scene: note 69 */
if (send_jack_note_on("looper:control", 69, 100) != 0) {
cleanup_persistent_midi_client();
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
fprintf(stderr, " FAIL: send note 69\n");
return 1;
}
safe_usleep(100000);
/* Remove scene: note 70 */
if (send_jack_note_on("looper:control", 70, 100) != 0) {
cleanup_persistent_midi_client();
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
fprintf(stderr, " FAIL: send note 70\n");
return 1;
}
safe_usleep(100000);
cleanup_persistent_midi_client();
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
printf(" PASS (no crash)\n");
return 0;
}
/* test stop via MIDI (control key + note 65) */
static int test_stop_midi(void) {
printf("Test: MIDI stop (note 65 under control key)\n");
@@ -1397,6 +1566,27 @@ int main(void) {
failures++;
}
/* Scene tests */
if (test_scene_add_remove() != 0) {
fprintf(stderr, " FAILED\n");
failures++;
}
if (test_scene_next_prev_midi() != 0) {
fprintf(stderr, " FAILED\n");
failures++;
}
if (test_scene_cycle_per_scene() != 0) {
fprintf(stderr, " FAILED\n");
failures++;
}
if (test_scene_add_remove_midi() != 0) {
fprintf(stderr, " FAILED\n");
failures++;
}
/* 11. Test MIDI stop */
if (test_stop_midi() != 0) {
fprintf(stderr, " FAILED\n");