weed-cli 1.8.0__tar.gz → 1.8.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. {weed_cli-1.8.0/weed_cli.egg-info → weed_cli-1.8.2}/PKG-INFO +1 -1
  2. {weed_cli-1.8.0 → weed_cli-1.8.2}/pyproject.toml +1 -1
  3. weed_cli-1.8.2/tests/test_dht.py +128 -0
  4. {weed_cli-1.8.0 → weed_cli-1.8.2/weed_cli.egg-info}/PKG-INFO +1 -1
  5. {weed_cli-1.8.0 → weed_cli-1.8.2}/weed_cli.egg-info/SOURCES.txt +1 -0
  6. {weed_cli-1.8.0 → weed_cli-1.8.2}/LICENSE +0 -0
  7. {weed_cli-1.8.0 → weed_cli-1.8.2}/README.md +0 -0
  8. {weed_cli-1.8.0 → weed_cli-1.8.2}/dht.py +0 -0
  9. {weed_cli-1.8.0 → weed_cli-1.8.2}/discovery_relay.py +0 -0
  10. {weed_cli-1.8.0 → weed_cli-1.8.2}/lightning_settle.py +0 -0
  11. {weed_cli-1.8.0 → weed_cli-1.8.2}/node.py +0 -0
  12. {weed_cli-1.8.0 → weed_cli-1.8.2}/poc_reputation.py +0 -0
  13. {weed_cli-1.8.0 → weed_cli-1.8.2}/setup.cfg +0 -0
  14. {weed_cli-1.8.0 → weed_cli-1.8.2}/shell.py +0 -0
  15. {weed_cli-1.8.0 → weed_cli-1.8.2}/tests/test_discovery_relay.py +0 -0
  16. {weed_cli-1.8.0 → weed_cli-1.8.2}/tests/test_node_manifest.py +0 -0
  17. {weed_cli-1.8.0 → weed_cli-1.8.2}/tests/test_web_ui_api.py +0 -0
  18. {weed_cli-1.8.0 → weed_cli-1.8.2}/tests/testutil.py +0 -0
  19. {weed_cli-1.8.0 → weed_cli-1.8.2}/tunnel_relay.py +0 -0
  20. {weed_cli-1.8.0 → weed_cli-1.8.2}/web_ui.py +0 -0
  21. {weed_cli-1.8.0 → weed_cli-1.8.2}/weed.py +0 -0
  22. {weed_cli-1.8.0 → weed_cli-1.8.2}/weed_cli.egg-info/dependency_links.txt +0 -0
  23. {weed_cli-1.8.0 → weed_cli-1.8.2}/weed_cli.egg-info/entry_points.txt +0 -0
  24. {weed_cli-1.8.0 → weed_cli-1.8.2}/weed_cli.egg-info/requires.txt +0 -0
  25. {weed_cli-1.8.0 → weed_cli-1.8.2}/weed_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weed-cli
3
- Version: 1.8.0
3
+ Version: 1.8.2
4
4
  Summary: Censorship-resistant video PoC — discovery/hosting/download over signed relay events, a real Kademlia DHT, or a TLS-capable NAT-traversal tunnel
5
5
  License: MIT
6
6
  Keywords: p2p,video,censorship-resistant,discovery,dht,kademlia,nat-traversal
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "weed-cli"
7
- version = "1.8.0"
7
+ version = "1.8.2"
8
8
  description = "Censorship-resistant video PoC — discovery/hosting/download over signed relay events, a real Kademlia DHT, or a TLS-capable NAT-traversal tunnel"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -0,0 +1,128 @@
