示例#1
0
def test_subgraph() -> None:
    """Test that we can isolate the required operators for parametrization."""
    with Fun(MockServer(), options(distributed=False)) as db:
        dat = put(b"bla bla")
        step1 = morph(capitalize, dat)
        step2 = shell("cat file1 file2", inp=dict(file1=step1, file2=dat))

        # random not included ops
        stepA = shell("echo 'bla'")
        _ = concat(dat, dat)
        _ = morph(capitalize, b"another word")

        final = shell("cat file1 file2",
                      inp={
                          "file1": stepA.stdout,
                          "file2": step2.stdout
                      })

        ops = _p._parametrize_subgraph(db, {"input": dat},
                                       {"output": final.stdout})
        assert len(ops) == 3
        assert step1.parent in ops
        assert step2.hash in ops
        assert final.hash in ops

        # get edges
        edges = _p._subgraph_edges(db, ops)
        print(edges)
示例#2
0
def test_dag_dump() -> None:
    """Test simple DAG dump to file."""
    with Fun(MockServer(), options(distributed=False)) as db:
        dat = put(b"bla bla")
        dat2 = put(b"blaXbla")
        errorstep = morph(raises, dat2)
        step1 = morph(upper, dat)
        step2 = shell("cat file1 file2", inp=dict(file1=step1, file2=dat))
        step2b = utils.concat(step2.stdout, errorstep, strict=False)
        step3 = shell("cat file1", inp=dict(file1=step2b))

        step4 = shell("cat file1", inp=dict(file1=step1))
        step4b = shell("cat file2", inp=dict(file2=step4.stdout))

        out = utils.concat(step1, dat, step2.stdout, step3.stdout)

        _dag.build_dag(db, out.hash)
        execute(step2b)
        execute(step4b)
        wait_for(step4b, 1.0)
        reset(step4)

        nodes, artefacts, labels, links = _graphviz.export(
            db, [out.hash, step4b.hash])
        dot = _graphviz.format_dot(nodes, artefacts, labels, links,
                                   [out.hash, step4b.hash])
        assert len(dot) > 0
        assert len(nodes) == 8
        assert len(labels) == 8

        # TODO pass through dot for testing?
        with open("g.dot", "w") as f:
            f.write(dot)
示例#3
0
def test_toposort() -> None:
    """Test that we can topologically sort the subset."""
    with Fun(MockServer(), options(distributed=False)) as db:
        dat = put(b"bla bla")
        step1 = morph(capitalize, dat)
        step2 = shell("cat file1 file2", inp=dict(file1=step1, file2=dat))

        # random not included ops
        stepA = shell("echo 'bla'")
        _ = concat(dat, dat)
        _ = morph(capitalize, b"another word")

        final = shell("cat file1 file2",
                      inp={
                          "file1": stepA.stdout,
                          "file2": step2.stdout
                      })

        ops = _p._parametrize_subgraph(db, {"input": dat},
                                       {"output": final.stdout})
        edges = _p._subgraph_edges(db, ops)
        sorted_ops = _p._subgraph_toposort(ops, edges)
        assert sorted_ops[0] == step1.parent
        assert sorted_ops[1] == step2.hash
        assert sorted_ops[2] == final.hash
示例#4
0
def test_double_execution(nworkers: int) -> None:
    """Test multiple executions of the same task."""
    # This test will fail if a job is re-executed multiple times.
    # external
    from rq.job import get_current_job

    def track_runs(inp: bytes) -> bytes:
        job = get_current_job()
        db: Redis[bytes] = job.connection
        val = db.incrby("sentinel", 1)
        time.sleep(0.5)
        return str(val).encode()

    with f.ManagedFun(nworkers=nworkers):
        # wait_for_workers(db, nworkers)
        dat = f.put(b"bla bla")
        step1 = f.morph(track_runs, dat)

        step1a = f.shell(
            "cat file1",
            inp=dict(file1=step1),
        )

        step1b = f.shell(
            "cat file2",
            inp=dict(file2=step1),
        )

        f.execute(step1a)
        f.execute(step1b)
        f.wait_for(step1a, timeout=10.0)
        f.wait_for(step1b, timeout=10.0)
        assert f.take(step1a.stdout) == b"1"
