1 | const IPFS = require('ipfs');
|
2 |
|
3 | const canonicaljson = require('@stratumn/canonicaljson');
|
4 | var ipfs;
|
5 | const unixFs = require('ipfs-unixfs');
|
6 | const multihashes = require('multihashes');
|
7 | let tryexpectedfailures = true; // Set to false if want to check the things we expect to fail.
|
8 | const ipfsAPI = require('ipfs-http-client')
|
9 | // connect to ipfs daemon API server
|
10 |
|
11 | const usehttpapi=false; // True uses local ipfs instance on machine where doing test, otherwise uses Javascript library
|
12 |
|
13 | let defaultipfsoptions = {
|
14 | repo: '/tmp/ipfs_testipfsv7', //TODO-IPFS think through where, esp for browser
|
15 | //init: true,
|
16 | //start: false,
|
17 | config: {
|
18 | Addresses: { Swarm: [ '/dns4/ws-star.discovery.libp2p.io/tcp/443/wss/p2p-websocket-star']},
|
19 | //Bootstrap: ['/dns4/dweb.me/tcp/443/wss/ipfs/QmPNgKEjC7wkpu3aHUzKKhZmbEfiGzL5TP1L8zZoHJyXZW'],
|
20 | //Bootstrap: ['/dns4/dweb.me/tcp/443/ws/ipfs/QmPNgKEjC7wkpu3aHUzKKhZmbEfiGzL5TP1L8zZoHJyXZW'],
|
21 | },
|
22 | EXPERIMENTAL: {
|
23 | pubsub: true
|
24 | }
|
25 | };
|
26 |
|
27 | // Converstion routines - IPFS's API is odd, some functions want a multihash (e.g. "Q..." or "z...") some wanta path e.g. "/ipfs/Q..." and soem want a CID data structure
|
28 | function ipfsFrom(url) {
|
29 | /*
|
30 | Convert to a ipfspath i.e. /ipfs/Qm....
|
31 | Required because of strange differences in APIs between files.cat and dag.get see https://github.com/ipfs/js-ipfs/issues/1229
|
32 | */
|
33 | if (url instanceof ipfs.CID)
|
34 | return "/ipfs/"+url.toBaseEncodedString();
|
35 | if (typeof(url) !== "string") { // It better be URL which unfortunately is hard to test
|
36 | url = url.path;
|
37 | }
|
38 | if (url.indexOf('/ipfs/')) {
|
39 | return url.slice(url.indexOf('/ipfs/'));
|
40 | }
|
41 | throw new errors.CodingError(`ipfsFrom: Cant convert url ${url} into a path starting /ipfs/`);
|
42 | }
|
43 | function multihashFrom(url) {
|
44 | if (url instanceof ipfs.CID)
|
45 | return url.toBaseEncodedString();
|
46 | if (typeof url === 'object' && url.path)
|
47 | url = url.path; // /ipfs/Q...
|
48 | if (typeof(url) === "string") {
|
49 | const idx = url.indexOf("/ipfs/");
|
50 | if (idx > -1) {
|
51 | return url.slice(idx+6);
|
52 | }
|
53 | }
|
54 | throw new errors.CodingError(`Cant turn ${url} into a multihash`);
|
55 | }
|
56 |
|
57 | function p_ipfsstart() {
|
58 | return new Promise((resolve, reject) => {
|
59 | if (!usehttpapi) {
|
60 | ipfs = new IPFS(defaultipfsoptions);
|
61 |
|
62 | ipfs.on('ready', () => {
|
63 | resolve();
|
64 | });
|
65 | ipfs.on('error', (err) => reject(err));
|
66 | } else {
|
67 | ipfs = ipfsAPI('localhost', '5001', {protocol: 'http'}) // leaving out the arguments will default to these values
|
68 | resolve();
|
69 | }
|
70 | })
|
71 | .then(() => ipfs.version())
|
72 | .then((version) => console.log('IPFS READY', version))
|
73 | .catch((err) => {
|
74 | console.log("Error caught in p_ipfsstart", err);
|
75 | throw(err);
|
76 | })
|
77 | }
|
78 |
|
79 | function check_result(name, buff, expected, expectfailure) {
|
80 | if ( (typeof(expected) === "number") && (expected !== buff.length)) {
|
81 | console.log(name, "Expected block length", expected, "but got", buff.length, expectfailure ? "Note this was expected to fail." : "");
|
82 | //console.log(buff); // Normally leave commented out - will be long if looking at 250k file !
|
83 | } else if ((typeof(expected) !== "number") && (canonicaljson.stringify(expected) !== canonicaljson.stringify(buff))) {
|
84 | console.log(name, "Expected:", expected.constructor.name, expected, "got", buff.constructor.name, buff, expectfailure ? "Note this was expected to fail." : "");
|
85 | } else {
|
86 | console.log(name, "Retrieved successfully");
|
87 | }
|
88 | return buff; // Simplify promise chain
|
89 | }
|
90 |
|
91 | async function test_files_cat(cid, expected, expectfailure) {
|
92 | try {
|
93 | if (expectfailure && !tryexpectedfailures) return;
|
94 | console.log("testing via files.cat")
|
95 | cid = ipfsFrom(cid); // Turn it into the /ipfs/Q... form that files.cat now expects
|
96 | buff = await ipfs.files.cat(cid); //Error: Groups are not supported in the blocks case - never returns from this call.
|
97 | check_result("files.cat", buff, expected, expectfailure);
|
98 | } catch(err) {
|
99 | console.log("Error thrown in files.cat", err);
|
100 | }
|
101 | }
|
102 |
|
103 | async function test_bylinks(cid, expected, expectfailure) {
|
104 | //TODO still working on this
|
105 | try {
|
106 | if (expectfailure && !tryexpectedfailures) return;
|
107 | console.log("testing via object.links and data")
|
108 | const links = await ipfs.object.links(multihashFrom(cid))
|
109 | console.log(`Retrieved ${links.length} links`);
|
110 | chunks = []
|
111 | for (let l in links) {
|
112 | const link = links[l];
|
113 | const lmh = link.multihash;
|
114 | console.log("Link",l,"multihash=",multihashes.toB58String(lmh), lmh)
|
115 | const d = await ipfs.object.data(lmh);
|
116 | console.log(`Read ${d.length} bytes`);
|
117 | const data = unixFs.unmarshal(d).data;
|
118 | console.log(`Unmarshaled ${data.length} bytes`)
|
119 | chunks.push(data);
|
120 | }
|
121 | const buff = Buffer.concat(chunks);
|
122 | check_result("bylinks", buff, expected, expectfailure)
|
123 | } catch (err) {
|
124 | console.log("Error thrown in test_bylinks", err);
|
125 | }
|
126 | }
|
127 |
|
128 | /* Each of this set of routines uploads with one method, and tries retrieving with multiple */
|
129 |
|
130 | async function test_long_file(note, multihash, len) {
|
131 | console.log(`--------Testing ${note} ${multihash}`);
|
132 | // Note this hash is fetchable via https://ipfs.io/ipfs/Qmbzs7jhkBZuVixhnM3J3QhMrL6bcAoSYiRPZrdoX3DhzB
|
133 | let cid = new CID(multihash);
|
134 | // Uncomment one or both of these tests
|
135 | await test_files_cat(cid, len,false); // Works in node and in Chrome
|
136 | //await test_bylinks(cid, len, false);
|
137 | }
|
138 | async function test_ipfs() {
|
139 | await p_ipfsstart(true);
|
140 |
|
141 | //Working 9May using files.cat and Addresses libp2p.io
|
142 | await test_long_file('PDF sent to http api a long time ago', "Qmbzs7jhkBZuVixhnM3J3QhMrL6bcAoSYiRPZrdoX3DhzB", 262438);
|
143 |
|
144 | //Fails 9May using files.cat and Addresses libp2p.io - doesnt succeed at files.cat,
|
145 | //On TransportIPFS test of same file, the first dag.get times out.
|
146 | //Note prior to these tests, this file was successfully retrieved from https://ipfs.io/ipfs/zdj7WkPCyjRgfCAMosMxCx8UhtW6rZvPNRsxCzg3mrxTLRVBr
|
147 | await test_long_file('Using curl urlstore add', 'zdj7WkPCyjRgfCAMosMxCx8UhtW6rZvPNRsxCzg3mrxTLRVBr', 321761); //Same video as above but via urlstore
|
148 |
|
149 | //await test_long_file('Commute 11Mb video sent a few months ago almost certainly via urlstore', 'zdj7Wc9BBA2kar84oo8S6VotYc9PySAnmc8ji6kzKAFjqMxHS', 11919082);
|
150 | //await test_long_file('500Mb file sent few days ago via urlstore', 'zdj7WfaG5e1PWoqxWUyUyS2nTe4pgNQZ4tRnrfd5uoxrXAANA', 521998952);
|
151 | //await test_long_file('Smaller 22Mb video sent 2018-03-13', 'zdj7WaHjDtE2e7g614UfXNwyrBwRUd6JkujRsLc9M2ufozLct', 22207578);
|
152 | //await test_long_file('Using ipfs add on dweb server 2018-05-09', 'QmYuULjZVhkj6NDFRzbJncVx4DGVcwiyofgmgADBfcVozs', 0);
|
153 | //await test_long_file('Not sure how this one was added its a video', 'QmRfcgjWEWdzKBnnSYwmV7Kt5wVVuWZvLm96o4dj7myWuy', 321761);
|
154 |
|
155 | //await test_long_file('Using a hash from the DHT Provide logs', 'zb2rhmFWNJ7TVEKQF6UEjnPbw4ESoq8CwbVTPHwQbacnoRd9M', 321761); // files.cat says invalid node type, object.links returns undefined
|
156 | //await test_long_file('Using ipfs add on standard deployment on my mac', 'QmUktxW4tz3dvDymDQ3ZRdMBFeCF8CKU3gb5GWJrbGaF4V', 321761); // Same file as above as of 27Mar doesnt respond on links?
|
157 | //await test_long_file('Using a hash from the DHT Provide logs', 'zdj7WXHDDkXthYNLKNQg2DZkBD8vmAQ2K37dURNRwAAM1iMSQ', 321761); // files.cat says invalid node type, object.links returns undefined
|
158 | //await test_long_file('Using a hash from add.csv using http add', 'QmfWQzucB7QWq32meSSKk8xLEtouAEWnWs7RatbxJz9wkj', 13980); // files.cat says invalid node type, object.links returns undefined
|
159 | //await test_long_file('Using a hash from add.csv using http urlstore', 'zb2rhXDUQRraHn3tQcq8MHVMVSVP9RwRyEMzyBhehssVjnPWb', 9613); // files.cat says invalid node type, object.links returns undefined
|
160 | console.log('---- finished --- ')
|
161 | }
|
162 |
|
163 | test_ipfs();
|