/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.slider.server.appmaster.model.mock

import com.codahale.metrics.MetricRegistry
import org.apache.slider.providers.ProviderRole
import org.apache.slider.server.appmaster.state.AbstractRecordFactory
import org.apache.slider.server.appmaster.state.AppState

/**
 * Extended app state that makes more things public
 */
class MockAppState extends AppState {

  public MockAppState(AbstractRecordFactory recordFactory) {
    super(recordFactory, new MetricRegistry());
  }

  long time = 0;
  
  /**
   * Instance with a mock record factory
   */
  public MockAppState() {
    super(new MockRecordFactory(), new MetricRegistry());
  }

  public Map<String, ProviderRole> getRoleMap() {
    return super.roleMap;
  }

  /**
   * Current time. if the <code>time</code> field
   * is set, that value is returned
   * @return the current time.
   */
  protected long now() {
    return time ?: System.currentTimeMillis();
  }
}
