skip to content
==> tests/spec.c <==
1/* JobSpec's text form both ways (jobs.rs's `ops_frames_and_the_merge` starts with it), and what decode
2 * refuses, with the Rust's messages. */
3#include "mesh/jobs/spec.h"
4#include "mesh/check.h"
5
6#include <stdlib.h>
7#include <string.h>
8
9int main(void) {
10    mj_setup su = {6, 0};
11    mj_spec s = {.id = (uint64_t)1 << 32 | 1, .program = mstrdup("p"), .op = 0xfe, .items = mj_ranges_of(0, 10), .priority = 0,
12                 .attempts = 3, .mode = MJ_MODE_COLLECT, .setup = mj_setup_clone(&su, 1), .nsetup = 1, .submitted_ms = 5, .members = 5};
13    msb b = {0};
14    mj_spec_encode(&s, &b);
15    CHECK_S(msb_str(&b), "id 4294967297 program p op 254 items 0-10 priority 0 attempts 3 deadline 0 mode collect setup 6:0 submitted 5 members 0x5");
16    mj_spec d = {0};
17    char *err = NULL;
18    CHECK(mj_spec_decode(msb_str(&b), &d, &err) && mj_spec_eq(&d, &s));
19    mj_spec_free(&d);
20    /* No setup, members 0, an endless set, a negative priority; and whitespace of every kind. */
21    const char *t = "id 7\tprogram a,b op 3 items 5-,1 priority -2 attempts 1 deadline 9 mode none setup - submitted 0 members 0x0\n";
22    CHECK(mj_spec_decode(t, &d, &err));
23    CHECK(mj_spec_endless(&d) && d.priority == -2 && d.nsetup == 0 && d.members == 0 && d.mode == MJ_MODE_NONE);
24    CHECK(mj_spec_runs(&d, "a") && mj_spec_runs(&d, "b") && !mj_spec_runs(&d, "a,b") && !mj_spec_runs(&d, ""));
25    const char *fp;
26    CHECK_U(mj_spec_first_program(&d, &fp), 1);
27    CHECK(fp[0] == 'a');
28    msb_clear(&b);
29    mj_spec_encode(&d, &b);
30    CHECK_S(msb_str(&b), "id 7 program a,b op 3 items 1-2,5- priority -2 attempts 1 deadline 9 mode none setup - submitted 0 members 0x0");
31    mj_spec_free(&d);
32    /* Refusals: a missing word, a bad number, a bad mode, setup without a colon. */
33    CHECK(!mj_spec_decode("id 7", &d, &err));
34    CHECK_S(err, "job spec \"id 7\"");
35    free(err);
36    CHECK(!mj_spec_decode("id x program p op 1 items 1 priority 0 attempts 1 deadline 0 mode none setup - submitted 0 members 0x0", &d, &err));
37    free(err);
38    CHECK(!mj_spec_decode("id 1 program p op 1 items 1 priority 0 attempts 1 deadline 0 mode all setup - submitted 0 members 0x0", &d, &err));
39    free(err);
40    CHECK(!mj_spec_decode("id 1 program p op 1 items 1 priority 0 attempts 1 deadline 0 mode none setup 6 submitted 0 members 0x0", &d, &err));
41    free(err);
42    /* A bad item set says so in Ranges' words. */
43    CHECK(!mj_spec_decode("id 1 program p op 1 items 5-5 priority 0 attempts 1 deadline 0 mode none setup - submitted 0 members 0x0", &d, &err));
44    CHECK(strncmp(err, "items \"5-5\"", 11) == 0);
45    free(err);
46    /* members: repeated 0x prefixes are trimmed, as trim_start_matches does. */
47    CHECK(mj_spec_decode("id 1 program p op 1 items 1 priority 0 attempts 1 deadline 0 mode none setup - submitted 0 members 0x0xff", &d, &err));
48    CHECK_U(d.members, 255);
49    mj_spec_free(&d);
50    mj_mode m;
51    CHECK(mj_mode_parse("nonzero", &m) && m == MJ_MODE_NONZERO && !mj_mode_parse("Collect", &m));
52    mj_spec_free(&s);
53    msb_free(&b);
54    return mesh_check_done();
55}