Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  TestArena.cpp   Sprache: C

 
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/
 */


#include "gtest/gtest.h"
#include "gmock/gmock.h"

#include "mozilla/gfx/IterableArena.h"
#include <string>

using namespace mozilla;
using namespace mozilla::gfx;

#ifdef A
#  undef A
#endif

#ifdef B
#  undef B
#endif

// to avoid having symbols that collide easily like A and B in the global
// namespace
namespace test_arena {

class A;
class B;

class Base {
 public:
  virtual ~Base() = default;
  virtual A* AsA() { return nullptr; }
  virtual B* AsB() { return nullptr; }
};

static int sDtorItemA = 0;
static int sDtorItemB = 0;

class A : public Base {
 public:
  virtual A* AsA() override { return this; }

  explicit A(uint64_t val) : mVal(val) {}
  ~A() { ++sDtorItemA; }

  uint64_t mVal;
};

class B : public Base {
 public:
  virtual B* AsB() override { return this; }

  explicit B(const std::string& str) : mVal(str) {}
  ~B() { ++sDtorItemB; }

  std::string mVal;
};

struct BigStruct {
  uint64_t mVal;
  uint8_t data[120];

  explicit BigStruct(uint64_t val) : mVal(val) {}
};

static void TestArenaAlloc(IterableArena::ArenaType aType) {
  sDtorItemA = 0;
  sDtorItemB = 0;
  IterableArena arena(aType, 256);

  // An empty arena has no items to iterate over.
  {
    int iterations = 0;
    arena.ForEach([&](void* item) { iterations++; });
    ASSERT_EQ(iterations, 0);
  }

  auto a1 = arena.Alloc<A>(42);
  auto b1 = arena.Alloc<B>("Obladi oblada");
  auto a2 = arena.Alloc<A>(1337);
  auto b2 = arena.Alloc<B>("Yellow submarine");
  auto b3 = arena.Alloc<B>("She's got a ticket to ride");

  // Alloc returns a non-negative offset if the allocation succeeded.
  ASSERT_TRUE(a1 >= 0);
  ASSERT_TRUE(a2 >= 0);
  ASSERT_TRUE(b1 >= 0);
  ASSERT_TRUE(b2 >= 0);
  ASSERT_TRUE(b3 >= 0);

  ASSERT_TRUE(arena.GetStorage(a1) != nullptr);
  ASSERT_TRUE(arena.GetStorage(a2) != nullptr);
  ASSERT_TRUE(arena.GetStorage(b1) != nullptr);
  ASSERT_TRUE(arena.GetStorage(b2) != nullptr);
  ASSERT_TRUE(arena.GetStorage(b3) != nullptr);

  ASSERT_TRUE(((Base*)arena.GetStorage(a1))->AsA() != nullptr);
  ASSERT_TRUE(((Base*)arena.GetStorage(a2))->AsA() != nullptr);

  ASSERT_TRUE(((Base*)arena.GetStorage(b1))->AsB() != nullptr);
  ASSERT_TRUE(((Base*)arena.GetStorage(b2))->AsB() != nullptr);
  ASSERT_TRUE(((Base*)arena.GetStorage(b3))->AsB() != nullptr);

  ASSERT_EQ(((Base*)arena.GetStorage(a1))->AsA()->mVal, (uint64_t)42);
  ASSERT_EQ(((Base*)arena.GetStorage(a2))->AsA()->mVal, (uint64_t)1337);

  ASSERT_EQ(((Base*)arena.GetStorage(b1))->AsB()->mVal,
            std::string("Obladi oblada"));
  ASSERT_EQ(((Base*)arena.GetStorage(b2))->AsB()->mVal,
            std::string("Yellow submarine"));
  ASSERT_EQ(((Base*)arena.GetStorage(b3))->AsB()->mVal,
            std::string("She's got a ticket to ride"));

  {
    int iterations = 0;
    arena.ForEach([&](void* item) { iterations++; });
    ASSERT_EQ(iterations, 5);
  }

  // Typically, running the destructors of the elements in the arena will is
  // done manually like this:
  arena.ForEach([](void* item) { ((Base*)item)->~Base(); });
  arena.Clear();
  ASSERT_EQ(sDtorItemA, 2);
  ASSERT_EQ(sDtorItemB, 3);

  // An empty arena has no items to iterate over (we just cleared it).
  {
    int iterations = 0;
    arena.ForEach([&](void* item) { iterations++; });
    ASSERT_EQ(iterations, 0);
  }
}

static void TestArenaLimit(IterableArena::ArenaType aType,
                           bool aShouldReachLimit) {
  IterableArena arena(aType, 128);

  // A non-growable arena should return a negative offset when running out
  // of space, without crashing.
  // We should not run out of space with a growable arena (unless the os is
  // running out of memory but this isn't expected for this test).
  bool reachedLimit = false;
  for (int i = 0; i < 100; ++i) {
    auto offset = arena.Alloc<A>(42);
    if (offset < 0) {
      reachedLimit = true;
      break;
    }
  }
  ASSERT_EQ(reachedLimit, aShouldReachLimit);
}

}  // namespace test_arena

using namespace test_arena;

TEST(Moz2D, FixedArena)
{
  TestArenaAlloc(IterableArena::FIXED_SIZE);
  TestArenaLimit(IterableArena::FIXED_SIZE, true);
}

TEST(Moz2D, GrowableArena)
{
  TestArenaAlloc(IterableArena::GROWABLE);
  TestArenaLimit(IterableArena::GROWABLE, false);

  IterableArena arena(IterableArena::GROWABLE, 16);
  // sizeof(BigStruct) is more than twice the initial capacity, make sure that
  // this doesn't blow everything up, since the arena doubles its storage size
  // each time it grows (until it finds a size that fits).
  auto a = arena.Alloc<BigStruct>(1);
  auto b = arena.Alloc<BigStruct>(2);
  auto c = arena.Alloc<BigStruct>(3);

  // Offsets should also still point to the appropriate values after
  // reallocation.
  ASSERT_EQ(((BigStruct*)arena.GetStorage(a))->mVal, (uint64_t)1);
  ASSERT_EQ(((BigStruct*)arena.GetStorage(b))->mVal, (uint64_t)2);
  ASSERT_EQ(((BigStruct*)arena.GetStorage(c))->mVal, (uint64_t)3);

  arena.Clear();
}

Messung V0.5
C=92 H=96 G=93

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge