1
0
Fork 0

unit testing for OSC

This commit is contained in:
Kevin Matz 2023-05-13 11:37:10 -04:00
parent 706fe5a3f9
commit 34d74375cc
2 changed files with 312 additions and 0 deletions

View File

@ -11,6 +11,7 @@ if (GTest_FOUND)
target_link_libraries(${PROJECT_NAME}
PRIVATE
GTest::gtest
LCP::OSC
LCP::RDM
LCP::UUID
LCP::sACN

311
test/test_osc.cpp Normal file
View File

@ -0,0 +1,311 @@
/*
test_osc.cpp
Copyright (c) 2023 Kevin Matz (kevin.matz@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <gtest/gtest.h>
#include <message.h>
#include <method.h>
/// \cite Spec10 First example OSC-String
const uint8_t string1_data[] = {
'O', 'S', 'C', 0x00, // OSC
};
/// \cite Spec10 Second example OSC-String
const uint8_t string2_data[] = {
'd', 'a', 't', 'a', // data
0x00, 0x00, 0x00, 0x00,
};
std::string tag1_string = ",f"; //!< \cite Spec10 First example Type Tag
std::string tag2_string = ",iisfff"; //!< \cite Spec10 Second example Type Tag
std::string tag3_string = ","; //!< \cite Spec10 Third example Type Tag
std::string tag4_string = ",ibb"; //!< \cite Spec10 Fourth example Type Tag
std::string address1_string = "/resonators/3/frequency"; //!< \cite Spec10 First example address
std::string address2_string = "/a/b/c/d/e"; //!< \cite Spec10 Second example address
/// \cite Spec10 First example Message
const uint8_t message1_data[] = {
0x2f, 0x6f, 0x73, 0x63, // /osc
0x69, 0x6c, 0x6c, 0x61, // illa
0x74, 0x6f, 0x72, 0x2f, // tor/
0x34, 0x2f, 0x66, 0x72, // 4/fr
0x65, 0x71, 0x75, 0x65, // eque
0x6e, 0x63, 0x79, 0x00, // ncy
0x2c, 0x66, 0x00, 0x00, // ,f
0x43, 0xdc, 0x00, 0x00, // 440.0
};
/// \cite Spec10 Second example Message
const uint8_t message2_data[] = {
0x2f, 0x66, 0x6f, 0x6f, // /foo
0x00, 0x00, 0x00, 0x00, //
0x2c, 0x69, 0x69, 0x73, // ,iis
0x66, 0x66, 0x00, 0x00, // ff
0x00, 0x00, 0x03, 0xe8, // 1000
0xff, 0xff, 0xff, 0xff, // -1
0x68, 0x65, 0x6c, 0x6c, // hell
0x6f, 0x00, 0x00, 0x00, // o
0x3f, 0x9d, 0xf3, 0xb6, // 1.234
0x40, 0xb5, 0xb2, 0x2d, // 5.678
};
TEST(OSC, int_in)
{
uint8_t value1_data[] = { 0x00, 0x00, 0x03, 0xe8 }; // 1000
uint8_t value2_data[] = { 0xff, 0xff, 0xff, 0xff }; // -1
auto stream1 = std::make_shared<bufferstream>(value1_data, sizeof(value1_data));
auto stream2 = std::make_shared<bufferstream>(value2_data, sizeof(value2_data));
OSC::int32 value1;
OSC::int32 value2;
value1.iStream(stream1);
value2.iStream(stream2);
EXPECT_FALSE(stream1->fail()) << "message 1 stream failed";
EXPECT_FALSE(stream2->fail()) << "message 2 stream failed";
EXPECT_EQ(value1.value, 1000) << "message 1 value mismatch";
EXPECT_EQ(value2.value, -1) << "message 2 value mismatch";
}
TEST(OSC, int_out)
{
uint8_t value1_data[] = { 0x00, 0x00, 0x03, 0xe8 }; // 1000
uint8_t value2_data[] = { 0xff, 0xff, 0xff, 0xff }; // -1
uint8_t buffer1[sizeof(value1_data)] = {0xff};
uint8_t buffer2[sizeof(value2_data)] = {0xff};
auto stream1 = std::make_shared<bufferstream>(buffer1, sizeof(buffer1));
auto stream2 = std::make_shared<bufferstream>(buffer2, sizeof(buffer2));
OSC::int32 value1(1000);
OSC::int32 value2(-1);
value1.oStream(stream1);
value2.oStream(stream2);
EXPECT_FALSE(stream1->fail()) << "value 1 stream failed";
EXPECT_FALSE(stream2->fail()) << "value 2 stream failed";
EXPECT_EQ(value1.streamSize(), sizeof(value1_data)) << "value 1 length mismatch";
EXPECT_EQ(value2.streamSize(), sizeof(value2_data)) << "value 2 length mismatch";
EXPECT_EQ(memcmp(buffer1, value1_data, sizeof(buffer1)), 0) << "value 1 output mismatch";
EXPECT_EQ(memcmp(buffer2, value2_data, sizeof(buffer2)), 0) << "value 2 output mismatch";
}
TEST(OSC, float_in)
{
uint8_t value1_data[] = { 0x3f, 0x9d, 0xf3, 0xb6 }; // 1.234
uint8_t value2_data[] = { 0x40, 0xb5, 0xb2, 0x2d }; // 5.678
auto stream1 = std::make_shared<bufferstream>(value1_data, sizeof(value1_data));
auto stream2 = std::make_shared<bufferstream>(value2_data, sizeof(value2_data));
OSC::float32 value1;
OSC::float32 value2;
value1.iStream(stream1);
value2.iStream(stream2);
EXPECT_FALSE(stream1->fail()) << "message 1 stream failed";
EXPECT_FALSE(stream2->fail()) << "message 2 stream failed";
EXPECT_FLOAT_EQ(value1.value, 1.234) << "message 1 value mismatch";
EXPECT_FLOAT_EQ(value2.value, 5.678) << "message 2 value mismatch";
}
TEST(OSC, float_out)
{
uint8_t value1_data[] = { 0x3f, 0x9d, 0xf3, 0xb6 }; // 1.234
uint8_t value2_data[] = { 0x40, 0xb5, 0xb2, 0x2d }; // 5.678
uint8_t buffer1[sizeof(value1_data)] = {0xff};
uint8_t buffer2[sizeof(value2_data)] = {0xff};
auto stream1 = std::make_shared<bufferstream>(buffer1, sizeof(buffer1));
auto stream2 = std::make_shared<bufferstream>(buffer2, sizeof(buffer2));
OSC::float32 value1((float)1.234);
OSC::float32 value2((float)5.678);
value1.oStream(stream1);
value2.oStream(stream2);
EXPECT_FALSE(stream1->fail()) << "value 1 stream failed";
EXPECT_FALSE(stream2->fail()) << "value 2 stream failed";
EXPECT_EQ(value1.streamSize(), sizeof(value1_data)) << "value 1 length mismatch";
EXPECT_EQ(value2.streamSize(), sizeof(value2_data)) << "value 2 length mismatch";
EXPECT_EQ(memcmp(buffer1, value1_data, sizeof(buffer1)), 0) << "value 1 output mismatch";
EXPECT_EQ(memcmp(buffer2, value2_data, sizeof(buffer2)), 0) << "value 2 output mismatch";
}
TEST(OSC, string_in)
{
EXPECT_FALSE(sizeof(string1_data) %4) << "string_1 data is not 32-bit aligned";
EXPECT_FALSE(sizeof(string2_data) %4) << "string_2 data is not 32-bit aligned";
OSC::string string1;
OSC::string string2;
uint8_t buffer1[sizeof(string1_data)];
uint8_t buffer2[sizeof(string2_data)];
std::copy(std::begin(string1_data),std::end(string1_data), std::begin(buffer1));
std::copy(std::begin(string2_data),std::end(string2_data), std::begin(buffer2));
auto stream1 = std::make_shared<bufferstream>(buffer1, sizeof(buffer1));
auto stream2 = std::make_shared<bufferstream>(buffer2, sizeof(buffer2));
string1.iStream(stream1);
string2.iStream(stream2);
EXPECT_FALSE(stream1->fail()) << "string 1 stream failed";
EXPECT_FALSE(stream2->fail()) << "string 2 stream failed";
EXPECT_EQ(string1.streamSize(), sizeof(string1_data)) << "string_1 data length mismatch";
EXPECT_EQ(string2.streamSize(), sizeof(string2_data)) << "string_2 data length mismatch";
EXPECT_STREQ(string1.value.c_str(), "OSC") << "string_1 value mismatch";
EXPECT_STREQ(string2.value.c_str(), "data") << "string_2 value mismatch";
}
TEST(OSC, string_out)
{
OSC::string string1;
OSC::string string2;
string1.value = "OSC";
string2.value = "data";
EXPECT_EQ(string1.streamSize(), sizeof(string1_data)) << "string_1 data length mismatch";
EXPECT_EQ(string2.streamSize(), sizeof(string2_data)) << "string_2 data length mismatch";
uint8_t buffer1[sizeof(string1_data)] = {0xff};
uint8_t buffer2[sizeof(string2_data)] = {0xff};
auto stream1 = std::make_shared<bufferstream>(buffer1, sizeof(buffer1));
auto stream2 = std::make_shared<bufferstream>(buffer2, sizeof(buffer2));
string1.oStream(stream1);
string2.oStream(stream2);
EXPECT_FALSE(stream1->fail()) << "string 1 stream failed";
EXPECT_FALSE(stream2->fail()) << "string 2 stream failed";
EXPECT_EQ(memcmp(string1_data, buffer1, sizeof(buffer1)), 0) << "string_1 output mismatch";
EXPECT_EQ(memcmp(string2_data, buffer2, sizeof(buffer2)), 0) << "string_2 output mismatch";
}
TEST(OSC, tags_in)
{
std::string tag5_string = ",f[ii[ss]]";
auto tags1 = OSC::Message::createArguments(tag1_string);
auto tags2 = OSC::Message::createArguments(tag2_string);
auto tags3 = OSC::Message::createArguments(tag3_string);
auto tags4 = OSC::Message::createArguments(tag4_string);
auto tags5 = OSC::Message::createArguments(tag5_string);
EXPECT_EQ(tags1.size(), 1) << "tag string 1: count mismatch";
EXPECT_EQ(tags2.size(), 6) << "tag string 2: count mismatch";
EXPECT_EQ(tags3.size(), 0) << "tag string 3: count mismatch";
EXPECT_EQ(tags4.size(), 3) << "tag string 4: count mismatch";
EXPECT_STREQ(tags4.back()->type().c_str(), "b") << "tag string 4: blob not matched";
EXPECT_EQ(tags5.size(), 2) << "tag string 5: count mismatch";
EXPECT_STREQ(tags5.back()->type().c_str(), "[ii[ss]]") << "tag string 5: array(s) not matched";
}
TEST(OSC, address)
{
auto *root = new OSC::Method();
EXPECT_FALSE(root->setName("\{}")) << "set invalid method name";
EXPECT_FALSE(root->setName("\[]")) << "set invalid method name";
auto *method1 = new OSC::Method(new OSC::Method(new OSC::Method(root,
"resonators"),
"3"),
"frequency");
auto *method2 = new OSC::Method(new OSC::Method(new OSC::Method(new OSC::Method(new OSC::Method(root,
"a"),
"b"),
"c"),
"d"),
"e");
EXPECT_STREQ(address1_string.c_str(), method1->address().c_str()) << "address 1 not matched";
EXPECT_STREQ(address2_string.c_str(), method2->address().c_str()) << "address 2 not matched";
delete root;
}
TEST(OSC, message_in)
{
EXPECT_FALSE(sizeof(message1_data) %4) << "message_1 data is not 32-bit aligned";
EXPECT_FALSE(sizeof(message2_data) %4) << "message_2 data is not 32-bit aligned";
OSC::Message message1;
OSC::Message message2;
uint8_t buffer1[sizeof(message1_data)];
uint8_t buffer2[sizeof(message2_data)];
std::copy(std::begin(message1_data),std::end(message1_data), std::begin(buffer1));
std::copy(std::begin(message2_data),std::end(message2_data), std::begin(buffer2));
auto stream1 = std::make_shared<bufferstream>(buffer1, sizeof(buffer1));
auto stream2 = std::make_shared<bufferstream>(buffer2, sizeof(buffer2));
message1.iStream(stream1);
message2.iStream(stream2);
EXPECT_FALSE(message1.streamSize() %4) << "Message 1 data size misaligned";
EXPECT_FALSE(message2.streamSize() %4) << "Message 2 data size misaligned";
EXPECT_EQ(message1.streamSize(), sizeof(message1_data)) << "message 1 data size mismatch";
EXPECT_EQ(message2.streamSize(), sizeof(message2_data)) << "message 2 data size mismatch";
EXPECT_FALSE(stream1->fail()) << "message 1 stream failed";
EXPECT_FALSE(stream2->fail()) << "message 2 stream failed";
EXPECT_STREQ(message1.address_pattern.c_str(), "/oscillator/4/frequency") << "message 1: address mismatch";
EXPECT_STREQ(message2.address_pattern.c_str(), "/foo") << "message 2: address mismatch";
EXPECT_STREQ(message1.type_tag().c_str(), ",f") << "message 1: type mismatch";
EXPECT_STREQ(message2.type_tag().c_str(), ",iisff") << "message 2: type mismatch";
auto arg = std::static_pointer_cast<OSC::float32>(message1.arguments.front());
EXPECT_FLOAT_EQ(arg->value, (float)440.0) << "message 1: value mismatch";
}
TEST(OSC, message_out)
{
OSC::Message message1;
message1.address_pattern = "/oscillator/4/frequency";
message1.addArgument((float)440.0);
OSC::Message message2;
message2.address_pattern = "/foo";
message2.addArgument((int)1000);
message2.addArgument((int)-1);
message2.addArgument(std::string("hello"));
message2.addArgument((float)1.234);
message2.addArgument((float)5.678);
EXPECT_FALSE(message1.streamSize() %4) << "Message 1 data size misaligned";
EXPECT_FALSE(message2.streamSize() %4) << "Message 2 data size misaligned";
EXPECT_EQ(message1.streamSize(), sizeof(message1_data)) << "message 1 data size mismatch";
EXPECT_EQ(message2.streamSize(), sizeof(message2_data)) << "message 2 data size mismatch";
EXPECT_STREQ(message1.type_tag().c_str(), ",f") << "message 1 type tag mismatch";
EXPECT_STREQ(message2.type_tag().c_str(), ",iisff") << "message 2 type tag mismatch";
uint8_t buffer1[sizeof(message1_data)];
uint8_t buffer2[sizeof(message2_data)];
auto stream1 = std::make_shared<bufferstream>(buffer1, sizeof(buffer1));
auto stream2 = std::make_shared<bufferstream>(buffer2, sizeof(buffer2));
message1.oStream(stream1);
message2.oStream(stream2);
EXPECT_FALSE(stream1->fail()) << "message 1 stream failed";
EXPECT_FALSE(stream2->fail()) << "message 2 stream failed";
EXPECT_EQ(memcmp(buffer1, message1_data, sizeof(buffer1)), 0) << "message 1 output mismatch";
EXPECT_EQ(memcmp(buffer2, message2_data, sizeof(buffer2)), 0) << "message 2 output mismatch";
}