#include "naut/script.h" #include "test.h" #include #include #include #include #include #ifndef NAUT_PHASE7_SCRIPT #define NAUT_PHASE7_SCRIPT "tests/fixtures/phase7.lua" #endif typedef struct { _Atomic unsigned calls; pthread_t caller; uint64_t torrent_id; uint32_t file_index; char destination[128]; } move_capture; static naut_err capture_move(void *opaque, uint64_t torrent_id, uint32_t file_index, const char *destination) { move_capture *capture = opaque; capture->caller = pthread_self(); capture->torrent_id = torrent_id; capture->file_index = file_index; snprintf(capture->destination, sizeof capture->destination, "%s", destination); atomic_fetch_add(&capture->calls, 1); return NAUT_OK; } /* Hand the script a single label "anime" so the fixture can route on it. */ static char **capture_labels(void *opaque, uint64_t torrent_id, size_t *count) { (void)opaque; (void)torrent_id; char **labels = malloc(sizeof *labels); if (!labels) { *count = 0; return NULL; } labels[0] = strdup("anime"); *count = labels[0] ? 1 : 0; return labels; } int main(void) { pthread_t owner = pthread_self(); move_capture capture = {0}; naut_event_bus *events = naut_event_bus_create(); naut_err error; naut_script_host host = { .move_file = capture_move, .labels = capture_labels, .context = &capture, }; naut_script *script = naut_script_create( events, NAUT_PHASE7_SCRIPT, 8, &host, &error); CHECK(script && error == NAUT_OK); naut_event event = { .type = NAUT_EVENT_TORRENT_FINISHED, .torrent_id = 42, }; naut_event_emit(events, &event); for (unsigned i = 0; i < 100; i++) { naut_script_stats pending; naut_script_get_stats(script, &pending); if (pending.handled == 1) break; usleep(1000); } CHECK_EQ(atomic_load(&capture.calls), 0); event = (naut_event) { .type = NAUT_EVENT_FILE_COMPLETE, .torrent_id = 42, .index = 3, .path = "/tmp/completed-file", }; naut_event_emit(events, &event); for (unsigned i = 0; i < 100 && atomic_load(&capture.calls) < 1; i++) usleep(1000); CHECK_EQ(atomic_load(&capture.calls), 1); CHECK(!pthread_equal(owner, capture.caller)); CHECK_EQ(capture.torrent_id, 42); CHECK_EQ(capture.file_index, 3); /* Proves naut.get_labels surfaced the label string into Lua. */ CHECK(strcmp(capture.destination, "/tmp/completed-file.anime") == 0); naut_script_stats stats; naut_script_get_stats(script, &stats); CHECK_EQ(stats.queued, 2); CHECK_EQ(stats.handled, 2); CHECK_EQ(stats.errors, 0); CHECK_EQ(stats.move_requests, 1); naut_script_destroy(script); naut_event_bus_destroy(events); TEST_MAIN_END(); }