#! /usr/bin/env python3
#
# Copyright (C) 2018-2019 Garmin Ltd.
#
# SPDX-License-Identifier: GPL-2.0-only
#

from . import create_server, create_client
from .server import DEFAULT_ANON_PERMS, ALL_PERMISSIONS
from bb.asyncrpc import InvokeError
from .client import ClientPool
import hashlib
import logging
import multiprocessing
import os
import sys
import tempfile
import threading
import unittest
import socket
import time
import signal
import subprocess
import json
import re
from pathlib import Path


THIS_DIR = Path(__file__).parent
BIN_DIR = THIS_DIR.parent.parent / "bin"

def server_prefunc(server, idx):
    logging.basicConfig(level=logging.DEBUG, filename='bbhashserv-%d.log' % idx, filemode='w',
                        format='%(levelname)s %(filename)s:%(lineno)d %(message)s')
    server.logger.debug("Running server %d" % idx)
    sys.stdout = open('bbhashserv-stdout-%d.log' % idx, 'w')
    sys.stderr = sys.stdout

class HashEquivalenceTestSetup(object):
    METHOD = 'TestMethod'

    server_index = 0
    client_index = 0

    def start_server(self, dbpath=None, upstream=None, read_only=False, prefunc=server_prefunc, anon_perms=DEFAULT_ANON_PERMS, admin_username=None, admin_password=None):
        self.server_index += 1
        if dbpath is None:
            dbpath = self.make_dbpath()

        def cleanup_server(server):
            if server.process.exitcode is not None:
                return

            server.process.terminate()
            server.process.join()

        server = create_server(self.get_server_addr(self.server_index),
                               dbpath,
                               upstream=upstream,
                               read_only=read_only,
                               anon_perms=anon_perms,
                               admin_username=admin_username,
                               admin_password=admin_password)
        server.dbpath = dbpath

        server.serve_as_process(prefunc=prefunc, args=(self.server_index,))
        self.addCleanup(cleanup_server, server)

        return server

    def make_dbpath(self):
        return os.path.join(self.temp_dir.name, "db%d.sqlite" % self.server_index)

    def start_client(self, server_address, username=None, password=None):
        def cleanup_client(client):
            client.close()

        client = create_client(server_address, username=username, password=password)
        self.addCleanup(cleanup_client, client)

        return client

    def start_test_server(self):
        self.server = self.start_server()
        return self.server.address

    def start_auth_server(self):
        auth_server = self.start_server(self.server.dbpath, anon_perms=[], admin_username="admin", admin_password="password")
        self.auth_server_address = auth_server.address
        self.admin_client = self.start_client(auth_server.address, username="admin", password="password")
        return self.admin_client

    def auth_client(self, user):
        return self.start_client(self.auth_server_address, user["username"], user["token"])

    def setUp(self):
        if sys.version_info < (3, 5, 0):
            self.skipTest('Python 3.5 or later required')

        self.temp_dir = tempfile.TemporaryDirectory(prefix='bb-hashserv')
        self.addCleanup(self.temp_dir.cleanup)

        self.server_address = self.start_test_server()

        self.client = self.start_client(self.server_address)

    def assertClientGetHash(self, client, taskhash, unihash):
        result = client.get_unihash(self.METHOD, taskhash)
        self.assertEqual(result, unihash)

    def assertUserPerms(self, user, permissions):
        with self.auth_client(user) as client:
            info = client.get_user()
            self.assertEqual(info, {
                "username": user["username"],
                "permissions": permissions,
            })

    def assertUserCanAuth(self, user):
        with self.start_client(self.auth_server_address) as client:
            client.auth(user["username"], user["token"])

    def assertUserCannotAuth(self, user):
        with self.start_client(self.auth_server_address) as client, self.assertRaises(InvokeError):
            client.auth(user["username"], user["token"])

    def create_test_hash(self, client):
        # Simple test that hashes can be created
        taskhash = '35788efcb8dfb0a02659d81cf2bfd695fb30faf9'
        outhash = '2765d4a5884be49b28601445c2760c5f21e7e5c0ee2b7e3fce98fd7e5970796f'
        unihash = 'f46d3fbb439bd9b921095da657a4de906510d2cd'

        self.assertClientGetHash(client, taskhash, None)

        result = client.report_unihash(taskhash, self.METHOD, outhash, unihash)
        self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash')
        return taskhash, outhash, unihash

    def run_hashclient(self, args, **kwargs):
        try:
            p = subprocess.run(
                [BIN_DIR / "bitbake-hashclient"] + args,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                encoding="utf-8",
                **kwargs
            )
        except subprocess.CalledProcessError as e:
            print(e.output)
            raise e

        print(p.stdout)
        return p