示例#5
0
def test_error_propagation_shell() -> None:
    """Test propagation of errors."""
    db = Redis()
    store = RedisStorage(db)
    s1 = funsies.shell(
        "cp file1 file3",
        inp=dict(file1="bla"),
        out=["file2"],
        connection=(db, store),
        opt=options(),
    )
    s2 = funsies.shell(
        "cat file2",
        inp=dict(file2=s1.out["file2"]),
        connection=(db, store),
        opt=options(),
    )
    s3 = funsies.shell(
        "cat file2",
        inp=dict(file2=s1.out["file2"]),
        strict=False,
        connection=(db, store),
        opt=options(),
    )

    run_op(db, store, s1.op.hash)
    run_op(db, store, s2.op.hash)
    with pytest.raises(UnwrapError):
        funsies.take(s2.stderr, connection=(db, store))

    run_op(db, store, s3.op.hash)
    assert funsies.take(s3.stderr, connection=(db, store)) != b""
    assert isinstance(funsies.take(s3.returncode, connection=(db, store)), int)
    assert funsies.take(s3.returncode, connection=(db, store)) != 0
示例#6
0
def test_dag_execute_same_root() -> None:
    """Test execution of two dags that share the same origin."""
    with Fun(MockServer(), defaults=options(distributed=False)):
        dat = put(b"bla bla")
        step1 = morph(lambda x: x.decode().upper().encode(), dat)
        step2 = shell("cat file1 file2", inp=dict(file1=step1, file2=dat))
        step2b = shell("cat file1", inp=dict(file1=step1))

        execute(step2)
        out = take(step2.stdout)
        assert out == b"BLA BLAbla bla"

        execute(step2b)
        out = take(step2b.stdout)
        assert out == b"BLA BLA"
示例#7
0
def test_error_propagation() -> None:
    """Test propagation of errors."""
    with Fun(MockServer()):
        db, store = get_connection()
        s1 = funsies.shell("cp file1 file3",
                           inp=dict(file1="bla"),
                           out=["file2"])
        s2 = funsies.shell("cat file1 file2",
                           inp=dict(file1="a file", file2=s1.out["file2"]))
        run_op(db, store, s1.op.hash)
        run_op(db, store, s2.op.hash)
        out = funsies.take(s2.stdout, strict=False)
        print(out)
        assert isinstance(out, Error)
        assert out.source == s1.op.hash
示例#8
0
def test_parametric() -> None:
    """Test that parametric DAGs work."""
    with Fun(MockServer(), options(distributed=False)) as db:
        dat = put(b"bla bla")
        step1 = morph(capitalize, dat)
        step2 = shell("cat file1 file2", inp=dict(file1=step1, file2=dat))
        final = shell("cat file1 file3",
                      inp={
                          "file1": step1,
                          "file3": step2.stdout
                      })

        param = _p.make_parametric(db, "param", {"input": dat},
                                   {"output": final.stdout})
        param2 = _p.Parametric.grab(db, param.hash)
        assert param == param2
示例#9
0
def test_error_propagation_morph() -> None:
    """Test propagation of errors."""
    with Fun(MockServer()):
        db, store = get_connection()
        s1 = funsies.shell("cp file1 file3",
                           inp=dict(file1="bla"),
                           out=["file2"])

        def fun_strict(inp: bytes) -> bytes:
            return inp

        def fun_lax(inp: Result[bytes]) -> bytes:
            return b"bla bla"

        s2 = funsies.morph(fun_strict, s1.out["file2"])
        s3 = funsies.morph(fun_lax, s1.out["file2"])
        s4 = funsies.morph(fun_lax, s1.out["file2"], strict=False)

        run_op(db, store, s1.op.hash)
        run_op(db, store, s2.parent)

        out = funsies.take(s2, strict=False)
        assert isinstance(out, Error)
        assert out.source == s1.op.hash

        print(s3.parent)
        run_op(db, store, s3.parent)
        out = funsies.take(s3, strict=False)
        assert isinstance(out, Error)
        assert out.source == s1.op.hash

        run_op(db, store, s4.parent)
        out = funsies.take(s4)
        assert out == b"bla bla"
