mobile/android/tests/background/junit3/src/testhelpers/WBORepository.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/tests/background/junit3/src/testhelpers/WBORepository.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,231 @@
     1.4 +/* Any copyright is dedicated to the Public Domain.
     1.5 +   http://creativecommons.org/publicdomain/zero/1.0/ */
     1.6 +
     1.7 +package org.mozilla.gecko.background.testhelpers;
     1.8 +
     1.9 +import java.util.Map.Entry;
    1.10 +import java.util.concurrent.ConcurrentHashMap;
    1.11 +import java.util.concurrent.ExecutorService;
    1.12 +import java.util.concurrent.Executors;
    1.13 +
    1.14 +import org.mozilla.gecko.background.common.log.Logger;
    1.15 +import org.mozilla.gecko.sync.repositories.InactiveSessionException;
    1.16 +import org.mozilla.gecko.sync.repositories.InvalidSessionTransitionException;
    1.17 +import org.mozilla.gecko.sync.repositories.NoStoreDelegateException;
    1.18 +import org.mozilla.gecko.sync.repositories.RecordFilter;
    1.19 +import org.mozilla.gecko.sync.repositories.Repository;
    1.20 +import org.mozilla.gecko.sync.repositories.StoreTrackingRepositorySession;
    1.21 +import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate;
    1.22 +import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionCreationDelegate;
    1.23 +import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
    1.24 +import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
    1.25 +import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionGuidsSinceDelegate;
    1.26 +import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionWipeDelegate;
    1.27 +import org.mozilla.gecko.sync.repositories.domain.Record;
    1.28 +
    1.29 +import android.content.Context;
    1.30 +
    1.31 +public class WBORepository extends Repository {
    1.32 +
    1.33 +  public class WBORepositoryStats {
    1.34 +    public long created         = -1;
    1.35 +    public long begun           = -1;
    1.36 +    public long fetchBegan      = -1;
    1.37 +    public long fetchCompleted  = -1;
    1.38 +    public long storeBegan      = -1;
    1.39 +    public long storeCompleted  = -1;
    1.40 +    public long finished        = -1;
    1.41 +  }
    1.42 +
    1.43 +  public static final String LOG_TAG = "WBORepository";
    1.44 +
    1.45 +  // Access to stats is not guarded.
    1.46 +  public WBORepositoryStats stats;
    1.47 +
    1.48 +  // Whether or not to increment the timestamp of stored records.
    1.49 +  public final boolean bumpTimestamps;
    1.50 +
    1.51 +  public class WBORepositorySession extends StoreTrackingRepositorySession {
    1.52 +
    1.53 +    protected WBORepository wboRepository;
    1.54 +    protected ExecutorService delegateExecutor = Executors.newSingleThreadExecutor();
    1.55 +    public ConcurrentHashMap<String, Record> wbos;
    1.56 +
    1.57 +    public WBORepositorySession(WBORepository repository) {
    1.58 +      super(repository);
    1.59 +
    1.60 +      wboRepository = repository;
    1.61 +      wbos          = new ConcurrentHashMap<String, Record>();
    1.62 +      stats         = new WBORepositoryStats();
    1.63 +      stats.created = now();
    1.64 +    }
    1.65 +
    1.66 +    @Override
    1.67 +    protected synchronized void trackGUID(String guid) {
    1.68 +      if (wboRepository.shouldTrack()) {
    1.69 +        super.trackGUID(guid);
    1.70 +      }
    1.71 +    }
    1.72 +
    1.73 +    @Override
    1.74 +    public void guidsSince(long timestamp,
    1.75 +                           RepositorySessionGuidsSinceDelegate delegate) {
    1.76 +      throw new RuntimeException("guidsSince not implemented.");
    1.77 +    }
    1.78 +
    1.79 +    @Override
    1.80 +    public void fetchSince(long timestamp,
    1.81 +                           RepositorySessionFetchRecordsDelegate delegate) {
    1.82 +      long fetchBegan  = now();
    1.83 +      stats.fetchBegan = fetchBegan;
    1.84 +      RecordFilter filter = storeTracker.getFilter();
    1.85 +
    1.86 +      for (Entry<String, Record> entry : wbos.entrySet()) {
    1.87 +        Record record = entry.getValue();
    1.88 +        if (record.lastModified >= timestamp) {
    1.89 +          if (filter != null &&
    1.90 +              filter.excludeRecord(record)) {
    1.91 +            Logger.debug(LOG_TAG, "Excluding record " + record.guid);
    1.92 +            continue;
    1.93 +          }
    1.94 +          delegate.deferredFetchDelegate(delegateExecutor).onFetchedRecord(record);
    1.95 +        }
    1.96 +      }
    1.97 +      long fetchCompleted  = now();
    1.98 +      stats.fetchCompleted = fetchCompleted;
    1.99 +      delegate.deferredFetchDelegate(delegateExecutor).onFetchCompleted(fetchCompleted);
   1.100 +    }
   1.101 +
   1.102 +    @Override
   1.103 +    public void fetch(final String[] guids,
   1.104 +                      final RepositorySessionFetchRecordsDelegate delegate) {
   1.105 +      long fetchBegan  = now();
   1.106 +      stats.fetchBegan = fetchBegan;
   1.107 +      for (String guid : guids) {
   1.108 +        if (wbos.containsKey(guid)) {
   1.109 +          delegate.deferredFetchDelegate(delegateExecutor).onFetchedRecord(wbos.get(guid));
   1.110 +        }
   1.111 +      }
   1.112 +      long fetchCompleted  = now();
   1.113 +      stats.fetchCompleted = fetchCompleted;
   1.114 +      delegate.deferredFetchDelegate(delegateExecutor).onFetchCompleted(fetchCompleted);
   1.115 +    }
   1.116 +
   1.117 +    @Override
   1.118 +    public void fetchAll(final RepositorySessionFetchRecordsDelegate delegate) {
   1.119 +      long fetchBegan  = now();
   1.120 +      stats.fetchBegan = fetchBegan;
   1.121 +      for (Entry<String, Record> entry : wbos.entrySet()) {
   1.122 +        Record record = entry.getValue();
   1.123 +        delegate.deferredFetchDelegate(delegateExecutor).onFetchedRecord(record);
   1.124 +      }
   1.125 +      long fetchCompleted  = now();
   1.126 +      stats.fetchCompleted = fetchCompleted;
   1.127 +      delegate.deferredFetchDelegate(delegateExecutor).onFetchCompleted(fetchCompleted);
   1.128 +    }
   1.129 +
   1.130 +    @Override
   1.131 +    public void store(final Record record) throws NoStoreDelegateException {
   1.132 +      if (delegate == null) {
   1.133 +        throw new NoStoreDelegateException();
   1.134 +      }
   1.135 +      final long now = now();
   1.136 +      if (stats.storeBegan < 0) {
   1.137 +        stats.storeBegan = now;
   1.138 +      }
   1.139 +      Record existing = wbos.get(record.guid);
   1.140 +      Logger.debug(LOG_TAG, "Existing record is " + (existing == null ? "<null>" : (existing.guid + ", " + existing)));
   1.141 +      if (existing != null &&
   1.142 +          existing.lastModified > record.lastModified) {
   1.143 +        Logger.debug(LOG_TAG, "Local record is newer. Not storing.");
   1.144 +        delegate.deferredStoreDelegate(delegateExecutor).onRecordStoreSucceeded(record.guid);
   1.145 +        return;
   1.146 +      }
   1.147 +      if (existing != null) {
   1.148 +        Logger.debug(LOG_TAG, "Replacing local record.");
   1.149 +      }
   1.150 +
   1.151 +      // Store a copy of the record with an updated modified time.
   1.152 +      Record toStore = record.copyWithIDs(record.guid, record.androidID);
   1.153 +      if (bumpTimestamps) {
   1.154 +        toStore.lastModified = now;
   1.155 +      }
   1.156 +      wbos.put(record.guid, toStore);
   1.157 +
   1.158 +      trackRecord(toStore);
   1.159 +      delegate.deferredStoreDelegate(delegateExecutor).onRecordStoreSucceeded(record.guid);
   1.160 +    }
   1.161 +
   1.162 +    @Override
   1.163 +    public void wipe(final RepositorySessionWipeDelegate delegate) {
   1.164 +      if (!isActive()) {
   1.165 +        delegate.onWipeFailed(new InactiveSessionException(null));
   1.166 +        return;
   1.167 +      }
   1.168 +
   1.169 +      Logger.info(LOG_TAG, "Wiping WBORepositorySession.");
   1.170 +      this.wbos = new ConcurrentHashMap<String, Record>();
   1.171 +
   1.172 +      // Wipe immediately for the convenience of test code.
   1.173 +      wboRepository.wbos = new ConcurrentHashMap<String, Record>();
   1.174 +      delegate.deferredWipeDelegate(delegateExecutor).onWipeSucceeded();
   1.175 +    }
   1.176 +
   1.177 +    @Override
   1.178 +    public void finish(RepositorySessionFinishDelegate delegate) throws InactiveSessionException {
   1.179 +      Logger.info(LOG_TAG, "Finishing WBORepositorySession: handing back " + this.wbos.size() + " WBOs.");
   1.180 +      wboRepository.wbos = this.wbos;
   1.181 +      stats.finished = now();
   1.182 +      super.finish(delegate);
   1.183 +    }
   1.184 +
   1.185 +    @Override
   1.186 +    public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException {
   1.187 +      this.wbos = wboRepository.cloneWBOs();
   1.188 +      stats.begun = now();
   1.189 +      super.begin(delegate);
   1.190 +    }
   1.191 +
   1.192 +    @Override
   1.193 +    public void storeDone(long end) {
   1.194 +      // TODO: this is not guaranteed to be called after all of the record
   1.195 +      // store callbacks have completed!
   1.196 +      if (stats.storeBegan < 0) {
   1.197 +        stats.storeBegan = end;
   1.198 +      }
   1.199 +      stats.storeCompleted = end;
   1.200 +      delegate.deferredStoreDelegate(delegateExecutor).onStoreCompleted(end);
   1.201 +    }
   1.202 +  }
   1.203 +
   1.204 +  public ConcurrentHashMap<String, Record> wbos;
   1.205 +
   1.206 +  public WBORepository(boolean bumpTimestamps) {
   1.207 +    super();
   1.208 +    this.bumpTimestamps = bumpTimestamps;
   1.209 +    this.wbos = new ConcurrentHashMap<String, Record>();
   1.210 +  }
   1.211 +
   1.212 +  public WBORepository() {
   1.213 +    this(false);
   1.214 +  }
   1.215 +
   1.216 +  public synchronized boolean shouldTrack() {
   1.217 +    return false;
   1.218 +  }
   1.219 +
   1.220 +  @Override
   1.221 +  public void createSession(RepositorySessionCreationDelegate delegate,
   1.222 +                            Context context) {
   1.223 +    delegate.deferredCreationDelegate().onSessionCreated(new WBORepositorySession(this));
   1.224 +  }
   1.225 +
   1.226 +  public ConcurrentHashMap<String, Record> cloneWBOs() {
   1.227 +    ConcurrentHashMap<String, Record> out = new ConcurrentHashMap<String, Record>();
   1.228 +    for (Entry<String, Record> entry : wbos.entrySet()) {
   1.229 +      out.put(entry.getKey(), entry.getValue()); // Assume that records are
   1.230 +                                                 // immutable.
   1.231 +    }
   1.232 +    return out;
   1.233 +  }
   1.234 +}

mercurial