class HashEquivalenceCommonTests(object):
    def auth_perms(self, *permissions):
        self.client_index += 1
        user = self.create_user(f"user-{self.client_index}", permissions)
        return self.auth_client(user)

    def create_user(self, username, permissions, *, client=None):
        def remove_user(username):
            try:
                self.admin_client.delete_user(username)
            except bb.asyncrpc.InvokeError:
                pass

        if client is None:
            client = self.admin_client

        user = client.new_user(username, permissions)
        self.addCleanup(remove_user, username)

        return user

    def test_create_hash(self):
        return self.create_test_hash(self.client)

    def test_create_equivalent(self):
        # Tests that a second reported task with the same outhash will be
        # assigned the same unihash
        taskhash = '53b8dce672cb6d0c73170be43f540460bfc347b4'
        outhash = '5a9cb1649625f0bf41fc7791b635cd9c2d7118c7f021ba87dcd03f72b67ce7a8'
        unihash = 'f37918cc02eb5a520b1aff86faacbc0a38124646'

        result = self.client.report_unihash(taskhash, self.METHOD, outhash, unihash)
        self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash')

        # Report a different task with the same outhash. The returned unihash
        # should match the first task
        taskhash2 = '3bf6f1e89d26205aec90da04854fbdbf73afe6b4'
        unihash2 = 'af36b199320e611fbb16f1f277d3ee1d619ca58b'
        result = self.client.report_unihash(taskhash2, self.METHOD, outhash, unihash2)
        self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash')

    def test_duplicate_taskhash(self):
        # Tests that duplicate reports of the same taskhash with different
        # outhash & unihash always return the unihash from the first reported
        # taskhash
        taskhash = '8aa96fcffb5831b3c2c0cb75f0431e3f8b20554a'
        outhash = 'afe240a439959ce86f5e322f8c208e1fedefea9e813f2140c81af866cc9edf7e'
        unihash = '218e57509998197d570e2c98512d0105985dffc9'
        self.client.report_unihash(taskhash, self.METHOD, outhash, unihash)

        self.assertClientGetHash(self.client, taskhash, unihash)

        outhash2 = '0904a7fe3dc712d9fd8a74a616ddca2a825a8ee97adf0bd3fc86082c7639914d'
        unihash2 = 'ae9a7d252735f0dafcdb10e2e02561ca3a47314c'
        self.client.report_unihash(taskhash, self.METHOD, outhash2, unihash2)

        self.assertClientGetHash(self.client, taskhash, unihash)

        outhash3 = '77623a549b5b1a31e3732dfa8fe61d7ce5d44b3370f253c5360e136b852967b4'
        unihash3 = '9217a7d6398518e5dc002ed58f2cbbbc78696603'
        self.client.report_unihash(taskhash, self.METHOD, outhash3, unihash3)

        self.assertClientGetHash(self.client, taskhash, unihash)

    def test_remove_taskhash(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)
        result = self.client.remove({"taskhash": taskhash})
        self.assertGreater(result["count"], 0)
        self.assertClientGetHash(self.client, taskhash, None)

        result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash)
        self.assertIsNone(result_outhash)

    def test_remove_unihash(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)
        result = self.client.remove({"unihash": unihash})
        self.assertGreater(result["count"], 0)
        self.assertClientGetHash(self.client, taskhash, None)

    def test_remove_outhash(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)
        result = self.client.remove({"outhash": outhash})
        self.assertGreater(result["count"], 0)

        result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash)
        self.assertIsNone(result_outhash)

    def test_remove_method(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)
        result = self.client.remove({"method": self.METHOD})
        self.assertGreater(result["count"], 0)
        self.assertClientGetHash(self.client, taskhash, None)

        result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash)
        self.assertIsNone(result_outhash)

    def test_clean_unused(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)

        # Clean the database, which should not remove anything because all hashes an in-use
        result = self.client.clean_unused(0)
        self.assertEqual(result["count"], 0)
        self.assertClientGetHash(self.client, taskhash, unihash)

        # Remove the unihash. The row in the outhash table should still be present
        self.client.remove({"unihash": unihash})
        result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash, False)
        self.assertIsNotNone(result_outhash)

        # Now clean with no minimum age which will remove the outhash
        result = self.client.clean_unused(0)
        self.assertEqual(result["count"], 1)
        result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash, False)
        self.assertIsNone(result_outhash)

    def test_huge_message(self):
        # Simple test that hashes can be created
        taskhash = 'c665584ee6817aa99edfc77a44dd853828279370'
        outhash = '3c979c3db45c569f51ab7626a4651074be3a9d11a84b1db076f5b14f7d39db44'
        unihash = '90e9bc1d1f094c51824adca7f8ea79a048d68824'

        self.assertClientGetHash(self.client, taskhash, None)

        siginfo = "0" * (self.client.max_chunk * 4)

        result = self.client.report_unihash(taskhash, self.METHOD, outhash, unihash, {
            'outhash_siginfo': siginfo
        })
        self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash')

        result_unihash = self.client.get_taskhash(self.METHOD, taskhash, True)
        self.assertEqual(result_unihash['taskhash'], taskhash)
        self.assertEqual(result_unihash['unihash'], unihash)
        self.assertEqual(result_unihash['method'], self.METHOD)

        result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash)
        self.assertEqual(result_outhash['taskhash'], taskhash)
        self.assertEqual(result_outhash['method'], self.METHOD)
        self.assertEqual(result_outhash['unihash'], unihash)
        self.assertEqual(result_outhash['outhash'], outhash)
        self.assertEqual(result_outhash['outhash_siginfo'], siginfo)

    def test_stress(self):
        def query_server(failures):
            client = Client(self.server_address)
            try:
                for i in range(1000):
                    taskhash = hashlib.sha256()
                    taskhash.update(str(i).encode('utf-8'))
                    taskhash = taskhash.hexdigest()
                    result = client.get_unihash(self.METHOD, taskhash)
                    if result != taskhash:
                        failures.append("taskhash mismatch: %s != %s" % (result, taskhash))
            finally:
                client.close()

        # Report hashes
        for i in range(1000):
            taskhash = hashlib.sha256()
            taskhash.update(str(i).encode('utf-8'))
            taskhash = taskhash.hexdigest()
            self.client.report_unihash(taskhash, self.METHOD, taskhash, taskhash)

        failures = []
        threads = [threading.Thread(target=query_server, args=(failures,)) for t in range(100)]

        for t in threads:
            t.start()

        for t in threads:
            t.join()

        self.assertFalse(failures)

    def test_upstream_server(self):
        # Tests upstream server support. This is done by creating two servers
        # that share a database file. The downstream server has it upstream
        # set to the test server, whereas the side server doesn't. This allows
        # verification that the hash requests are being proxied to the upstream
        # server by verifying that they appear on the downstream client, but not
        # the side client. It also verifies that the results are pulled into
        # the downstream database by checking that the downstream and side servers
        # match after the downstream is done waiting for all backfill tasks
        down_server = self.start_server(upstream=self.server_address)
        down_client = self.start_client(down_server.address)
        side_server = self.start_server(dbpath=down_server.dbpath)
        side_client = self.start_client(side_server.address)

        def check_hash(taskhash, unihash, old_sidehash):
            nonlocal down_client
            nonlocal side_client

            # check upstream server
            self.assertClientGetHash(self.client, taskhash, unihash)

            # Hash should *not* be present on the side server
            self.assertClientGetHash(side_client, taskhash, old_sidehash)

            # Hash should be present on the downstream server, since it
            # will defer to the upstream server. This will trigger
            # the backfill in the downstream server
            self.assertClientGetHash(down_client, taskhash, unihash)

            # After waiting for the downstream client to finish backfilling the
            # task from the upstream server, it should appear in the side server
            # since the database is populated
            down_client.backfill_wait()
            self.assertClientGetHash(side_client, taskhash, unihash)

        # Basic report
        taskhash = '8aa96fcffb5831b3c2c0cb75f0431e3f8b20554a'
        outhash = 'afe240a439959ce86f5e322f8c208e1fedefea9e813f2140c81af866cc9edf7e'
        unihash = '218e57509998197d570e2c98512d0105985dffc9'
        self.client.report_unihash(taskhash, self.METHOD, outhash, unihash)

        check_hash(taskhash, unihash, None)

        # Duplicated taskhash with multiple output hashes and unihashes.
        # All servers should agree with the originally reported hash
        outhash2 = '0904a7fe3dc712d9fd8a74a616ddca2a825a8ee97adf0bd3fc86082c7639914d'
        unihash2 = 'ae9a7d252735f0dafcdb10e2e02561ca3a47314c'
        self.client.report_unihash(taskhash, self.METHOD, outhash2, unihash2)

        check_hash(taskhash, unihash, unihash)

        # Report an equivalent task. The sideload will originally report
        # no unihash until backfilled
        taskhash3 = "044c2ec8aaf480685a00ff6ff49e6162e6ad34e1"
        unihash3 = "def64766090d28f627e816454ed46894bb3aab36"
        self.client.report_unihash(taskhash3, self.METHOD, outhash, unihash3)

        check_hash(taskhash3, unihash, None)

        # Test that reporting a unihash in the downstream client isn't
        # propagating to the upstream server
        taskhash4 = "e3da00593d6a7fb435c7e2114976c59c5fd6d561"
        outhash4 = "1cf8713e645f491eb9c959d20b5cae1c47133a292626dda9b10709857cbe688a"
        unihash4 = "3b5d3d83f07f259e9086fcb422c855286e18a57d"
        down_client.report_unihash(taskhash4, self.METHOD, outhash4, unihash4)
        down_client.backfill_wait()

        self.assertClientGetHash(down_client, taskhash4, unihash4)
        self.assertClientGetHash(side_client, taskhash4, unihash4)
        self.assertClientGetHash(self.client, taskhash4, None)

        # Test that reporting a unihash in the downstream is able to find a
        # match which was previously reported to the upstream server
        taskhash5 = '35788efcb8dfb0a02659d81cf2bfd695fb30faf9'
        outhash5 = '2765d4a5884be49b28601445c2760c5f21e7e5c0ee2b7e3fce98fd7e5970796f'
        unihash5 = 'f46d3fbb439bd9b921095da657a4de906510d2cd'
        result = self.client.report_unihash(taskhash5, self.METHOD, outhash5, unihash5)

        taskhash6 = '35788efcb8dfb0a02659d81cf2bfd695fb30fafa'
        unihash6 = 'f46d3fbb439bd9b921095da657a4de906510d2ce'
        result = down_client.report_unihash(taskhash6, self.METHOD, outhash5, unihash6)
        self.assertEqual(result['unihash'], unihash5, 'Server failed to copy unihash from upstream')

        # Tests read through from server with
        taskhash7 = '9d81d76242cc7cfaf7bf74b94b9cd2e29324ed74'
        outhash7 = '8470d56547eea6236d7c81a644ce74670ca0bbda998e13c629ef6bb3f0d60b69'
        unihash7 = '05d2a63c81e32f0a36542ca677e8ad852365c538'
        self.client.report_unihash(taskhash7, self.METHOD, outhash7, unihash7)

        result = down_client.get_taskhash(self.METHOD, taskhash7, True)
        self.assertEqual(result['unihash'], unihash7, 'Server failed to copy unihash from upstream')
        self.assertEqual(result['outhash'], outhash7, 'Server failed to copy unihash from upstream')
        self.assertEqual(result['taskhash'], taskhash7, 'Server failed to copy unihash from upstream')
        self.assertEqual(result['method'], self.METHOD)

        taskhash8 = '86978a4c8c71b9b487330b0152aade10c1ee58aa'
        outhash8 = 'ca8c128e9d9e4a28ef24d0508aa20b5cf880604eacd8f65c0e366f7e0cc5fbcf'
        unihash8 = 'd8bcf25369d40590ad7d08c84d538982f2023e01'
        self.client.report_unihash(taskhash8, self.METHOD, outhash8, unihash8)

        result = down_client.get_outhash(self.METHOD, outhash8, taskhash8)
        self.assertEqual(result['unihash'], unihash8, 'Server failed to copy unihash from upstream')
        self.assertEqual(result['outhash'], outhash8, 'Server failed to copy unihash from upstream')
        self.assertEqual(result['taskhash'], taskhash8, 'Server failed to copy unihash from upstream')
        self.assertEqual(result['method'], self.METHOD)

        taskhash9 = 'ae6339531895ddf5b67e663e6a374ad8ec71d81c'
        outhash9 = 'afc78172c81880ae10a1fec994b5b4ee33d196a001a1b66212a15ebe573e00b5'
        unihash9 = '6662e699d6e3d894b24408ff9a4031ef9b038ee8'
        self.client.report_unihash(taskhash9, self.METHOD, outhash9, unihash9)

        result = down_client.get_taskhash(self.METHOD, taskhash9, False)
        self.assertEqual(result['unihash'], unihash9, 'Server failed to copy unihash from upstream')
        self.assertEqual(result['taskhash'], taskhash9, 'Server failed to copy unihash from upstream')
        self.assertEqual(result['method'], self.METHOD)

    def test_unihash_exsits(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)
        self.assertTrue(self.client.unihash_exists(unihash))
        self.assertFalse(self.client.unihash_exists('6662e699d6e3d894b24408ff9a4031ef9b038ee8'))

    def test_ro_server(self):
        rw_server = self.start_server()
        rw_client = self.start_client(rw_server.address)

        ro_server = self.start_server(dbpath=rw_server.dbpath, read_only=True)
        ro_client = self.start_client(ro_server.address)

        # Report a hash via the read-write server
        taskhash = '35788efcb8dfb0a02659d81cf2bfd695fb30faf9'
        outhash = '2765d4a5884be49b28601445c2760c5f21e7e5c0ee2b7e3fce98fd7e5970796f'
        unihash = 'f46d3fbb439bd9b921095da657a4de906510d2cd'

        result = rw_client.report_unihash(taskhash, self.METHOD, outhash, unihash)
        self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash')

        # Check the hash via the read-only server
        self.assertClientGetHash(ro_client, taskhash, unihash)

        # Ensure that reporting via the read-only server fails
        taskhash2 = 'c665584ee6817aa99edfc77a44dd853828279370'
        outhash2 = '3c979c3db45c569f51ab7626a4651074be3a9d11a84b1db076f5b14f7d39db44'
        unihash2 = '90e9bc1d1f094c51824adca7f8ea79a048d68824'

        result = ro_client.report_unihash(taskhash2, self.METHOD, outhash2, unihash2)
        self.assertEqual(result['unihash'], unihash2)

        # Ensure that the database was not modified
        self.assertClientGetHash(rw_client, taskhash2, None)


    def test_slow_server_start(self):
        # Ensures that the server will exit correctly even if it gets a SIGTERM
        # before entering the main loop

        event = multiprocessing.Event()

        def prefunc(server, idx):
            nonlocal event
            server_prefunc(server, idx)
            event.wait()

        def do_nothing(signum, frame):
            pass

        old_signal = signal.signal(signal.SIGTERM, do_nothing)
        self.addCleanup(signal.signal, signal.SIGTERM, old_signal)

        server = self.start_server(prefunc=prefunc)
        server.process.terminate()
        time.sleep(30)
        event.set()
        server.process.join(300)
        self.assertIsNotNone(server.process.exitcode, "Server did not exit in a timely manner!")

    def test_diverging_report_race(self):
        # Tests that a reported task will correctly pick up an updated unihash

        # This is a baseline report added to the database to ensure that there
        # is something to match against as equivalent
        outhash1 = 'afd11c366050bcd75ad763e898e4430e2a60659b26f83fbb22201a60672019fa'
        taskhash1 = '3bde230c743fc45ab61a065d7a1815fbfa01c4740e4c895af2eb8dc0f684a4ab'
        unihash1 = '3bde230c743fc45ab61a065d7a1815fbfa01c4740e4c895af2eb8dc0f684a4ab'
        result = self.client.report_unihash(taskhash1, self.METHOD, outhash1, unihash1)

        # Add a report that is equivalent to Task 1. It should ignore the
        # provided unihash and report the unihash from task 1
        taskhash2 = '6259ae8263bd94d454c086f501c37e64c4e83cae806902ca95b4ab513546b273'
        unihash2 = taskhash2
        result = self.client.report_unihash(taskhash2, self.METHOD, outhash1, unihash2)
        self.assertEqual(result['unihash'], unihash1)

        # Add another report for Task 2, but with a different outhash (e.g. the
        # task is non-deterministic). It should still be marked with the Task 1
        # unihash because it has the Task 2 taskhash, which is equivalent to
        # Task 1
        outhash3 = 'd2187ee3a8966db10b34fe0e863482288d9a6185cb8ef58a6c1c6ace87a2f24c'
        result = self.client.report_unihash(taskhash2, self.METHOD, outhash3, unihash2)
        self.assertEqual(result['unihash'], unihash1)


    def test_diverging_report_reverse_race(self):
        # Same idea as the previous test, but Tasks 2 and 3 are reported in
        # reverse order the opposite order

        outhash1 = 'afd11c366050bcd75ad763e898e4430e2a60659b26f83fbb22201a60672019fa'
        taskhash1 = '3bde230c743fc45ab61a065d7a1815fbfa01c4740e4c895af2eb8dc0f684a4ab'
        unihash1 = '3bde230c743fc45ab61a065d7a1815fbfa01c4740e4c895af2eb8dc0f684a4ab'
        result = self.client.report_unihash(taskhash1, self.METHOD, outhash1, unihash1)

        taskhash2 = '6259ae8263bd94d454c086f501c37e64c4e83cae806902ca95b4ab513546b273'
        unihash2 = taskhash2

        # Report Task 3 first. Since there is nothing else in the database it
        # will use the client provided unihash
        outhash3 = 'd2187ee3a8966db10b34fe0e863482288d9a6185cb8ef58a6c1c6ace87a2f24c'
        result = self.client.report_unihash(taskhash2, self.METHOD, outhash3, unihash2)
        self.assertEqual(result['unihash'], unihash2)

        # Report Task 2. This is equivalent to Task 1 but there is already a mapping for
        # taskhash2 so it will report unihash2
        result = self.client.report_unihash(taskhash2, self.METHOD, outhash1, unihash2)
        self.assertEqual(result['unihash'], unihash2)

        # The originally reported unihash for Task 3 should be unchanged even if it
        # shares a taskhash with Task 2
        self.assertClientGetHash(self.client, taskhash2, unihash2)


    def test_client_pool_get_unihashes(self):
        TEST_INPUT = (
            # taskhash                                   outhash                                                            unihash
            ('8aa96fcffb5831b3c2c0cb75f0431e3f8b20554a', 'afe240a439959ce86f5e322f8c208e1fedefea9e813f2140c81af866cc9edf7e','218e57509998197d570e2c98512d0105985dffc9'),
            # Duplicated taskhash with multiple output hashes and unihashes.
            ('8aa96fcffb5831b3c2c0cb75f0431e3f8b20554a', '0904a7fe3dc712d9fd8a74a616ddca2a825a8ee97adf0bd3fc86082c7639914d', 'ae9a7d252735f0dafcdb10e2e02561ca3a47314c'),
            # Equivalent hash
            ("044c2ec8aaf480685a00ff6ff49e6162e6ad34e1", '0904a7fe3dc712d9fd8a74a616ddca2a825a8ee97adf0bd3fc86082c7639914d', "def64766090d28f627e816454ed46894bb3aab36"),
            ("e3da00593d6a7fb435c7e2114976c59c5fd6d561", "1cf8713e645f491eb9c959d20b5cae1c47133a292626dda9b10709857cbe688a", "3b5d3d83f07f259e9086fcb422c855286e18a57d"),
            ('35788efcb8dfb0a02659d81cf2bfd695fb30faf9', '2765d4a5884be49b28601445c2760c5f21e7e5c0ee2b7e3fce98fd7e5970796f', 'f46d3fbb439bd9b921095da657a4de906510d2cd'),
            ('35788efcb8dfb0a02659d81cf2bfd695fb30fafa', '2765d4a5884be49b28601445c2760c5f21e7e5c0ee2b7e3fce98fd7e5970796f', 'f46d3fbb439bd9b921095da657a4de906510d2ce'),
            ('9d81d76242cc7cfaf7bf74b94b9cd2e29324ed74', '8470d56547eea6236d7c81a644ce74670ca0bbda998e13c629ef6bb3f0d60b69', '05d2a63c81e32f0a36542ca677e8ad852365c538'),
        )
        EXTRA_QUERIES = (
            "6b6be7a84ab179b4240c4302518dc3f6",
        )

        with ClientPool(self.server_address, 10) as client_pool:
            for taskhash, outhash, unihash in TEST_INPUT:
                self.client.report_unihash(taskhash, self.METHOD, outhash, unihash)

            query = {idx: (self.METHOD, data[0]) for idx, data in enumerate(TEST_INPUT)}
            for idx, taskhash in enumerate(EXTRA_QUERIES):
                query[idx + len(TEST_INPUT)] = (self.METHOD, taskhash)

            result = client_pool.get_unihashes(query)

            self.assertDictEqual(result, {
                0: "218e57509998197d570e2c98512d0105985dffc9",
                1: "218e57509998197d570e2c98512d0105985dffc9",
                2: "218e57509998197d570e2c98512d0105985dffc9",
                3: "3b5d3d83f07f259e9086fcb422c855286e18a57d",
                4: "f46d3fbb439bd9b921095da657a4de906510d2cd",
                5: "f46d3fbb439bd9b921095da657a4de906510d2cd",
                6: "05d2a63c81e32f0a36542ca677e8ad852365c538",
                7: None,
            })

    def test_client_pool_unihash_exists(self):
        TEST_INPUT = (
            # taskhash                                   outhash                                                            unihash
            ('8aa96fcffb5831b3c2c0cb75f0431e3f8b20554a', 'afe240a439959ce86f5e322f8c208e1fedefea9e813f2140c81af866cc9edf7e','218e57509998197d570e2c98512d0105985dffc9'),
            # Duplicated taskhash with multiple output hashes and unihashes.
            ('8aa96fcffb5831b3c2c0cb75f0431e3f8b20554a', '0904a7fe3dc712d9fd8a74a616ddca2a825a8ee97adf0bd3fc86082c7639914d', 'ae9a7d252735f0dafcdb10e2e02561ca3a47314c'),
            # Equivalent hash
            ("044c2ec8aaf480685a00ff6ff49e6162e6ad34e1", '0904a7fe3dc712d9fd8a74a616ddca2a825a8ee97adf0bd3fc86082c7639914d', "def64766090d28f627e816454ed46894bb3aab36"),
            ("e3da00593d6a7fb435c7e2114976c59c5fd6d561", "1cf8713e645f491eb9c959d20b5cae1c47133a292626dda9b10709857cbe688a", "3b5d3d83f07f259e9086fcb422c855286e18a57d"),
            ('35788efcb8dfb0a02659d81cf2bfd695fb30faf9', '2765d4a5884be49b28601445c2760c5f21e7e5c0ee2b7e3fce98fd7e5970796f', 'f46d3fbb439bd9b921095da657a4de906510d2cd'),
            ('35788efcb8dfb0a02659d81cf2bfd695fb30fafa', '2765d4a5884be49b28601445c2760c5f21e7e5c0ee2b7e3fce98fd7e5970796f', 'f46d3fbb439bd9b921095da657a4de906510d2ce'),
            ('9d81d76242cc7cfaf7bf74b94b9cd2e29324ed74', '8470d56547eea6236d7c81a644ce74670ca0bbda998e13c629ef6bb3f0d60b69', '05d2a63c81e32f0a36542ca677e8ad852365c538'),
        )
        EXTRA_QUERIES = (
            "6b6be7a84ab179b4240c4302518dc3f6",
        )

        result_unihashes = set()


        with ClientPool(self.server_address, 10) as client_pool:
            for taskhash, outhash, unihash in TEST_INPUT:
                result = self.client.report_unihash(taskhash, self.METHOD, outhash, unihash)
                result_unihashes.add(result["unihash"])

            query = {}
            expected = {}

            for _, _, unihash in TEST_INPUT:
                idx = len(query)
                query[idx] = unihash
                expected[idx] = unihash in result_unihashes


            for unihash in EXTRA_QUERIES:
                idx = len(query)
                query[idx] = unihash
                expected[idx] = False

            result = client_pool.unihashes_exist(query)
            self.assertDictEqual(result, expected)


    def test_auth_read_perms(self):
        admin_client = self.start_auth_server()

        # Create hashes with non-authenticated server
        taskhash, outhash, unihash = self.create_test_hash(self.client)

        # Validate hash can be retrieved using authenticated client
        with self.auth_perms("@read") as client:
            self.assertClientGetHash(client, taskhash, unihash)

        with self.auth_perms() as client, self.assertRaises(InvokeError):
            self.assertClientGetHash(client, taskhash, unihash)

    def test_auth_report_perms(self):
        admin_client = self.start_auth_server()

        # Without read permission, the user is completely denied
        with self.auth_perms() as client, self.assertRaises(InvokeError):
            self.create_test_hash(client)

        # Read permission allows the call to succeed, but it doesn't record
        # anythin in the database
        with self.auth_perms("@read") as client:
            taskhash, outhash, unihash = self.create_test_hash(client)
            self.assertClientGetHash(client, taskhash, None)

        # Report permission alone is insufficient
        with self.auth_perms("@report") as client, self.assertRaises(InvokeError):
            self.create_test_hash(client)

        # Read and report permission actually modify the database
        with self.auth_perms("@read", "@report") as client:
            taskhash, outhash, unihash = self.create_test_hash(client)
            self.assertClientGetHash(client, taskhash, unihash)

    def test_auth_no_token_refresh_from_anon_user(self):
        self.start_auth_server()

        with self.start_client(self.auth_server_address) as client, self.assertRaises(InvokeError):
            client.refresh_token()

    def test_auth_self_token_refresh(self):
        admin_client = self.start_auth_server()

        # Create a new user with no permissions
        user = self.create_user("test-user", [])

        with self.auth_client(user) as client:
            new_user = client.refresh_token()

        self.assertEqual(user["username"], new_user["username"])
        self.assertNotEqual(user["token"], new_user["token"])
        self.assertUserCanAuth(new_user)
        self.assertUserCannotAuth(user)

        # Explicitly specifying with your own username is fine also
        with self.auth_client(new_user) as client:
            new_user2 = client.refresh_token(user["username"])

        self.assertEqual(user["username"], new_user2["username"])
        self.assertNotEqual(user["token"], new_user2["token"])
        self.assertUserCanAuth(new_user2)
        self.assertUserCannotAuth(new_user)
        self.assertUserCannotAuth(user)

    def test_auth_token_refresh(self):
        admin_client = self.start_auth_server()

        user = self.create_user("test-user", [])

        with self.auth_perms() as client, self.assertRaises(InvokeError):
            client.refresh_token(user["username"])

        with self.auth_perms("@user-admin") as client:
            new_user = client.refresh_token(user["username"])

        self.assertEqual(user["username"], new_user["username"])
        self.assertNotEqual(user["token"], new_user["token"])
        self.assertUserCanAuth(new_user)
        self.assertUserCannotAuth(user)

    def test_auth_self_get_user(self):
        admin_client = self.start_auth_server()

        user = self.create_user("test-user", [])
        user_info = user.copy()
        del user_info["token"]

        with self.auth_client(user) as client:
            info = client.get_user()
            self.assertEqual(info, user_info)

            # Explicitly asking for your own username is fine also
            info = client.get_user(user["username"])
            self.assertEqual(info, user_info)

    def test_auth_get_user(self):
        admin_client = self.start_auth_server()

        user = self.create_user("test-user", [])
        user_info = user.copy()
        del user_info["token"]

        with self.auth_perms() as client, self.assertRaises(InvokeError):
            client.get_user(user["username"])

        with self.auth_perms("@user-admin") as client:
            info = client.get_user(user["username"])
            self.assertEqual(info, user_info)

            info = client.get_user("nonexist-user")
            self.assertIsNone(info)

    def test_auth_reconnect(self):
        admin_client = self.start_auth_server()

        user = self.create_user("test-user", [])
        user_info = user.copy()
        del user_info["token"]

        with self.auth_client(user) as client:
            info = client.get_user()
            self.assertEqual(info, user_info)

            client.disconnect()

            info = client.get_user()
            self.assertEqual(info, user_info)

    def test_auth_delete_user(self):
        admin_client = self.start_auth_server()

        user = self.create_user("test-user", [])

        # self service
        with self.auth_client(user) as client:
            client.delete_user(user["username"])

        self.assertIsNone(admin_client.get_user(user["username"]))
        user = self.create_user("test-user", [])

        with self.auth_perms() as client, self.assertRaises(InvokeError):
            client.delete_user(user["username"])

        with self.auth_perms("@user-admin") as client:
            client.delete_user(user["username"])

        # User doesn't exist, so even though the permission is correct, it's an
        # error
        with self.auth_perms("@user-admin") as client, self.assertRaises(InvokeError):
            client.delete_user(user["username"])

    def test_auth_set_user_perms(self):
        admin_client = self.start_auth_server()

        user = self.create_user("test-user", [])

        self.assertUserPerms(user, [])

        # No self service to change permissions
        with self.auth_client(user) as client, self.assertRaises(InvokeError):
            client.set_user_perms(user["username"], ["@all"])
        self.assertUserPerms(user, [])

        with self.auth_perms() as client, self.assertRaises(InvokeError):
            client.set_user_perms(user["username"], ["@all"])
        self.assertUserPerms(user, [])

        with self.auth_perms("@user-admin") as client:
            client.set_user_perms(user["username"], ["@all"])
        self.assertUserPerms(user, sorted(list(ALL_PERMISSIONS)))

        # Bad permissions
        with self.auth_perms("@user-admin") as client, self.assertRaises(InvokeError):
            client.set_user_perms(user["username"], ["@this-is-not-a-permission"])
        self.assertUserPerms(user, sorted(list(ALL_PERMISSIONS)))

    def test_auth_get_all_users(self):
        admin_client = self.start_auth_server()

        user = self.create_user("test-user", [])

        with self.auth_client(user) as client, self.assertRaises(InvokeError):
            client.get_all_users()

        # Give the test user the correct permission
        admin_client.set_user_perms(user["username"], ["@user-admin"])

        with self.auth_client(user) as client:
            all_users = client.get_all_users()

        # Convert to a dictionary for easier comparison
        all_users = {u["username"]: u for u in all_users}

        self.assertEqual(all_users,
            {
                "admin": {
                    "username": "admin",
                    "permissions": sorted(list(ALL_PERMISSIONS)),
                },
                "test-user": {
                    "username": "test-user",
                    "permissions": ["@user-admin"],
                }
            }
        )

    def test_auth_new_user(self):
        self.start_auth_server()

        permissions = ["@read", "@report", "@db-admin", "@user-admin"]
        permissions.sort()

        with self.auth_perms() as client, self.assertRaises(InvokeError):
            self.create_user("test-user", permissions, client=client)

        with self.auth_perms("@user-admin") as client:
            user = self.create_user("test-user", permissions, client=client)
            self.assertIn("token", user)
            self.assertEqual(user["username"], "test-user")
            self.assertEqual(user["permissions"], permissions)

    def test_auth_become_user(self):
        admin_client = self.start_auth_server()

        user = self.create_user("test-user", ["@read", "@report"])
        user_info = user.copy()
        del user_info["token"]

        with self.auth_perms() as client, self.assertRaises(InvokeError):
            client.become_user(user["username"])

        with self.auth_perms("@user-admin") as client:
            become = client.become_user(user["username"])
            self.assertEqual(become, user_info)

            info = client.get_user()
            self.assertEqual(info, user_info)

            # Verify become user is preserved across disconnect
            client.disconnect()

            info = client.get_user()
            self.assertEqual(info, user_info)

            # test-user doesn't have become_user permissions, so this should
            # not work
            with self.assertRaises(InvokeError):
                client.become_user(user["username"])

        # No self-service of become
        with self.auth_client(user) as client, self.assertRaises(InvokeError):
            client.become_user(user["username"])

        # Give test user permissions to become
        admin_client.set_user_perms(user["username"], ["@user-admin"])

        # It's possible to become yourself (effectively a noop)
        with self.auth_perms("@user-admin") as client:
            become = client.become_user(client.username)

    def test_auth_gc(self):
        admin_client = self.start_auth_server()

        with self.auth_perms() as client, self.assertRaises(InvokeError):
            client.gc_mark("ABC", {"unihash": "123"})

        with self.auth_perms() as client, self.assertRaises(InvokeError):
            client.gc_status()

        with self.auth_perms() as client, self.assertRaises(InvokeError):
            client.gc_sweep("ABC")

        with self.auth_perms("@db-admin") as client:
            client.gc_mark("ABC", {"unihash": "123"})

        with self.auth_perms("@db-admin") as client:
            client.gc_status()

        with self.auth_perms("@db-admin") as client:
            client.gc_sweep("ABC")

    def test_get_db_usage(self):
        usage = self.client.get_db_usage()

        self.assertTrue(isinstance(usage, dict))
        for name in usage.keys():
            self.assertTrue(isinstance(usage[name], dict))
            self.assertIn("rows", usage[name])
            self.assertTrue(isinstance(usage[name]["rows"], int))

    def test_get_db_query_columns(self):
        columns = self.client.get_db_query_columns()

        self.assertTrue(isinstance(columns, list))
        self.assertTrue(len(columns) > 0)

        for col in columns:
            self.client.remove({col: ""})

    def test_auth_is_owner(self):
        admin_client = self.start_auth_server()

        user = self.create_user("test-user", ["@read", "@report"])
        with self.auth_client(user) as client:
            taskhash, outhash, unihash = self.create_test_hash(client)
            data = client.get_taskhash(self.METHOD, taskhash, True)
            self.assertEqual(data["owner"], user["username"])

    def test_gc(self):
        taskhash = '53b8dce672cb6d0c73170be43f540460bfc347b4'
        outhash = '5a9cb1649625f0bf41fc7791b635cd9c2d7118c7f021ba87dcd03f72b67ce7a8'
        unihash = 'f37918cc02eb5a520b1aff86faacbc0a38124646'

        result = self.client.report_unihash(taskhash, self.METHOD, outhash, unihash)
        self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash')

        taskhash2 = '3bf6f1e89d26205aec90da04854fbdbf73afe6b4'
        outhash2 = '77623a549b5b1a31e3732dfa8fe61d7ce5d44b3370f253c5360e136b852967b4'
        unihash2 = 'af36b199320e611fbb16f1f277d3ee1d619ca58b'

        result = self.client.report_unihash(taskhash2, self.METHOD, outhash2, unihash2)
        self.assertClientGetHash(self.client, taskhash2, unihash2)

        # Mark the first unihash to be kept
        ret = self.client.gc_mark("ABC", {"unihash": unihash, "method": self.METHOD})
        self.assertEqual(ret, {"count": 1})

        ret = self.client.gc_status()
        self.assertEqual(ret, {"mark": "ABC", "keep": 1, "remove": 1})

        # Second hash is still there; mark doesn't delete hashes
        self.assertClientGetHash(self.client, taskhash2, unihash2)

        ret = self.client.gc_sweep("ABC")
        self.assertEqual(ret, {"count": 1})

        # Hash is gone. Taskhash is returned for second hash
        self.assertClientGetHash(self.client, taskhash2, None)
        # First hash is still present
        self.assertClientGetHash(self.client, taskhash, unihash)

    def test_gc_switch_mark(self):
        taskhash = '53b8dce672cb6d0c73170be43f540460bfc347b4'
        outhash = '5a9cb1649625f0bf41fc7791b635cd9c2d7118c7f021ba87dcd03f72b67ce7a8'
        unihash = 'f37918cc02eb5a520b1aff86faacbc0a38124646'

        result = self.client.report_unihash(taskhash, self.METHOD, outhash, unihash)
        self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash')

        taskhash2 = '3bf6f1e89d26205aec90da04854fbdbf73afe6b4'
        outhash2 = '77623a549b5b1a31e3732dfa8fe61d7ce5d44b3370f253c5360e136b852967b4'
        unihash2 = 'af36b199320e611fbb16f1f277d3ee1d619ca58b'

        result = self.client.report_unihash(taskhash2, self.METHOD, outhash2, unihash2)
        self.assertClientGetHash(self.client, taskhash2, unihash2)

        # Mark the first unihash to be kept
        ret = self.client.gc_mark("ABC", {"unihash": unihash, "method": self.METHOD})
        self.assertEqual(ret, {"count": 1})

        ret = self.client.gc_status()
        self.assertEqual(ret, {"mark": "ABC", "keep": 1, "remove": 1})

        # Second hash is still there; mark doesn't delete hashes
        self.assertClientGetHash(self.client, taskhash2, unihash2)

        # Switch to a different mark and mark the second hash. This will start
        # a new collection cycle
        ret = self.client.gc_mark("DEF", {"unihash": unihash2, "method": self.METHOD})
        self.assertEqual(ret, {"count": 1})

        ret = self.client.gc_status()
        self.assertEqual(ret, {"mark": "DEF", "keep": 1, "remove": 1})

        # Both hashes are still present
        self.assertClientGetHash(self.client, taskhash2, unihash2)
        self.assertClientGetHash(self.client, taskhash, unihash)

        # Sweep with the new mark
        ret = self.client.gc_sweep("DEF")
        self.assertEqual(ret, {"count": 1})

        # First hash is gone, second is kept
        self.assertClientGetHash(self.client, taskhash2, unihash2)
        self.assertClientGetHash(self.client, taskhash, None)

    def test_gc_switch_sweep_mark(self):
        taskhash = '53b8dce672cb6d0c73170be43f540460bfc347b4'
        outhash = '5a9cb1649625f0bf41fc7791b635cd9c2d7118c7f021ba87dcd03f72b67ce7a8'
        unihash = 'f37918cc02eb5a520b1aff86faacbc0a38124646'

        result = self.client.report_unihash(taskhash, self.METHOD, outhash, unihash)
        self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash')

        taskhash2 = '3bf6f1e89d26205aec90da04854fbdbf73afe6b4'
        outhash2 = '77623a549b5b1a31e3732dfa8fe61d7ce5d44b3370f253c5360e136b852967b4'
        unihash2 = 'af36b199320e611fbb16f1f277d3ee1d619ca58b'

        result = self.client.report_unihash(taskhash2, self.METHOD, outhash2, unihash2)
        self.assertClientGetHash(self.client, taskhash2, unihash2)

        # Mark the first unihash to be kept
        ret = self.client.gc_mark("ABC", {"unihash": unihash, "method": self.METHOD})
        self.assertEqual(ret, {"count": 1})

        ret = self.client.gc_status()
        self.assertEqual(ret, {"mark": "ABC", "keep": 1, "remove": 1})

        # Sweeping with a different mark raises an error
        with self.assertRaises(InvokeError):
            self.client.gc_sweep("DEF")

        # Both hashes are present
        self.assertClientGetHash(self.client, taskhash2, unihash2)
        self.assertClientGetHash(self.client, taskhash, unihash)

    def test_gc_new_hashes(self):
        taskhash = '53b8dce672cb6d0c73170be43f540460bfc347b4'
        outhash = '5a9cb1649625f0bf41fc7791b635cd9c2d7118c7f021ba87dcd03f72b67ce7a8'
        unihash = 'f37918cc02eb5a520b1aff86faacbc0a38124646'

        result = self.client.report_unihash(taskhash, self.METHOD, outhash, unihash)
        self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash')

        # Start a new garbage collection
        ret = self.client.gc_mark("ABC", {"unihash": unihash, "method": self.METHOD})
        self.assertEqual(ret, {"count": 1})

        ret = self.client.gc_status()
        self.assertEqual(ret, {"mark": "ABC", "keep": 1, "remove": 0})

        # Add second hash. It should inherit the mark from the current garbage
        # collection operation

        taskhash2 = '3bf6f1e89d26205aec90da04854fbdbf73afe6b4'
        outhash2 = '77623a549b5b1a31e3732dfa8fe61d7ce5d44b3370f253c5360e136b852967b4'
        unihash2 = 'af36b199320e611fbb16f1f277d3ee1d619ca58b'

        result = self.client.report_unihash(taskhash2, self.METHOD, outhash2, unihash2)
        self.assertClientGetHash(self.client, taskhash2, unihash2)

        # Sweep should remove nothing
        ret = self.client.gc_sweep("ABC")
        self.assertEqual(ret, {"count": 0})

        # Both hashes are present
        self.assertClientGetHash(self.client, taskhash2, unihash2)
        self.assertClientGetHash(self.client, taskhash, unihash)


