text:
package net.ssehub.kernel_haven.util.logic;

import static net.ssehub.kernel_haven.util.null_checks.NullHelpers.notNull;

import java.util.function.Function;

import net.ssehub.kernel_haven.util.null_checks.NonNull;

/**
 * Static utility method for simplifying {@link Formula}s. By default, this only does some simple simplifications.
 * However, a more complex simplifier can be registered via {@link #setSimplifier(Function)} (e.g. LogicUtils in
 * CnfUtils plugin does this).
 *
 * @author Adam
 */
public class FormulaSimplifier {

    private static @NonNull Function<@NonNull Formula, @NonNull Formula> simplifier
            = FormulaSimplifier::defaultSimplifier;

    /**
     * Don't allow any instances.
     */
    private FormulaSimplifier() {
    }

    /**
     * Changes the simplifier to be used. Overrides the previous one.
     *
     * @param simplifier The new simplifier to use.
     */
    public static void setSimplifier(@NonNull Function<@NonNull Formula, @NonNull Formula> simplifier) {
        FormulaSimplifier.simplifier = simplifier;
    }

    /**
     * Simplifies the given formula. Uses the previously set simplifier (see {@link #setSimplifier(Function)}).
     *
     * @param formula The formla to simplify.
     * @return The simplified formula.
     */
    public static @NonNull Formula simplify(@NonNull Formula formula) {
        return notNull(simplifier.apply(formula));
    }

    /**
     * The default simplifier. Simplifies boolean formulas a bit. The following simplification rules are done:
     *

     *
{@code NOT(NOT(a)) -> a}

     *
{@code NOT(true) -> false}

     *
{@code NOT(false) -> true}

     *
     *
{@code true OR a -> true}

     *
{@code a OR true -> true}

     *
{@code false OR false -> false}

     *
{@code a OR false -> a}

     *
{@code false OR a -> a}

     *
{@code a OR a -> a}

     *
     *
{@code false AND a -> false}

     *
{@code a AND false -> false}

     *
{@code true AND true -> true}

     *
{@code a AND true -> a}

     *
{@code true AND a -> a}

     *
{@code a AND a -> a}

     *

     *
     * This ensures that no constants are left after the simplification (except if the whole Formula becomes True or
     * False).
     *
     * @param formula The formula to simplify.
     * @return A new formula equal to the original, but simplified.
     */
    public static @NonNull Formula defaultSimplifier(@NonNull Formula formula) {
        return DefaultSimplifierVisitor.INSTANCE.visit(formula);
    }

    /**
     * The visitor implementing {@link FormulaSimplifier#defaultSimplifier(Formula)}.
     */
    private static class DefaultSimplifierVisitor implements IFormulaVisitor<@NonNull Formula> {

        static final @NonNull DefaultSimplifierVisitor INSTANCE = new DefaultSimplifierVisitor();

        @Override
        public @NonNull Formula visitFalse(@NonNull False falseConstant) {
            return falseConstant;
        }

        @Override
        public @NonNull Formula visitTrue(@NonNull True trueConstant) {
            return trueConstant;
        }

        @Override
        public @NonNull Formula visitVariable(@NonNull Variable variable) {
            return variable;
        }

        @Override
        public @NonNull Formula visitNegation(@NonNull Negation formula) {
            Formula nested = formula.getFormula().accept(this);

            Formula result;

            if (nested instanceof Negation) {
                result = ((Negation) nested).getFormula();

            } else if (nested instanceof True) {
                result = False.INSTANCE;

            } else if (nested instanceof False) {
                result = True.INSTANCE;

            } else {
                // only create new instance if nested actually changed
                if (formula.getFormula() != nested) {
                    result = new Negation(nested);
                } else {
                    result = formula;
                }
            }

            return result;
        }

        @Override
        public @NonNull Formula visitDisjunction(@NonNull Disjunction formula) {
            Formula left = formula.getLeft().accept(this);
            Formula right = formula.getRight().accept(this);

            Formula result;

            if (left instanceof True || right instanceof True) {
                result = True.INSTANCE;

            } else if (left instanceof False && right instanceof False) {
                result = False.INSTANCE;

            } else if (left instanceof False) {
                result = right;

            } else if (right instanceof False) {
                result = left;

            } else if (left.equals(right)) {
                result = left;

            } else {
                // only create new instance if nested actually changed
                if (formula.getLeft() != left || formula.getRight() != right) {
                    result = new Disjunction(left, right);
                } else {
                    result = formula;
                }
            }

            return result;
        }

        @Override
        public @NonNull Formula visitConjunction(@NonNull Conjunction formula) {
            Formula left = formula.getLeft().accept(this);
            Formula right = formula.getRight().accept(this);

            Formula result;

            if (left instanceof False || right instanceof False) {
                result = False.INSTANCE;

            } else if (left instanceof True && right instanceof True) {
                result = True.INSTANCE;

            } else if (left instanceof True) {
                result = right;

            } else if (right instanceof True) {
                result = left;

            } else if (left.equals(right)) {
                result = left;

            } else {
                // only create new instance if nested actually changed
                if (formula.getLeft() != left || formula.getRight() != right) {
                    result = new Conjunction(left, right);
                } else {
                    result = formula;
                }
            }

            return result;
        }

    }

}


text:
typedef struct MessageHandlerListEntry {
   Device2262nMessageHandler* handler;
   MessageHandlerListEntry* next;
} MessageHandlerListEntry;

class Device2262n : public Device {
   public:
      Device2262n(int pulseWidth, int pulseSlack, int minRepeats);

      virtual int deviceType(void);
      virtual char* deviceName(void);

      virtual bool registerMessageHandler(Device2262nMessageHandler* handler);

      virtual void processPulse(long duration);
      virtual void decodeMessage(Message* message);
      virtual void handleMessage(Message* message);

   private:
      int _pulseWidth;
      int _pulseSlack;
      int _minRepeats;
      MessageHandlerListEntry* _messageHandlers;
      bool syncFound;
      unsigned int bitCount;
      unsigned char tristateCode[TRISTATE_MESSAGE_LENGTH];
      unsigned char lastMessage[TRISTATE_MESSAGE_LENGTH];
      unsigned int durations[BITS_IN_MESSAGE_2262];
      long pulseCount;
      long repeatCount;
};

#endif

redpajama_set_name: RedPajamaGithub


text:
/**
 * Simple button.
 * @project UI controls.
 * @author Anna Agte
 * @version 1.0
 */

goog.provide('DD.ui.controls.Button');

goog.require('DD.ui.controls.Control');
goog.require('DD.ui.controls.renderer.Button');
goog.require('goog.ui.registry');

// ------------------------------
// Constructor
// ------------------------------

/**
 * @example

// Full form.
var button = new DD.ui.controls.Button({
  caption: 'Open settings',
  click: function() { // show settings },
  id: 'settings',
  //icon: '/images/settings-open.png',
  imageIndex: 511,
  hint: 'Show settings',
  cssClass: 'user-button',
  nodeId: 'settings-button',
  toggle: {
    caption: 'Close settings',
    //icon: 'images/settings-close.png'
    imageIndex: 512
  }
});

// Short form.
var button = new DD.ui.controls.Button('Open settings', function() { // show settings });

 * @param {Object|string=} options Component's options or only a caption.
 *    See other possible options in {@link DD.ui.controls.Control}.
 * @param {Object=} options.toggle Options to toggle on click.
 * @param {string=} options.toggle.icon New icon value.
 * @param {number=} options.toggle.imageIndex New imageIndex value.
 * @param {string=} options.toggle.caption New caption value.
 * @param {eventCallback=} click Click handler.
 *    Ignored if the first parameter is options, not a caption.
 * @constructor
 * @extends DD.ui.controls.Control
 */
DD.ui.controls.Button = function(options) {

  if (!goog.isObject(options)) {
    var tempOptions = {};
    if (goog.isString(arguments[0]))
      tempOptions.caption = arguments[0];
    if (goog.isFunction(arguments[1]))
      tempOptions.click = arguments[1];
    options = tempOptions;
  }

  DD.ui.controls.Control.call(this, options);
};
goog.inherits(DD.ui.controls.Button, DD.ui.controls.Control);
goog.ui.registry.setDefaultRenderer(DD.ui.controls.Button, DD.ui.controls.renderer.Button);

// ------------------------------
// Prototype
// ------------------------------

goog.scope(function() {

/** @alias DD.ui.controls.Button.prototype */
var prototype = DD.ui.controls.Button.prototype;
var superClass_ = DD.ui.controls.Button.superClass_;
var ACTION = DD.ui.EventType.ACTION;

// ------------------------------
// Methods
// ------------------------------

/**
 * @inheritdoc
 */
prototype.assign = function(options) {

  if (!goog.isObject(options))
    options = {};

  if (!options.caption && !options.icon && !goog.isNumber(options.imageIndex)) {
    options.caption = 'Button';
  }

  superClass_.assign.call(this, options);

  if (goog.isObject(options.toggle)) {

    var caption1 = this.getCaption();
    var icon1 = this.getIcon();
    var imageIndex1 = this.getImageIndex();

    var caption2 = options.toggle.caption;
    var icon2 = options.toggle.icon;
    var imageIndex2 = options.toggle.imageIndex;

    var toggled = false;

    this.listen(ACTION, function() {
      toggled = !toggled;
      if (caption2 !== undefined)
        this.setCaption(toggled ? caption2 : caption1);
      if (icon2 !== undefined)
        this.setIcon(toggled ? icon2 : icon1);
      if (imageIndex2 !== undefined)
        this.setImageIndex(toggled ? imageIndex2 : imageIndex1);
    });
  }
};

}); // goog.scope


text:
package org.keycloak.forms.login.freemarker.model;

import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.services.util.ResolveRelative;

import java.net.URI;
import java.util.Map;

/**
 * @author Bill Burke
 * @version $Revision: 1 $
 */
public class ClientBean {

    private KeycloakSession session;
    protected ClientModel client;

    public ClientBean(KeycloakSession session, ClientModel client) {
        this.session = session;
        this.client = client;
    }

    public String getClientId() {
        return client.getClientId();
    }

    public String getName() {
        return client.getName();
    }

    public String getDescription() {
        return client.getDescription();
    }

    public String getBaseUrl() {
        return ResolveRelative.resolveRelativeUri(session, client.getRootUrl(), client.getBaseUrl());
    }

    public Map<String,String> getAttributes(){
        return client.getAttributes();
    }

    public String getAttribute(String key){
        return client.getAttribute(key);
    }
}


text:
package gobblin.metrics.reporter;

import lombok.Getter;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;

import com.codahale.metrics.Counter;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Meter;
import com.codahale.metrics.Timer;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.typesafe.config.Config;

import gobblin.metrics.context.ReportableContext;

/**
 * Stores {@link ReportableContext} that is should report in a list.
 */
public class ContextStoreReporter extends ScheduledReporter {

  @Getter
  private final List<ReportableContext> reportedContexts;

  public ContextStoreReporter(String name, Config config) {
    super(name, config);
    this.reportedContexts = Lists.newArrayList();
  }

  @Override protected void report(ReportableContext context) {
    this.reportedContexts.add(context);
  }

  @Override public void report(SortedMap<String, Gauge> gauges, SortedMap<String, Counter> counters,
      SortedMap<String, Histogram> histograms, SortedMap<String, Meter> meters, SortedMap<String, Timer> timers,
      Map<String, Object> tags) {
    // Noop
  }

  public Set<ReportableContext> getContextsToReport() {
    return Sets.newHashSet(this.getMetricContextsToReport());
  }
}


text:
using content::BrowserThread;

namespace switches {
const char kPasswordFileForTest[] = "password-file-for-test";
const char kSyncUserForTest[] = "sync-user-for-test";
const char kSyncPasswordForTest[] = "sync-password-for-test";
const char kSyncServerCommandLine[] = "sync-server-command-line";
}

