1import time
2import io
3
4import pytest
5
6from File import FileServer
7from File import FileRequest
8from Crypt import CryptHash
9from . import Spy
10
11
12@pytest.mark.usefixtures("resetSettings")
13@pytest.mark.usefixtures("resetTempSettings")
14class TestPeer:
15    def testPing(self, file_server, site, site_temp):
16        file_server.sites[site.address] = site
17        client = FileServer(file_server.ip, 1545)
18        client.sites[site_temp.address] = site_temp
19        site_temp.connection_server = client
20        connection = client.getConnection(file_server.ip, 1544)
21
22        # Add file_server as peer to client
23        peer_file_server = site_temp.addPeer(file_server.ip, 1544)
24
25        assert peer_file_server.ping() is not None
26
27        assert peer_file_server in site_temp.peers.values()
28        peer_file_server.remove()
29        assert peer_file_server not in site_temp.peers.values()
30
31        connection.close()
32        client.stop()
33
34    def testDownloadFile(self, file_server, site, site_temp):
35        file_server.sites[site.address] = site
36        client = FileServer(file_server.ip, 1545)
37        client.sites[site_temp.address] = site_temp
38        site_temp.connection_server = client
39        connection = client.getConnection(file_server.ip, 1544)
40
41        # Add file_server as peer to client
42        peer_file_server = site_temp.addPeer(file_server.ip, 1544)
43
44        # Testing streamFile
45        buff = peer_file_server.getFile(site_temp.address, "content.json", streaming=True)
46        assert b"sign" in buff.getvalue()
47
48        # Testing getFile
49        buff = peer_file_server.getFile(site_temp.address, "content.json")
50        assert b"sign" in buff.getvalue()
51
52        connection.close()
53        client.stop()
54
55    def testHashfield(self, site):
56        sample_hash = list(site.content_manager.contents["content.json"]["files_optional"].values())[0]["sha512"]
57
58        site.storage.verifyFiles(quick_check=True)  # Find what optional files we have
59
60        # Check if hashfield has any files
61        assert site.content_manager.hashfield
62        assert len(site.content_manager.hashfield) > 0
63
64        # Check exsist hash
65        assert site.content_manager.hashfield.getHashId(sample_hash) in site.content_manager.hashfield
66
67        # Add new hash
68        new_hash = CryptHash.sha512sum(io.BytesIO(b"hello"))
69        assert site.content_manager.hashfield.getHashId(new_hash) not in site.content_manager.hashfield
70        assert site.content_manager.hashfield.appendHash(new_hash)
71        assert not site.content_manager.hashfield.appendHash(new_hash)  # Don't add second time
72        assert site.content_manager.hashfield.getHashId(new_hash) in site.content_manager.hashfield
73
74        # Remove new hash
75        assert site.content_manager.hashfield.removeHash(new_hash)
76        assert site.content_manager.hashfield.getHashId(new_hash) not in site.content_manager.hashfield
77
78    def testHashfieldExchange(self, file_server, site, site_temp):
79        server1 = file_server
80        server1.sites[site.address] = site
81        site.connection_server = server1
82
83        server2 = FileServer(file_server.ip, 1545)
84        server2.sites[site_temp.address] = site_temp
85        site_temp.connection_server = server2
86        site.storage.verifyFiles(quick_check=True)  # Find what optional files we have
87
88        # Add file_server as peer to client
89        server2_peer1 = site_temp.addPeer(file_server.ip, 1544)
90
91        # Check if hashfield has any files
92        assert len(site.content_manager.hashfield) > 0
93
94        # Testing hashfield sync
95        assert len(server2_peer1.hashfield) == 0
96        assert server2_peer1.updateHashfield()  # Query hashfield from peer
97        assert len(server2_peer1.hashfield) > 0
98
99        # Test force push new hashfield
100        site_temp.content_manager.hashfield.appendHash("AABB")
101        server1_peer2 = site.addPeer(file_server.ip, 1545, return_peer=True)
102        with Spy.Spy(FileRequest, "route") as requests:
103            assert len(server1_peer2.hashfield) == 0
104            server2_peer1.sendMyHashfield()
105            assert len(server1_peer2.hashfield) == 1
106            server2_peer1.sendMyHashfield()  # Hashfield not changed, should be ignored
107
108            assert len(requests) == 1
109
110            time.sleep(0.01)  # To make hashfield change date different
111
112            site_temp.content_manager.hashfield.appendHash("AACC")
113            server2_peer1.sendMyHashfield()  # Push hashfield
114
115            assert len(server1_peer2.hashfield) == 2
116            assert len(requests) == 2
117
118            site_temp.content_manager.hashfield.appendHash("AADD")
119
120            assert server1_peer2.updateHashfield(force=True)  # Request hashfield
121            assert len(server1_peer2.hashfield) == 3
122            assert len(requests) == 3
123
124            assert not server2_peer1.sendMyHashfield()  # Not changed, should be ignored
125            assert len(requests) == 3
126
127        server2.stop()
128
129    def testFindHash(self, file_server, site, site_temp):
130        file_server.sites[site.address] = site
131        client = FileServer(file_server.ip, 1545)
132        client.sites[site_temp.address] = site_temp
133        site_temp.connection_server = client
134
135        # Add file_server as peer to client
136        peer_file_server = site_temp.addPeer(file_server.ip, 1544)
137
138        assert peer_file_server.findHashIds([1234]) == {}
139
140        # Add fake peer with requred hash
141        fake_peer_1 = site.addPeer(file_server.ip_external, 1544)
142        fake_peer_1.hashfield.append(1234)
143        fake_peer_2 = site.addPeer("1.2.3.5", 1545)
144        fake_peer_2.hashfield.append(1234)
145        fake_peer_2.hashfield.append(1235)
146        fake_peer_3 = site.addPeer("1.2.3.6", 1546)
147        fake_peer_3.hashfield.append(1235)
148        fake_peer_3.hashfield.append(1236)
149
150        res = peer_file_server.findHashIds([1234, 1235])
151        assert sorted(res[1234]) == sorted([(file_server.ip_external, 1544), ("1.2.3.5", 1545)])
152        assert sorted(res[1235]) == sorted([("1.2.3.5", 1545), ("1.2.3.6", 1546)])
153
154        # Test my address adding
155        site.content_manager.hashfield.append(1234)
156
157        res = peer_file_server.findHashIds([1234, 1235])
158        assert sorted(res[1234]) == sorted([(file_server.ip_external, 1544), ("1.2.3.5", 1545), (file_server.ip, 1544)])
159        assert sorted(res[1235]) == sorted([("1.2.3.5", 1545), ("1.2.3.6", 1546)])
160