소스 검색

Merge pull request #52 from Relayz-io/kyrylo/tests-for-rpc-interface

A further step on improvements of tests for the RPC

near-smartcontracts's PR:
Relayz-io/near-smartcontracts#7
develop
Kyrylo Stepanov 2 년 전
부모
커밋
825c353046
No account linked to committer's email address
2개의 변경된 파일188개의 추가작업 그리고 71개의 파일을 삭제
  1. 1
    0
      near-client/Cargo.toml
  2. 187
    71
      near-client/tests/rpc.rs

+ 1
- 0
near-client/Cargo.toml 파일 보기

@@ -26,6 +26,7 @@ url = "2"
26 26
 
27 27
 [dev-dependencies]
28 28
 anyhow = "1"
29
+git2 = "0.15.0"
29 30
 reqwest = { version = "0.11", features = ["json"] }
30 31
 rand = "0.8.5"
31 32
 rand_chacha = "0.3"

+ 187
- 71
near-client/tests/rpc.rs 파일 보기

@@ -1,3 +1,4 @@
1
+use git2::{Cred, RemoteCallbacks};
1 2
 use itertools::Itertools;
2 3
 use near_account_id::AccountId;
3 4
 use near_client::{
@@ -9,59 +10,33 @@ use rand_chacha::ChaChaRng;
9 10
 use reqwest::Url;
10 11
 use serde_json::json;
11 12
 use std::{
12
-    fs::{create_dir, File},
13
-    io::{copy, Cursor, Read},
13
+    fs::{create_dir, read, write},
14 14
     path::Path,
15 15
     str::FromStr,
16 16
 };
17 17
 use workspaces::{network::Sandbox, types::SecretKey, Worker};
18 18
 
19 19
 // auxiliary structs and methods
20
-struct InitMeta {
21
-    worker: Worker<Sandbox>,
22
-    client: NearClient,
23
-    wasm: Vec<u8>,
24
-    signer_account_id: AccountId,
25
-}
26
-
27
-impl InitMeta {
28
-    async fn new() -> anyhow::Result<Self> {
29
-        let worker = workspaces::sandbox().await?;
30
-        let wasm = download_contract().await?;
31
-        let rpc_url = Url::parse(format!("http://localhost:{}", worker.rpc_port()).as_str())?;
32
-        let client = NearClient::new(rpc_url)?;
33
-        let signer_account_id = AccountId::from_str("alice.test.near")?;
34
-
35
-        Ok(InitMeta {
36
-            worker,
37
-            client,
38
-            wasm,
39
-            signer_account_id,
40
-        })
41
-    }
20
+fn near_client(worker: &Worker<Sandbox>) -> anyhow::Result<NearClient> {
21
+    let rpc_url = Url::parse(format!("http://localhost:{}", worker.rpc_port()).as_str())?;
22
+    let client = NearClient::new(rpc_url)?;
23
+    Ok(client)
42 24
 }
43 25
 
44
-async fn create_signer(meta: &InitMeta) -> anyhow::Result<Signer> {
26
+async fn create_signer(
27
+    worker: &Worker<Sandbox>,
28
+    client: &NearClient,
29
+    signer_acc_id: &AccountId,
30
+) -> anyhow::Result<Signer> {
45 31
     let secret_key = ED25519SecretKey::from_bytes(&random_bits())?;
46 32
     let ws_secret_key_str = to_workspaces_sk(&secret_key);
47 33
     let pk = ED25519PublicKey::from(&secret_key);
48 34
     let ws_sk = SecretKey::from_str(&ws_secret_key_str)?;
49
-    let _ = meta
50
-        .worker
51
-        .create_tla(meta.signer_account_id.clone(), ws_sk)
52
-        .await?;
35
+    let _ = worker.create_tla(signer_acc_id.clone(), ws_sk).await?;
53 36
 
54
-    let access_key_nonce = meta
55
-        .client
56
-        .view_access_key(&meta.signer_account_id, &pk)
57
-        .await?
58
-        .nonce;
37
+    let access_key_nonce = client.view_access_key(signer_acc_id, &pk).await?.nonce;
59 38
 
60
-    let signer_acc = Signer::new(
61
-        &ws_secret_key_str,
62
-        meta.signer_account_id.clone(),
63
-        access_key_nonce,
64
-    )?;
39
+    let signer_acc = Signer::new(&ws_secret_key_str, signer_acc_id.clone(), access_key_nonce)?;
65 40
 
66 41
     Ok(signer_acc)
67 42
 }
@@ -72,22 +47,55 @@ async fn download_contract() -> anyhow::Result<Vec<u8>> {
72 47
     let fname = "contract.wasm";
73 48
     let full_dest = format!("{}/{}", target_path, fname);
74 49
 
75
-    if !Path::new(target_path).exists() {
76
-        create_dir(target_path)?;
77
-    }
50
+    let contract_bytes = if !Path::new(&full_dest).exists() {
51
+        if !Path::new(&target_path).exists() {
52
+            create_dir(target_path)?;
53
+        };
78 54
 
79
-    if !Path::new(&full_dest).exists() {
80
-        let response = reqwest::get(target).await?;
81
-        let mut file = File::create(&full_dest)?;
82
-        let mut content = Cursor::new(response.bytes().await?);
83
-        copy(&mut content, &mut file)?;
84
-    }
55
+        let contract_bytes = reqwest::get(target).await?.bytes().await?;
56
+        write(full_dest, &contract_bytes)?;
57
+        contract_bytes.to_vec()
58
+    } else {
59
+        read(&full_dest)?
60
+    };
61
+
62
+    Ok(contract_bytes)
63
+}
64
+
65
+async fn clone_and_compile_wasm() -> anyhow::Result<Vec<u8>> {
66
+    let tmp_path = "../target/tmp-contracts";
67
+    let repo_path = format!("{}/near-smartcontracts", tmp_path);
68
+    let target_path = format!("{}/test-contract", repo_path);
69
+    let repo_url = "git@github.com:Relayz-io/near-smartcontracts.git";
70
+
71
+    if !Path::new(&target_path).exists() {
72
+        if !Path::new(&tmp_path).exists() {
73
+            create_dir(tmp_path)?;
74
+        }
75
+
76
+        // Prepare callbacks.
77
+        let mut callbacks = RemoteCallbacks::new();
78
+        callbacks.credentials(|_, username_from_url, _| {
79
+            let username = username_from_url
80
+                .ok_or_else(|| git2::Error::from_str("Parsing the given URL is failed"))?;
81
+            Cred::ssh_key_from_agent(username)
82
+        });
85 83
 
86
-    let mut file = File::open(full_dest)?;
87
-    let mut data = Vec::new();
88
-    file.read_to_end(&mut data)?;
84
+        // Prepare fetch options.
85
+        let mut fo = git2::FetchOptions::new();
86
+        fo.remote_callbacks(callbacks);
89 87
 
90
-    Ok(data)
88
+        // Prepare builder.
89
+        let mut builder = git2::build::RepoBuilder::new();
90
+        builder.fetch_options(fo);
91
+        builder.branch("main");
92
+
93
+        // Clone the project.
94
+        builder.clone(repo_url, Path::new(&repo_path))?;
95
+    }
96
+    let wasm = workspaces::compile_project(&target_path).await?;
97
+
98
+    Ok(wasm)
91 99
 }
92 100
 
93 101
 fn random_bits() -> [u8; 32] {
@@ -111,38 +119,146 @@ fn to_workspaces_sk(sk: &ED25519SecretKey) -> String {
111 119
 // tests themselves
112 120
 #[tokio::test]
113 121
 async fn contract_creation() -> anyhow::Result<()> {
114
-    let meta = InitMeta::new().await?;
115
-    let mut signer = create_signer(&meta).await?;
116
-
117
-    let call = meta
118
-        .client
119
-        .deploy_contract(&mut signer, &meta.signer_account_id, meta.wasm);
122
+    let worker = workspaces::sandbox().await?;
123
+    let client = near_client(&worker)?;
124
+    let signer_account_id = AccountId::from_str("alice.test.near").unwrap();
125
+    let mut signer = create_signer(&worker, &client, &signer_account_id).await?;
126
+    let wasm = download_contract().await?;
120 127
 
121
-    call.commit_empty().await?;
128
+    client
129
+        .deploy_contract(&mut signer, &signer_account_id, wasm)
130
+        .commit_empty()
131
+        .await?;
122 132
 
123 133
     Ok(())
124 134
 }
125 135
 
126 136
 #[tokio::test]
127 137
 async fn contract_function_call() -> anyhow::Result<()> {
128
-    let meta = InitMeta::new().await?;
129
-    let mut signer = create_signer(&meta).await?;
138
+    let worker = workspaces::sandbox().await?;
139
+    let client = near_client(&worker)?;
140
+    let signer_account_id = AccountId::from_str("alice.test.near").unwrap();
141
+    let mut signer = create_signer(&worker, &client, &signer_account_id).await?;
142
+    let wasm = download_contract().await?;
130 143
 
131
-    let call = meta
132
-        .client
133
-        .deploy_contract(&mut signer, &meta.signer_account_id, meta.wasm);
134
-    call.commit_empty().await?;
144
+    client
145
+        .deploy_contract(&mut signer, &signer_account_id, wasm)
146
+        .commit_empty()
147
+        .await?;
135 148
 
136
-    let call = meta
137
-        .client
138
-        .function_call(&mut signer, &meta.signer_account_id, "new_default_meta")
149
+    client
150
+        .function_call(&mut signer, &signer_account_id, "new_default_meta")
139 151
         .args(json!({
140
-            "owner_id": &meta.signer_account_id,
152
+            "owner_id": &signer_account_id,
141 153
             "total_supply": "100",
142 154
         }))
143 155
         .gas(near_units::parse_gas!("300 T") as u64)
144
-        .build()?;
145
-    call.commit_empty().await?;
156
+        .build()?
157
+        .commit_empty()
158
+        .await?;
159
+
160
+    Ok(())
161
+}
162
+
163
+#[tokio::test]
164
+async fn multiple_tests() -> anyhow::Result<()> {
165
+    let worker = workspaces::sandbox().await?;
166
+    let client = near_client(&worker)?;
167
+    let signer_account_id = AccountId::from_str("alice.test.near").unwrap();
168
+    let mut signer = create_signer(&worker, &client, &signer_account_id).await?;
169
+
170
+    let wasm = clone_and_compile_wasm().await?;
171
+
172
+    init_contract(&client, &signer_account_id, &mut signer, wasm).await?;
173
+
174
+    fc_no_params(&client, &signer_account_id, &mut signer).await?;
175
+    fc_with_one_param_and_result(&client, &signer_account_id, &mut signer).await?;
176
+    fc_with_param_and_result(&client, &signer_account_id, &mut signer).await?;
177
+
178
+    view_no_params(&client, &signer_account_id).await?;
179
+    view_with_params(&client, &signer_account_id).await?;
180
+
181
+    Ok(())
182
+}
183
+
184
+async fn init_contract(
185
+    client: &NearClient,
186
+    contract_id: &AccountId,
187
+    signer: &mut Signer,
188
+    wasm: Vec<u8>,
189
+) -> anyhow::Result<()> {
190
+    client
191
+        .deploy_contract(signer, contract_id, wasm)
192
+        .commit_empty()
193
+        .await?;
194
+
195
+    Ok(())
196
+}
197
+
198
+async fn view_no_params(client: &NearClient, contract_id: &AccountId) -> anyhow::Result<()> {
199
+    client.view::<u64>(contract_id, "show_id", None).await?;
200
+
201
+    Ok(())
202
+}
203
+
204
+async fn view_with_params(client: &NearClient, contract_id: &AccountId) -> anyhow::Result<()> {
205
+    client
206
+        .view::<String>(contract_id, "show_type", Some(json!({"is_message": true})))
207
+        .await?;
208
+
209
+    Ok(())
210
+}
211
+
212
+// fc = function call
213
+async fn fc_no_params(
214
+    client: &NearClient,
215
+    contract_id: &AccountId,
216
+    signer: &mut Signer,
217
+) -> anyhow::Result<()> {
218
+    client
219
+        .function_call(signer, contract_id, "increment")
220
+        .gas(near_units::parse_gas!("300 T") as u64)
221
+        .build()?
222
+        .commit_empty()
223
+        .await?;
224
+
225
+    Ok(())
226
+}
227
+
228
+async fn fc_with_one_param_and_result(
229
+    client: &NearClient,
230
+    contract_id: &AccountId,
231
+    signer: &mut Signer,
232
+) -> anyhow::Result<()> {
233
+    let expected_result = "change message";
234
+    let message = client
235
+        .function_call(signer, contract_id, "change_message")
236
+        .args(json!({ "message": expected_result }))
237
+        .gas(near_units::parse_gas!("300 T") as u64)
238
+        .build()?
239
+        .commit::<String>()
240
+        .await?;
241
+
242
+    assert_eq!(message, expected_result);
243
+
244
+    Ok(())
245
+}
246
+
247
+async fn fc_with_param_and_result(
248
+    client: &NearClient,
249
+    contract_id: &AccountId,
250
+    signer: &mut Signer,
251
+) -> anyhow::Result<()> {
252
+    let expected_id = 666u64;
253
+    let id = client
254
+        .function_call(signer, contract_id, "change_id")
255
+        .args(json!({ "id": expected_id }))
256
+        .gas(near_units::parse_gas!("300 T") as u64)
257
+        .build()?
258
+        .commit::<u64>()
259
+        .await?;
260
+
261
+    assert_eq!(id, expected_id);
146 262
 
147 263
     Ok(())
148 264
 }

Loading…
취소
저장