<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/test/trace_event_analyzer.h"
#include "base/version.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/tracing.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/gpu/gpu_blacklist.h"
#include "content/browser/gpu/gpu_data_manager.h"
#include "net/base/net_util.h"

namespace {

class GpuFeatureTest : public InProcessBrowserTest {
 public:
  GpuFeatureTest() {}

  virtual void SetUpCommandLine(CommandLine* command_line) {
    // This enables DOM automation for tab contents.
    EnableDOMAutomation();
  }

  void SetupBlacklist(const std::string& json_blacklist) {
    scoped_ptr<Version> os_version(Version::GetVersionFromString("1.0"));
    GpuBlacklist* blacklist = new GpuBlacklist("1.0 unknown");

    ASSERT_TRUE(blacklist->LoadGpuBlacklist(
        json_blacklist, GpuBlacklist::kAllOs));
    GpuDataManager::GetInstance()->SetBuiltInGpuBlacklist(blacklist);
  }

  void RunTest(const FilePath& url, bool expect_gpu_process) {
    using namespace trace_analyzer;

    FilePath test_path;
    PathService::Get(chrome::DIR_TEST_DATA, &test_path);
    test_path = test_path.Append(FILE_PATH_LITERAL("gpu"));
    test_path = test_path.Append(url);

    ASSERT_TRUE(file_util::PathExists(test_path))
        << "Missing test file: " << test_path.value();

    ASSERT_TRUE(tracing::BeginTracing("test_gpu"));

    ui_test_utils::DOMMessageQueue message_queue;
    // Have to use a new tab for the blacklist to work.
    ui_test_utils::NavigateToURLWithDisposition(
        browser(), net::FilePathToFileURL(test_path), NEW_FOREGROUND_TAB,
        ui_test_utils::BROWSER_TEST_NONE);
    // Wait for message indicating the test has finished running.
    ASSERT_TRUE(message_queue.WaitForMessage(NULL));

    std::string json_events;
    ASSERT_TRUE(tracing::EndTracing(&json_events));

    scoped_ptr<TraceAnalyzer> analyzer(TraceAnalyzer::Create(json_events));
    EXPECT_EQ(expect_gpu_process, analyzer->FindOneEvent(
        Query(EVENT_NAME) == Query::String("GpuProcessLaunched")) != NULL);
  }
};

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, AcceleratedCompositingAllowed) {
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(flags.flags(), 0u);

  const bool expect_gpu_process = true;
  const FilePath url(FILE_PATH_LITERAL("feature_compositing.html"));
  RunTest(url, expect_gpu_process);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, AcceleratedCompositingBlocked) {
  const std::string json_blacklist =
      "{\n"
      "  \"name\": \"gpu blacklist\",\n"
      "  \"version\": \"1.0\",\n"
      "  \"entries\": [\n"
      "    {\n"
      "      \"id\": 1,\n"
      "      \"blacklist\": [\n"
      "        \"accelerated_compositing\"\n"
      "      ]\n"
      "    }\n"
      "  ]\n"
      "}";
  SetupBlacklist(json_blacklist);
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(
      flags.flags(),
      static_cast<uint32>(GpuFeatureFlags::kGpuFeatureAcceleratedCompositing));

  const bool expect_gpu_process = false;
  const FilePath url(FILE_PATH_LITERAL("feature_compositing.html"));
  RunTest(url, expect_gpu_process);
}

#if defined(OS_LINUX)
// http://crbug.com/104142
#define WebGLAllowed FLAKY_WebGLAllowed
#endif
IN_PROC_BROWSER_TEST_F(GpuFeatureTest, WebGLAllowed) {
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(flags.flags(), 0u);

  const bool expect_gpu_process = true;
  const FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
  RunTest(url, expect_gpu_process);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, WebGLBlocked) {
  const std::string json_blacklist =
      "{\n"
      "  \"name\": \"gpu blacklist\",\n"
      "  \"version\": \"1.0\",\n"
      "  \"entries\": [\n"
      "    {\n"
      "      \"id\": 1,\n"
      "      \"blacklist\": [\n"
      "        \"webgl\"\n"
      "      ]\n"
      "    }\n"
      "  ]\n"
      "}";
  SetupBlacklist(json_blacklist);
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(
      flags.flags(),
      static_cast<uint32>(GpuFeatureFlags::kGpuFeatureWebgl));

  const bool expect_gpu_process = false;
  const FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
  RunTest(url, expect_gpu_process);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, Canvas2DAllowed) {
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(flags.flags(), 0u);

#if defined(OS_MACOSX)
  // TODO(zmo): enabling Mac when skia backend is enabled.
  const bool expect_gpu_process = false;
#else
  const bool expect_gpu_process = true;
#endif
  const FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
  RunTest(url, expect_gpu_process);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, Canvas2DBlocked) {
  const std::string json_blacklist =
      "{\n"
      "  \"name\": \"gpu blacklist\",\n"
      "  \"version\": \"1.0\",\n"
      "  \"entries\": [\n"
      "    {\n"
      "      \"id\": 1,\n"
      "      \"blacklist\": [\n"
      "        \"accelerated_2d_canvas\"\n"
      "      ]\n"
      "    }\n"
      "  ]\n"
      "}";
  SetupBlacklist(json_blacklist);
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(
      flags.flags(),
      static_cast<uint32>(GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas));

  const bool expect_gpu_process = false;
  const FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
  RunTest(url, expect_gpu_process);
}

}  // namespace anonymous

<commit_msg>Marking GpuFeatureTest.Canvas2DAllowed flaky on Linux.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/test/trace_event_analyzer.h"
#include "base/version.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/tracing.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/gpu/gpu_blacklist.h"
#include "content/browser/gpu/gpu_data_manager.h"
#include "net/base/net_util.h"

namespace {

class GpuFeatureTest : public InProcessBrowserTest {
 public:
  GpuFeatureTest() {}

  virtual void SetUpCommandLine(CommandLine* command_line) {
    // This enables DOM automation for tab contents.
    EnableDOMAutomation();
  }

  void SetupBlacklist(const std::string& json_blacklist) {
    scoped_ptr<Version> os_version(Version::GetVersionFromString("1.0"));
    GpuBlacklist* blacklist = new GpuBlacklist("1.0 unknown");

    ASSERT_TRUE(blacklist->LoadGpuBlacklist(
        json_blacklist, GpuBlacklist::kAllOs));
    GpuDataManager::GetInstance()->SetBuiltInGpuBlacklist(blacklist);
  }

  void RunTest(const FilePath& url, bool expect_gpu_process) {
    using namespace trace_analyzer;

    FilePath test_path;
    PathService::Get(chrome::DIR_TEST_DATA, &test_path);
    test_path = test_path.Append(FILE_PATH_LITERAL("gpu"));
    test_path = test_path.Append(url);

    ASSERT_TRUE(file_util::PathExists(test_path))
        << "Missing test file: " << test_path.value();

    ASSERT_TRUE(tracing::BeginTracing("test_gpu"));

    ui_test_utils::DOMMessageQueue message_queue;
    // Have to use a new tab for the blacklist to work.
    ui_test_utils::NavigateToURLWithDisposition(
        browser(), net::FilePathToFileURL(test_path), NEW_FOREGROUND_TAB,
        ui_test_utils::BROWSER_TEST_NONE);
    // Wait for message indicating the test has finished running.
    ASSERT_TRUE(message_queue.WaitForMessage(NULL));

    std::string json_events;
    ASSERT_TRUE(tracing::EndTracing(&json_events));

    scoped_ptr<TraceAnalyzer> analyzer(TraceAnalyzer::Create(json_events));
    EXPECT_EQ(expect_gpu_process, analyzer->FindOneEvent(
        Query(EVENT_NAME) == Query::String("GpuProcessLaunched")) != NULL);
  }
};

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, AcceleratedCompositingAllowed) {
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(flags.flags(), 0u);

  const bool expect_gpu_process = true;
  const FilePath url(FILE_PATH_LITERAL("feature_compositing.html"));
  RunTest(url, expect_gpu_process);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, AcceleratedCompositingBlocked) {
  const std::string json_blacklist =
      "{\n"
      "  \"name\": \"gpu blacklist\",\n"
      "  \"version\": \"1.0\",\n"
      "  \"entries\": [\n"
      "    {\n"
      "      \"id\": 1,\n"
      "      \"blacklist\": [\n"
      "        \"accelerated_compositing\"\n"
      "      ]\n"
      "    }\n"
      "  ]\n"
      "}";
  SetupBlacklist(json_blacklist);
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(
      flags.flags(),
      static_cast<uint32>(GpuFeatureFlags::kGpuFeatureAcceleratedCompositing));

  const bool expect_gpu_process = false;
  const FilePath url(FILE_PATH_LITERAL("feature_compositing.html"));
  RunTest(url, expect_gpu_process);
}

#if defined(OS_LINUX)
// http://crbug.com/104142
#define WebGLAllowed FLAKY_WebGLAllowed
#endif
IN_PROC_BROWSER_TEST_F(GpuFeatureTest, WebGLAllowed) {
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(flags.flags(), 0u);

  const bool expect_gpu_process = true;
  const FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
  RunTest(url, expect_gpu_process);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, WebGLBlocked) {
  const std::string json_blacklist =
      "{\n"
      "  \"name\": \"gpu blacklist\",\n"
      "  \"version\": \"1.0\",\n"
      "  \"entries\": [\n"
      "    {\n"
      "      \"id\": 1,\n"
      "      \"blacklist\": [\n"
      "        \"webgl\"\n"
      "      ]\n"
      "    }\n"
      "  ]\n"
      "}";
  SetupBlacklist(json_blacklist);
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(
      flags.flags(),
      static_cast<uint32>(GpuFeatureFlags::kGpuFeatureWebgl));

  const bool expect_gpu_process = false;
  const FilePath url(FILE_PATH_LITERAL("feature_webgl.html"));
  RunTest(url, expect_gpu_process);
}

#if defined(OS_LINUX)
// http://crbug.com/104142
#define Canvas2DAllowed FLAKY_Canvas2DAllowed
#endif
IN_PROC_BROWSER_TEST_F(GpuFeatureTest, Canvas2DAllowed) {
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(flags.flags(), 0u);

#if defined(OS_MACOSX)
  // TODO(zmo): enabling Mac when skia backend is enabled.
  const bool expect_gpu_process = false;
#else
  const bool expect_gpu_process = true;
#endif
  const FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
  RunTest(url, expect_gpu_process);
}

IN_PROC_BROWSER_TEST_F(GpuFeatureTest, Canvas2DBlocked) {
  const std::string json_blacklist =
      "{\n"
      "  \"name\": \"gpu blacklist\",\n"
      "  \"version\": \"1.0\",\n"
      "  \"entries\": [\n"
      "    {\n"
      "      \"id\": 1,\n"
      "      \"blacklist\": [\n"
      "        \"accelerated_2d_canvas\"\n"
      "      ]\n"
      "    }\n"
      "  ]\n"
      "}";
  SetupBlacklist(json_blacklist);
  GpuFeatureFlags flags = GpuDataManager::GetInstance()->GetGpuFeatureFlags();
  EXPECT_EQ(
      flags.flags(),
      static_cast<uint32>(GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas));

  const bool expect_gpu_process = false;
  const FilePath url(FILE_PATH_LITERAL("feature_canvas2d.html"));
  RunTest(url, expect_gpu_process);
}

}  // namespace anonymous

