Skip to content

Commit

Permalink
-added the 'Wait' action
Browse files Browse the repository at this point in the history
  • Loading branch information
kamchatka-volcano committed Jun 24, 2023
1 parent 8454284 commit 915e42e
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 8 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ set(SRC
src/useractionformatparser.cpp
src/utils.cpp
src/writefile.cpp
src/wait.cpp
)

SealLake_Executable(
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,13 @@ The following sections are available to set up test actions:
-Write input.txt: Hello world
```

- **Wait**
The `Wait` action is used to wait for a specified amount of time by putting the thread to sleep:
```
-Wait: 500 ms
-Wait: 2 sec
```

### Configuration

An optional configuration file for `lunchtoast` uses the [`shoal`](https://shoal.eelnet.org) config format and can be
Expand Down
5 changes: 4 additions & 1 deletion src/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,10 @@ std::vector<Section> Test::readAction(
if (section.name.starts_with("Write")) {
createWriteAction(section);
return sections | views::drop(1) | ranges::to<std::vector>;
;
}
if (section.name.starts_with("Wait")) {
actions_.emplace_back(makeWaitAction(section), TestActionType::RequiredOperation);
return sections | views::drop(1) | ranges::to<std::vector>;
}
if (section.name.starts_with("Assert")) {
auto actionType = sfun::trim(sfun::after(section.name, "Assert"));
Expand Down
9 changes: 2 additions & 7 deletions src/testaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "comparefiles.h"
#include "launchprocess.h"
#include "testactiontype.h"
#include "wait.h"
#include "writefile.h"
#include <variant>

Expand Down Expand Up @@ -48,13 +49,7 @@ class TestAction {
}

private:
std::variant<
CompareFileContent,
CompareFiles,
LaunchProcess,
WriteFile>
action_;

std::variant<CompareFileContent, CompareFiles, LaunchProcess, WriteFile, Wait> action_;
TestActionType actionType_;
};

Expand Down
44 changes: 44 additions & 0 deletions src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace lunchtoast {
namespace views = ranges::views;
namespace fs = std::filesystem;
using namespace std::string_view_literals;

StringStream::StringStream(const std::string& str)
: stream_{str}
Expand Down Expand Up @@ -237,5 +238,48 @@ std::unordered_map<std::string, std::string> readInputParamSections(const std::s
result | views::take_last(1)) |
ranges::to<std::unordered_map>;
}
namespace {

bool isSecFormat(std::string_view str)
{
static const auto format = std::vector{"s"sv, "sec"sv, "seconds"sv};
return std::ranges::find(format, str) != format.end();
}

bool isMsecFormat(std::string_view str)
{
static const auto format = std::vector{"ms"sv, "msec"sv, "milliseconds"sv};
return std::ranges::find(format, str) != format.end();
}

}

std::optional<std::chrono::milliseconds> readTime(std::string_view str)
{
auto parts = sfun::split(str);
auto timePeriod = std::string{parts.at(0)};

static const auto format = std::regex{"(\\d+)([a-z]*)"};
auto match = std::smatch{};
if (!std::regex_match(timePeriod, match, format))
return std::nullopt;
const auto timeValue = std::stoi(match[1].str());

if (match.size() > 2 && match[2].length() > 0){
const auto timeFormat = match[2].str();
if (isSecFormat(timeFormat))
return std::chrono::seconds{timeValue};
else if (isMsecFormat(timeFormat))
return std::chrono::milliseconds{timeValue};
else return std::nullopt;
}

auto timeScaleParts = parts | views::drop(1);
if (std::ranges::find_if(timeScaleParts, isMsecFormat) != timeScaleParts.end())
return std::chrono::milliseconds{timeValue};
else if (std::ranges::find_if(timeScaleParts, isSecFormat) != timeScaleParts.end())
return std::chrono::seconds{timeValue};
else return std::nullopt;
}

} //namespace lunchtoast
3 changes: 3 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <string_view>
#include <unordered_map>
#include <vector>
#include <chrono>

namespace lunchtoast {

Expand All @@ -22,6 +23,8 @@ std::vector<std::string> splitCommand(const std::string& str);
std::vector<std::string> splitSectionValue(const std::string& str);
std::unordered_map<std::string, std::string> readInputParamSections(const std::string&);
std::string normalizeLineEndings(std::string_view str);
std::optional<std::chrono::milliseconds> readTime(std::string_view str);


template<typename TContainer>
requires requires(TContainer t) {
Expand Down
28 changes: 28 additions & 0 deletions src/wait.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "wait.h"
#include "errors.h"
#include "utils.h"
#include <thread>

namespace lunchtoast {

Wait::Wait(std::chrono::milliseconds timePeriod)
: timePeriod_{timePeriod}
{
}

TestActionResult Wait::operator()() const
{
std::this_thread::sleep_for(timePeriod_);
return TestActionResult::Success();
}

Wait makeWaitAction(const Section& section)
{
auto time = readTime(section.value);
if (!time.has_value())
throw TestConfigError{"Wait section value must specify time duration (e.g. '500 ms')"};

return Wait{time.value()};
}

}//namespace lunchtoast
21 changes: 21 additions & 0 deletions src/wait.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once
#include "testactionresult.h"
#include "section.h"
#include <filesystem>
#include <string>
#include <chrono>

namespace lunchtoast {

class Wait {
public:
explicit Wait(std::chrono::milliseconds timePeriod);
TestActionResult operator()() const;

private:
std::chrono::milliseconds timePeriod_;
};

Wait makeWaitAction(const Section&);

} //namespace lunchtoast
21 changes: 21 additions & 0 deletions tests/test_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <gtest/gtest.h>
#include <functional>
#include <sstream>
#include <chrono>

TEST(Utils, SplitCommand)
{
Expand Down Expand Up @@ -166,4 +167,24 @@ TEST(Utils, ReadInputParams6)
const auto sections = lunchtoast::readInputParamSections(R"()");
const auto expectedSections = std::unordered_map<std::string, std::string>{};
EXPECT_EQ(sections, expectedSections);
}

TEST(Utils, ReadTime)
{
EXPECT_EQ(lunchtoast::readTime("100msec"), std::chrono::milliseconds{100});
EXPECT_EQ(lunchtoast::readTime("100 msec"), std::chrono::milliseconds{100});
EXPECT_EQ(lunchtoast::readTime("100ms"), std::chrono::milliseconds{100});
EXPECT_EQ(lunchtoast::readTime("100 ms"), std::chrono::milliseconds{100});
EXPECT_EQ(lunchtoast::readTime("100 milliseconds"), std::chrono::milliseconds{100});

EXPECT_EQ(lunchtoast::readTime("100sec"), std::chrono::seconds{100});
EXPECT_EQ(lunchtoast::readTime("100 sec"), std::chrono::seconds{100});
EXPECT_EQ(lunchtoast::readTime("100s"), std::chrono::seconds{100});
EXPECT_EQ(lunchtoast::readTime("100 s"), std::chrono::seconds{100});
EXPECT_EQ(lunchtoast::readTime("100 seconds"), std::chrono::seconds{100});

EXPECT_FALSE(lunchtoast::readTime("seconds"));
EXPECT_FALSE(lunchtoast::readTime("foo seconds"));
EXPECT_FALSE(lunchtoast::readTime("foo"));
EXPECT_FALSE(lunchtoast::readTime("-1 sec"));
}

0 comments on commit 915e42e

Please sign in to comment.