blob: 1d385e32d280e35da728597c50f64173fec2a703 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fidl/test/compatibility/cpp/fidl.h>
#include <fidl/test/imported/cpp/fidl.h>
#include <gtest/gtest.h>
#include <src/lib/fxl/test/test_settings.h>
#include <src/tests/fidl/compatibility/helpers.h>
#include <src/tests/fidl/compatibility/hlcpp_client_app.h>
using fidl::test::compatibility::Echo_EchoVectorsWithError_Result;
using fidl::test::compatibility::RespondWith;
using fidl::test::compatibility::this_is_a_struct;
using fidl::test::compatibility::this_is_a_table;
using fidl::test::compatibility::this_is_a_union;
using fidl::test::compatibility::this_is_a_xunion;
using fidl::test::compatibility::VectorsStruct;
using fidl_test_compatibility_helpers::DataGenerator;
using fidl_test_compatibility_helpers::ExtractShortName;
using fidl_test_compatibility_helpers::ForAllImpls;
using fidl_test_compatibility_helpers::GetImplsUnderTest;
using fidl_test_compatibility_helpers::HandlesEq;
using fidl_test_compatibility_helpers::Impls;
using fidl_test_compatibility_helpers::PrintSummary;
using fidl_test_compatibility_helpers::Summary;
namespace {
void InitializeVectorsStruct(VectorsStruct* value, DataGenerator& gen) {
for (uint32_t i = 0; i < fidl::test::compatibility::arrays_size; i++) {
value->bools.push_back(gen.next<bool>());
value->int8s.push_back(gen.next<int8_t>());
value->int16s.push_back(gen.next<int16_t>());
value->int32s.push_back(gen.next<int32_t>());
value->int64s.push_back(gen.next<int64_t>());
value->uint8s.push_back(gen.next<uint8_t>());
value->uint16s.push_back(gen.next<uint16_t>());
value->uint32s.push_back(gen.next<uint32_t>());
value->uint64s.push_back(gen.next<uint64_t>());
value->float32s.push_back(gen.next<float>());
value->float64s.push_back(gen.next<double>());
value->enums.push_back(gen.choose(fidl::test::compatibility::default_enum::kOne,
fidl::test::compatibility::default_enum::kZero));
value->bits.push_back(gen.choose(fidl::test::compatibility::default_bits::kOne,
fidl::test::compatibility::default_bits::kTwo));
value->handles.push_back(gen.next<zx::handle>());
value->nullable_handles.push_back(gen.next<zx::handle>(true));
value->strings.push_back(gen.next<std::string>());
value->nullable_strings.push_back(gen.next<fidl::StringPtr>());
value->structs.push_back(this_is_a_struct{});
value->structs[i].s = gen.next<std::string>();
if (gen.next<bool>()) {
value->nullable_structs.push_back(std::make_unique<this_is_a_struct>());
value->nullable_structs.back()->s = gen.next<std::string>();
}
value->unions.push_back(gen.next<this_is_a_union>());
value->nullable_unions.push_back(gen.next<std::unique_ptr<this_is_a_union>>());
value->arrays.push_back(std::array<uint32_t, fidl::test::compatibility::vectors_size>{});
value->vectors.push_back(std::vector<uint32_t>{});
for (size_t j = 0; j < fidl::test::compatibility::vectors_size; j++) {
value->arrays.back()[j] = gen.next<uint32_t>();
value->vectors.back().push_back(gen.next<uint32_t>());
}
value->nullable_vectors.push_back(fidl::VectorPtr<uint32_t>());
if (gen.next<bool>()) {
value->nullable_vectors.back().emplace();
for (size_t j = 0; j < fidl::test::compatibility::vectors_size; j++) {
value->nullable_vectors.back()->push_back(gen.next<uint32_t>());
}
} else {
value->nullable_vectors.back().reset();
}
value->tables.push_back(gen.next<this_is_a_table>());
value->xunions.push_back(gen.next<this_is_a_xunion>());
}
}
void ExpectVectorsStructEq(const VectorsStruct& a, const VectorsStruct& b) {
EXPECT_TRUE(fidl::Equals(a.bools, b.bools));
EXPECT_TRUE(fidl::Equals(a.int8s, b.int8s));
EXPECT_TRUE(fidl::Equals(a.int16s, b.int16s));
EXPECT_TRUE(fidl::Equals(a.int32s, b.int32s));
EXPECT_TRUE(fidl::Equals(a.int64s, b.int64s));
EXPECT_TRUE(fidl::Equals(a.uint8s, b.uint8s));
EXPECT_TRUE(fidl::Equals(a.uint16s, b.uint16s));
EXPECT_TRUE(fidl::Equals(a.uint32s, b.uint32s));
EXPECT_TRUE(fidl::Equals(a.uint64s, b.uint64s));
EXPECT_TRUE(fidl::Equals(a.float32s, b.float32s));
EXPECT_TRUE(fidl::Equals(a.float64s, b.float64s));
EXPECT_TRUE(fidl::Equals(a.enums, b.enums));
EXPECT_TRUE(fidl::Equals(a.bits, b.bits));
EXPECT_EQ(a.handles.size(), b.handles.size());
EXPECT_EQ(a.nullable_handles.size(), b.nullable_handles.size());
EXPECT_EQ(a.handles.size(), a.nullable_handles.size());
for (size_t i = 0; i < a.handles.size(); i++) {
EXPECT_TRUE(HandlesEq(a.handles[i], b.handles[i]));
EXPECT_TRUE(HandlesEq(a.nullable_handles[i], b.nullable_handles[i]));
}
EXPECT_TRUE(fidl::Equals(a.strings, b.strings));
EXPECT_TRUE(fidl::Equals(a.nullable_strings, b.nullable_strings));
EXPECT_TRUE(fidl::Equals(a.structs, b.structs));
EXPECT_TRUE(fidl::Equals(a.nullable_structs, b.nullable_structs));
EXPECT_TRUE(fidl::Equals(a.unions, b.unions));
EXPECT_TRUE(fidl::Equals(a.nullable_unions, b.nullable_unions));
EXPECT_TRUE(fidl::Equals(a.arrays, b.arrays));
EXPECT_TRUE(fidl::Equals(a.vectors, b.vectors));
EXPECT_TRUE(fidl::Equals(a.nullable_vectors, b.nullable_vectors));
EXPECT_TRUE(fidl::Equals(a.tables, b.tables));
EXPECT_TRUE(fidl::Equals(a.xunions, b.xunions));
}
class CompatibilityTest : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
protected:
void SetUp() override {
proxy_url_ = ::testing::get<0>(GetParam());
server_url_ = ::testing::get<1>(GetParam());
// The FIDL support lib requires async_get_default_dispatcher() to return
// non-null.
loop_.reset(new async::Loop(&kAsyncLoopConfigAttachToCurrentThread));
}
std::string proxy_url_;
std::string server_url_;
std::unique_ptr<async::Loop> loop_;
};
Impls impls;
Summary summary;
TEST(Vector, EchoVectors) {
ForAllImpls(impls, [](async::Loop& loop, fidl::test::compatibility::EchoPtr& proxy,
const std::string& server_url, const std::string& proxy_url) {
summary[ExtractShortName(proxy_url) + " <-> " + ExtractShortName(server_url) + " (vector)"] =
false;
// Using randomness to avoid having to come up with varied values by
// hand. Seed deterministically so that this function's outputs are
// predictable.
DataGenerator generator(0x1234);
VectorsStruct sent;
InitializeVectorsStruct(&sent, generator);
VectorsStruct sent_clone;
sent.Clone(&sent_clone);
VectorsStruct resp_clone;
bool called_back = false;
proxy->EchoVectors(std::move(sent), server_url,
[&loop, &resp_clone, &called_back](VectorsStruct resp) {
ASSERT_EQ(ZX_OK, resp.Clone(&resp_clone));
called_back = true;
loop.Quit();
});
loop.Run();
ASSERT_TRUE(called_back);
ExpectVectorsStructEq(sent_clone, resp_clone);
summary[ExtractShortName(proxy_url) + " <-> " + ExtractShortName(server_url) + " (vector)"] =
true;
});
}
TEST(Vector, EchoVectorsWithErrorSuccessCase) {
ForAllImpls(impls, [](async::Loop& loop, fidl::test::compatibility::EchoPtr& proxy,
const std::string& server_url, const std::string& proxy_url) {
summary[ExtractShortName(proxy_url) + " <-> " + ExtractShortName(server_url) +
" (vector result success)"] = false;
// Using randomness to avoid having to come up with varied values by
// hand. Seed deterministically so that this function's outputs are
// predictable.
DataGenerator generator(0x1234);
VectorsStruct sent;
InitializeVectorsStruct(&sent, generator);
auto err = fidl::test::compatibility::default_enum::kOne;
VectorsStruct sent_clone;
sent.Clone(&sent_clone);
VectorsStruct resp_clone;
bool called_back = false;
proxy->EchoVectorsWithError(
std::move(sent), err, server_url, RespondWith::SUCCESS,
[&loop, &resp_clone, &called_back](Echo_EchoVectorsWithError_Result resp) {
ASSERT_TRUE(resp.is_response());
ASSERT_EQ(ZX_OK, resp.response().value.Clone(&resp_clone));
called_back = true;
loop.Quit();
});
loop.Run();
ASSERT_TRUE(called_back);
ExpectVectorsStructEq(sent_clone, resp_clone);
summary[ExtractShortName(proxy_url) + " <-> " + ExtractShortName(server_url) +
" (vector result success)"] = true;
});
}
TEST(Vector, EchoVectorsWithErrorErrorCase) {
ForAllImpls(impls, [](async::Loop& loop, fidl::test::compatibility::EchoPtr& proxy,
const std::string& server_url, const std::string& proxy_url) {
summary[ExtractShortName(proxy_url) + " <-> " + ExtractShortName(server_url) +
" (vector result error)"] = false;
// Using randomness to avoid having to come up with varied values by
// hand. Seed deterministically so that this function's outputs are
// predictable.
DataGenerator generator(0xF1D7);
VectorsStruct sent;
InitializeVectorsStruct(&sent, generator);
auto err = fidl::test::compatibility::default_enum::kOne;
bool called_back = false;
proxy->EchoVectorsWithError(std::move(sent), err, server_url, RespondWith::ERR,
[&loop, &err, &called_back](Echo_EchoVectorsWithError_Result resp) {
ASSERT_TRUE(resp.is_err());
ASSERT_EQ(err, resp.err());
called_back = true;
loop.Quit();
});
loop.Run();
ASSERT_TRUE(called_back);
summary[ExtractShortName(proxy_url) + " <-> " + ExtractShortName(server_url) +
" (vector result error)"] = true;
});
}
} // namespace
int main(int argc, char** argv) {
if (!fxl::SetTestSettings(argc, argv)) {
return EXIT_FAILURE;
}
testing::InitGoogleTest(&argc, argv);
assert(GetImplsUnderTest(&impls));
int r = RUN_ALL_TESTS();
PrintSummary(summary);
return r;
}