<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome_frame/test/net/fake_external_tab.h"

#include <exdisp.h>

#include "app/app_paths.h"
#include "app/resource_bundle.h"
#include "app/win_util.h"

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/i18n/icu_util.h"
#include "base/path_service.h"
#include "base/scoped_bstr_win.h"
#include "base/scoped_comptr_win.h"
#include "base/scoped_variant_win.h"

#include "chrome/browser/browser_prefs.h"
#include "chrome/browser/plugin_service.h"
#include "chrome/browser/process_singleton.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/web_cache_manager.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "chrome_frame/utils.h"
#include "chrome_frame/test/chrome_frame_test_utils.h"
#include "chrome_frame/test/net/dialog_watchdog.h"
#include "chrome_frame/test/net/test_automation_resource_message_filter.h"

namespace {

// A special command line switch to allow developers to manually launch the
// browser and debug CF inside the browser.
const wchar_t kManualBrowserLaunch[] = L"manual-browser";

// Pops up a message box after the test environment has been set up
// and before tearing it down.  Useful for when debugging tests and not
// the test environment that's been set up.
const wchar_t kPromptAfterSetup[] = L"prompt-after-setup";

const int kTestServerPort = 4666;
// The test HTML we use to initialize Chrome Frame.
// Note that there's a little trick in there to avoid an extra URL request
// that the browser will otherwise make for the site's favicon.
// If we don't do this the browser will create a new URL request after
// the CF page has been initialized and that URL request will confuse the
// global URL instance counter in the unit tests and subsequently trip
// some DCHECKs.
const char kChromeFrameHtml[] = ""
    "<meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\" />"
    "<link rel=\"shortcut icon\" href=\"file://c:\\favicon.ico\"/>"
    "Chrome Frame should now be loaded";

bool ShouldLaunchBrowser() {
  return !CommandLine::ForCurrentProcess()->HasSwitch(kManualBrowserLaunch);
}

bool PromptAfterSetup() {
  return CommandLine::ForCurrentProcess()->HasSwitch(kPromptAfterSetup);
}

}  // end namespace

FakeExternalTab::FakeExternalTab() {
  PathService::Get(chrome::DIR_USER_DATA, &overridden_user_dir_);
  GetProfilePath(&user_data_dir_);
  PathService::Override(chrome::DIR_USER_DATA, user_data_dir_);
  process_singleton_.reset(new ProcessSingleton(user_data_dir_));
}

FakeExternalTab::~FakeExternalTab() {
  if (!overridden_user_dir_.empty()) {
    PathService::Override(chrome::DIR_USER_DATA, overridden_user_dir_);
  }
}

std::wstring FakeExternalTab::GetProfileName() {
  return L"iexplore";
}

bool FakeExternalTab::GetProfilePath(FilePath* path) {
  if (!chrome::GetChromeFrameUserDataDirectory(path))
    return false;
  *path = path->Append(GetProfileName());
  return true;
}

void FakeExternalTab::Initialize() {
  DCHECK(g_browser_process == NULL);
  SystemMonitor system_monitor;

  // The gears plugin causes the PluginRequestInterceptor to kick in and it
  // will cause problems when it tries to intercept URL requests.
  PathService::Override(chrome::FILE_GEARS_PLUGIN, FilePath());

  icu_util::Initialize();

  chrome::RegisterPathProvider();
  app::RegisterPathProvider();

  // Load Chrome.dll as our resource dll.
  FilePath dll;
  PathService::Get(base::DIR_MODULE, &dll);
  dll = dll.Append(chrome::kBrowserResourcesDll);
  HMODULE res_mod = ::LoadLibraryExW(dll.value().c_str(),
      NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
  DCHECK(res_mod);
  _AtlBaseModule.SetResourceInstance(res_mod);

  ResourceBundle::InitSharedInstance(L"en-US");

  CommandLine* cmd = CommandLine::ForCurrentProcess();
  cmd->AppendSwitch(switches::kDisableWebResources);
  cmd->AppendSwitch(switches::kSingleProcess);

  browser_process_.reset(new BrowserProcessImpl(*cmd));
  // BrowserProcessImpl's constructor should set g_browser_process.
  DCHECK(g_browser_process);
  // Set the app locale and create the child threads.
  g_browser_process->set_application_locale("en-US");
  g_browser_process->db_thread();
  g_browser_process->file_thread();
  g_browser_process->io_thread();

  RenderProcessHost::set_run_renderer_in_process(true);

  Profile* profile = g_browser_process->profile_manager()->
      GetDefaultProfile(FilePath(user_data()));
  PrefService* prefs = profile->GetPrefs();
  DCHECK(prefs != NULL);

  WebCacheManager::RegisterPrefs(prefs);
  PrefService* local_state = browser_process_->local_state();
  local_state->RegisterStringPref(prefs::kApplicationLocale, L"");
  local_state->RegisterBooleanPref(prefs::kMetricsReportingEnabled, false);

  browser::RegisterLocalState(local_state);

  // Override some settings to avoid hitting some preferences that have not
  // been registered.
  prefs->SetBoolean(prefs::kPasswordManagerEnabled, false);
  prefs->SetBoolean(prefs::kAlternateErrorPagesEnabled, false);
  prefs->SetBoolean(prefs::kSafeBrowsingEnabled, false);

  profile->InitExtensions();
}

void FakeExternalTab::Shutdown() {
  browser_process_.reset();
  g_browser_process = NULL;
  process_singleton_.reset();

  ResourceBundle::CleanupSharedInstance();
}

CFUrlRequestUnittestRunner::CFUrlRequestUnittestRunner(int argc, char** argv)
    : NetTestSuite(argc, argv),
      chrome_frame_html_("/chrome_frame", kChromeFrameHtml) {
  // Register the main thread by instantiating it, but don't call any methods.
  main_thread_.reset(new ChromeThread(ChromeThread::UI,
                                      MessageLoop::current()));
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  fake_chrome_.Initialize();
  pss_subclass_.reset(new ProcessSingletonSubclass(this));
  EXPECT_TRUE(pss_subclass_->Subclass(fake_chrome_.user_data()));
  StartChromeFrameInHostBrowser();
}

CFUrlRequestUnittestRunner::~CFUrlRequestUnittestRunner() {
  fake_chrome_.Shutdown();
}

void CFUrlRequestUnittestRunner::StartChromeFrameInHostBrowser() {
  if (!ShouldLaunchBrowser())
    return;

  win_util::ScopedCOMInitializer com;
  chrome_frame_test::CloseAllIEWindows();

  test_http_server_.reset(new test_server::SimpleWebServer(kTestServerPort));
  test_http_server_->AddResponse(&chrome_frame_html_);
  std::wstring url(StringPrintf(L"http://localhost:%i/chrome_frame",
                                kTestServerPort).c_str());

  // Launch IE.  This launches IE correctly on Vista too.
  ScopedHandle ie_process(chrome_frame_test::LaunchIE(url));
  EXPECT_TRUE(ie_process.IsValid());

  // NOTE: If you're running IE8 and CF is not being loaded, you need to
  // disable IE8's prebinding until CF properly handles that situation.
  //
  // HKCU\Software\Microsoft\Internet Explorer\Main
  // Value name: EnablePreBinding (REG_DWORD)
  // Value: 0
}

void CFUrlRequestUnittestRunner::ShutDownHostBrowser() {
  if (ShouldLaunchBrowser()) {
    win_util::ScopedCOMInitializer com;
    chrome_frame_test::CloseAllIEWindows();
  }
}

// Override virtual void Initialize to not call icu initialize
void CFUrlRequestUnittestRunner::Initialize() {
  DCHECK(::GetCurrentThreadId() == test_thread_id_);

  // Start by replicating some of the steps that would otherwise be
  // done by TestSuite::Initialize.  We can't call the base class
  // directly because it will attempt to initialize some things such as
  // ICU that have already been initialized for this process.
  InitializeLogging();
  base::Time::UseHighResolutionTimer(true);

#if !defined(PURIFY) && defined(OS_WIN)
  logging::SetLogAssertHandler(UnitTestAssertHandler);
#endif  // !defined(PURIFY)

  // Next, do some initialization for NetTestSuite.
  NetTestSuite::InitializeTestThread();
}

void CFUrlRequestUnittestRunner::Shutdown() {
  DCHECK(::GetCurrentThreadId() == test_thread_id_);
  NetTestSuite::Shutdown();
}

void CFUrlRequestUnittestRunner::OnConnectAutomationProviderToChannel(
    const std::string& channel_id) {
  Profile* profile = g_browser_process->profile_manager()->
      GetDefaultProfile(fake_chrome_.user_data());

  AutomationProviderList* list =
      g_browser_process->InitAutomationProviderList();
  DCHECK(list);
  list->AddProvider(TestAutomationProvider::NewAutomationProvider(profile,
      channel_id, this));
}

void CFUrlRequestUnittestRunner::OnInitialTabLoaded() {
  test_http_server_.reset();
  StartTests();
}

void CFUrlRequestUnittestRunner::RunMainUIThread() {
  DCHECK(MessageLoop::current());
  DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI);
  MessageLoop::current()->Run();
}

void CFUrlRequestUnittestRunner::StartTests() {
  if (PromptAfterSetup())
    MessageBoxA(NULL, "click ok to run", "", MB_OK);

  DCHECK_EQ(test_thread_.IsValid(), false);
  test_thread_.Set(::CreateThread(NULL, 0, RunAllUnittests, this, 0,
                                  &test_thread_id_));
  DCHECK(test_thread_.IsValid());
}

// static
DWORD CFUrlRequestUnittestRunner::RunAllUnittests(void* param) {
  PlatformThread::SetName("CFUrlRequestUnittestRunner");
  // Needed for some url request tests like the intercept job tests, etc.
  NotificationService service;
  CFUrlRequestUnittestRunner* me =
      reinterpret_cast<CFUrlRequestUnittestRunner*>(param);
  me->Run();
  me->fake_chrome_.ui_loop()->PostTask(FROM_HERE,
      NewRunnableFunction(TakeDownBrowser, me));
  return 0;
}

// static
void CFUrlRequestUnittestRunner::TakeDownBrowser(
    CFUrlRequestUnittestRunner* me) {
  if (PromptAfterSetup())
    MessageBoxA(NULL, "click ok to exit", "", MB_OK);

  me->ShutDownHostBrowser();
}

