test/Ottoman_test.cpp
author Jens Alfke <jens@mooseyard.com>
Sun Sep 20 15:14:12 2009 -0700 (2009-09-20)
changeset 0 31a43d94cc26
permissions -rw-r--r--
First official checkin.
jens@0
     1
/*
jens@0
     2
 *  Ottoman_test.cpp
jens@0
     3
 *  Ottoman
jens@0
     4
 *
jens@0
     5
 *  Created by Jens Alfke on 9/11/09.
jens@0
     6
 *  Copyright 2009 Jens Alfke. All rights reserved.
jens@0
     7
 *  BSD-Licensed: See the file "LICENSE.txt" for details.
jens@0
     8
 */
jens@0
     9
jens@0
    10
#include <gtest/gtest.h>
jens@0
    11
#include "TestUtils.h"
jens@0
    12
#include "Chunk.h"
jens@0
    13
#include "Ottoman.h"
jens@0
    14
#include "VersionDictionary.h"
jens@0
    15
#include <fcntl.h>
jens@0
    16
#include <stdio.h>
jens@0
    17
jens@0
    18
using namespace Mooseyard;
jens@0
    19
jens@0
    20
jens@0
    21
TEST(Ottoman,Build) {
jens@0
    22
    ASSERT_EQ(8, sizeof(Chunk));
jens@0
    23
    ASSERT_EQ(8, sizeof(KeyValueChunk));
jens@0
    24
        
jens@0
    25
    time_t startTime = ::time(NULL);
jens@0
    26
    time_t createTime;
jens@0
    27
    {
jens@0
    28
        Ottoman otto;
jens@0
    29
        EXPECT_EQ((void*)NULL, otto.lastVersion());
jens@0
    30
        ASSERT_NE((void*)NULL, otto.currentVersion());
jens@0
    31
        readWords();
jens@0
    32
        for( int i=0; i<sNWords; i++) {
jens@0
    33
            Blob kv(sWords[i]);
jens@0
    34
            otto.currentVersion()->put(Key(kv),kv);
jens@0
    35
        }
jens@0
    36
        Timer t("Saving Ottoman", sNWords);
jens@0
    37
        otto.saveAs("/tmp/test.ottoman");
jens@0
    38
        
jens@0
    39
        VersionDictionary *last = otto.lastVersion();
jens@0
    40
        ASSERT_NE((void*)NULL, last);
jens@0
    41
        EXPECT_EQ(sNWords, last->count());
jens@0
    42
        ASSERT_NE((void*)NULL, otto.currentVersion());
jens@0
    43
        EXPECT_FALSE(otto.currentVersion()->isChanged());
jens@0
    44
        createTime = last->timestamp();
jens@0
    45
        EXPECT_GE(createTime, startTime);
jens@0
    46
        EXPECT_LE(createTime, ::time(NULL));
jens@0
    47
    }
jens@0
    48
    {
jens@0
    49
        Ottoman otto("/tmp/test.ottoman");
jens@0
    50
        VersionDictionary *last = otto.lastVersion();
jens@0
    51
        ASSERT_NE((void*)NULL, last);
jens@0
    52
        ASSERT_EQ(0, last->generation());
jens@0
    53
        ASSERT_EQ(createTime, last->timestamp());
jens@0
    54
        {
jens@0
    55
            Timer t("Reading from Ottoman", sNWords);
jens@0
    56
            EXPECT_EQ( sNWords ,  last->count() );
jens@0
    57
            for( int i=0; i<sNWords; i++) {
jens@0
    58
                Key key(sWords[i]);
jens@0
    59
                Blob value = last->get(key);
jens@0
    60
                ASSERT_TRUE(value);
jens@0
    61
                ASSERT_TRUE( value.equals(key) ) << "expected '" << key << "', got '" << value << "' (i=" << i <<")";
jens@0
    62
            }
jens@0
    63
        }
jens@0
    64
        
jens@0
    65
        printf("Iterating through the Ottoman...\n");
jens@0
    66
        Timer t("Iterating Ottoman", sNWords);
jens@0
    67
        int n=0;
jens@0
    68
        for( VersionDictionary::Iterator it(last); it; ++it) {
jens@0
    69
            n++;
jens@0
    70
            ASSERT_TRUE(it.key().length > 0 && it.key().length < 50);
jens@0
    71
            ASSERT_TRUE(it.key().equals(it.value()));
jens@0
    72
            ASSERT_EQ( 0, ((size_t)it.value().bytes & 0x3) );  // 4-byte aligned
jens@0
    73
        }
jens@0
    74
        ASSERT_EQ(sNWords, n);
jens@0
    75
    }
jens@0
    76
    {
jens@0
    77
        printf("Opening Ottoman...\n");
jens@0
    78
        Ottoman otto("/tmp/test.ottoman");
jens@0
    79
        OverlayDictionary *current = otto.currentVersion();
jens@0
    80
        ASSERT_TRUE(current != NULL);
jens@0
    81
        EXPECT_EQ( sNWords ,  current->count() );
jens@0
    82
        EXPECT_TRUE(current->get("asparagus").equals("asparagus"));
jens@0
    83
        
jens@0
    84
        current->put("animal", "AMINAL");
jens@0
    85
        current->put("growf", "growf");
jens@0
    86
        EXPECT_TRUE(current->remove("asparagus"));
jens@0
    87
        
jens@0
    88
        EXPECT_EQ( sNWords, current->count() );
jens@0
    89
        EXPECT_TRUE(current->get("animal").equals("AMINAL"));
jens@0
    90
        EXPECT_TRUE(current->get("growf").equals("growf"));
jens@0
    91
        EXPECT_EQ( NULL, current->get("asparagus").bytes );
jens@0
    92
        EXPECT_TRUE(!current->contains("asparagus"));
jens@0
    93
        
jens@0
    94
        int n=0;
jens@0
    95
        for( OverlayDictionary::Iterator it(*current); it; ++it) {
jens@0
    96
            n++;
jens@0
    97
            ASSERT_TRUE(!it.key().equals("asparagus"));
jens@0
    98
        }
jens@0
    99
        ASSERT_EQ(sNWords, n);
jens@0
   100
        
jens@0
   101
        printf("Saving Ottoman...\n");
jens@0
   102
        {
jens@0
   103
            Timer t("Saving Ottoman");
jens@0
   104
            otto.save();
jens@0
   105
        }
jens@0
   106
        
jens@0
   107
        EXPECT_EQ( sNWords, current->count() );
jens@0
   108
        EXPECT_TRUE(current->get("animal").equals("AMINAL"));
jens@0
   109
        EXPECT_TRUE(current->get("growf").equals("growf"));
jens@0
   110
        EXPECT_EQ( NULL, current->get("asparagus").bytes );
jens@0
   111
        EXPECT_TRUE(!current->contains("asparagus"));
jens@0
   112
        
jens@0
   113
        n=0;
jens@0
   114
        for( OverlayDictionary::Iterator it(*current); it; ++it) {
jens@0
   115
            n++;
jens@0
   116
            ASSERT_TRUE(!it.key().equals("asparagus"));
jens@0
   117
        }
jens@0
   118
        ASSERT_EQ(sNWords, n);
jens@0
   119
        
jens@0
   120
        EXPECT_EQ(1, otto.lastVersion()->generation());
jens@0
   121
        const VersionDictionary *prev = otto.lastVersion()->previousVersion();
jens@0
   122
        ASSERT_TRUE(prev != NULL);
jens@0
   123
        EXPECT_EQ(0, prev->generation());
jens@0
   124
        EXPECT_TRUE(prev->get("asparagus").equals("asparagus"));
jens@0
   125
        EXPECT_TRUE(prev->get("growf").equals(NULL));
jens@0
   126
    }
jens@0
   127
    {
jens@0
   128
        printf("Re-opening Ottoman...\n");
jens@0
   129
        Ottoman otto("/tmp/test.ottoman", false);
jens@0
   130
        ASSERT_EQ(NULL, otto.currentVersion());
jens@0
   131
        VersionDictionary *last = otto.lastVersion();
jens@0
   132
        ASSERT_TRUE(last != NULL);
jens@0
   133
        EXPECT_EQ(1, last->generation());
jens@0
   134
        EXPECT_GE(last->timestamp(), createTime);
jens@0
   135
        EXPECT_LE(last->timestamp(), ::time(NULL));
jens@0
   136
        EXPECT_EQ( sNWords ,  last->count() );
jens@0
   137
        EXPECT_TRUE(last->get("animal").equals("AMINAL"));
jens@0
   138
        EXPECT_TRUE(last->get("growf").equals("growf"));
jens@0
   139
        EXPECT_EQ( NULL, last->get("asparagus").bytes );
jens@0
   140
        EXPECT_TRUE(!last->contains("asparagus"));
jens@0
   141
        
jens@0
   142
        int n=0;
jens@0
   143
        for( VersionDictionary::Iterator it(last); it; ++it) {
jens@0
   144
            n++;
jens@0
   145
            ASSERT_TRUE(!it.key().equals("asparagus"));
jens@0
   146
        }
jens@0
   147
        ASSERT_EQ(sNWords, n);
jens@0
   148
    }
jens@0
   149
    {
jens@0
   150
        printf("Writing Ottoman to a new file...\n");
jens@0
   151
        Ottoman oldhf("/tmp/test.ottoman");
jens@0
   152
        
jens@0
   153
        oldhf.saveAs("/tmp/test2.ottoman");
jens@0
   154
    }
jens@0
   155
    {
jens@0
   156
        printf("Opening new file...\n");
jens@0
   157
        Ottoman otto("/tmp/test2.ottoman");
jens@0
   158
        OverlayDictionary *current = otto.currentVersion();
jens@0
   159
        ASSERT_TRUE(current != NULL);
jens@0
   160
        
jens@0
   161
        EXPECT_EQ( sNWords ,  current->count() );
jens@0
   162
        EXPECT_TRUE(current->get("animal").equals("AMINAL"));
jens@0
   163
        EXPECT_TRUE(current->get("growf").equals("growf"));
jens@0
   164
        EXPECT_EQ( NULL, current->get("asparagus").bytes );
jens@0
   165
        EXPECT_TRUE(!current->contains("asparagus"));
jens@0
   166
        
jens@0
   167
        int n=0;
jens@0
   168
        for( OverlayDictionary::Iterator it(*current); it; ++it) {
jens@0
   169
            n++;
jens@0
   170
            ASSERT_TRUE(!it.key().equals("asparagus"));
jens@0
   171
        }
jens@0
   172
        ASSERT_EQ(sNWords, n);
jens@0
   173
jens@0
   174
        printf("Iterating the chunks...\n");
jens@0
   175
        int lastType = -1;
jens@0
   176
        int count = 0;
jens@0
   177
        n = 0;
jens@0
   178
        ChunkIterator *it = otto.chunkIterator();
jens@0
   179
        for (; *it; it->next()) {
jens@0
   180
            uint16_t type = it->chunk()->type();
jens@0
   181
            if (type != lastType) {
jens@0
   182
                if (count > 0)
jens@0
   183
                    printf("%6d\n", count);
jens@0
   184
                printf("type %u ... ", type);
jens@0
   185
                lastType = type;
jens@0
   186
                count = 0;
jens@0
   187
            }
jens@0
   188
            count++;
jens@0
   189
            ASSERT_LE(type, 3);
jens@0
   190
            if (type != 0)      // don't count padding chunks
jens@0
   191
                n++;
jens@0
   192
        }
jens@0
   193
        if (count > 0)
jens@0
   194
            printf("%6d\n", count);
jens@0
   195
        printf("Iterated over %i chunks\n",n);
jens@0
   196
        EXPECT_EQ(sNWords+256+1, n);
jens@0
   197
        EXPECT_TRUE(it->atEOF());
jens@0
   198
        
jens@0
   199
        printf("Scavenging...\n");
jens@0
   200
        EXPECT_TRUE( otto.scavenge() );
jens@0
   201
    }
jens@0
   202
}    
jens@0
   203