def test_upload():
    'Tests the UPLOAD command'
    dbconn = setup_test()
    dbdata = init_server(dbconn)
    conn = ServerConnection()
    assert conn.connect('localhost', 2001), 'Connection to server at localhost:2001 failed'
    reset_top_dir(dbdata)
    pwhash = '$argon2id$v=19$m=65536,t=2,p=1$ew5lqHA5z38za+257DmnTA$0LWVrI2r7XCqdcCYkJLok65qussSyhN5TTZP+OTgzEI'
    devid = '22222222-2222-2222-2222-222222222222'
    devpair = EncryptionPair(CryptoString('CURVE25519:@X~msiMmBq0nsNnn0%~x{M|NU_{?<Wj)cYybdh&Z'), CryptoString('CURVE25519:W30{oJ?w~NBbj{F8Ag4~<bcWy6_uQ{i{X?NDq4^l'))
    dbdata['pwhash'] = pwhash
    dbdata['devid'] = devid
    dbdata['devpair'] = devpair
    regcode_admin(dbdata, conn)
    login_admin(dbdata, conn)
    init_user(dbdata, conn)
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': '1000', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 400), 'test_upload: #1 failed to handle missing parameter'
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': '1000', 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': (('/ wsp ' + dbdata['admin_wid']) + ' 22222222-2222-2222-2222-222222222222')}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 404), 'test_upload: #2 failed to handle non-existent path'
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str((1073741824 * 200)), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 414), 'test_upload: #3 failed to handle file too big'
    cur = dbconn.cursor()
    cur.execute(f"INSERT INTO quotas(wid, usage, quota)	VALUES('{dbdata['admin_wid']}', 5100 , 5120)")
    dbconn.commit()
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str((1048576 * 30)), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 409), 'test_upload: #4 quota check failed'
    cur = dbconn.cursor()
    cur.execute(f"UPDATE quotas SET quota=0 WHERE wid = '{dbdata['admin_wid']}'")
    dbconn.commit()
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:5(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 100), 'test_upload: #5 failed to proceed to file upload'
    conn.write(('0' * 1000))
    response = conn.read_response(server_response)
    assert (response['Code'] == 410), 'test_upload: #5 failed to handle file hash mismatch'
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 100), 'test_upload: #6 failed to proceed to file upload'
    conn.write(('0' * 1000))
    response = conn.read_response(server_response)
    assert (response['Code'] == 200), 'test_upload: #6 failed to handle file hash mismatch'
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    tempFileName = response['Data']['TempName']
    assert (response['Code'] == 100), 'test_upload: #6 failed to proceed to file upload'
    assert (tempFileName != ''), 'test_upload: #6 server failed to return temp file name'
    conn.write(('0' * 500))
    del conn
    conn = ServerConnection()
    assert conn.connect('localhost', 2001), 'Connection to server at localhost:2001 failed'
    login_admin(dbdata, conn)
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid']), 'TempName': tempFileName, 'Offset': '2000'}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 400), 'test_upload: #7 failed to handle offset > file size'
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid']), 'TempName': tempFileName, 'Offset': '500'}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 100), 'test_upload: #8 failed to proceed to file upload'
    conn.write(('0' * 500))
    response = conn.read_response(server_response)
    assert (response['Code'] == 200), 'test_upload: #8 failed to resume with exact offset match'
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    tempFileName = response['Data']['TempName']
    assert (response['Code'] == 100), 'test_upload: #6 failed to proceed to file upload'
    assert (tempFileName != ''), 'test_upload: #6 server failed to return temp file name'
    conn.write(('0' * 500))
    del conn
    conn = ServerConnection()
    assert conn.connect('localhost', 2001), 'Connection to server at localhost:2001 failed'
    login_admin(dbdata, conn)
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid']), 'TempName': tempFileName, 'Offset': '400'}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 100), 'test_upload: #9 failed to proceed to file upload'
    conn.write(('0' * 600))
    response = conn.read_response(server_response)
    assert (response['Code'] == 200), 'test_upload: #9 failed to resume with overlapping offset'
    conn.disconnect()