void CFUrlRequestUnittestRunner::InitializeLogging() {
  FilePath exe;
  PathService::Get(base::FILE_EXE, &exe);
  FilePath log_filename = exe.ReplaceExtension(FILE_PATH_LITERAL("log"));
  logging::InitLogging(log_filename.value().c_str(),
                       logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG,
                       logging::LOCK_LOG_FILE,
                       logging::DELETE_OLD_LOG_FILE);
  // We want process and thread IDs because we may have multiple processes.
  // Note: temporarily enabled timestamps in an effort to catch bug 6361.
  logging::SetLogItems(true, true, true, true);
}

void FilterDisabledTests() {
  if (::testing::FLAGS_gtest_filter.length() &&
      ::testing::FLAGS_gtest_filter.Compare("*") != 0) {
    // Don't override user specified filters.
    return;
  }

  const char* disabled_tests[] = {
    // Tests disabled since they're testing the same functionality used
    // by the TestAutomationProvider.
    "URLRequestTest.Intercept",
    "URLRequestTest.InterceptNetworkError",
    "URLRequestTest.InterceptRestartRequired",
    "URLRequestTest.InterceptRespectsCancelMain",
    "URLRequestTest.InterceptRespectsCancelRedirect",
    "URLRequestTest.InterceptRespectsCancelFinal",
    "URLRequestTest.InterceptRespectsCancelInRestart",
    "URLRequestTest.InterceptRedirect",
    "URLRequestTest.InterceptServerError",
    "URLRequestTestFTP.*",

    // Tests that are currently not working:

    // Temporarily disabled because they needs user input (login dialog).
    "URLRequestTestHTTP.BasicAuth",
    "URLRequestTestHTTP.BasicAuthWithCookies",

    // HTTPS tests temporarily disabled due to the certificate error dialog.
    // TODO(tommi): The tests currently fail though, so need to fix.
    "HTTPSRequestTest.HTTPSMismatchedTest",
    "HTTPSRequestTest.HTTPSExpiredTest",

    // Tests chrome's network stack's cache (might not apply to CF).
    "URLRequestTestHTTP.VaryHeader",

    // I suspect we can only get this one to work (if at all) on IE8 and
    // later by using the new INTERNET_OPTION_SUPPRESS_BEHAVIOR flags
    // See http://msdn.microsoft.com/en-us/library/aa385328(VS.85).aspx
    "URLRequestTest.DoNotSaveCookies",

    // TODO(ananta): This test has been consistently failing. Disabling it for
    // now.
    "URLRequestTestHTTP.GetTest_NoCache",

    // These tests have been disabled as the Chrome cookie policies don't make
    // sense for the host network stack.
    "URLRequestTest.DoNotSaveCookies_ViaPolicy",
    "URLRequestTest.DoNotSendCookies_ViaPolicy",
    "URLRequestTest.DoNotSaveCookies_ViaPolicy_Async",
    "URLRequestTest.CookiePolicy_ForceSession",
  };

  std::string filter("-");  // All following filters will be negative.
  for (int i = 0; i < arraysize(disabled_tests); ++i) {
    if (i > 0)
      filter += ":";
    filter += disabled_tests[i];
  }

  ::testing::FLAGS_gtest_filter = filter;
}

int main(int argc, char** argv) {
  DialogWatchdog watchdog;
  // See url_request_unittest.cc for these credentials.
  SupplyProxyCredentials credentials("user", "secret");
  watchdog.AddObserver(&credentials);
  testing::InitGoogleTest(&argc, argv);
  FilterDisabledTests();
  PluginService::EnableChromePlugins(false);
  CFUrlRequestUnittestRunner test_suite(argc, argv);
  test_suite.RunMainUIThread();
  return 0;
}
<commit_msg>Disabling the following net tests for ChromeFrame as this functionality does not exist there.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome_frame/test/net/fake_external_tab.h"

#include <exdisp.h>

#include "app/app_paths.h"
#include "app/resource_bundle.h"
#include "app/win_util.h"

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/i18n/icu_util.h"
#include "base/path_service.h"
#include "base/scoped_bstr_win.h"
#include "base/scoped_comptr_win.h"
#include "base/scoped_variant_win.h"

#include "chrome/browser/browser_prefs.h"
#include "chrome/browser/plugin_service.h"
#include "chrome/browser/process_singleton.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/web_cache_manager.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "chrome_frame/utils.h"
#include "chrome_frame/test/chrome_frame_test_utils.h"
#include "chrome_frame/test/net/dialog_watchdog.h"
#include "chrome_frame/test/net/test_automation_resource_message_filter.h"

namespace {

// A special command line switch to allow developers to manually launch the
// browser and debug CF inside the browser.
const wchar_t kManualBrowserLaunch[] = L"manual-browser";

// Pops up a message box after the test environment has been set up
// and before tearing it down.  Useful for when debugging tests and not
// the test environment that's been set up.
const wchar_t kPromptAfterSetup[] = L"prompt-after-setup";

const int kTestServerPort = 4666;
// The test HTML we use to initialize Chrome Frame.
// Note that there's a little trick in there to avoid an extra URL request
// that the browser will otherwise make for the site's favicon.
// If we don't do this the browser will create a new URL request after
// the CF page has been initialized and that URL request will confuse the
// global URL instance counter in the unit tests and subsequently trip
// some DCHECKs.
const char kChromeFrameHtml[] = ""
    "<meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\" />"
    "<link rel=\"shortcut icon\" href=\"file://c:\\favicon.ico\"/>"
    "Chrome Frame should now be loaded";

bool ShouldLaunchBrowser() {
  return !CommandLine::ForCurrentProcess()->HasSwitch(kManualBrowserLaunch);
}

bool PromptAfterSetup() {
  return CommandLine::ForCurrentProcess()->HasSwitch(kPromptAfterSetup);
}

}  // end namespace

FakeExternalTab::FakeExternalTab() {
  PathService::Get(chrome::DIR_USER_DATA, &overridden_user_dir_);
  GetProfilePath(&user_data_dir_);
  PathService::Override(chrome::DIR_USER_DATA, user_data_dir_);
  process_singleton_.reset(new ProcessSingleton(user_data_dir_));
}

FakeExternalTab::~FakeExternalTab() {
  if (!overridden_user_dir_.empty()) {
    PathService::Override(chrome::DIR_USER_DATA, overridden_user_dir_);
  }
}

std::wstring FakeExternalTab::GetProfileName() {
  return L"iexplore";
}

bool FakeExternalTab::GetProfilePath(FilePath* path) {
  if (!chrome::GetChromeFrameUserDataDirectory(path))
    return false;
  *path = path->Append(GetProfileName());
  return true;
}

void FakeExternalTab::Initialize() {
  DCHECK(g_browser_process == NULL);
  SystemMonitor system_monitor;

  // The gears plugin causes the PluginRequestInterceptor to kick in and it
  // will cause problems when it tries to intercept URL requests.
  PathService::Override(chrome::FILE_GEARS_PLUGIN, FilePath());

  icu_util::Initialize();

  chrome::RegisterPathProvider();
  app::RegisterPathProvider();

  // Load Chrome.dll as our resource dll.
  FilePath dll;
  PathService::Get(base::DIR_MODULE, &dll);
  dll = dll.Append(chrome::kBrowserResourcesDll);
  HMODULE res_mod = ::LoadLibraryExW(dll.value().c_str(),
      NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
  DCHECK(res_mod);
  _AtlBaseModule.SetResourceInstance(res_mod);

  ResourceBundle::InitSharedInstance(L"en-US");

  CommandLine* cmd = CommandLine::ForCurrentProcess();
  cmd->AppendSwitch(switches::kDisableWebResources);
  cmd->AppendSwitch(switches::kSingleProcess);

  browser_process_.reset(new BrowserProcessImpl(*cmd));
  // BrowserProcessImpl's constructor should set g_browser_process.
  DCHECK(g_browser_process);
  // Set the app locale and create the child threads.
  g_browser_process->set_application_locale("en-US");
  g_browser_process->db_thread();
  g_browser_process->file_thread();
  g_browser_process->io_thread();

  RenderProcessHost::set_run_renderer_in_process(true);

  Profile* profile = g_browser_process->profile_manager()->
      GetDefaultProfile(FilePath(user_data()));
  PrefService* prefs = profile->GetPrefs();
  DCHECK(prefs != NULL);

  WebCacheManager::RegisterPrefs(prefs);
  PrefService* local_state = browser_process_->local_state();
  local_state->RegisterStringPref(prefs::kApplicationLocale, L"");
  local_state->RegisterBooleanPref(prefs::kMetricsReportingEnabled, false);

  browser::RegisterLocalState(local_state);

  // Override some settings to avoid hitting some preferences that have not
  // been registered.
  prefs->SetBoolean(prefs::kPasswordManagerEnabled, false);
  prefs->SetBoolean(prefs::kAlternateErrorPagesEnabled, false);
  prefs->SetBoolean(prefs::kSafeBrowsingEnabled, false);

  profile->InitExtensions();
}

void FakeExternalTab::Shutdown() {
  browser_process_.reset();
  g_browser_process = NULL;
  process_singleton_.reset();

  ResourceBundle::CleanupSharedInstance();
}

CFUrlRequestUnittestRunner::CFUrlRequestUnittestRunner(int argc, char** argv)
    : NetTestSuite(argc, argv),
      chrome_frame_html_("/chrome_frame", kChromeFrameHtml) {
  // Register the main thread by instantiating it, but don't call any methods.
  main_thread_.reset(new ChromeThread(ChromeThread::UI,
                                      MessageLoop::current()));
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  fake_chrome_.Initialize();
  pss_subclass_.reset(new ProcessSingletonSubclass(this));
  EXPECT_TRUE(pss_subclass_->Subclass(fake_chrome_.user_data()));
  StartChromeFrameInHostBrowser();
}

CFUrlRequestUnittestRunner::~CFUrlRequestUnittestRunner() {
  fake_chrome_.Shutdown();
}

void CFUrlRequestUnittestRunner::StartChromeFrameInHostBrowser() {
  if (!ShouldLaunchBrowser())
    return;

  win_util::ScopedCOMInitializer com;
  chrome_frame_test::CloseAllIEWindows();

  test_http_server_.reset(new test_server::SimpleWebServer(kTestServerPort));
  test_http_server_->AddResponse(&chrome_frame_html_);
  std::wstring url(StringPrintf(L"http://localhost:%i/chrome_frame",
                                kTestServerPort).c_str());

  // Launch IE.  This launches IE correctly on Vista too.
  ScopedHandle ie_process(chrome_frame_test::LaunchIE(url));
  EXPECT_TRUE(ie_process.IsValid());

  // NOTE: If you're running IE8 and CF is not being loaded, you need to
  // disable IE8's prebinding until CF properly handles that situation.
  //
  // HKCU\Software\Microsoft\Internet Explorer\Main
  // Value name: EnablePreBinding (REG_DWORD)
  // Value: 0
}

void CFUrlRequestUnittestRunner::ShutDownHostBrowser() {
  if (ShouldLaunchBrowser()) {
    win_util::ScopedCOMInitializer com;
    chrome_frame_test::CloseAllIEWindows();
  }
}

// Override virtual void Initialize to not call icu initialize
void CFUrlRequestUnittestRunner::Initialize() {
  DCHECK(::GetCurrentThreadId() == test_thread_id_);

  // Start by replicating some of the steps that would otherwise be
  // done by TestSuite::Initialize.  We can't call the base class
  // directly because it will attempt to initialize some things such as
  // ICU that have already been initialized for this process.
  InitializeLogging();
  base::Time::UseHighResolutionTimer(true);

#if !defined(PURIFY) && defined(OS_WIN)
  logging::SetLogAssertHandler(UnitTestAssertHandler);
#endif  // !defined(PURIFY)

  // Next, do some initialization for NetTestSuite.
  NetTestSuite::InitializeTestThread();
}

void CFUrlRequestUnittestRunner::Shutdown() {
  DCHECK(::GetCurrentThreadId() == test_thread_id_);
  NetTestSuite::Shutdown();
}

void CFUrlRequestUnittestRunner::OnConnectAutomationProviderToChannel(
    const std::string& channel_id) {
  Profile* profile = g_browser_process->profile_manager()->
      GetDefaultProfile(fake_chrome_.user_data());

  AutomationProviderList* list =
      g_browser_process->InitAutomationProviderList();
  DCHECK(list);
  list->AddProvider(TestAutomationProvider::NewAutomationProvider(profile,
      channel_id, this));
}

void CFUrlRequestUnittestRunner::OnInitialTabLoaded() {
  test_http_server_.reset();
  StartTests();
}

void CFUrlRequestUnittestRunner::RunMainUIThread() {
  DCHECK(MessageLoop::current());
  DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI);
  MessageLoop::current()->Run();
}

