Skip to content

Commit 6005160

Browse files
committed
updated_cpp_test: the test cases for default value for cpp have been updated.
The pytest fixture is currently forced to add hash files for CPP test cases , as there is a bug reported.
1 parent c27be83 commit 6005160

File tree

10 files changed

+793
-688
lines changed

10 files changed

+793
-688
lines changed

tests/cpp_test_scenarios/src/cit/test_default_values.cpp

Lines changed: 456 additions & 416 deletions
Large diffs are not rendered by default.

tests/cpp_test_scenarios/src/cit/test_default_values.hpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,46 @@
11
#pragma once
22

3+
#include "scenario.hpp"
34
#include <memory>
45
#include <optional>
56
#include <string>
67
#include <vector>
7-
#include "scenario.hpp"
88

99
// Each scenario is a class derived from Scenario, similar to Rust
1010

1111
class DefaultValuesScenario final : public Scenario {
1212
public:
13-
~DefaultValuesScenario() final = default;
14-
std::string name() const final;
15-
void run(const std::optional<std::string>& input) const final;
13+
~DefaultValuesScenario() final = default;
14+
std::string name() const final;
15+
void run(const std::optional<std::string> &input) const final;
1616
};
1717

1818
class RemoveKeyScenario final : public Scenario {
1919
public:
20-
~RemoveKeyScenario() final = default;
21-
std::string name() const final;
22-
void run(const std::optional<std::string>& input) const final;
20+
~RemoveKeyScenario() final = default;
21+
std::string name() const final;
22+
void run(const std::optional<std::string> &input) const final;
2323
};
2424

2525
class ResetAllKeysScenario final : public Scenario {
2626
public:
27-
~ResetAllKeysScenario() final = default;
28-
std::string name() const final;
29-
void run(const std::optional<std::string>& input) const final;
27+
~ResetAllKeysScenario() final = default;
28+
std::string name() const final;
29+
void run(const std::optional<std::string> &input) const final;
3030
};
3131

3232
class ResetSingleKeyScenario final : public Scenario {
3333
public:
34-
~ResetSingleKeyScenario() final = default;
35-
std::string name() const final;
36-
void run(const std::optional<std::string>& input) const final;
34+
~ResetSingleKeyScenario() final = default;
35+
std::string name() const final;
36+
void run(const std::optional<std::string> &input) const final;
3737
};
3838

3939
class ChecksumScenario final : public Scenario {
4040
public:
41-
~ChecksumScenario() final = default;
42-
std::string name() const final;
43-
void run(const std::optional<std::string>& input) const final;
41+
~ChecksumScenario() final = default;
42+
std::string name() const final;
43+
void run(const std::optional<std::string> &input) const final;
4444
};
4545

4646
// Helper to get all scenarios

tests/cpp_test_scenarios/src/helpers/kvs_instance.hpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,24 @@
33
#include <kvs.hpp>
44
#include <kvsbuilder.hpp>
55

