Esempio n. 1
0
func checkChildWorkUnits(t *testing.T, j *jobserver.JobServer, parent, child, workSpecName string, expected map[string]map[string]interface{}) {
	missing := make(map[string]struct{})
	for name := range expected {
		missing[name] = struct{}{}
	}
	units, msg, err := j.GetChildWorkUnits(parent)
	if !assert.NoError(t, err) {
		return
	}
	assert.Empty(t, msg)
	assert.Len(t, units, 1)
	if assert.Contains(t, units, child) {
		for _, unit := range units[child] {
			assert.Equal(t, child, unit["worker_id"])
			assert.Equal(t, workSpecName, unit["work_spec_name"])
			if assert.IsType(t, []byte{}, unit["work_unit_key"]) {
				bName := unit["work_unit_key"].([]byte)
				name := string(bName)
				if assert.Contains(t, expected, name) {
					assert.Equal(t, expected[name], unit["work_unit_data"])
				}
				assert.Contains(t, missing, name, "duplicate child work unit")
				delete(missing, name)
			}
		}
	}
	assert.Empty(t, missing)
}
Esempio n. 2
0
func getOneWork(t *testing.T, j *jobserver.JobServer) (ok bool, workSpecName, workUnitKey string, workUnitData map[string]interface{}) {
	anything, msg, err := j.GetWork("test", map[string]interface{}{"available_gb": 1})
	if !assert.NoError(t, err) {
		return
	}
	assert.Empty(t, msg)
	// Since we didn't request multiple work units we should always
	// get at most one, but maybe none
	if assert.NotNil(t, anything) &&
		assert.IsType(t, cborrpc.PythonTuple{}, anything) {
		tuple := anything.(cborrpc.PythonTuple)
		if assert.Len(t, tuple.Items, 3) {
			// "no work unit" gets returned as tuple (nil,
			// nil, nil)
			if tuple.Items[0] != nil &&
				assert.IsType(t, "", tuple.Items[0]) &&
				assert.IsType(t, []byte{}, tuple.Items[1]) &&
				assert.IsType(t, map[string]interface{}{}, tuple.Items[2]) {
				ok = true
				workSpecName = tuple.Items[0].(string)
				bWorkUnitKey := tuple.Items[1].([]byte)
				workUnitKey = string(bWorkUnitKey)
				workUnitData = tuple.Items[2].(map[string]interface{})
			}
		}
	}
	return
}
Esempio n. 3
0
// listWorkUnits calls GetWorkUnits (as the similarly-named Python
// function does) and validates that the response matches an expected
// set of work units.
func listWorkUnits(t *testing.T, j *jobserver.JobServer, workSpecName string, options map[string]interface{}, expected map[string]map[string]interface{}) {
	gwu, msg, err := j.GetWorkUnits(workSpecName, options)
	if !assert.NoError(t, err) {
		return
	}
	assert.Empty(t, msg)
	missing := make(map[string]struct{})
	for name := range expected {
		missing[name] = struct{}{}
	}
	for _, item := range gwu {
		if !assert.IsType(t, cborrpc.PythonTuple{}, item) {
			continue
		}
		tuple := item.(cborrpc.PythonTuple)
		if !assert.Len(t, tuple.Items, 2) {
			continue
		}
		if !assert.IsType(t, []byte{}, tuple.Items[0]) {
			continue
		}
		name := string(tuple.Items[0].([]byte))
		assert.IsType(t, map[string]interface{}{}, tuple.Items[1])
		if assert.Contains(t, expected, name, "unexpected work unit") {
			assert.Equal(t, expected[name], tuple.Items[1])
		}
		assert.Contains(t, missing, name, "duplicate work unit")
		delete(missing, name)
	}
}
Esempio n. 4
0
// checkWorkUnitStatus makes a weak assertion about a specific work
// unit's status by calling GetWorkUnitStatus for it.
func checkWorkUnitStatus(t *testing.T, j *jobserver.JobServer, workSpecName, workUnitKey string, status jobserver.WorkUnitStatus) {
	dicts, msg, err := j.GetWorkUnitStatus(workSpecName, []string{workUnitKey})
	if assert.NoError(t, err) {
		assert.Empty(t, msg)
		if assert.Len(t, dicts, 1) {
			assert.Equal(t, status, dicts[0]["status"])
		}
	}
}
Esempio n. 5
0
// addWorkUnit packages a single work unit key and data dictionary
// into the tuple format JobServer expects, and calls AddWorkUnits(),
// checking the result.
func addWorkUnit(t *testing.T, j *jobserver.JobServer, workSpecName, key string, data map[string]interface{}) {
	keyDataPair := cborrpc.PythonTuple{Items: []interface{}{key, data}}
	keyDataList := []interface{}{keyDataPair}
	ok, msg, err := j.AddWorkUnits(workSpecName, keyDataList)
	if assert.NoError(t, err) {
		assert.True(t, ok)
		assert.Empty(t, msg)
	}
}
Esempio n. 6
0
// setWorkSpec calls the eponymous JobServer function, checking that
// it ran successfully, and returns the work spec name on success.
func setWorkSpec(t *testing.T, j *jobserver.JobServer, workSpec map[string]interface{}) string {
	ok, msg, err := j.SetWorkSpec(workSpec)
	if assert.NoError(t, err) {
		assert.True(t, ok)
		assert.Empty(t, msg)
	}

	workSpecName, ok := workSpec["name"].(string)
	assert.True(t, ok, "workSpec[\"name\"] not a string")
	return workSpecName
}
Esempio n. 7
0
// finishWorkUnit marks a specific work unit as finished.
func finishWorkUnit(t *testing.T, j *jobserver.JobServer, workSpecName, workUnitKey string, data map[string]interface{}) {
	options := map[string]interface{}{
		"status": jobserver.Finished,
	}
	if data != nil {
		options["data"] = data
	}
	ok, msg, err := j.UpdateWorkUnit(workSpecName, workUnitKey, options)
	if assert.NoError(t, err) {
		assert.True(t, ok)
		assert.Empty(t, msg)
	}
}
Esempio n. 8
0
// addPrefixedWorkUnits adds a series of similarly-named work units
// to a work spec.  If prefix is "u", it adds count work units named
// u001, u002, ....  The work spec dictionaries have a single key "k"
// with values v1, v2, ....
func addPrefixedWorkUnits(t *testing.T, j *jobserver.JobServer, workSpecName, prefix string, count int) {
	workUnitKvps := make([]interface{}, count)
	for i := range workUnitKvps {
		key := fmt.Sprintf("%s%03d", prefix, i+1)
		data := map[string]interface{}{"k": fmt.Sprintf("v%v", i+1)}
		items := []interface{}{key, data}
		workUnitKvps[i] = cborrpc.PythonTuple{Items: items}
	}
	ok, msg, err := j.AddWorkUnits(workSpecName, workUnitKvps)
	if assert.NoError(t, err) {
		assert.True(t, ok)
		assert.Empty(t, msg)
	}
}
Esempio n. 9
0
// addWorkUnits adds a batch of work units to the system in one call.
func addWorkUnits(t *testing.T, j *jobserver.JobServer, workSpecName string, workUnits map[string]map[string]interface{}) {
	// Assemble the parameters to AddWorkUnits as one big list of
	// pairs of (key, data)
	var awu []interface{}
	for name, data := range workUnits {
		pair := []interface{}{name, data}
		awu = append(awu, pair)
	}
	ok, msg, err := j.AddWorkUnits(workSpecName, awu)
	if assert.NoError(t, err) {
		assert.True(t, ok)
		assert.Empty(t, msg)
	}
}
Esempio n. 10
0
// delWorkUnitsBy is the core of the DelWorkUnits tests that expect to
// delet single work units.  It calls options(state) to get options
// to DelWorkUnits, and verifies that this deletes the single work unit
// associated with state.
func delWorkUnitsBy(t *testing.T, j *jobserver.JobServer, n int, state jobserver.WorkUnitStatus, options func(jobserver.WorkUnitStatus) map[string]interface{}) {
	workSpecName, expected := prepareSomeOfEach(t, j, n)
	delete(expected, stateShortName[state])

	count, msg, err := j.DelWorkUnits(workSpecName, options(state))
	if assert.NoError(t, err) {
		assert.Equal(t, 1, count)
		assert.Empty(t, msg)
	}
	listWorkUnits(t, j, workSpecName, gwuEverything, expected)

	_, err = j.Clear()
	assert.NoError(t, err)
}
Esempio n. 11
0
// prioritizeWorkUnit changes the priority of a single work unit.
func prioritizeWorkUnit(t *testing.T, j *jobserver.JobServer, workSpecName, key string, priority int, adjust bool) {
	options := map[string]interface{}{
		"work_unit_keys": []interface{}{key},
	}
	if adjust {
		options["priority"] = nil
		options["adjustment"] = priority
	} else {
		options["priority"] = priority
		options["adjustment"] = nil
	}
	ok, msg, err := j.PrioritizeWorkUnits(workSpecName, options)
	if assert.NoError(t, err) {
		assert.True(t, ok)
		assert.Empty(t, msg)
	}
}
Esempio n. 12
0
// getSpecificWork calls GetWork expecting a specific work unit to
// come back, and returns its data dictionary.
func getSpecificWork(t *testing.T, j *jobserver.JobServer, workSpecName, workUnitKey string) map[string]interface{} {
	anything, msg, err := j.GetWork("test", map[string]interface{}{"available_gb": 1})
	if !assert.NoError(t, err) {
		return nil
	}
	assert.Empty(t, msg)
	if assert.NotNil(t, anything) && assert.IsType(t, cborrpc.PythonTuple{}, anything) {
		tuple := anything.(cborrpc.PythonTuple)
		if assert.Len(t, tuple.Items, 3) && assert.NotNil(t, tuple.Items[0]) {
			assert.Equal(t, workSpecName, tuple.Items[0])
			assert.Equal(t, []byte(workUnitKey), tuple.Items[1])
			if assert.IsType(t, tuple.Items[2], map[string]interface{}{}) {
				return tuple.Items[2].(map[string]interface{})
			}
		}
	}
	return nil
}
Esempio n. 13
0
// getOneWorkUnit calls GetWorkUnits for a single specific work unit,
// checks the results, and returns its data dictionary (or nil if absent).
func getOneWorkUnit(t *testing.T, j *jobserver.JobServer, workSpecName, workUnitKey string) map[string]interface{} {
	list, msg, err := j.GetWorkUnits(workSpecName, map[string]interface{}{"work_unit_keys": []interface{}{workUnitKey}})
	if !assert.NoError(t, err) {
		return nil
	}
	assert.Empty(t, msg)
	if !assert.Len(t, list, 1) {
		return nil
	}
	if !assert.IsType(t, cborrpc.PythonTuple{}, list[0]) {
		return nil
	}
	tuple := list[0].(cborrpc.PythonTuple)
	if !assert.Len(t, tuple.Items, 2) {
		return nil
	}
	assert.Equal(t, []byte(workUnitKey), tuple.Items[0])
	if assert.IsType(t, map[string]interface{}{}, tuple.Items[1]) {
		return tuple.Items[1].(map[string]interface{})
	}
	return nil
}
Esempio n. 14
0
func prepareSomeOfEach(t *testing.T, j *jobserver.JobServer, n int) (workSpecName string, expected map[string]map[string]interface{}) {
	data := map[string]interface{}{"x": 1}
	expected = map[string]map[string]interface{}{}
	workSpecName = setWorkSpec(t, j, WorkSpecData)

	for _, name := range []string{"FA", "IL"}[:n] {
		addWorkUnit(t, j, workSpecName, name, data)
		getSpecificWork(t, j, workSpecName, name)
		ok, msg, err := j.UpdateWorkUnit(workSpecName, name, map[string]interface{}{"status": jobserver.Failed})
		if assert.NoError(t, err) {
			assert.True(t, ok)
			assert.Empty(t, msg)
		}
		expected[name] = data
	}

	for _, name := range []string{"FI", "NI"}[:n] {
		addWorkUnit(t, j, workSpecName, name, data)
		getSpecificWork(t, j, workSpecName, name)
		finishWorkUnit(t, j, workSpecName, name, nil)
		expected[name] = data
	}

	for _, name := range []string{"PE", "ND"}[:n] {
		addWorkUnit(t, j, workSpecName, name, data)
		getSpecificWork(t, j, workSpecName, name)
		expected[name] = data
	}

	for _, name := range []string{"AV", "AI"}[:n] {
		addWorkUnit(t, j, workSpecName, name, data)
		expected[name] = data
	}

	return
}