1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "mojo/public/bindings/lib/bindings_serialization.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "mojo/public/bindings/lib/buffer.h"
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "mojo/public/tests/simple_bindings_support.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace mojo {
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace test {
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool IsZero(void* p_buf, size_t size) {
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  char* buf = reinterpret_cast<char*>(p_buf);
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (size_t i = 0; i < size; ++i) {
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (buf[i] != 0)
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Tests small and large allocations in ScratchBuffer.
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST(ScratchBufferTest, Basic) {
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SimpleBindingsSupport bindings_support;
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Test that a small allocation is placed on the stack.
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  internal::ScratchBuffer buf;
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void* small = buf.Allocate(10);
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(small >= &buf && small < (&buf + sizeof(buf)));
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(IsZero(small, 10));
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Large allocations won't be on the stack.
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void* large = buf.Allocate(100*1024);
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(IsZero(large, 100*1024));
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(large >= &buf && large < (&buf + sizeof(buf)));
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // But another small allocation should be back on the stack.
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  small = buf.Allocate(10);
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(IsZero(small, 10));
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(small >= &buf && small < (&buf + sizeof(buf)));
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Tests that Buffer::current() returns the correct value.
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST(ScratchBufferTest, Stacked) {
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SimpleBindingsSupport bindings_support;
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(Buffer::current());
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  {
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    internal::ScratchBuffer a;
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(&a, Buffer::current());
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    {
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      internal::ScratchBuffer b;
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_EQ(&b, Buffer::current());
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(Buffer::current());
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Tests that FixedBuffer allocates memory aligned to 8 byte boundaries.
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST(FixedBufferTest, Alignment) {
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SimpleBindingsSupport bindings_support;
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  internal::FixedBuffer buf(internal::Align(10) * 2);
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(buf.size(), 16u * 2);
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void* a = buf.Allocate(10);
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(a);
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(IsZero(a, 10));
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(0, reinterpret_cast<ptrdiff_t>(a) % 8);
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void* b = buf.Allocate(10);
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(b);
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(IsZero(b, 10));
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(0, reinterpret_cast<ptrdiff_t>(b) % 8);
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Any more allocations would result in an assert, but we can't test that.
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Tests that FixedBuffer::Leak passes ownership to the caller.
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST(FixedBufferTest, Leak) {
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SimpleBindingsSupport bindings_support;
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void* ptr = NULL;
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void* buf_ptr = NULL;
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  {
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    internal::FixedBuffer buf(8);
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_EQ(8u, buf.size());
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ptr = buf.Allocate(8);
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(ptr);
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    void* buf_ptr = buf.Leak();
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // The buffer should point to the first element allocated.
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TODO(mpcomplete): Is this a reasonable expectation?
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(ptr, buf_ptr);
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // The FixedBuffer should be empty now.
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(0u, buf.size());
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_FALSE(buf.Leak());
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Since we called Leak, ptr is still writable after FixedBuffer went out of
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // scope.
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  memset(ptr, 1, 8);
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  free(buf_ptr);
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace test
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace mojo
113