blob: 689258b69d9ccee9554e5d59838abb42fbfb7511 [file] [log] [blame]
// Copyright 2020 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.
#ifndef LIB_FIDL_CPP_TEST_TEST_UTIL_H_
#define LIB_FIDL_CPP_TEST_TEST_UTIL_H_
#include <lib/fidl/internal.h>
#include <cstdint>
#include <ios>
#include <iostream>
#include <gtest/gtest.h>
#include "lib/fidl/cpp/clone.h"
namespace fidl {
namespace test {
namespace util {
template <typename T>
bool cmp_payload(const T* actual, size_t actual_size, const T* expected, size_t expected_size) {
bool pass = true;
for (size_t i = 0; i < actual_size && i < expected_size; i++) {
if (actual[i] != expected[i]) {
pass = false;
std::cout << std::dec << "element[" << i << "]: " << std::hex << "actual=0x" << +actual[i]
<< " "
<< "expected=0x" << +expected[i] << "\n";
}
}
if (actual_size != expected_size) {
pass = false;
std::cout << std::dec << "element[...]: "
<< "actual.size=" << +actual_size << " "
<< "expected.size=" << +expected_size << "\n";
}
return pass;
}
template <class Output, class Input>
Output RoundTrip(const Input& input) {
fidl::Encoder encoder(fidl::Encoder::NoHeader::NO_HEADER);
auto offset = encoder.Alloc(EncodingInlineSize<Input, fidl::Encoder>(&encoder));
fidl::Clone(input).Encode(&encoder, offset);
auto msg = encoder.GetMessage();
const char* err_msg = nullptr;
EXPECT_EQ(ZX_OK, msg.Validate(Output::FidlType, &err_msg)) << err_msg;
EXPECT_EQ(ZX_OK, msg.Decode(Output::FidlType, &err_msg)) << err_msg;
fidl::Decoder decoder(std::move(msg));
Output output;
Output::Decode(&decoder, &output, 0);
return output;
}
template <class Output>
Output DecodedBytes(std::vector<uint8_t> input) {
Message message(BytePart(input.data(), input.capacity(), input.size()), HandlePart());
const char* error = nullptr;
EXPECT_EQ(ZX_OK, message.Decode(Output::FidlType, &error)) << error;
fidl::Decoder decoder(std::move(message));
Output output;
Output::Decode(&decoder, &output, 0);
return output;
}
template <class Output>
Output DecodedBytes(std::vector<uint8_t> bytes, std::vector<zx_handle_t> handles) {
Message message(BytePart(bytes.data(), bytes.capacity(), bytes.size()),
HandlePart(handles.data(), handles.capacity(), handles.size()));
const char* error = nullptr;
EXPECT_EQ(ZX_OK, message.Decode(Output::FidlType, &error)) << error;
fidl::Decoder decoder(std::move(message));
Output output;
Output::Decode(&decoder, &output, 0);
return output;
}
template <class Input>
bool ValueToBytes(const Input& input, const std::vector<uint8_t>& expected) {
fidl::Encoder enc(fidl::Encoder::NoHeader::NO_HEADER);
auto offset = enc.Alloc(EncodingInlineSize<Input, fidl::Encoder>(&enc));
fidl::Clone(input).Encode(&enc, offset);
auto msg = enc.GetMessage();
return cmp_payload(msg.bytes().data(), msg.bytes().actual(), expected.data(), expected.size());
}
template <class Input>
bool ValueToBytes(Input input, const std::vector<uint8_t>& bytes,
const std::vector<zx_handle_t>& handles) {
fidl::Encoder enc(fidl::Encoder::NoHeader::NO_HEADER);
auto offset = enc.Alloc(EncodingInlineSize<Input, fidl::Encoder>(&enc));
input.Encode(&enc, offset);
auto msg = enc.GetMessage();
auto bytes_match =
cmp_payload(msg.bytes().data(), msg.bytes().actual(), bytes.data(), bytes.size());
auto handles_match =
cmp_payload(msg.handles().data(), msg.handles().actual(), handles.data(), handles.size());
return bytes_match && handles_match;
}
template <class Output>
void CheckDecodeFailure(std::vector<uint8_t> input, std::vector<zx_handle_t> handles,
const zx_status_t expected_failure_code) {
Message message(BytePart(input.data(), input.capacity(), input.size()),
HandlePart(handles.data(), handles.capacity(), handles.size()));
const char* error = nullptr;
EXPECT_EQ(expected_failure_code, message.Decode(Output::FidlType, &error)) << error;
}
template <class Input>
void CheckEncodeFailure(const Input& input, const zx_status_t expected_failure_code) {
fidl::Encoder enc(fidl::Encoder::NoHeader::NO_HEADER);
auto offset = enc.Alloc(EncodingInlineSize<Input, fidl::Encoder>(&enc));
fidl::Clone(input).Encode(&enc, offset);
auto msg = enc.GetMessage();
const char* error = nullptr;
EXPECT_EQ(expected_failure_code, msg.Validate(Input::FidlType, &error)) << error;
}
} // namespace util
} // namespace test
} // namespace fidl
#endif // LIB_FIDL_CPP_TEST_TEST_UTIL_H_