// Helper class that checks whether a sync test server is running or not.
class SyncServerStatusChecker : public net::URLFetcherDelegate {
 public:
  SyncServerStatusChecker() : running_(false) {}

  virtual void OnURLFetchComplete(const net::URLFetcher* source) {
    std::string data;
    source->GetResponseAsString(&data);
    running_ =
        (source->GetStatus().status() == net::URLRequestStatus::SUCCESS &&
        source->GetResponseCode() == 200 && data.find("ok") == 0);
    MessageLoop::current()->Quit();
  }

  bool running() const { return running_; }

 private:
  bool running_;
};

void SetProxyConfigCallback(
    base::WaitableEvent* done,
    net::URLRequestContextGetter* url_request_context_getter,
    const net::ProxyConfig& proxy_config) {
  net::ProxyService* proxy_service =
      url_request_context_getter->GetURLRequestContext()->proxy_service();
  proxy_service->ResetConfigService(
      new net::ProxyConfigServiceFixed(proxy_config));
  done->Signal();
}

SyncTest::SyncTest(TestType test_type)
    : test_type_(test_type),
      server_type_(SERVER_TYPE_UNDECIDED),
      num_clients_(-1),
      use_verifier_(true),
      notifications_enabled_(true),
      test_server_handle_(base::kNullProcessHandle),
      number_of_default_sync_items_(0) {
  sync_datatype_helper::AssociateWithTest(this);
  switch (test_type_) {
    case SINGLE_CLIENT: {
      num_clients_ = 1;
      break;
    }
    case TWO_CLIENT: {
      num_clients_ = 2;
      break;
    }
    case MULTIPLE_CLIENT: {
      num_clients_ = 3;
      break;
    }
  }
}

SyncTest::~SyncTest() {}

void SyncTest::SetUp() {
  CommandLine* cl = CommandLine::ForCurrentProcess();
  if (cl->HasSwitch(switches::kPasswordFileForTest)) {
    ReadPasswordFile();
  } else if (cl->HasSwitch(switches::kSyncUserForTest) &&
             cl->HasSwitch(switches::kSyncPasswordForTest)) {
    username_ = cl->GetSwitchValueASCII(switches::kSyncUserForTest);
    password_ = cl->GetSwitchValueASCII(switches::kSyncPasswordForTest);
  } else {
    SetupMockGaiaResponses();
  }

  if (!cl->HasSwitch(switches::kSyncServiceURL) &&
      !cl->HasSwitch(switches::kSyncServerCommandLine)) {
    // If neither a sync server URL nor a sync server command line is
    // provided, start up a local python sync test server and point Chrome
    // to its URL.  This is the most common configuration, and the only
    // one that makes sense for most developers.
    server_type_ = LOCAL_PYTHON_SERVER;
  } else if (cl->HasSwitch(switches::kSyncServiceURL) &&
             cl->HasSwitch(switches::kSyncServerCommandLine)) {
    // If a sync server URL and a sync server command line are provided,
    // start up a local sync server by running the command line. Chrome
    // will connect to the server at the URL that was provided.
    server_type_ = LOCAL_LIVE_SERVER;
  } else if (cl->HasSwitch(switches::kSyncServiceURL) &&
             !cl->HasSwitch(switches::kSyncServerCommandLine)) {
    // If a sync server URL is provided, but not a server command line,
    // it is assumed that the server is already running. Chrome will
    // automatically connect to it at the URL provided. There is nothing
    // to do here.
    server_type_ = EXTERNAL_LIVE_SERVER;
  } else {
    // If a sync server command line is provided, but not a server URL,
    // we flag an error.
    LOG(FATAL) << "Can't figure out how to run a server.";
  }

  if (username_.empty() || password_.empty())
    LOG(FATAL) << "Cannot run sync tests without GAIA credentials.";

  // Mock the Mac Keychain service.  The real Keychain can block on user input.
#if defined(OS_MACOSX)
  Encryptor::UseMockKeychain(true);
#endif

  // Yield control back to the InProcessBrowserTest framework.
  InProcessBrowserTest::SetUp();
}

void SyncTest::TearDown() {
  // Allow the InProcessBrowserTest framework to perform its tear down.
  InProcessBrowserTest::TearDown();

  // Stop the local python test server. This is a no-op if one wasn't started.
  TearDownLocalPythonTestServer();

  // Stop the local sync test server. This is a no-op if one wasn't started.
  TearDownLocalTestServer();
}

void SyncTest::SetUpCommandLine(CommandLine* cl) {
  AddTestSwitches(cl);
  AddOptionalTypesToCommandLine(cl);
}

void SyncTest::AddTestSwitches(CommandLine* cl) {
  // TODO(rsimha): Until we implement a fake Tango server against which tests
  // can run, we need to set the --sync-notification-method to "p2p".
  if (!cl->HasSwitch(switches::kSyncNotificationMethod))
    cl->AppendSwitchASCII(switches::kSyncNotificationMethod, "p2p");

  // Disable non-essential access of external network resources.
  if (!cl->HasSwitch(switches::kDisableBackgroundNetworking))
    cl->AppendSwitch(switches::kDisableBackgroundNetworking);
}

void SyncTest::AddOptionalTypesToCommandLine(CommandLine* cl) {}

// static
Profile* SyncTest::MakeProfile(const FilePath::StringType name) {
  FilePath path;
  PathService::Get(chrome::DIR_USER_DATA, &path);
  path = path.Append(name);

  if (!file_util::PathExists(path))
    CHECK(file_util::CreateDirectory(path));

  Profile* profile =
      Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
  g_browser_process->profile_manager()->RegisterTestingProfile(profile, true);
  return profile;
}

Profile* SyncTest::GetProfile(int index) {
  if (profiles_.empty())
    LOG(FATAL) << "SetupClients() has not yet been called.";
  if (index < 0 || index >= static_cast<int>(profiles_.size()))
    LOG(FATAL) << "GetProfile(): Index is out of bounds.";
  return profiles_[index];
}

Browser* SyncTest::GetBrowser(int index) {
  if (browsers_.empty())
    LOG(FATAL) << "SetupClients() has not yet been called.";
  if (index < 0 || index >= static_cast<int>(browsers_.size()))
    LOG(FATAL) << "GetBrowser(): Index is out of bounds.";
  return browsers_[index];
}

ProfileSyncServiceHarness* SyncTest::GetClient(int index) {
  if (clients_.empty())
    LOG(FATAL) << "SetupClients() has not yet been called.";
  if (index < 0 || index >= static_cast<int>(clients_.size()))
    LOG(FATAL) << "GetClient(): Index is out of bounds.";
  return clients_[index];
}

Profile* SyncTest::verifier() {
  if (verifier_ == NULL)
    LOG(FATAL) << "SetupClients() has not yet been called.";
  return verifier_;
}

void SyncTest::DisableVerifier() {
  use_verifier_ = false;
}

bool SyncTest::SetupClients() {
  if (num_clients_ <= 0)
    LOG(FATAL) << "num_clients_ incorrectly initialized.";
  if (!profiles_.empty() || !browsers_.empty() || !clients_.empty())
    LOG(FATAL) << "SetupClients() has already been called.";

  // Start up a sync test server if one is needed.
  SetUpTestServerIfRequired();

  // Create the required number of sync profiles, browsers and clients.
  profiles_.resize(num_clients_);
  browsers_.resize(num_clients_);
  clients_.resize(num_clients_);
  for (int i = 0; i < num_clients_; ++i) {
    InitializeInstance(i);
  }

  // Create the verifier profile.
  verifier_ = MakeProfile(FILE_PATH_LITERAL("Verifier"));
  ui_test_utils::WaitForBookmarkModelToLoad(verifier()->GetBookmarkModel());
  ui_test_utils::WaitForTemplateURLServiceToLoad(
      TemplateURLServiceFactory::GetForProfile(verifier()));
  return (verifier_ != NULL);
}

void SyncTest::InitializeInstance(int index) {
  profiles_[index] = MakeProfile(
      base::StringPrintf(FILE_PATH_LITERAL("Profile%d"), index));
  EXPECT_FALSE(GetProfile(index) == NULL) << "Could not create Profile "
                                          << index << ".";

  browsers_[index] = Browser::Create(GetProfile(index));
  EXPECT_FALSE(GetBrowser(index) == NULL) << "Could not create Browser "
                                          << index << ".";

  clients_[index] = new ProfileSyncServiceHarness(GetProfile(index),
                                                  username_,
                                                  password_);
  EXPECT_FALSE(GetClient(index) == NULL) << "Could not create Client "
                                         << index << ".";

  ui_test_utils::WaitForBookmarkModelToLoad(
      GetProfile(index)->GetBookmarkModel());

  ui_test_utils::WaitForTemplateURLServiceToLoad(
      TemplateURLServiceFactory::GetForProfile(GetProfile(index)));
}

void SyncTest::RestartSyncService(int index) {
  DVLOG(1) << "Restarting profile sync service for profile " << index << ".";
  delete clients_[index];
  Profile* profile = GetProfile(index);
  ProfileSyncService* service =
      ProfileSyncServiceFactory::GetForProfile(profile);
  service->ResetForTest();
  clients_[index] = new ProfileSyncServiceHarness(profile,
                                                  username_,
                                                  password_);
  service->Initialize();
  GetClient(index)->AwaitSyncRestart();
}

bool SyncTest::SetupSync() {
  // Create sync profiles and clients if they haven't already been created.
  if (profiles_.empty()) {
    if (!SetupClients())
      LOG(FATAL) << "SetupClients() failed.";
  }

  // Sync each of the profiles.
  for (int i = 0; i < num_clients_; ++i) {
    if (!GetClient(i)->SetupSync())
      LOG(FATAL) << "SetupSync() failed.";
  }

  // Because clients may modify sync data as part of startup (for example local
  // session-releated data is rewritten), we need to ensure all startup-based
  // changes have propagated between the clients.
  AwaitQuiescence();

  // The number of default entries is the number of entries existing after
  // sync startup excluding top level folders and other permanent items.
  // This value must be updated whenever new permanent items are added (although
  // this should handle new datatype-specific top level folders).
  number_of_default_sync_items_ = GetClient(0)->GetNumEntries() -
                                  GetClient(0)->GetNumDatatypes() - 7;
  DVLOG(1) << "Setting " << number_of_default_sync_items_ << " as default "
           << " number of entries.";

  return true;
}

void SyncTest::CleanUpOnMainThread() {
  // Close all browser windows.
  browser::CloseAllBrowsers();
  ui_test_utils::RunAllPendingInMessageLoop();

  // All browsers should be closed at this point, or else we could see memory
  // corruption in QuitBrowser().
  CHECK_EQ(0U, BrowserList::size());
  clients_.clear();
}

void SyncTest::SetUpInProcessBrowserTestFixture() {
  // We don't take a reference to |resolver|, but mock_host_resolver_override_
  // does, so effectively assumes ownership.
  net::RuleBasedHostResolverProc* resolver =
      new net::RuleBasedHostResolverProc(host_resolver());
  resolver->AllowDirectLookup("*.google.com");
  // On Linux, we use Chromium's NSS implementation which uses the following
  // hosts for certificate verification. Without these overrides, running the
  // integration tests on Linux causes error as we make external DNS lookups.
  resolver->AllowDirectLookup("*.thawte.com");
  resolver->AllowDirectLookup("*.geotrust.com");
  resolver->AllowDirectLookup("*.gstatic.com");
  mock_host_resolver_override_.reset(
      new net::ScopedDefaultHostResolverProc(resolver));
}

void SyncTest::TearDownInProcessBrowserTestFixture() {
  mock_host_resolver_override_.reset();
}