class TestHashEquivalenceClient(HashEquivalenceTestSetup, unittest.TestCase):
    def get_server_addr(self, server_idx):
        return "unix://" + os.path.join(self.temp_dir.name, 'sock%d' % server_idx)

    def test_get(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)

        p = self.run_hashclient(["--address", self.server_address, "get", self.METHOD, taskhash])
        data = json.loads(p.stdout)
        self.assertEqual(data["unihash"], unihash)
        self.assertEqual(data["outhash"], outhash)
        self.assertEqual(data["taskhash"], taskhash)
        self.assertEqual(data["method"], self.METHOD)

    def test_get_outhash(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)

        p = self.run_hashclient(["--address", self.server_address, "get-outhash", self.METHOD, outhash, taskhash])
        data = json.loads(p.stdout)
        self.assertEqual(data["unihash"], unihash)
        self.assertEqual(data["outhash"], outhash)
        self.assertEqual(data["taskhash"], taskhash)
        self.assertEqual(data["method"], self.METHOD)

    def test_stats(self):
        p = self.run_hashclient(["--address", self.server_address, "stats"], check=True)
        json.loads(p.stdout)

    def test_stress(self):
        self.run_hashclient(["--address", self.server_address, "stress"], check=True)

    def test_unihash_exsits(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)

        p = self.run_hashclient([
            "--address", self.server_address,
            "unihash-exists", unihash,
        ], check=True)
        self.assertEqual(p.stdout.strip(), "true")

        p = self.run_hashclient([
            "--address", self.server_address,
            "unihash-exists", '6662e699d6e3d894b24408ff9a4031ef9b038ee8',
        ], check=True)
        self.assertEqual(p.stdout.strip(), "false")

    def test_unihash_exsits_quiet(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)

        p = self.run_hashclient([
            "--address", self.server_address,
            "unihash-exists", unihash,
            "--quiet",
        ])
        self.assertEqual(p.returncode, 0)
        self.assertEqual(p.stdout.strip(), "")

        p = self.run_hashclient([
            "--address", self.server_address,
            "unihash-exists", '6662e699d6e3d894b24408ff9a4031ef9b038ee8',
            "--quiet",
        ])
        self.assertEqual(p.returncode, 1)
        self.assertEqual(p.stdout.strip(), "")

    def test_remove_taskhash(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)
        self.run_hashclient([
            "--address", self.server_address,
            "remove",
            "--where", "taskhash", taskhash,
        ], check=True)
        self.assertClientGetHash(self.client, taskhash, None)

        result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash)
        self.assertIsNone(result_outhash)

    def test_remove_unihash(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)
        self.run_hashclient([
            "--address", self.server_address,
            "remove",
            "--where", "unihash", unihash,
        ], check=True)
        self.assertClientGetHash(self.client, taskhash, None)

    def test_remove_outhash(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)
        self.run_hashclient([
            "--address", self.server_address,
            "remove",
            "--where", "outhash", outhash,
        ], check=True)

        result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash)
        self.assertIsNone(result_outhash)

    def test_remove_method(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)
        self.run_hashclient([
            "--address", self.server_address,
            "remove",
            "--where", "method", self.METHOD,
        ], check=True)
        self.assertClientGetHash(self.client, taskhash, None)

        result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash)
        self.assertIsNone(result_outhash)

    def test_clean_unused(self):
        taskhash, outhash, unihash = self.create_test_hash(self.client)

        # Clean the database, which should not remove anything because all hashes an in-use
        self.run_hashclient([
            "--address", self.server_address,
            "clean-unused", "0",
        ], check=True)
        self.assertClientGetHash(self.client, taskhash, unihash)

        # Remove the unihash. The row in the outhash table should still be present
        self.run_hashclient([
            "--address", self.server_address,
            "remove",
            "--where", "unihash", unihash,
        ], check=True)
        result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash, False)
        self.assertIsNotNone(result_outhash)

        # Now clean with no minimum age which will remove the outhash
        self.run_hashclient([
            "--address", self.server_address,
            "clean-unused", "0",
        ], check=True)
        result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash, False)
        self.assertIsNone(result_outhash)

    def test_refresh_token(self):
        admin_client = self.start_auth_server()

        user = admin_client.new_user("test-user", ["@read", "@report"])

        p = self.run_hashclient([
            "--address", self.auth_server_address,
            "--login", user["username"],
            "--password", user["token"],
            "refresh-token"
        ], check=True)

        new_token = None
        for l in p.stdout.splitlines():
            l = l.rstrip()
            m = re.match(r'Token: +(.*)$', l)
            if m is not None:
                new_token = m.group(1)

        self.assertTrue(new_token)

        print("New token is %r" % new_token)

        self.run_hashclient([
            "--address", self.auth_server_address,
            "--login", user["username"],
            "--password", new_token,
            "get-user"
        ], check=True)

    def test_set_user_perms(self):
        admin_client = self.start_auth_server()

        user = admin_client.new_user("test-user", ["@read"])

        self.run_hashclient([
            "--address", self.auth_server_address,
            "--login", admin_client.username,
            "--password", admin_client.password,
            "set-user-perms",
            "-u", user["username"],
            "@read", "@report",
        ], check=True)

        new_user = admin_client.get_user(user["username"])

        self.assertEqual(set(new_user["permissions"]), {"@read", "@report"})

    def test_get_user(self):
        admin_client = self.start_auth_server()

        user = admin_client.new_user("test-user", ["@read"])

        p = self.run_hashclient([
            "--address", self.auth_server_address,
            "--login", admin_client.username,
            "--password", admin_client.password,
            "get-user",
            "-u", user["username"],
        ], check=True)

        self.assertIn("Username:", p.stdout)
        self.assertIn("Permissions:", p.stdout)

        p = self.run_hashclient([
            "--address", self.auth_server_address,
            "--login", user["username"],
            "--password", user["token"],
            "get-user",
        ], check=True)

        self.assertIn("Username:", p.stdout)
        self.assertIn("Permissions:", p.stdout)

    def test_get_all_users(self):
        admin_client = self.start_auth_server()

        admin_client.new_user("test-user1", ["@read"])
        admin_client.new_user("test-user2", ["@read"])

        p = self.run_hashclient([
            "--address", self.auth_server_address,
            "--login", admin_client.username,
            "--password", admin_client.password,
            "get-all-users",
        ], check=True)

        self.assertIn("admin", p.stdout)
        self.assertIn("test-user1", p.stdout)
        self.assertIn("test-user2", p.stdout)

    def test_new_user(self):
        admin_client = self.start_auth_server()

        p = self.run_hashclient([
            "--address", self.auth_server_address,
            "--login", admin_client.username,
            "--password", admin_client.password,
            "new-user",
            "-u", "test-user",
            "@read", "@report",
        ], check=True)

        new_token = None
        for l in p.stdout.splitlines():
            l = l.rstrip()
            m = re.match(r'Token: +(.*)$', l)
            if m is not None:
                new_token = m.group(1)

        self.assertTrue(new_token)

        user = {
            "username": "test-user",
            "token": new_token,
        }

        self.assertUserPerms(user, ["@read", "@report"])

    def test_delete_user(self):
        admin_client = self.start_auth_server()

        user = admin_client.new_user("test-user", ["@read"])

        p = self.run_hashclient([
            "--address", self.auth_server_address,
            "--login", admin_client.username,
            "--password", admin_client.password,
            "delete-user",
            "-u", user["username"],
        ], check=True)

        self.assertIsNone(admin_client.get_user(user["username"]))

    def test_get_db_usage(self):
        p = self.run_hashclient([
            "--address", self.server_address,
            "get-db-usage",
        ], check=True)

    def test_get_db_query_columns(self):
        p = self.run_hashclient([
            "--address", self.server_address,
            "get-db-query-columns",
        ], check=True)

    def test_gc(self):
        taskhash = '53b8dce672cb6d0c73170be43f540460bfc347b4'
        outhash = '5a9cb1649625f0bf41fc7791b635cd9c2d7118c7f021ba87dcd03f72b67ce7a8'
        unihash = 'f37918cc02eb5a520b1aff86faacbc0a38124646'

        result = self.client.report_unihash(taskhash, self.METHOD, outhash, unihash)
        self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash')

        taskhash2 = '3bf6f1e89d26205aec90da04854fbdbf73afe6b4'
        outhash2 = '77623a549b5b1a31e3732dfa8fe61d7ce5d44b3370f253c5360e136b852967b4'
        unihash2 = 'af36b199320e611fbb16f1f277d3ee1d619ca58b'

        result = self.client.report_unihash(taskhash2, self.METHOD, outhash2, unihash2)
        self.assertClientGetHash(self.client, taskhash2, unihash2)

        # Mark the first unihash to be kept
        self.run_hashclient([
            "--address", self.server_address,
            "gc-mark", "ABC",
            "--where", "unihash", unihash,
            "--where", "method", self.METHOD
        ], check=True)

        # Second hash is still there; mark doesn't delete hashes
        self.assertClientGetHash(self.client, taskhash2, unihash2)

        self.run_hashclient([
            "--address", self.server_address,
            "gc-sweep", "ABC",
        ], check=True)

        # Hash is gone. Taskhash is returned for second hash
        self.assertClientGetHash(self.client, taskhash2, None)
        # First hash is still present
        self.assertClientGetHash(self.client, taskhash, unihash)


