Neo4j 和 Django 测试

ain*_*sti 5 python testing django neo4j

我将 Django 和 Neo4j 与 neomodel 一起用作 OGM(用于图形的 ORM)。它运行良好,但在测试方面,Neomodel 不支持关系数据库的常见 Django 行为。我的意思是它不会创建一个在测试开始时创建并在测试结束后销毁的临时 Neo4j 实例。

我一直在做一些研究,我发现了两种可能的解决方案:

  • 第一个是创建一个自定义发现运行器,您可以在其中停止开发数据库,​​然后从另一条路径启动测试数据库,运行您的测试,最后停止测试实例并再次启动开发实例。这个解决方案是在neo4j数据库的Django测试线程中提出的。以下代码已针对 3.1.1 Neo4j 版本进行了调整:

    from time import sleep
    from subprocess import call
    
    from django.test.runner import DiscoverRunner
    from py2neo import authenticate
    
    class DiscoverRunner(DiscoverRunner):
    def setup_databases(self, *args, **kwargs):
        # Stop your development instance
        call("sudo neo4j stop", shell=True)
        # Sleep to ensure the service has completely stopped
        sleep(1)
        # Start your test instance (see section below for more details)
        success = call("neo4j_test/neo4j-community-3.1.1/bin/neo4j"
                       " start", shell=True)
        # Need to sleep to wait for the test instance to completely come up
        sleep(10)
        if success != 0:
            return False
    
        # These lines have been commented because I've set the configuration
        # dbms.security.auth_enabled=false
        #try:
        #    # For neo4j 2.2.x you'll need to set a password or deactivate auth
        #    # Nigel Small's py2neo gives us an easy way to accomplish this
        #    # call("source /path/to/virtualenv/bin/activate && "
        #    #      "/path/to/virtualenv/bin/neoauth "
        #    #      "neo4j neo4j my-p4ssword")
    
        #    authenticate("localhost:7474", "neo4j", "my-password")
    
        #except OSError:
        #    pass
        # Don't import neomodel until we get here because we need to wait
        # for the new db to be spawned
        from neomodel import db
        # Delete all previous entries in the db prior to running tests
        query = "match (n)-[r]-() delete n,r"
        db.cypher_query(query)
        super(DiscoverRunner, self).__init__(*args, **kwargs)
    
    def teardown_databases(self, old_config, **kwargs):
        from neomodel import db
        # Delete all previous entries in the db after running tests
        query = "match (n)-[r]-() delete n,r"
        db.cypher_query(query)
        sleep(1)
        # Shut down test neo4j instance
        success = call("neo4j_test/neo4j-community-3.1.1/bin/neo4j"
                       " stop", shell=True)
        if success != 0:
            return False
        sleep(1)
        # start back up development instance
        call("sudo neo4j start", shell=True)
    
    Run Code Online (Sandbox Code Playgroud)

    它工作正常,直到它尝试连接到测试数据库并进行查询,因为它使用加密连接并查找'~/.neo4/known_hosts'连接密钥,但它与开发数据库之一冲突并因以下错误而崩溃:

    neo4j.v1.exceptions.ProtocolError: Server certificate does not match known certificate for 'localhost'; check details in file '~/.neo4j/known_hosts'
    
    Run Code Online (Sandbox Code Playgroud)

    那么,有没有办法避免这种认证检查?

  • 第二种解决方案是创建相同的发现运行器并设置 Neo4j 中可用的 ImpermanentDatabase。问题是我发现的所有信息都在 Java 中,在 python unittests 中的 Neo4j ImpermanentDatabase,它并没有让我清楚如何在 python 中实现它。有人对如何在python中使用它有一些概念吗(无论是使用neomodel、py2neo还是直接使用python驱动程序都没有关系)

首先十分感谢。

ain*_*sti 2

经过一番研究,我提出了使用第一种方法的解决方案。

Neo4j 的官方 python 驱动程序在连接到驱动程序时有一个可配置的参数(加密的):

GraphDatabase.driver('bolt://' + hostname, auth=basic_auth(username, password), encrypted=True)
Run Code Online (Sandbox Code Playgroud)

如果加密参数设置为 False,则将'~/.neo4/known_hosts'被忽略并且不会出现错误。遗憾的是,neomodel 框架尚不支持调整该参数,但我已经在 github 中分叉了存储库,并在全局设置中添加了一个名为 ENCRYPTED_CONNECTION 的变量,可以覆盖该变量以实现此目标。

我正在等待拉取请求被接受,我会通知是否接受。

顺便说一句,如果有人能给我们一些问题中评论的第二种方法的一些启发,那就太棒了。

谢谢。