示例#10
0
def test_subdag() -> None:
    """Test that subdags execute properly."""
    def cap(inp: bytes) -> bytes:
        return inp.upper()

    def map_reduce(
            inputs: dict[str, bytes]) -> dict[str, _graph.Artefact[bytes]]:
        """Basic map reduce."""
        inp_data = inputs["inp"].split(b" ")
        out: list[_graph.Artefact[bytes]] = []
        for el in inp_data:
            out += [morph(cap, el, opt=options(distributed=False))]
        return {"out": concat(*out, join="-")}

    with Fun(MockServer(), defaults=options(distributed=False)) as db:
        dat = put(b"bla bla lol what")
        inp = {"inp": dat}
        cmd = _subdag.subdag_funsie(map_reduce, {"inp": Encoding.blob},
                                    {"out": Encoding.blob})
        operation = _graph.make_op(db, cmd, inp, options())
        out = _graph.Artefact[bytes].grab(db, operation.out["out"])

        final = shell(
            "cat file1 file2",
            inp=dict(file1=out, file2=b"something"),
        )

        execute(final)
        data = take(final.stdout)
        assert data == b"BLA-BLA-LOL-WHATsomething"
示例#11
0
def test_dag_execute2() -> None:
    """Test execution of a _dag."""
    with Fun(MockServer(), defaults=options(distributed=False)):
        dat = put(b"bla bla")
        step1 = morph(lambda x: x.decode().upper().encode(), dat)
        step2 = shell("cat file1 file2", inp=dict(file1=step1, file2=dat))
        step11 = shell("echo 'bla'")
        final = shell("cat file1 file2",
                      inp={
                          "file1": step11.stdout,
                          "file2": step2.stdout
                      })
        output = final.stdout

        # make queue
        execute(output)
        out = take(output)
        assert out == b"bla\nBLA BLAbla bla"
示例#12
0
def test_parametric_eval() -> None:
    """Test that parametric evaluate properly."""
    with Fun(MockServer(), options(distributed=False)) as db:
        dat = put(b"bla bla")
        step1 = morph(capitalize, dat)
        step2 = shell("cat file1 file2", inp=dict(file1=step1, file2=dat))
        final = shell("cat file1 file3",
                      inp={
                          "file1": step1,
                          "file3": step2.stdout
                      })
        execute(final.stdout)
        # b'BLA BLABLA BLAbla bla'

        param = _p.make_parametric(db, "param", {"input": dat},
                                   {"output": final.stdout})
        dat2 = put(b"lol lol")
        out = param.evaluate(db, {"input": dat2})
        execute(out["output"])
        assert take(out["output"]) == b"LOL LOLLOL LOLlol lol"
示例#13
0
def test_not_generated() -> None:
    """What happens when an artefact is not generated?"""
    with Fun(MockServer()):
        db, store = get_connection()
        s = funsies.shell("cp file1 file2",
                          inp=dict(file1="bla"),
                          out=["file3"])
        run_op(db, store, s.op.hash)
        assert funsies.take(s.returncode) == 0
        with pytest.raises(UnwrapError):
            funsies.take(s.out["file3"])
示例#14
0
def optimize_conformer_xtb(structure: Artefact[bytes]) -> Artefact[bytes]:
    """Optimize a structure using xtb."""
    # perform an xtb optimization
    optim = f.shell(
        "xtb input.xyz --opt vtight",
        inp={"input.xyz": structure},
        out=[".xtboptok", "xtbopt.xyz"],
    )
    # barrier for convergence (fails if .xtboptok is not found)
    struct: Artefact[bytes] = f.reduce(lambda x, y: x, optim.out["xtbopt.xyz"],
                                       optim.out[".xtboptok"])
    return struct
示例#15
0
def test_dag_cached() -> None:
    """Test that DAG caching works."""
    serv = MockServer()
    with Fun(serv, defaults=options(distributed=False)):
        dat = put(b"bla bla")
        step1 = morph(lambda x: x.decode().upper().encode(), dat)
        step2b = shell("echo 'not'", inp=dict(file1=step1))
        merge = shell("cat file1 file2",
                      inp=dict(file1=step1, file2=step2b.stdout),
                      out=["file2"])
        execute(merge)

    with Fun(serv, defaults=options(distributed=False, evaluate=False)):
        # Same as above, should run through with no evaluation
        dat = put(b"bla bla")
        step1 = morph(lambda x: x.decode().upper().encode(), dat)
        step2b = shell("echo 'not'", inp=dict(file1=step1))
        merge = shell("cat file1 file2",
                      inp=dict(file1=step1, file2=step2b.stdout),
                      out=["file2"])
        execute(merge)

    with Fun(serv, defaults=options(distributed=False, evaluate=False)):
        dat = put(b"bla bla")
        step1 = morph(lambda x: x.decode().upper().encode(), dat)
        # DIFFERENT HERE: Trigger re-evaluation and raise
        step2b = shell("echo 'knot'", inp=dict(file1=step1))
        merge = shell("cat file1 file2",
                      inp=dict(file1=step1, file2=step2b.stdout),
                      out=["file2"])
        with pytest.raises(RuntimeError):
            execute(merge)