class TestHashEquivalenceUnixServer(HashEquivalenceTestSetup, HashEquivalenceCommonTests, unittest.TestCase):
    def get_server_addr(self, server_idx):
        return "unix://" + os.path.join(self.temp_dir.name, 'sock%d' % server_idx)


class TestHashEquivalenceUnixServerLongPath(HashEquivalenceTestSetup, unittest.TestCase):
    DEEP_DIRECTORY = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ccccccccccccccccccccccccccccccccccccccccccc"
    def get_server_addr(self, server_idx):
        os.makedirs(os.path.join(self.temp_dir.name, self.DEEP_DIRECTORY), exist_ok=True)
        return "unix://" + os.path.join(self.temp_dir.name, self.DEEP_DIRECTORY, 'sock%d' % server_idx)


    def test_long_sock_path(self):
        # Simple test that hashes can be created
        taskhash = '35788efcb8dfb0a02659d81cf2bfd695fb30faf9'
        outhash = '2765d4a5884be49b28601445c2760c5f21e7e5c0ee2b7e3fce98fd7e5970796f'
        unihash = 'f46d3fbb439bd9b921095da657a4de906510d2cd'

        self.assertClientGetHash(self.client, taskhash, None)

        result = self.client.report_unihash(taskhash, self.METHOD, outhash, unihash)
        self.assertEqual(result['unihash'], unihash, 'Server returned bad unihash')