void SyncTest::ReadPasswordFile() {
  CommandLine* cl = CommandLine::ForCurrentProcess();
  password_file_ = cl->GetSwitchValuePath(switches::kPasswordFileForTest);
  if (password_file_.empty())
    LOG(FATAL) << "Can't run live server test without specifying --"
               << switches::kPasswordFileForTest << "=<filename>";
  std::string file_contents;
  file_util::ReadFileToString(password_file_, &file_contents);
  ASSERT_NE(file_contents, "") << "Password file \""
      << password_file_.value() << "\" does not exist.";
  std::vector<std::string> tokens;
  std::string delimiters = "\r\n";
  Tokenize(file_contents, delimiters, &tokens);
  ASSERT_EQ(2U, tokens.size()) << "Password file \""
      << password_file_.value()
      << "\" must contain exactly two lines of text.";
  username_ = tokens[0];
  password_ = tokens[1];
}

void SyncTest::SetupMockGaiaResponses() {
  username_ = "user@gmail.com";
  password_ = "password";
  factory_.reset(new net::URLFetcherImplFactory());
  fake_factory_.reset(new net::FakeURLFetcherFactory(factory_.get()));
  fake_factory_->SetFakeResponse(
      GaiaUrls::GetInstance()->client_login_url(),
      "SID=sid\nLSID=lsid",
      true);
  fake_factory_->SetFakeResponse(
      GaiaUrls::GetInstance()->get_user_info_url(),
      "email=user@gmail.com",
      true);
  fake_factory_->SetFakeResponse(
      GaiaUrls::GetInstance()->issue_auth_token_url(),
      "auth",
      true);
  fake_factory_->SetFakeResponse(
      GoogleURLTracker::kSearchDomainCheckURL,
      ".google.com",
      true);
  fake_factory_->SetFakeResponse(
      GaiaUrls::GetInstance()->client_login_to_oauth2_url(),
      "some_response",
      true);
  fake_factory_->SetFakeResponse(
      GaiaUrls::GetInstance()->oauth2_token_url(),
      "{"
      "  \"refresh_token\": \"rt1\","
      "  \"access_token\": \"at1\","
      "  \"expires_in\": 3600,"
      "  \"token_type\": \"Bearer\""
      "}",
      true);
  fake_factory_->SetFakeResponse(
      GaiaUrls::GetInstance()->client_oauth_url(),
      "{"
      "  \"oauth2\": {"
      "    \"refresh_token\": \"rt1\","
      "    \"access_token\": \"at1\","
      "    \"expires_in\": 3600,"
      "    \"token_type\": \"Bearer\""
      "  }"
      "}",
      true);
  fake_factory_->SetFakeResponse(
      GaiaUrls::GetInstance()->oauth1_login_url(),
      "SID=sid\nLSID=lsid\nAuth=auth_token",
      true);
}

// Start up a local sync server based on the value of server_type_, which
// was determined from the command line parameters.
void SyncTest::SetUpTestServerIfRequired() {
  if (server_type_ == LOCAL_PYTHON_SERVER) {
    if (!SetUpLocalPythonTestServer())
      LOG(FATAL) << "Failed to set up local python sync and XMPP servers";
  } else if (server_type_ == LOCAL_LIVE_SERVER) {
    // Using mock gaia credentials requires the use of a mock XMPP server.
    if (username_ == "user@gmail.com" && !SetUpLocalPythonTestServer())
      LOG(FATAL) << "Failed to set up local python XMPP server";
    if (!SetUpLocalTestServer())
      LOG(FATAL) << "Failed to set up local test server";
  } else if (server_type_ == EXTERNAL_LIVE_SERVER) {
    // Nothing to do; we'll just talk to the URL we were given.
  } else {
    LOG(FATAL) << "Don't know which server environment to run test in.";
  }
}

bool SyncTest::SetUpLocalPythonTestServer() {
  EXPECT_TRUE(sync_server_.Start())
      << "Could not launch local python test server.";

  CommandLine* cl = CommandLine::ForCurrentProcess();
  if (server_type_ == LOCAL_PYTHON_SERVER) {
    std::string sync_service_url = sync_server_.GetURL("chromiumsync").spec();
    cl->AppendSwitchASCII(switches::kSyncServiceURL, sync_service_url);
    DVLOG(1) << "Started local python sync server at " << sync_service_url;
  }

  int xmpp_port = 0;
  if (!sync_server_.server_data().GetInteger("xmpp_port", &xmpp_port)) {
    LOG(ERROR) << "Could not find valid xmpp_port value";
    return false;
  }
  if ((xmpp_port <= 0) || (xmpp_port > kuint16max)) {
    LOG(ERROR) << "Invalid xmpp port: " << xmpp_port;
    return false;
  }

  net::HostPortPair xmpp_host_port_pair(sync_server_.host_port_pair());
  xmpp_host_port_pair.set_port(xmpp_port);
  xmpp_port_.reset(new net::ScopedPortException(xmpp_port));

  if (!cl->HasSwitch(switches::kSyncNotificationHostPort)) {
    cl->AppendSwitchASCII(switches::kSyncNotificationHostPort,
                          xmpp_host_port_pair.ToString());
    // The local XMPP server only supports insecure connections.
    cl->AppendSwitch(switches::kSyncAllowInsecureXmppConnection);
  }
  DVLOG(1) << "Started local python XMPP server at "
           << xmpp_host_port_pair.ToString();

  return true;
}

bool SyncTest::SetUpLocalTestServer() {
  CommandLine* cl = CommandLine::ForCurrentProcess();
  CommandLine::StringType server_cmdline_string = cl->GetSwitchValueNative(
      switches::kSyncServerCommandLine);
  CommandLine::StringVector server_cmdline_vector;
  CommandLine::StringType delimiters(FILE_PATH_LITERAL(" "));
  Tokenize(server_cmdline_string, delimiters, &server_cmdline_vector);
  CommandLine server_cmdline(server_cmdline_vector);
  base::LaunchOptions options;
#if defined(OS_WIN)
  options.start_hidden = true;
#endif
  if (!base::LaunchProcess(server_cmdline, options, &test_server_handle_))
    LOG(ERROR) << "Could not launch local test server.";

  const base::TimeDelta kMaxWaitTime = TestTimeouts::action_max_timeout();
  const int kNumIntervals = 15;
  if (WaitForTestServerToStart(kMaxWaitTime, kNumIntervals)) {
    DVLOG(1) << "Started local test server at "
             << cl->GetSwitchValueASCII(switches::kSyncServiceURL) << ".";
    return true;
  } else {
    LOG(ERROR) << "Could not start local test server at "
               << cl->GetSwitchValueASCII(switches::kSyncServiceURL) << ".";
    return false;
  }
}

bool SyncTest::TearDownLocalPythonTestServer() {
  if (!sync_server_.Stop()) {
    LOG(ERROR) << "Could not stop local python test server.";
    return false;
  }
  xmpp_port_.reset();
  return true;
}

bool SyncTest::TearDownLocalTestServer() {
  if (test_server_handle_ != base::kNullProcessHandle) {
    EXPECT_TRUE(base::KillProcess(test_server_handle_, 0, false))
        << "Could not stop local test server.";
    base::CloseProcessHandle(test_server_handle_);
    test_server_handle_ = base::kNullProcessHandle;
  }
  return true;
}

bool SyncTest::WaitForTestServerToStart(base::TimeDelta wait, int intervals) {
  for (int i = 0; i < intervals; ++i) {
    if (IsTestServerRunning())
      return true;
    base::PlatformThread::Sleep(wait / intervals);
  }
  return false;
}

bool SyncTest::IsTestServerRunning() {
  CommandLine* cl = CommandLine::ForCurrentProcess();
  std::string sync_url = cl->GetSwitchValueASCII(switches::kSyncServiceURL);
  GURL sync_url_status(sync_url.append("/healthz"));
  SyncServerStatusChecker delegate;
  scoped_ptr<net::URLFetcher> fetcher(net::URLFetcher::Create(
    sync_url_status, net::URLFetcher::GET, &delegate));
  fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE |
                        net::LOAD_DO_NOT_SEND_COOKIES |
                        net::LOAD_DO_NOT_SAVE_COOKIES);
  fetcher->SetRequestContext(g_browser_process->system_request_context());
  fetcher->Start();
  ui_test_utils::RunMessageLoop();
  return delegate.running();
}

void SyncTest::EnableNetwork(Profile* profile) {
  SetProxyConfig(profile->GetRequestContext(),
                 net::ProxyConfig::CreateDirect());
  if (notifications_enabled_) {
    EnableNotificationsImpl();
  }
  // TODO(rsimha): Remove this line once http://crbug.com/53857 is fixed.
  net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
}

void SyncTest::DisableNetwork(Profile* profile) {
  DisableNotificationsImpl();
  // Set the current proxy configuration to a nonexistent proxy to effectively
  // disable networking.
  net::ProxyConfig config;
  config.proxy_rules().ParseFromString("http=127.0.0.1:0");
  SetProxyConfig(profile->GetRequestContext(), config);
  // TODO(rsimha): Remove this line once http://crbug.com/53857 is fixed.
  net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
}

bool SyncTest::EnableEncryption(int index, syncer::ModelType type) {
  return GetClient(index)->EnableEncryptionForType(type);
}

bool SyncTest::IsEncrypted(int index, syncer::ModelType type) {
  return GetClient(index)->IsTypeEncrypted(type);
}

bool SyncTest::AwaitQuiescence() {
  return ProfileSyncServiceHarness::AwaitQuiescence(clients());
}

bool SyncTest::ServerSupportsNotificationControl() const {
  EXPECT_NE(SERVER_TYPE_UNDECIDED, server_type_);

  // Supported only if we're using the python testserver.
  return server_type_ == LOCAL_PYTHON_SERVER;
}

void SyncTest::DisableNotificationsImpl() {
  ASSERT_TRUE(ServerSupportsNotificationControl());
  std::string path = "chromiumsync/disablenotifications";
  ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
  ASSERT_EQ("Notifications disabled",
            UTF16ToASCII(chrome::GetActiveWebContents(browser())->GetTitle()));
}

void SyncTest::DisableNotifications() {
  DisableNotificationsImpl();
  notifications_enabled_ = false;
}

void SyncTest::EnableNotificationsImpl() {
  ASSERT_TRUE(ServerSupportsNotificationControl());
  std::string path = "chromiumsync/enablenotifications";
  ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
  ASSERT_EQ("Notifications enabled",
            UTF16ToASCII(chrome::GetActiveWebContents(browser())->GetTitle()));
}

void SyncTest::EnableNotifications() {
  EnableNotificationsImpl();
  notifications_enabled_ = true;
}

void SyncTest::TriggerNotification(syncer::ModelTypeSet changed_types) {
  ASSERT_TRUE(ServerSupportsNotificationControl());
  const std::string& data =
      syncer::P2PNotificationData("from_server",
                                         syncer::NOTIFY_ALL,
                                         changed_types).ToString();
  const std::string& path =
      std::string("chromiumsync/sendnotification?channel=") +
      syncer::kSyncP2PNotificationChannel + "&data=" + data;
  ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
  ASSERT_EQ("Notification sent",
            UTF16ToASCII(chrome::GetActiveWebContents(browser())->GetTitle()));
}

bool SyncTest::ServerSupportsErrorTriggering() const {
  EXPECT_NE(SERVER_TYPE_UNDECIDED, server_type_);

  // Supported only if we're using the python testserver.
  return server_type_ == LOCAL_PYTHON_SERVER;
}

void SyncTest::TriggerMigrationDoneError(syncer::ModelTypeSet model_types) {
  ASSERT_TRUE(ServerSupportsErrorTriggering());
  std::string path = "chromiumsync/migrate";
  char joiner = '?';
  for (syncer::ModelTypeSet::Iterator it = model_types.First();
       it.Good(); it.Inc()) {
    path.append(
        base::StringPrintf(
            "%ctype=%d", joiner,
            syncer::GetSpecificsFieldNumberFromModelType(it.Get())));
    joiner = '&';
  }
  ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
  ASSERT_EQ("Migration: 200",
            UTF16ToASCII(chrome::GetActiveWebContents(browser())->GetTitle()));
}