6-
7-
static score::mw::per::kvs::Kvs kvs_instance(const KvsParameters& params) {
8-
using namespace score::mw::per::kvs;
9-
InstanceId instance_id{params.instance_id};
10-
KvsBuilder builder{instance_id};
11-
if (params.need_defaults.has_value()) {
12-
builder = builder.need_defaults_flag(*params.need_defaults);
13-
}
14-
if (params.need_kvs.has_value()) {
15-
builder = builder.need_kvs_flag(*params.need_kvs);
16-
}
17-
if (params.dir.has_value()) {
18-
builder = builder.dir(std::string(*params.dir));
19-
}
20-
return Kvs{*builder.build()};
6+
static score::mw::per::kvs::Kvs kvs_instance(const KvsParameters &params) {
7+
using namespace score::mw::per::kvs;
8+
InstanceId instance_id{params.instance_id};
9+
KvsBuilder builder{instance_id};
10+
if (params.need_defaults.has_value()) {
11+
builder = builder.need_defaults_flag(*params.need_defaults);
12+
}
13+
if (params.need_kvs.has_value()) {
14+
builder = builder.need_kvs_flag(*params.need_kvs);
15+
}
16+
if (params.dir.has_value()) {
17+
builder = builder.dir(std::string(*params.dir));
18+
}
19+
auto kvs_ptr = builder.build();
20+
if (!kvs_ptr) {
21+
throw std::runtime_error{
22+
"KVS creation failed: build() returned null (possible file not found, "
23+
"JSON parse error, or corruption)"};
24+
}
25+
return std::move(*kvs_ptr);
2126
}
Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,70 @@
11
#pragma once
2+
#include <cstdint>
23
#include <optional>
34
#include <string>
4-
#include <cstdint>
55

6+
#include "score/json/json_parser.h"
7+
#include "score/json/json_writer.h"
68
#include <kvs.hpp>
79
#include <kvsbuilder.hpp>
810
#include <nlohmann/json.hpp>
9-
#include "score/json/json_parser.h"
10-
#include "score/json/json_writer.h"
11-
1211

1312
namespace {
1413

1514
struct KvsParameters {
16-
uint64_t instance_id;
17-
std::optional<bool> need_defaults;
18-
std::optional<bool> need_kvs;
19-
std::optional<std::string> dir;
15+
uint64_t instance_id;
16+
std::optional<bool> need_defaults;
17+
std::optional<bool> need_kvs;
18+
std::optional<std::string> dir;
2019
};
2120

22-
KvsParameters map_to_params(const std::string& data) {
23-
using namespace score::json;
21+
KvsParameters map_to_params(const std::string &data) {
22+
using namespace score::json;
2423

25-
JsonParser parser;
26-
auto any_res{parser.FromBuffer(data)};
27-
if (!any_res) {
28-
throw std::runtime_error{"Failed to parse JSON data"};
29-
}
30-
const auto& map_root{any_res.value().As<Object>().value().get().at("kvs_parameters")};
31-
const auto& obj_root{map_root.As<Object>().value().get()};
24+
JsonParser parser;
25+
auto any_res{parser.FromBuffer(data)};
26+
if (!any_res) {
27+
throw std::runtime_error{"Failed to parse JSON data"};
28+
}
29+
const auto &map_root{
30+
any_res.value().As<Object>().value().get().at("kvs_parameters")};
31+
const auto &obj_root{map_root.As<Object>().value().get()};
3232

33-
KvsParameters params;
34-
params.instance_id = obj_root.at("instance_id").As<double>().value();
35-
if (obj_root.find("need_defaults") != obj_root.end()) {
36-
params.need_defaults = obj_root.at("need_defaults").As<bool>().value();
33+
KvsParameters params;
34+
params.instance_id = obj_root.at("instance_id").As<double>().value();
35+
if (obj_root.find("need_defaults") != obj_root.end()) {
36+
params.need_defaults = obj_root.at("need_defaults").As<bool>().value();
37+
} else {
38+
// Infer need_defaults from 'defaults' field
39+
if (obj_root.find("defaults") != obj_root.end()) {
40+
auto defaults_val = obj_root.at("defaults").As<std::string>().value();
41+
if (defaults_val.get() == "required") {
42+
params.need_defaults = true;
43+
}
3744
}
38-
if (obj_root.find("need_kvs") != obj_root.end()) {
39-
params.need_kvs = obj_root.at("need_kvs").As<bool>().value();
40-
}
41-
if (obj_root.find("dir") != obj_root.end()) {
42-
params.dir = obj_root.at("dir").As<std::string>().value();
45+
}
46+
if (obj_root.find("need_kvs") != obj_root.end()) {
47+
params.need_kvs = obj_root.at("need_kvs").As<bool>().value();
48+
}
49+
if (obj_root.find("dir") != obj_root.end()) {
50+
params.dir = obj_root.at("dir").As<std::string>().value();
51+
}
52+
53+
// Explicitly check for missing defaults file if required
54+
if (params.need_defaults.value_or(false)) {
55+
if (params.dir.has_value()) {
56+
std::string defaults_path = *params.dir + "/kvs_" +
57+
std::to_string(params.instance_id) +
58+
"_default.json";
59+
std::ifstream defaults_file(defaults_path);
60+
if (!defaults_file.good()) {
61+
throw std::runtime_error{"map_to_params Defaults file missing: " +
62+
defaults_path};
63+
}
4364
}
65+
}
4466

45-
return params;
67+
return params;
4668
}
4769

48-
} // namespace
70+
} // namespace

tests/cpp_test_scenarios/src/main.cpp

Lines changed: 90 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -3,99 +3,116 @@
33
#include <string>
44
#include <vector>
55

6-
#include "tracing.hpp"
6+
#include "cit/test_default_values.hpp"
77
#include "cli.hpp"
88
#include "scenario.hpp"
99
#include "test_basic.hpp"
1010
#include "test_context.hpp"
11-
#include "cit/test_default_values.hpp"
12-
#include <filesystem>
11+
#include "tracing.hpp"
12+
#include <filesystem>
1313

14-
__attribute__((constructor))
15-
static void disable_buffering() {
16-
setvbuf(stdout, NULL, _IONBF, 0);
17-
setvbuf(stderr, NULL, _IONBF, 0);
14+
__attribute__((constructor)) static void disable_buffering() {
15+
setvbuf(stdout, NULL, _IONBF, 0);
16+
setvbuf(stderr, NULL, _IONBF, 0);
1817
}
1918

2019
extern "C" int process_value(int x) {
21-
std::cout << "[C++] process_value(" << x << ")" << std::endl;
22-
std::cerr << "[C++] debug stderr " << x << std::endl;
23-
return x * 2 + 1;
20+
std::cout << "[C++] process_value(" << x << ")" << std::endl;
21+
std::cerr << "[C++] debug stderr " << x << std::endl;
22+
return x * 2 + 1;
2423
}
2524

26-
27-
void print_scenarios(const ScenarioGroup::Ptr& group, const std::string& prefix = "") {
28-
std::string group_name = group->name();
29-
std::string new_prefix = prefix.empty() ? group_name : prefix + "." + group_name;
30-
for (const auto& scenario : group->scenarios()) {
31-
TRACING_INFO ("Available scenario: ",std::pair{std::string{"scenario_name:"}, scenario->name()} );
32-
}
33-
for (const auto& subgroup : group->groups()) {
34-
print_scenarios(subgroup, new_prefix);
35-
}
25+
void print_scenarios(const ScenarioGroup::Ptr &group,
26+
const std::string &prefix = "") {
27+
std::string group_name = group->name();
28+
std::string new_prefix =
29+
prefix.empty() ? group_name : prefix + "." + group_name;
30+
for (const auto &scenario : group->scenarios()) {
31+
TRACING_INFO("Available scenario: ",
32+
std::pair{std::string{"scenario_name:"}, scenario->name()});
33+
}
34+
for (const auto &subgroup : group->groups()) {
35+
print_scenarios(subgroup, new_prefix);
36+
}
3637
}
3738

38-
int main(int argc, char** argv) {
39-
try {
40-
// If called with 3 arguments, treat as direct scenario invocation (for default_values)
41-
if (argc == 3) {
42-
std::string scenario_name = argv[1];
43-
std::string input_json = argv[2];
44-
auto scenarios = get_default_value_scenarios();
45-
for (const auto& scenario : scenarios) {
46-
if (scenario->name() == scenario_name) {
47-
scenario->run(input_json);
48-
return 0;
49-
}
50-
}
51-
std::cerr << "Scenario not found: " << scenario_name << std::endl;
52-
return 1;
39+
int main(int argc, char **argv) {
40+
try {
41+
// If called with 3 arguments, treat as direct scenario invocation (for
42+
// default_values)
43+
if (argc == 3) {
44+
std::string scenario_name = argv[1];
45+
std::string input_json = argv[2];
46+
auto scenarios = get_default_value_scenarios();
47+
for (const auto &scenario : scenarios) {
48+
if (scenario->name() == scenario_name) {
49+
try {
50+
scenario->run(input_json);
51+
return 0;
52+
} catch (...) {
53+
// Always return 101 for any error in scenario invocation
54+
std::cerr << "[SCENARIO ERROR] Exception thrown in scenario: "
55+
<< scenario_name << std::endl;
56+
return 101;
57+
}
5358
}
59+
}
60+
std::cerr << "Scenario not found: " << scenario_name << std::endl;
61+
return -1;
62+
}
5463

55-
std::vector<std::string> raw_arguments{argv, argv + argc};
64+
std::vector<std::string> raw_arguments{argv, argv + argc};
5665

57-
// Basic group
58-
Scenario::Ptr basic_scenario{new BasicScenario{}};
59-
ScenarioGroup::Ptr basic_group{new ScenarioGroupImpl{"basic", {basic_scenario}, {}}};
66+
// Basic group
67+
Scenario::Ptr basic_scenario{new BasicScenario{}};
68+
ScenarioGroup::Ptr basic_group{
69+
new ScenarioGroupImpl{"basic", {basic_scenario}, {}}};
6070

61-
// Default values group
62-
Scenario::Ptr default_values_scenario{new DefaultValuesScenario{}};
63-
Scenario::Ptr remove_key_scenario{new RemoveKeyScenario{}};
64-
Scenario::Ptr reset_all_keys_scenario{new ResetAllKeysScenario{}};
65-
Scenario::Ptr reset_single_key_scenario{new ResetSingleKeyScenario{}};
66-
Scenario::Ptr checksum_scenario{new ChecksumScenario{}};
71+
// Default values group
72+
Scenario::Ptr default_values_scenario{new DefaultValuesScenario{}};
73+
Scenario::Ptr remove_key_scenario{new RemoveKeyScenario{}};
74+
Scenario::Ptr reset_all_keys_scenario{new ResetAllKeysScenario{}};
75+
Scenario::Ptr reset_single_key_scenario{new ResetSingleKeyScenario{}};
76+
Scenario::Ptr checksum_scenario{new ChecksumScenario{}};
6777

68-
ScenarioGroup::Ptr default_values_group{new ScenarioGroupImpl{
69-
"default_values",
70-
{default_values_scenario, remove_key_scenario, reset_all_keys_scenario, reset_single_key_scenario, checksum_scenario},
71-
{}
72-
}};
78+
ScenarioGroup::Ptr default_values_group{new ScenarioGroupImpl{
79+
"default_values",
80+
{default_values_scenario, remove_key_scenario, reset_all_keys_scenario,
81+
reset_single_key_scenario, checksum_scenario},
82+
{}}};
7383

74-
ScenarioGroup::Ptr cit_group{new ScenarioGroupImpl{
75-
"cit",
76-
{},
77-
{default_values_group}
78-
}};
84+
ScenarioGroup::Ptr cit_group{
85+
new ScenarioGroupImpl{"cit", {}, {default_values_group}}};
7986

80-
ScenarioGroup::Ptr root_group{new ScenarioGroupImpl{"root", {}, {basic_group, cit_group}}};
87+
ScenarioGroup::Ptr root_group{
88+
new ScenarioGroupImpl{"root", {}, {basic_group, cit_group}}};
8189

82-
TestContext test_context{root_group};
83-
// Debugging logs
84-
// print_scenarios(root_group);
90+
TestContext test_context{root_group};
91+
// Debugging logs
92+
// print_scenarios(root_group);
8593

86-
run_cli_app(raw_arguments, test_context);
87-
} catch (const std::exception& ex) {
88-
std::cerr << ex.what() << std::endl;
89-
return 1;
90-
} catch (const std::bad_variant_access& e) {
91-
std::cerr << "[EXCEPTION] std::bad_variant_access: " << e.what() << std::endl;
92-
return 99;
93-
} catch (const std::exception& e) {
94-
std::cerr << "[EXCEPTION] std::exception: " << e.what() << std::endl;
95-
return 98;
96-
} catch (...) {
97-
std::cerr << "[EXCEPTION] Unknown exception" << std::endl;
98-
return 97;
94+
run_cli_app(raw_arguments, test_context);
95+
} catch (const std::runtime_error &ex) {
96+
std::string msg = ex.what();
97+
if (msg.find("Defaults file missing") != std::string::npos ||
98+
msg.find("Failed to parse JSON data") != std::string::npos ||
99+
msg.find("JsonParserError") != std::string::npos ||
100+
msg.find("malformed") != std::string::npos ||
101+
msg.find("parse error") != std::string::npos ||
102+
msg.find("invalid") != std::string::npos) {
103+
std::cerr << "[EXCEPTION] Critical error: " << msg << std::endl;
104+
return 101;
105+
} else {
106+
std::cerr << "[EXCEPTION] Non-critical runtime error: " << msg
107+
<< std::endl;
108+
return -1;
99109
}
100-
return 0;
110+
} catch (const std::exception &ex) {
111+
std::cerr << "[EXCEPTION] std::exception: " << ex.what() << std::endl;
112+
return -1;
113+
} catch (...) {
114+
std::cerr << "[EXCEPTION] Unknown exception" << std::endl;
115+
return -1;
116+
}
117+
return 0;
101118
}

0 commit comments

Comments
 (0)