xref: /openbmc/bmcweb/test/http/server_sent_event_test.cpp (revision 40e9b92ec19acffb46f83a6e55b18974da5d708e)
1*40e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
2*40e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
38f79c5b6SEd Tanous #include "http/server_sent_event.hpp"
441fe81c2SEd Tanous #include "http_request.hpp"
58f79c5b6SEd Tanous 
6f0b59af4SEd Tanous #include <boost/asio/buffer.hpp>
7f0b59af4SEd Tanous #include <boost/asio/io_context.hpp>
88d45b9cbSEd Tanous #include <boost/asio/read.hpp>
98f79c5b6SEd Tanous #include <boost/beast/_experimental/test/stream.hpp>
108f79c5b6SEd Tanous 
11f0b59af4SEd Tanous #include <chrono>
128f79c5b6SEd Tanous #include <memory>
138f79c5b6SEd Tanous #include <string>
148f79c5b6SEd Tanous #include <string_view>
15f0b59af4SEd Tanous #include <utility>
168f79c5b6SEd Tanous 
178f79c5b6SEd Tanous #include "gtest/gtest.h"
188f79c5b6SEd Tanous namespace crow
198f79c5b6SEd Tanous {
208f79c5b6SEd Tanous namespace sse_socket
218f79c5b6SEd Tanous {
228f79c5b6SEd Tanous 
238f79c5b6SEd Tanous namespace
248f79c5b6SEd Tanous {
258f79c5b6SEd Tanous 
TEST(ServerSentEvent,SseWorks)268f79c5b6SEd Tanous TEST(ServerSentEvent, SseWorks)
278f79c5b6SEd Tanous {
288f79c5b6SEd Tanous     boost::asio::io_context io;
298f79c5b6SEd Tanous     boost::beast::test::stream stream(io);
308f79c5b6SEd Tanous     boost::beast::test::stream out(io);
318f79c5b6SEd Tanous     stream.connect(out);
328f79c5b6SEd Tanous 
33f80a87f2SEd Tanous     Request req;
34f80a87f2SEd Tanous 
358f79c5b6SEd Tanous     bool openCalled = false;
36bd79bce8SPatrick Williams     auto openHandler =
37bd79bce8SPatrick Williams         [&openCalled](Connection&, const Request& /*handedReq*/) {
38f80a87f2SEd Tanous             openCalled = true;
39f80a87f2SEd Tanous         };
408f79c5b6SEd Tanous     bool closeCalled = false;
418f79c5b6SEd Tanous     auto closeHandler = [&closeCalled](Connection&) { closeCalled = true; };
428f79c5b6SEd Tanous 
438f79c5b6SEd Tanous     std::shared_ptr<ConnectionImpl<boost::beast::test::stream>> conn =
448f79c5b6SEd Tanous         std::make_shared<ConnectionImpl<boost::beast::test::stream>>(
4593cf0ac2SEd Tanous             std::move(stream), openHandler, closeHandler);
46f80a87f2SEd Tanous     conn->start(req);
478f79c5b6SEd Tanous     // Connect
488f79c5b6SEd Tanous     {
498f79c5b6SEd Tanous         constexpr std::string_view expected =
508f79c5b6SEd Tanous             "HTTP/1.1 200 OK\r\n"
518f79c5b6SEd Tanous             "Content-Type: text/event-stream\r\n"
528f79c5b6SEd Tanous             "\r\n";
538f79c5b6SEd Tanous 
54464924caSEd Tanous         while (out.str().size() != expected.size() || !openCalled)
558f79c5b6SEd Tanous         {
568f79c5b6SEd Tanous             io.run_for(std::chrono::milliseconds(1));
578f79c5b6SEd Tanous         }
588f79c5b6SEd Tanous 
598f79c5b6SEd Tanous         std::string eventContent;
608f79c5b6SEd Tanous         eventContent.resize(expected.size());
618f79c5b6SEd Tanous         boost::asio::read(out, boost::asio::buffer(eventContent));
628f79c5b6SEd Tanous 
638f79c5b6SEd Tanous         EXPECT_EQ(eventContent, expected);
648f79c5b6SEd Tanous         EXPECT_TRUE(openCalled);
658f79c5b6SEd Tanous         EXPECT_FALSE(closeCalled);
668f79c5b6SEd Tanous         EXPECT_TRUE(out.str().empty());
678f79c5b6SEd Tanous     }
688f79c5b6SEd Tanous     // Send one event
698f79c5b6SEd Tanous     {
706d799e14SEd Tanous         conn->sendSseEvent("TestEventId", "TestEventContent");
718f79c5b6SEd Tanous         std::string_view expected = "id: TestEventId\n"
728f79c5b6SEd Tanous                                     "data: TestEventContent\n"
738f79c5b6SEd Tanous                                     "\n";
748f79c5b6SEd Tanous 
758f79c5b6SEd Tanous         while (out.str().size() < expected.size())
768f79c5b6SEd Tanous         {
778f79c5b6SEd Tanous             io.run_for(std::chrono::milliseconds(1));
788f79c5b6SEd Tanous         }
798f79c5b6SEd Tanous         EXPECT_EQ(out.str(), expected);
808f79c5b6SEd Tanous 
818f79c5b6SEd Tanous         std::string eventContent;
828f79c5b6SEd Tanous         eventContent.resize(expected.size());
838f79c5b6SEd Tanous         boost::asio::read(out, boost::asio::buffer(eventContent));
848f79c5b6SEd Tanous 
858f79c5b6SEd Tanous         EXPECT_EQ(eventContent, expected);
868f79c5b6SEd Tanous         EXPECT_TRUE(out.str().empty());
878f79c5b6SEd Tanous     }
888f79c5b6SEd Tanous     // Send second event
898f79c5b6SEd Tanous     {
906d799e14SEd Tanous         conn->sendSseEvent("TestEventId2", "TestEvent\nContent2");
91bd79bce8SPatrick Williams         constexpr std::string_view expected =
92bd79bce8SPatrick Williams             "id: TestEventId2\n"
938f79c5b6SEd Tanous             "data: TestEvent\n"
948f79c5b6SEd Tanous             "data: Content2\n"
958f79c5b6SEd Tanous             "\n";
968f79c5b6SEd Tanous 
978f79c5b6SEd Tanous         while (out.str().size() < expected.size())
988f79c5b6SEd Tanous         {
998f79c5b6SEd Tanous             io.run_for(std::chrono::milliseconds(1));
1008f79c5b6SEd Tanous         }
1018f79c5b6SEd Tanous 
1028f79c5b6SEd Tanous         std::string eventContent;
1038f79c5b6SEd Tanous         eventContent.resize(expected.size());
1048f79c5b6SEd Tanous         boost::asio::read(out, boost::asio::buffer(eventContent));
1058f79c5b6SEd Tanous         EXPECT_EQ(eventContent, expected);
1068f79c5b6SEd Tanous         EXPECT_TRUE(out.str().empty());
1078f79c5b6SEd Tanous     }
1088f79c5b6SEd Tanous     // close the remote
1098f79c5b6SEd Tanous     {
1108f79c5b6SEd Tanous         out.close();
1118f79c5b6SEd Tanous         while (!closeCalled)
1128f79c5b6SEd Tanous         {
1138f79c5b6SEd Tanous             io.run_for(std::chrono::milliseconds(1));
1148f79c5b6SEd Tanous         }
1158f79c5b6SEd Tanous     }
1168f79c5b6SEd Tanous }
1178f79c5b6SEd Tanous } // namespace
1188f79c5b6SEd Tanous 
1198f79c5b6SEd Tanous } // namespace sse_socket
1208f79c5b6SEd Tanous } // namespace crow
121