Home | History | Annotate | Download | only in service
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "gpu/command_buffer/service/common_decoder.h"
      6 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
      7 #include "testing/gtest/include/gtest/gtest.h"
      8 
      9 namespace gpu {
     10 
     11 TEST(CommonDecoderBucket, Basic) {
     12   CommonDecoder::Bucket bucket;
     13   EXPECT_EQ(0u, bucket.size());
     14   EXPECT_TRUE(NULL == bucket.GetData(0, 0));
     15 }
     16 
     17 TEST(CommonDecoderBucket, Size) {
     18   CommonDecoder::Bucket bucket;
     19   bucket.SetSize(24);
     20   EXPECT_EQ(24u, bucket.size());
     21   bucket.SetSize(12);
     22   EXPECT_EQ(12u, bucket.size());
     23 }
     24 
     25 TEST(CommonDecoderBucket, GetData) {
     26   CommonDecoder::Bucket bucket;
     27 
     28   bucket.SetSize(24);
     29   EXPECT_TRUE(NULL != bucket.GetData(0, 0));
     30   EXPECT_TRUE(NULL != bucket.GetData(24, 0));
     31   EXPECT_TRUE(NULL == bucket.GetData(25, 0));
     32   EXPECT_TRUE(NULL != bucket.GetData(0, 24));
     33   EXPECT_TRUE(NULL == bucket.GetData(0, 25));
     34   bucket.SetSize(23);
     35   EXPECT_TRUE(NULL == bucket.GetData(0, 24));
     36 }
     37 
     38 TEST(CommonDecoderBucket, SetData) {
     39   CommonDecoder::Bucket bucket;
     40   static const char data[] = "testing";
     41 
     42   bucket.SetSize(10);
     43   EXPECT_TRUE(bucket.SetData(data, 0, sizeof(data)));
     44   EXPECT_EQ(0, memcmp(data, bucket.GetData(0, sizeof(data)), sizeof(data)));
     45   EXPECT_TRUE(bucket.SetData(data, 2, sizeof(data)));
     46   EXPECT_EQ(0, memcmp(data, bucket.GetData(2, sizeof(data)), sizeof(data)));
     47   EXPECT_FALSE(bucket.SetData(data, 0, sizeof(data) * 2));
     48   EXPECT_FALSE(bucket.SetData(data, 5, sizeof(data)));
     49 }
     50 
     51 class TestCommonDecoder : public CommonDecoder {
     52  public:
     53   // Overridden from AsyncAPIInterface
     54   virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE {
     55     return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
     56   }
     57 
     58   // Overridden from AsyncAPIInterface
     59   virtual error::Error DoCommand(
     60       unsigned int command,
     61       unsigned int arg_count,
     62       const void* cmd_data) OVERRIDE {
     63     return DoCommonCommand(command, arg_count, cmd_data);
     64   }
     65 
     66   CommonDecoder::Bucket* GetBucket(uint32 id) const {
     67     return CommonDecoder::GetBucket(id);
     68   }
     69 };
     70 
     71 class MockCommandBufferEngine : public CommandBufferEngine {
     72  public:
     73   static const int32 kStartValidShmId = 1;
     74   static const int32 kValidShmId = 2;
     75   static const int32 kInvalidShmId = 3;
     76   static const size_t kBufferSize = 1024;
     77   static const int32 kValidOffset = kBufferSize / 2;
     78   static const int32 kInvalidOffset = kBufferSize;
     79 
     80   MockCommandBufferEngine()
     81       : CommandBufferEngine(),
     82         token_(),
     83         get_offset_(0) {
     84   }
     85 
     86   // Overridden from CommandBufferEngine.
     87   virtual Buffer GetSharedMemoryBuffer(int32 shm_id) OVERRIDE {
     88     Buffer buffer;
     89     if (IsValidSharedMemoryId(shm_id)) {
     90       buffer.ptr = buffer_;
     91       buffer.size = kBufferSize;
     92     }
     93     return buffer;
     94   }
     95 
     96   template <typename T>
     97   T GetSharedMemoryAs(uint32 offset) {
     98     DCHECK_LT(offset, kBufferSize);
     99     return reinterpret_cast<T>(&buffer_[offset]);
    100   }
    101 
    102   int32 GetSharedMemoryOffset(const void* memory) {
    103     ptrdiff_t offset = reinterpret_cast<const int8*>(memory) - &buffer_[0];
    104     DCHECK_GE(offset, 0);
    105     DCHECK_LT(static_cast<size_t>(offset), kBufferSize);
    106     return static_cast<int32>(offset);
    107   }
    108 
    109   // Overridden from CommandBufferEngine.
    110   virtual void set_token(int32 token) OVERRIDE {
    111     token_ = token;
    112   }
    113 
    114   int32 token() const {
    115     return token_;
    116   }
    117 
    118   // Overridden from CommandBufferEngine.
    119   virtual bool SetGetBuffer(int32 transfer_buffer_id) OVERRIDE {
    120     NOTREACHED();
    121     return false;
    122   }
    123 
    124   // Overridden from CommandBufferEngine.
    125   virtual bool SetGetOffset(int32 offset) OVERRIDE {
    126     if (static_cast<size_t>(offset) < kBufferSize) {
    127       get_offset_ = offset;
    128       return true;
    129     }
    130     return false;
    131   }
    132 
    133   // Overridden from CommandBufferEngine.
    134   virtual int32 GetGetOffset() OVERRIDE {
    135     return get_offset_;
    136   }
    137 
    138  private:
    139   bool IsValidSharedMemoryId(int32 shm_id) {
    140     return shm_id == kValidShmId || shm_id == kStartValidShmId;
    141   }
    142 
    143   int8 buffer_[kBufferSize];
    144   int32 token_;
    145   int32 get_offset_;
    146 };
    147 
    148 const int32 MockCommandBufferEngine::kStartValidShmId;
    149 const int32 MockCommandBufferEngine::kValidShmId;
    150 const int32 MockCommandBufferEngine::kInvalidShmId;
    151 const size_t MockCommandBufferEngine::kBufferSize;
    152 const int32 MockCommandBufferEngine::kValidOffset;
    153 const int32 MockCommandBufferEngine::kInvalidOffset;
    154 
    155 class CommonDecoderTest : public testing::Test {
    156  protected:
    157   virtual void SetUp() {
    158     decoder_.set_engine(&engine_);
    159   }
    160 
    161   virtual void TearDown() {
    162   }
    163 
    164   template <typename T>
    165   error::Error ExecuteCmd(const T& cmd) {
    166     COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed);
    167     return decoder_.DoCommand(cmd.kCmdId,
    168                               ComputeNumEntries(sizeof(cmd)) - 1,
    169                               &cmd);
    170   }
    171 
    172   template <typename T>
    173   error::Error ExecuteImmediateCmd(const T& cmd, size_t data_size) {
    174     COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
    175     return decoder_.DoCommand(cmd.kCmdId,
    176                               ComputeNumEntries(sizeof(cmd) + data_size) - 1,
    177                               &cmd);
    178   }
    179 
    180   MockCommandBufferEngine engine_;
    181   TestCommonDecoder decoder_;
    182 };
    183 
    184 TEST_F(CommonDecoderTest, Initialize) {
    185   EXPECT_EQ(0, engine_.GetGetOffset());
    186 }
    187 
    188 TEST_F(CommonDecoderTest, DoCommonCommandInvalidCommand) {
    189   EXPECT_EQ(error::kUnknownCommand, decoder_.DoCommand(999999, 0, NULL));
    190 }
    191 
    192 TEST_F(CommonDecoderTest, HandleNoop) {
    193   cmd::Noop cmd;
    194   const uint32 kSkipCount = 5;
    195   cmd.Init(kSkipCount);
    196   EXPECT_EQ(error::kNoError,
    197             ExecuteImmediateCmd(
    198                 cmd, kSkipCount * kCommandBufferEntrySize));
    199   const uint32 kSkipCount2 = 1;
    200   cmd.Init(kSkipCount2);
    201   EXPECT_EQ(error::kNoError,
    202             ExecuteImmediateCmd(
    203                 cmd, kSkipCount2 * kCommandBufferEntrySize));
    204 }
    205 
    206 TEST_F(CommonDecoderTest, SetToken) {
    207   cmd::SetToken cmd;
    208   const int32 kTokenId = 123;
    209   EXPECT_EQ(0, engine_.token());
    210   cmd.Init(kTokenId);
    211   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    212   EXPECT_EQ(kTokenId, engine_.token());
    213 }
    214 
    215 TEST_F(CommonDecoderTest, SetBucketSize) {
    216   cmd::SetBucketSize cmd;
    217   const uint32 kBucketId = 123;
    218   const uint32 kBucketLength1 = 1234;
    219   const uint32 kBucketLength2 = 78;
    220   // Check the bucket does not exist.
    221   EXPECT_TRUE(NULL == decoder_.GetBucket(kBucketId));
    222   // Check we can create one.
    223   cmd.Init(kBucketId, kBucketLength1);
    224   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    225   CommonDecoder::Bucket* bucket;
    226   bucket = decoder_.GetBucket(kBucketId);
    227   EXPECT_TRUE(NULL != bucket);
    228   EXPECT_EQ(kBucketLength1, bucket->size());
    229   // Check we can change it.
    230   cmd.Init(kBucketId, kBucketLength2);
    231   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    232   bucket = decoder_.GetBucket(kBucketId);
    233   EXPECT_TRUE(NULL != bucket);
    234   EXPECT_EQ(kBucketLength2, bucket->size());
    235   // Check we can delete it.
    236   cmd.Init(kBucketId, 0);
    237   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    238   bucket = decoder_.GetBucket(kBucketId);
    239   EXPECT_EQ(0u, bucket->size());
    240 }
    241 
    242 TEST_F(CommonDecoderTest, SetBucketData) {
    243   cmd::SetBucketSize size_cmd;
    244   cmd::SetBucketData cmd;
    245 
    246   static const char kData[] = "1234567890123456789";
    247 
    248   const uint32 kBucketId = 123;
    249   const uint32 kInvalidBucketId = 124;
    250 
    251   size_cmd.Init(kBucketId, sizeof(kData));
    252   EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd));
    253   CommonDecoder::Bucket* bucket = decoder_.GetBucket(kBucketId);
    254   // Check the data is not there.
    255   EXPECT_NE(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData)));
    256 
    257   // Check we can set it.
    258   const uint32 kSomeOffsetInSharedMemory = 50;
    259   void* memory = engine_.GetSharedMemoryAs<void*>(kSomeOffsetInSharedMemory);
    260   memcpy(memory, kData, sizeof(kData));
    261   cmd.Init(kBucketId, 0, sizeof(kData),
    262            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
    263   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    264   EXPECT_EQ(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData)));
    265 
    266   // Check we can set it partially.
    267   static const char kData2[] = "ABCEDFG";
    268   const uint32 kSomeOffsetInBucket = 5;
    269   memcpy(memory, kData2, sizeof(kData2));
    270   cmd.Init(kBucketId, kSomeOffsetInBucket, sizeof(kData2),
    271            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
    272   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    273   EXPECT_EQ(0, memcmp(bucket->GetData(kSomeOffsetInBucket, sizeof(kData2)),
    274                       kData2, sizeof(kData2)));
    275   const char* bucket_data = bucket->GetDataAs<const char*>(0, sizeof(kData));
    276   // Check that nothing was affected outside of updated area.
    277   EXPECT_EQ(kData[kSomeOffsetInBucket - 1],
    278             bucket_data[kSomeOffsetInBucket - 1]);
    279   EXPECT_EQ(kData[kSomeOffsetInBucket + sizeof(kData2)],
    280             bucket_data[kSomeOffsetInBucket + sizeof(kData2)]);
    281 
    282   // Check that it fails if the bucket_id is invalid
    283   cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData2),
    284            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
    285   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    286 
    287   // Check that it fails if the offset is out of range.
    288   cmd.Init(kBucketId, bucket->size(), 1,
    289            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
    290   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    291 
    292   // Check that it fails if the size is out of range.
    293   cmd.Init(kBucketId, 0, bucket->size() + 1,
    294            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
    295   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    296 }
    297 
    298 TEST_F(CommonDecoderTest, SetBucketDataImmediate) {
    299   cmd::SetBucketSize size_cmd;
    300   int8 buffer[1024];
    301   cmd::SetBucketDataImmediate& cmd =
    302       *reinterpret_cast<cmd::SetBucketDataImmediate*>(&buffer);
    303 
    304   static const char kData[] = "1234567890123456789";
    305 
    306   const uint32 kBucketId = 123;
    307   const uint32 kInvalidBucketId = 124;
    308 
    309   size_cmd.Init(kBucketId, sizeof(kData));
    310   EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd));
    311   CommonDecoder::Bucket* bucket = decoder_.GetBucket(kBucketId);
    312   // Check the data is not there.
    313   EXPECT_NE(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData)));
    314 
    315   // Check we can set it.
    316   void* memory = &buffer[0] + sizeof(cmd);
    317   memcpy(memory, kData, sizeof(kData));
    318   cmd.Init(kBucketId, 0, sizeof(kData));
    319   EXPECT_EQ(error::kNoError,
    320             ExecuteImmediateCmd(cmd, sizeof(kData)));
    321   EXPECT_EQ(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData)));
    322 
    323   // Check we can set it partially.
    324   static const char kData2[] = "ABCEDFG";
    325   const uint32 kSomeOffsetInBucket = 5;
    326   memcpy(memory, kData2, sizeof(kData2));
    327   cmd.Init(kBucketId, kSomeOffsetInBucket, sizeof(kData2));
    328   EXPECT_EQ(error::kNoError,
    329             ExecuteImmediateCmd(cmd, sizeof(kData2)));
    330   EXPECT_EQ(0, memcmp(bucket->GetData(kSomeOffsetInBucket, sizeof(kData2)),
    331                       kData2, sizeof(kData2)));
    332   const char* bucket_data = bucket->GetDataAs<const char*>(0, sizeof(kData));
    333   // Check that nothing was affected outside of updated area.
    334   EXPECT_EQ(kData[kSomeOffsetInBucket - 1],
    335             bucket_data[kSomeOffsetInBucket - 1]);
    336   EXPECT_EQ(kData[kSomeOffsetInBucket + sizeof(kData2)],
    337             bucket_data[kSomeOffsetInBucket + sizeof(kData2)]);
    338 
    339   // Check that it fails if the bucket_id is invalid
    340   cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData2));
    341   EXPECT_NE(error::kNoError,
    342             ExecuteImmediateCmd(cmd, sizeof(kData2)));
    343 
    344   // Check that it fails if the offset is out of range.
    345   cmd.Init(kBucketId, bucket->size(), 1);
    346   EXPECT_NE(error::kNoError,
    347             ExecuteImmediateCmd(cmd, sizeof(kData2)));
    348 
    349   // Check that it fails if the size is out of range.
    350   cmd.Init(kBucketId, 0, bucket->size() + 1);
    351   EXPECT_NE(error::kNoError,
    352             ExecuteImmediateCmd(cmd, sizeof(kData2)));
    353 }
    354 
    355 TEST_F(CommonDecoderTest, GetBucketStart) {
    356   cmd::SetBucketSize size_cmd;
    357   cmd::SetBucketData set_cmd;
    358   cmd::GetBucketStart cmd;
    359 
    360   static const char kData[] = "1234567890123456789";
    361   static const char zero[sizeof(kData)] = { 0, };
    362 
    363   const uint32 kBucketSize = sizeof(kData);
    364   const uint32 kBucketId = 123;
    365   const uint32 kInvalidBucketId = 124;
    366 
    367   // Put data in the bucket.
    368   size_cmd.Init(kBucketId, sizeof(kData));
    369   EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd));
    370   const uint32 kSomeOffsetInSharedMemory = 50;
    371   uint8* start = engine_.GetSharedMemoryAs<uint8*>(kSomeOffsetInSharedMemory);
    372   memcpy(start, kData, sizeof(kData));
    373   set_cmd.Init(kBucketId, 0, sizeof(kData),
    374                MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
    375   EXPECT_EQ(error::kNoError, ExecuteCmd(set_cmd));
    376 
    377   // Check that the size is correct with no data buffer.
    378   uint32* memory =
    379       engine_.GetSharedMemoryAs<uint32*>(kSomeOffsetInSharedMemory);
    380   *memory = 0x0;
    381   cmd.Init(kBucketId,
    382            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
    383            0, 0, 0);
    384   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    385   EXPECT_EQ(kBucketSize, *memory);
    386 
    387   // Check that the data is copied with data buffer.
    388   const uint32 kDataOffsetInSharedMemory = 54;
    389   uint8* data = engine_.GetSharedMemoryAs<uint8*>(kDataOffsetInSharedMemory);
    390   *memory = 0x0;
    391   memset(data, 0, sizeof(kData));
    392   cmd.Init(kBucketId,
    393            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
    394            kBucketSize, MockCommandBufferEngine::kValidShmId,
    395            kDataOffsetInSharedMemory);
    396   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    397   EXPECT_EQ(kBucketSize, *memory);
    398   EXPECT_EQ(0, memcmp(data, kData, kBucketSize));
    399 
    400   // Check that we can get a piece.
    401   *memory = 0x0;
    402   memset(data, 0, sizeof(kData));
    403   const uint32 kPieceSize = kBucketSize / 2;
    404   cmd.Init(kBucketId,
    405            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
    406            kPieceSize, MockCommandBufferEngine::kValidShmId,
    407            kDataOffsetInSharedMemory);
    408   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    409   EXPECT_EQ(kBucketSize, *memory);
    410   EXPECT_EQ(0, memcmp(data, kData, kPieceSize));
    411   EXPECT_EQ(0, memcmp(data + kPieceSize, zero, sizeof(kData) - kPieceSize));
    412 
    413   // Check that it fails if the result_id is invalid
    414   cmd.Init(kInvalidBucketId,
    415            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
    416            0, 0, 0);
    417   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    418 
    419   // Check that it fails if the data_id is invalid
    420   cmd.Init(kBucketId,
    421            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
    422            1, MockCommandBufferEngine::kInvalidShmId, 0);
    423   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    424 
    425   // Check that it fails if the data_size is invalid
    426   cmd.Init(kBucketId,
    427            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
    428            1, 0, 0);
    429   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    430   cmd.Init(kBucketId,
    431            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
    432            MockCommandBufferEngine::kBufferSize + 1,
    433            MockCommandBufferEngine::kValidShmId, 0);
    434   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    435 
    436   // Check that it fails if the data_offset is invalid
    437   cmd.Init(kBucketId,
    438            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
    439            0, 0, 1);
    440   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    441   cmd.Init(kBucketId,
    442            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
    443            MockCommandBufferEngine::kBufferSize,
    444            MockCommandBufferEngine::kValidShmId, 1);
    445   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    446 
    447   // Check that it fails if the result size is not set to zero
    448   *memory = 0x1;
    449   cmd.Init(kBucketId,
    450            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory,
    451            0, 0, 0);
    452   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    453 }
    454 
    455 TEST_F(CommonDecoderTest, GetBucketData) {
    456   cmd::SetBucketSize size_cmd;
    457   cmd::SetBucketData set_cmd;
    458   cmd::GetBucketData cmd;
    459 
    460   static const char kData[] = "1234567890123456789";
    461   static const char zero[sizeof(kData)] = { 0, };
    462 
    463   const uint32 kBucketId = 123;
    464   const uint32 kInvalidBucketId = 124;
    465 
    466   size_cmd.Init(kBucketId, sizeof(kData));
    467   EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd));
    468   const uint32 kSomeOffsetInSharedMemory = 50;
    469   uint8* memory = engine_.GetSharedMemoryAs<uint8*>(kSomeOffsetInSharedMemory);
    470   memcpy(memory, kData, sizeof(kData));
    471   set_cmd.Init(kBucketId, 0, sizeof(kData),
    472                MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
    473   EXPECT_EQ(error::kNoError, ExecuteCmd(set_cmd));
    474 
    475   // Check we can get the whole thing.
    476   memset(memory, 0, sizeof(kData));
    477   cmd.Init(kBucketId, 0, sizeof(kData),
    478            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
    479   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    480   EXPECT_EQ(0, memcmp(memory, kData, sizeof(kData)));
    481 
    482   // Check we can get a piece.
    483   const uint32 kSomeOffsetInBucket = 5;
    484   const uint32 kLengthOfPiece = 6;
    485   const uint8 kSentinel = 0xff;
    486   memset(memory, 0, sizeof(kData));
    487   memory[-1] = kSentinel;
    488   cmd.Init(kBucketId, kSomeOffsetInBucket, kLengthOfPiece,
    489            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
    490   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
    491   EXPECT_EQ(0, memcmp(memory, kData + kSomeOffsetInBucket, kLengthOfPiece));
    492   EXPECT_EQ(0, memcmp(memory + kLengthOfPiece, zero,
    493                       sizeof(kData) - kLengthOfPiece));
    494   EXPECT_EQ(kSentinel, memory[-1]);
    495 
    496   // Check that it fails if the bucket_id is invalid
    497   cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData),
    498            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
    499   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    500 
    501   // Check that it fails if the offset is invalid
    502   cmd.Init(kBucketId, sizeof(kData) + 1, 1,
    503            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
    504   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    505 
    506   // Check that it fails if the size is invalid
    507   cmd.Init(kBucketId, 0, sizeof(kData) + 1,
    508            MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory);
    509   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
    510 }
    511 
    512 }  // namespace gpu
    513