class TestHashEquivalenceTCPServer(HashEquivalenceTestSetup, HashEquivalenceCommonTests, unittest.TestCase):
    def get_server_addr(self, server_idx):
        # Some hosts cause asyncio module to misbehave, when IPv6 is not enabled.
        # If IPv6 is enabled, it should be safe to use localhost directly, in general
        # case it is more reliable to resolve the IP address explicitly.
        return socket.gethostbyname("localhost") + ":0"


class TestHashEquivalenceWebsocketServer(HashEquivalenceTestSetup, HashEquivalenceCommonTests, unittest.TestCase):
    def setUp(self):
        try:
            import websockets
        except ImportError as e:
            self.skipTest(str(e))

        super().setUp()

    def get_server_addr(self, server_idx):
        # Some hosts cause asyncio module to misbehave, when IPv6 is not enabled.
        # If IPv6 is enabled, it should be safe to use localhost directly, in general
        # case it is more reliable to resolve the IP address explicitly.
        host = socket.gethostbyname("localhost")
        return "ws://%s:0" % host


class TestHashEquivalenceWebsocketsSQLAlchemyServer(TestHashEquivalenceWebsocketServer):
    def setUp(self):
        try:
            import sqlalchemy
            import aiosqlite
        except ImportError as e:
            self.skipTest(str(e))

        super().setUp()

    def make_dbpath(self):
        return "sqlite+aiosqlite:///%s" % os.path.join(self.temp_dir.name, "db%d.sqlite" % self.server_index)