void SyncTest::TriggerBirthdayError() {
  ASSERT_TRUE(ServerSupportsErrorTriggering());
  std::string path = "chromiumsync/birthdayerror";
  ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
  ASSERT_EQ("Birthday error",
            UTF16ToASCII(chrome::GetActiveWebContents(browser())->GetTitle()));
}

void SyncTest::TriggerTransientError() {
  ASSERT_TRUE(ServerSupportsErrorTriggering());
  std::string path = "chromiumsync/transienterror";
  ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
  ASSERT_EQ("Transient error",
            UTF16ToASCII(chrome::GetActiveWebContents(browser())->GetTitle()));
}

void SyncTest::TriggerAuthError() {
  ASSERT_TRUE(ServerSupportsErrorTriggering());
  std::string path = "chromiumsync/cred";
  ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
}

namespace {

sync_pb::SyncEnums::ErrorType
    GetClientToServerResponseErrorType(
        syncer::SyncProtocolErrorType error) {
  switch (error) {
    case syncer::SYNC_SUCCESS:
      return sync_pb::SyncEnums::SUCCESS;
    case syncer::NOT_MY_BIRTHDAY:
      return sync_pb::SyncEnums::NOT_MY_BIRTHDAY;
    case syncer::THROTTLED:
      return sync_pb::SyncEnums::THROTTLED;
    case syncer::CLEAR_PENDING:
      return sync_pb::SyncEnums::CLEAR_PENDING;
    case syncer::TRANSIENT_ERROR:
      return sync_pb::SyncEnums::TRANSIENT_ERROR;
    case syncer::MIGRATION_DONE:
      return sync_pb::SyncEnums::MIGRATION_DONE;
    case syncer::UNKNOWN_ERROR:
      return sync_pb::SyncEnums::UNKNOWN;
    default:
      NOTREACHED();
      return sync_pb::SyncEnums::UNKNOWN;
  }
}

sync_pb::SyncEnums::Action GetClientToServerResponseAction(
    const syncer::ClientAction& action) {
  switch (action) {
    case syncer::UPGRADE_CLIENT:
      return sync_pb::SyncEnums::UPGRADE_CLIENT;
    case syncer::CLEAR_USER_DATA_AND_RESYNC:
      return sync_pb::SyncEnums::CLEAR_USER_DATA_AND_RESYNC;
    case syncer::ENABLE_SYNC_ON_ACCOUNT:
      return sync_pb::SyncEnums::ENABLE_SYNC_ON_ACCOUNT;
    case syncer::STOP_AND_RESTART_SYNC:
      return sync_pb::SyncEnums::STOP_AND_RESTART_SYNC;
    case syncer::DISABLE_SYNC_ON_CLIENT:
      return sync_pb::SyncEnums::DISABLE_SYNC_ON_CLIENT;
    case syncer::UNKNOWN_ACTION:
      return sync_pb::SyncEnums::UNKNOWN_ACTION;
    default:
      NOTREACHED();
      return sync_pb::SyncEnums::UNKNOWN_ACTION;
  }
}

}  // namespace

void SyncTest::TriggerSyncError(const syncer::SyncProtocolError& error,
                                SyncErrorFrequency frequency) {
  ASSERT_TRUE(ServerSupportsErrorTriggering());
  std::string path = "chromiumsync/error";
  int error_type =
      static_cast<int>(GetClientToServerResponseErrorType(
          error.error_type));
  int action = static_cast<int>(GetClientToServerResponseAction(
      error.action));

  path.append(base::StringPrintf("?error=%d", error_type));
  path.append(base::StringPrintf("&action=%d", action));

  path.append(base::StringPrintf("&error_description=%s",
                                 error.error_description.c_str()));
  path.append(base::StringPrintf("&url=%s", error.url.c_str()));
  path.append(base::StringPrintf("&frequency=%d", frequency));

  ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
  std::string output = UTF16ToASCII(
      chrome::GetActiveWebContents(browser())->GetTitle());
  ASSERT_TRUE(output.find("SetError: 200") != string16::npos);
}

void SyncTest::TriggerCreateSyncedBookmarks() {
  ASSERT_TRUE(ServerSupportsErrorTriggering());
  std::string path = "chromiumsync/createsyncedbookmarks";
  ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
  ASSERT_EQ("Synced Bookmarks",
            UTF16ToASCII(chrome::GetActiveWebContents(browser())->GetTitle()));
}

int SyncTest::NumberOfDefaultSyncItems() const {
  return number_of_default_sync_items_;
}

void SyncTest::SetProxyConfig(net::URLRequestContextGetter* context_getter,
                              const net::ProxyConfig& proxy_config) {
  base::WaitableEvent done(false, false);
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&SetProxyConfigCallback, &done,
                 make_scoped_refptr(context_getter), proxy_config));
  done.Wait();
}


text:
#include "modules/audio_processing/audio_processing_impl.h"

#include <algorithm>
#include <memory>
#include <vector>

#include "api/array_view.h"
#include "modules/audio_processing/test/test_utils.h"
#include "modules/include/module_common_types.h"
#include "rtc_base/criticalsection.h"
#include "rtc_base/event.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/random.h"
#include "system_wrappers/include/sleep.h"
#include "test/gtest.h"

namespace webrtc {

namespace {

class AudioProcessingImplLockTest;

// Type of the render thread APM API call to use in the test.
enum class RenderApiImpl {
  ProcessReverseStreamImpl1,
  ProcessReverseStreamImpl2,
  AnalyzeReverseStreamImpl
};

// Type of the capture thread APM API call to use in the test.
enum class CaptureApiImpl {
  ProcessStreamImpl1,
  ProcessStreamImpl2,
  ProcessStreamImpl3
};

// The runtime parameter setting scheme to use in the test.
enum class RuntimeParameterSettingScheme {
  SparseStreamMetadataChangeScheme,
  ExtremeStreamMetadataChangeScheme,
  FixedMonoStreamMetadataScheme,
  FixedStereoStreamMetadataScheme
};

// Variant of echo canceller settings to use in the test.
enum class AecType {
  BasicWebRtcAecSettings,
  AecTurnedOff,
  BasicWebRtcAecSettingsWithExtentedFilter,
  BasicWebRtcAecSettingsWithDelayAgnosticAec,
  BasicWebRtcAecSettingsWithAecMobile
};

// Thread-safe random number generator wrapper.
class RandomGenerator {
 public:
  RandomGenerator() : rand_gen_(42U) {}

  int RandInt(int min, int max) {
    rtc::CritScope cs(&crit_);
    return rand_gen_.Rand(min, max);
  }

  int RandInt(int max) {
    rtc::CritScope cs(&crit_);
    return rand_gen_.Rand(max);
  }

  float RandFloat() {
    rtc::CritScope cs(&crit_);
    return rand_gen_.Rand<float>();
  }

 private:
  rtc::CriticalSection crit_;
  Random rand_gen_ RTC_GUARDED_BY(crit_);
};

// Variables related to the audio data and formats.
struct AudioFrameData {
  explicit AudioFrameData(int max_frame_size) {
    // Set up the two-dimensional arrays needed for the APM API calls.
    input_framechannels.resize(2 * max_frame_size);
    input_frame.resize(2);
    input_frame[0] = &input_framechannels[0];
    input_frame[1] = &input_framechannels[max_frame_size];

    output_frame_channels.resize(2 * max_frame_size);
    output_frame.resize(2);
    output_frame[0] = &output_frame_channels[0];
    output_frame[1] = &output_frame_channels[max_frame_size];
  }

  AudioFrame frame;
  std::vector<float*> output_frame;
  std::vector<float> output_frame_channels;
  AudioProcessing::ChannelLayout output_channel_layout =
      AudioProcessing::ChannelLayout::kMono;
  int input_sample_rate_hz = 16000;
  int input_number_of_channels = -1;
  std::vector<float*> input_frame;
  std::vector<float> input_framechannels;
  AudioProcessing::ChannelLayout input_channel_layout =
      AudioProcessing::ChannelLayout::kMono;
  int output_sample_rate_hz = 16000;
  int output_number_of_channels = -1;
  StreamConfig input_stream_config;
  StreamConfig output_stream_config;
  int input_samples_per_channel = -1;
  int output_samples_per_channel = -1;
};

// The configuration for the test.
struct TestConfig {
  // Test case generator for the test configurations to use in the brief tests.
  static std::vector<TestConfig> GenerateBriefTestConfigs() {
    std::vector<TestConfig> test_configs;
    AecType aec_types[] = {AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec,
                           AecType::BasicWebRtcAecSettingsWithAecMobile};
    for (auto aec_type : aec_types) {
      TestConfig test_config;
      test_config.aec_type = aec_type;

      test_config.min_number_of_calls = 300;

      // Perform tests only with the extreme runtime parameter setting scheme.
      test_config.runtime_parameter_setting_scheme =
          RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme;

      // Only test 16 kHz for this test suite.
      test_config.initial_sample_rate_hz = 16000;

      // Create test config for the second processing API function set.
      test_config.render_api_function =
          RenderApiImpl::ProcessReverseStreamImpl2;
      test_config.capture_api_function = CaptureApiImpl::ProcessStreamImpl2;

      // Create test config for the first processing API function set.
      test_configs.push_back(test_config);
      test_config.render_api_function =
          RenderApiImpl::AnalyzeReverseStreamImpl;
      test_config.capture_api_function = CaptureApiImpl::ProcessStreamImpl3;
      test_configs.push_back(test_config);
    }

    // Return the created test configurations.
    return test_configs;
  }

  // Test case generator for the test configurations to use in the extensive
  // tests.
  static std::vector<TestConfig> GenerateExtensiveTestConfigs() {
    // Lambda functions for the test config generation.
    auto add_processing_apis = [](TestConfig test_config) {
      struct AllowedApiCallCombinations {
        RenderApiImpl render_api;
        CaptureApiImpl capture_api;
      };

      const AllowedApiCallCombinations api_calls[] = {
          {RenderApiImpl::ProcessReverseStreamImpl1,
           CaptureApiImpl::ProcessStreamImpl1},
          {RenderApiImpl::ProcessReverseStreamImpl2,
           CaptureApiImpl::ProcessStreamImpl2},
          {RenderApiImpl::ProcessReverseStreamImpl2,
           CaptureApiImpl::ProcessStreamImpl3},
          {RenderApiImpl::AnalyzeReverseStreamImpl,
           CaptureApiImpl::ProcessStreamImpl2},
          {RenderApiImpl::AnalyzeReverseStreamImpl,
           CaptureApiImpl::ProcessStreamImpl3}};
      std::vector<TestConfig> out;
      for (auto api_call : api_calls) {
        test_config.render_api_function = api_call.render_api;
        test_config.capture_api_function = api_call.capture_api;
        out.push_back(test_config);
      }
      return out;
    };

    auto add_aec_settings = [](const std::vector<TestConfig>& in) {
      std::vector<TestConfig> out;
      AecType aec_types[] = {
          AecType::BasicWebRtcAecSettings, AecType::AecTurnedOff,
          AecType::BasicWebRtcAecSettingsWithExtentedFilter,
          AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec,
          AecType::BasicWebRtcAecSettingsWithAecMobile};
      for (auto test_config : in) {
        // Due to a VisualStudio 2015 compiler issue, the internal loop
        // variable here cannot override a previously defined name.
        // In other words "type" cannot be named "aec_type" here.
        // https://connect.microsoft.com/VisualStudio/feedback/details/2291755
        for (auto type : aec_types) {
          test_config.aec_type = type;
          out.push_back(test_config);
        }
      }
      return out;
    };

    auto add_settings_scheme = [](const std::vector<TestConfig>& in) {
      std::vector<TestConfig> out;
      RuntimeParameterSettingScheme schemes[] = {
          RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme,
          RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme,
          RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme,
          RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme};

      for (auto test_config : in) {
        for (auto scheme : schemes) {
          test_config.runtime_parameter_setting_scheme = scheme;
          out.push_back(test_config);
        }
      }
      return out;
    };

    auto add_sample_rates = [](const std::vector<TestConfig>& in) {
      const int sample_rates[] = {8000, 16000, 32000, 48000};

      std::vector<TestConfig> out;
      for (auto test_config : in) {
        auto available_rates =
            (test_config.aec_type ==
                     AecType::BasicWebRtcAecSettingsWithAecMobile
                 ? rtc::ArrayView<const int>(sample_rates, 2)
                 : rtc::ArrayView<const int>(sample_rates));

        for (auto rate : available_rates) {
          test_config.initial_sample_rate_hz = rate;
          out.push_back(test_config);
        }
      }
      return out;
    };

    // Generate test configurations of the relevant combinations of the
    // parameters to
    // test.
    TestConfig test_config;
    test_config.min_number_of_calls = 10000;
    return add_sample_rates(add_settings_scheme(
        add_aec_settings(add_processing_apis(test_config))));
  }

