def test_ver_map_verions_in_range(): spec = SpecVerifier.demo() vm = make_random_version_map(spec) vm[1][1] = -1 raises(AssertionError, lambda: check_version_map(vm)) vm[1][1] = spec["numberOfQuestions"] + 1 raises(AssertionError, lambda: check_version_map(vm, spec))
def build_database(server=None, password=None, vermap={}): """Build the database from a pre-set version map. args: vermap (dict): question version map. If empty dict, server will make its own mapping. For the map format see :func:`plom.finish.make_random_version_map`. server (str): password (str): return: str: long multiline string of all the version DB entries. """ if server and ":" in server: s, p = server.split(":") msgr = ManagerMessenger(s, port=p) else: msgr = ManagerMessenger(server) msgr.start() if not password: password = getpass('Please enter the "manager" password: ') check_version_map(vermap) msgr.requestAndSaveToken("manager", password) try: status = msgr.TriggerPopulateDB(vermap) except PlomBenignException: # TODO this should be a more specific exception raise RuntimeError("Server already has a populated database") from None # grab map and sanity check qvmap = msgr.getGlobalQuestionVersionMap() if vermap: assert qvmap == vermap msgr.closeUser() msgr.stop() return status
def test_ver_map_from_dict(): spec = SpecVerifier.demo() spec_dict = spec.get_public_spec_dict() vm = make_random_version_map(spec_dict) check_version_map(vm, spec_dict) check_version_map(vm, spec)
def test_ver_map_check_spec_or_dict(): spec = SpecVerifier.demo() vm = make_random_version_map(spec) vm.pop(1) raises(AssertionError, lambda: check_version_map(vm, spec)) raises(AssertionError, lambda: check_version_map(vm, spec.get_public_spec_dict()))
def test_ver_map_fix_has_ver1_only(): # assumes version 2 is fixed in demo: test will need adjusting if that changes spec = SpecVerifier.demo() vm = make_random_version_map(spec) vm[1][2] = 2 raises(AssertionError, lambda: check_version_map(vm, spec))
def test_ver_map_types4(): spec = SpecVerifier.demo() vm = make_random_version_map(spec) vm[1][2] = "str" raises(AssertionError, lambda: check_version_map(vm))
def test_ver_map_types3(): spec = SpecVerifier.demo() vm = make_random_version_map(spec) vm[1]["2"] = vm[1].pop(2) raises(AssertionError, lambda: check_version_map(vm))
def test_ver_map_fails_if_too_short(): spec = SpecVerifier.demo() vm = make_random_version_map(spec) vm.pop(1) check_version_map(vm) # passes if we don't know spec raises(AssertionError, lambda: check_version_map(vm, spec))
def test_make_rand_ver_map(): spec = SpecVerifier.demo() vm = make_random_version_map(spec) check_version_map(vm) check_version_map(vm, spec)
def buildExamDatabaseFromSpec(spec, db, version_map=None): """Build metadata for exams from spec and insert into the database. Arguments: spec (dict): exam specification, see :func:`plom.SpecVerifier`. db (database): the database to populate. version_map (dict/None): optional predetermined version map keyed by test number and question number. If None, we will build our own random version mapping. For the map format see :func:`plom.finish.make_random_version_map`. Returns: bool: True if succuess. str: a status string, one line per test, ending with an error if failure. Raises: ValueError: if database already populated. KeyError: invalid question selection scheme in spec. """ buildSpecialRubrics(spec, db) if db.areAnyPapersProduced(): raise ValueError("Database already populated") if not version_map: # TODO: move reproducible random seed support to the make fcn? random.seed(spec["privateSeed"]) version_map = make_random_version_map(spec) check_version_map(version_map) ok = True status = "" # build bundles for annotation images # for q in range(1, 1 + spec["numberOfQuestions"]): # for v in range(1, 1 + spec["numberOfVersions"]): # pass # if not db.createAnnotationBundle(q, v): # ok = False # status += "Error making bundle for q.v={}.{}".format(q, v) # build bundle for replacement pages (for page-not-submitted images) if not db.createReplacementBundle(): ok = False status += "Error making bundle for replacement pages" for t in range(1, spec["numberToProduce"] + 1): log.info("Creating DB entry for test {} of {}.".format( t, spec["numberToProduce"])) if db.createTest(t): status += "DB entry for test {:04}:".format(t) else: status += " Error creating" ok = False if db.createIDGroup(t, spec["idPages"]["pages"]): status += " ID" else: status += " Error creating idgroup" ok = False if db.createDNMGroup(t, spec["doNotMark"]["pages"]): status += " DNM" else: status += "Error creating DoNotMark-group" ok = False for g in range(spec["numberOfQuestions"]): # runs from 0,1,2,... gs = str(g + 1) # now a str and 1,2,3,... v = version_map[t][g + 1] assert v in range(1, spec["numberOfVersions"] + 1) if spec["question"][gs]["select"] == "fix": vstr = "f{}".format(v) assert v == 1 elif spec["question"][gs]["select"] == "shuffle": vstr = "v{}".format(v) # elif spec["question"][gs]["select"] == "param": # vstr = "p{}".format(v) else: raise KeyError( 'Invalid spec: question {} "select" of "{}" is unexpected'. format(gs, spec["question"][gs]["select"])) # if db.createQGroup(t, int(gs), v, spec["question"][gs]["pages"], int(spec["question"][gs]["mark"])): if db.createQGroup(t, int(gs), v, spec["question"][gs]["pages"]): status += " Q{}{}".format(gs, vstr) else: status += "Error creating Question {} ver {}".format(gs, vstr) ok = False status += "\n" return ok, status