class TestHashEquivalenceExternalServer(HashEquivalenceTestSetup, HashEquivalenceCommonTests, unittest.TestCase):
    def get_env(self, name):
        v = os.environ.get(name)
        if not v:
            self.skipTest(f'{name} not defined to test an external server')
        return v

    def start_test_server(self):
        return self.get_env('BB_TEST_HASHSERV')

    def start_server(self, *args, **kwargs):
        self.skipTest('Cannot start local server when testing external servers')

    def start_auth_server(self):

        self.auth_server_address = self.server_address
        self.admin_client = self.start_client(
            self.server_address,
            username=self.get_env('BB_TEST_HASHSERV_USERNAME'),
            password=self.get_env('BB_TEST_HASHSERV_PASSWORD'),
        )
        return self.admin_client

    def setUp(self):
        super().setUp()
        if "BB_TEST_HASHSERV_USERNAME" in os.environ:
            self.client = self.start_client(
                self.server_address,
                username=os.environ["BB_TEST_HASHSERV_USERNAME"],
                password=os.environ["BB_TEST_HASHSERV_PASSWORD"],
            )
        self.client.remove({"method": self.METHOD})

    def tearDown(self):
        self.client.remove({"method": self.METHOD})
        super().tearDown()


    def test_auth_get_all_users(self):
        self.skipTest("Cannot test all users with external server")

