Skip to content
This repository was archived by the owner on Oct 23, 2022. It is now read-only.

Commit 90fa9a3

Browse files
bors[bot]ljedrz
andauthored
Merge #361
361: add go-ipfs DHT interop tests to the CI, enable jsipfs interop tests r=ljedrz a=ljedrz Initially this PR only added `go-ipfs` interop DHT tests to the Linux CI run. Even if that functionality was a tiny amount of code, I might have gotten lost in the moment and gone a bit too far with extending this PR to also introduce a `jsipfs` interop functionality 😅 - I can split it out if that's desirable. In any case, the individual commits describe specific changes; the diff seems big, but it's mostly moving stuff around, as almost all of the `go-ipfs` interop code is compatible with `jsipfs`. The `jsipfs` interop tests are not run in the CI yet. Co-authored-by: ljedrz <[email protected]>
2 parents 7c4e652 + ee7a70e commit 90fa9a3

File tree

6 files changed

+178
-121
lines changed

6 files changed

+178
-121
lines changed

.github/workflows/ci.yml

+11
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ jobs:
5050
CARGO_INCREMENTAL: 0
5151
LLVM_CONFIG_PATH: /usr/local/opt/llvm/bin/llvm-config
5252
NDK_HOME: /usr/local/lib/android/sdk/ndk-bundle
53+
GO_IPFS_PATH: /home/runner/work/rust-ipfs/rust-ipfs/go-ipfs/ipfs
5354
VCPKGRS_DYNAMIC: 1
5455
DEBUG: ipfsd-ctl:* # enables all debug output from javascript 'debug' lib used by js-ipfsd-ctl
5556

@@ -89,6 +90,12 @@ jobs:
8990
if: matrix.platform.host == 'macos-latest'
9091
run: brew install llvm openssl
9192

93+
- name: Download go-ipfs on Linux
94+
if: matrix.platform.host == 'ubuntu-latest'
95+
run: |
96+
curl -L https://github.com/ipfs/go-ipfs/releases/download/v0.6.0/go-ipfs_v0.6.0_linux-amd64.tar.gz --output go_ipfs.tar.gz
97+
tar -xf go_ipfs.tar.gz
98+
9299
- name: Install dependencies windows (openssl)
93100
uses: lukka/[email protected]
94101
id: windows-runvcpkg
@@ -113,6 +120,10 @@ jobs:
113120
if: matrix.platform.cross == false
114121
run: cargo build --locked --workspace --all-targets
115122

123+
- name: Run interop DHT tests with go-ipfs
124+
if: matrix.platform.host == 'ubuntu-latest'
125+
run: cargo test --features=test_go_interop dht
126+
116127
- name: Setup conformance tests (non-cross targets)
117128
if: matrix.platform.cross == false
118129
run: ./setup.sh

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ version = "0.1.0"
88
[features]
99
default = []
1010
nightly = []
11-
test_dht_with_go = []
11+
test_go_interop = []
12+
test_js_interop = []
1213

1314
[dependencies]
1415
anyhow = { default-features = false, version = "1.0" }

