1// Copyright 2017 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <dirent.h>
6#include <errno.h>
7#include <fcntl.h>
8#include <stdbool.h>
9#include <stdint.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <sys/stat.h>
14#include <unistd.h>
15
16#include <unittest/unittest.h>
17
18#include "misc.h"
19#include "filesystems.h"
20
21bool fcheck_dir_contents(DIR* dir, expected_dirent_t* edirents, size_t len) {
22    BEGIN_HELPER;
23
24    rewinddir(dir);
25    size_t seen = 0;
26    while (seen != len) {
27        struct dirent* de = readdir(dir);
28        ASSERT_NE(de, NULL, "Didn't see all expected direntries");
29        bool found = false;
30        for (size_t i = 0; i < len; i++) {
31            if (strcmp(edirents[i].d_name, de->d_name) == 0) {
32                ASSERT_EQ(edirents[i].d_type, de->d_type, "Saw direntry with unexpected type");
33                ASSERT_FALSE(edirents[i].seen, "Direntry seen twice");
34                edirents[i].seen = true;
35                seen++;
36                found = true;
37                break;
38            }
39        }
40
41        ASSERT_TRUE(found, "Saw an unexpected dirent");
42    }
43
44    ASSERT_EQ(readdir(dir), NULL, "There exists an entry we didn't expect to see");
45
46    // Flip 'seen' back to false so the array of expected dirents can be reused
47    for (size_t i = 0; i < len; i++) {
48        edirents[i].seen = false;
49    }
50
51    END_HELPER;
52}
53
54bool check_dir_contents(const char* dirname, expected_dirent_t* edirents, size_t len) {
55    BEGIN_HELPER;
56    DIR* dir = opendir(dirname);
57    EXPECT_TRUE(fcheck_dir_contents(dir, edirents, len), "");
58    ASSERT_EQ(closedir(dir), 0, "Couldn't close inspected directory");
59    END_HELPER;
60}
61
62// Check the contents of a file are what we expect
63bool check_file_contents(int fd, const uint8_t* buf, size_t length) {
64    BEGIN_HELPER;
65    ASSERT_EQ(lseek(fd, 0, SEEK_SET), 0, "");
66    uint8_t* out = malloc(length);
67    ASSERT_NE(out, NULL, "Failed to allocate checking buffer");
68    ASSERT_STREAM_ALL(read, fd, out, length);
69    ASSERT_EQ(memcmp(buf, out, length), 0, "");
70    free(out);
71    END_HELPER;
72}
73
74bool check_remount(void) {
75    BEGIN_HELPER;
76    ASSERT_EQ(test_info->unmount(kMountPath), 0, "");
77    ASSERT_EQ(test_info->fsck(test_disk_path), 0, "");
78    ASSERT_EQ(test_info->mount(test_disk_path, kMountPath), 0, "");
79    END_HELPER;
80}
81