  RenderApiImpl render_api_function = RenderApiImpl::ProcessReverseStreamImpl2;
  CaptureApiImpl capture_api_function = CaptureApiImpl::ProcessStreamImpl2;
  RuntimeParameterSettingScheme runtime_parameter_setting_scheme =
      RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme;
  int initial_sample_rate_hz = 16000;
  AecType aec_type = AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec;
  int min_number_of_calls = 300;
};

// Handler for the frame counters.
class FrameCounters {
 public:
  void IncreaseRenderCounter() {
    rtc::CritScope cs(&crit_);
    render_count++;
  }

  void IncreaseCaptureCounter() {
    rtc::CritScope cs(&crit_);
    capture_count++;
  }

  int GetCaptureCounter() const {
    rtc::CritScope cs(&crit_);
    return capture_count;
  }

  int GetRenderCounter() const {
    rtc::CritScope cs(&crit_);
    return render_count;
  }

  int CaptureMinusRenderCounters() const {
    rtc::CritScope cs(&crit_);
    return capture_count - render_count;
  }

  int RenderMinusCaptureCounters() const {
    return -CaptureMinusRenderCounters();
  }

  bool BothCountersExceedeThreshold(int threshold) {
    rtc::CritScope cs(&crit_);
    return (render_count > threshold && capture_count > threshold);
  }

 private:
  rtc::CriticalSection crit_;
  int render_count RTC_GUARDED_BY(crit_) = 0;
  int capture_count RTC_GUARDED_BY(crit_) = 0;
};

// Class for handling the capture side processing.
class CaptureProcessor {
 public:
  CaptureProcessor(int max_frame_size,
                   RandomGenerator* rand_gen,
                   rtc::Event* render_call_event,
                   rtc::Event* capture_call_event,
                   FrameCounters* shared_counters_state,
                   AudioProcessingImplLockTest* test_framework,
                   TestConfig* test_config,
                   AudioProcessing* apm);
  bool Process();

 private:
  static const int kMaxCallDifference = 10;
  static const float kCaptureInputFloatLevel;
  static const int kCaptureInputFixLevel = 1024;

  void PrepareFrame();
  void CallApmCaptureSide();
  void ApplyRuntimeSettingScheme();

  RandomGenerator* const rand_gen_ = nullptr;
  rtc::Event* const render_call_event_ = nullptr;
  rtc::Event* const capture_call_event_ = nullptr;
  FrameCounters* const frame_counters_ = nullptr;
  AudioProcessingImplLockTest* const test_ = nullptr;
  const TestConfig* const test_config_ = nullptr;
  AudioProcessing* const apm_ = nullptr;
  AudioFrameData frame_data_;
};

// Class for handling the stats processing.
class StatsProcessor {
 public:
  StatsProcessor(RandomGenerator* rand_gen,
                 TestConfig* test_config,
                 AudioProcessing* apm);
  bool Process();

 private:
  RandomGenerator* rand_gen_ = nullptr;
  TestConfig* test_config_ = nullptr;
  AudioProcessing* apm_ = nullptr;
};

// Class for handling the render side processing.
class RenderProcessor {
 public:
  RenderProcessor(int max_frame_size,
                  RandomGenerator* rand_gen,
                  rtc::Event* render_call_event,
                  rtc::Event* capture_call_event,
                  FrameCounters* shared_counters_state,
                  AudioProcessingImplLockTest* test_framework,
                  TestConfig* test_config,
                  AudioProcessing* apm);
  bool Process();

 private:
  static const int kMaxCallDifference = 10;
  static const int kRenderInputFixLevel = 16384;
  static const float kRenderInputFloatLevel;

  void PrepareFrame();
  void CallApmRenderSide();
  void ApplyRuntimeSettingScheme();

  RandomGenerator* const rand_gen_ = nullptr;
  rtc::Event* const render_call_event_ = nullptr;
  rtc::Event* const capture_call_event_ = nullptr;
  FrameCounters* const frame_counters_ = nullptr;
  AudioProcessingImplLockTest* const test_ = nullptr;
  const TestConfig* const test_config_ = nullptr;
  AudioProcessing* const apm_ = nullptr;
  AudioFrameData frame_data_;
  bool first_render_call_ = true;
};

class AudioProcessingImplLockTest
    : public ::testing::TestWithParam<TestConfig> {
 public:
  AudioProcessingImplLockTest();
  bool RunTest();
  bool MaybeEndTest();

 private:
  static const int kTestTimeOutLimit = 10 * 60 * 1000;
  static const int kMaxFrameSize = 480;

  // ::testing::TestWithParam<> implementation
  void SetUp() override;
  void TearDown() override;

  // Thread callback for the render thread
  static bool RenderProcessorThreadFunc(void* context) {
    return reinterpret_cast<AudioProcessingImplLockTest*>(context)
        ->render_thread_state_.Process();
  }

  // Thread callback for the capture thread
  static bool CaptureProcessorThreadFunc(void* context) {
    return reinterpret_cast<AudioProcessingImplLockTest*>(context)
        ->capture_thread_state_.Process();
  }

  // Thread callback for the stats thread
  static bool StatsProcessorThreadFunc(void* context) {
    return reinterpret_cast<AudioProcessingImplLockTest*>(context)
        ->stats_thread_state_.Process();
  }

  // Tests whether all the required render and capture side calls have been
  // done.
  bool TestDone() {
    return frame_counters_.BothCountersExceedeThreshold(
        test_config_.min_number_of_calls);
  }

  // Start the threads used in the test.
  void StartThreads() {
    render_thread_.Start();
    render_thread_.SetPriority(rtc::kRealtimePriority);
    capture_thread_.Start();
    capture_thread_.SetPriority(rtc::kRealtimePriority);
    stats_thread_.Start();
    stats_thread_.SetPriority(rtc::kNormalPriority);
  }

  // Event handlers for the test.
  rtc::Event test_complete_;
  rtc::Event render_call_event_;
  rtc::Event capture_call_event_;

  // Thread related variables.
  rtc::PlatformThread render_thread_;
  rtc::PlatformThread capture_thread_;
  rtc::PlatformThread stats_thread_;
  mutable RandomGenerator rand_gen_;

  std::unique_ptr<AudioProcessing> apm_;
  TestConfig test_config_;
  FrameCounters frame_counters_;
  RenderProcessor render_thread_state_;
  CaptureProcessor capture_thread_state_;
  StatsProcessor stats_thread_state_;
};

// Sleeps a random time between 0 and max_sleep milliseconds.
void SleepRandomMs(int max_sleep, RandomGenerator* rand_gen) {
  int sleeptime = rand_gen->RandInt(0, max_sleep);
  SleepMs(sleeptime);
}

// Populates a float audio frame with random data.
void PopulateAudioFrame(float** frame,
                        float amplitude,
                        size_t num_channels,
                        size_t samples_per_channel,
                        RandomGenerator* rand_gen) {
  for (size_t ch = 0; ch < num_channels; ch++) {
    for (size_t k = 0; k < samples_per_channel; k++) {
      // Store random 16 bit quantized float number between +-amplitude.
      frame[ch][k] = amplitude * (2 * rand_gen->RandFloat() - 1);
    }
  }
}

// Populates an audioframe frame of AudioFrame type with random data.
void PopulateAudioFrame(AudioFrame* frame,
                        int16_t amplitude,
                        RandomGenerator* rand_gen) {
  ASSERT_GT(amplitude, 0);
  ASSERT_LE(amplitude, 32767);
  int16_t* frame_data = frame->mutable_data();
  for (size_t ch = 0; ch < frame->num_channels_; ch++) {
    for (size_t k = 0; k < frame->samples_per_channel_; k++) {
      // Store random 16 bit number between -(amplitude+1) and
      // amplitude.
      frame_data[k * ch] =
          rand_gen->RandInt(2 * amplitude + 1) - amplitude - 1;
    }
  }
}

AudioProcessingImplLockTest::AudioProcessingImplLockTest()
    : test_complete_(false, false),
      render_call_event_(false, false),
      capture_call_event_(false, false),
      render_thread_(RenderProcessorThreadFunc, this, "render"),
      capture_thread_(CaptureProcessorThreadFunc, this, "capture"),
      stats_thread_(StatsProcessorThreadFunc, this, "stats"),
      apm_(AudioProcessingImpl::Create()),
      render_thread_state_(kMaxFrameSize,
                           &rand_gen_,
                           &render_call_event_,
                           &capture_call_event_,
                           &frame_counters_,
                           this,
                           &test_config_,
                           apm_.get()),
      capture_thread_state_(kMaxFrameSize,
                            &rand_gen_,
                            &render_call_event_,
                            &capture_call_event_,
                            &frame_counters_,
                            this,
                            &test_config_,
                            apm_.get()),
      stats_thread_state_(&rand_gen_, &test_config_, apm_.get()) {}

// Run the test with a timeout.
bool AudioProcessingImplLockTest::RunTest() {
  StartThreads();
  return test_complete_.Wait(kTestTimeOutLimit);
}

bool AudioProcessingImplLockTest::MaybeEndTest() {
  if (HasFatalFailure() || TestDone()) {
    test_complete_.Set();
    return true;
  }
  return false;
}

// Setup of test and APM.
void AudioProcessingImplLockTest::SetUp() {
  test_config_ = static_cast<TestConfig>(GetParam());

  ASSERT_EQ(apm_->kNoError, apm_->level_estimator()->Enable(true));
  ASSERT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));

  ASSERT_EQ(apm_->kNoError,
            apm_->gain_control()->set_mode(GainControl::kAdaptiveDigital));
  ASSERT_EQ(apm_->kNoError, apm_->gain_control()->Enable(true));

  ASSERT_EQ(apm_->kNoError, apm_->noise_suppression()->Enable(true));
  ASSERT_EQ(apm_->kNoError, apm_->voice_detection()->Enable(true));

  Config config;
  if (test_config_.aec_type == AecType::AecTurnedOff) {
    ASSERT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false));
    ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
  } else if (test_config_.aec_type ==
             AecType::BasicWebRtcAecSettingsWithAecMobile) {
    ASSERT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(true));
    ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(false));
  } else {
    ASSERT_EQ(apm_->kNoError, apm_->echo_control_mobile()->Enable(false));
    ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->Enable(true));
    ASSERT_EQ(apm_->kNoError, apm_->echo_cancellation()->enable_metrics(true));
    ASSERT_EQ(apm_->kNoError,
              apm_->echo_cancellation()->enable_delay_logging(true));

    config.Set<ExtendedFilter>(
        new ExtendedFilter(test_config_.aec_type ==
                           AecType::BasicWebRtcAecSettingsWithExtentedFilter));

    config.Set<DelayAgnostic>(
        new DelayAgnostic(test_config_.aec_type ==
                          AecType::BasicWebRtcAecSettingsWithDelayAgnosticAec));

    apm_->SetExtraOptions(config);
  }
}