void CFUrlRequestUnittestRunner::StartTests() {
  if (PromptAfterSetup())
    MessageBoxA(NULL, "click ok to run", "", MB_OK);

  DCHECK_EQ(test_thread_.IsValid(), false);
  test_thread_.Set(::CreateThread(NULL, 0, RunAllUnittests, this, 0,
                                  &test_thread_id_));
  DCHECK(test_thread_.IsValid());
}

// static
DWORD CFUrlRequestUnittestRunner::RunAllUnittests(void* param) {
  PlatformThread::SetName("CFUrlRequestUnittestRunner");
  // Needed for some url request tests like the intercept job tests, etc.
  NotificationService service;
  CFUrlRequestUnittestRunner* me =
      reinterpret_cast<CFUrlRequestUnittestRunner*>(param);
  me->Run();
  me->fake_chrome_.ui_loop()->PostTask(FROM_HERE,
      NewRunnableFunction(TakeDownBrowser, me));
  return 0;
}

// static
void CFUrlRequestUnittestRunner::TakeDownBrowser(
    CFUrlRequestUnittestRunner* me) {
  if (PromptAfterSetup())
    MessageBoxA(NULL, "click ok to exit", "", MB_OK);

  me->ShutDownHostBrowser();
}

void CFUrlRequestUnittestRunner::InitializeLogging() {
  FilePath exe;
  PathService::Get(base::FILE_EXE, &exe);
  FilePath log_filename = exe.ReplaceExtension(FILE_PATH_LITERAL("log"));
  logging::InitLogging(log_filename.value().c_str(),
                       logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG,
                       logging::LOCK_LOG_FILE,
                       logging::DELETE_OLD_LOG_FILE);
  // We want process and thread IDs because we may have multiple processes.
  // Note: temporarily enabled timestamps in an effort to catch bug 6361.
  logging::SetLogItems(true, true, true, true);
}

void FilterDisabledTests() {
  if (::testing::FLAGS_gtest_filter.length() &&
      ::testing::FLAGS_gtest_filter.Compare("*") != 0) {
    // Don't override user specified filters.
    return;
  }

  const char* disabled_tests[] = {
    // Tests disabled since they're testing the same functionality used
    // by the TestAutomationProvider.
    "URLRequestTest.Intercept",
    "URLRequestTest.InterceptNetworkError",
    "URLRequestTest.InterceptRestartRequired",
    "URLRequestTest.InterceptRespectsCancelMain",
    "URLRequestTest.InterceptRespectsCancelRedirect",
    "URLRequestTest.InterceptRespectsCancelFinal",
    "URLRequestTest.InterceptRespectsCancelInRestart",
    "URLRequestTest.InterceptRedirect",
    "URLRequestTest.InterceptServerError",
    "URLRequestTestFTP.*",

    // Tests that are currently not working:

    // Temporarily disabled because they needs user input (login dialog).
    "URLRequestTestHTTP.BasicAuth",
    "URLRequestTestHTTP.BasicAuthWithCookies",

    // HTTPS tests temporarily disabled due to the certificate error dialog.
    // TODO(tommi): The tests currently fail though, so need to fix.
    "HTTPSRequestTest.HTTPSMismatchedTest",
    "HTTPSRequestTest.HTTPSExpiredTest",

    // Tests chrome's network stack's cache (might not apply to CF).
    "URLRequestTestHTTP.VaryHeader",

    // I suspect we can only get this one to work (if at all) on IE8 and
    // later by using the new INTERNET_OPTION_SUPPRESS_BEHAVIOR flags
    // See http://msdn.microsoft.com/en-us/library/aa385328(VS.85).aspx
    "URLRequestTest.DoNotSaveCookies",

    // TODO(ananta): This test has been consistently failing. Disabling it for
    // now.
    "URLRequestTestHTTP.GetTest_NoCache",

    // These tests have been disabled as the Chrome cookie policies don't make
    // sense or have not been implemented for the host network stack.
    "URLRequestTest.DoNotSaveCookies_ViaPolicy",
    "URLRequestTest.DoNotSendCookies_ViaPolicy",
    "URLRequestTest.DoNotSaveCookies_ViaPolicy_Async",
    "URLRequestTest.CookiePolicy_ForceSession",
    "URLRequestTest.DoNotSendCookies",
    "URLRequestTest.DoNotSendCookies_ViaPolicy_Async",
    "URLRequestTest.CancelTest_During_OnGetCookiesBlocked",
    "URLRequestTest.CancelTest_During_OnSetCookieBlocked",
  };

  std::string filter("-");  // All following filters will be negative.
  for (int i = 0; i < arraysize(disabled_tests); ++i) {
    if (i > 0)
      filter += ":";
    filter += disabled_tests[i];
  }

  ::testing::FLAGS_gtest_filter = filter;
}

int main(int argc, char** argv) {
  DialogWatchdog watchdog;
  // See url_request_unittest.cc for these credentials.
  SupplyProxyCredentials credentials("user", "secret");
  watchdog.AddObserver(&credentials);
  testing::InitGoogleTest(&argc, argv);
  FilterDisabledTests();
  PluginService::EnableChromePlugins(false);
  CFUrlRequestUnittestRunner test_suite(argc, argv);
  test_suite.RunMainUIThread();
  return 0;
}
<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** rtspconnectionclient.cpp
**
** Interface to an RTSP client connection
**
** -------------------------------------------------------------------------*/

#include "rtspconnectionclient.h"

RTSPConnection::SessionSink::SessionSink(UsageEnvironment& env, Callback* callback)
	: MediaSink(env)
	, m_buffer(NULL)
	, m_bufferSize(0)
	, m_callback(callback)
	, m_markerSize(0)
{
	allocate(1024*1024);
}

RTSPConnection::SessionSink::~SessionSink()
{
	delete [] m_buffer;
}

void RTSPConnection::SessionSink::allocate(ssize_t bufferSize)
{
	m_bufferSize = bufferSize;
	m_buffer = new u_int8_t[m_bufferSize];
	if (m_callback)
	{
		m_markerSize = m_callback->onNewBuffer(m_buffer, m_bufferSize);
		envir() << "markerSize:" << (int)m_markerSize << "\n";
	}
}

void RTSPConnection::SessionSink::afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes, struct timeval presentationTime, unsigned durationInMicroseconds)
{
	if (numTruncatedBytes != 0)
	{
		delete [] m_buffer;
		envir() << "buffer too small " << (int)m_bufferSize << " allocate bigger one\n";
		allocate(m_bufferSize*2);
	}
	else if (m_callback)
	{
		if (!m_callback->onData(this->name(), m_buffer, frameSize+m_markerSize, presentationTime))
		{
			envir() << "NOTIFY failed\n";
		}
	}
	this->continuePlaying();
}

Boolean RTSPConnection::SessionSink::continuePlaying()
{
	Boolean ret = False;
	if (source() != NULL)
	{
		source()->getNextFrame(m_buffer+m_markerSize, m_bufferSize-m_markerSize,
				afterGettingFrame, this,
				onSourceClosure, this);
		ret = True;
	}
	return ret;
}

RTSPConnection::RTSPConnection(Environment& env, Callback* callback, const char* rtspURL, int timeout, bool rtpovertcp, int verbosityLevel)
				: m_startCallbackTask(NULL)
				, m_env(env)
				, m_callback(callback)
				, m_url(rtspURL)
				, m_timeout(timeout)
				, m_rtpovertcp(rtpovertcp)
				, m_verbosity(verbosityLevel)
				, m_rtspClient(NULL)
{
	this->start();
}

void RTSPConnection::start(unsigned int delay)
{
	m_startCallbackTask = m_env.taskScheduler().scheduleDelayedTask(delay*1000000, TaskstartCallback, this);
}

void RTSPConnection::TaskstartCallback()
{
	if (m_rtspClient)
	{

		Medium::close(m_rtspClient);
	}

	m_rtspClient = new RTSPClientConnection(*this, m_env, m_callback, m_url.c_str(), m_timeout, m_rtpovertcp, m_verbosity);
}

RTSPConnection::~RTSPConnection()
{
	m_env.taskScheduler().unscheduleDelayedTask(m_startCallbackTask);
	Medium::close(m_rtspClient);
}

RTSPConnection::RTSPClientConnection::RTSPClientConnection(RTSPConnection& connection, Environment& env, Callback* callback, const char* rtspURL, int timeout, bool rtpovertcp, int verbosityLevel)
				: RTSPClientConstrutor(env, rtspURL, verbosityLevel, NULL, 0)
				, m_connection(connection)
				, m_timeout(timeout)
				, m_rtpovertcp(rtpovertcp)
				, m_session(NULL)
				, m_subSessionIter(NULL)
				, m_callback(callback)
				, m_nbPacket(0)
{
	// start tasks
	m_ConnectionTimeoutTask = envir().taskScheduler().scheduleDelayedTask(m_timeout*1000000, TaskConnectionTimeout, this);

	// initiate connection process
	this->sendNextCommand();
}

RTSPConnection::RTSPClientConnection::~RTSPClientConnection()
{
	envir().taskScheduler().unscheduleDelayedTask(m_ConnectionTimeoutTask);
	envir().taskScheduler().unscheduleDelayedTask(m_DataArrivalTimeoutTask);

	delete m_subSessionIter;

	// free subsession
	if (m_session != NULL)
	{
		MediaSubsessionIterator iter(*m_session);
		MediaSubsession* subsession;
		while ((subsession = iter.next()) != NULL)
		{
			if (subsession->sink)
			{
				envir() << "Close session: " << subsession->mediumName() << "/" << subsession->codecName() << "\n";
				Medium::close(subsession->sink);
				subsession->sink = NULL;
			}
		}
		Medium::close(m_session);
	}
}

