ninenano

Client implementation of the 9P protocol for constrained devices

git clone https://git.8pit.net/ninenano.git

  1#include <stdio.h>
  2#include <stdlib.h>
  3#include <string.h>
  4
  5#include <sys/stat.h>
  6#include <sys/types.h>
  7
  8#include "9p.h"
  9#include "9util.h"
 10#include "xtimer.h"
 11
 12#include "lwip.h"
 13#include "lwip/netif.h"
 14
 15#include "net/af.h"
 16#include "net/ipv6/addr.h"
 17#include "net/sock/tcp.h"
 18
 19#include "embUnit.h"
 20#include "../../util.h"
 21
 22/**
 23 * TCP control socket.
 24 */
 25static sock_tcp_t csock;
 26
 27/**
 28 * Global 9P connection context.
 29 */
 30static _9pctx ctx;
 31
 32static void
 33setcmd(char *cmd)
 34{
 35	if (sock_tcp_write(&csock, cmd, strlen(cmd)) < 0)
 36		TEST_FAIL("Couldn't write to control server");
 37}
 38
 39static void
 40tear_down(void)
 41{
 42	memset(ctx.fids, 0, _9P_MAXFIDS * sizeof(_9pfid));
 43}
 44
 45static void
 46set_up(void)
 47{
 48	xtimer_usleep(1000);
 49}
 50
 51/**
 52 * @defgroup _9putil_tests Tests for utility functios from `9p/util.c`.
 53 *
 54 * @{
 55 */
 56
 57static void
 58test_9putil_pstring_and_hstring(void)
 59{
 60	_9ppkt pkt;
 61	uint8_t buf[10];
 62	char dest[10];
 63
 64	pkt.buf = buf;
 65	pkt.len = 10;
 66
 67	TEST_ASSERT_EQUAL_INT(0, pstring("foobar", &pkt));
 68
 69	pkt.buf = buf;
 70	pkt.len = 10;
 71
 72	TEST_ASSERT_EQUAL_INT(0, hstring(dest, 10, &pkt));
 73	TEST_ASSERT_EQUAL_STRING("foobar", (char*)dest);
 74}
 75
 76static void
 77test_9putil_pstring_empty_string(void)
 78{
 79	_9ppkt pkt;
 80	uint8_t buf[2];
 81	char dest[2];
 82
 83	pkt.buf = buf;
 84	pkt.len = 4;
 85
 86	TEST_ASSERT_EQUAL_INT(0, pstring(NULL, &pkt));
 87
 88	pkt.buf = buf;
 89	pkt.len = 4;
 90
 91	TEST_ASSERT_EQUAL_INT(0, hstring(dest, 2, &pkt));
 92	TEST_ASSERT_EQUAL_STRING("", (char*)dest);
 93}
 94
 95static void
 96test_9putil_pstring_buffer_to_small1(void)
 97{
 98	_9ppkt pkt;
 99	uint8_t buf[1];
100
101	pkt.buf = buf;
102	pkt.len = 1;
103
104	TEST_ASSERT_EQUAL_INT(-1, pstring(NULL, &pkt));
105}
106
107static void
108test_9putil_pstring_buffer_to_small2(void)
109{
110	_9ppkt pkt;
111	uint8_t buf[5];
112
113	pkt.buf = buf;
114	pkt.len = 5;
115
116	TEST_ASSERT_EQUAL_INT(-1, pstring("lolz", &pkt));
117}
118
119static void
120test_9putil_hstring_invalid1(void)
121{
122	_9ppkt pkt;
123	uint8_t buf[10];
124	char dest[10];
125
126	pkt.buf = buf;
127	pkt.len = 10;
128
129	TEST_ASSERT_EQUAL_INT(0, pstring("kek", &pkt));
130
131	pkt.buf = buf;
132	pkt.len = BIT16SZ - 1;
133
134	TEST_ASSERT_EQUAL_INT(-1, hstring(dest, 10, &pkt));
135}
136
137static void
138test_9putil_hstring_invalid2(void)
139{
140	_9ppkt pkt;
141	uint8_t buf[5];
142	char dest[5];
143
144	pkt.len = 5;
145	pkt.buf = buf;
146
147	htop16(pkt.len, &pkt);
148
149	pkt.len = 5;
150	pkt.buf = buf;
151
152	TEST_ASSERT_EQUAL_INT(-1, hstring(dest, 5, &pkt));
153}
154
155static void
156test_9putil_hstring_invalid3(void)
157{
158	_9ppkt pkt;
159	uint8_t buf[5];
160	char dest[5];
161
162	pkt.buf = buf;
163	pkt.len = 5;
164
165	TEST_ASSERT_EQUAL_INT(0, pstring("foo", &pkt));
166
167	pkt.buf = buf;
168	pkt.len = 5;
169
170	htop16(42, &pkt);
171
172	TEST_ASSERT_EQUAL_INT(-1, hstring(dest, 5, &pkt));
173}
174
175static void
176test_9putil_fidtbl_add(void)
177{
178	_9pfid *f;
179
180	f = fidtbl(ctx.fids, 23, ADD);
181	f->fid = 23;
182
183	TEST_ASSERT_NOT_NULL(f);
184	TEST_ASSERT_EQUAL_INT(23, f->fid);
185	TEST_ASSERT_EQUAL_INT(1, cntfids(ctx.fids));
186}
187
188static void
189test_9putil_fidtbl_add_invalid(void)
190{
191	TEST_ASSERT_NULL(fidtbl(ctx.fids, 0, ADD));
192	TEST_ASSERT_EQUAL_INT(0, cntfids(ctx.fids));
193}
194
195static void
196test_9putil_fidtbl_add_full(void)
197{
198	_9pfid *f;
199	size_t i;
200
201	for (i = 1; i <= _9P_MAXFIDS; i++) {
202		f = fidtbl(ctx.fids, i, ADD);
203		TEST_ASSERT_NOT_NULL(f);
204		f->fid = i;
205	}
206
207	TEST_ASSERT_NULL(fidtbl(ctx.fids, ++i, ADD));
208	TEST_ASSERT_EQUAL_INT(_9P_MAXFIDS, cntfids(ctx.fids));
209}
210
211static void
212test_9putil_fidtbl_get(void)
213{
214	_9pfid *f1, *f2;
215
216	f1 = fidtbl(ctx.fids, 42, ADD);
217	f1->fid = 42;
218
219	f2 = fidtbl(ctx.fids, 42, GET);
220
221	TEST_ASSERT_NOT_NULL(f2);
222	TEST_ASSERT_EQUAL_INT(42, f2->fid);
223}
224
225static void
226test_9putil_fidtbl_delete(void)
227{
228	_9pfid *f1, *f2;
229
230	f1 = fidtbl(ctx.fids, 1337, ADD);
231	f1->fid = 1337;
232
233	f2 = fidtbl(ctx.fids, 1337, DEL);
234
235	TEST_ASSERT_NOT_NULL(f2);
236	TEST_ASSERT_EQUAL_INT(0, f2->fid);
237	TEST_ASSERT_NULL(fidtbl(ctx.fids, 1337, GET));
238}
239
240static void
241test_9putil_fidtbl_delete_rootfid(void)
242{
243	fidtbl(ctx.fids, _9P_ROOTFID, ADD);
244	TEST_ASSERT_NULL(fidtbl(ctx.fids, _9P_ROOTFID, DEL));
245}
246
247static void
248test_9putil__newfid(void)
249{
250	_9pfid *f1, *f2;
251
252	f1 = newfid(ctx.fids);
253	TEST_ASSERT_NOT_NULL(f1);
254
255	TEST_ASSERT_EQUAL_INT(1, cntfids(ctx.fids));
256
257	f2 = fidtbl(ctx.fids, f1->fid, GET);
258	TEST_ASSERT_NOT_NULL(f2);
259
260	TEST_ASSERT_EQUAL_INT(f1->fid, f2->fid);
261}
262
263static void
264test_9putil__newfid_full(void)
265{
266	_9pfid *f;
267	size_t i;
268
269	for (i = 1; i <= _9P_MAXFIDS; i++) {
270		f = fidtbl(ctx.fids, i, ADD);
271		TEST_ASSERT_NOT_NULL(f);
272		f->fid = i;
273	}
274
275	TEST_ASSERT_NULL(newfid(ctx.fids));
276}
277
278Test*
279tests_9putil_tests(void)
280{
281	EMB_UNIT_TESTFIXTURES(fixtures) {
282		new_TestFixture(test_9putil_pstring_and_hstring),
283		new_TestFixture(test_9putil_pstring_empty_string),
284		new_TestFixture(test_9putil_pstring_buffer_to_small1),
285		new_TestFixture(test_9putil_pstring_buffer_to_small2),
286		new_TestFixture(test_9putil_hstring_invalid1),
287		new_TestFixture(test_9putil_hstring_invalid2),
288		new_TestFixture(test_9putil_hstring_invalid3),
289
290		new_TestFixture(test_9putil_fidtbl_add),
291		new_TestFixture(test_9putil_fidtbl_add_invalid),
292		new_TestFixture(test_9putil_fidtbl_add_full),
293		new_TestFixture(test_9putil_fidtbl_get),
294		new_TestFixture(test_9putil_fidtbl_delete),
295		new_TestFixture(test_9putil_fidtbl_delete_rootfid),
296
297		new_TestFixture(test_9putil__newfid),
298		new_TestFixture(test_9putil__newfid_full),
299	};
300
301	EMB_UNIT_TESTCALLER(_9putil_tests, NULL, tear_down, fixtures);
302	return (Test*)&_9putil_tests;
303}
304
305/**@}*/
306
307/**
308 * @defgroup _9p_tests Tests for protocol functions from `9p/9p.c`.
309 *
310 * You might be wondering why there are no comments below this points.
311 * This is the case because the purpose of the various test cases is
312 * explained in the file `tests/server/tests.go` instead.
313 *
314 * Please refer to that file if you seek more information about the
315 * various test cases. The test cases just act as stupid TCP clients,
316 * the interessting stuff happens on the server side.
317 */
318
319static void
320test_9p__header_too_short1(void)
321{
322	setcmd("header_too_short1\n");
323	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pversion(&ctx));
324}
325
326static void
327test_9p__header_too_short2(void)
328{
329	setcmd("header_too_short2\n");
330	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pversion(&ctx));
331}
332
333static void
334test_9p__header_too_large(void)
335{
336	setcmd("header_too_large\n");
337	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pversion(&ctx));
338}
339
340static void
341test_9p__header_wrong_type(void)
342{
343	setcmd("header_wrong_type\n");
344	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pversion(&ctx));
345}
346
347static void
348test_9p__header_invalid_type(void)
349{
350	setcmd("header_invalid_type\n");
351	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pversion(&ctx));
352}
353
354static void
355test_9p__header_tag_mismatch(void)
356{
357	setcmd("header_tag_mismatch\n");
358	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pversion(&ctx));
359}
360
361static void
362test_9p__header_type_mismatch(void)
363{
364	setcmd("header_type_mismatch\n");
365	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pversion(&ctx));
366}
367
368static void
369test_9p__rversion_success(void)
370{
371	setcmd("rversion_success\n");
372	TEST_ASSERT_EQUAL_INT(0, _9pversion(&ctx));
373}
374
375static void
376test_9p__rversion_unknown(void)
377{
378	setcmd("rversion_unknown\n");
379	TEST_ASSERT_EQUAL_INT(-ENOPROTOOPT, _9pversion(&ctx));
380}
381
382static void
383test_9p__rversion_msize_too_big(void)
384{
385	setcmd("rversion_msize_too_big\n");
386	TEST_ASSERT_EQUAL_INT(-EMSGSIZE, _9pversion(&ctx));
387}
388
389static void
390test_9p__rversion_invalid(void)
391{
392	setcmd("rversion_invalid\n");
393	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pversion(&ctx));
394}
395
396static void
397test_9p__rversion_invalid_len(void)
398{
399	setcmd("rversion_invalid_len\n");
400	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pversion(&ctx));
401}
402
403static void
404test_9p__rversion_version_too_long(void)
405{
406	setcmd("rversion_version_too_long\n");
407	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pversion(&ctx));
408}
409
410static void
411test_9p__rattach_success(void)
412{
413	_9pfid *fid;
414
415	setcmd("rattach_success\n");
416	TEST_ASSERT_EQUAL_INT(0, _9pattach(&ctx, &fid, "foo", NULL));
417
418	TEST_ASSERT(fid->fid > 0);
419	TEST_ASSERT_EQUAL_INT(1, cntfids(ctx.fids));
420}
421
422static void
423test_9p__rattach_invalid_len(void)
424{
425	_9pfid *fid;
426
427	setcmd("rattach_invalid_len\n");
428	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pattach(&ctx, &fid, "foobar", NULL));
429}
430
431static void
432test_9p__rstat_success(void)
433{
434	_9pfid f;
435	struct stat st;
436
437	f.fid = 2342;
438
439	setcmd("rstat_success\n");
440	TEST_ASSERT_EQUAL_INT(0, _9pstat(&ctx, &f, &st));
441
442	TEST_ASSERT_EQUAL_INT(23, f.qid.type);
443	TEST_ASSERT_EQUAL_INT(2342, f.qid.vers);
444	TEST_ASSERT_EQUAL_INT(1337, f.qid.path);
445
446	TEST_ASSERT_EQUAL_INT(S_IFDIR, st.st_mode);
447	TEST_ASSERT_EQUAL_INT(1494443596, st.st_atime);
448	TEST_ASSERT_EQUAL_INT(1494443609, st.st_mtime);
449	TEST_ASSERT_EQUAL_INT(st.st_mtime, st.st_ctime);
450	TEST_ASSERT_EQUAL_INT(2342, st.st_size);
451
452	TEST_ASSERT_EQUAL_INT(0, st.st_dev);
453	TEST_ASSERT_EQUAL_INT(0, st.st_ino);
454	TEST_ASSERT_EQUAL_INT(0, st.st_rdev);
455	TEST_ASSERT_EQUAL_INT(1, st.st_nlink);
456	TEST_ASSERT_EQUAL_INT(0, st.st_uid);
457	TEST_ASSERT_EQUAL_INT(0, st.st_gid);
458	TEST_ASSERT_EQUAL_INT(_9P_MSIZE - _9P_IOHDRSIZ, st.st_blksize);
459	TEST_ASSERT_EQUAL_INT(2342 / (_9P_MSIZE - _9P_IOHDRSIZ) + 1, st.st_blocks);
460}
461
462static void
463test_9p__rstat_too_short(void)
464{
465	_9pfid f;
466	struct stat st;
467
468	f.fid = 1337;
469
470	setcmd("rstat_too_short\n");
471	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pstat(&ctx, &f, &st));
472}
473
474static void
475test_9p__rwalk_success(void)
476{
477	_9pfid *f;
478
479	setcmd("rwalk_success\n");
480	TEST_ASSERT_EQUAL_INT(0, _9pwalk(&ctx, &f, "foo/bar"));
481
482	TEST_ASSERT_EQUAL_INT(23, f->qid.type);
483	TEST_ASSERT_EQUAL_INT(42, f->qid.vers);
484	TEST_ASSERT_EQUAL_INT(1337, f->qid.path);
485
486	TEST_ASSERT_EQUAL_INT(1, cntfids(ctx.fids));
487}
488
489static void
490test_9p__rwalk_rootfid(void)
491{
492	_9pfid *f;
493
494	setcmd("rwalk_success\n");
495	TEST_ASSERT_EQUAL_INT(0, _9pwalk(&ctx, &f, "/"));
496
497	TEST_ASSERT(f->fid != _9P_ROOTFID);
498	TEST_ASSERT_EQUAL_INT(1, cntfids(ctx.fids));
499}
500
501static void
502test_9p__rwalk_invalid_len(void)
503{
504	_9pfid *f;
505
506	setcmd("rwalk_invalid_len\n");
507	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pwalk(&ctx, &f, "foobar"));
508	TEST_ASSERT_EQUAL_INT(0, cntfids(ctx.fids));
509}
510
511static void
512test_9p__rwalk_path_too_many_elems(void)
513{
514	_9pfid *f;
515	char *path;
516
517	path = "1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17";
518	TEST_ASSERT_EQUAL_INT(-ENAMETOOLONG, _9pwalk(&ctx, &f, path));
519	TEST_ASSERT_EQUAL_INT(0, cntfids(ctx.fids));
520}
521
522static void
523test_9p__rwalk_path_too_long(void)
524{
525	_9pfid *f;
526	char path[_9P_MSIZE];
527
528	memset(path, 'a', sizeof(path));
529	path[5] = '/';
530	path[sizeof(path) - 1] = '\0';
531
532	TEST_ASSERT_EQUAL_INT(-EOVERFLOW, _9pwalk(&ctx, &f, path));
533	TEST_ASSERT_EQUAL_INT(0, cntfids(ctx.fids));
534}
535
536static void
537test_9p__rwalk_nwqid_too_large(void)
538{
539	_9pfid *f;
540
541	setcmd("rwalk_nwqid_too_large\n");
542	TEST_ASSERT_EQUAL_INT(-EBADMSG, _9pwalk(&ctx, &f, "foo"));
543	TEST_ASSERT_EQUAL_INT(0, cntfids(ctx.fids));
544}
545
546static void
547test_9p__ropen_success(void)
548{
549	_9pfid f;
550
551	f.fid = 42;
552
553	setcmd("ropen_success\n");
554	TEST_ASSERT_EQUAL_INT(0, _9popen(&ctx, &f, 0));
555	TEST_ASSERT_EQUAL_INT(1337, f.iounit);
556}
557
558static void
559test_9p__rcreate_success(void)
560{
561	_9pfid f;
562
563	f.fid = 4223;
564
565	setcmd("rcreate_success\n");
566	TEST_ASSERT_EQUAL_INT(0, _9pcreate(&ctx, &f, "hurrdurr", ORDWR, 0));
567	TEST_ASSERT_EQUAL_INT(9001, f.iounit);
568}
569
570static void
571test_9p__rcreate_name_too_long(void)
572{
573	_9pfid f;
574	char name[_9P_MSIZE - _9P_HEADSIZ - BIT32SZ - BIT16SZ];
575
576	memset(name, 'a', sizeof(name));
577	name[sizeof(name) - 1] = '\0';
578
579	TEST_ASSERT_EQUAL_INT(-EOVERFLOW, _9pcreate(&ctx, &f, name, ORDWR, 0));
580}
581
582static void
583test_9p__rread_success(void)
584{
585	_9pfid f;
586	ssize_t ret;
587	char dest[7];
588
589	setcmd("rread_success\n");
590
591	f.fid = 42;
592	f.off = 0;
593	f.iounit = 50;
594
595	ret = _9pread(&ctx, &f, dest, 6);
596	TEST_ASSERT_EQUAL_INT(6, ret);
597
598	dest[ret] = '\0';
599	TEST_ASSERT_EQUAL_STRING("Hello!", (char*)dest);
600}
601
602static void
603test_9p__rread_with_offset1(void)
604{
605	_9pfid f;
606	ssize_t ret;
607	char dest[11];
608
609	// Set command twice because with an iounit of 5
610	// we need to send two requests to receive the
611	// entire file.
612	setcmd("rread_with_offset\n");
613	setcmd("rread_with_offset\n");
614
615	f.fid = 23;
616	f.off = 0;
617	f.iounit = 5;
618
619	ret = _9pread(&ctx, &f, dest, 10);
620	TEST_ASSERT_EQUAL_INT(10, ret);
621
622	dest[ret] = '\0';
623	TEST_ASSERT_EQUAL_STRING("1234567890", (char*)dest);
624}
625
626static void
627test_9p__rread_with_offset2(void)
628{
629	_9pfid f;
630	ssize_t ret;
631	char dest[6];
632
633	setcmd("rread_with_offset\n");
634
635	f.fid = 42;
636	f.off = 0;
637	f.iounit = 9999;
638
639	ret = _9pread(&ctx, &f, dest, 5);
640	dest[ret] = '\0';
641
642	TEST_ASSERT_EQUAL_INT(5, ret);
643	TEST_ASSERT_EQUAL_STRING("12345", (char*)dest);
644
645	setcmd("rread_with_offset\n");
646
647	ret = _9pread(&ctx, &f, dest, 5);
648	dest[ret] = '\0';
649
650	TEST_ASSERT_EQUAL_INT(5, ret);
651	TEST_ASSERT_EQUAL_STRING("67890", (char*)dest);
652}
653
654static void
655test_9p__rread_count_zero(void)
656{
657	_9pfid f;
658	char dest[11];
659
660	setcmd("rread_count_zero\n");
661
662	f.fid = 42;
663	f.off = 0;
664	f.iounit = 1337;
665
666	TEST_ASSERT_EQUAL_INT(0, _9pread(&ctx, &f, dest, 10));
667}
668
669static void
670test_9p__rread_with_larger_count(void)
671{
672	_9pfid f;
673	ssize_t ret;
674	char dest[7];
675
676	setcmd("rread_success\n");
677
678	f.fid = 5;
679	f.off = 0;
680	f.iounit = 100;
681
682	ret = _9pread(&ctx, &f, dest, 100);
683	TEST_ASSERT_EQUAL_INT(6, ret);
684
685	dest[ret] = '\0';
686	TEST_ASSERT_EQUAL_STRING("Hello!", (char*)dest);
687}
688
689static void
690test_9p__rwrite_success(void)
691{
692	_9pfid f;
693	char *str = "hurrdurr";
694	size_t l;
695
696	setcmd("rwrite_success\n");
697
698	f.fid = 9002;
699	f.off = 0;
700	f.iounit = 50;
701
702	l = strlen(str);
703	TEST_ASSERT_EQUAL_INT(l, _9pwrite(&ctx, &f, str, l));
704}
705
706static void
707test_9p__rclunk_success(void)
708{
709	_9pfid *f;
710
711	setcmd("rclunk_success\n");
712
713	f = fidtbl(ctx.fids, 23, ADD);
714	f->fid = 23;
715
716	TEST_ASSERT_EQUAL_INT(0, _9pclunk(&ctx, f));
717}
718
719static void
720test_9p__rclunk_bad_fid(void)
721{
722	_9pfid f;
723
724	setcmd("rclunk_success\n");
725
726	f.fid = 42;
727	TEST_ASSERT_EQUAL_INT(-EBADF, _9pclunk(&ctx, &f));
728}
729
730static void
731test_9p__rremove_success(void)
732{
733	_9pfid *f;
734
735	setcmd("remove_success\n");
736
737	f = fidtbl(ctx.fids, 9, ADD);
738	f->fid = 9;
739
740	TEST_ASSERT_EQUAL_INT(0, _9premove(&ctx, f));
741}
742
743static void
744test_9p__rremove_bad_fid(void)
745{
746	_9pfid f;
747
748	setcmd("remove_success\n");
749
750	f.fid = 5;
751	TEST_ASSERT_EQUAL_INT(-EBADF, _9premove(&ctx, &f));
752}
753
754Test*
755tests_9p_tests(void)
756{
757	EMB_UNIT_TESTFIXTURES(fixtures) {
758		new_TestFixture(test_9p__header_too_short1),
759		new_TestFixture(test_9p__header_too_short2),
760		new_TestFixture(test_9p__header_too_large),
761		new_TestFixture(test_9p__header_wrong_type),
762		new_TestFixture(test_9p__header_invalid_type),
763		new_TestFixture(test_9p__header_tag_mismatch),
764		new_TestFixture(test_9p__header_type_mismatch),
765
766		new_TestFixture(test_9p__rversion_success),
767		new_TestFixture(test_9p__rversion_unknown),
768		new_TestFixture(test_9p__rversion_msize_too_big),
769		new_TestFixture(test_9p__rversion_invalid),
770		new_TestFixture(test_9p__rversion_invalid_len),
771		new_TestFixture(test_9p__rversion_version_too_long),
772
773		new_TestFixture(test_9p__rattach_success),
774		new_TestFixture(test_9p__rattach_invalid_len),
775
776		new_TestFixture(test_9p__rstat_success),
777		new_TestFixture(test_9p__rstat_too_short),
778
779		new_TestFixture(test_9p__rwalk_success),
780		new_TestFixture(test_9p__rwalk_rootfid),
781		new_TestFixture(test_9p__rwalk_invalid_len),
782		new_TestFixture(test_9p__rwalk_path_too_long),
783		new_TestFixture(test_9p__rwalk_path_too_many_elems),
784		new_TestFixture(test_9p__rwalk_nwqid_too_large),
785
786		new_TestFixture(test_9p__ropen_success),
787
788		new_TestFixture(test_9p__rcreate_success),
789		new_TestFixture(test_9p__rcreate_name_too_long),
790
791		new_TestFixture(test_9p__rread_success),
792		new_TestFixture(test_9p__rread_with_offset1),
793		new_TestFixture(test_9p__rread_with_offset2),
794		new_TestFixture(test_9p__rread_count_zero),
795		new_TestFixture(test_9p__rread_with_larger_count),
796
797		new_TestFixture(test_9p__rwrite_success),
798
799		new_TestFixture(test_9p__rclunk_success),
800		new_TestFixture(test_9p__rclunk_bad_fid),
801
802		new_TestFixture(test_9p__rremove_success),
803		new_TestFixture(test_9p__rremove_bad_fid),
804	};
805
806	EMB_UNIT_TESTCALLER(_9p_tests, set_up, tear_down, fixtures);
807	return (Test*)&_9p_tests;
808}
809
810/**@}*/
811
812int
813main(void)
814{
815	char *addr, *cport, *pport;
816	sock_tcp_ep_t cr = SOCK_IPV6_EP_ANY;
817	sock_tcp_ep_t pr = SOCK_IPV6_EP_ANY;
818
819	puts("Waiting for address autoconfiguration...");
820	xtimer_sleep(3);
821
822	GETENV(addr, "NINERIOT_ADDR");
823
824	if (!ipv6_addr_from_str((ipv6_addr_t*)&cr.addr, addr)
825			|| !ipv6_addr_from_str((ipv6_addr_t*)&pr.addr, addr)) {
826		fprintf(stderr, "Address '%s' is malformed\n", addr);
827		return EXIT_FAILURE;
828	}
829
830	GETENV(pport, "NINERIOT_PPORT");
831	GETENV(cport, "NINERIOT_CPORT");
832
833	pr.port = atoi(pport);
834	cr.port = atoi(cport);
835
836	if (sock_tcp_connect(&csock, &cr, 0, SOCK_FLAGS_REUSE_EP) < 0
837			|| sock_tcp_connect(&psock, &pr, 0, SOCK_FLAGS_REUSE_EP) < 0) {
838		fprintf(stderr, "Couldn't connect to server\n");
839		return EXIT_FAILURE;
840	}
841
842	_9pinit(&ctx, recvfn, sendfn);
843
844	TESTS_START();
845	TESTS_RUN(tests_9putil_tests());
846	TESTS_RUN(tests_9p_tests());
847	TESTS_END();
848
849	sock_tcp_disconnect(&csock);
850	sock_tcp_disconnect(&psock);
851
852	return EXIT_SUCCESS;
853}