void AudioProcessingImplLockTest::TearDown() {
  render_call_event_.Set();
  capture_call_event_.Set();
  render_thread_.Stop();
  capture_thread_.Stop();
  stats_thread_.Stop();
}

StatsProcessor::StatsProcessor(RandomGenerator* rand_gen,
                               TestConfig* test_config,
                               AudioProcessing* apm)
    : rand_gen_(rand_gen), test_config_(test_config), apm_(apm) {}

// Implements the callback functionality for the statistics
// collection thread.
bool StatsProcessor::Process() {
  SleepRandomMs(100, rand_gen_);

  EXPECT_EQ(apm_->echo_cancellation()->is_enabled(),
            ((test_config_->aec_type != AecType::AecTurnedOff) &&
             (test_config_->aec_type !=
              AecType::BasicWebRtcAecSettingsWithAecMobile)));
  apm_->echo_cancellation()->stream_drift_samples();
  EXPECT_EQ(apm_->echo_control_mobile()->is_enabled(),
            (test_config_->aec_type != AecType::AecTurnedOff) &&
                (test_config_->aec_type ==
                 AecType::BasicWebRtcAecSettingsWithAecMobile));
  EXPECT_TRUE(apm_->gain_control()->is_enabled());
  EXPECT_TRUE(apm_->noise_suppression()->is_enabled());

  // The below return values are not testable.
  apm_->noise_suppression()->speech_probability();
  apm_->voice_detection()->is_enabled();

  return true;
}

const float CaptureProcessor::kCaptureInputFloatLevel = 0.03125f;

CaptureProcessor::CaptureProcessor(int max_frame_size,
                                   RandomGenerator* rand_gen,
                                   rtc::Event* render_call_event,
                                   rtc::Event* capture_call_event,
                                   FrameCounters* shared_counters_state,
                                   AudioProcessingImplLockTest* test_framework,
                                   TestConfig* test_config,
                                   AudioProcessing* apm)
    : rand_gen_(rand_gen),
      render_call_event_(render_call_event),
      capture_call_event_(capture_call_event),
      frame_counters_(shared_counters_state),
      test_(test_framework),
      test_config_(test_config),
      apm_(apm),
      frame_data_(max_frame_size) {}

// Implements the callback functionality for the capture thread.
bool CaptureProcessor::Process() {
  // Sleep a random time to simulate thread jitter.
  SleepRandomMs(3, rand_gen_);

  // Check whether the test is done.
  if (test_->MaybeEndTest()) {
    return false;
  }

  // Ensure that the number of render and capture calls do not
  // differ too much.
  if (frame_counters_->CaptureMinusRenderCounters() > kMaxCallDifference) {
    render_call_event_->Wait(rtc::Event::kForever);
  }

  // Apply any specified capture side APM non-processing runtime calls.
  ApplyRuntimeSettingScheme();

  // Apply the capture side processing call.
  CallApmCaptureSide();

  // Increase the number of capture-side calls.
  frame_counters_->IncreaseCaptureCounter();

  // Flag to the render thread that another capture API call has occurred
  // by triggering this threads call event.
  capture_call_event_->Set();

  return true;
}

// Prepares a frame with relevant audio data and metadata.
void CaptureProcessor::PrepareFrame() {
  // Restrict to a common fixed sample rate if the AudioFrame
  // interface is used.
  if (test_config_->capture_api_function ==
      CaptureApiImpl::ProcessStreamImpl1) {
    frame_data_.input_sample_rate_hz = test_config_->initial_sample_rate_hz;
    frame_data_.output_sample_rate_hz = test_config_->initial_sample_rate_hz;
  }

  // Prepare the audioframe data and metadata.
  frame_data_.input_samples_per_channel =
      frame_data_.input_sample_rate_hz * AudioProcessing::kChunkSizeMs / 1000;
  frame_data_.frame.sample_rate_hz_ = frame_data_.input_sample_rate_hz;
  frame_data_.frame.num_channels_ = frame_data_.input_number_of_channels;
  frame_data_.frame.samples_per_channel_ =
      frame_data_.input_samples_per_channel;
  PopulateAudioFrame(&frame_data_.frame, kCaptureInputFixLevel, rand_gen_);

  // Prepare the float audio input data and metadata.
  frame_data_.input_stream_config.set_sample_rate_hz(
      frame_data_.input_sample_rate_hz);
  frame_data_.input_stream_config.set_num_channels(
      frame_data_.input_number_of_channels);
  frame_data_.input_stream_config.set_has_keyboard(false);
  PopulateAudioFrame(&frame_data_.input_frame[0], kCaptureInputFloatLevel,
                     frame_data_.input_number_of_channels,
                     frame_data_.input_samples_per_channel, rand_gen_);
  frame_data_.input_channel_layout =
      (frame_data_.input_number_of_channels == 1
           ? AudioProcessing::ChannelLayout::kMono
           : AudioProcessing::ChannelLayout::kStereo);

  // Prepare the float audio output data and metadata.
  frame_data_.output_samples_per_channel =
      frame_data_.output_sample_rate_hz * AudioProcessing::kChunkSizeMs / 1000;
  frame_data_.output_stream_config.set_sample_rate_hz(
      frame_data_.output_sample_rate_hz);
  frame_data_.output_stream_config.set_num_channels(
      frame_data_.output_number_of_channels);
  frame_data_.output_stream_config.set_has_keyboard(false);
  frame_data_.output_channel_layout =
      (frame_data_.output_number_of_channels == 1
           ? AudioProcessing::ChannelLayout::kMono
           : AudioProcessing::ChannelLayout::kStereo);
}

// Applies the capture side processing API call.
void CaptureProcessor::CallApmCaptureSide() {
  // Prepare a proper capture side processing API call input.
  PrepareFrame();

  // Set the stream delay.
  apm_->set_stream_delay_ms(30);

  // Set the analog level.
  apm_->gain_control()->set_stream_analog_level(80);

  // Call the specified capture side API processing method.
  int result = AudioProcessing::kNoError;
  switch (test_config_->capture_api_function) {
    case CaptureApiImpl::ProcessStreamImpl1:
      result = apm_->ProcessStream(&frame_data_.frame);
      break;
    case CaptureApiImpl::ProcessStreamImpl2:
      result = apm_->ProcessStream(
          &frame_data_.input_frame[0], frame_data_.input_samples_per_channel,
          frame_data_.input_sample_rate_hz, frame_data_.input_channel_layout,
          frame_data_.output_sample_rate_hz, frame_data_.output_channel_layout,
          &frame_data_.output_frame[0]);
      break;
    case CaptureApiImpl::ProcessStreamImpl3:
      result = apm_->ProcessStream(
          &frame_data_.input_frame[0], frame_data_.input_stream_config,
          frame_data_.output_stream_config, &frame_data_.output_frame[0]);
      break;
    default:
      FAIL();
  }

  // Retrieve the new analog level.
  apm_->gain_control()->stream_analog_level();

  // Check the return code for error.
  ASSERT_EQ(AudioProcessing::kNoError, result);
}

// Applies any runtime capture APM API calls and audio stream characteristics
// specified by the scheme for the test.
void CaptureProcessor::ApplyRuntimeSettingScheme() {
  const int capture_count_local = frame_counters_->GetCaptureCounter();

  // Update the number of channels and sample rates for the input and output.
  // Note that the counts frequencies for when to set parameters
  // are set using prime numbers in order to ensure that the
  // permutation scheme in the parameter setting changes.
  switch (test_config_->runtime_parameter_setting_scheme) {
    case RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme:
      if (capture_count_local == 0)
        frame_data_.input_sample_rate_hz = 16000;
      else if (capture_count_local % 11 == 0)
        frame_data_.input_sample_rate_hz = 32000;
      else if (capture_count_local % 73 == 0)
        frame_data_.input_sample_rate_hz = 48000;
      else if (capture_count_local % 89 == 0)
        frame_data_.input_sample_rate_hz = 16000;
      else if (capture_count_local % 97 == 0)
        frame_data_.input_sample_rate_hz = 8000;

      if (capture_count_local == 0)
        frame_data_.input_number_of_channels = 1;
      else if (capture_count_local % 4 == 0)
        frame_data_.input_number_of_channels =
            (frame_data_.input_number_of_channels == 1 ? 2 : 1);

      if (capture_count_local == 0)
        frame_data_.output_sample_rate_hz = 16000;
      else if (capture_count_local % 5 == 0)
        frame_data_.output_sample_rate_hz = 32000;
      else if (capture_count_local % 47 == 0)
        frame_data_.output_sample_rate_hz = 48000;
      else if (capture_count_local % 53 == 0)
        frame_data_.output_sample_rate_hz = 16000;
      else if (capture_count_local % 71 == 0)
        frame_data_.output_sample_rate_hz = 8000;

      if (capture_count_local == 0)
        frame_data_.output_number_of_channels = 1;
      else if (capture_count_local % 8 == 0)
        frame_data_.output_number_of_channels =
            (frame_data_.output_number_of_channels == 1 ? 2 : 1);
      break;
    case RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme:
      if (capture_count_local % 2 == 0) {
        frame_data_.input_number_of_channels = 1;
        frame_data_.input_sample_rate_hz = 16000;
        frame_data_.output_number_of_channels = 1;
        frame_data_.output_sample_rate_hz = 16000;
      } else {
        frame_data_.input_number_of_channels =
            (frame_data_.input_number_of_channels == 1 ? 2 : 1);
        if (frame_data_.input_sample_rate_hz == 8000)
          frame_data_.input_sample_rate_hz = 16000;
        else if (frame_data_.input_sample_rate_hz == 16000)
          frame_data_.input_sample_rate_hz = 32000;
        else if (frame_data_.input_sample_rate_hz == 32000)
          frame_data_.input_sample_rate_hz = 48000;
        else if (frame_data_.input_sample_rate_hz == 48000)
          frame_data_.input_sample_rate_hz = 8000;

        frame_data_.output_number_of_channels =
            (frame_data_.output_number_of_channels == 1 ? 2 : 1);
        if (frame_data_.output_sample_rate_hz == 8000)
          frame_data_.output_sample_rate_hz = 16000;
        else if (frame_data_.output_sample_rate_hz == 16000)
          frame_data_.output_sample_rate_hz = 32000;
        else if (frame_data_.output_sample_rate_hz == 32000)
          frame_data_.output_sample_rate_hz = 48000;
        else if (frame_data_.output_sample_rate_hz == 48000)
          frame_data_.output_sample_rate_hz = 8000;
      }
      break;
    case RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme:
      if (capture_count_local == 0) {
        frame_data_.input_sample_rate_hz = 16000;
        frame_data_.input_number_of_channels = 1;
        frame_data_.output_sample_rate_hz = 16000;
        frame_data_.output_number_of_channels = 1;
      }
      break;
    case RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme:
      if (capture_count_local == 0) {
        frame_data_.input_sample_rate_hz = 16000;
        frame_data_.input_number_of_channels = 2;
        frame_data_.output_sample_rate_hz = 16000;
        frame_data_.output_number_of_channels = 2;
      }
      break;
    default:
      FAIL();
  }

  // Call any specified runtime APM setter and
  // getter calls.
  switch (test_config_->runtime_parameter_setting_scheme) {
    case RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme:
    case RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme:
      break;
    case RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme:
    case RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme:
      if (capture_count_local % 2 == 0) {
        ASSERT_EQ(AudioProcessing::Error::kNoError,
                  apm_->set_stream_delay_ms(30));
        apm_->set_stream_key_pressed(true);
        apm_->set_delay_offset_ms(15);
        EXPECT_EQ(apm_->delay_offset_ms(), 15);
      } else {
        ASSERT_EQ(AudioProcessing::Error::kNoError,
                  apm_->set_stream_delay_ms(50));
        apm_->set_stream_key_pressed(false);
        apm_->set_delay_offset_ms(20);
        EXPECT_EQ(apm_->delay_offset_ms(), 20);
        apm_->delay_offset_ms();
      }
      break;
    default:
      FAIL();
  }

  // Restric the number of output channels not to exceed
  // the number of input channels.
  frame_data_.output_number_of_channels =
      std::min(frame_data_.output_number_of_channels,
               frame_data_.input_number_of_channels);
}

