mirror of
https://github.com/logos-storage/logos-storage-nim.git
synced 2026-01-14 19:33:10 +00:00
adds integration tests for using magnet links and torrent file while retrieving BitTorrent content from Codex Net
This commit is contained in:
parent
f9ce8892a7
commit
29bb01751b
@ -94,6 +94,16 @@ proc info*(
|
||||
let response = await client.get(client.baseurl & "/debug/info")
|
||||
return JsonNode.parse(await response.body)
|
||||
|
||||
proc connect*(
|
||||
client: CodexClient, peerId: string, address: string
|
||||
): Future[?!void] {.async: (raises: [CancelledError, HttpError]).} =
|
||||
let url = client.baseurl & "/connect/" & peerId & "?addrs=" & address
|
||||
let response = await client.get(url)
|
||||
if response.status != 200:
|
||||
return
|
||||
failure("Cannot connect to node with peerId: " & peerId & ": " & $response.status)
|
||||
return success()
|
||||
|
||||
proc setLogLevel*(
|
||||
client: CodexClient, level: string
|
||||
): Future[void] {.async: (raises: [CancelledError, HttpError]).} =
|
||||
@ -196,6 +206,43 @@ proc downloadTorrent*(
|
||||
|
||||
success await response.body
|
||||
|
||||
proc downloadTorrent*(
|
||||
client: CodexClient,
|
||||
contents: string,
|
||||
contentType = "text/plain",
|
||||
endpoint = "magnet",
|
||||
): Future[?!string] {.async: (raises: [CancelledError, HttpError]).} =
|
||||
if contents.len == 0:
|
||||
return failure("No content provided!")
|
||||
if endpoint != "magnet" and endpoint != "torrent-file":
|
||||
return failure(
|
||||
"Invalid endpoint: has to be either 'magnet' or 'torrent-file' but got: " &
|
||||
endpoint
|
||||
)
|
||||
if endpoint == "magnet" and
|
||||
(contentType != "application/octet-stream" and contentType != "text/plain"):
|
||||
return failure(
|
||||
"Invalid content type: for 'magnet' endpoint has to be either 'application/octet-stream' or 'text/plain' but got: " &
|
||||
contentType
|
||||
)
|
||||
if endpoint == "torrent-file" and
|
||||
(contentType != "application/octet-stream" and contentType != "application/json"):
|
||||
return failure(
|
||||
"Invalid content type: for 'torrent-file' endpoint has to be either 'application/octet-stream' or 'application/json' but got: " &
|
||||
contentType
|
||||
)
|
||||
|
||||
var headers = newSeq[HttpHeaderTuple]()
|
||||
headers = @[("Content-Type", contentType)]
|
||||
|
||||
let response = await client.post(
|
||||
client.baseurl & "/torrent/" & endpoint, body = contents, headers = headers
|
||||
)
|
||||
if not response.status == 200:
|
||||
return failure($response.status)
|
||||
|
||||
success await response.body
|
||||
|
||||
proc downloadManifestOnly*(
|
||||
client: CodexClient, cid: Cid
|
||||
): Future[?!string] {.async: (raises: [CancelledError, HttpError]).} =
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import std/net
|
||||
import std/strformat
|
||||
import std/sequtils
|
||||
import std/json except `%`, `%*`
|
||||
import pkg/nimcrypto
|
||||
from pkg/libp2p import `==`, `$`, MultiHash, init
|
||||
from pkg/libp2p import `==`, `$`, MultiHash, init, digest, hex
|
||||
import pkg/codex/units
|
||||
import pkg/codex/utils/iter
|
||||
import pkg/codex/manifest
|
||||
@ -10,7 +12,6 @@ import pkg/codex/bittorrent/manifest
|
||||
import ./twonodes
|
||||
import ../examples
|
||||
import ../codex/examples
|
||||
import json
|
||||
|
||||
proc createInfoDictionaryForContent(
|
||||
content: seq[byte], pieceLength = DefaultPieceLength.int, name = string.none
|
||||
@ -55,12 +56,93 @@ proc createInfoDictionaryForContent(
|
||||
success info
|
||||
|
||||
twonodessuite "BitTorrent API":
|
||||
setup:
|
||||
# why we do not seem to need this? yet it is twice as fast with this
|
||||
let infoPeer1 = (await client1.info()).tryGet
|
||||
let peerId1 = infoPeer1["id"].getStr()
|
||||
let announceAddress1 = infoPeer1["announceAddresses"][0].getStr()
|
||||
(await client2.connect(peerId1, announceAddress1)).tryGet
|
||||
|
||||
test "uploading and downloading the content", twoNodesConfig:
|
||||
let exampleContent = exampleString(100)
|
||||
let infoHash = (await client1.uploadTorrent(exampleContent)).tryGet
|
||||
let downloadedContent = (await client2.downloadTorrent(infoHash)).tryGet
|
||||
check downloadedContent == exampleContent
|
||||
|
||||
test "downloading content using magnet link", twoNodesConfig:
|
||||
let exampleContent = exampleString(100)
|
||||
let multiHash = (await client1.uploadTorrent(exampleContent)).tryGet
|
||||
let infoHash = byteutils.toHex(multiHash.data.buffer[multiHash.dpos .. ^1])
|
||||
let magnetLink = fmt"magnet:?xt=urn:btih:{infoHash}"
|
||||
let downloadedContent = (await client2.downloadTorrent(magnetLink)).tryGet
|
||||
check downloadedContent == exampleContent
|
||||
|
||||
test "downloading content using torrent file", twoNodesConfig:
|
||||
let exampleFileName = "example.txt"
|
||||
let exampleContent = exampleString(100)
|
||||
let multiHash = (
|
||||
await client1.uploadTorrent(
|
||||
contents = exampleContent,
|
||||
filename = some exampleFileName,
|
||||
contentType = "text/plain",
|
||||
)
|
||||
).tryGet
|
||||
|
||||
let expectedInfo = createInfoDictionaryForContent(
|
||||
content = exampleContent.toBytes, name = some exampleFileName
|
||||
).tryGet
|
||||
|
||||
let expectedInfoBencoded = expectedInfo.bencode()
|
||||
let expectedMultiHash =
|
||||
MultiHash.digest($Sha1HashCodec, expectedInfoBencoded).mapFailure.tryGet()
|
||||
|
||||
assert expectedMultiHash == multiHash
|
||||
|
||||
let torrentFileContent = "d4:info" & string.fromBytes(expectedInfoBencoded) & "e"
|
||||
|
||||
let downloadedContent = (
|
||||
await client2.downloadTorrent(
|
||||
contents = torrentFileContent,
|
||||
contentType = "application/octet-stream",
|
||||
endpoint = "torrent-file",
|
||||
)
|
||||
).tryGet
|
||||
check downloadedContent == exampleContent
|
||||
|
||||
test "downloading content using torrent file (JSON format)", twoNodesConfig:
|
||||
let exampleFileName = "example.txt"
|
||||
let exampleContent = exampleString(100)
|
||||
let multiHash = (
|
||||
await client1.uploadTorrent(
|
||||
contents = exampleContent,
|
||||
filename = some exampleFileName,
|
||||
contentType = "text/plain",
|
||||
)
|
||||
).tryGet
|
||||
|
||||
let expectedInfo = createInfoDictionaryForContent(
|
||||
content = exampleContent.toBytes, name = some exampleFileName
|
||||
).tryGet
|
||||
|
||||
let expectedInfoBencoded = expectedInfo.bencode()
|
||||
let expectedMultiHash =
|
||||
MultiHash.digest($Sha1HashCodec, expectedInfoBencoded).mapFailure.tryGet()
|
||||
|
||||
assert expectedMultiHash == multiHash
|
||||
|
||||
let infoJson = %*{"info": %expectedInfo}
|
||||
|
||||
let torrentJson = $infoJson
|
||||
|
||||
let downloadedContent = (
|
||||
await client2.downloadTorrent(
|
||||
contents = torrentJson,
|
||||
contentType = "application/json",
|
||||
endpoint = "torrent-file",
|
||||
)
|
||||
).tryGet
|
||||
check downloadedContent == exampleContent
|
||||
|
||||
test "uploading and downloading the content (exactly one piece long)", twoNodesConfig:
|
||||
let numOfBlocksPerPiece = int(DefaultPieceLength div BitTorrentBlockSize)
|
||||
let bytes = await RandomChunker.example(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user