示例#16
0
def test_artefact_disk_distributed() -> None:
    """Test whether artefacts on disk works on different nodes."""
    # funsies
    import funsies as f

    with tempfile.TemporaryDirectory() as td:
        with f.ManagedFun(nworkers=1, data_url=f"file://{td}"):
            dat = f.put(b"bla bla")
            step1 = f.morph(lambda x: x.decode().upper().encode(), dat)
            step2 = f.shell("cat file1 file2",
                            inp=dict(file1=step1, file2=dat))
            step2b = f.shell("cat file1", inp=dict(file1=step1))

            f.execute(step2)
            f.wait_for(step2, 1.0)
            out = f.take(step2.stdout)
            assert out == b"BLA BLAbla bla"

            f.execute(step2b)
            f.wait_for(step2b, 1.0)
            out = f.take(step2b.stdout)
            assert out == b"BLA BLA"
示例#17
0
def test_shell_norun() -> None:
    """Test run on a shell command that didn't run."""
    with Fun(MockServer()):
        cmd = shell("cat file1", inp={"file1": b"bla bla"}, out=["bla"])

        with tempfile.TemporaryDirectory() as d:
            debug.shell(cmd, d)
            n = os.listdir(d)
            assert "input_files" in n
            assert "output_files" in n

            with open(os.path.join(d, "errors.json"), "r") as f:
                assert "NotFound" in f.read()
示例#18
0
def test_dag_efficient() -> None:
    """Test that DAG building doesn't do extra work."""
    with Fun(MockServer()) as db:
        dat = put(b"bla bla")
        step1 = morph(lambda x: x.decode().upper().encode(), dat)
        step2 = shell("cat file1 file2",
                      inp=dict(file1=step1, file2=dat),
                      out=["file2"])
        step2b = shell("echo 'not'", inp=dict(file1=step1))
        merge = shell("cat file1 file2",
                      inp=dict(file1=step1, file2=step2b.stdout),
                      out=["file2"])

        _dag.build_dag(db, step2.stdout.hash)
        # check that step2 only has stdout has no dependents
        assert len(_dag._dag_dependents(db, step2.stdout.hash,
                                        step2.hash)) == 0
        assert len(_dag._dag_dependents(db, step2.stdout.hash,
                                        step1.parent)) == 1

        _dag.build_dag(db, merge.hash)
        # check that however, the merged one has two dependents for step1
        assert len(_dag._dag_dependents(db, merge.hash, step1.parent)) == 2
示例#19
0
def test_data_race(nworkers: int) -> None:
    """Test a data race when execute calls are interleaved."""
    with f.ManagedFun(nworkers=nworkers):
        dat = f.put(b"bla bla")
        step1 = f.morph(lambda x: x.decode().upper().encode(), dat)
        step2 = f.shell(
            "cat file1 file2; grep 'bla' file2 file1 > file3; date >> file3",
            inp=dict(file1=step1, file2=dat),
            out=["file2", "file3"],
        )

        f.execute(step1)
        f.execute(step2)
        f.wait_for(step1, timeout=20.0)
        f.wait_for(step2, timeout=20.0)
示例#20
0
def test_parametrize() -> None:
    """Test that parametrization works."""
    with Fun(MockServer(), options(distributed=False)) as db:
        dat = put(b"bla bla")
        dat2 = put(b"bla bla bla")

        step1 = morph(capitalize, dat)
        step2 = shell("cat file1 file2", inp=dict(file1=step1, file2=dat))
        final = shell("cat file1 file3",
                      inp={
                          "file1": step1,
                          "file3": step2.stdout
                      })

        pinp = {"input": dat}
        pout = {"final.stdout": final.stdout, "step1": step1}
        new_inp = {"input": dat2}

        ops = _p._parametrize_subgraph(db, pinp, pout)
        edges = _p._subgraph_edges(db, ops)
        sorted_ops = _p._subgraph_toposort(ops, edges)
        pinp2 = dict([(k, v.hash) for k, v in pinp.items()])
        pout2 = dict([(k, v.hash) for k, v in pout.items()])
        new_out = _p._do_parametrize(db, sorted_ops, pinp2, pout2, new_inp)

        # re-run with dat2, check if the same.
        step1 = morph(capitalize, dat2)
        step2 = shell("cat file1 file2", inp=dict(file1=step1, file2=dat2))
        final = shell("cat file1 file3",
                      inp={
                          "file1": step1,
                          "file3": step2.stdout
                      })

        assert new_out["final.stdout"] == final.stdout
        assert new_out["step1"] == step1
示例#21
0
def test_dag_large() -> None:
    """Test that DAG building doesn't do extra work for large operations."""
    with Fun(MockServer()) as db:
        outputs = []
        for i in range(100):
            dat = put(f"bla{i}".encode())
            step1 = morph(lambda x: x.decode().upper().encode(), dat)
            step2 = shell(
                "cat file1 file2",
                inp=dict(file1=step1, file2="something"),
                out=["file2"],
            )
            outputs += [concat(step1, step1, step2.stdout, join=b" ")]

        final = concat(*outputs, join=b"\n")
        _dag.build_dag(db, final.hash)
        assert len(_dag._dag_dependents(db, final.hash, hash_t("root"))) == 100
示例#22
0
def test_shell_run() -> None:
    """Test run on a shell command."""
    with Fun(MockServer()):
        db, store = get_connection()
        cmd = shell("cat file1", inp={"file1": b"bla bla"}, out=["bla"])
        _ = run_op(db, store, cmd.hash)

        with tempfile.TemporaryDirectory() as d:
            debug.shell(cmd, d)
            n = os.listdir(d)
            assert "stdout0" in n
            assert "stderr0" in n
            assert "input_files" in n
            assert "output_files" in n

            with open(os.path.join(d, "errors.json"), "r") as f:
                assert "MissingOutput" in f.read()
示例#23
0
def test_artefact() -> None:
    """Test artefact debug."""
    with Fun(MockServer()) as db:
        cmd = shell("cat file1", inp={"file1": b"bla bla"}, out=["bla"])

        with tempfile.TemporaryDirectory() as d:
            debug.artefact(cmd.stdout, d, connection=db)
            n = os.listdir(d)
            assert "metadata.json" in n
            assert "error.json" in n
            assert "data" not in n

        with tempfile.TemporaryDirectory() as d:
            debug.artefact(cmd.inp["file1"], d, connection=db)
            n = os.listdir(d)
            assert "metadata.json" in n
            assert "error.json" not in n
            assert "data" in n
示例#24
0
def test_dag_build() -> None:
    """Test simple DAG build."""
    with Fun(MockServer()) as db:
        dat = put(b"bla bla")
        step1 = morph(lambda x: x.decode().upper().encode(), dat)
        step2 = shell("cat file1 file2", inp=dict(file1=step1, file2=dat))
        output = step2.stdout

        _dag.build_dag(db, output.hash)
        assert len(db.smembers(join(DAG_OPERATIONS, output.hash))) == 2

        # test deletion
        _dag.delete_all_dags(db)
        assert len(db.smembers(join(DAG_OPERATIONS, output.hash))) == 0

        # test new _dag
        _dag.build_dag(db, step1.hash)
        assert len(db.smembers(join(DAG_OPERATIONS, step1.hash))) == 1

        assert len(_dag.descendants(db, step1.parent)) == 1
示例#25
0
def test_error_tolerant() -> None:
    """Test error tolerant funsie."""
    def error_tolerant_fun(inp: Result[bytes]) -> bytes:
        if isinstance(inp, Error):
            return b"err"
        else:
            return b""

    with Fun(MockServer()):
        db, store = get_connection()
        s1 = funsies.shell("cp file1 file3",
                           inp=dict(file1="bla"),
                           out=["file2"])
        s2 = funsies.morph(error_tolerant_fun, s1.out["file2"], strict=False)

        with pytest.raises(RuntimeError):
            # Test operation not found
            run_op(db, store, s2.hash)

        run_op(db, store, s1.op)
        run_op(db, store, s2.parent)
        assert funsies.take(s2) == b"err"
