blob: 18d9545dce8be7541e0cc8f7d00df2c29fc4c863 [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
Ed Tanous8f79c5b2024-01-30 15:56:37 -08003#include "http/server_sent_event.hpp"
Ed Tanouse60300a2025-02-23 12:31:53 -08004#include "http/server_sent_event_impl.hpp"
Ed Tanous41fe81c2024-09-02 15:08:41 -07005#include "http_request.hpp"
Ed Tanous796ba932020-08-02 04:29:21 +00006#include "test_stream.hpp"
Ed Tanous8f79c5b2024-01-30 15:56:37 -08007
Ed Tanousf0b59af2024-03-20 13:38:04 -07008#include <boost/asio/buffer.hpp>
9#include <boost/asio/io_context.hpp>
Ed Tanous8d45b9c2024-04-08 17:50:10 -070010#include <boost/asio/read.hpp>
Ed Tanous8f79c5b2024-01-30 15:56:37 -080011
Ed Tanousf0b59af2024-03-20 13:38:04 -070012#include <chrono>
Ed Tanous8f79c5b2024-01-30 15:56:37 -080013#include <memory>
14#include <string>
15#include <string_view>
Ed Tanousf0b59af2024-03-20 13:38:04 -070016#include <utility>
Ed Tanous8f79c5b2024-01-30 15:56:37 -080017
18#include "gtest/gtest.h"
19namespace crow
20{
21namespace sse_socket
22{
23
24namespace
25{
26
27TEST(ServerSentEvent, SseWorks)
28{
29 boost::asio::io_context io;
Ed Tanous796ba932020-08-02 04:29:21 +000030 TestStream stream(io);
31 TestStream out(io);
Ed Tanous8f79c5b2024-01-30 15:56:37 -080032 stream.connect(out);
33
Ed Tanousf80a87f2024-06-16 12:10:33 -070034 Request req;
35
Ed Tanous8f79c5b2024-01-30 15:56:37 -080036 bool openCalled = false;
Patrick Williamsbd79bce2024-08-16 15:22:20 -040037 auto openHandler =
38 [&openCalled](Connection&, const Request& /*handedReq*/) {
39 openCalled = true;
40 };
Ed Tanous8f79c5b2024-01-30 15:56:37 -080041 bool closeCalled = false;
42 auto closeHandler = [&closeCalled](Connection&) { closeCalled = true; };
43
Ed Tanous796ba932020-08-02 04:29:21 +000044 std::shared_ptr<ConnectionImpl<TestStream>> conn =
45 std::make_shared<ConnectionImpl<TestStream>>(std::move(stream),
46 openHandler, closeHandler);
Ed Tanousf80a87f2024-06-16 12:10:33 -070047 conn->start(req);
Ed Tanous8f79c5b2024-01-30 15:56:37 -080048 // Connect
49 {
50 constexpr std::string_view expected =
51 "HTTP/1.1 200 OK\r\n"
52 "Content-Type: text/event-stream\r\n"
53 "\r\n";
54
Ed Tanous464924c2024-12-20 14:49:45 -080055 while (out.str().size() != expected.size() || !openCalled)
Ed Tanous8f79c5b2024-01-30 15:56:37 -080056 {
57 io.run_for(std::chrono::milliseconds(1));
58 }
59
60 std::string eventContent;
61 eventContent.resize(expected.size());
62 boost::asio::read(out, boost::asio::buffer(eventContent));
63
64 EXPECT_EQ(eventContent, expected);
65 EXPECT_TRUE(openCalled);
66 EXPECT_FALSE(closeCalled);
67 EXPECT_TRUE(out.str().empty());
68 }
69 // Send one event
70 {
Ed Tanous6d799e12024-09-11 14:33:37 -070071 conn->sendSseEvent("TestEventId", "TestEventContent");
Ed Tanous8f79c5b2024-01-30 15:56:37 -080072 std::string_view expected = "id: TestEventId\n"
73 "data: TestEventContent\n"
74 "\n";
75
76 while (out.str().size() < expected.size())
77 {
78 io.run_for(std::chrono::milliseconds(1));
79 }
80 EXPECT_EQ(out.str(), expected);
81
82 std::string eventContent;
83 eventContent.resize(expected.size());
84 boost::asio::read(out, boost::asio::buffer(eventContent));
85
86 EXPECT_EQ(eventContent, expected);
87 EXPECT_TRUE(out.str().empty());
88 }
89 // Send second event
90 {
Ed Tanous6d799e12024-09-11 14:33:37 -070091 conn->sendSseEvent("TestEventId2", "TestEvent\nContent2");
Patrick Williamsbd79bce2024-08-16 15:22:20 -040092 constexpr std::string_view expected =
93 "id: TestEventId2\n"
94 "data: TestEvent\n"
95 "data: Content2\n"
96 "\n";
Ed Tanous8f79c5b2024-01-30 15:56:37 -080097
98 while (out.str().size() < expected.size())
99 {
100 io.run_for(std::chrono::milliseconds(1));
101 }
102
103 std::string eventContent;
104 eventContent.resize(expected.size());
105 boost::asio::read(out, boost::asio::buffer(eventContent));
106 EXPECT_EQ(eventContent, expected);
107 EXPECT_TRUE(out.str().empty());
108 }
109 // close the remote
110 {
111 out.close();
112 while (!closeCalled)
113 {
114 io.run_for(std::chrono::milliseconds(1));
115 }
116 }
117}
118} // namespace
119
120} // namespace sse_socket
121} // namespace crow