Tests the UPLOAD command
def test_upload():
    
    dbconn = setup_test()
    dbdata = init_server(dbconn)
    conn = ServerConnection()
    assert conn.connect('localhost', 2001), 'Connection to server at localhost:2001 failed'
    reset_top_dir(dbdata)
    pwhash = '$argon2id$v=19$m=65536,t=2,p=1$ew5lqHA5z38za+257DmnTA$0LWVrI2r7XCqdcCYkJLok65qussSyhN5TTZP+OTgzEI'
    devid = '22222222-2222-2222-2222-222222222222'
    devpair = EncryptionPair(CryptoString('CURVE25519:@X~msiMmBq0nsNnn0%~x{M|NU_{?<Wj)cYybdh&Z'), CryptoString('CURVE25519:W30{oJ?w~NBbj{F8Ag4~<bcWy6_uQ{i{X?NDq4^l'))
    dbdata['pwhash'] = pwhash
    dbdata['devid'] = devid
    dbdata['devpair'] = devpair
    regcode_admin(dbdata, conn)
    login_admin(dbdata, conn)
    init_user(dbdata, conn)
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': '1000', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 400), 'test_upload: #1 failed to handle missing parameter'
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': '1000', 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': (('/ wsp ' + dbdata['admin_wid']) + ' 22222222-2222-2222-2222-222222222222')}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 404), 'test_upload: #2 failed to handle non-existent path'
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str((1073741824 * 200)), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 414), 'test_upload: #3 failed to handle file too big'
    cur = dbconn.cursor()
    cur.execute(f"INSERT INTO quotas(wid, usage, quota)	VALUES('{dbdata['admin_wid']}', 5100 , 5120)")
    dbconn.commit()
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str((1048576 * 30)), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 409), 'test_upload: #4 quota check failed'
    cur = dbconn.cursor()
    cur.execute(f"UPDATE quotas SET quota=0 WHERE wid = '{dbdata['admin_wid']}'")
    dbconn.commit()
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:5(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 100), 'test_upload: #5 failed to proceed to file upload'
    conn.write(('0' * 1000))
    response = conn.read_response(server_response)
    assert (response['Code'] == 410), 'test_upload: #5 failed to handle file hash mismatch'
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 100), 'test_upload: #6 failed to proceed to file upload'
    conn.write(('0' * 1000))
    response = conn.read_response(server_response)
    assert (response['Code'] == 200), 'test_upload: #6 failed to handle file hash mismatch'
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    tempFileName = response['Data']['TempName']
    assert (response['Code'] == 100), 'test_upload: #6 failed to proceed to file upload'
    assert (tempFileName != ), 'test_upload: #6 server failed to return temp file name'
    conn.write(('0' * 500))
    del conn
    conn = ServerConnection()
    assert conn.connect('localhost', 2001), 'Connection to server at localhost:2001 failed'
    login_admin(dbdata, conn)
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid']), 'TempName': tempFileName, 'Offset': '2000'}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 400), 'test_upload: #7 failed to handle offset > file size'
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid']), 'TempName': tempFileName, 'Offset': '500'}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 100), 'test_upload: #8 failed to proceed to file upload'
    conn.write(('0' * 500))
    response = conn.read_response(server_response)
    assert (response['Code'] == 200), 'test_upload: #8 failed to resume with exact offset match'
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid'])}})
    response = conn.read_response(server_response)
    tempFileName = response['Data']['TempName']
    assert (response['Code'] == 100), 'test_upload: #6 failed to proceed to file upload'
    assert (tempFileName != ), 'test_upload: #6 server failed to return temp file name'
    conn.write(('0' * 500))
    del conn
    conn = ServerConnection()
    assert conn.connect('localhost', 2001), 'Connection to server at localhost:2001 failed'
    login_admin(dbdata, conn)
    conn.send_message({'Action': 'UPLOAD', 'Data': {'Size': str(1000), 'Hash': 'BLAKE2B-256:4(8V*JuSdLH#SL%edxldiA<&TayrTtdIV9yiK~Tp', 'Path': ('/ wsp ' + dbdata['admin_wid']), 'TempName': tempFileName, 'Offset': '400'}})
    response = conn.read_response(server_response)
    assert (response['Code'] == 100), 'test_upload: #9 failed to proceed to file upload'
    conn.write(('0' * 600))
    response = conn.read_response(server_response)
    assert (response['Code'] == 200), 'test_upload: #9 failed to resume with overlapping offset'
    conn.disconnect()