示例#26
0
def test_timeout_deadlock() -> None:
    """Test funsies that time out.

    Here we explicitly check if dependents are still enqueued or if the whole
    thing deadlocks.
    """
    def timeout_fun(*inp: str) -> bytes:
        time.sleep(3.0)
        return b"what"

    def cap(inp: bytes) -> bytes:
        return inp.capitalize()

    with f.ManagedFun(nworkers=2):
        # Test when python function times out
        s1 = f.reduce(timeout_fun,
                      "bla bla",
                      "bla bla",
                      opt=f.options(timeout=1))
        s1b = f.morph(cap, s1)
        # Test when shell function times out
        s2 = f.shell("sleep 20", "echo 'bla bla'", opt=f.options(timeout=1))
        s2b = f.morph(cap, s2.stdouts[1])
        f.execute(s1b, s2b)

        # Check err for reduce
        f.wait_for(s1b, timeout=1.5)
        err = f.take(s1b, strict=False)
        assert isinstance(err, f.errors.Error)
        assert err.kind == f.errors.ErrorKind.JobTimedOut
        assert err.source == s1.parent

        # Check err for shell
        f.wait_for(s2b, timeout=1.5)
        err = f.take(s2b, strict=False)
        assert isinstance(err, f.errors.Error)
        assert err.kind == f.errors.ErrorKind.JobTimedOut
        assert err.source == s2.hash
示例#27
0
def test_integration(reference: str, nworkers: int) -> None:
    """Test full integration."""
    # make a temp file and copy reference database
    dir = tempfile.mkdtemp()
    if not make_reference:
        shutil.copy(os.path.join(ref_dir, reference, "appendonly.aof"), dir)
    shutil.copy(os.path.join(ref_dir, "redis.conf"), dir)

    # Dictionary for test data
    test_data = {}

    # Start funsie script
    with ManagedFun(nworkers=nworkers,
                    directory=dir,
                    redis_args=["redis.conf"]):
        dat = put(b"bla bla")
        step1 = morph(lambda x: x.decode().upper().encode(), dat)
        step2 = shell(
            "cat file1 file2; grep 'bla' file2 file1 > file3; date >> file3",
            inp=dict(file1=step1, file2=dat),
            out=["file2", "file3"],
        )
        echo = shell("sleep 1", "date")
        merge = reduce(
            join_bytes,
            step2.out["file3"],
            echo.stdouts[1],
            name="merger",
        )

        def tolist(x: bytes, y: bytes) -> Dict[int, str]:
            return {1: x.decode(), 8: y.decode()}

        A = py(tolist, merge, echo.stdouts[1])
        test_data["test1"] = A

        def raises(inp: bytes) -> bytes:
            raise RuntimeError("an error was raised")

        def error_count(*inp: Result[bytes]) -> bytes:
            out = utils.match_results(inp, lambda x: 0, lambda x: 1)
            return str(sum(out)).encode()

        err = morph(raises, dat)
        count = reduce(error_count,
                       dat,
                       dat,
                       err,
                       dat,
                       err,
                       err,
                       echo.stdouts[0],
                       strict=False)
        cat = utils.concat(merge,
                           dat,
                           err,
                           count,
                           echo.stdouts[1],
                           strict=False)
        test_data["test2"] = cat

        execute(step1)
        wait_for(step1, timeout=10.0)
        execute(step2)
        wait_for(step2, timeout=10.0)
        assert take(step1) == b"BLA BLA"
        assert take(step2.stdout) == b"BLA BLAbla bla"

        if make_reference:
            folder = os.path.join(ref_dir, reference)
            os.makedirs(folder, exist_ok=True)

            for name, artefact in test_data.items():
                with open(os.path.join(folder, name), "wb") as f:
                    execute(artefact)
                    wait_for(artefact, 10.0)
                    out = take(artefact)
                    data2 = _serdes.encode(artefact.kind, out)
                    assert isinstance(data2, bytes)
                    f.write(data2)

            shutil.copy(
                os.path.join(dir, "appendonly.aof"),
                os.path.join(folder, "appendonly.aof"),
            )
        else:
            # Test against reference dbs
            for name, artefact in test_data.items():
                execute(artefact)
                wait_for(artefact, 10.0)
                with open(os.path.join(ref_dir, reference, name), "rb") as f:
                    data = f.read()

                out = take(artefact)
                data_ref = _serdes.encode(artefact.kind, out)
                assert isinstance(data_ref, bytes)
                assert data == data_ref

    shutil.rmtree(dir)