const float RenderProcessor::kRenderInputFloatLevel = 0.5f;

RenderProcessor::RenderProcessor(int max_frame_size,
                                 RandomGenerator* rand_gen,
                                 rtc::Event* render_call_event,
                                 rtc::Event* capture_call_event,
                                 FrameCounters* shared_counters_state,
                                 AudioProcessingImplLockTest* test_framework,
                                 TestConfig* test_config,
                                 AudioProcessing* apm)
    : rand_gen_(rand_gen),
      render_call_event_(render_call_event),
      capture_call_event_(capture_call_event),
      frame_counters_(shared_counters_state),
      test_(test_framework),
      test_config_(test_config),
      apm_(apm),
      frame_data_(max_frame_size) {}

// Implements the callback functionality for the render thread.
bool RenderProcessor::Process() {
  // Conditional wait to ensure that a capture call has been done
  // before the first render call is performed (implicitly
  // required by the APM API).
  if (first_render_call_) {
    capture_call_event_->Wait(rtc::Event::kForever);
    first_render_call_ = false;
  }

  // Sleep a random time to simulate thread jitter.
  SleepRandomMs(3, rand_gen_);

  // Check whether the test is done.
  if (test_->MaybeEndTest()) {
    return false;
  }

  // Ensure that the number of render and capture calls do not
  // differ too much.
  if (frame_counters_->RenderMinusCaptureCounters() > kMaxCallDifference) {
    capture_call_event_->Wait(rtc::Event::kForever);
  }

  // Apply any specified render side APM non-processing runtime calls.
  ApplyRuntimeSettingScheme();

  // Apply the render side processing call.
  CallApmRenderSide();

  // Increase the number of render-side calls.
  frame_counters_->IncreaseRenderCounter();

  // Flag to the capture thread that another render API call has occurred
  // by triggering this threads call event.
  render_call_event_->Set();
  return true;
}

// Prepares the render side frame and the accompanying metadata
// with the appropriate information.
void RenderProcessor::PrepareFrame() {
  // Restrict to a common fixed sample rate if the AudioFrame interface is
  // used.
  if ((test_config_->render_api_function ==
       RenderApiImpl::ProcessReverseStreamImpl1) ||
      (test_config_->aec_type !=
       AecType::BasicWebRtcAecSettingsWithAecMobile)) {
    frame_data_.input_sample_rate_hz = test_config_->initial_sample_rate_hz;
    frame_data_.output_sample_rate_hz = test_config_->initial_sample_rate_hz;
  }

  // Prepare the audioframe data and metadata
  frame_data_.input_samples_per_channel =
      frame_data_.input_sample_rate_hz * AudioProcessing::kChunkSizeMs / 1000;
  frame_data_.frame.sample_rate_hz_ = frame_data_.input_sample_rate_hz;
  frame_data_.frame.num_channels_ = frame_data_.input_number_of_channels;
  frame_data_.frame.samples_per_channel_ =
      frame_data_.input_samples_per_channel;
  PopulateAudioFrame(&frame_data_.frame, kRenderInputFixLevel, rand_gen_);

  // Prepare the float audio input data and metadata.
  frame_data_.input_stream_config.set_sample_rate_hz(
      frame_data_.input_sample_rate_hz);
  frame_data_.input_stream_config.set_num_channels(
      frame_data_.input_number_of_channels);
  frame_data_.input_stream_config.set_has_keyboard(false);
  PopulateAudioFrame(&frame_data_.input_frame[0], kRenderInputFloatLevel,
                     frame_data_.input_number_of_channels,
                     frame_data_.input_samples_per_channel, rand_gen_);
  frame_data_.input_channel_layout =
      (frame_data_.input_number_of_channels == 1
           ? AudioProcessing::ChannelLayout::kMono
           : AudioProcessing::ChannelLayout::kStereo);

  // Prepare the float audio output data and metadata.
  frame_data_.output_samples_per_channel =
      frame_data_.output_sample_rate_hz * AudioProcessing::kChunkSizeMs / 1000;
  frame_data_.output_stream_config.set_sample_rate_hz(
      frame_data_.output_sample_rate_hz);
  frame_data_.output_stream_config.set_num_channels(
      frame_data_.output_number_of_channels);
  frame_data_.output_stream_config.set_has_keyboard(false);
  frame_data_.output_channel_layout =
      (frame_data_.output_number_of_channels == 1
           ? AudioProcessing::ChannelLayout::kMono
           : AudioProcessing::ChannelLayout::kStereo);
}

// Makes the render side processing API call.
void RenderProcessor::CallApmRenderSide() {
  // Prepare a proper render side processing API call input.
  PrepareFrame();

  // Call the specified render side API processing method.
  int result = AudioProcessing::kNoError;
  switch (test_config_->render_api_function) {
    case RenderApiImpl::ProcessReverseStreamImpl1:
      result = apm_->ProcessReverseStream(&frame_data_.frame);
      break;
    case RenderApiImpl::ProcessReverseStreamImpl2:
      result = apm_->ProcessReverseStream(
          &frame_data_.input_frame[0], frame_data_.input_stream_config,
          frame_data_.output_stream_config, &frame_data_.output_frame[0]);
      break;
    case RenderApiImpl::AnalyzeReverseStreamImpl:
      result = apm_->AnalyzeReverseStream(
          &frame_data_.input_frame[0], frame_data_.input_samples_per_channel,
          frame_data_.input_sample_rate_hz, frame_data_.input_channel_layout);
      break;
    default:
      FAIL();
  }

  // Check the return code for error.
  ASSERT_EQ(AudioProcessing::kNoError, result);
}

// Applies any render capture side APM API calls and audio stream
// characteristics
// specified by the scheme for the test.
void RenderProcessor::ApplyRuntimeSettingScheme() {
  const int render_count_local = frame_counters_->GetRenderCounter();

  // Update the number of channels and sample rates for the input and output.
  // Note that the counts frequencies for when to set parameters
  // are set using prime numbers in order to ensure that the
  // permutation scheme in the parameter setting changes.
  switch (test_config_->runtime_parameter_setting_scheme) {
    case RuntimeParameterSettingScheme::SparseStreamMetadataChangeScheme:
      if (render_count_local == 0)
        frame_data_.input_sample_rate_hz = 16000;
      else if (render_count_local % 47 == 0)
        frame_data_.input_sample_rate_hz = 32000;
      else if (render_count_local % 71 == 0)
        frame_data_.input_sample_rate_hz = 48000;
      else if (render_count_local % 79 == 0)
        frame_data_.input_sample_rate_hz = 16000;
      else if (render_count_local % 83 == 0)
        frame_data_.input_sample_rate_hz = 8000;

      if (render_count_local == 0)
        frame_data_.input_number_of_channels = 1;
      else if (render_count_local % 4 == 0)
        frame_data_.input_number_of_channels =
            (frame_data_.input_number_of_channels == 1 ? 2 : 1);

      if (render_count_local == 0)
        frame_data_.output_sample_rate_hz = 16000;
      else if (render_count_local % 17 == 0)
        frame_data_.output_sample_rate_hz = 32000;
      else if (render_count_local % 19 == 0)
        frame_data_.output_sample_rate_hz = 48000;
      else if (render_count_local % 29 == 0)
        frame_data_.output_sample_rate_hz = 16000;
      else if (render_count_local % 61 == 0)
        frame_data_.output_sample_rate_hz = 8000;

      if (render_count_local == 0)
        frame_data_.output_number_of_channels = 1;
      else if (render_count_local % 8 == 0)
        frame_data_.output_number_of_channels =
            (frame_data_.output_number_of_channels == 1 ? 2 : 1);
      break;
    case RuntimeParameterSettingScheme::ExtremeStreamMetadataChangeScheme:
      if (render_count_local == 0) {
        frame_data_.input_number_of_channels = 1;
        frame_data_.input_sample_rate_hz = 16000;
        frame_data_.output_number_of_channels = 1;
        frame_data_.output_sample_rate_hz = 16000;
      } else {
        frame_data_.input_number_of_channels =
            (frame_data_.input_number_of_channels == 1 ? 2 : 1);
        if (frame_data_.input_sample_rate_hz == 8000)
          frame_data_.input_sample_rate_hz = 16000;
        else if (frame_data_.input_sample_rate_hz == 16000)
          frame_data_.input_sample_rate_hz = 32000;
        else if (frame_data_.input_sample_rate_hz == 32000)
          frame_data_.input_sample_rate_hz = 48000;
        else if (frame_data_.input_sample_rate_hz == 48000)
          frame_data_.input_sample_rate_hz = 8000;

        frame_data_.output_number_of_channels =
            (frame_data_.output_number_of_channels == 1 ? 2 : 1);
        if (frame_data_.output_sample_rate_hz == 8000)
          frame_data_.output_sample_rate_hz = 16000;
        else if (frame_data_.output_sample_rate_hz == 16000)
          frame_data_.output_sample_rate_hz = 32000;
        else if (frame_data_.output_sample_rate_hz == 32000)
          frame_data_.output_sample_rate_hz = 48000;
        else if (frame_data_.output_sample_rate_hz == 48000)
          frame_data_.output_sample_rate_hz = 8000;
      }
      break;
    case RuntimeParameterSettingScheme::FixedMonoStreamMetadataScheme:
      if (render_count_local == 0) {
        frame_data_.input_sample_rate_hz = 16000;
        frame_data_.input_number_of_channels = 1;
        frame_data_.output_sample_rate_hz = 16000;
        frame_data_.output_number_of_channels = 1;
      }
      break;
    case RuntimeParameterSettingScheme::FixedStereoStreamMetadataScheme:
      if (render_count_local == 0) {
        frame_data_.input_sample_rate_hz = 16000;
        frame_data_.input_number_of_channels = 2;
        frame_data_.output_sample_rate_hz = 16000;
        frame_data_.output_number_of_channels = 2;
      }
      break;
    default:
      FAIL();
  }

  // Restric the number of output channels not to exceed
  // the number of input channels.
  frame_data_.output_number_of_channels =
      std::min(frame_data_.output_number_of_channels,
               frame_data_.input_number_of_channels);
}

}  // anonymous namespace

TEST_P(AudioProcessingImplLockTest, LockTest) {
  // Run test and verify that it did not time out.
  ASSERT_TRUE(RunTest());
}

// Instantiate tests from the extreme test configuration set.
INSTANTIATE_TEST_CASE_P(
    DISABLED_AudioProcessingImplLockExtensive,
    AudioProcessingImplLockTest,
    ::testing::ValuesIn(TestConfig::GenerateExtensiveTestConfigs()));

INSTANTIATE_TEST_CASE_P(
    AudioProcessingImplLockBrief,
    AudioProcessingImplLockTest,
    ::testing::ValuesIn(TestConfig::GenerateBriefTestConfigs()));

}  // namespace webrtc


text:
"use strict";
class CommandBus {
    constructor(ioc) {
        this.ioc = ioc;
    }
    register(name, command, handler) {
        command.__command_name__ = name;
        this.ioc.addClass('__Infra-Command_command__.' + name, command);
        this.ioc.addClass('__Infra-Command_handler__.' + name, handler);
    }
    execute(command) {
        var promise;
        try {
            var handler = this.ioc.get('__Infra-Command_handler__.' + command.constructor.__command_name__);
            var handled = handler.handle(command);
            if (handled instanceof Promise) {
                promise = handled;
            }
            else {
                promise = new Promise((resolve, reject) => {
                    resolve(handled);
                });
            }
        }
        catch (e) {
            promise = new Promise((resolve, reject) => {
                reject(e);
            });
        }
        return promise;
    }
}
exports.CommandBus = CommandBus;
//# sourceMappingURL=CommandBus.js.map