void RTSPConnection::RTSPClientConnection::sendNextCommand()
{
	if (m_subSessionIter == NULL)
	{
		// no SDP, send DESCRIBE
		this->sendDescribeCommand(continueAfterDESCRIBE);
	}
	else
	{
		m_subSession = m_subSessionIter->next();
		if (m_subSession != NULL)
		{
			// still subsession to SETUP
			if (!m_subSession->initiate())
			{
				envir() << "Failed to initiate " << m_subSession->mediumName() << "/" << m_subSession->codecName() << " subsession: " << envir().getResultMsg() << "\n";
				this->sendNextCommand();
			}
			else
			{
				if (fVerbosityLevel > 1)
				{
					envir() << "Initiated " << m_subSession->mediumName() << "/" << m_subSession->codecName() << " subsession" << "\n";
				}
			}

			this->sendSetupCommand(*m_subSession, continueAfterSETUP, false, m_rtpovertcp);
		}
		else
		{
			// no more subsession to SETUP, send PLAY
			this->sendPlayCommand(*m_session, continueAfterPLAY);
		}
	}
}

void RTSPConnection::RTSPClientConnection::continueAfterDESCRIBE(int resultCode, char* resultString)
{
	if (resultCode != 0)
	{
		envir() << "Failed to DESCRIBE: " << resultString << "\n";
		m_callback->onError(m_connection, resultString);
	}
	else
	{
		if (fVerbosityLevel > 1)
		{
			envir() << "Got SDP:\n" << resultString << "\n";
		}
		m_session = MediaSession::createNew(envir(), resultString);
		m_subSessionIter = new MediaSubsessionIterator(*m_session);
		this->sendNextCommand();
	}
	delete[] resultString;
}

void RTSPConnection::RTSPClientConnection::continueAfterSETUP(int resultCode, char* resultString)
{
	if (resultCode != 0)
	{
		envir() << "Failed to SETUP: " << resultString << "\n";
		m_callback->onError(m_connection, resultString);
	}
	else
	{
		m_subSession->sink = SessionSink::createNew(envir(), m_callback);
		if (m_subSession->sink == NULL)
		{
			envir() << "Failed to create a data sink for " << m_subSession->mediumName() << "/" << m_subSession->codecName() << " subsession: " << envir().getResultMsg() << "\n";
		}
		else if (m_callback->onNewSession(m_subSession->sink->name(), m_subSession->mediumName(), m_subSession->codecName(), m_subSession->savedSDPLines()))
		{
			envir() << "Created a data sink for the \"" << m_subSession->mediumName() << "/" << m_subSession->codecName() << "\" subsession" << "\n";
			m_subSession->sink->startPlaying(*(m_subSession->readSource()), NULL, NULL);
		}
	}
	delete[] resultString;
	this->sendNextCommand();
}

void RTSPConnection::RTSPClientConnection::continueAfterPLAY(int resultCode, char* resultString)
{
	if (resultCode != 0)
	{
		envir() << "Failed to PLAY: " << resultString << "\n";
		m_callback->onError(m_connection, resultString);
	}
	else
	{
		if (fVerbosityLevel > 1)
		{
			envir() << "PLAY OK" << "\n";
		}
		m_DataArrivalTimeoutTask = envir().taskScheduler().scheduleDelayedTask(m_timeout*1000000, TaskDataArrivalTimeout, this);

	}
	envir().taskScheduler().unscheduleDelayedTask(m_ConnectionTimeoutTask);
	delete[] resultString;
}

void RTSPConnection::RTSPClientConnection::TaskConnectionTimeout()
{
	m_callback->onConnectionTimeout(m_connection);
}

void RTSPConnection::RTSPClientConnection::TaskDataArrivalTimeout()
{
	unsigned int newTotNumPacketsReceived = 0;

	MediaSubsessionIterator iter(*m_session);
	MediaSubsession* subsession;
	while ((subsession = iter.next()) != NULL)
	{
		RTPSource* src = subsession->rtpSource();
		if (src != NULL)
		{
			newTotNumPacketsReceived += src->receptionStatsDB().totNumPacketsReceived();
		}
	}

	if (newTotNumPacketsReceived == m_nbPacket)
	{
		m_callback->onDataTimeout(m_connection);
	}
	else
	{
		m_nbPacket = newTotNumPacketsReceived;
		m_DataArrivalTimeoutTask = envir().taskScheduler().scheduleDelayedTask(m_timeout*1000000, TaskDataArrivalTimeout, this);
	}
}
<commit_msg>run onNewSession callback, before onNewBuffer<commit_after>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** rtspconnectionclient.cpp
**
** Interface to an RTSP client connection
**
** -------------------------------------------------------------------------*/

#include "rtspconnectionclient.h"

RTSPConnection::SessionSink::SessionSink(UsageEnvironment& env, Callback* callback)
	: MediaSink(env)
	, m_buffer(NULL)
	, m_bufferSize(0)
	, m_callback(callback)
	, m_markerSize(0)
{
	allocate(1024*1024);
}

RTSPConnection::SessionSink::~SessionSink()
{
	delete [] m_buffer;
}

void RTSPConnection::SessionSink::allocate(ssize_t bufferSize)
{
	m_bufferSize = bufferSize;
	m_buffer = new u_int8_t[m_bufferSize];
	if (m_callback)
	{
		m_markerSize = m_callback->onNewBuffer(m_buffer, m_bufferSize);
		envir() << "markerSize:" << (int)m_markerSize << "\n";
	}
}

void RTSPConnection::SessionSink::afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes, struct timeval presentationTime, unsigned durationInMicroseconds)
{
	if (numTruncatedBytes != 0)
	{
		delete [] m_buffer;
		envir() << "buffer too small " << (int)m_bufferSize << " allocate bigger one\n";
		allocate(m_bufferSize*2);
	}
	else if (m_callback)
	{
		if (!m_callback->onData(this->name(), m_buffer, frameSize+m_markerSize, presentationTime))
		{
			envir() << "NOTIFY failed\n";
		}
	}
	this->continuePlaying();
}

Boolean RTSPConnection::SessionSink::continuePlaying()
{
	Boolean ret = False;
	if (source() != NULL)
	{
		source()->getNextFrame(m_buffer+m_markerSize, m_bufferSize-m_markerSize,
				afterGettingFrame, this,
				onSourceClosure, this);
		ret = True;
	}
	return ret;
}

RTSPConnection::RTSPConnection(Environment& env, Callback* callback, const char* rtspURL, int timeout, bool rtpovertcp, int verbosityLevel)
				: m_startCallbackTask(NULL)
				, m_env(env)
				, m_callback(callback)
				, m_url(rtspURL)
				, m_timeout(timeout)
				, m_rtpovertcp(rtpovertcp)
				, m_verbosity(verbosityLevel)
				, m_rtspClient(NULL)
{
	this->start();
}

void RTSPConnection::start(unsigned int delay)
{
	m_startCallbackTask = m_env.taskScheduler().scheduleDelayedTask(delay*1000000, TaskstartCallback, this);
}

void RTSPConnection::TaskstartCallback()
{
	if (m_rtspClient)
	{

		Medium::close(m_rtspClient);
	}

	m_rtspClient = new RTSPClientConnection(*this, m_env, m_callback, m_url.c_str(), m_timeout, m_rtpovertcp, m_verbosity);
}

RTSPConnection::~RTSPConnection()
{
	m_env.taskScheduler().unscheduleDelayedTask(m_startCallbackTask);
	Medium::close(m_rtspClient);
}

RTSPConnection::RTSPClientConnection::RTSPClientConnection(RTSPConnection& connection, Environment& env, Callback* callback, const char* rtspURL, int timeout, bool rtpovertcp, int verbosityLevel)
				: RTSPClientConstrutor(env, rtspURL, verbosityLevel, NULL, 0)
				, m_connection(connection)
				, m_timeout(timeout)
				, m_rtpovertcp(rtpovertcp)
				, m_session(NULL)
				, m_subSessionIter(NULL)
				, m_callback(callback)
				, m_nbPacket(0)
{
	// start tasks
	m_ConnectionTimeoutTask = envir().taskScheduler().scheduleDelayedTask(m_timeout*1000000, TaskConnectionTimeout, this);

	// initiate connection process
	this->sendNextCommand();
}

RTSPConnection::RTSPClientConnection::~RTSPClientConnection()
{
	envir().taskScheduler().unscheduleDelayedTask(m_ConnectionTimeoutTask);
	envir().taskScheduler().unscheduleDelayedTask(m_DataArrivalTimeoutTask);

	delete m_subSessionIter;

	// free subsession
	if (m_session != NULL)
	{
		MediaSubsessionIterator iter(*m_session);
		MediaSubsession* subsession;
		while ((subsession = iter.next()) != NULL)
		{
			if (subsession->sink)
			{
				envir() << "Close session: " << subsession->mediumName() << "/" << subsession->codecName() << "\n";
				Medium::close(subsession->sink);
				subsession->sink = NULL;
			}
		}
		Medium::close(m_session);
	}
}

void RTSPConnection::RTSPClientConnection::sendNextCommand()
{
	if (m_subSessionIter == NULL)
	{
		// no SDP, send DESCRIBE
		this->sendDescribeCommand(continueAfterDESCRIBE);
	}
	else
	{
		m_subSession = m_subSessionIter->next();
		if (m_subSession != NULL)
		{
			// still subsession to SETUP
			if (!m_subSession->initiate())
			{
				envir() << "Failed to initiate " << m_subSession->mediumName() << "/" << m_subSession->codecName() << " subsession: " << envir().getResultMsg() << "\n";
				this->sendNextCommand();
			}
			else
			{
				if (fVerbosityLevel > 1)
				{
					envir() << "Initiated " << m_subSession->mediumName() << "/" << m_subSession->codecName() << " subsession" << "\n";
				}
			}

			this->sendSetupCommand(*m_subSession, continueAfterSETUP, false, m_rtpovertcp);
		}
		else
		{
			// no more subsession to SETUP, send PLAY
			this->sendPlayCommand(*m_session, continueAfterPLAY);
		}
	}
}

void RTSPConnection::RTSPClientConnection::continueAfterDESCRIBE(int resultCode, char* resultString)
{
	if (resultCode != 0)
	{
		envir() << "Failed to DESCRIBE: " << resultString << "\n";
		m_callback->onError(m_connection, resultString);
	}
	else
	{
		if (fVerbosityLevel > 1)
		{
			envir() << "Got SDP:\n" << resultString << "\n";
		}
		m_session = MediaSession::createNew(envir(), resultString);
		m_subSessionIter = new MediaSubsessionIterator(*m_session);
		this->sendNextCommand();
	}
	delete[] resultString;
}

