LCOV - code coverage report
Current view: top level - tests/integration/harness/gkfs.io - write_validate.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 40 59 67.8 %
Date: 2024-04-30 13:21:35 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   Copyright 2018-2024, Barcelona Supercomputing Center (BSC), Spain
       3             :   Copyright 2015-2024, Johannes Gutenberg Universitaet Mainz, Germany
       4             : 
       5             :   This software was partially supported by the
       6             :   EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu).
       7             : 
       8             :   This software was partially supported by the
       9             :   ADA-FS project under the SPPEXA project funded by the DFG.
      10             : 
      11             :   This file is part of GekkoFS.
      12             : 
      13             :   GekkoFS is free software: you can redistribute it and/or modify
      14             :   it under the terms of the GNU General Public License as published by
      15             :   the Free Software Foundation, either version 3 of the License, or
      16             :   (at your option) any later version.
      17             : 
      18             :   GekkoFS is distributed in the hope that it will be useful,
      19             :   but WITHOUT ANY WARRANTY; without even the implied warranty of
      20             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      21             :   GNU General Public License for more details.
      22             : 
      23             :   You should have received a copy of the GNU General Public License
      24             :   along with GekkoFS.  If not, see <https://www.gnu.org/licenses/>.
      25             : 
      26             :   SPDX-License-Identifier: GPL-3.0-or-later
      27             : */
      28             : 
      29             : /* C++ includes */
      30             : #include <CLI/CLI.hpp>
      31             : #include <nlohmann/json.hpp>
      32             : #include <memory>
      33             : #include <fmt/format.h>
      34             : #include <commands.hpp>
      35             : #include <reflection.hpp>
      36             : #include <serialize.hpp>
      37             : #include <binary_buffer.hpp>
      38             : 
      39             : /* C includes */
      40             : #include <sys/types.h>
      41             : #include <sys/stat.h>
      42             : #include <fcntl.h>
      43             : #include <unistd.h>
      44             : 
      45             : using json = nlohmann::json;
      46             : 
      47         494 : struct write_validate_options {
      48             :     bool verbose{};
      49             :     std::string pathname;
      50             :     ::size_t count;
      51             : 
      52             :     REFL_DECL_STRUCT(write_validate_options, REFL_DECL_MEMBER(bool, verbose),
      53             :                      REFL_DECL_MEMBER(std::string, pathname),
      54             :                      REFL_DECL_MEMBER(::size_t, count));
      55             : };
      56             : 
      57             : struct write_validate_output {
      58             :     int retval;
      59             :     int errnum;
      60             : 
      61             :     REFL_DECL_STRUCT(write_validate_output, REFL_DECL_MEMBER(int, retval),
      62             :                      REFL_DECL_MEMBER(int, errnum));
      63             : };
      64             : 
      65             : void
      66          10 : to_json(json& record, const write_validate_output& out) {
      67          10 :     record = serialize(out);
      68          10 : }
      69             : 
      70             : void
      71          10 : write_validate_exec(const write_validate_options& opts) {
      72             : 
      73          10 :     int fd = ::open(opts.pathname.c_str(), O_WRONLY);
      74             : 
      75          10 :     if(fd == -1) {
      76           0 :         if(opts.verbose) {
      77           0 :             fmt::print(
      78             :                     "write_validate(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n",
      79           0 :                     opts.pathname, opts.count, fd, errno, ::strerror(errno));
      80           0 :             return;
      81             :         }
      82             : 
      83           0 :         json out = write_validate_output{fd, errno};
      84           0 :         fmt::print("{}\n", out.dump(2));
      85             : 
      86           0 :         return;
      87             :     }
      88             : 
      89             : 
      90          10 :     std::string data = "";
      91     7323277 :     for(::size_t i = 0; i < opts.count; i++) {
      92    14646534 :         data += char((i % 10) + '0');
      93             :     }
      94             : 
      95          10 :     io::buffer buf(data);
      96             : 
      97          10 :     auto rv = ::write(fd, buf.data(), opts.count);
      98             : 
      99          10 :     if(opts.verbose) {
     100           0 :         fmt::print(
     101             :                 "write_validate(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n",
     102           0 :                 opts.pathname, opts.count, rv, errno, ::strerror(errno));
     103          10 :         return;
     104             :     }
     105             : 
     106          10 :     if(rv < 0 or ::size_t(rv) != opts.count) {
     107           0 :         json out = write_validate_output{(int) rv, errno};
     108           0 :         fmt::print("{}\n", out.dump(2));
     109           0 :         return;
     110             :     }
     111             : 
     112             : 
     113          10 :     io::buffer bufread(opts.count);
     114             : 
     115          10 :     size_t total = 0;
     116          10 :     do {
     117          10 :         rv = ::read(fd, bufread.data(), opts.count - total);
     118          10 :         total += rv;
     119          10 :     } while(rv > 0 and total < opts.count);
     120             : 
     121          10 :     if(rv < 0 and total != opts.count) {
     122           0 :         json out = write_validate_output{(int) rv, errno};
     123           0 :         fmt::print("{}\n", out.dump(2));
     124           0 :         return;
     125             :     }
     126             : 
     127          10 :     if(memcmp(buf.data(), bufread.data(), opts.count)) {
     128          10 :         rv = 1;
     129          10 :         errno = 0;
     130          10 :         json out = write_validate_output{(int) rv, errno};
     131          10 :         fmt::print("{}\n", out.dump(2));
     132          10 :         return;
     133             :     } else {
     134           0 :         rv = 2;
     135           0 :         errno = EINVAL;
     136           0 :         json out = write_validate_output{(int) -1, errno};
     137           0 :         fmt::print("{}\n", out.dump(2));
     138             :     }
     139             : }
     140             : 
     141             : void
     142         247 : write_validate_init(CLI::App& app) {
     143             : 
     144             :     // Create the option and subcommand objects
     145         247 :     auto opts = std::make_shared<write_validate_options>();
     146         494 :     auto* cmd = app.add_subcommand(
     147             :             "write_validate",
     148         494 :             "Execute the write()-read() system call and compare the content of the buffer");
     149             : 
     150             :     // Add options to cmd, binding them to opts
     151         247 :     cmd->add_flag("-v,--verbose", opts->verbose,
     152         494 :                   "Produce human writeable output");
     153             : 
     154         494 :     cmd->add_option("pathname", opts->pathname, "Directory name")
     155             :             ->required()
     156         494 :             ->type_name("");
     157             : 
     158         494 :     cmd->add_option("count", opts->count, "Number of bytes to test")
     159             :             ->required()
     160         494 :             ->type_name("");
     161             : 
     162         998 :     cmd->callback([opts]() { write_validate_exec(*opts); });
     163         247 : }

Generated by: LCOV version 1.16