File: auth_index_upgrade_downgrade.js

package info (click to toggle)
mongodb 1%3A2.4.10-5
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 82,464 kB
  • sloc: cpp: 740,225; ansic: 152,098; sh: 13,820; python: 11,864; makefile: 1,012; perl: 922; pascal: 617; java: 452; lisp: 222; asm: 174
file content (145 lines) | stat: -rw-r--r-- 5,943 bytes parent folder | download | duplicates (3)
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
144
145
//
// Upgrade and downgrade a MongoD node with existing system.users collections.
//
// Between 2.2 and 2.4, the schema of system.users documents expanded, and the uniqueness
// constraints changed.  As a result, the indexes on system.users collections must be replaced.
//
// Theory of operation:
//
// Running version 2.2:
//   * Construct a database, "old", and insert elements into old.system.users.
//   * Construct { user: 1 } unique index on old.system.users.
// Restart the node running version "latest":
//   * Construct a database, "new", and insert elements into new.system.users.
//   * Verify the presence of the { user: 1, userSource: 1 } unique index on new.system.users.
//   * Verify the presence of the { user: 1, userSource: 1 } unique index on old.system.users.
//   * Verify the absence of the { user: 1 } unique index on old.system.users.
//   * Verify the absence of the { user: 1 } unique index on new.system.users.
//   * Verify can insert privilege documents that would have conflicted in 2.2 into the database.
//   * Verify that the authenticate command works.
//   * Remove the conflicting entries.
// Restart the node running version 2.2:
//   * Verify that it didn't crash.
//   * Verify that the authenticate command works.
// Restart the node running version "latest":
//   * Verify that it didn't crash.
//   * Verify that the authenticate command works.
//   * Verify that the desired indexes are present.
//   * Verify can insert privilege documents that would have conflicted in 2.2 into the database.

var oldVersion = "2.2";
var newVersion = "2.4";

// Raises an exception if "status" is not a GetLastError object indicating success.
function assertGLEOK(status) {
    assert(status.ok && status.err === null,
           "Expected OK status object; found " + tojson(status));
}

// Raises an exception if "status" is not a GetLastError object indicating failure.
function assertGLENotOK(status) {
    assert(status.ok && status.err !== null,
           "Expected not-OK status object; found " + tojson(status));
}

// Finds and returns a cursor over all indexes on "collectionName" in database object "db" with
// the given "keyPattern".
function findIndex(db, collectionName, keyPattern) {
    return db.system.indexes.find({ key: keyPattern, ns: db.getName() + '.' + collectionName });
}

// Asserts that an index matching "keyPattern" is present for "collectionName" in "db".
function assertIndexExists(db, collectionName, keyPattern) {
    assert.eq(1, findIndex(db, collectionName, keyPattern).itcount());
}

// Asserts that an index matching "keyPattern" is absent for "collectionName" in "db".
function assertIndexDoesNotExist(db, collectionName, keyPattern) {
    assert.eq(0, findIndex(db, collectionName, keyPattern).itcount());
}

// Asserts that inserting "obj" into "collection" succeeds.
function assertInsertSucceeds(collection, obj) {
    collection.insert(obj);
    assertGLEOK(collection.getDB().getLastErrorObj());
}

// Asserts that inserting "obj" into "collection" fails.
function assertInsertFails(collection, obj) {
    collection.insert(obj);
    assertGLENotOK(collection.getDB().getLastErrorObj());
}

// Runs the function "action" with database objects for every database named in "dbNames", using
// "conn" as the connection object.
function withDbs(conn, dbNames, action) {
    var dbs = [];
    var i;
    for (i = 0; i < dbNames.length; ++i) {
        dbs.push(conn.getDB(dbNames[i]));
    }
    action.apply(null, dbs);
}

//
// With oldVersion
//
var conn = MongoRunner.runMongod({ remember: true, binVersion: oldVersion, smallfiles: "" });

withDbs(conn, ["old"], function (dbOld) {
    dbOld.system.users.ensureIndex({ user: 1 }, { unique: 1 });
    assertGLEOK(dbOld.getLastErrorObj());

    assertInsertSucceeds(dbOld.system.users, {user: 'andy', pwd: hex_md5('andy:mongo:a')});
    assertInsertSucceeds(dbOld.system.users, {user: 'spencer', pwd: hex_md5('spencer:mongo:a')});
    assertInsertFails(dbOld.system.users, {user: 'spencer', pwd: hex_md5('spencer:mongo:b')});
    assert(dbOld.auth('andy', 'a'));
});

//
// With newVersion
//
MongoRunner.stopMongod(conn);
conn = MongoRunner.runMongod({ restart: conn, binVersion: newVersion });
withDbs(conn, ["old", "new"], function (dbOld, dbNew) {

    assertInsertSucceeds(dbNew.system.users, {user: 'andy', pwd: hex_md5('andy:mongo:a')});
    assertInsertSucceeds(dbNew.system.users, {user: 'andy', userSource: 'old', roles: ["read"]});

    assertIndexExists(dbOld, 'system.users', { user: 1, userSource: 1 });
    assertIndexExists(dbNew, 'system.users', { user: 1, userSource: 1 });
    assertIndexDoesNotExist(dbOld, 'system.users', { user: 1 });
    assertIndexDoesNotExist(dbNew, 'system.users', { user: 1 });

    dbNew.system.users.remove({user: 'andy', userSource: 'old'});
    assert(dbNew.auth('andy', 'a'));
    assert(dbOld.auth('andy', 'a'));
});

//
// Again with oldVersion
//
MongoRunner.stopMongod(conn);
conn = MongoRunner.runMongod({ restart: conn, binVersion: oldVersion });
withDbs(conn, ["old", "new"], function (dbOld, dbNew) {
    assert.eq(1, dbNew.system.users.find({user: 'andy'}).itcount());
    assert.eq(1, dbOld.system.users.find({user: 'andy'}).itcount());
    assert(dbNew.auth('andy', 'a'));
    assert(dbOld.auth('andy', 'a'));
});


//
// Again with newVersion
//
MongoRunner.stopMongod(conn);
conn = MongoRunner.runMongod({ restart: conn, binVersion: newVersion });
withDbs(conn, ["old", "new"], function (dbOld, dbNew) {
    assert(dbNew.auth('andy', 'a'));
    assert(dbOld.auth('andy', 'a'));
    assertIndexExists(dbOld, 'system.users', { user: 1, userSource: 1 });
    assertIndexExists(dbNew, 'system.users', { user: 1, userSource: 1 });
    assertIndexDoesNotExist(dbOld, 'system.users', { user: 1 });
    assertIndexDoesNotExist(dbNew, 'system.users', { user: 1 });
    assertInsertSucceeds(dbNew.system.users, {user: 'andy', userSource: 'old', roles: ["read"]});
});