void RTSPConnection::RTSPClientConnection::continueAfterSETUP(int resultCode, char* resultString)
{
	if (resultCode != 0)
	{
		envir() << "Failed to SETUP: " << resultString << "\n";
		m_callback->onError(m_connection, resultString);
	}
	else
	{
		if (m_callback->onNewSession(m_subSession->sink->name(), m_subSession->mediumName(), m_subSession->codecName(), m_subSession->savedSDPLines()))
		{
			envir() << "Created a data sink for the \"" << m_subSession->mediumName() << "/" << m_subSession->codecName() << "\" subsession" << "\n";
			m_subSession->sink = SessionSink::createNew(envir(), m_callback);
			if (m_subSession->sink == NULL)
			{
				envir() << "Failed to create a data sink for " << m_subSession->mediumName() << "/" << m_subSession->codecName() << " subsession: " << envir().getResultMsg() << "\n";
			} else {
				m_subSession->sink->startPlaying(*(m_subSession->readSource()), NULL, NULL);
			}
		}
	}
	delete[] resultString;
	this->sendNextCommand();
}

void RTSPConnection::RTSPClientConnection::continueAfterPLAY(int resultCode, char* resultString)
{
	if (resultCode != 0)
	{
		envir() << "Failed to PLAY: " << resultString << "\n";
		m_callback->onError(m_connection, resultString);
	}
	else
	{
		if (fVerbosityLevel > 1)
		{
			envir() << "PLAY OK" << "\n";
		}
		m_DataArrivalTimeoutTask = envir().taskScheduler().scheduleDelayedTask(m_timeout*1000000, TaskDataArrivalTimeout, this);

	}
	envir().taskScheduler().unscheduleDelayedTask(m_ConnectionTimeoutTask);
	delete[] resultString;
}

void RTSPConnection::RTSPClientConnection::TaskConnectionTimeout()
{
	m_callback->onConnectionTimeout(m_connection);
}

void RTSPConnection::RTSPClientConnection::TaskDataArrivalTimeout()
{
	unsigned int newTotNumPacketsReceived = 0;

	MediaSubsessionIterator iter(*m_session);
	MediaSubsession* subsession;
	while ((subsession = iter.next()) != NULL)
	{
		RTPSource* src = subsession->rtpSource();
		if (src != NULL)
		{
			newTotNumPacketsReceived += src->receptionStatsDB().totNumPacketsReceived();
		}
	}

	if (newTotNumPacketsReceived == m_nbPacket)
	{
		m_callback->onDataTimeout(m_connection);
	}
	else
	{
		m_nbPacket = newTotNumPacketsReceived;
		m_DataArrivalTimeoutTask = envir().taskScheduler().scheduleDelayedTask(m_timeout*1000000, TaskDataArrivalTimeout, this);
	}
}
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////////////
//
// webcam.cpp --a part of libdecodeqr
//
// Copyright(C) 2007 NISHI Takao <zophos@koka-in.org>
//                   JMA  (Japan Medical Association)
//                   NaCl (Network Applied Communication Laboratory Ltd.)
//
// This is free software with ABSOLUTELY NO WARRANTY.
// You can redistribute and/or modify it under the terms of LGPL.
//
// $Id$
//
#include <stdio.h>
#include <highgui.h>
#include "../../libdecodeqr/decodeqr.h"

int main(int argc,char *argv[])
{
    //
    // start camera
    //
    CvCapture *capture=cvCaptureFromCAM(0);
    if(!capture)
        return(-1);

    //
    // initialize qr decoder
    //
    QrDecoderHandle decoder=qr_decoder_open();
    printf("libdecodeqr version %s\n",qr_decoder_version());

    cvNamedWindow("src",1);
    cvNamedWindow("bin",1);

    puts("Hit [SPACE] key to grab, or any key to end.");
    puts("");

    //
    // 1 shot grabing
    //
    //
    // allocate grabed buffer to decoder
    //
    int key=-1;

    IplImage *camera=cvQueryFrame(capture);
    IplImage *src=NULL;
    if(camera){
        src=cvCloneImage(camera);
        qr_decoder_set_image_buffer(decoder,src);
    }
    else
        key=1;

    unsigned char *text=NULL;
    int text_size=0;

    while(key<=0){
        cvShowImage("src",camera);
        key=cvWaitKey(150);

        //
        // when [SPACE] key pressed, do decode.
        //
        if(key==0x20&&!qr_decoder_is_busy(decoder)){
            key=-1;

            //
            // if left-bottom origin (MS-Windows style) format,
            // it must be converted to left-top origin.
            //
            if(camera->origin)
                cvConvertImage(camera,src,CV_CVTIMG_FLIP);
            else
                cvCopy(camera,src);

            //
            // While decoding is a failure, decrease the
            // adaptive_th_size parameter.
            // Note that the adaptive_th_size must be odd.
            //
            short sz,stat;
            for(sz=25,stat=0;
                (sz>=3)&&((stat&QR_IMAGEREADER_DECODED)==0);
                sz-=2)
                stat=qr_decoder_decode(decoder,sz);

            //
            // for debug, show binarized image.
            //
            cvShowImage("bin",
                        qr_decoder_get_binarized_image_buffer(decoder));
            printf("adaptive_th_size=%d, status=%04x\n",sz,stat);

            //
            // on suceed decoding, print decoded text.
            //
            QrCodeHeader header;
            if(qr_decoder_get_header(decoder,&header)){
                if(text_size<header.byte_size+1){
                    if(text)
                        delete text;

                    text_size=header.byte_size+1;
                    text=new unsigned char[text_size];
                }
                qr_decoder_get_body(decoder,text,text_size);
                printf("%s\n\n",text);

                //
                // draw found code region with green line
                //
                CvPoint *vertexes=qr_decoder_get_coderegion_vertexes(decoder);
                CvPoint pt=vertexes[3];
                int i;
                for(i=0;i<4;i++){
                    cvLine(src,pt,vertexes[i],CV_RGB(0,255,0),3);
                    pt=vertexes[i];
                }

                //
                // draw found finder patterns with green ellipse
                //
                CvBox2D *boxes=qr_decoder_get_finderpattern_boxes(decoder);
                for(i=0;i<3;i++){
                    CvSize sz=cvSize((int)boxes[i].size.width/2,
                                     (int)boxes[i].size.height/2);
                    cvEllipse(src,
                              cvPointFrom32f(boxes[i].center),
                              sz,
                              boxes[i].angle,
                              0,360,
                              CV_RGB(0,255,0),2);
                }

                if(src->origin)
                    cvConvertImage(src,src,CV_CVTIMG_FLIP);

                cvShowImage("src",src);

                //
                // wait 1500msec.
                //
                key=cvWaitKey(1500);
            }
        }

        camera=cvQueryFrame(capture);
        if(!camera)
            break;
    }

    if(text)
        delete text;

    qr_decoder_close(decoder);
    if(src)
        cvReleaseImage(&src);
    cvReleaseCapture(&capture);

    return(0);
}
<commit_msg>src/sample/webcam/webcam.cpp:     * dumps core bug fixed?<commit_after>/////////////////////////////////////////////////////////////////////////
//
// webcam.cpp --a part of libdecodeqr
//
// Copyright(C) 2007 NISHI Takao <zophos@koka-in.org>
//                   JMA  (Japan Medical Association)
//                   NaCl (Network Applied Communication Laboratory Ltd.)
//
// This is free software with ABSOLUTELY NO WARRANTY.
// You can redistribute and/or modify it under the terms of LGPL.
//
// $Id$
//
#include <stdio.h>
#include <highgui.h>
#include "../../libdecodeqr/decodeqr.h"

