summaryrefslogtreecommitdiff
path: root/jstests/disk/directoryperdb.js
blob: 58940a30ff4c785d6ed9d82b947132d71962ef20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
var baseDir = 'jstests_disk_directoryper';
var baseName = 'directoryperdb';
var dbpath = MongoRunner.dataPath + baseDir + '/';
var storageEngine = "wiredTiger";

// Matches wiredTiger collection-*.wt and index-*.wt files
var dbFileMatcher = /(collection|index)-.+\.wt$/;

// Set up helper functions.
assertDocumentCount = function(db, count) {
    assert.eq(count,
              db[baseName].count(),
              'Expected ' + count + ' documents in ' + db._name + '.' + baseName + '. ' +
                  'Found: ' + tojson(db[baseName].find().toArray()));
};

/**
 * Returns the current connection which gets restarted with wiredtiger.
 */
checkDBFilesInDBDirectory = function(conn, dbToCheck) {
    MongoRunner.stopMongod(conn);
    conn = MongoRunner.runMongod({dbpath: dbpath, directoryperdb: '', restart: true});

    var dir = dbpath + dbToCheck;

    // The KV catalog escapes non alpha-numeric characters with its UTF-8 byte sequence in
    // decimal when creating the directory on disk.
    if (dbToCheck == '&') {
        dir = dbpath + '.38';
    } else if (dbToCheck == '処') {
        dir = dbpath + '.229.135.166';
    } else if (dbToCheck == Array(22).join('処')) {
        dir = dbpath + Array(22).join('.229.135.166');
    }

    files = listFiles(dir);
    var fileCount = 0;
    for (f in files) {
        if (files[f].isDirectory)
            continue;
        fileCount += 1;
        assert(dbFileMatcher.test(files[f].name),
               'In directory:' + dir + ' found unexpected file: ' + files[f].name);
    }
    assert(fileCount > 0, 'Expected more than zero nondirectory files in database directory');
    return conn;
};

/**
 * Returns the restarted connection with wiredtiger.
 */
checkDBDirectoryNonexistent = function(conn, dbToCheck) {
    MongoRunner.stopMongod(conn);
    conn = MongoRunner.runMongod({dbpath: dbpath, directoryperdb: '', restart: true});

    var files = listFiles(dbpath);
    // Check that there are no files in the toplevel dbpath.
    for (f in files) {
        if (!files[f].isDirectory) {
            assert(!dbFileMatcher.test(files[f].name),
                   'Database file' + files[f].name +
                       ' exists in dbpath after deleting all non-directoryperdb databases');
        }
    }

    // Check db directories to ensure db files in them have been destroyed.
    var dir = dbpath + dbToCheck;
    // The KV catalog escapes non alpha-numeric characters with its UTF-8 byte sequence in
    // decimal when creating the directory on disk.
    if (dbToCheck == '&') {
        dir = dbpath + '.38';
    } else if (dbToCheck == '処') {
        dir = dbpath + '.229.135.166';
    } else if (dbToCheck == Array(22).join('処')) {
        dir = dbpath + Array(22).join('.229.135.166');
    }
    var files = listFiles(dir);
    assert.eq(files.length, 0, 'Files left behind in database directory');
    return conn;
};

// Start the directoryperdb instance of mongod.
var m = MongoRunner.runMongod({storageEngine: storageEngine, dbpath: dbpath, directoryperdb: ''});
// Check that the 'local' db has allocated data.
m = checkDBFilesInDBDirectory(m, 'local');

// Create database with directoryperdb.
var dbBase = m.getDB(baseName);
dbBase[baseName].insert({});
assertDocumentCount(dbBase, 1);
m = checkDBFilesInDBDirectory(m, baseName);
dbBase = m.getDB(baseName);

// Drop a database created with directoryperdb.
assert.commandWorked(dbBase.runCommand({dropDatabase: 1}));
assertDocumentCount(dbBase, 0);
m = checkDBDirectoryNonexistent(m, baseName);
dbBase = m.getDB(baseName);

// It should be impossible to create a database named 'journal' with directoryperdb, as that
// directory exists. This test has been disabled until SERVER-2460 is resolved.
/*
db = m.getDB( 'journal' );
assert.writeError(db[ 'journal' ].insert( {} ));
*/

// Using WiredTiger, it should be impossible to create a database named 'WiredTiger' with
// directoryperdb, as that file is created by the WiredTiger storageEngine.
var dbW = m.getDB('WiredTiger');
assert.writeError(dbW[baseName].insert({}));

// Create a database named 'a' repeated 63 times.
var dbNameAA = Array(64).join('a');
var dbAA = m.getDB(dbNameAA);
assert.commandWorked(dbAA[baseName].insert({}));
assertDocumentCount(dbAA, 1);
m = checkDBFilesInDBDirectory(m, dbAA);

// Create a database named '&'.
var dbAnd = m.getDB('&');
assert.commandWorked(dbAnd[baseName].insert({}));
assertDocumentCount(dbAnd, 1);
m = checkDBFilesInDBDirectory(m, dbAnd);

// Unicode directoryperdb databases do not work on Windows.
// Disabled until https://jira.mongodb.org/browse/SERVER-16725
// is resolved.
if (!_isWindows()) {
    // Create a database named '処'.
    var dbNameU = '処';
    var dbU = m.getDB(dbNameU);
    assert.commandWorked(dbU[baseName].insert({}));
    assertDocumentCount(dbU, 1);
    m = checkDBFilesInDBDirectory(m, dbU);

    // Create a database named '処' repeated 21 times.
    var dbNameUU = Array(22).join('処');
    var dbUU = m.getDB(dbNameUU);
    assert.commandWorked(dbUU[baseName].insert({}));
    assertDocumentCount(dbUU, 1);
    m = checkDBFilesInDBDirectory(m, dbUU);
}
MongoRunner.stopMongod(m);