resrc_flow_t *resrc_flow_new_from_json (json_t *o, resrc_flow_t *parent) { json_t *jhierarchyo = NULL; /* json hierarchy object */ const char *basename = NULL; const char *name = NULL; const char *hierarchy = NULL; const char *path = NULL; const char *hierarchy_path = NULL; const char *tmp = NULL; const char *type = NULL; int64_t id; int64_t ssize; resrc_flow_t *resrc_flow = NULL; resrc_t *flow_resrc; resrc_t *resrc = NULL; size_t size = 1; uuid_t uuid; if (!Jget_str (o, "type", &type)) goto ret; Jget_str (o, "basename", &basename); Jget_str (o, "name", &name); if (!(Jget_int64 (o, "id", &id))) id = -1; if (Jget_str (o, "uuid", &tmp)) uuid_parse (tmp, uuid); else uuid_clear(uuid); if (Jget_int64 (o, "size", &ssize)) size = (size_t) ssize; if ((jhierarchyo = Jobj_get (o, "hierarchy"))) { /* Get first key and value from hierarchy object */ const char *key = json_object_iter_key (json_object_iter (jhierarchyo)); if (key) { hierarchy = key; Jget_str (jhierarchyo, key, &hierarchy_path); } } if (!Jget_str (o, "path", &path)) { if (hierarchy_path) path = xstrdup (hierarchy_path); } if (!path) { if (parent) path = xasprintf ("%s/%s", resrc_path (parent->flow_resrc), name); else path = xasprintf ("/%s", name); } if (!(flow_resrc = resrc_new_resource (type, path, basename, name, NULL, id, uuid, size))) goto ret; if (!strncmp (type, "node", 5)) { resrc = resrc_lookup (name); } if ((resrc_flow = resrc_flow_new (parent, flow_resrc, resrc))) { /* add time window if we are given a start time */ int64_t starttime; if (Jget_int64 (o, "starttime", &starttime)) { json_t * w = Jnew (); char *json_str; int64_t endtime; int64_t wall_time; Jadd_int64 (w, "starttime", starttime); if (!Jget_int64 (o, "endtime", &endtime)) { if (Jget_int64 (o, "walltime", &wall_time)) endtime = starttime + wall_time; else endtime = TIME_MAX; } Jadd_int64 (w, "endtime", endtime); json_str = xstrdup (Jtostr (w)); resrc_twindow_insert (resrc_flow->flow_resrc, "0", (void *) json_str); Jput (w); } } if (resrc) resrc_graph_insert (resrc, hierarchy, resrc_flow); ret: return resrc_flow; }
static void test_temporal_allocation () { int rc = 0; size_t available; resrc_t *resource = resrc_new_resource ("custom", "/test", "test", "test1", NULL, 1, NULL, 10); available = resrc_available_at_time (resource, 0); rc = (rc || !(available == 10)); available = resrc_available_during_range (resource, 0, 1000, false); rc = (rc || !(available == 10)); ok (!rc, "resrc_available...(time/range) on unallocated resource work"); // Setup the resource allocations for the rest of the tests resrc_stage_resrc (resource, 5, NULL); rc = (rc || resrc_allocate_resource (resource, 1, 1, 1000)); resrc_stage_resrc (resource, 10, NULL); rc = (rc || resrc_allocate_resource (resource, 2, 2000, 3000)); ok (!rc, "Temporal allocation setup works"); if (rc) { return; } // Start the actual testing resrc_stage_resrc (resource, 1, NULL); // This should fail rc = (rc || !resrc_allocate_resource (resource, 3, 10, 3000)); // This should work rc = (rc || resrc_allocate_resource (resource, 3, 10, 1999)); ok (!rc, "Overlapping temporal allocations work"); if (rc) { return; } // Test "available at time" // Job 1 available = resrc_available_at_time (resource, 1); rc = (rc || !(available == 5)); // Jobs 1 & 3 available = resrc_available_at_time (resource, 10); rc = (rc || !(available == 4)); available = resrc_available_at_time (resource, 500); rc = (rc || !(available == 4)); available = resrc_available_at_time (resource, 1000); rc = (rc || !(available == 4)); // Job 3 available = resrc_available_at_time (resource, 1500); rc = (rc || !(available == 9)); available = resrc_available_at_time (resource, 1999); rc = (rc || !(available == 9)); // Job 2 available = resrc_available_at_time (resource, 2000); rc = (rc || !(available == 0)); available = resrc_available_at_time (resource, 2500); rc = (rc || !(available == 0)); available = resrc_available_at_time (resource, 3000); rc = (rc || !(available == 0)); // No Jobs available = resrc_available_at_time (resource, 3001); rc = (rc || !(available == 10)); ok (!rc, "resrc_available_at_time works"); if (rc) { return; } // Test "available during range" // Range == job window (both edges are the same) available = resrc_available_during_range (resource, 2000, 3000, false); rc = (rc || !(available == 0)); available = resrc_available_during_range (resource, 0, 1000, false); rc = (rc || !(available == 4)); available = resrc_available_during_range (resource, 10, 1999, false); rc = (rc || !(available == 4)); ok (!rc, "resrc_available_during_range: range == job window works"); rc = 0; // Range is a subset of job window (no edges are the same) available = resrc_available_during_range (resource, 4, 6, false); rc = (rc || !(available == 5)); available = resrc_available_during_range (resource, 20, 999, false); rc = (rc || !(available == 4)); available = resrc_available_during_range (resource, 1001, 1998, false); rc = (rc || !(available == 9)); available = resrc_available_during_range (resource, 2500, 2600, false); rc = (rc || !(available == 0)); ok (!rc, "resrc_available_during_range: range is a subset (no edges) works"); rc = 0; // Range is a subset of a job window (one edge is the same) available = resrc_available_during_range (resource, 0, 999, false); rc = (rc || !(available == 4)); available = resrc_available_during_range (resource, 10, 999, false); rc = (rc || !(available == 4)); available = resrc_available_during_range (resource, 20, 1000, false); rc = (rc || !(available == 4)); available = resrc_available_during_range (resource, 1001, 1999, false); rc = (rc || !(available == 9)); available = resrc_available_during_range (resource, 1001, 1999, false); rc = (rc || !(available == 9)); ok (!rc, "resrc_available_during_range: range is a subset (1 edge) works"); rc = 0; // Range overlaps 1 job window // (no edges are exactly equal) available = resrc_available_during_range (resource, 2500, 4000, false); rc = (rc || !(available == 0)); // (1 edge is exactly equal) available = resrc_available_during_range (resource, 3000, 5000, false); rc = (rc || !(available == 0)); ok (!rc, "resrc_available_during_range: range overlaps 1 job works"); rc = 0; // Range overlaps multiple job windows // (no edges are exactly equal) available = resrc_available_during_range (resource, 100, 1500, false); rc = (rc || !(available == 4)); available = resrc_available_during_range (resource, 1500, 2500, false); rc = (rc || !(available == 0)); // (some edges are exactly equal) available = resrc_available_during_range (resource, 1000, 2000, false); rc = (rc || !(available == 0)); ok (!rc, "resrc_available_during_range: range overlaps multiple job works"); rc = 0; // Range overlaps all job windows (edges exactly equal) available = resrc_available_during_range (resource, 0, 3000, false); rc = (rc || !(available == 0)); available = resrc_available_during_range (resource, 0, 2000, false); rc = (rc || !(available == 0)); // Range overlaps no job windows available = resrc_available_during_range (resource, 3001, 5000, false); rc = (rc || !(available == 10)); ok (!rc, "resrc_available_during_range: range overlaps all job works"); resrc_resource_destroy (resource); }