int main(int argc,char *argv[])
{
    //
    // start camera
    //
    CvCapture *capture=cvCaptureFromCAM(0);
    if(!capture)
        return(-1);

    //
    // initialize qr decoder
    //
    QrDecoderHandle decoder=qr_decoder_open();
    printf("libdecodeqr version %s\n",qr_decoder_version());

    cvNamedWindow("src",1);
    cvNamedWindow("bin",1);

    puts("Hit [SPACE] key to grab, or any key to end.");
    puts("");

    //
    // 1 shot grabing
    //
    //
    // allocate grabed buffer to decoder
    //
    int key=-1;

    IplImage *camera=cvQueryFrame(capture);
    IplImage *src=NULL,*bin=NULL;
    if(camera){
        src=cvCloneImage(camera);
        qr_decoder_set_image_buffer(decoder,src);
    }
    else
        key=1;

    unsigned char *text=NULL;
    int text_size=0;

    while(key<=0){
        cvShowImage("src",camera);
        key=cvWaitKey(150);

        //
        // when [SPACE] key pressed, do decode.
        //
        if(key==0x20&&!qr_decoder_is_busy(decoder)){
            key=-1;

            //
            // if left-bottom origin (MS-Windows style) format,
            // it must be converted to left-top origin.
            //
            if(camera->origin)
                cvConvertImage(camera,src,CV_CVTIMG_FLIP);
            else
                cvCopy(camera,src);

            //
            // While decoding is a failure, decrease the
            // adaptive_th_size parameter.
            // Note that the adaptive_th_size must be odd.
            //
            short sz,stat;
            for(sz=25,stat=0;
                (sz>=3)&&((stat&QR_IMAGEREADER_DECODED)==0);
                sz-=2)
                stat=qr_decoder_decode(decoder,sz);

            //
            // for debug, show binarized image.
            //
            if(bin)
                cvReleaseImage(&bin);
            bin=cvCloneImage(qr_decoder_get_binarized_image_buffer(decoder));
            cvShowImage("bin",bin);
            printf("adaptive_th_size=%d, status=%04x\n",sz,stat);

            //
            // on suceed decoding, print decoded text.
            //
            QrCodeHeader header;
            if(qr_decoder_get_header(decoder,&header)){
                if(text_size<header.byte_size+1){
                    if(text)
                        delete text;

                    text_size=header.byte_size+1;
                    text=new unsigned char[text_size];
                }
                qr_decoder_get_body(decoder,text,text_size);
                printf("%s\n\n",text);

                //
                // draw found code region with green line
                //
                CvPoint *vertexes=qr_decoder_get_coderegion_vertexes(decoder);
                CvPoint pt=vertexes[3];
                int i;
                for(i=0;i<4;i++){
                    cvLine(src,pt,vertexes[i],CV_RGB(0,255,0),3);
                    pt=vertexes[i];
                }

                //
                // draw found finder patterns with green ellipse
                //
                CvBox2D *boxes=qr_decoder_get_finderpattern_boxes(decoder);
                for(i=0;i<3;i++){
                    CvSize sz=cvSize((int)boxes[i].size.width/2,
                                     (int)boxes[i].size.height/2);
                    cvEllipse(src,
                              cvPointFrom32f(boxes[i].center),
                              sz,
                              boxes[i].angle,
                              0,360,
                              CV_RGB(0,255,0),2);
                }

                if(src->origin)
                    cvConvertImage(src,src,CV_CVTIMG_FLIP);

                cvShowImage("src",src);

                //
                // wait 1500msec.
                //
                key=cvWaitKey(1500);
            }
        }

        camera=cvQueryFrame(capture);
        if(!camera)
            break;
    }

    if(text)
        delete text;

    qr_decoder_close(decoder);
    if(bin)
        cvReleaseImage(&bin);
    if(src)
        cvReleaseImage(&src);

    cvReleaseCapture(&capture);

    return(0);
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include "../Util/GitDescription.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"

#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#ifdef __linux__
#include <malloc.h>
#endif

#include <algorithm>
#include <chrono>
#include <iomanip>
#include <numeric>
#include <vector>

const unsigned number_of_elements = 268435456;

struct Statistics
{
    double min, max, med, mean, dev;
};

void RunStatistics(std::vector<double> &timings_vector, Statistics &stats)
{
    std::sort(timings_vector.begin(), timings_vector.end());
    stats.min = timings_vector.front();
    stats.max = timings_vector.back();
    stats.med = timings_vector[timings_vector.size() / 2];
    double primary_sum = std::accumulate(timings_vector.begin(), timings_vector.end(), 0.0);
    stats.mean = primary_sum / timings_vector.size();

    double primary_sq_sum = std::inner_product(
        timings_vector.begin(), timings_vector.end(), timings_vector.begin(), 0.0);
    stats.dev = std::sqrt(primary_sq_sum / timings_vector.size() - (stats.mean * stats.mean));
}

int main(int argc, char *argv[])
{
    LogPolicy::GetInstance().Unmute();

    SimpleLogger().Write() << "starting up engines, " << g_GIT_DESCRIPTION << ", "
                           << "compiled at " << __DATE__ << ", " __TIME__;

#ifdef __FreeBSD__
    SimpleLogger().Write() << "Not supported on FreeBSD";
    return 0;
#endif

    if (1 == argc)
    {
        SimpleLogger().Write(logWARNING) << "usage: " << argv[0] << " /path/on/device";
        return -1;
    }

    boost::filesystem::path test_path = boost::filesystem::path(argv[1]);
    test_path /= "osrm.tst";
    SimpleLogger().Write(logDEBUG) << "temporary file: " << test_path.string();

    try
    {
        // create files for testing
        if (2 == argc)
        {
            // create file to test
            if (boost::filesystem::exists(test_path))
            {
                throw OSRMException("Data file already exists");
            }

            int *random_array = new int[number_of_elements];
            std::generate(random_array, random_array + number_of_elements, std::rand);
#ifdef __APPLE__
            FILE *fd = fopen(test_path.string().c_str(), "w");
            fcntl(fileno(fd), F_NOCACHE, 1);
            fcntl(fileno(fd), F_RDAHEAD, 0);
            TIMER_START(write_1gb);
            write(fileno(fd), (char *)random_array, number_of_elements * sizeof(unsigned));
            TIMER_STOP(write_1gb);
            fclose(fd);
#endif
#ifdef __linux__
            int f =
                open(test_path.string().c_str(), O_CREAT | O_TRUNC | O_WRONLY | O_SYNC, S_IRWXU);
            if (-1 == f)
            {
                throw OSRMException("Could not open random data file");
            }
            TIMER_START(write_1gb);
            int ret = write(f, random_array, number_of_elements * sizeof(unsigned));
            if (0 > ret)
            {
                throw OSRMException("could not write random data file");
            }
            TIMER_STOP(write_1gb);
            close(f);
#endif
            delete[] random_array;
            SimpleLogger().Write(logDEBUG) << "writing raw 1GB took " << TIMER_SEC(write_1gb)
                                           << "s";
            SimpleLogger().Write() << "raw write performance: " << std::setprecision(5)
                                   << std::fixed << 1024 * 1024 / TIMER_SEC(write_1gb)
                                   << "MB/sec";

            SimpleLogger().Write(logDEBUG)
                << "finished creation of random data. Flush disk cache now!";
        }
        else
        {
            // Run Non-Cached I/O benchmarks
            if (!boost::filesystem::exists(test_path))
            {
                throw OSRMException("data file does not exist");
            }

            // volatiles do not get optimized
            Statistics stats;

#ifdef __APPLE__
            volatile unsigned single_block[1024];
            char *raw_array = new char[number_of_elements * sizeof(unsigned)];
            FILE *fd = fopen(test_path.string().c_str(), "r");
            fcntl(fileno(fd), F_NOCACHE, 1);
            fcntl(fileno(fd), F_RDAHEAD, 0);
#endif
#ifdef __linux__
            char *single_block = (char *)memalign(512, 1024 * sizeof(unsigned));

            int f = open(test_path.string().c_str(), O_RDONLY | O_DIRECT | O_SYNC);
            if (-1 == f)
            {
                SimpleLogger().Write(logDEBUG) << "opened, error: " << strerror(errno);
                return -1;
            }
            char *raw_array = (char *)memalign(512, number_of_elements * sizeof(unsigned));
#endif
            TIMER_START(read_1gb);
#ifdef __APPLE__
            read(fileno(fd), raw_array, number_of_elements * sizeof(unsigned));
            close(fileno(fd));
            fd = fopen(test_path.string().c_str(), "r");
#endif
#ifdef __linux__
            int ret = read(f, raw_array, number_of_elements * sizeof(unsigned));
            SimpleLogger().Write(logDEBUG) << "read " << ret
                                           << " bytes, error: " << strerror(errno);
            close(f);
            f = open(test_path.string().c_str(), O_RDONLY | O_DIRECT | O_SYNC);
            SimpleLogger().Write(logDEBUG) << "opened, error: " << strerror(errno);
#endif
            TIMER_STOP(read_1gb);

            SimpleLogger().Write(logDEBUG) << "reading raw 1GB took " << TIMER_SEC(read_1gb)
                                           << "s";
            SimpleLogger().Write() << "raw read performance: " << std::setprecision(5) << std::fixed
                                   << 1024 * 1024 / TIMER_SEC(read_1gb) << "MB/sec";

            std::vector<double> timing_results_raw_random;
            SimpleLogger().Write(logDEBUG) << "running 1000 random I/Os of 4KB";

#ifdef __APPLE__
            fseek(fd, 0, SEEK_SET);
#endif
#ifdef __linux__
            lseek(f, 0, SEEK_SET);
#endif
            // make 1000 random access, time each I/O seperately
            unsigned number_of_blocks = (number_of_elements * sizeof(unsigned) - 1) / 4096;
            for (unsigned i = 0; i < 1000; ++i)
            {
                unsigned block_to_read = std::rand() % number_of_blocks;
                off_t current_offset = block_to_read * 4096;
                TIMER_START(random_access);
#ifdef __APPLE__
                int ret1 = fseek(fd, current_offset, SEEK_SET);
                int ret2 = read(fileno(fd), (char *)&single_block[0], 4096);
#endif

#ifdef __FreeBSD__
                int ret1 = 0;
                int ret2 = 0;
#endif

#ifdef __linux__
                int ret1 = lseek(f, current_offset, SEEK_SET);
                int ret2 = read(f, (char *)single_block, 4096);
#endif
                TIMER_STOP(random_access);
                if (((off_t) - 1) == ret1)
                {
                    SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
                    SimpleLogger().Write(logWARNING) << "seek error " << strerror(errno);
                    throw OSRMException("seek error");
                }
                if (-1 == ret2)
                {
                    SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
                    SimpleLogger().Write(logWARNING) << "read error " << strerror(errno);
                    throw OSRMException("read error");
                }
                timing_results_raw_random.push_back(TIMER_SEC(random_access));
            }

            // Do statistics
            SimpleLogger().Write(logDEBUG) << "running raw random I/O statistics";
            std::ofstream random_csv("random.csv", std::ios::trunc);
            for (unsigned i = 0; i < timing_results_raw_random.size(); ++i)
            {
                random_csv << i << ", " << timing_results_raw_random[i] << std::endl;
            }
            random_csv.close();
            RunStatistics(timing_results_raw_random, stats);

            SimpleLogger().Write() << "raw random I/O: " << std::setprecision(5) << std::fixed
                                   << "min: " << stats.min << "ms, "
                                   << "mean: " << stats.mean << "ms, "
                                   << "med: " << stats.med << "ms, "
                                   << "max: " << stats.max << "ms, "
                                   << "dev: " << stats.dev << "ms";

            std::vector<double> timing_results_raw_seq;
#ifdef __APPLE__
            fseek(fd, 0, SEEK_SET);
#endif
#ifdef __linux__
            lseek(f, 0, SEEK_SET);
#endif

            // read every 100th block
            for (unsigned i = 0; i < 1000; ++i)
            {
                off_t current_offset = i * 4096;
                TIMER_START(read_every_100);
#ifdef __APPLE__
                int ret1 = fseek(fd, current_offset, SEEK_SET);
                int ret2 = read(fileno(fd), (char *)&single_block, 4096);
#endif

#ifdef __FreeBSD__
                int ret1 = 0;
                int ret2 = 0;
#endif

#ifdef __linux__
                int ret1 = lseek(f, current_offset, SEEK_SET);

                int ret2 = read(f, (char *)single_block, 4096);
#endif
                TIMER_STOP(read_every_100);
                if (((off_t) - 1) == ret1)
                {
                    SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
                    SimpleLogger().Write(logWARNING) << "seek error " << strerror(errno);
                    throw OSRMException("seek error");
                }
                if (-1 == ret2)
                {
                    SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
                    SimpleLogger().Write(logWARNING) << "read error " << strerror(errno);
                    throw OSRMException("read error");
                }
                timing_results_raw_seq.push_back(TIMER_SEC(read_every_100));
            }
#ifdef __APPLE__
            fclose(fd);
            // free(single_element);
            free(raw_array);
// free(single_block);
#endif
#ifdef __linux__
            close(f);
#endif
            // Do statistics
            SimpleLogger().Write(logDEBUG) << "running sequential I/O statistics";
            // print simple statistics: min, max, median, variance
            std::ofstream seq_csv("sequential.csv", std::ios::trunc);
            for (unsigned i = 0; i < timing_results_raw_seq.size(); ++i)
            {
                seq_csv << i << ", " << timing_results_raw_seq[i] << std::endl;
            }
            seq_csv.close();
            RunStatistics(timing_results_raw_seq, stats);
            SimpleLogger().Write() << "raw sequential I/O: " << std::setprecision(5) << std::fixed
                                   << "min: " << stats.min << "ms, "
                                   << "mean: " << stats.mean << "ms, "
                                   << "med: " << stats.med << "ms, "
                                   << "max: " << stats.max << "ms, "
                                   << "dev: " << stats.dev << "ms";

            if (boost::filesystem::exists(test_path))
            {
                boost::filesystem::remove(test_path);
                SimpleLogger().Write(logDEBUG) << "removing temporary files";
            }
        }
    }
    catch (const std::exception &e)
    {
        SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
        SimpleLogger().Write(logWARNING) << "cleaning up, and exiting";
        if (boost::filesystem::exists(test_path))
        {
            boost::filesystem::remove(test_path);
            SimpleLogger().Write(logWARNING) << "removing temporary files";
        }
        return -1;
    }
    return 0;
}
<commit_msg>disable io-benchmark on Windows<commit_after>/*

Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include "../Util/GitDescription.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"

#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#ifdef __linux__
#include <malloc.h>
#endif

#include <algorithm>
#include <chrono>
#include <iomanip>
#include <numeric>
#include <vector>

const unsigned number_of_elements = 268435456;

struct Statistics
{
    double min, max, med, mean, dev;
};

void RunStatistics(std::vector<double> &timings_vector, Statistics &stats)
{
    std::sort(timings_vector.begin(), timings_vector.end());
    stats.min = timings_vector.front();
    stats.max = timings_vector.back();
    stats.med = timings_vector[timings_vector.size() / 2];
    double primary_sum = std::accumulate(timings_vector.begin(), timings_vector.end(), 0.0);
    stats.mean = primary_sum / timings_vector.size();

    double primary_sq_sum = std::inner_product(
        timings_vector.begin(), timings_vector.end(), timings_vector.begin(), 0.0);
    stats.dev = std::sqrt(primary_sq_sum / timings_vector.size() - (stats.mean * stats.mean));
}

int main(int argc, char *argv[])
{
    LogPolicy::GetInstance().Unmute();

    SimpleLogger().Write() << "starting up engines, " << g_GIT_DESCRIPTION << ", "
                           << "compiled at " << __DATE__ << ", " __TIME__;

#ifdef __FreeBSD__
    SimpleLogger().Write() << "Not supported on FreeBSD";
    return 0;
#endif
#ifdef WIN32
    SimpleLogger().Write() << "Not supported on Windows";
    return 0;
#else

    if (1 == argc)
    {
        SimpleLogger().Write(logWARNING) << "usage: " << argv[0] << " /path/on/device";
        return -1;
    }

    boost::filesystem::path test_path = boost::filesystem::path(argv[1]);
    test_path /= "osrm.tst";
    SimpleLogger().Write(logDEBUG) << "temporary file: " << test_path.string();

    try
    {
        // create files for testing
        if (2 == argc)
        {
            // create file to test
            if (boost::filesystem::exists(test_path))
            {
                throw OSRMException("Data file already exists");
            }

            int *random_array = new int[number_of_elements];
            std::generate(random_array, random_array + number_of_elements, std::rand);
#ifdef __APPLE__
            FILE *fd = fopen(test_path.string().c_str(), "w");
            fcntl(fileno(fd), F_NOCACHE, 1);
            fcntl(fileno(fd), F_RDAHEAD, 0);
            TIMER_START(write_1gb);
            write(fileno(fd), (char *)random_array, number_of_elements * sizeof(unsigned));
            TIMER_STOP(write_1gb);
            fclose(fd);
#endif
#ifdef __linux__
            int f =
                open(test_path.string().c_str(), O_CREAT | O_TRUNC | O_WRONLY | O_SYNC, S_IRWXU);
            if (-1 == f)
            {
                throw OSRMException("Could not open random data file");
            }
            TIMER_START(write_1gb);
            int ret = write(f, random_array, number_of_elements * sizeof(unsigned));
            if (0 > ret)
            {
                throw OSRMException("could not write random data file");
            }
            TIMER_STOP(write_1gb);
            close(f);
#endif
            delete[] random_array;
            SimpleLogger().Write(logDEBUG) << "writing raw 1GB took " << TIMER_SEC(write_1gb)
                                           << "s";
            SimpleLogger().Write() << "raw write performance: " << std::setprecision(5)
                                   << std::fixed << 1024 * 1024 / TIMER_SEC(write_1gb)
                                   << "MB/sec";

            SimpleLogger().Write(logDEBUG)
                << "finished creation of random data. Flush disk cache now!";
        }
        else
        {
            // Run Non-Cached I/O benchmarks
            if (!boost::filesystem::exists(test_path))
            {
                throw OSRMException("data file does not exist");
            }

            // volatiles do not get optimized
            Statistics stats;

#ifdef __APPLE__
            volatile unsigned single_block[1024];
            char *raw_array = new char[number_of_elements * sizeof(unsigned)];
            FILE *fd = fopen(test_path.string().c_str(), "r");
            fcntl(fileno(fd), F_NOCACHE, 1);
            fcntl(fileno(fd), F_RDAHEAD, 0);
#endif
#ifdef __linux__
            char *single_block = (char *)memalign(512, 1024 * sizeof(unsigned));

            int f = open(test_path.string().c_str(), O_RDONLY | O_DIRECT | O_SYNC);
            if (-1 == f)
            {
                SimpleLogger().Write(logDEBUG) << "opened, error: " << strerror(errno);
                return -1;
            }
            char *raw_array = (char *)memalign(512, number_of_elements * sizeof(unsigned));
#endif
            TIMER_START(read_1gb);
#ifdef __APPLE__
            read(fileno(fd), raw_array, number_of_elements * sizeof(unsigned));
            close(fileno(fd));
            fd = fopen(test_path.string().c_str(), "r");
#endif
#ifdef __linux__
            int ret = read(f, raw_array, number_of_elements * sizeof(unsigned));
            SimpleLogger().Write(logDEBUG) << "read " << ret
                                           << " bytes, error: " << strerror(errno);
            close(f);
            f = open(test_path.string().c_str(), O_RDONLY | O_DIRECT | O_SYNC);
            SimpleLogger().Write(logDEBUG) << "opened, error: " << strerror(errno);
#endif
            TIMER_STOP(read_1gb);

            SimpleLogger().Write(logDEBUG) << "reading raw 1GB took " << TIMER_SEC(read_1gb)
                                           << "s";
            SimpleLogger().Write() << "raw read performance: " << std::setprecision(5) << std::fixed
                                   << 1024 * 1024 / TIMER_SEC(read_1gb) << "MB/sec";

            std::vector<double> timing_results_raw_random;
            SimpleLogger().Write(logDEBUG) << "running 1000 random I/Os of 4KB";

#ifdef __APPLE__
            fseek(fd, 0, SEEK_SET);
#endif
#ifdef __linux__
            lseek(f, 0, SEEK_SET);
#endif
            // make 1000 random access, time each I/O seperately
            unsigned number_of_blocks = (number_of_elements * sizeof(unsigned) - 1) / 4096;
            for (unsigned i = 0; i < 1000; ++i)
            {
                unsigned block_to_read = std::rand() % number_of_blocks;
                off_t current_offset = block_to_read * 4096;
                TIMER_START(random_access);
#ifdef __APPLE__
                int ret1 = fseek(fd, current_offset, SEEK_SET);
                int ret2 = read(fileno(fd), (char *)&single_block[0], 4096);
#endif

#ifdef __FreeBSD__
                int ret1 = 0;
                int ret2 = 0;
#endif

#ifdef __linux__
                int ret1 = lseek(f, current_offset, SEEK_SET);
                int ret2 = read(f, (char *)single_block, 4096);
#endif
                TIMER_STOP(random_access);
                if (((off_t) - 1) == ret1)
                {
                    SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
                    SimpleLogger().Write(logWARNING) << "seek error " << strerror(errno);
                    throw OSRMException("seek error");
                }
                if (-1 == ret2)
                {
                    SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
                    SimpleLogger().Write(logWARNING) << "read error " << strerror(errno);
                    throw OSRMException("read error");
                }
                timing_results_raw_random.push_back(TIMER_SEC(random_access));
            }

            // Do statistics
            SimpleLogger().Write(logDEBUG) << "running raw random I/O statistics";
            std::ofstream random_csv("random.csv", std::ios::trunc);
            for (unsigned i = 0; i < timing_results_raw_random.size(); ++i)
            {
                random_csv << i << ", " << timing_results_raw_random[i] << std::endl;
            }
            random_csv.close();
            RunStatistics(timing_results_raw_random, stats);

            SimpleLogger().Write() << "raw random I/O: " << std::setprecision(5) << std::fixed
                                   << "min: " << stats.min << "ms, "
                                   << "mean: " << stats.mean << "ms, "
                                   << "med: " << stats.med << "ms, "
                                   << "max: " << stats.max << "ms, "
                                   << "dev: " << stats.dev << "ms";

            std::vector<double> timing_results_raw_seq;
#ifdef __APPLE__
            fseek(fd, 0, SEEK_SET);
#endif
#ifdef __linux__
            lseek(f, 0, SEEK_SET);
#endif

            // read every 100th block
            for (unsigned i = 0; i < 1000; ++i)
            {
                off_t current_offset = i * 4096;
                TIMER_START(read_every_100);
#ifdef __APPLE__
                int ret1 = fseek(fd, current_offset, SEEK_SET);
                int ret2 = read(fileno(fd), (char *)&single_block, 4096);
#endif

#ifdef __FreeBSD__
                int ret1 = 0;
                int ret2 = 0;
#endif

#ifdef __linux__
                int ret1 = lseek(f, current_offset, SEEK_SET);

                int ret2 = read(f, (char *)single_block, 4096);
#endif
                TIMER_STOP(read_every_100);
                if (((off_t) - 1) == ret1)
                {
                    SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
                    SimpleLogger().Write(logWARNING) << "seek error " << strerror(errno);
                    throw OSRMException("seek error");
                }
                if (-1 == ret2)
                {
                    SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
                    SimpleLogger().Write(logWARNING) << "read error " << strerror(errno);
                    throw OSRMException("read error");
                }
                timing_results_raw_seq.push_back(TIMER_SEC(read_every_100));
            }
#ifdef __APPLE__
            fclose(fd);
            // free(single_element);
            free(raw_array);
// free(single_block);
#endif
#ifdef __linux__
            close(f);
#endif
            // Do statistics
            SimpleLogger().Write(logDEBUG) << "running sequential I/O statistics";
            // print simple statistics: min, max, median, variance
            std::ofstream seq_csv("sequential.csv", std::ios::trunc);
            for (unsigned i = 0; i < timing_results_raw_seq.size(); ++i)
            {
                seq_csv << i << ", " << timing_results_raw_seq[i] << std::endl;
            }
            seq_csv.close();
            RunStatistics(timing_results_raw_seq, stats);
            SimpleLogger().Write() << "raw sequential I/O: " << std::setprecision(5) << std::fixed
                                   << "min: " << stats.min << "ms, "
                                   << "mean: " << stats.mean << "ms, "
                                   << "med: " << stats.med << "ms, "
                                   << "max: " << stats.max << "ms, "
                                   << "dev: " << stats.dev << "ms";

            if (boost::filesystem::exists(test_path))
            {
                boost::filesystem::remove(test_path);
                SimpleLogger().Write(logDEBUG) << "removing temporary files";
            }
        }
    }
    catch (const std::exception &e)
    {
        SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
        SimpleLogger().Write(logWARNING) << "cleaning up, and exiting";
        if (boost::filesystem::exists(test_path))
        {
            boost::filesystem::remove(test_path);
            SimpleLogger().Write(logWARNING) << "removing temporary files";
        }
        return -1;
    }
    return 0;
#endif
}
<|endoftext|>