1#include <fcntl.h>2#include <stdio.h>3#include <stdlib.h>4#include <errno.h>56#include <sys/stat.h>7#include <sys/types.h>89#include "9p.h"10#include "vfs.h"11#include "9pfs.h"12#include "xtimer.h"1314#include "lwip.h"15#include "lwip/netif.h"1617#include "net/af.h"18#include "net/ipv6/addr.h"19#include "net/sock/tcp.h"2021#include "embUnit.h"22#include "../../util.h"2324/**25 * 9P file system superblock.26 */27static _9pfs fs;2829/**30 * Mount point where the 9pfs is mounted.31 */32static vfs_mount_t mountp;3334static void35set_up(void)36{37 int ret;3839 mountp.mount_point = "/mnt";40 mountp.fs = &_9p_file_system;41 mountp.private_data = &fs;4243 _9pinit(&fs.ctx, recvfn, sendfn);44 if ((ret = vfs_mount(&mountp)))45 fprintf(stderr, "vfs_mount failed: %d\n", ret);46}4748static void49tear_down(void)50{51 int ret;5253 if ((ret = vfs_umount(&mountp)))54 fprintf(stderr, "vfs_umount failed: %d\n", ret);55}5657static void58test_9pfs__create_and_remove_directory(void)59{60 struct stat st;6162 TEST_ASSERT_EQUAL_INT(0, vfs_mkdir("/mnt/foo/wtf", S_IRUSR|S_IWUSR));63 TEST_ASSERT_EQUAL_INT(0, vfs_rmdir("/mnt/foo/wtf"));6465 TEST_ASSERT(vfs_stat("/mnt/foo/wtf", &st) != 0);66 TEST_ASSERT_EQUAL_INT(1, cntfids(fs.ctx.fids));67}6869static void70test_9pfs__read(void)71{72 int fd;73 ssize_t n;74 char dest[BUFSIZ];7576 fd = vfs_open("/mnt/foo/bar/hello", OREAD, S_IRUSR|S_IWUSR);77 TEST_ASSERT(fd >= 0);7879 n = vfs_read(fd, dest, BUFSIZ - 1);80 TEST_ASSERT_EQUAL_INT(13, n);8182 dest[n] = '\0';83 TEST_ASSERT_EQUAL_STRING("Hello World!\n", (char*)dest);8485 TEST_ASSERT_EQUAL_INT(0, vfs_close(fd));86}8788static void89test_9pfs__lseek_and_read(void)90{91 int fd;92 ssize_t n;93 char dest[BUFSIZ];9495 fd = vfs_open("/mnt/foo/bar/hello", OREAD, S_IRUSR|S_IWUSR);96 TEST_ASSERT(fd >= 0);9798 TEST_ASSERT_EQUAL_INT(6, vfs_lseek(fd, 6, SEEK_SET));99100 n = vfs_read(fd, dest, BUFSIZ - 1);101 TEST_ASSERT_EQUAL_INT(7, n);102103 dest[n] = '\0';104 TEST_ASSERT_EQUAL_STRING("World!\n", (char*)dest);105106 TEST_ASSERT_EQUAL_INT(0, vfs_close(fd));107}108109static void110test_9pfs__create_and_delete(void)111{112 int fd;113 struct stat buf;114115 fd = vfs_open("/mnt/foo/falafel", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);116 TEST_ASSERT(fd >= 0);117118 TEST_ASSERT_EQUAL_INT(0, vfs_close(fd));119 TEST_ASSERT_EQUAL_INT(0, vfs_unlink("/mnt/foo/falafel"));120121 TEST_ASSERT(vfs_stat("/mnt/foo/falafel", &buf) < 0);122}123124static void125test_9pfs__write_lseek_and_read(void)126{127 int fd;128 ssize_t n;129 char *str = "foobar";130 char dest[7];131132 fd = vfs_open("/mnt/writeme", O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR);133 TEST_ASSERT(fd >= 0);134135 TEST_ASSERT_EQUAL_INT(2, cntfids(fs.ctx.fids));136137 n = vfs_write(fd, str, 6);138 TEST_ASSERT_EQUAL_INT(6, n);139140 TEST_ASSERT_EQUAL_INT(0, vfs_lseek(fd, 0, SEEK_SET));141142 n = vfs_read(fd, dest, 6);143 TEST_ASSERT_EQUAL_INT(6, n);144145 dest[6] = '\0';146 TEST_ASSERT_EQUAL_STRING(str, (char*)dest);147148 TEST_ASSERT_EQUAL_INT(0, vfs_close(fd));149 TEST_ASSERT_EQUAL_INT(1, cntfids(fs.ctx.fids));150}151152static void153test_9pfs__opendir_and_closedir(void)154{155 vfs_DIR dirp;156157 TEST_ASSERT_EQUAL_INT(0, vfs_opendir(&dirp, "/mnt/foo"));158 TEST_ASSERT_EQUAL_INT(2, cntfids(fs.ctx.fids));159 TEST_ASSERT_EQUAL_INT(0, vfs_closedir(&dirp));160161 TEST_ASSERT_EQUAL_INT(1, cntfids(fs.ctx.fids));162}163164static void165test_9pfs__opendir_file(void)166{167 vfs_DIR dirp;168169 TEST_ASSERT_EQUAL_INT(-ENOTDIR,170 vfs_opendir(&dirp, "/mnt/foo/bar/hello"));171 TEST_ASSERT_EQUAL_INT(1, cntfids(fs.ctx.fids));172}173174static void175test_9pfs__readdir_single_entry(void)176{177 vfs_DIR dirp;178 vfs_dirent_t entry;179180 TEST_ASSERT_EQUAL_INT(0, vfs_opendir(&dirp, "/mnt/foo"));181 TEST_ASSERT_EQUAL_INT(1, vfs_readdir(&dirp, &entry));182 TEST_ASSERT_EQUAL_STRING("bar", (char*)entry.d_name);183 TEST_ASSERT_EQUAL_INT(0, vfs_readdir(&dirp, &entry));184185 TEST_ASSERT_EQUAL_INT(0, vfs_closedir(&dirp));186 TEST_ASSERT_EQUAL_INT(1, cntfids(fs.ctx.fids));187}188189static void190test_9pfs__readdir_multiple_entries(void)191{192 int i;193 vfs_DIR dirp;194 vfs_dirent_t entry;195 char dirname[VFS_NAME_MAX + 1];196197 TEST_ASSERT_EQUAL_INT(0, vfs_opendir(&dirp, "/mnt/dirs"));198 for (i = 1; i <= 5; i++) {199 TEST_ASSERT_EQUAL_INT(1, vfs_readdir(&dirp, &entry));200 snprintf(dirname, sizeof(dirname), "%d", i);201 TEST_ASSERT_EQUAL_STRING((char*)dirname, (char*)entry.d_name);202 }203 TEST_ASSERT_EQUAL_INT(0, vfs_readdir(&dirp, &entry));204205 TEST_ASSERT_EQUAL_INT(0, vfs_closedir(&dirp));206 TEST_ASSERT_EQUAL_INT(1, cntfids(fs.ctx.fids));207}208209Test*210tests_9pfs_tests(void)211{212 EMB_UNIT_TESTFIXTURES(fixtures) {213 new_TestFixture(test_9pfs__read),214 new_TestFixture(test_9pfs__lseek_and_read),215 new_TestFixture(test_9pfs__create_and_delete),216 new_TestFixture(test_9pfs__write_lseek_and_read),217 new_TestFixture(test_9pfs__create_and_remove_directory),218 new_TestFixture(test_9pfs__opendir_and_closedir),219 new_TestFixture(test_9pfs__opendir_file),220 new_TestFixture(test_9pfs__readdir_single_entry),221 new_TestFixture(test_9pfs__readdir_multiple_entries),222 };223224 EMB_UNIT_TESTCALLER(_9pfs_tests, set_up, tear_down, fixtures);225 return (Test*)&_9pfs_tests;226}227228int229main(void)230{231 char *addr, *port;232 sock_tcp_ep_t remote = SOCK_IPV6_EP_ANY;233234 GETENV(addr, "NINERIOT_ADDR");235 GETENV(port, "NINERIOT_PPORT");236237 remote.port = atoi(port);238 if (!ipv6_addr_from_str((ipv6_addr_t *)&remote.addr, addr)) {239 fprintf(stderr, "Address '%s' is malformed\n", addr);240 return EXIT_FAILURE;241 }242243 puts("Waiting for address autoconfiguration...");244 xtimer_sleep(3);245246 if (sock_tcp_connect(&psock, &remote, 0, SOCK_FLAGS_REUSE_EP) < 0) {247 fprintf(stderr, "Couldn't connect to server\n");248 return EXIT_FAILURE;249 }250251 fs.uname = "glenda";252 fs.aname = NULL;253254 TESTS_START();255 TESTS_RUN(tests_9pfs_tests());256 TESTS_END();257258 sock_tcp_disconnect(&psock);259 return EXIT_SUCCESS;260}