skip to content
==> tests/gen.h <==
1/* The random op generator of the Rust golden tests (tests/common/mod.rs there), identical. */
2#include "mesh/jobs/op.h"
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7
8static mj_spec mkspec(mj_job_id id, const char *items, int32_t prio, uint32_t members, bool setup) {
9    mj_spec s = {.id = id, .program = mstrdup("p"), .op = 254, .priority = prio, .attempts = 3, .mode = MJ_MODE_COLLECT, .submitted_ms = 5, .members = members};
10    if (!mj_ranges_parse(items, &s.items, NULL)) abort();
11    if (setup) {
12        mj_setup su = {6, 0};
13        s.setup = mj_setup_clone(&su, 1);
14        s.nsetup = 1;
15    }
16    return s;
17}
18
19/* ---- the generator the Rust golden test runs (tests/gold_table.rs) ------------------------- */
20
21static uint64_t rs;
22static uint64_t rnd(uint64_t n) {
23    rs ^= rs << 13;
24    rs ^= rs >> 7;
25    rs ^= rs << 17;
26    return rs % (n ? n : 1);
27}
28
29static mj_spec gspec(uint64_t k) {
30    if (k == 0) return mkspec((uint64_t)1 << 32 | 1, "0-200", 0, 0, false);
31    if (k == 1) return mkspec((uint64_t)1 << 32 | 2, "0-", 1, 0, false);
32    return mkspec((uint64_t)2 << 32 | 1, "5-50,100-", 2, 0, false);
33}
34
35static mj_op gen(void) {
36    uint64_t k = rnd(3);
37    mj_spec sp = gspec(k);
38    mj_job_id job = sp.id;
39    mj_op o;
40    switch (rnd(10)) {
41    case 0: o = mj_op_submit(&sp); break;
42    case 1:
43    case 2:
44    case 3: {
45        uint64_t item = rnd(220);
46        mj_res r = {0};
47        r.lease = rnd(5);
48        r.member = (uint32_t)rnd(4);
49        r.result = (uint32_t)rnd(1000);
50        r.out_len = (size_t)rnd(3);
51        r.out = r.out_len ? mxalloc(r.out_len) : NULL;
52        for (size_t i = 0; i < r.out_len; i++) r.out[i] = (uint8_t)rnd(256);
53        if (rnd(2) == 1) {
54            uint8_t f = (uint8_t)rnd(256);
55            r.has_blob = true;
56            memset(r.blob.hash.b, f, 32);
57            r.blob.len = (uint32_t)rnd(10000);
58            r.blob.holders = (uint32_t)rnd(16);
59        }
60        o = mj_op_done(job, item, &r);
61        mj_res_free(&r);
62        break;
63    }
64    case 4:
65    case 5: {
66        uint64_t s = rnd(220), e = s + rnd(30), lease = rnd(5);
67        uint32_t member = (uint32_t)rnd(4);
68        o = mj_op_done_run(job, s, e, lease, member);
69        break;
70    }
71    case 6: {
72        uint64_t item = rnd(220);
73        uint32_t tries = (uint32_t)rnd(4);
74        char why[8];
75        snprintf(why, sizeof why, "w%llu", (unsigned long long)rnd(9));
76        o = mj_op_fail(job, item, tries, why);
77        break;
78    }
79    case 7: {
80        uint64_t item = rnd(220);
81        o = mj_op_fails(job, item, (uint32_t)rnd(5));
82        break;
83    }
84    case 8:
85        switch (rnd(4)) {
86        case 0: o = mj_op_dupes(job, rnd(10)); break;
87        case 1: {
88            uint64_t at = rnd(100);
89            o = mj_op_finish(job, at, 1 + (uint32_t)rnd(3));
90            break;
91        }
92        case 2: {
93            char why[8];
94            snprintf(why, sizeof why, "c%llu", (unsigned long long)rnd(9));
95            o = mj_op_cancel(job, why);
96            break;
97        }
98        default: {
99            uint32_t seq = (uint32_t)rnd(4);
100            o = mj_op_tone(job, seq, (uint32_t)rnd(2));
101        }
102        }
103        break;
104    default: {
105        if (rnd(20) == 0) {
106            o = mj_op_forget(job);
107            break;
108        }
109        uint64_t upto = rnd(220), n = rnd(3);
110        mj_tally tl[3];
111        for (uint64_t i = 0; i < n; i++) {
112            tl[i].member = (uint32_t)rnd(4);
113            tl[i].n = rnd(50);
114        }
115        o = mj_op_fold(job, upto, tl, (size_t)n);
116    }
117    }
118    mj_spec_free(&sp);
119    return o;
120}
121