def test_integration(reference: str, nworkers: int) -> None:
    """Test full integration."""
    # make a temp file and copy reference database
    dir = tempfile.mkdtemp()
    if not make_reference:
        shutil.copy(os.path.join(ref_dir, reference, "appendonly.aof"), dir)
        shutil.copytree(os.path.join(ref_dir, reference, "data"),
                        os.path.join(dir, "data"))
    shutil.copy(os.path.join(ref_dir, "redis.conf"), dir)

    # data url
    datadir = f"file://{os.path.join(dir, 'data')}"

    # Dictionary for test data
    test_data: dict[str, Any] = {}

    def update_data(a: dict[int, int], b: list[int]) -> dict[int, int]:
        for i in b:
            a[i] = a.get(i, 0) + 1
        return a

    def sum_data(x: dict[int, int]) -> int:
        return sum([int(k) * v for k, v in x.items()])

    def make_secret(x: int) -> str:
        return secrets.token_hex(x)

    # Start funsie script
    with ManagedFun(
            nworkers=nworkers,
            directory=dir,
            data_url=datadir,
            redis_args=["redis.conf"],
    ) as db:
        integers = put([5, 4, 8, 9, 9, 10, 1, 3])
        init_data = put({100: 9})
        test_data["init_data"] = init_data
        nbytes = put(4)

        s1 = reduce(update_data, init_data, integers)
        num = morph(sum_data, s1)
        date = shell("date").stdout
        test_data["date"] = date
        rand = morph(make_secret, nbytes)

        s4 = template(
            "date:{{date}}\n" + "some random bytes:{{random}}\n" +
            "a number: {{num}}\n" + "a string: {{string}}\n",
            {
                "date": date,
                "random": rand,
                "num": num,
                "string": "wazza"
            },
            name="a template",
        )
        test_data["s4"] = s4

        execute(s4)
        wait_for(s4, 5)

        # check that the db doesn't itself include data
        for k in db.keys():
            assert b"data" not in k

        if make_reference:
            folder = os.path.join(ref_dir, reference)
            os.makedirs(folder, exist_ok=True)

            for name, artefact in test_data.items():
                with open(os.path.join(folder, name), "wb") as f:
                    execute(artefact)
                    wait_for(artefact, 10.0)
                    out = take(artefact)
                    data2 = _serdes.encode(artefact.kind, out)
                    assert isinstance(data2, bytes)
                    f.write(data2)

            shutil.copy(
                os.path.join(dir, "appendonly.aof"),
                os.path.join(folder, "appendonly.aof"),
            )
            shutil.copytree(
                os.path.join(dir, "data"),
                os.path.join(folder, "data"),
            )
        else:
            # Test against reference dbs
            for name, artefact in test_data.items():
                execute(artefact)
                wait_for(artefact, 10.0)
                with open(os.path.join(ref_dir, reference, name), "rb") as f:
                    data = f.read()

                out = take(artefact)
                data_ref = _serdes.encode(artefact.kind, out)
                assert isinstance(data_ref, bytes)
                assert data == data_ref

    # delete tempdir
    shutil.rmtree(dir)
示例#29
0
        return out

    out = []
    for s in structures:
        out += [f.morph(to_dict, s, out=Encoding.json)]  # elements to dicts
    return f.reduce(sort_by_energy, *out)  # transform to a sorted list


with f.Fun():
    # put smiles in db
    smiles = f.put(b"C(O)CCCC(O)")

    # Generate 3d conformers with openbabel
    gen3d = f.shell(
        "obabel input.smi --gen3d --ff mmff94 --minimize -O struct.mol",
        inp={"input.smi": smiles},
        out=["struct.mol"],
    )
    # abort if molecule is empty
    struct = not_empty(gen3d.out["struct.mol"])

    # Generate conformers.
    confab = f.shell(
        "obabel input.mol -O conformers.xyz --confab --verbose",
        inp={"input.mol": struct},
        out=["conformers.xyz"],
    )

    # Optimize conformer ensemble using xtb.
    optimized1 = f.dynamic.sac(
        # split the xyz file