Przeglądaj źródła

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 lat temu
rodzic
commit
825c353046
No account linked to committer's email address
2 zmienionych plików z 188 dodań i 71 usunięć
  1. 1
    0
      near-client/Cargo.toml
  2. 187
    71
      near-client/tests/rpc.rs

+ 1
- 0
near-client/Cargo.toml Wyświetl plik

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

+ 187
- 71
near-client/tests/rpc.rs Wyświetl plik

1
+use git2::{Cred, RemoteCallbacks};
1
 use itertools::Itertools;
2
 use itertools::Itertools;
2
 use near_account_id::AccountId;
3
 use near_account_id::AccountId;
3
 use near_client::{
4
 use near_client::{
9
 use reqwest::Url;
10
 use reqwest::Url;
10
 use serde_json::json;
11
 use serde_json::json;
11
 use std::{
12
 use std::{
12
-    fs::{create_dir, File},
13
-    io::{copy, Cursor, Read},
13
+    fs::{create_dir, read, write},
14
     path::Path,
14
     path::Path,
15
     str::FromStr,
15
     str::FromStr,
16
 };
16
 };
17
 use workspaces::{network::Sandbox, types::SecretKey, Worker};
17
 use workspaces::{network::Sandbox, types::SecretKey, Worker};
18
 
18
 
19
 // auxiliary structs and methods
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
     let secret_key = ED25519SecretKey::from_bytes(&random_bits())?;
31
     let secret_key = ED25519SecretKey::from_bytes(&random_bits())?;
46
     let ws_secret_key_str = to_workspaces_sk(&secret_key);
32
     let ws_secret_key_str = to_workspaces_sk(&secret_key);
47
     let pk = ED25519PublicKey::from(&secret_key);
33
     let pk = ED25519PublicKey::from(&secret_key);
48
     let ws_sk = SecretKey::from_str(&ws_secret_key_str)?;
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
     Ok(signer_acc)
41
     Ok(signer_acc)
67
 }
42
 }
72
     let fname = "contract.wasm";
47
     let fname = "contract.wasm";
73
     let full_dest = format!("{}/{}", target_path, fname);
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
 fn random_bits() -> [u8; 32] {
101
 fn random_bits() -> [u8; 32] {
111
 // tests themselves
119
 // tests themselves
112
 #[tokio::test]
120
 #[tokio::test]
113
 async fn contract_creation() -> anyhow::Result<()> {
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
     Ok(())
133
     Ok(())
124
 }
134
 }
125
 
135
 
126
 #[tokio::test]
136
 #[tokio::test]
127
 async fn contract_function_call() -> anyhow::Result<()> {
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
         .args(json!({
151
         .args(json!({
140
-            "owner_id": &meta.signer_account_id,
152
+            "owner_id": &signer_account_id,
141
             "total_supply": "100",
153
             "total_supply": "100",
142
         }))
154
         }))
143
         .gas(near_units::parse_gas!("300 T") as u64)
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
     Ok(())
263
     Ok(())
148
 }
264
 }

Ładowanie…
Anuluj
Zapisz