tests/common/interop.rs

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#[cfg(any(feature = "test_go_interop", feature = "test_js_interop"))]
2+
pub use common::ForeignNode;
3+
4+
#[cfg(all(not(feature = "test_go_interop"), not(feature = "test_js_interop")))]
5+
pub struct ForeignNode;
6+
7+
#[cfg(any(feature = "test_go_interop", feature = "test_js_interop"))]
8+
pub mod common {
9+
use anyhow;
10+
use libp2p::{core::PublicKey, Multiaddr, PeerId};
11+
use rand::prelude::*;
12+
use serde::Deserialize;
13+
use std::time::Duration;
14+
use std::{
15+
env, fs,
16+
path::PathBuf,
17+
process::{Child, Command, Stdio},
18+
thread,
19+
};
20+
21+
// this environment variable should point to the location of the foreign ipfs binary
22+
#[cfg(feature = "test_go_interop")]
23+
pub const ENV_IPFS_PATH: &str = "GO_IPFS_PATH";
24+
#[cfg(feature = "test_js_interop")]
25+
pub const ENV_IPFS_PATH: &str = "JS_IPFS_PATH";
26+
27+
pub struct ForeignNode {
28+
pub dir: PathBuf,
29+
pub daemon: Child,
30+
pub id: PeerId,
31+
pub pk: PublicKey,
32+
pub addrs: Vec<Multiaddr>,
33+
}
34+
35+
impl ForeignNode {
36+
pub fn new() -> ForeignNode {
37+
let binary_path = env::vars()
38+
.find(|(key, _val)| key == ENV_IPFS_PATH)
39+
.unwrap_or_else(|| {
40+
panic!("the {} environment variable was not found", ENV_IPFS_PATH)
41+
})
42+
.1;
43+
44+
let mut tmp_dir = env::temp_dir();
45+
let mut rng = rand::thread_rng();
46+
tmp_dir.push(&format!("ipfs_test_{}", rng.gen::<u64>()));
47+
let _ = fs::create_dir(&tmp_dir);
48+
49+
Command::new(&binary_path)
50+
.env("IPFS_PATH", &tmp_dir)
51+
.arg("init")
52+
.arg("-p")
53+
.arg("test")
54+
.arg("--bits")
55+
.arg("2048")
56+
.stdout(Stdio::null())
57+
.status()
58+
.unwrap();
59+
60+
let daemon = Command::new(&binary_path)
61+
.env("IPFS_PATH", &tmp_dir)
62+
.arg("daemon")
63+
.stdout(Stdio::null())
64+
.spawn()
65+
.unwrap();
66+
67+
// give the daemon a little bit of time to start
68+
thread::sleep(Duration::from_secs(1));
69+
70+
let node_id = Command::new(&binary_path)
71+
.env("IPFS_PATH", &tmp_dir)
72+
.arg("id")
73+
.output()
74+
.unwrap()
75+
.stdout;
76+
77+
let node_id_stdout = String::from_utf8_lossy(&node_id);
78+
let ForeignNodeId {
79+
id,
80+
addresses,
81+
public_key,
82+
..
83+
} = serde_json::de::from_str(&node_id_stdout).unwrap();
84+
85+
let id = id.parse().unwrap();
86+
let pk = PublicKey::from_protobuf_encoding(
87+
&base64::decode(public_key.into_bytes()).unwrap(),
88+
)
89+
.unwrap();
90+
91+
ForeignNode {
92+
dir: tmp_dir,
93+
daemon,
94+
id,
95+
pk,
96+
addrs: addresses,
97+
}
98+
}
99+
100+
#[allow(dead_code)]
101+
pub async fn identity(&self) -> Result<(PublicKey, Vec<Multiaddr>), anyhow::Error> {
102+
Ok((self.pk.clone(), self.addrs.clone()))
103+
}
104+
}
105+
106+
impl Drop for ForeignNode {
107+
fn drop(&mut self) {
108+
let _ = self.daemon.kill();
109+
let _ = fs::remove_dir_all(&self.dir);
110+
}
111+
}
112+
113+
#[derive(Deserialize, Debug)]
114+
#[cfg_attr(feature = "test_go_interop", serde(rename_all = "PascalCase"))]
115+
#[cfg_attr(feature = "test_js_interop", serde(rename_all = "camelCase"))]
116+
pub struct ForeignNodeId {
117+
#[cfg_attr(feature = "test_go_interop", serde(rename = "ID"))]
118+
pub id: String,
119+
pub public_key: String,
120+
pub addresses: Vec<Multiaddr>,
121+
#[serde(skip)]
122+
agent_version: String,
123+
#[serde(skip)]
124+
protocol_version: String,
125+
}
126+
}

tests/common/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod interop;

tests/connect_two.rs

+9
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,20 @@ use libp2p::{multiaddr::Protocol, Multiaddr};
33
use std::time::Duration;
44
use tokio::time::timeout;
55

6+
#[cfg(any(feature = "test_go_interop", feature = "test_js_interop"))]
7+
mod common;
8+
#[cfg(any(feature = "test_go_interop", feature = "test_js_interop"))]
9+
use common::interop::ForeignNode;
10+
611
// Make sure two instances of ipfs can be connected by `Multiaddr`.
712
#[tokio::test(max_threads = 1)]
813
async fn connect_two_nodes_by_addr() {
914
let node_a = Node::new("a").await;
15+
16+
#[cfg(all(not(feature = "test_go_interop"), not(feature = "test_js_interop")))]
1017
let node_b = Node::new("b").await;
18+
#[cfg(any(feature = "test_go_interop", feature = "test_js_interop"))]
19+
let node_b = ForeignNode::new();
1120

1221
let (_, mut b_addrs) = node_b.identity().await.unwrap();
1322
let b_addr = b_addrs.pop().unwrap();

0 commit comments

Comments
 (0)