UNPKG

8.03 kBJavaScriptView Raw
1const tape = require('tape')
2const hypercoreCrypto = require('hypercore-crypto')
3const Corestore = require('corestore')
4const ram = require('random-access-memory')
5const create = require('./helpers/create')
6const Replicator = require('./helpers/replicator')
7
8tape('close event', function (t) {
9 t.plan(1)
10
11 var drive = create()
12
13 drive.on('close', function () {
14 t.pass('close event')
15 t.end()
16 })
17
18 drive.ready(function () {
19 drive.close()
20 })
21})
22
23tape('write and read', function (t) {
24 var drive = create()
25
26 drive.writeFile('/hello.txt', 'world', function (err) {
27 t.error(err, 'no error')
28 drive.readFile('/hello.txt', function (err, buf) {
29 t.error(err, 'no error')
30 t.same(buf, Buffer.from('world'))
31 t.end()
32 })
33 })
34})
35
36tape('write and read, with encoding', function (t) {
37 var drive = create()
38
39 drive.writeFile('/hello.txt', 'world', { encoding: 'utf8' }, function (err) {
40 t.error(err, 'no error')
41 drive.readFile('/hello.txt', { encoding: 'utf8' }, function (err, str) {
42 t.error(err, 'no error')
43 t.same(str, 'world')
44 t.end()
45 })
46 })
47})
48
49tape('write and read (2 parallel)', function (t) {
50 t.plan(6)
51
52 var drive = create()
53
54 drive.writeFile('/hello.txt', 'world', function (err) {
55 t.error(err, 'no error')
56 drive.readFile('/hello.txt', function (err, buf) {
57 t.error(err, 'no error')
58 t.same(buf, Buffer.from('world'))
59 })
60 })
61
62 drive.writeFile('/world.txt', 'hello', function (err) {
63 t.error(err, 'no error')
64 drive.readFile('/world.txt', function (err, buf) {
65 t.error(err, 'no error')
66 t.same(buf, Buffer.from('hello'))
67 })
68 })
69})
70
71tape('write and read (sparse)', function (t) {
72 var drive = create()
73 drive.on('ready', function () {
74 var clone = create(drive.key)
75 var r = new Replicator(t)
76
77 r.replicate(clone, drive)
78
79 drive.writeFile('/hello.txt', 'world', function (err) {
80 t.error(err, 'no error')
81 var readStream = clone.createReadStream('/hello.txt')
82 readStream.on('data', function (data) {
83 t.same(data.toString(), 'world')
84 r.end()
85 })
86 })
87 })
88})
89
90tape('root is always there', function (t) {
91 var drive = create()
92
93 drive.access('/', function (err) {
94 t.error(err, 'no error')
95 drive.readdir('/', function (err, list) {
96 t.error(err, 'no error')
97 t.same(list, [])
98 t.end()
99 })
100 })
101})
102
103tape('provide keypair', function (t) {
104 const keyPair = hypercoreCrypto.keyPair()
105 var drive = create(keyPair.publicKey, { keyPair })
106
107 drive.on('ready', function () {
108 t.ok(drive.writable)
109 t.ok(drive.metadata.writable)
110 t.ok(keyPair.publicKey.equals(drive.key))
111
112 drive.writeFile('/hello.txt', 'world', function (err) {
113 t.error(err, 'no error')
114 drive.readFile('/hello.txt', function (err, buf) {
115 t.error(err, 'no error')
116 t.same(buf, Buffer.from('world'))
117 t.end()
118 })
119 })
120 })
121})
122
123tape.skip('can reopen when providing a keypair', function (t) {
124 const keyPair = hypercoreCrypto.keyPair()
125 const store = new Corestore(ram)
126 var drive = create(keyPair.publicKey, { keyPair, corestore: store })
127
128 drive.on('ready', function () {
129 t.ok(drive.writable)
130 t.ok(drive.metadata.writable)
131 t.ok(keyPair.publicKey.equals(drive.key))
132
133 drive.writeFile('/hello.txt', 'world', function (err) {
134 t.error(err, 'no error')
135 console.log('CORE LENGTH BEFORE CLOSE:', drive.metadata.length)
136 drive.close(err => {
137 t.error(err, 'no error')
138 drive = create(keyPair.publicKey, { keyPair, corestore: store })
139
140 drive.on('ready', function () {
141 console.log('CORE LENGTH:', drive.metadata.length)
142 t.ok(drive.writable)
143 t.ok(drive.metadata.writable)
144 t.ok(keyPair.publicKey.equals(drive.key))
145
146 drive.readFile('/hello.txt', function (err, buf) {
147 t.error(err, 'no error')
148 t.same(buf, Buffer.from('world'))
149 t.end()
150 })
151 })
152 })
153 })
154 })
155})
156
157tape('write and read, no cache', function (t) {
158 var drive = create({
159 metadataStorageCacheSize: 0,
160 contentStorageCacheSize: 0,
161 treeCacheSize: 0
162 })
163
164 drive.writeFile('/hello.txt', 'world', function (err) {
165 t.error(err, 'no error')
166 drive.readFile('/hello.txt', function (err, buf) {
167 t.error(err, 'no error')
168 t.same(buf, Buffer.from('world'))
169 t.end()
170 })
171 })
172})
173
174tape('can read a single directory', async function (t) {
175 const drive = create(null)
176
177 let files = ['a', 'b', 'c', 'd', 'e', 'f']
178 let fileSet = new Set(files)
179
180 for (let file of files) {
181 await insertFile(file, 'a small file')
182 }
183
184 drive.readdir('/', (err, files) => {
185 t.error(err, 'no error')
186 for (let file of files) {
187 t.true(fileSet.has(file), 'correct file was listed')
188 fileSet.delete(file)
189 }
190 t.same(fileSet.size, 0, 'all files were listed')
191 t.end()
192 })
193
194 function insertFile (name, content) {
195 return new Promise((resolve, reject) => {
196 drive.writeFile(name, content, err => {
197 if (err) return reject(err)
198 return resolve()
199 })
200 })
201 }
202})
203
204tape.skip('can stream a large directory', async function (t) {
205 const drive = create(null)
206
207 let files = new Array(1000).fill(0).map((_, idx) => '' + idx)
208 let fileSet = new Set(files)
209
210 for (let file of files) {
211 await insertFile(file, 'a small file')
212 }
213
214 let stream = drive.createDirectoryStream('/')
215 stream.on('data', ({ path, stat }) => {
216 if (!fileSet.has(path)) {
217 return t.fail('an incorrect file was streamed')
218 }
219 fileSet.delete(path)
220 })
221 stream.on('end', () => {
222 t.same(fileSet.size, 0, 'all files were streamed')
223 t.end()
224 })
225
226 function insertFile (name, content) {
227 return new Promise((resolve, reject) => {
228 drive.writeFile(name, content, err => {
229 if (err) return reject(err)
230 return resolve()
231 })
232 })
233 }
234})
235
236tape('can read sparse metadata', async function (t) {
237 const r = new Replicator(t)
238 const { read, write } = await getTestDrives()
239
240 let files = ['a', 'b/a/b', 'b/c', 'c/b', 'd/e/f/g/h', 'd/e/a', 'e/a', 'e/b', 'f', 'g']
241
242 for (let file of files) {
243 await insertFile(file, 'a small file')
244 await checkFile(file)
245 }
246
247 r.end()
248
249 function checkFile (file) {
250 return new Promise(resolve => {
251 read.stat(file, (err, st) => {
252 t.error(err, 'no error')
253 t.true(st)
254 return resolve()
255 })
256 })
257 }
258
259 function insertFile (name, content) {
260 return new Promise((resolve, reject) => {
261 write.writeFile(name, content, err => {
262 if (err) return reject(err)
263 return resolve()
264 })
265 })
266 }
267
268 function getTestDrives () {
269 return new Promise(resolve => {
270 let drive = create()
271 drive.on('ready', () => {
272 let clone = create(drive.key, { sparseMetadata: true, sparse: true })
273 r.replicate(clone, drive)
274 return resolve({ read: clone, write: drive })
275 })
276 })
277 }
278})
279
280tape('unavailable drive becomes ready', function (t) {
281 var drive1 = create()
282 var drive2 = null
283
284 drive1.ready(err => {
285 t.error(err, 'no error')
286 drive2 = create(drive1.key)
287 drive2.ready(err => {
288 t.error(err, 'no error')
289 drive2.readFile('blah', (err, contents) => {
290 t.true(err)
291 t.same(err.errno, 2)
292 t.end()
293 })
294 })
295 })
296})
297
298tape('copy', function (t) {
299 var drive = create()
300 drive.ready(err => {
301 t.error(err, 'no error')
302 drive.writeFile('hello', 'world', err => {
303 t.error(err, 'no error')
304 drive.copy('hello', 'also_hello', err => {
305 t.error(err, 'no error')
306 drive.readFile('hello', { encoding: 'utf8' }, (err, contents) => {
307 t.error(err, 'no error')
308 t.same(contents, 'world')
309 drive.readFile('also_hello', { encoding: 'utf8' }, (err, contents) => {
310 t.error(err, 'no error')
311 t.same(contents, 'world')
312 t.end()
313 })
314 })
315 })
316 })
317 })
318})