GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/test_libcvmfs.cc Lines: 0 104 0.0 %
Date: 2019-02-03 02:48:13 Branches: 0 40 0.0 %

Line Branch Exec Source
1
/**
2
 * This file is part of the CernVM File System.
3
 *
4
 * This is a simple test program to test the facilities of the libcvmfs C
5
 * (not C++) library, which is used by Parrot and some other tools.
6
 *
7
 * The goal here is not so much to build the ultimate testing tool, but to
8
 * provide a simple build target which can verify that libcvmfs is exporting the
9
 * proper set of symbols to be used by a C program.
10
 */
11
12
#define __STDC_FORMAT_MACROS
13
14
#include "cvmfs_config.h"
15
16
#include <errno.h>
17
#include <inttypes.h>
18
19
#include <cassert>
20
#include <cstdio>
21
#include <cstdlib>
22
#include <cstring>
23
#include <ctime>
24
#include <map>
25
#include <string>
26
27
#include "libcvmfs.h"
28
29
#define TEST_LINE_MAX 1024
30
31
typedef std::map<std::string, cvmfs_context*> RepoMap;
32
static RepoMap attached_repos;
33
cvmfs_option_map *cvmfs_opts = NULL;
34
35
void cvmfs_test_help()
36
{
37
  printf("commands are:\n");
38
  printf("   attach <repo name (without .cern.ch)>\n");
39
  printf("   detach <repo name (without .cern.ch)>\n");
40
  printf("   list <path>\n");
41
  printf("   cat  <path>\n");
42
  printf("   quit\n");
43
}
44
45
static void cvmfs_log_ignore(const char *msg) {
46
  // Remove comment to debug test failures
47
  // fprintf(stderr, "%s\n", msg);
48
}
49
50
int cvmfs_test_list(cvmfs_context *ctx, const char *path)
51
{
52
  if (ctx == NULL) {
53
    fprintf(stderr, "%s\n", "please attach a repo first!");
54
    return -1;
55
  }
56
57
  char filepath[TEST_LINE_MAX];
58
  struct stat info;
59
60
  char **buffer = 0;
61
  size_t length = 0;
62
  int i;
63
64
  int result = cvmfs_listdir(ctx, path, &buffer, &length);
65
  if (result < 0) {
66
    fprintf(stderr, "%s: %s\n", path, strerror(errno));
67
    return -1;
68
  }
69
70
71
  for (i = 0; buffer[i]; i++) {
72
    snprintf(filepath, TEST_LINE_MAX, "%s/%s", path, buffer[i]);
73
    cvmfs_stat(ctx, filepath, &info);
74
    printf("%10" PRIu64 " %s\n",
75
           static_cast<uint64_t>(info.st_size), buffer[i]);
76
  }
77
78
  free(buffer);
79
80
  return 0;
81
}
82
83
int cvmfs_test_cat(cvmfs_context *ctx, const char *path)
84
{
85
  if (ctx == NULL) {
86
    fprintf(stderr, "%s\n", "please attach a repo first!");
87
    return -1;
88
  }
89
90
  char buffer[TEST_LINE_MAX];
91
92
  int fd = cvmfs_open(ctx, path);
93
  if (fd < 0) {
94
    fprintf(stderr, "%s: %s\n", path, strerror(errno));
95
    return fd;
96
  }
97
98
  while (1) {
99
    int length = read(fd, buffer, sizeof(buffer));
100
    if (length <= 0) break;
101
    int retval = write(1, buffer, length);
102
    assert(retval == length);
103
  }
104
105
  cvmfs_close(ctx, fd);
106
107
  return 0;
108
}
109
110
cvmfs_context* cvmfs_test_attach(const char *repo_name)
111
{
112
  cvmfs_context *ctx = NULL;
113
114
  RepoMap::const_iterator i = attached_repos.find(repo_name);
115
  if (i == attached_repos.end()) {
116
    std::string fqrn = std::string(repo_name) + ".cern.ch";
117
    cvmfs_option_map *repo_opts = cvmfs_options_clone(cvmfs_opts);
118
    cvmfs_options_set(repo_opts, "CVMFS_SERVER_URL",
119
      "http://cvmfs-stratum-one.cern.ch/cvmfs/@fqrn@;"
120
      "http://cernvmfs.gridpp.rl.ac.uk/cvmfs/@fqrn@;"
121
      "http://cvmfs.racf.bnl.gov/cvmfs/@fqrn@");
122
    cvmfs_options_set(repo_opts, "CVMFS_PUBLIC_KEY",
123
                      "/etc/cvmfs/keys/cern.ch/cern.ch.pub");
124
125
    char *repo_options_str = cvmfs_options_dump(repo_opts);
126
    printf("attaching repo with options:\n%s\n", repo_options_str);
127
    cvmfs_options_free(repo_options_str);
128
    cvmfs_errors retval = cvmfs_attach_repo_v2(fqrn.c_str(), repo_opts, &ctx);
129
    if (retval != LIBCVMFS_ERR_OK) {
130
      cvmfs_options_fini(repo_opts);
131
      fprintf(stderr, "couldn't initialize cvmfs!\n");
132
    } else {
133
      // Let cvmfs_detach_repo free the options_map
134
      cvmfs_adopt_options(ctx, repo_opts);
135
      attached_repos[repo_name] = ctx;
136
    }
137
  } else {
138
    printf("switching to previously attached repo: %s\n", repo_name);
139
    ctx = i->second;
140
  }
141
142
  return ctx;
143
}
144
145
void cvmfs_test_detach(const char *repo_name, const cvmfs_context *active_ctx) {
146
  RepoMap::iterator i = attached_repos.find(repo_name);
147
  if (i == attached_repos.end()) {
148
    printf("Did not find '%s' to detach\n", repo_name);
149
    return;
150
  }
151
152
  cvmfs_context *ctx = i->second;
153
  if (ctx == active_ctx) {
154
    printf("'%s' is currently active and cannot be detached.\n", repo_name);
155
    return;
156
  }
157
158
  attached_repos.erase(i);
159
  cvmfs_detach_repo(ctx);
160
}
161
162
163
int main(int argc, char *argv[])
164
{
165
  char line[TEST_LINE_MAX];
166
  char path[TEST_LINE_MAX];
167
  char repo_name[TEST_LINE_MAX];
168
169
  cvmfs_set_log_fn(cvmfs_log_ignore);
170
171
  cvmfs_opts = cvmfs_options_init();
172
  cvmfs_options_set(cvmfs_opts, "CVMFS_CACHE_DIR", "/tmp/test-libcvmfs-cache");
173
  cvmfs_options_set(cvmfs_opts, "CVMFS_HTTP_PROXY", "DIRECT");
174
175
  char *global_options_str = cvmfs_options_dump(cvmfs_opts);
176
  printf("%s: initializing with options:\n%s\n", argv[0], global_options_str);
177
  cvmfs_options_free(global_options_str);
178
  cvmfs_errors retval = cvmfs_init_v2(cvmfs_opts);
179
  if (retval != LIBCVMFS_ERR_OK) {
180
    cvmfs_options_fini(cvmfs_opts);
181
    fprintf(stderr, "couldn't initialize libcvmfs!\n");
182
    return -1;
183
  }
184
185
  cvmfs_context *ctx = NULL;
186
187
  while (1) {
188
    printf("cvmfs> ");
189
    fflush(stdout);
190
191
    if (!fgets(line, sizeof(line), stdin)) break;
192
193
    line[strlen(line)-1] = 0;
194
195
    if (sscanf(line, "list %s", path) == 1) {
196
      cvmfs_test_list(ctx, path);
197
    } else if (sscanf(line, "cat %s", path) == 1) {
198
      cvmfs_test_cat(ctx, path);
199
    } else if (sscanf(line, "attach %s", repo_name) == 1) {
200
      ctx = cvmfs_test_attach(repo_name);
201
    } else if (sscanf(line, "detach %s", repo_name) == 1) {
202
      cvmfs_test_detach(repo_name, ctx);
203
    } else if (!strcmp(line, "quit")) {
204
      break;
205
    } else {
206
      cvmfs_test_help();
207
    }
208
  }
209
210
  cvmfs_fini();
211
  cvmfs_options_fini(cvmfs_opts);
212
213
  return 0;
214
}
215