1
+ """
2
+ dht.py's real Kademlia swarm -- multiple real dht.DHTNode instances (each
3
+ its own thread + its own asyncio event loop, see DHTNode's own docstring)
4
+ in one process. Unlike discovery_relay.py, kademlia.network.Server carries
5
+ no module-level global state shared across instances, so running several
6
+ in-process (rather than as separate subprocesses, the way
7
+ tests/conftest.py's `relay` fixture has to for discovery_relay.py) is
8
+ correct here, not a test-isolation shortcut -- kademlia's own test suite
9
+ does the same thing for the same reason.
10
+ """
11
+ import pytest
12
+
13
+ import dht
14
+ from testutil import free_port
15
+
16
+
17
+ def make_node(bootstrap_port=None):
18
+ port = free_port()
19
+ bootstrap = [('127.0.0.1', bootstrap_port)] if bootstrap_port else None
20
+ node = dht.DHTNode(port, bootstrap_nodes=bootstrap, quiet=True)
21
+ node.start()
22
+ return node, port
23
+
24
+
25
+ @pytest.fixture()
26
+ def swarm():
27
+ """Yields a list callers append (node, port) pairs to; stops every
28
+ node on teardown regardless of how many the test actually created."""
29
+ nodes = []
30
+ yield nodes
31
+ for node, _ in nodes:
32
+ node.stop()
33
+
34
+
35
+ def test_solo_node_with_no_neighbors_cannot_store_or_retrieve_anything(swarm):
36
+ """Not a trivial "empty DHT" check -- a real, easy-to-miss operational
37
+ gotcha discovered while writing these tests: kademlia's get/set work
38
+ by routing to the nearest *known* nodes, and a node with zero known
39
+ neighbors (the very first node in a swarm, before anyone else has
40
+ bootstrapped to or from it) has nowhere to route to. It doesn't raise
41
+ -- it logs a warning and silently no-ops, so announce()/lookup() both
42
+ just look like "nothing here" instead of "not connected to anything
43
+ yet." A genuinely-empty lookup in a *working* multi-node swarm is
44
+ covered separately below (test_lookup_for_unknown_hash_on_a_real_swarm)."""
45
+ a, _ = make_node()
46
+ swarm.append((a, _))
47
+ a.announce('c' * 64, '127.0.0.1:9201')
48
+ assert a.lookup('c' * 64) == []
49
+
50
+
51
+ def test_two_nodes_announce_and_lookup(swarm):
52
+ """The actual round trip: B joins A's swarm, B announces, A looks it
53
+ up -- A and B never talk except for B's one bootstrap connection, so
54
+ finding it on A proves the DHT's own get/set is doing the work, not
55
+ some direct A<->B shortcut."""
56
+ a, a_port = make_node()
57
+ swarm.append((a, a_port))
58
+ b, b_port = make_node(bootstrap_port=a_port)
59
+ swarm.append((b, b_port))
60
+
61
+ b.announce('c' * 64, '127.0.0.1:9201', title='My Video')
62
+
63
+ results = a.lookup('c' * 64)
64
+ assert results == [{'host': '127.0.0.1:9201', 'title': 'My Video'}]
65
+
66
+
67
+ def test_lookup_for_unknown_hash_on_a_real_swarm_is_empty(swarm):
68
+ a, a_port = make_node()
69
+ swarm.append((a, a_port))
70
+ b, b_port = make_node(bootstrap_port=a_port)
71
+ swarm.append((b, b_port))
72
+
73
+ b.announce('c' * 64, '127.0.0.1:9201')
74
+ assert a.lookup('d' * 64) == []
75
+
76
+
77
+ def test_two_hosts_for_same_content_hash_merge_not_overwrite(swarm):
78
+ """_announce's own contract (see its docstring): a second host
79
+ announcing the same content_hash must show up *alongside* the first,
80
+ not replace it -- multiple peers hosting the same file is real,
81
+ useful redundancy, not a conflict to resolve."""
82
+ a, a_port = make_node()
83
+ swarm.append((a, a_port))
84
+ b, b_port = make_node(bootstrap_port=a_port)
85
+ swarm.append((b, b_port))
86
+
87
+ a.announce('c' * 64, '127.0.0.1:9201', title='v')
88
+ b.announce('c' * 64, '127.0.0.1:9202', title='v')
89
+
90
+ hosts = {e['host'] for e in a.lookup('c' * 64)}
91
+ assert hosts == {'127.0.0.1:9201', '127.0.0.1:9202'}
92
+
93
+
94
+ def test_reannouncing_same_host_replaces_its_own_entry_not_duplicates(swarm):
95
+ """A completely solo node (zero known neighbors -- nobody's ever
96
+ bootstrapped to or from it) can't even get/set against itself:
97
+ kademlia's own set/get work by routing to the nearest known nodes, and
98
+ with none known there's nowhere to route to (it logs a warning and
99
+ silently no-ops, discovered the hard way -- an earlier version of
100
+ this test tried exactly that and got [] back instead of real data).
101
+ Two nodes is the minimum for get/set to actually do anything."""
102
+ a, a_port = make_node()
103
+ swarm.append((a, a_port))
104
+ b, b_port = make_node(bootstrap_port=a_port)
105
+ swarm.append((b, b_port))
106
+
107
+ a.announce('c' * 64, '127.0.0.1:9201', title='v1')
108
+ a.announce('c' * 64, '127.0.0.1:9201', title='v2')
109
+
110
+ results = b.lookup('c' * 64)
111
+ assert results == [{'host': '127.0.0.1:9201', 'title': 'v2'}]
112
+
113
+
114
+ def test_three_node_chain_propagates_through_indirect_bootstrap(swarm):
115
+ """C bootstraps through B, never touches A directly -- if C can still
116
+ look up something A announced, that's Kademlia's own routing doing
117
+ real work, not just a two-node special case."""
118
+ a, a_port = make_node()
119
+ swarm.append((a, a_port))
120
+ b, b_port = make_node(bootstrap_port=a_port)
121
+ swarm.append((b, b_port))
122
+ c, c_port = make_node(bootstrap_port=b_port)
123
+ swarm.append((c, c_port))
124
+
125
+ a.announce('c' * 64, '127.0.0.1:9201', title='from A')
126
+
127
+ results = c.lookup('c' * 64)
128
+ assert results == [{'host': '127.0.0.1:9201', 'title': 'from A'}]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weed-cli
3
- Version: 1.8.0
3
+ Version: 1.8.2
4
4
  Summary: Censorship-resistant video PoC — discovery/hosting/download over signed relay events, a real Kademlia DHT, or a TLS-capable NAT-traversal tunnel
5
5
  License: MIT
6
6
  Keywords: p2p,video,censorship-resistant,discovery,dht,kademlia,nat-traversal
@@ -10,6 +10,7 @@ shell.py
10
10
  tunnel_relay.py
11
11
  web_ui.py
12
12
  weed.py
13
+ tests/test_dht.py
13
14
  tests/test_discovery_relay.py
14
15
  tests/test_node_manifest.py
15
16
  tests/test_web_ui_api.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes