~pbeaman/akiban-persistit/find-deadlock3

« back to all changes in this revision

Viewing changes to src/test/java/com/persistit/stress/unit/AccumulatorRestart.java.moved

  • Committer: Peter Beaman
  • Date: 2012-11-18 16:34:21 UTC
  • Revision ID: pbeaman@akiban.com-20121118163421-gg8zypbv0k26d8je
Remove .moved files

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * Copyright © 2005-2012 Akiban Technologies, Inc.  All rights reserved.
3
 
 * 
4
 
 * This program and the accompanying materials are made available
5
 
 * under the terms of the Eclipse Public License v1.0 which
6
 
 * accompanies this distribution, and is available at
7
 
 * http://www.eclipse.org/legal/epl-v10.html
8
 
 * 
9
 
 * This program may also be available under different license terms.
10
 
 * For more information, see www.akiban.com or contact licensing@akiban.com.
11
 
 * 
12
 
 * Contributors:
13
 
 * Akiban Technologies, Inc.
14
 
 */
15
 
 
16
 
package com.persistit.stress.unit;
17
 
 
18
 
import java.rmi.RemoteException;
19
 
import java.util.Random;
20
 
 
21
 
import javax.management.ObjectName;
22
 
 
23
 
import com.persistit.Accumulator;
24
 
import com.persistit.Configuration;
25
 
import com.persistit.Exchange;
26
 
import com.persistit.Persistit;
27
 
import com.persistit.Transaction;
28
 
import com.persistit.exception.PersistitException;
29
 
import com.persistit.mxbeans.CheckpointManagerMXBean;
30
 
import com.persistit.util.ArgParser;
31
 
import com.persistit.util.Util;
32
 
 
33
 
/**
34
 
 * Tests Accumulator values after restart. This test modifies accumulators and
35
 
 * then restarts Persistit, both gracefully and after failure, to verify that
36
 
 * the recovered Accumulator values are always correct. The test specifically
37
 
 * attempts to test the juxtaposition of a Checkpoint and the final Accumulator
38
 
 * update to look for bugs similar to 1064565.
39
 
 * 
40
 
 * @author peter
41
 
 * 
42
 
 */
43
 
public class AccumulatorRestart extends StressBase {
44
 
    final static Random RANDOM = new Random();
45
 
 
46
 
    private final static String[] ARGS_TEMPLATE = { "repeat|int:1:0:1000000000|Repetitions" };
47
 
 
48
 
    public final static long CHECKPOINT_INTERVAL = 30;
49
 
 
50
 
    long _checkpointTimestamp = 0;
51
 
    long _checkpointTime = 0;
52
 
 
53
 
    public AccumulatorRestart(final String argsString) {
54
 
        super(argsString);
55
 
    }
56
 
 
57
 
    @Override
58
 
    public void setUp() throws Exception {
59
 
        super.setUp();
60
 
        _ap = new ArgParser("com.persistit.Stress1", _args, ARGS_TEMPLATE).strict();
61
 
        _repeatTotal = _ap.getIntValue("repeat");
62
 
    }
63
 
 
64
 
    @Override
65
 
    public void executeTest() {
66
 
        /*
67
 
         * Local copies, managed by this thread for comparison
68
 
         */
69
 
        long minValue = 0;
70
 
        long maxValue = 0;
71
 
        long sumValue = 0;
72
 
        long seqValue = 0;
73
 
 
74
 
        for (_count = 1;; _count++) {
75
 
            try {
76
 
                System.out.println(_threadName + " starting cycle " + _count);
77
 
                _ex = getPersistit().getExchange("persistit", _rootName + _threadIndex, true);
78
 
                final Accumulator sum = _ex.getTree().getAccumulator(Accumulator.Type.SUM, 17);
79
 
                final Accumulator max = _ex.getTree().getAccumulator(Accumulator.Type.MAX, 22);
80
 
                final Accumulator min = _ex.getTree().getAccumulator(Accumulator.Type.MIN, 23);
81
 
                final Accumulator seq = _ex.getTree().getAccumulator(Accumulator.Type.SEQ, 47);
82
 
                final Transaction txn = _ex.getTransaction();
83
 
 
84
 
                if (_count > 1) {
85
 
                    txn.begin();
86
 
                    try {
87
 
                        final long minv = min.getSnapshotValue(txn);
88
 
                        final long maxv = max.getSnapshotValue(txn);
89
 
                        final long seqv = seq.getSnapshotValue(txn);
90
 
                        final long sumv = sum.getSnapshotValue(txn);
91
 
                        if (minv != minValue || maxv != maxValue || seqv != seqValue || sumv != sumValue) {
92
 
                            fail(String.format("Values don't match: (min/max/seq/sum) "
93
 
                                    + "expected=(%,d/%,d/%,d/%,d) actual=(%,d/%,d/%,d/%,d)", minValue, maxValue,
94
 
                                    seqValue, sumValue, minv, maxv, seqv, sumv));
95
 
                        }
96
 
                        txn.commit();
97
 
                    } finally {
98
 
                        txn.end();
99
 
                    }
100
 
                }
101
 
                int seqValueHold = 0;
102
 
                final boolean a = RANDOM.nextInt(50) == 0;
103
 
                txn.begin();
104
 
                try {
105
 
                    final long timeOffset = RANDOM.nextInt(1000) - 500;
106
 
                    while (!isTriggered(timeOffset)) {
107
 
                        final long r = RANDOM.nextInt(1000) - 500;
108
 
                        min.update(bsum(minValue, r), txn);
109
 
                        max.update(bsum(maxValue, r), txn);
110
 
                        seq.update(1, txn);
111
 
                        sum.update(r, txn);
112
 
                        long minWas = getLong(_ex.to("min"), Long.MAX_VALUE);
113
 
                        _ex.getValue().put(Math.min(bsum(minValue, r), minWas));
114
 
                        _ex.store();
115
 
                        long maxWas = getLong(_ex.to("max"), Long.MIN_VALUE);
116
 
                        _ex.getValue().put(Math.max(bsum(maxValue, r), maxWas));
117
 
                        _ex.store();
118
 
                        long seqWas = getLong(_ex.to("seq"), 0);
119
 
                        _ex.getValue().put(Math.max(seqValue + 1, seqWas));
120
 
                        _ex.store();
121
 
                        long sumWas = getLong(_ex.to("sum"), 0);
122
 
                        _ex.getValue().put(Math.min(sumValue + r, sumWas));
123
 
                        _ex.store();
124
 
                        seqValueHold++;
125
 
                        if (!a) {
126
 
                            minValue = Math.min(bsum(minValue, r), minValue);
127
 
                            maxValue = Math.max(bsum(maxValue, r), maxValue);
128
 
                            seqValue = seqValue + seqValueHold;
129
 
                            sumValue = sumValue + r;
130
 
                            seqValueHold = 0;
131
 
                        }
132
 
                    }
133
 
                    if (a) {
134
 
                        txn.rollback();
135
 
                    } else {
136
 
                        txn.commit();
137
 
                    }
138
 
                } finally {
139
 
                    txn.end();
140
 
                }
141
 
 
142
 
                if ((_count % 3) == 0) {
143
 
                    Persistit db = getPersistit();
144
 
                    db.close();
145
 
 
146
 
                    if (isStopped() || _count >= _repeatTotal) {
147
 
                        break;
148
 
                    }
149
 
 
150
 
                    final Configuration config = db.getConfiguration();
151
 
                    db = new Persistit();
152
 
                    db.initialize(config);
153
 
                    setPersistit(db);
154
 
                }
155
 
            } catch (final Exception ex) {
156
 
                handleThrowable(ex);
157
 
            }
158
 
        }
159
 
    }
160
 
 
161
 
    private boolean isTriggered(final long timeOffset) {
162
 
        final long cp = getPersistit().getCurrentCheckpoint().getTimestamp();
163
 
        final long now = System.nanoTime();
164
 
 
165
 
        if (_checkpointTime == 0) {
166
 
            if (cp > _checkpointTimestamp) {
167
 
                _checkpointTime = now;
168
 
                _checkpointTimestamp = cp;
169
 
            }
170
 
        }
171
 
        if (_checkpointTime != 0) {
172
 
            if (timeOffset > 0 && now > _checkpointTime + timeOffset) {
173
 
                _checkpointTime = 0;
174
 
                return true;
175
 
            } else if (timeOffset < 0 && now > _checkpointTime + timeOffset + CHECKPOINT_INTERVAL * Util.MS_PER_S) {
176
 
                _checkpointTime = 0;
177
 
                return true;
178
 
            }
179
 
        }
180
 
        return false;
181
 
    }
182
 
 
183
 
    private long bsum(final long a, final long b) {
184
 
        if (a < 0) {
185
 
            return a + b > 0 ? a : a + b;
186
 
        } else {
187
 
            return a + b < 0 ? a : a + b;
188
 
        }
189
 
    }
190
 
 
191
 
    private long getLong(final Exchange ex, final long dflt) throws PersistitException {
192
 
        if (ex.getValue().isDefined()) {
193
 
            return ex.getValue().getLong();
194
 
        } else {
195
 
            return dflt;
196
 
        }
197
 
    }
198
 
}