text:
#include "../lists.h"
#include "../mem.h"
#include "../native.h"
#include "../object.h"
#include "../strings.h"
#include "../variable.h"

/* Use quite klugy approach: when we add order dependency from 'a' to 'b', just
 * append 'b' to of value of variable 'a'.
 */
LIST * add_pair( FRAME * frame, int flags )
{
    LIST * arg = lol_get( frame->args, 0 );
    LISTITER iter = list_begin( arg );
    LISTITER const end = list_end( arg );
    var_set( frame->module, list_item( iter ), list_copy_range( arg, list_next(
        iter ), end ), VAR_APPEND );
    return L0;
}

/* Given a list and a value, returns position of that value in the list, or -1
 * if not found.
 */
int list_index( LIST * list, OBJECT * value )
{
    int result = 0;
    LISTITER iter = list_begin( list );
    LISTITER const end = list_end( list );
    for ( ; iter != end; iter = list_next( iter ), ++result )
        if ( object_equal( list_item( iter ), value ) )
            return result;
    return -1;
}

enum colors { white, gray, black };

/* Main routine for topological sort. Calls itself recursively on all adjacent
 * vertices which were not yet visited. After that, 'current_vertex' is added to
 * '*result_ptr'.
 */
void do_ts( int * * graph, int current_vertex, int * colors, int * * result_ptr
    )
{
    int i;

    colors[ current_vertex ] = gray;
    for ( i = 0; graph[ current_vertex ][ i ] != -1; ++i )
    {
        int adjacent_vertex = graph[ current_vertex ][ i ];
        if ( colors[ adjacent_vertex ] == white )
            do_ts( graph, adjacent_vertex, colors, result_ptr );
        /* The vertex is either black, in which case we do not have to do
         * anything, or gray, in which case we have a loop. If we have a loop,
         * it is not clear what useful diagnostic we can emit, so we emit
         * nothing.
         */
    }
    colors[ current_vertex ] = black;
    **result_ptr = current_vertex;
    ( *result_ptr )++;
}

void topological_sort( int * * graph, int num_vertices, int * result )
{
    int i;
    int * colors = ( int * )BJAM_CALLOC( num_vertices, sizeof( int ) );
    for ( i = 0; i < num_vertices; ++i )
        colors[ i ] = white;

    for ( i = num_vertices - 1; i >= 0; --i )
        if ( colors[ i ] == white )
            do_ts( graph, i, colors, &result );

    BJAM_FREE( colors );
}

LIST * order( FRAME * frame, int flags )
{
    LIST * arg = lol_get( frame->args, 0 );
    LIST * result = L0;
    int src;
    LISTITER iter = list_begin( arg );
    LISTITER const end = list_end( arg );

    /* We need to create a graph of order dependencies between the passed
     * objects. We assume there are no duplicates passed to 'add_pair'.
     */
    int length = list_length( arg );
    int * * graph = ( int * * )BJAM_CALLOC( length, sizeof( int * ) );
    int * order = ( int * )BJAM_MALLOC( ( length + 1 ) * sizeof( int ) );

    for ( src = 0; iter != end; iter = list_next( iter ), ++src )
    {
        /* For all objects this one depends upon, add elements to 'graph'. */
        LIST * dependencies = var_get( frame->module, list_item( iter ) );
        int index = 0;
        LISTITER dep_iter = list_begin( dependencies );
        LISTITER const dep_end = list_end( dependencies );

        graph[ src ] = ( int * )BJAM_CALLOC( list_length( dependencies ) + 1,
            sizeof( int ) );
        for ( ; dep_iter != dep_end; dep_iter = list_next( dep_iter ) )
        {
            int const dst = list_index( arg, list_item( dep_iter ) );
            if ( dst != -1 )
                graph[ src ][ index++ ] = dst;
        }
        graph[ src ][ index ] = -1;
    }

    topological_sort( graph, length, order );

    {
        int index = length - 1;
        for ( ; index >= 0; --index )
        {
            int i;
            LISTITER iter = list_begin( arg );
            LISTITER const end = list_end( arg );
            for ( i = 0; i < order[ index ]; ++i, iter = list_next( iter ) );
            result = list_push_back( result, object_copy( list_item( iter ) ) );
        }
    }

    /* Clean up */
    {
        int i;
        for ( i = 0; i < length; ++i )
            BJAM_FREE( graph[ i ] );
        BJAM_FREE( graph );
        BJAM_FREE( order );
    }

    return result;
}

void init_order()
{
    {
        char const * args[] = { "first", "second", 0 };
        declare_native_rule( "class@order", "add-pair", args, add_pair, 1 );
    }

    {
        char const * args[] = { "objects", "*", 0 };
        declare_native_rule( "class@order", "order", args, order, 1 );
    }
}


text:
package org.apache.camel.impl.console;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.util.Map;

import org.apache.camel.spi.Configurer;
import org.apache.camel.spi.annotations.DevConsole;
import org.apache.camel.util.json.JsonObject;

import static org.apache.camel.util.UnitUtils.printUnitFromBytesDot;

@DevConsole("memory")
@Configurer(bootstrap = true)
public class MemoryDevConsole extends AbstractDevConsole {

    public MemoryDevConsole() {
        super("jvm", "memory", "JVM Memory", "Displays JVM memory information");
    }

    @Override
    protected String doCallText(Map<String, Object> options) {
        StringBuilder sb = new StringBuilder();

        MemoryMXBean mb = ManagementFactory.getMemoryMXBean();
        if (mb != null) {
            sb.append(String.format("Heap Init: %s\n", printUnitFromBytesDot(mb.getHeapMemoryUsage().getInit())));
            sb.append(String.format("Heap Max: %s\n", printUnitFromBytesDot(mb.getHeapMemoryUsage().getMax())));
            sb.append(String.format("Heap Used: %s\n", printUnitFromBytesDot(mb.getHeapMemoryUsage().getUsed())));
            sb.append(String.format("Heap Committed: %s\n", printUnitFromBytesDot(mb.getHeapMemoryUsage().getCommitted())));
            sb.append("\n");
            sb.append(String.format("Non-Heap Init: %s\n", printUnitFromBytesDot(mb.getNonHeapMemoryUsage().getInit())));
            sb.append(String.format("Non-Heap Max: %s\n", printUnitFromBytesDot(mb.getNonHeapMemoryUsage().getMax())));
            sb.append(String.format("Non-Heap Used: %s\n", printUnitFromBytesDot(mb.getNonHeapMemoryUsage().getUsed())));
            sb.append(String.format("Non-Heap Committed: %s\n",
                    printUnitFromBytesDot(mb.getNonHeapMemoryUsage().getCommitted())));
        }

        return sb.toString();
    }

    @Override
    protected JsonObject doCallJson(Map<String, Object> options) {
        JsonObject root = new JsonObject();

        MemoryMXBean mb = ManagementFactory.getMemoryMXBean();
        if (mb != null) {
            root.put("heapMemoryInit", printUnitFromBytesDot(mb.getHeapMemoryUsage().getInit()));
            root.put("heapMemoryMax", printUnitFromBytesDot(mb.getHeapMemoryUsage().getMax()));
            root.put("heapMemoryUsed", printUnitFromBytesDot(mb.getHeapMemoryUsage().getUsed()));
            root.put("heapMemoryCommitted", printUnitFromBytesDot(mb.getHeapMemoryUsage().getCommitted()));
            root.put("nonHeapMemoryInit", printUnitFromBytesDot(mb.getNonHeapMemoryUsage().getInit()));
            root.put("nonHeapMemoryMax", printUnitFromBytesDot(mb.getNonHeapMemoryUsage().getMax()));
            root.put("nonHeapMemoryUsed", printUnitFromBytesDot(mb.getNonHeapMemoryUsage().getUsed()));
            root.put("nonHeapMemoryCommitted", printUnitFromBytesDot(mb.getNonHeapMemoryUsage().getCommitted()));
        }

        return root;
    }
}


text:
var mongoose = require('mongoose');
var Step = require('step');
var _ = require('lodash');
var debug = require('debug')("chalk:stat:courses");
var Chalk = require('../Chalk');
var Const = require('../const');

module.exports = (name, cb) => {
  var id = Const.course[name];
  Step(
    function() {
      debug("Collecting Data...");
      console.log("Show data for %s", name);
      Chalk.Course.find({courseId: id}, this);
    },
    function(err, courses) {
      if(err) console.log(err);
      var group = this.group();
      _(courses).forEach((course) => {
        Chalk.Student.find({studentId: course.studentId}, group());
      });
    },
    require('./reduce-result'),
    require('./debug-student'),
    require('./debug-course')(name),
    function(err) {
      debug("Complete");
      if(err) console.log(err);
      this();
    },
    cb
  );
};


text:
sdog
====

A process monitor using an extremely limited (but still useful enough for me)
subset of the systemd watchdog protocol

"450 downloads in the last week" -- are people actually using this, or is pypi
just full of bots? o.o;;  I welcome your feedback if you are actually a person :)

```
Usage: sdog [options] -- daemon-to-run [daemon options]

Options:
  -h, --help              show this help message and exit
  -t N, --timeout=N       Maximum seconds between pings
  -r N, --respawn=N       Delay between respawns
  -s FILE, --socket=FILE  Path to socket
  -T NAME, --title=NAME   Daemon name (defaults to the first param after "--")
                          (Requires setproctitle module)
  -v, --verbose           Verbose mode
```

For Daemons
===========

There is the sdog.notifier module

```
from sdog.notifier import SDNotifier

def main():
    # Create the notifier
    sd = SDNotifier()

    # Connect to the work queue and signal that we're ready to go
    work_queue = WorkQueue("localhost:1234")
    sd.ready()

    while True:
        # Get some work and signal that we're working on it
        item = work_queue.get()
        sd.status("Processing %s" % item.name)

        # Do the work then signal that we are alive and running successfully
        do_some_work(item)
        sd.watchdog()
```

Protocol
========

The daemon will be launched with `NOTIFY_SOCKET=/some/path.sock` in its
environment; it should then write datagram packets into this socket:

```
READY=1      -- signal that the daemon has loaded, and to start monitoring
WATCHDOG=1   -- must be sent at least once every $timeout seconds
STATUS=blah  -- update the current status message
```


text:
require "rubygems"
require "active_resource"
require "utils/starsrrecord"
require "common/faust_constants"

class EmiStorageRecord < ActiveResource::Base
  self.format = :xml
end

class StorageRecord
  def initialize(element)
    @element = element

  end

  def to_hash

    rh = {}
    rh[FaustStorageData.RecordIdentity] = @element[SRecords.RecordId]
    rh[FaustStorageData.Site] = @element[SRecords.Site]
    rh[FaustStorageData.StorageMedia] = @element[SRecords.StorageMedia]
    rh[FaustStorageData.StorageShare] = @element[SRecords.StorageShare]
    rh[FaustStorageData.StorageClass] = @element[SRecords.StorageClass]
    rh[FaustStorageData.DirectoryPath] = @element[SRecords.DirectoryPath]
    rh[FaustStorageData.ResourceCapacityUsed] = @element[SRecords.ResourceCapacityUsed]
    rh[FaustStorageData.ResourceCapacityAllocated] = @element[SRecords.Resourcecapacityalloc]
    rh[FaustStorageData.StorageSystem] = @element[SRecords.StorageSystem]
    rh[FaustStorageData.Group] = @element[SRecords.Group]
    rh[FaustStorageData.StartTime] = @element[SRecords.StartTime]
    rh[FaustStorageData.EndTime] = @element[SRecords.EndTime]
    rh

  end

end