blob: 7bf13128d884510f5bb02e7491913fdddadd2e24 [file] [log] [blame]
// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <memory>
#include "cobalt/websocket/web_socket_message_container.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
const char payload_filler = '?';
} // namespace
namespace cobalt {
namespace websocket {
class WebSocketMessageContainerTest : public ::testing::Test {
public:
WebSocketMessageContainerTest() {
PopulateBinaryFrame(2); // Create a final binary frame with 2 byte payload.
PopulateTextFrame();
PopulateContinuationFrame(3);
}
protected:
void PopulateBinaryFrame(int payload_size) {
net::WebSocketFrameChunk* chunk = new net::WebSocketFrameChunk();
chunk->header = std::unique_ptr<net::WebSocketFrameHeader>(
new net::WebSocketFrameHeader());
chunk->header->final = true;
chunk->header->payload_length = payload_size;
chunk->header->opcode = net::WebSocketFrameHeader::kOpCodeBinary;
chunk->data = base::WrapRefCounted<net::IOBufferWithSize>(
new net::IOBufferWithSize(payload_size));
chunk->final_chunk = true;
WebSocketFrameContainer::ErrorCode error_code =
final_binary_frame_.Take(chunk);
EXPECT_EQ(error_code, WebSocketFrameContainer::kErrorNone);
}
void PopulateTextFrame() {
net::WebSocketFrameChunk* chunk = new net::WebSocketFrameChunk();
chunk->header = std::unique_ptr<net::WebSocketFrameHeader>(
new net::WebSocketFrameHeader());
chunk->header->final = false;
chunk->header->payload_length = 0;
chunk->header->opcode = net::WebSocketFrameHeader::kOpCodeText;
chunk->final_chunk = true;
WebSocketFrameContainer::ErrorCode error_code =
nonfinal_text_frame_.Take(chunk);
EXPECT_EQ(error_code, WebSocketFrameContainer::kErrorNone);
}
void PopulateContinuationFrame(int payload_size) {
net::WebSocketFrameChunk* chunk = new net::WebSocketFrameChunk();
chunk->header = std::unique_ptr<net::WebSocketFrameHeader>(
new net::WebSocketFrameHeader());
chunk->header->final = true;
chunk->header->payload_length = payload_size;
chunk->header->opcode = net::WebSocketFrameHeader::kOpCodeContinuation;
chunk->data = base::WrapRefCounted<net::IOBufferWithSize>(
new net::IOBufferWithSize(payload_size));
net::IOBufferWithSize& data_array(*chunk->data.get());
SbMemorySet(data_array.data(), payload_filler, data_array.size());
chunk->final_chunk = true;
WebSocketFrameContainer::ErrorCode error_code =
final_continuation_frame_.Take(chunk);
EXPECT_EQ(error_code, WebSocketFrameContainer::kErrorNone);
}
WebSocketFrameContainer final_binary_frame_; // Final frame
WebSocketFrameContainer nonfinal_text_frame_; // Not a final frame.
WebSocketFrameContainer final_continuation_frame_;
WebSocketMessageContainer message_container_;
};
TEST_F(WebSocketMessageContainerTest, Construct) {
EXPECT_TRUE(message_container_.empty());
EXPECT_FALSE(message_container_.IsMessageComplete());
EXPECT_EQ(message_container_.GetCurrentPayloadSizeBytes(), 0UL);
}
TEST_F(WebSocketMessageContainerTest, Clear) {
EXPECT_TRUE(message_container_.Take(&final_binary_frame_));
message_container_.clear();
EXPECT_TRUE(message_container_.empty());
EXPECT_FALSE(message_container_.IsMessageComplete());
EXPECT_EQ(message_container_.GetCurrentPayloadSizeBytes(), 0UL);
}
TEST_F(WebSocketMessageContainerTest, GetMessageOpCode) {
net::WebSocketFrameHeader::OpCode op;
EXPECT_FALSE(message_container_.GetMessageOpCode(&op));
EXPECT_TRUE(message_container_.Take(&final_binary_frame_));
EXPECT_TRUE(message_container_.GetMessageOpCode(&op));
EXPECT_EQ(op, net::WebSocketFrameHeader::kOpCodeBinary);
}
TEST_F(WebSocketMessageContainerTest, TakeMultipleFrames) {
EXPECT_EQ(message_container_.GetFrames().size(), 0U);
EXPECT_TRUE(message_container_.Take(&nonfinal_text_frame_));
EXPECT_EQ(message_container_.GetFrames().size(), 1U);
EXPECT_TRUE(message_container_.Take(&final_continuation_frame_));
EXPECT_EQ(message_container_.GetFrames().size(), 2U);
}
TEST_F(WebSocketMessageContainerTest, IsMessageComplete) {
EXPECT_TRUE(message_container_.Take(&final_binary_frame_));
EXPECT_TRUE(message_container_.IsMessageComplete());
}
TEST_F(WebSocketMessageContainerTest, IsMessageComplete2) {
EXPECT_TRUE(message_container_.Take(&nonfinal_text_frame_));
EXPECT_FALSE(message_container_.IsMessageComplete());
EXPECT_TRUE(message_container_.Take(&final_continuation_frame_));
EXPECT_TRUE(message_container_.IsMessageComplete());
}
TEST_F(WebSocketMessageContainerTest, IsTextMessage) {
EXPECT_TRUE(message_container_.Take(&nonfinal_text_frame_));
EXPECT_TRUE(message_container_.IsTextMessage());
}
TEST_F(WebSocketMessageContainerTest, IsTextMessage2) {
EXPECT_TRUE(message_container_.Take(&final_binary_frame_));
EXPECT_FALSE(message_container_.IsTextMessage());
}
TEST_F(WebSocketMessageContainerTest, PayloadSize) {
EXPECT_EQ(message_container_.GetCurrentPayloadSizeBytes(), 0UL);
EXPECT_TRUE(message_container_.Take(&nonfinal_text_frame_));
EXPECT_EQ(message_container_.GetCurrentPayloadSizeBytes(), 0UL);
EXPECT_TRUE(message_container_.Take(&final_continuation_frame_));
EXPECT_EQ(message_container_.GetCurrentPayloadSizeBytes(), 3UL);
}
TEST_F(WebSocketMessageContainerTest, TakeStartsWithContinuationFrame) {
EXPECT_FALSE(message_container_.Take(&final_continuation_frame_));
}
TEST_F(WebSocketMessageContainerTest, GetIOBuffer) {
EXPECT_TRUE(message_container_.Take(&nonfinal_text_frame_));
EXPECT_TRUE(message_container_.Take(&final_continuation_frame_));
scoped_refptr<net::IOBufferWithSize> payload =
message_container_.GetMessageAsIOBuffer();
int payload_size = payload->size();
EXPECT_GE(payload_size, 0);
char* data = payload->data();
for (int i = 0; i != payload_size; ++i) {
DCHECK_EQ(payload_filler, data[i]);
}
}
} // namespace websocket
} // namespace cobalt