168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) * found in the LICENSE file.
468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) */
568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <errno.h>
768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <fcntl.h>
868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <pthread.h>
968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <stdio.h>
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <sys/ioctl.h>
1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <sys/stat.h>
1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <sys/time.h>
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "gtest/gtest.h"
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "nacl_io/fifo_char.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/socket/fifo_packet.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "nacl_io/socket/packet.h"
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ppapi_simple/ps.h"
2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)using namespace nacl_io;
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace {
2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const size_t kTestSize = 32;
268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const size_t kHalfSize = kTestSize / 2;
278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const size_t kQuarterSize = kTestSize / 4;
2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)};
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)/**
318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Test writes that start a wrapped location.  We had
328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * a bug where writes that wrapped around were fine but
338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * bytes that started at a wrapped location were being
348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * written to the wrong loction.
358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */
368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TEST(FIFOChar, WriteWrapped) {
378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  char temp_wr[kTestSize * 2];
388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  char temp_rd[kTestSize * 2];
398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  size_t wr_offs = 0;
408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  size_t rd_offs = 0;
418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  memset(temp_rd, 0, sizeof(temp_rd));
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t index = 0; index < sizeof(temp_wr); index++)
448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    temp_wr[index] = index;
458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  FIFOChar fifo(kTestSize);
478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Fill the fifo
498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  wr_offs += fifo.Write(temp_wr + wr_offs, kTestSize);
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ(kTestSize, wr_offs);
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Read 1/2 of it
538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  rd_offs += fifo.Read(temp_rd + rd_offs, kHalfSize);
548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ(kHalfSize, rd_offs);
558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Write the next two quaters.  The second
578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // of these calls to write start at a wrapped
588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // location 1/4 of the way into the fifo
598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  wr_offs += fifo.Write(temp_wr + wr_offs, kQuarterSize);
608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ(kTestSize + kQuarterSize, wr_offs);
618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  wr_offs += fifo.Write(temp_wr + wr_offs, kQuarterSize);
628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ(kTestSize + kHalfSize, wr_offs);
638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Finally read all the bytes we wrote.
658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  rd_offs += fifo.Read(temp_rd + rd_offs, kTestSize);
668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ(kTestSize + kHalfSize, rd_offs);
678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t i = 0; i < rd_offs; i++)
698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ASSERT_EQ((char)i, temp_rd[i]) << "fifo mismatch at pos:" << i;
708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST(FIFOChar, Wrap) {
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  char temp_wr[kTestSize * 2];
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  char temp_rd[kTestSize * 2];
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  size_t wr_offs = 0;
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  size_t rd_offs = 0;
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FIFOChar fifo(kTestSize);
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  memset(temp_rd, 0, sizeof(temp_rd));
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (size_t index = 0; index < sizeof(temp_wr); index++)
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    temp_wr[index] = index;
8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(fifo.IsEmpty());
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(fifo.IsFull());
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Wrap read and write differently, and verify copy is correct
8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(0, fifo.ReadAvailable());
8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(kTestSize, fifo.WriteAvailable());
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wr_offs += fifo.Write(temp_wr, kHalfSize);
9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(kHalfSize, wr_offs);
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(fifo.IsEmpty());
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(fifo.IsFull());
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  rd_offs += fifo.Read(temp_rd, kQuarterSize);
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(kQuarterSize, rd_offs);
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(fifo.IsEmpty());
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(fifo.IsFull());
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wr_offs += fifo.Write(&temp_wr[wr_offs], kTestSize);
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(kTestSize + kQuarterSize, wr_offs);
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(fifo.IsEmpty());
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  rd_offs += fifo.Read(&temp_rd[rd_offs], kTestSize);
10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(kTestSize + kQuarterSize, rd_offs);
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(fifo.IsEmpty());
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(fifo.IsFull());
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (size_t index = 0; index < kQuarterSize + kTestSize; index++)
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ((char) index, temp_rd[index]);
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST(FIFOPacket, Packets) {
11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  char temp_wr[kTestSize];
12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FIFOPacket fifo(kTestSize);
12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Packet pkt0(NULL);
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Packet pkt1(NULL);
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  pkt0.Copy(temp_wr, kHalfSize, 0);
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  pkt1.Copy(temp_wr, kTestSize, 0);
12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(fifo.IsEmpty());
12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(fifo.IsFull());
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(0, fifo.ReadAvailable());
13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(kTestSize, fifo.WriteAvailable());
13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  fifo.WritePacket(&pkt0);
13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(fifo.IsEmpty());
13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(fifo.IsFull());
13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(kHalfSize, fifo.ReadAvailable());
13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(kHalfSize, fifo.WriteAvailable());
13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  fifo.WritePacket(&pkt1);
14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(fifo.IsEmpty());
14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(fifo.IsFull());
14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(kHalfSize + kTestSize, fifo.ReadAvailable());
14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(0, fifo.WriteAvailable());
14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(&pkt0, fifo.ReadPacket());
14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(fifo.IsEmpty());
14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(fifo.IsFull());
15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(kTestSize, fifo.ReadAvailable());
15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(0, fifo.WriteAvailable());
15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(&pkt1, fifo.ReadPacket());
15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(fifo.IsEmpty());
15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(fifo.IsFull());
15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(0, fifo.ReadAvailable());
16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(kTestSize, fifo.WriteAvailable());
16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
162