From c8eff5e44fe120d98da09dc7d0d075d6d603a661 Mon Sep 17 00:00:00 2001 From: James Robinson Date: Tue, 25 Aug 2015 10:39:21 -0700 Subject: [PATCH] Update to mojo d259eb58aa59e14a13d5e0dc3984b855b475ba09 This updates to mojo commit d259eb58aa59 and limits the roll script to only pull in the parts of //mojo that are currently being used. More stuff will be dropped in the future. --- .gitignore | 2 + DEPS | 2 +- gpu/command_buffer/build_gles2_cmd_buffer.py | 64 +- gpu/command_buffer/service/gl_surface_mock.h | 7 +- .../service/gles2_cmd_decoder.cc | 5 +- mojo/BUILD.gn | 111 ---- mojo/OWNERS | 11 - mojo/PRESUBMIT.py | 288 --------- mojo/PRESUBMIT_test.py | 310 ---------- mojo/README.md | 6 - mojo/android/BUILD.gn | 11 +- mojo/android/javatests/mojo_test_case.cc | 2 +- mojo/android/system/base_run_loop.cc | 2 +- mojo/application/BUILD.gn | 4 +- .../application_runner_chromium.cc | 2 +- mojo/application/content_handler_factory.cc | 2 +- mojo/common/BUILD.gn | 44 +- mojo/common/binding_set_unittest.cc | 2 +- mojo/common/callback_binding_unittest.cc | 104 ++++ .../common/common_type_converters_unittest.cc | 203 ------- mojo/common/dart/BUILD.gn | 8 +- .../dart/lib/trace_controller_impl.dart | 46 -- mojo/common/dart/lib/trace_provider_impl.dart | 46 ++ mojo/common/dart/lib/tracing_helper.dart | 10 +- mojo/common/interface_ptr_set_unittest.cc | 2 +- ...troller_impl.cc => trace_provider_impl.cc} | 31 +- ...ontroller_impl.h => trace_provider_impl.h} | 23 +- mojo/common/tracing_impl.cc | 6 +- mojo/common/tracing_impl.h | 6 +- mojo/converters/array_string/BUILD.gn | 28 + .../array_string_type_converters.cc | 29 + .../array_string_type_converters.h} | 38 +- .../array_string_type_converters_unittest.cc | 38 ++ mojo/converters/base/BUILD.gn | 30 + .../base/base_type_converters.cc} | 29 +- mojo/converters/base/base_type_converters.h | 38 ++ .../base/base_type_converters_unittest.cc | 66 ++ mojo/converters/url/BUILD.gn | 30 + mojo/converters/url/url_type_converters.cc | 19 + mojo/converters/url/url_type_converters.h | 26 + .../url/url_type_converters_unittest.cc | 31 + mojo/dart/BUILD.gn | 14 + mojo/dart/apptest/BUILD.gn | 15 +- mojo/dart/apptest/lib/apptest.dart | 3 +- mojo/dart/dart_snapshotter/BUILD.gn | 27 + mojo/dart/dart_snapshotter/main.cc | 100 ++++ .../test/dart_snapshotter_test.py | 83 +++ mojo/dart/dart_snapshotter/vm.cc | 44 ++ mojo/dart/dart_snapshotter/vm.h | 45 ++ mojo/dart/embedder/BUILD.gn | 12 +- mojo/dart/embedder/dart_controller.cc | 105 +--- mojo/dart/embedder/dart_controller.h | 10 +- mojo/dart/embedder/io/mojo_patch.dart | 11 +- mojo/dart/embedder/mojo_dart_state.h | 2 +- mojo/dart/embedder/test/BUILD.gn | 2 +- mojo/dart/http_load_test/BUILD.gn | 20 + .../dart/http_load_test/{ => bin}/tester.dart | 20 +- mojo/dart/http_load_test/{ => lib}/main.dart | 4 +- .../http_load_test/{ => lib/src}/part0.dart | 0 mojo/dart/http_load_test/pubspec.lock | 3 + mojo/dart/http_load_test/pubspec.yaml | 1 + mojo/dart/http_load_test/runner.py | 6 +- mojo/dart/mojo_services/BUILD.gn | 1 + mojo/dart/mojo_services/CHANGELOG.md | 4 + mojo/dart/mojo_services/pubspec.yaml | 2 +- mojo/dart/mojom/BUILD.gn | 2 +- mojo/dart/mojom/CHANGELOG.md | 4 + mojo/dart/mojom/pubspec.yaml | 2 +- mojo/dart/observatory_test/BUILD.gn | 8 +- .../dart/observatory_test/{ => lib}/main.dart | 0 mojo/dart/observatory_tester/runner.py | 2 +- mojo/dart/testing/BUILD.gn | 2 +- mojo/data_pipe_utils/BUILD.gn | 39 ++ .../data_pipe_drainer.cc | 18 +- .../data_pipe_drainer.h | 10 +- .../data_pipe_file_utils.cc | 4 +- .../data_pipe_utils.cc | 28 +- .../data_pipe_utils.h | 6 +- .../data_pipe_utils_internal.h | 6 +- .../data_pipe_utils_unittest.cc | 2 +- mojo/devtools/README.md | 11 - mojo/devtools/common/README.md | 136 ----- mojo/devtools/common/android_gdb/__init__.py | 0 mojo/devtools/common/android_gdb/config.py | 9 - .../android_gdb/install_remote_file_reader.py | 20 - .../android_gdb/remote_file_connection.py | 69 --- mojo/devtools/common/android_gdb/session.py | 317 ---------- .../devtools/common/android_gdb/signatures.py | 30 - .../common/android_stack_parser/LICENSE | 202 ------- .../android_stack_parser/README.chromium | 30 - .../common/android_stack_parser/stack | 255 -------- .../common/android_stack_parser/stack_core.py | 262 -------- .../common/android_stack_parser/symbol.py | 563 ------------------ mojo/devtools/common/devtoolslib/__init__.py | 0 .../common/devtoolslib/android_shell.py | 430 ------------- mojo/devtools/common/devtoolslib/apptest.py | 77 --- .../common/devtoolslib/apptest_dart.py | 35 -- .../common/devtoolslib/apptest_gtest.py | 120 ---- .../devtoolslib/apptest_gtest_unittest.py | 57 -- .../common/devtoolslib/http_server.py | 223 ------- .../devtoolslib/http_server_unittest.py | 140 ----- .../common/devtoolslib/linux_shell.py | 66 -- mojo/devtools/common/devtoolslib/paths.py | 96 --- mojo/devtools/common/devtoolslib/shell.py | 79 --- .../common/devtoolslib/shell_arguments.py | 243 -------- .../devtoolslib/shell_arguments_unittest.py | 46 -- .../common/devtoolslib/shell_config.py | 196 ------ mojo/devtools/common/devtoolslib/utils.py | 16 - mojo/devtools/common/mojo_debug | 330 ---------- mojo/devtools/common/mojo_run | 95 --- mojo/devtools/common/mojo_test | 110 ---- mojo/devtools/common/remote_adb_setup | 51 -- mojo/edk/system/BUILD.gn | 1 + mojo/edk/system/channel_endpoint.cc | 40 +- mojo/edk/system/channel_endpoint.h | 29 +- mojo/edk/system/channel_manager.cc | 14 +- mojo/edk/system/channel_manager.h | 13 +- mojo/edk/system/channel_manager_unittest.cc | 3 + mojo/edk/system/data_pipe_impl_unittest.cc | 61 ++ mojo/edk/system/ipc_support_unittest.cc | 417 ++++++++----- .../message_pipe_dispatcher_unittest.cc | 5 +- mojo/edk/system/raw_channel_unittest.cc | 3 +- .../system/remote_producer_data_pipe_impl.cc | 21 +- mojo/edk/system/simple_dispatcher_unittest.cc | 1 - mojo/edk/system/test_utils.cc | 20 + mojo/edk/system/test_utils.h | 9 + mojo/edk/system/test_utils_unittest.cc | 53 ++ mojo/edk/system/unique_identifier.cc | 52 +- mojo/edk/system/unique_identifier.h | 2 +- mojo/edk/system/unique_identifier_unittest.cc | 10 +- mojo/environment/BUILD.gn | 3 +- mojo/environment/default_async_waiter.cc | 2 +- mojo/gles2/BUILD.gn | 56 +- mojo/gles2/control_thunks_impl.cc | 82 +++ mojo/gles2/control_thunks_impl.h | 69 +++ mojo/gles2/gles2_context.cc | 2 +- mojo/gles2/gles2_context.h | 10 +- mojo/gles2/gles2_impl.cc | 67 +-- mojo/gles2/mgl_impl.cc | 46 ++ mojo/go/BUILD.gn | 92 --- mojo/go/c_embedder/c_embedder.cc | 19 - mojo/go/c_embedder/c_embedder.h | 18 - mojo/go/go.py | 98 --- mojo/go/rules.gni | 156 ----- mojo/go/stamp.py | 24 - mojo/go/system/embedder/embedder.go | 14 - mojo/go/tests/README.txt | 10 - mojo/go/tests/application_impl_test.go | 161 ----- mojo/go/tests/async_waiter_test.go | 92 --- mojo/go/tests/encoding_test.go | 196 ------ mojo/go/tests/interface_test.go | 25 - mojo/go/tests/message_test.go | 45 -- mojo/go/tests/request_response_test.go | 78 --- mojo/go/tests/router_test.go | 148 ----- mojo/go/tests/system_test.go | 302 ---------- mojo/go/tests/testutil.go | 203 ------- mojo/go/tests/testutil_test.go | 64 -- mojo/go/tests/union_test.go | 184 ------ mojo/go/tests/validation_test.go | 453 -------------- mojo/gpu/BUILD.gn | 1 + mojo/gpu/gl_context.cc | 8 +- mojo/gpu/gl_context.h | 5 +- mojo/gpu/mojo_gles2_impl_autogen.cc | 87 +-- mojo/message_pump/BUILD.gn | 39 ++ .../handle_watcher.cc | 8 +- .../{common => message_pump}/handle_watcher.h | 6 +- .../handle_watcher_unittest.cc | 6 +- .../message_pump_mojo.cc | 6 +- .../message_pump_mojo.h | 6 +- .../message_pump_mojo_handler.h | 6 +- .../message_pump_mojo_unittest.cc | 4 +- mojo/{common => message_pump}/time_helper.cc | 2 +- mojo/{common => message_pump}/time_helper.h | 6 +- mojo/mojo_apps_js_unittests.isolate | 50 -- mojo/mojo_js_unittests.isolate | 49 -- mojo/mojo_python_unittests.isolate | 22 - mojo/nacl/BUILD.gn | 75 --- mojo/nacl/README.md | 37 -- mojo/nacl/monacl_shell.cc | 48 -- mojo/python/BUILD.gn | 66 -- mojo/python/mojo_utils/__init__.py | 3 - mojo/python/mojo_utils/data_pipe_utils.py | 76 --- mojo/python/system/mojo_embedder.pyx | 50 -- mojo/python/system/mojo_tests/__init__.py | 3 - .../system/mojo_tests/validation_util.pyx | 35 -- mojo/python/tests/async_wait_unittest.py | 50 -- .../tests/bindings_constants_unittest.py | 38 -- .../bindings_control_messages_unittest.py | 90 --- mojo/python/tests/bindings_enums_unittest.py | 61 -- .../tests/bindings_interface_unittest.py | 123 ---- ..._serialization_deserialization_unittest.py | 102 ---- .../python/tests/bindings_structs_unittest.py | 217 ------- .../bindings_structs_version_unittest.py | 150 ----- mojo/python/tests/bindings_unions_unittest.py | 188 ------ mojo/python/tests/data_pipe_utils_unittest.py | 96 --- mojo/python/tests/generation_unittest.py | 37 -- mojo/python/tests/messaging_unittest.py | 218 ------- mojo/python/tests/mojo_unittest.py | 24 - mojo/python/tests/promise_unittest.py | 238 -------- mojo/python/tests/runloop_unittest.py | 41 -- mojo/python/tests/system_unittest.py | 327 ---------- mojo/python/tests/validation_unittest.py | 90 --- mojo/services/BUILD.gn | 29 +- mojo/services/mojo_services.gni | 33 + .../sharing/public/interfaces/BUILD.gn | 16 + .../sharing/public/interfaces/sharing.mojom | 10 + .../tracing/public/interfaces/tracing.mojom | 18 +- .../security/public/interfaces/BUILD.gn | 12 + .../public/interfaces/principal.mojom | 49 ++ mojo/tests/BUILD.gn | 32 - mojo/tests/task_tracker_perftest.cc | 135 ----- mojo/tools/BUILD.gn | 28 - mojo/tools/analyze_bloat.py | 93 --- mojo/tools/android_shortcuts/BUILD.gn | 41 -- .../android_shortcuts/apk/AndroidManifest.xml | 40 -- .../apk/res/values/strings.xml | 11 - .../mojo/shortcuts/AlarmReceiver.java | 54 -- .../mojo/shortcuts/ApplicationUpdater.java | 157 ----- .../mojo/shortcuts/ShortcutsActivity.java | 107 ---- mojo/tools/apptest_runner.py | 59 -- mojo/tools/check_mojom_golden_files.py | 103 ---- mojo/tools/data/apptests | 127 ---- mojo/tools/data/nacl_apptests | 33 - mojo/tools/data/unittests | 96 --- mojo/tools/deploy_domokit_site.py | 157 ----- mojo/tools/devtools.py | 15 - mojo/tools/download_keystore.py | 93 --- mojo/tools/embed/data.h | 22 - mojo/tools/embed/embed_data.py | 76 --- mojo/tools/embed/rules.gni | 49 -- .../generate_java_callback_interfaces.py | 69 --- mojo/tools/get_test_list.py | 243 -------- mojo/tools/linux64/dump_syms.sha1 | 1 - mojo/tools/linux64/symupload.sha1 | 1 - mojo/tools/message_generator.cc | 63 -- mojo/tools/mojob.py | 318 ---------- mojo/tools/mopy/__init__.py | 0 mojo/tools/mopy/config.py | 148 ----- mojo/tools/mopy/file_hash.py | 26 - mojo/tools/mopy/gn.py | 157 ----- mojo/tools/mopy/gn_unittest.py | 76 --- mojo/tools/mopy/gtest.py | 17 - mojo/tools/mopy/log.py | 29 - mojo/tools/mopy/memoize.py | 17 - mojo/tools/mopy/mojo_python_tests_runner.py | 52 -- mojo/tools/mopy/paths.py | 77 --- mojo/tools/mopy/perf_data_uploader.py | 200 ------- mojo/tools/mopy/print_process_error.py | 22 - mojo/tools/mopy/transitive_hash.py | 80 --- mojo/tools/mopy/version.py | 14 - mojo/tools/perf_test_runner.py | 85 --- mojo/tools/prepare_pub_packages.py | 92 --- mojo/tools/publish_pub_packages.py | 74 --- mojo/tools/remote_file_reader.cc | 325 ---------- mojo/tools/roll/android_build.patch | 33 - mojo/tools/roll/build_v8.patch | 11 - mojo/tools/roll/compare_deps.py | 36 -- mojo/tools/roll/patch.py | 49 -- mojo/tools/roll/sanitizers_build.patch | 35 -- mojo/tools/roll/update_from_chromium.py | 121 ---- mojo/tools/roll/utils.py | 32 - mojo/tools/roll_services.py | 75 --- mojo/tools/run_command_through_symbolizer.py | 26 - mojo/tools/run_mojo_python_bindings_tests.py | 35 -- mojo/tools/run_mojo_python_tests.py | 30 - mojo/tools/test_runner.py | 152 ----- .../testing/mojom_fetcher/dependency_tests.py | 110 ---- mojo/tools/testing/mojom_fetcher/fakes.py | 113 ---- .../mojom_fetcher/mojom_directory_tests.py | 50 -- .../mojom_fetcher/mojom_fetcher_tests.py | 109 ---- .../testing/mojom_fetcher/mojom_file_tests.py | 44 -- .../testing/mojom_fetcher/mojom_gn_tests.py | 88 --- .../testing/mojom_fetcher/repository_tests.py | 43 -- mojo/tools/upload_binaries.py | 234 -------- services/asset_bundle/BUILD.gn | 5 +- services/asset_bundle/asset_bundle_apptest.cc | 3 +- services/asset_bundle/asset_bundle_impl.cc | 2 +- services/asset_bundle/asset_unpacker_job.h | 2 +- services/sky/BUILD.gn | 1 - sky/engine/bindings/BUILD.gn | 1 - sky/engine/core/BUILD.gn | 2 +- sky/engine/core/loader/CanvasImageDecoder.h | 2 +- sky/engine/core/script/dart_controller.cc | 2 +- sky/engine/platform/BUILD.gn | 1 - sky/engine/tonic/BUILD.gn | 2 +- sky/engine/tonic/dart_library_loader.cc | 2 +- sky/engine/tonic/dart_snapshot_loader.h | 2 +- sky/engine/web/BUILD.gn | 5 +- sky/engine/web/Sky.cpp | 2 +- sky/services/keyboard/BUILD.gn | 1 - sky/services/media/BUILD.gn | 2 +- sky/services/media/ios/media_player_impl.mm | 2 +- sky/services/ns_net/BUILD.gn | 1 - sky/shell/BUILD.gn | 4 +- sky/shell/dart/BUILD.gn | 2 +- sky/shell/dart/dart_library_provider_files.cc | 2 +- sky/shell/shell.cc | 2 +- sky/shell/tracing_controller.h | 2 +- sky/shell/ui/engine.cc | 2 +- .../mojo/mojo_converters_input_events.patch | 20 + .../roll/patches/mojo/services_keyboard.patch | 30 + sky/tools/roll/roll.py | 16 +- 302 files changed, 2267 insertions(+), 16170 deletions(-) delete mode 100644 mojo/BUILD.gn delete mode 100644 mojo/OWNERS delete mode 100644 mojo/PRESUBMIT.py delete mode 100755 mojo/PRESUBMIT_test.py delete mode 100644 mojo/README.md create mode 100644 mojo/common/callback_binding_unittest.cc delete mode 100644 mojo/common/common_type_converters_unittest.cc delete mode 100644 mojo/common/dart/lib/trace_controller_impl.dart create mode 100644 mojo/common/dart/lib/trace_provider_impl.dart rename mojo/common/{trace_controller_impl.cc => trace_provider_impl.cc} (62%) rename mojo/common/{trace_controller_impl.h => trace_provider_impl.h} (63%) create mode 100644 mojo/converters/array_string/BUILD.gn create mode 100644 mojo/converters/array_string/array_string_type_converters.cc rename mojo/{common/common_type_converters.h => converters/array_string/array_string_type_converters.h} (53%) create mode 100644 mojo/converters/array_string/array_string_type_converters_unittest.cc create mode 100644 mojo/converters/base/BUILD.gn rename mojo/{common/common_type_converters.cc => converters/base/base_type_converters.cc} (53%) create mode 100644 mojo/converters/base/base_type_converters.h create mode 100644 mojo/converters/base/base_type_converters_unittest.cc create mode 100644 mojo/converters/url/BUILD.gn create mode 100644 mojo/converters/url/url_type_converters.cc create mode 100644 mojo/converters/url/url_type_converters.h create mode 100644 mojo/converters/url/url_type_converters_unittest.cc create mode 100644 mojo/dart/BUILD.gn create mode 100644 mojo/dart/dart_snapshotter/BUILD.gn create mode 100644 mojo/dart/dart_snapshotter/main.cc create mode 100755 mojo/dart/dart_snapshotter/test/dart_snapshotter_test.py create mode 100644 mojo/dart/dart_snapshotter/vm.cc create mode 100644 mojo/dart/dart_snapshotter/vm.h create mode 100644 mojo/dart/http_load_test/BUILD.gn rename mojo/dart/http_load_test/{ => bin}/tester.dart (79%) rename mojo/dart/http_load_test/{ => lib}/main.dart (75%) rename mojo/dart/http_load_test/{ => lib/src}/part0.dart (100%) create mode 100644 mojo/dart/http_load_test/pubspec.lock create mode 100644 mojo/dart/http_load_test/pubspec.yaml rename mojo/dart/observatory_test/{ => lib}/main.dart (100%) create mode 100644 mojo/data_pipe_utils/BUILD.gn rename mojo/{common => data_pipe_utils}/data_pipe_drainer.cc (73%) rename mojo/{common => data_pipe_utils}/data_pipe_drainer.h (80%) rename mojo/{common => data_pipe_utils}/data_pipe_file_utils.cc (99%) rename mojo/{common => data_pipe_utils}/data_pipe_utils.cc (83%) rename mojo/{common => data_pipe_utils}/data_pipe_utils.h (92%) rename mojo/{common => data_pipe_utils}/data_pipe_utils_internal.h (75%) rename mojo/{common => data_pipe_utils}/data_pipe_utils_unittest.cc (97%) delete mode 100644 mojo/devtools/README.md delete mode 100644 mojo/devtools/common/README.md delete mode 100644 mojo/devtools/common/android_gdb/__init__.py delete mode 100644 mojo/devtools/common/android_gdb/config.py delete mode 100644 mojo/devtools/common/android_gdb/install_remote_file_reader.py delete mode 100644 mojo/devtools/common/android_gdb/remote_file_connection.py delete mode 100644 mojo/devtools/common/android_gdb/session.py delete mode 100644 mojo/devtools/common/android_gdb/signatures.py delete mode 100644 mojo/devtools/common/android_stack_parser/LICENSE delete mode 100644 mojo/devtools/common/android_stack_parser/README.chromium delete mode 100755 mojo/devtools/common/android_stack_parser/stack delete mode 100644 mojo/devtools/common/android_stack_parser/stack_core.py delete mode 100644 mojo/devtools/common/android_stack_parser/symbol.py delete mode 100644 mojo/devtools/common/devtoolslib/__init__.py delete mode 100644 mojo/devtools/common/devtoolslib/android_shell.py delete mode 100644 mojo/devtools/common/devtoolslib/apptest.py delete mode 100644 mojo/devtools/common/devtoolslib/apptest_dart.py delete mode 100644 mojo/devtools/common/devtoolslib/apptest_gtest.py delete mode 100644 mojo/devtools/common/devtoolslib/apptest_gtest_unittest.py delete mode 100644 mojo/devtools/common/devtoolslib/http_server.py delete mode 100644 mojo/devtools/common/devtoolslib/http_server_unittest.py delete mode 100644 mojo/devtools/common/devtoolslib/linux_shell.py delete mode 100644 mojo/devtools/common/devtoolslib/paths.py delete mode 100644 mojo/devtools/common/devtoolslib/shell.py delete mode 100644 mojo/devtools/common/devtoolslib/shell_arguments.py delete mode 100644 mojo/devtools/common/devtoolslib/shell_arguments_unittest.py delete mode 100644 mojo/devtools/common/devtoolslib/shell_config.py delete mode 100644 mojo/devtools/common/devtoolslib/utils.py delete mode 100755 mojo/devtools/common/mojo_debug delete mode 100755 mojo/devtools/common/mojo_run delete mode 100755 mojo/devtools/common/mojo_test delete mode 100755 mojo/devtools/common/remote_adb_setup create mode 100644 mojo/edk/system/test_utils_unittest.cc create mode 100644 mojo/gles2/control_thunks_impl.cc create mode 100644 mojo/gles2/control_thunks_impl.h create mode 100644 mojo/gles2/mgl_impl.cc delete mode 100644 mojo/go/BUILD.gn delete mode 100644 mojo/go/c_embedder/c_embedder.cc delete mode 100644 mojo/go/c_embedder/c_embedder.h delete mode 100755 mojo/go/go.py delete mode 100644 mojo/go/rules.gni delete mode 100644 mojo/go/stamp.py delete mode 100644 mojo/go/system/embedder/embedder.go delete mode 100644 mojo/go/tests/README.txt delete mode 100644 mojo/go/tests/application_impl_test.go delete mode 100644 mojo/go/tests/async_waiter_test.go delete mode 100644 mojo/go/tests/encoding_test.go delete mode 100644 mojo/go/tests/interface_test.go delete mode 100644 mojo/go/tests/message_test.go delete mode 100644 mojo/go/tests/request_response_test.go delete mode 100644 mojo/go/tests/router_test.go delete mode 100644 mojo/go/tests/system_test.go delete mode 100644 mojo/go/tests/testutil.go delete mode 100644 mojo/go/tests/testutil_test.go delete mode 100644 mojo/go/tests/union_test.go delete mode 100644 mojo/go/tests/validation_test.go create mode 100644 mojo/message_pump/BUILD.gn rename mojo/{common => message_pump}/handle_watcher.cc (98%) rename mojo/{common => message_pump}/handle_watcher.h (93%) rename mojo/{common => message_pump}/handle_watcher_unittest.cc (99%) rename mojo/{common => message_pump}/message_pump_mojo.cc (98%) rename mojo/{common => message_pump}/message_pump_mojo.h (96%) rename mojo/{common => message_pump}/message_pump_mojo_handler.h (79%) rename mojo/{common => message_pump}/message_pump_mojo_unittest.cc (97%) rename mojo/{common => message_pump}/time_helper.cc (93%) rename mojo/{common => message_pump}/time_helper.h (84%) delete mode 100644 mojo/mojo_apps_js_unittests.isolate delete mode 100644 mojo/mojo_js_unittests.isolate delete mode 100644 mojo/mojo_python_unittests.isolate delete mode 100644 mojo/nacl/BUILD.gn delete mode 100644 mojo/nacl/README.md delete mode 100644 mojo/nacl/monacl_shell.cc delete mode 100644 mojo/python/BUILD.gn delete mode 100644 mojo/python/mojo_utils/__init__.py delete mode 100644 mojo/python/mojo_utils/data_pipe_utils.py delete mode 100644 mojo/python/system/mojo_embedder.pyx delete mode 100644 mojo/python/system/mojo_tests/__init__.py delete mode 100644 mojo/python/system/mojo_tests/validation_util.pyx delete mode 100644 mojo/python/tests/async_wait_unittest.py delete mode 100644 mojo/python/tests/bindings_constants_unittest.py delete mode 100644 mojo/python/tests/bindings_control_messages_unittest.py delete mode 100644 mojo/python/tests/bindings_enums_unittest.py delete mode 100644 mojo/python/tests/bindings_interface_unittest.py delete mode 100644 mojo/python/tests/bindings_serialization_deserialization_unittest.py delete mode 100644 mojo/python/tests/bindings_structs_unittest.py delete mode 100644 mojo/python/tests/bindings_structs_version_unittest.py delete mode 100644 mojo/python/tests/bindings_unions_unittest.py delete mode 100644 mojo/python/tests/data_pipe_utils_unittest.py delete mode 100644 mojo/python/tests/generation_unittest.py delete mode 100644 mojo/python/tests/messaging_unittest.py delete mode 100644 mojo/python/tests/mojo_unittest.py delete mode 100644 mojo/python/tests/promise_unittest.py delete mode 100644 mojo/python/tests/runloop_unittest.py delete mode 100644 mojo/python/tests/system_unittest.py delete mode 100644 mojo/python/tests/validation_unittest.py create mode 100644 mojo/services/mojo_services.gni create mode 100644 mojo/services/sharing/public/interfaces/BUILD.gn create mode 100644 mojo/services/sharing/public/interfaces/sharing.mojom create mode 100644 mojo/services/vanadium/security/public/interfaces/BUILD.gn create mode 100644 mojo/services/vanadium/security/public/interfaces/principal.mojom delete mode 100644 mojo/tests/BUILD.gn delete mode 100644 mojo/tests/task_tracker_perftest.cc delete mode 100644 mojo/tools/BUILD.gn delete mode 100755 mojo/tools/analyze_bloat.py delete mode 100644 mojo/tools/android_shortcuts/BUILD.gn delete mode 100644 mojo/tools/android_shortcuts/apk/AndroidManifest.xml delete mode 100644 mojo/tools/android_shortcuts/apk/res/values/strings.xml delete mode 100644 mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/AlarmReceiver.java delete mode 100644 mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ApplicationUpdater.java delete mode 100644 mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ShortcutsActivity.java delete mode 100755 mojo/tools/apptest_runner.py delete mode 100755 mojo/tools/check_mojom_golden_files.py delete mode 100644 mojo/tools/data/apptests delete mode 100644 mojo/tools/data/nacl_apptests delete mode 100644 mojo/tools/data/unittests delete mode 100755 mojo/tools/deploy_domokit_site.py delete mode 100644 mojo/tools/devtools.py delete mode 100755 mojo/tools/download_keystore.py delete mode 100644 mojo/tools/embed/data.h delete mode 100755 mojo/tools/embed/embed_data.py delete mode 100644 mojo/tools/embed/rules.gni delete mode 100644 mojo/tools/generate_java_callback_interfaces.py delete mode 100755 mojo/tools/get_test_list.py delete mode 100644 mojo/tools/linux64/dump_syms.sha1 delete mode 100644 mojo/tools/linux64/symupload.sha1 delete mode 100644 mojo/tools/message_generator.cc delete mode 100755 mojo/tools/mojob.py delete mode 100644 mojo/tools/mopy/__init__.py delete mode 100644 mojo/tools/mopy/config.py delete mode 100644 mojo/tools/mopy/file_hash.py delete mode 100644 mojo/tools/mopy/gn.py delete mode 100644 mojo/tools/mopy/gn_unittest.py delete mode 100644 mojo/tools/mopy/gtest.py delete mode 100644 mojo/tools/mopy/log.py delete mode 100644 mojo/tools/mopy/memoize.py delete mode 100644 mojo/tools/mopy/mojo_python_tests_runner.py delete mode 100644 mojo/tools/mopy/paths.py delete mode 100755 mojo/tools/mopy/perf_data_uploader.py delete mode 100644 mojo/tools/mopy/print_process_error.py delete mode 100644 mojo/tools/mopy/transitive_hash.py delete mode 100644 mojo/tools/mopy/version.py delete mode 100755 mojo/tools/perf_test_runner.py delete mode 100755 mojo/tools/prepare_pub_packages.py delete mode 100755 mojo/tools/publish_pub_packages.py delete mode 100644 mojo/tools/remote_file_reader.cc delete mode 100644 mojo/tools/roll/android_build.patch delete mode 100644 mojo/tools/roll/build_v8.patch delete mode 100755 mojo/tools/roll/compare_deps.py delete mode 100755 mojo/tools/roll/patch.py delete mode 100644 mojo/tools/roll/sanitizers_build.patch delete mode 100755 mojo/tools/roll/update_from_chromium.py delete mode 100755 mojo/tools/roll/utils.py delete mode 100755 mojo/tools/roll_services.py delete mode 100755 mojo/tools/run_command_through_symbolizer.py delete mode 100755 mojo/tools/run_mojo_python_bindings_tests.py delete mode 100755 mojo/tools/run_mojo_python_tests.py delete mode 100755 mojo/tools/test_runner.py delete mode 100644 mojo/tools/testing/mojom_fetcher/dependency_tests.py delete mode 100644 mojo/tools/testing/mojom_fetcher/fakes.py delete mode 100644 mojo/tools/testing/mojom_fetcher/mojom_directory_tests.py delete mode 100755 mojo/tools/testing/mojom_fetcher/mojom_fetcher_tests.py delete mode 100644 mojo/tools/testing/mojom_fetcher/mojom_file_tests.py delete mode 100644 mojo/tools/testing/mojom_fetcher/mojom_gn_tests.py delete mode 100644 mojo/tools/testing/mojom_fetcher/repository_tests.py delete mode 100755 mojo/tools/upload_binaries.py create mode 100644 sky/tools/roll/patches/mojo/mojo_converters_input_events.patch create mode 100644 sky/tools/roll/patches/mojo/services_keyboard.patch diff --git a/.gitignore b/.gitignore index ed086d94eb60c..87190951c1642 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,8 @@ Thumbs.db /examples/**/pubspec.lock /mojo/common/dart/packages /mojo/dart/apptest/packages +/mojo/dart/http_load_test/bin/packages +/mojo/dart/http_load_test/packages/ /mojo/dart/mojo_services/packages /mojo/dart/mojo_services/pubspec.lock /mojo/dart/mojom/bin/packages diff --git a/DEPS b/DEPS index b7e418a38f47f..c67163d931862 100644 --- a/DEPS +++ b/DEPS @@ -19,7 +19,7 @@ vars = { 'chromium_git': 'https://chromium.googlesource.com', - 'mojo_sdk_revision': '9a5f81a3d2a6d027677366edb5de3ae85f6dbf16', + 'mojo_sdk_revision': '76ff57433b48527dc491dac4c52c9d71a7c3a0e3', 'skia_revision': '29ccdf86ab0a1649fd775c9431891bacb1391e99', 'dart_revision': '95c951ad190f156eb61b99203c2e4948211c44a7', 'dart_observatory_packages_revision': 'cdc4b3d4c15b9c0c8e7702dff127b440afbb7485', diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 9887d8f5080e4..6c1f6227412f7 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -32,6 +32,17 @@ """ +_MOJO_EXPOSED_EXTENSIONS = ["CHROMIUM_bind_uniform_location", + "CHROMIUM_map_sub", + "CHROMIUM_miscellaneous", + "CHROMIUM_resize", + "CHROMIUM_sync_point", + "CHROMIUM_texture_mailbox", + "EXT_debug_marker", + "OES_vertex_array_object", + "occlusion_query_EXT"] + + # This string is copied directly out of the gl2.h file from GLES2.0 # # Edits: @@ -2803,14 +2814,14 @@ }, 'MapBufferSubDataCHROMIUM': { 'gen_cmd': False, - 'extension': True, + 'extension': "CHROMIUM_map_sub", 'chromium': True, 'client_test': False, 'pepper_interface': 'ChromiumMapSub', }, 'MapTexSubImage2DCHROMIUM': { 'gen_cmd': False, - 'extension': "CHROMIUM_sub_image", + 'extension': "CHROMIUM_map_sub", 'chromium': True, 'client_test': False, 'pepper_interface': 'ChromiumMapSub', @@ -3205,7 +3216,7 @@ }, 'UnmapBufferSubDataCHROMIUM': { 'gen_cmd': False, - 'extension': True, + 'extension': "CHROMIUM_map_sub", 'chromium': True, 'client_test': False, 'pepper_interface': 'ChromiumMapSub', @@ -3216,7 +3227,7 @@ }, 'UnmapTexSubImage2DCHROMIUM': { 'gen_cmd': False, - 'extension': "CHROMIUM_sub_image", + 'extension': "CHROMIUM_map_sub", 'chromium': True, 'client_test': False, 'pepper_interface': 'ChromiumMapSub', @@ -3454,7 +3465,7 @@ }, 'BindUniformLocationCHROMIUM': { 'type': 'GLchar', - 'extension': True, + 'extension': "CHROMIUM_bind_uniform_location", 'data_transfer_methods': ['bucket'], 'needs_size': True, 'gl_test_func': 'DoBindUniformLocationCHROMIUM', @@ -4350,25 +4361,15 @@ def WriteMojoGLES2Impl(self, func, file): file.Write("%s MojoGLES2Impl::%s(%s) {\n" % (func.return_type, func.original_name, func.MakeTypedOriginalArgString(""))) - # TODO(alhaad): Add Mojo C thunk for each of the following methods and - # remove this. - func_list = ["GenQueriesEXT", "BeginQueryEXT", "MapTexSubImage2DCHROMIUM", - "UnmapTexSubImage2DCHROMIUM", "DeleteQueriesEXT", - "EndQueryEXT", "GetQueryObjectuivEXT", "ShallowFlushCHROMIUM"] - if func.original_name in func_list: - file.Write("return static_cast" - "(MojoGLES2GetGLES2Interface(context_))->" + - func.original_name + "(" + func.MakeOriginalArgString("") + - ");") - file.Write("}") - return - extensions = ["CHROMIUM_sync_point", "CHROMIUM_texture_mailbox"] - if func.IsCoreGLFunction() or func.GetInfo("extension") in extensions: + is_mojo_extension = func.GetInfo("extension") in _MOJO_EXPOSED_EXTENSIONS + if func.IsCoreGLFunction() or is_mojo_extension: file.Write("MojoGLES2MakeCurrent(context_);"); func_return = "gl" + func.original_name + "(" + \ func.MakeOriginalArgString("") + ");" - if func.return_type == "void": + if func.original_name == "ResizeCHROMIUM": + file.Write("MGLResizeSurface(width, height);"); + elif func.return_type == "void": file.Write(func_return); else: file.Write("return " + func_return); @@ -10186,9 +10187,16 @@ def WriteMojoGLES2Impl(self, filename): #include "mojo/gpu/mojo_gles2_impl_autogen.h" #include "base/logging.h" +#include "mojo/public/c/gles2/chromium_bind_uniform_location.h" +#include "mojo/public/c/gles2/chromium_map_sub.h" +#include "mojo/public/c/gles2/chromium_miscellaneous.h" #include "mojo/public/c/gles2/chromium_sync_point.h" #include "mojo/public/c/gles2/chromium_texture_mailbox.h" +#include "mojo/public/c/gles2/ext_debug_marker.h" #include "mojo/public/c/gles2/gles2.h" +#include "mojo/public/c/gles2/occlusion_query_ext.h" +#include "mojo/public/c/gles2/oes_vertex_array_object.h" +#include "mojo/public/c/gpu/MGL/mgl_onscreen.h" namespace mojo { @@ -10585,10 +10593,6 @@ def main(argv): "gpu/command_buffer/common/gles2_cmd_format_test_autogen.h") gen.WriteGLES2InterfaceHeader( "gpu/command_buffer/client/gles2_interface_autogen.h") - gen.WriteMojoGLES2ImplHeader( - "mojo/gpu/mojo_gles2_impl_autogen.h") - gen.WriteMojoGLES2Impl( - "mojo/gpu/mojo_gles2_impl_autogen.cc") gen.WriteGLES2InterfaceStub( "gpu/command_buffer/client/gles2_interface_stub_autogen.h") gen.WriteGLES2InterfaceStubImpl( @@ -10632,16 +10636,18 @@ def main(argv): gen.WriteCommonUtilsImpl( "gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h") gen.WriteGLES2Header("gpu/GLES2/gl2chromium_autogen.h") + mojo_gles2_prefix = ("mojo/public/c/gles2/gles2_call_visitor") gen.WriteMojoGLCallVisitor(mojo_gles2_prefix + "_autogen.h") - mojo_extensions = ["CHROMIUM_texture_mailbox", "CHROMIUM_sync_point", - "CHROMIUM_sub_image", "CHROMIUM_miscellaneous", - "CHROMIUM_resize", "EXT_debug_marker", - "OES_vertex_array_object", "occlusion_query_EXT"] - for extension in mojo_extensions: + for extension in _MOJO_EXPOSED_EXTENSIONS: gen.WriteMojoGLCallVisitorForExtension( mojo_gles2_prefix + "_" + extension.lower() + "_autogen.h", extension) + gen.WriteMojoGLES2ImplHeader( + "mojo/gpu/mojo_gles2_impl_autogen.h") + gen.WriteMojoGLES2Impl( + "mojo/gpu/mojo_gles2_impl_autogen.cc") + Format(gen.generated_cpp_filenames) if gen.errors > 0: diff --git a/gpu/command_buffer/service/gl_surface_mock.h b/gpu/command_buffer/service/gl_surface_mock.h index 0652be64de396..97c8a091fb228 100644 --- a/gpu/command_buffer/service/gl_surface_mock.h +++ b/gpu/command_buffer/service/gl_surface_mock.h @@ -5,8 +5,9 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GL_SURFACE_MOCK_H_ #define GPU_COMMAND_BUFFER_SERVICE_GL_SURFACE_MOCK_H_ -#include "ui/gl/gl_surface.h" #include "testing/gmock/include/gmock/gmock.h" +#include "ui/gfx/swap_result.h" +#include "ui/gl/gl_surface.h" namespace gpu { @@ -18,8 +19,8 @@ class GLSurfaceMock : public gfx::GLSurface { MOCK_METHOD0(Destroy, void()); MOCK_METHOD1(Resize, bool(const gfx::Size& size)); MOCK_METHOD0(IsOffscreen, bool()); - MOCK_METHOD0(SwapBuffers, bool()); - MOCK_METHOD4(PostSubBuffer, bool(int x, int y, int width, int height)); + MOCK_METHOD0(SwapBuffers, gfx::SwapResult()); + MOCK_METHOD4(PostSubBuffer, gfx::SwapResult(int x, int y, int width, int height)); MOCK_METHOD0(SupportsPostSubBuffer, bool()); MOCK_METHOD0(GetSize, gfx::Size()); MOCK_METHOD0(GetHandle, void*()); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index f782d52c3133e..61ad037dbc685 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -8222,7 +8222,8 @@ error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM( gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer( is_offscreen ? offscreen_size_ : surface_->GetSize()); } - if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) { + if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height) != + gfx::SwapResult::SWAP_FAILED) { return error::kNoError; } else { LOG(ERROR) << "Context lost because PostSubBuffer failed."; @@ -10347,7 +10348,7 @@ void GLES2DecoderImpl::DoSwapBuffers() { glFlush(); } } else { - if (!surface_->SwapBuffers()) { + if (surface_->SwapBuffers() == gfx::SwapResult::SWAP_FAILED) { LOG(ERROR) << "Context lost because SwapBuffers failed."; if (!CheckResetStatus()) { MarkContextLost(error::kUnknown); diff --git a/mojo/BUILD.gn b/mojo/BUILD.gn deleted file mode 100644 index 7f55975397712..0000000000000 --- a/mojo/BUILD.gn +++ /dev/null @@ -1,111 +0,0 @@ -# Copyright 2014 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. - -import("//build/config/ui.gni") -import("//build/module_args/mojo.gni") -import("//mojo/public/mojo.gni") - -# TODO(beng): this meta target should probably move to the root dir's BUILD.gn. -group("mojo") { - # Meta-target, don't link into production code. - testonly = true - declare_args() { - mojo_use_go = false - - # TODO(ncbray): support ASAN once NaCl's GN build is unforked. - mojo_use_nacl = is_linux && !is_asan - } - deps = [ - ":tests", - "//benchmarks", - "//examples", - "//mojo/common", - "//mojo/dart/apptest", - "//mojo/dart/apptest:apptest_pkg", - "//mojo/dart/mojom", - "//mojo/dart/mojo_services", - "//mojo/dart/observatory_test", - "//mojo/public", - "//mojo/services", - "//services", - ] - - if (is_android) { - deps += [ - "//mojo/android", - "//mojo/java", - "//mojo/tools/android_shortcuts", - "//mojo/tools:remote_file_reader", - ] - } - - if (is_linux && mojo_use_go) { - deps += [ "//mojo/go" ] - } - - if (is_linux) { - deps += [ "//mojo/python" ] - } - - if (mojo_use_nacl) { - deps += [ - "//mojo/nacl:mojo_nacl", - "//mojo/nacl:mojo_nacl_tests", - ] - } -} - -group("tests") { - testonly = true - deps = [ - "//mojo/common:mojo_common_unittests", - "//mojo/converters/surfaces/tests:mojo_surfaces_lib_unittests", - "//mojo/edk/system:tests", - "//mojo/edk/test:public_tests", - "//mojo/dart/embedder/test:dart_unittests", - "//mojo/public/cpp/bindings/tests:versioning_apptests", - "//mojo/services/view_manager/public/cpp/tests:mojo_view_manager_lib_unittests", - "//mojo/tests:mojo_task_tracker_perftests", - "//mojo/tools:message_generator", - "//services/asset_bundle:apptests", - "//services/clipboard:apptests", - "//services/dart/dart_apptests", - "//services/files:apptests", - "//mojo/gpu:apptests", - "//mojo/services/files/public/c:apptests", - "//services/authenticating_url_loader_interceptor:apptests", - "//services/http_server:apptests", - "//services/prediction:apptests", - "//services/reaper:tests", - "//services/url_response_disk_cache:tests", - "//services/view_manager:mojo_view_manager_client_apptests", - "//services/view_manager:view_manager_service_apptests", - "//services/view_manager:view_manager_service_unittests", - "//services/window_manager:window_manager_apptests", - "//services/window_manager:window_manager_unittests", - "//shell:apptests", - ] - - if (is_linux) { - deps += [ "//services/python:python_apptests" ] - } - - if (is_android) { - deps += [ "//services/notifications:apptests" ] - } - - # TODO(jamesr): We only support building V8 snapshot data on a linux host since it - # needs a 32 bit toolchain and we don't have one configured for mac hosts. - if (host_os == "linux") { - deps += [ - "//mojo/edk/js:tests", - "//services/js:js_apptests", - "//services/js:js_services_unittests", - ] - } - - if (mojo_use_prebuilt_network_service) { - deps += [ "//mojo/public/tools:copy_network_service_apptests" ] - } -} diff --git a/mojo/OWNERS b/mojo/OWNERS deleted file mode 100644 index b8640873acef3..0000000000000 --- a/mojo/OWNERS +++ /dev/null @@ -1,11 +0,0 @@ -aa@chromium.org -abarth@chromium.org -ben@chromium.org -darin@chromium.org -davemoore@chromium.org -jamesr@chromium.org -mpcomplete@chromium.org -qsr@chromium.org -sky@chromium.org -viettrungluu@chromium.org -yzshen@chromium.org diff --git a/mojo/PRESUBMIT.py b/mojo/PRESUBMIT.py deleted file mode 100644 index 444a3725e03fe..0000000000000 --- a/mojo/PRESUBMIT.py +++ /dev/null @@ -1,288 +0,0 @@ -# Copyright 2014 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. - -"""Presubmit script for mojo - -See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts -for more details about the presubmit API built into depot_tools. -""" - -import os.path -import re - -# NOTE: The EDK allows all external paths, so doesn't need a whitelist. -_PACKAGE_WHITELISTED_EXTERNAL_PATHS = { - "SDK": ["//build/module_args/mojo.gni", - "//build/module_args/dart.gni", - "//testing/gtest", - "//third_party/cython", - "//third_party/khronos"], - "services": ["//build/module_args/mojo.gni", - "//testing/gtest"], -} - -# These files are not part of the exported package. -_PACKAGE_IGNORED_BUILD_FILES = { - "SDK": {}, - "EDK": {}, - "services": {"mojo/services/BUILD.gn"}, -} - - -_PACKAGE_PATH_PREFIXES = {"SDK": "mojo/public/", - "EDK": "mojo/edk/", - "services": "mojo/services"} - -# TODO(etiennej): python_binary_source_set added due to crbug.com/443147 -_PACKAGE_SOURCE_SET_TYPES = {"SDK": ["mojo_sdk_source_set", - "python_binary_source_set"], - "EDK": ["mojo_edk_source_set"], - "services": ["mojo_sdk_source_set"]} - -_ILLEGAL_EXTERNAL_PATH_WARNING_MESSAGE = \ - "Found disallowed external paths within SDK buildfiles." - -_ILLEGAL_SERVICES_ABSOLUTE_PATH_WARNING_MESSAGE = \ - "Found references to services' public buildfiles via absolute paths " \ - "within services' public buildfiles." - -_ILLEGAL_EDK_ABSOLUTE_PATH_WARNING_MESSAGE = \ - "Found references to the EDK via absolute paths within EDK buildfiles." - -_ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGE_TEMPLATE = \ - "Found references to the SDK via absolute paths within %s buildfiles." - -_ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGES = { - "SDK": _ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGE_TEMPLATE % "SDK", - "EDK": _ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGE_TEMPLATE % "EDK", - "services": _ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGE_TEMPLATE - % "services' public", -} - -_INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGE_TEMPLATE = \ - "All source sets in %s must be constructed via %s." - -_INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGES = { - "SDK": _INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGE_TEMPLATE - % ("the SDK", _PACKAGE_SOURCE_SET_TYPES["SDK"]), - "EDK": _INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGE_TEMPLATE - % ("the EDK", _PACKAGE_SOURCE_SET_TYPES["EDK"]), - "services": _INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGE_TEMPLATE - % ("services' client libs", _PACKAGE_SOURCE_SET_TYPES["services"]), -} - -def _IsBuildFileWithinPackage(f, package): - """Returns whether |f| specifies a GN build file within |package|.""" - assert package in _PACKAGE_PATH_PREFIXES - package_path_prefix = _PACKAGE_PATH_PREFIXES[package] - - if not f.LocalPath().startswith(package_path_prefix): - return False - if (not f.LocalPath().endswith("/BUILD.gn") and - not f.LocalPath().endswith(".gni")): - return False - if f.LocalPath() in _PACKAGE_IGNORED_BUILD_FILES[package]: - return False - return True - -def _AffectedBuildFilesWithinPackage(input_api, package): - """Returns all the affected build files within |package|.""" - return [f for f in input_api.AffectedFiles() - if _IsBuildFileWithinPackage(f, package)] - -def _FindIllegalAbsolutePathsInBuildFiles(input_api, package): - """Finds illegal absolute paths within the build files in - |input_api.AffectedFiles()| that are within |package|. - An illegal absolute path within the SDK or a service's SDK is one that is to - the SDK itself or a non-whitelisted external path. An illegal absolute path - within the EDK is one that is to the SDK or the EDK. - Returns any such references in a list of (file_path, line_number, - referenced_path) tuples.""" - illegal_references = [] - for f in _AffectedBuildFilesWithinPackage(input_api, package): - for line_num, line in f.ChangedContents(): - # Determine if this is a reference to an absolute path. - m = re.search(r'"(//[^"]*)"', line) - if not m: - continue - referenced_path = m.group(1) - - if not referenced_path.startswith("//mojo"): - # In the EDK, all external absolute paths are allowed. - if package == "EDK": - continue - - # Determine if this is a whitelisted external path. - if referenced_path in _PACKAGE_WHITELISTED_EXTERNAL_PATHS[package]: - continue - - illegal_references.append((f.LocalPath(), line_num, referenced_path)) - - return illegal_references - -def _PathReferenceInBuildFileWarningItem(build_file, line_num, referenced_path): - """Returns a string expressing a warning item that |referenced_path| is - referenced at |line_num| in |build_file|.""" - return "%s, line %d (%s)" % (build_file, line_num, referenced_path) - -def _IncorrectSourceSetTypeWarningItem(build_file, line_num): - """Returns a string expressing that the error occurs at |line_num| in - |build_file|.""" - return "%s, line %d" % (build_file, line_num) - -def _CheckNoIllegalAbsolutePathsInBuildFiles(input_api, output_api, package): - """Makes sure that the BUILD.gn files within |package| do not reference the - SDK/EDK via absolute paths, and do not reference disallowed external - dependencies.""" - sdk_references = [] - edk_references = [] - external_deps_references = [] - services_references = [] - - # Categorize any illegal references. - illegal_references = _FindIllegalAbsolutePathsInBuildFiles(input_api, package) - for build_file, line_num, referenced_path in illegal_references: - reference_string = _PathReferenceInBuildFileWarningItem(build_file, - line_num, - referenced_path) - if referenced_path.startswith("//mojo/public"): - sdk_references.append(reference_string) - elif package == "SDK": - external_deps_references.append(reference_string) - elif package == "services": - if referenced_path.startswith("//mojo/services"): - services_references.append(reference_string) - else: - external_deps_references.append(reference_string) - elif referenced_path.startswith("//mojo/edk"): - edk_references.append(reference_string) - - # Package up categorized illegal references into results. - results = [] - if sdk_references: - results.extend([output_api.PresubmitError( - _ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGES[package], - items=sdk_references)]) - - if external_deps_references: - assert package == "SDK" or package == "services" - results.extend([output_api.PresubmitError( - _ILLEGAL_EXTERNAL_PATH_WARNING_MESSAGE, - items=external_deps_references)]) - - if services_references: - assert package == "services" - results.extend([output_api.PresubmitError( - _ILLEGAL_SERVICES_ABSOLUTE_PATH_WARNING_MESSAGE, - items=services_references)]) - - if edk_references: - assert package == "EDK" - results.extend([output_api.PresubmitError( - _ILLEGAL_EDK_ABSOLUTE_PATH_WARNING_MESSAGE, - items=edk_references)]) - - return results - -def _CheckSourceSetsAreOfCorrectType(input_api, output_api, package): - """Makes sure that the BUILD.gn files always use the correct wrapper type for - |package|, which can be one of ["SDK", "EDK"], to construct source_set - targets.""" - assert package in _PACKAGE_SOURCE_SET_TYPES - required_source_set_type = _PACKAGE_SOURCE_SET_TYPES[package] - - problems = [] - for f in _AffectedBuildFilesWithinPackage(input_api, package): - for line_num, line in f.ChangedContents(): - m = re.search(r"[a-z_]*source_set\(", line) - if not m: - continue - source_set_type = m.group(0)[:-1] - if source_set_type in required_source_set_type: - continue - problems.append(_IncorrectSourceSetTypeWarningItem(f.LocalPath(), - line_num)) - - if not problems: - return [] - return [output_api.PresubmitError( - _INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGES[package], - items=problems)] - -def _CheckChangePylintsClean(input_api, output_api): - # Additional python module paths (we're in src/mojo/); not everyone needs - # them, but it's easiest to add them to everyone's path. - # For ply and jinja2: - third_party_path = os.path.join( - input_api.PresubmitLocalPath(), "..", "third_party") - # For the bindings generator: - mojo_public_bindings_pylib_path = os.path.join( - input_api.PresubmitLocalPath(), "public", "tools", "bindings", "pylib") - # For the python bindings: - mojo_python_bindings_path = os.path.join( - input_api.PresubmitLocalPath(), "public", "python") - # For the python bindings tests: - mojo_python_bindings_tests_path = os.path.join( - input_api.PresubmitLocalPath(), "python", "tests") - # For the roll tools scripts: - mojo_roll_tools_path = os.path.join( - input_api.PresubmitLocalPath(), "tools", "roll") - # For all mojo/tools scripts: - mopy_path = os.path.join(input_api.PresubmitLocalPath(), "tools") - # For all mojo/devtools scripts: - devtools_path = os.path.join(input_api.PresubmitLocalPath(), "devtools") - # TODO(vtl): Don't lint these files until the (many) problems are fixed - # (possibly by deleting/rewriting some files). - temporary_black_list = ( - r".*\bpublic[\\\/]tools[\\\/]bindings[\\\/]pylib[\\\/]mojom[\\\/]" - r"generate[\\\/].+\.py$", - r".*\bpublic[\\\/]tools[\\\/]bindings[\\\/]generators[\\\/].+\.py$") - black_list = input_api.DEFAULT_BLACK_LIST + temporary_black_list + ( - # Imported from Android tools, we might want not to fix the warnings - # raised for it to make it easier to compare the code with the original. - r".*\bdevtools[\\\/]common[\\\/]android_stack_parser[\\\/].+\.py$",) - - results = [] - pylint_extra_paths = [ - third_party_path, - mojo_public_bindings_pylib_path, - mojo_python_bindings_path, - mojo_python_bindings_tests_path, - mojo_roll_tools_path, - mopy_path, - devtools_path - ] - results.extend(input_api.canned_checks.RunPylint( - input_api, output_api, extra_paths_list=pylint_extra_paths, - black_list=black_list)) - return results - -def _BuildFileChecks(input_api, output_api): - """Performs checks on SDK, EDK, and services' public buildfiles.""" - results = [] - for package in ["SDK", "EDK", "services"]: - results.extend(_CheckNoIllegalAbsolutePathsInBuildFiles(input_api, - output_api, - package)) - results.extend(_CheckSourceSetsAreOfCorrectType(input_api, - output_api, - package)) - return results - -def _CommonChecks(input_api, output_api): - """Checks common to both upload and commit.""" - results = [] - results.extend(_BuildFileChecks(input_api, output_api)) - return results - -def CheckChangeOnUpload(input_api, output_api): - results = [] - results.extend(_CommonChecks(input_api, output_api)) - results.extend(_CheckChangePylintsClean(input_api, output_api)) - return results - -def CheckChangeOnCommit(input_api, output_api): - results = [] - results.extend(_CommonChecks(input_api, output_api)) - return results diff --git a/mojo/PRESUBMIT_test.py b/mojo/PRESUBMIT_test.py deleted file mode 100755 index 3e2443c7e77c6..0000000000000 --- a/mojo/PRESUBMIT_test.py +++ /dev/null @@ -1,310 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -import os -import sys -import unittest - -import PRESUBMIT - -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -from PRESUBMIT_test_mocks import MockFile -from PRESUBMIT_test_mocks import MockInputApi, MockOutputApi - -_SDK_BUILD_FILE = 'mojo/public/some/path/BUILD.gn' -_EDK_BUILD_FILE = 'mojo/edk/some/path/BUILD.gn' -_SERVICE_BUILD_FILE = 'mojo/services/some_service/public/BUILD.gn' -_IRRELEVANT_BUILD_FILE = 'mojo/foo/some/path/BUILD.gn' - -_PACKAGE_BUILDFILES = { - 'SDK' : _SDK_BUILD_FILE, - 'EDK' : _EDK_BUILD_FILE, - 'services' : _SERVICE_BUILD_FILE -} - -class AbsoluteReferencesInBuildFilesTest(unittest.TestCase): - """Tests the checking for illegal absolute paths within SDK/EDK buildfiles. - """ - def setUp(self): - self.sdk_absolute_path = '//mojo/public/some/absolute/path' - self.sdk_relative_path = 'mojo/public/some/relative/path' - self.edk_absolute_path = '//mojo/edk/some/absolute/path' - self.edk_relative_path = 'mojo/edk/some/relative/path' - self.service_absolute_path = '//mojo/services/some/service' - self.service_relative_path = '../../../some/service' - self.whitelisted_external_path = '//testing/gtest' - self.non_whitelisted_external_path = '//base' - - def inputApiContainingFileWithPaths(self, filename, paths): - """Returns a MockInputApi object with a single file having |filename| as - its name and |paths| as its contents, with each path being wrapped in a - pair of double-quotes to match the syntax for strings within BUILD.gn - files.""" - contents = [ '"%s"' % path for path in paths ] - mock_file = MockFile(filename, contents) - mock_input_api = MockInputApi() - mock_input_api.files.append(mock_file) - return mock_input_api - - def checkWarningWithSingleItem(self, - warning, - expected_message, - build_file, - line_num, - referenced_path): - """Checks that |warning| has a message of |expected_message| and a single - item whose contents are the absolute path warning item for - (build_file, line_num, referenced_path).""" - self.assertEqual(expected_message, warning.message) - self.assertEqual(1, len(warning.items)) - expected_item = PRESUBMIT._PathReferenceInBuildFileWarningItem( - build_file, line_num, referenced_path) - self.assertEqual(expected_item, warning.items[0]) - - def checkSDKAbsolutePathWarningWithSingleItem(self, - warning, - package, - build_file, - line_num, - referenced_path): - """Checks that |warning| has the message for an absolute SDK path within - |package| and a single item whose contents are the absolute path warning - item for (build_file, line_num, referenced_path).""" - expected_message = \ - PRESUBMIT._ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGES[package] - self.checkWarningWithSingleItem(warning, - expected_message, - build_file, - line_num, - referenced_path) - - def _testAbsoluteSDKReferenceInPackage(self, package): - """Tests that an absolute SDK path within |package| is flagged.""" - buildfile = _PACKAGE_BUILDFILES[package] - mock_input_api = self.inputApiContainingFileWithPaths( - buildfile, - [ self.sdk_relative_path, self.sdk_absolute_path ]) - warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) - - self.assertEqual(1, len(warnings)) - self.checkSDKAbsolutePathWarningWithSingleItem(warnings[0], - package, - buildfile, - 2, - self.sdk_absolute_path) - - def _testExternalReferenceInPackage(self, package): - """Tests that an illegal external path within |package| is flagged.""" - buildfile = _PACKAGE_BUILDFILES[package] - mock_input_api = self.inputApiContainingFileWithPaths( - buildfile, - [ self.non_whitelisted_external_path, self.whitelisted_external_path ]) - warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) - - if package == 'EDK': - # All external paths are allowed in the EDK. - self.assertEqual(0, len(warnings)) - return - - self.assertEqual(1, len(warnings)) - expected_message = PRESUBMIT._ILLEGAL_EXTERNAL_PATH_WARNING_MESSAGE - self.checkWarningWithSingleItem(warnings[0], - expected_message, - buildfile, - 1, - self.non_whitelisted_external_path) - - def testAbsoluteSDKReferenceInSDKBuildFile(self): - """Tests that an absolute SDK path within an SDK buildfile is flagged.""" - self._testAbsoluteSDKReferenceInPackage('SDK') - - def testExternalReferenceInSDKBuildFile(self): - """Tests that an illegal external path in an SDK buildfile is flagged.""" - self._testExternalReferenceInPackage('SDK') - - def testAbsoluteEDKReferenceInSDKBuildFile(self): - """Tests that an absolute EDK path in an SDK buildfile is flagged.""" - mock_input_api = self.inputApiContainingFileWithPaths( - _SDK_BUILD_FILE, - [ self.edk_absolute_path ]) - warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) - - self.assertEqual(1, len(warnings)) - expected_message = PRESUBMIT._ILLEGAL_EXTERNAL_PATH_WARNING_MESSAGE - self.checkWarningWithSingleItem(warnings[0], - expected_message, - _SDK_BUILD_FILE, - 1, - self.edk_absolute_path) - - def testAbsoluteSDKReferenceInEDKBuildFile(self): - """Tests that an absolute SDK path within an EDK buildfile is flagged.""" - self._testAbsoluteSDKReferenceInPackage('EDK') - - def testAbsoluteEDKReferenceInEDKBuildFile(self): - """Tests that an absolute EDK path in an EDK buildfile is flagged.""" - mock_input_api = self.inputApiContainingFileWithPaths( - _EDK_BUILD_FILE, - [ self.edk_absolute_path, self.edk_relative_path ]) - warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) - - self.assertEqual(1, len(warnings)) - expected_message = PRESUBMIT._ILLEGAL_EDK_ABSOLUTE_PATH_WARNING_MESSAGE - self.checkWarningWithSingleItem(warnings[0], - expected_message, - _EDK_BUILD_FILE, - 1, - self.edk_absolute_path) - - def testExternalReferenceInEDKBuildFile(self): - """Tests that an external path in an EDK buildfile is not flagged.""" - self._testExternalReferenceInPackage('EDK') - - def testAbsoluteSDKReferenceInServiceBuildFile(self): - """Tests that an absolute SDK path within a service's public buildfile is - flagged.""" - self._testAbsoluteSDKReferenceInPackage("services") - - def testAbsoluteServiceReferenceInServiceBuildFile(self): - """Tests that an absolute path to a service within a service's public - buildfile is flagged.""" - mock_input_api = self.inputApiContainingFileWithPaths( - _SERVICE_BUILD_FILE, - [ self.service_relative_path, self.service_absolute_path ]) - warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) - - self.assertEqual(1, len(warnings)) - expected_message = \ - PRESUBMIT._ILLEGAL_SERVICES_ABSOLUTE_PATH_WARNING_MESSAGE - self.checkWarningWithSingleItem(warnings[0], - expected_message, - _SERVICE_BUILD_FILE, - 2, - self.service_absolute_path) - - def testExternalReferenceInServiceBuildFile(self): - """Tests that an illegal external path in a service's buildfile is flagged - .""" - self._testExternalReferenceInPackage("services") - - def testIrrelevantBuildFile(self): - """Tests that nothing is flagged in a non SDK/EDK buildfile.""" - mock_input_api = self.inputApiContainingFileWithPaths( - _IRRELEVANT_BUILD_FILE, - [ self.sdk_absolute_path, - self.sdk_relative_path, - self.edk_absolute_path, - self.edk_relative_path, - self.non_whitelisted_external_path, - self.whitelisted_external_path ]) - warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) - self.assertEqual(0, len(warnings)) - -class SourceSetTypesInBuildFilesTest(unittest.TestCase): - """Tests checking of correct source set types within SDK/EDK buildfiles.""" - - def inputApiContainingFileWithSourceSets(self, filename, source_sets): - """Returns a MockInputApi object containing a single file having |filename| - as its name and |source_sets| as its contents.""" - mock_file = MockFile(filename, source_sets) - mock_input_api = MockInputApi() - mock_input_api.files.append(mock_file) - return mock_input_api - - def checkWarningWithSingleItem(self, - warning, - package, - build_file, - line_num): - """Checks that warning has the expected incorrect source set type message - for |package| and a single item whose contents are the incorrect source - set type item for (build_file, line_num).""" - expected_message = \ - PRESUBMIT._INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGES[package] - self.assertEqual(expected_message, warning.message) - self.assertEqual(1, len(warning.items)) - expected_item = PRESUBMIT._IncorrectSourceSetTypeWarningItem( - build_file, line_num) - self.assertEqual(expected_item, warning.items[0]) - - def _testNakedSourceSetInPackage(self, package): - """Tests that a source_set within |package| is flagged.""" - buildfile = _PACKAGE_BUILDFILES[package] - naked_source_set = 'source_set(' - correct_source_set = 'mojo_sdk_source_set(' - if package == 'EDK': - correct_source_set = 'mojo_edk_source_set(' - mock_input_api = self.inputApiContainingFileWithSourceSets( - buildfile, - [ correct_source_set, naked_source_set ]) - warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) - - self.assertEqual(1, len(warnings)) - self.checkWarningWithSingleItem(warnings[0], package, buildfile, 2) - - def _testWrongTypeOfWrapperSourceSetInPackage(self, package): - """Tests that the wrong type of wrapper source_set in |package| is flagged - (e.g., mojo_edk_source_set within the SDK).""" - buildfile = _PACKAGE_BUILDFILES[package] - mock_input_api = self.inputApiContainingFileWithSourceSets( - buildfile, - [ 'mojo_sdk_source_set(', 'mojo_edk_source_set(' ]) - warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) - - self.assertEqual(1, len(warnings)) - warning_line = 2 - if package == 'EDK': - warning_line = 1 - self.checkWarningWithSingleItem(warnings[0], - package, - buildfile, - warning_line) - - def testNakedSourceSetInSDKBuildFile(self): - """Tests that a source_set within the SDK is flagged.""" - self._testNakedSourceSetInPackage('SDK') - - def testPythonSourceSetInSDKBuildFile(self): - """Tests that a python_binary_source_set within an SDK buildfile is - accepted.""" - mock_input_api = self.inputApiContainingFileWithSourceSets( - _SDK_BUILD_FILE, - [ 'mojo_sdk_source_set(', 'python_binary_source_set(' ]) - warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) - - self.assertEqual(0, len(warnings)) - - def testEDKSourceSetInSDKBuildFile(self): - """Tests that a mojo_edk_source_set within an SDK buildfile is flagged.""" - self._testWrongTypeOfWrapperSourceSetInPackage('SDK') - - def testNakedSourceSetInEDKBuildFile(self): - """Tests that a source_set within the EDK is flagged.""" - self._testNakedSourceSetInPackage('EDK') - - def testSDKSourceSetInEDKBuildFile(self): - """Tests that a mojo_sdk_source_set within an EDK buildfile is flagged.""" - self._testWrongTypeOfWrapperSourceSetInPackage('EDK') - - def testNakedSourceSetInServiceBuildFile(self): - """Tests that a source_set within a service's public buildfile is flagged. - """ - self._testNakedSourceSetInPackage("services") - - def testEDKSourceSetInServiceBuildFile(self): - """Tests that a mojo_edk_source_set within a service's public buildfile is - flagged.""" - self._testWrongTypeOfWrapperSourceSetInPackage("services") - - def testIrrelevantBuildFile(self): - """Tests that a source_set in a non-SDK/EDK buildfile isn't flagged.""" - mock_input_api = self.inputApiContainingFileWithSourceSets( - _IRRELEVANT_BUILD_FILE, - [ 'source_set(' ]) - warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) - self.assertEqual(0, len(warnings)) - -if __name__ == '__main__': - unittest.main() diff --git a/mojo/README.md b/mojo/README.md deleted file mode 100644 index 5af1dcb50be60..0000000000000 --- a/mojo/README.md +++ /dev/null @@ -1,6 +0,0 @@ -Mojo -==== - -Mojo is an effort to extract a common platform out of Chrome's renderer and -plugin processes that can support multiple types of sandboxed content, such as -HTML, Pepper, or NaCl. diff --git a/mojo/android/BUILD.gn b/mojo/android/BUILD.gn index 8e0aacd89d934..746a1565a1fac 100644 --- a/mojo/android/BUILD.gn +++ b/mojo/android/BUILD.gn @@ -45,10 +45,10 @@ source_set("libsystem_java") { deps = [ ":system_java_jni_headers", "//base", - "//mojo/public/cpp/environment", - "//mojo/common:common", + "//mojo/message_pump", "//mojo/public/c/system:system", "//mojo/public/cpp/bindings:callback", + "//mojo/public/cpp/environment", ] } @@ -125,13 +125,12 @@ shared_library("mojo_java_unittests") { ":system_java_jni_headers", "//base", "//base/test/:test_support", - "//mojo/common", "//mojo/edk/system", + "//mojo/environment:chromium", + "//mojo/message_pump", "//mojo/public/cpp/bindings/tests:mojo_public_bindings_test_utils", - "//mojo/public/cpp/test_support:test_utils", "//mojo/public/cpp/environment", - "//mojo/edk/system", - "//mojo/environment:chromium", + "//mojo/public/cpp/test_support:test_utils", ] defines = [ "UNIT_TEST" ] } diff --git a/mojo/android/javatests/mojo_test_case.cc b/mojo/android/javatests/mojo_test_case.cc index 419d14d496c58..2df0bc7b64012 100644 --- a/mojo/android/javatests/mojo_test_case.cc +++ b/mojo/android/javatests/mojo_test_case.cc @@ -13,7 +13,7 @@ #include "base/run_loop.h" #include "base/test/test_support_android.h" #include "jni/MojoTestCase_jni.h" -#include "mojo/common/message_pump_mojo.h" +#include "mojo/message_pump/message_pump_mojo.h" #include "mojo/public/cpp/environment/environment.h" diff --git a/mojo/android/system/base_run_loop.cc b/mojo/android/system/base_run_loop.cc index 3d05e30c57d79..f361a94f98c2b 100644 --- a/mojo/android/system/base_run_loop.cc +++ b/mojo/android/system/base_run_loop.cc @@ -12,7 +12,7 @@ #include "base/bind.h" #include "base/message_loop/message_loop.h" #include "jni/BaseRunLoop_jni.h" -#include "mojo/common/message_pump_mojo.h" +#include "mojo/message_pump/message_pump_mojo.h" namespace mojo { namespace android { diff --git a/mojo/application/BUILD.gn b/mojo/application/BUILD.gn index f28c13bc2eac7..35cb345237848 100644 --- a/mojo/application/BUILD.gn +++ b/mojo/application/BUILD.gn @@ -13,7 +13,7 @@ source_set("application") { ] deps = [ "//base", - "//mojo/common", + "//mojo/message_pump", "//mojo/public/cpp/system", "//mojo/environment:chromium", ] @@ -27,8 +27,8 @@ source_set("content_handler") { deps = [ ":application", "//base", - "//mojo/common", "//mojo/environment:chromium", + "//mojo/message_pump", "//mojo/public/interfaces/application", "//mojo/services/content_handler/public/interfaces", "//mojo/services/network/public/interfaces", diff --git a/mojo/application/application_runner_chromium.cc b/mojo/application/application_runner_chromium.cc index 451d4480766fa..d54f4b23c2d9f 100644 --- a/mojo/application/application_runner_chromium.cc +++ b/mojo/application/application_runner_chromium.cc @@ -9,7 +9,7 @@ #include "base/debug/stack_trace.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" -#include "mojo/common/message_pump_mojo.h" +#include "mojo/message_pump/message_pump_mojo.h" #include "mojo/public/cpp/application/application_delegate.h" #include "mojo/public/cpp/application/application_impl.h" diff --git a/mojo/application/content_handler_factory.cc b/mojo/application/content_handler_factory.cc index 12310015d05d4..9594fdb9216be 100644 --- a/mojo/application/content_handler_factory.cc +++ b/mojo/application/content_handler_factory.cc @@ -13,7 +13,7 @@ #include "base/threading/platform_thread.h" #include "base/trace_event/trace_event.h" #include "mojo/application/application_runner_chromium.h" -#include "mojo/common/message_pump_mojo.h" +#include "mojo/message_pump/message_pump_mojo.h" #include "mojo/public/cpp/application/application_connection.h" #include "mojo/public/cpp/application/application_delegate.h" #include "mojo/public/cpp/application/application_impl.h" diff --git a/mojo/common/BUILD.gn b/mojo/common/BUILD.gn index 460471b808e78..242006097e4ce 100644 --- a/mojo/common/BUILD.gn +++ b/mojo/common/BUILD.gn @@ -5,54 +5,25 @@ import("//mojo/public/tools/bindings/mojom.gni") import("//testing/test.gni") -component("common") { - output_name = "mojo_common_lib" - +source_set("common") { sources = [ "binding_set.h", - "common_type_converters.cc", - "common_type_converters.h", - "data_pipe_drainer.cc", - "data_pipe_drainer.h", - "data_pipe_file_utils.cc", - "data_pipe_utils.cc", - "data_pipe_utils.h", - "data_pipe_utils_internal.h", - "handle_watcher.cc", - "handle_watcher.h", "interface_ptr_set.h", - "message_pump_mojo.cc", - "message_pump_mojo.h", - "message_pump_mojo_handler.h", "task_tracker.cc", "task_tracker.h", - "time_helper.cc", - "time_helper.h", ] - if (is_nacl) { - sources -= [ "data_pipe_file_utils.cc" ] - } - deps = [ "//base", - "//base/third_party/dynamic_annotations", - "//mojo/public/c/system", "//mojo/public/cpp/bindings", - "//mojo/public/cpp/environment:environment", - "//mojo/public/cpp/system", - "//url", ] } test("mojo_common_unittests") { sources = [ "binding_set_unittest.cc", - "common_type_converters_unittest.cc", - "data_pipe_utils_unittest.cc", - "handle_watcher_unittest.cc", + "callback_binding_unittest.cc", "interface_ptr_set_unittest.cc", - "message_pump_mojo_unittest.cc", "task_tracker_unittest.cc", ] @@ -61,10 +32,15 @@ test("mojo_common_unittests") { ":test_interfaces", "//base", "//base/test:test_support", - "//base:message_loop_tests", + "//mojo/converters/array_string:tests", + "//mojo/converters/base:tests", + "//mojo/converters/url:tests", + "//mojo/data_pipe_utils:tests", "//mojo/edk/test:run_all_unittests", "//mojo/edk/test:test_support", "//mojo/environment:chromium", + "//mojo/message_pump", + "//mojo/message_pump:tests", "//mojo/public/cpp/bindings", "//mojo/public/cpp/bindings:callback", "//mojo/public/cpp/system", @@ -83,8 +59,8 @@ mojom("test_interfaces") { source_set("tracing_impl") { sources = [ - "trace_controller_impl.cc", - "trace_controller_impl.h", + "trace_provider_impl.cc", + "trace_provider_impl.h", "tracing_impl.cc", "tracing_impl.h", ] diff --git a/mojo/common/binding_set_unittest.cc b/mojo/common/binding_set_unittest.cc index 421a405fd4694..c37053e248da2 100644 --- a/mojo/common/binding_set_unittest.cc +++ b/mojo/common/binding_set_unittest.cc @@ -5,8 +5,8 @@ #include "mojo/common/binding_set.h" #include "base/message_loop/message_loop.h" -#include "mojo/common/message_pump_mojo.h" #include "mojo/common/test_interfaces.mojom.h" +#include "mojo/message_pump/message_pump_mojo.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/mojo/common/callback_binding_unittest.cc b/mojo/common/callback_binding_unittest.cc new file mode 100644 index 0000000000000..aa59856dcc27a --- /dev/null +++ b/mojo/common/callback_binding_unittest.cc @@ -0,0 +1,104 @@ +// Copyright 2013 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/bind.h" +#include "mojo/public/cpp/bindings/callback.h" +#include "mojo/public/cpp/bindings/map.h" +#include "mojo/public/cpp/bindings/string.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +struct RunnableNoArgs { + RunnableNoArgs(int* calls) : calls(calls) {} + void Run() const { (*calls)++; } + + int* calls; +}; + +TEST(CallbackBindingTest, BaseBindToMojoCallbackNoParams) { + mojo::Callback cb; + int calls = 0; + RunnableNoArgs r(&calls); + cb = r; + cb.Run(); + EXPECT_EQ(1, calls); + + cb = base::Bind(&RunnableNoArgs::Run, base::Unretained(&r)); + cb.Run(); + EXPECT_EQ(2, calls); +} + +struct RunnableOnePrimitiveArg { + explicit RunnableOnePrimitiveArg(int* calls) : calls(calls) {} + void Run(int a) const { (*calls)++; } + + int* calls; +}; + +TEST(CallbackBindingTest, BaseBindToMojoCallbackPrimitiveParam) { + mojo::Callback mojo_callback; + int calls = 0; + RunnableOnePrimitiveArg r(&calls); + mojo_callback = r; + mojo_callback.Run(0); + EXPECT_EQ(1, calls); + + base::Callback base_callback = + base::Bind(&RunnableOnePrimitiveArg::Run, base::Unretained(&r)); + mojo_callback = base_callback; + mojo_callback.Run(0); + EXPECT_EQ(2, calls); +} + +struct RunnableOneMojoStringParam { + explicit RunnableOneMojoStringParam(int* calls) : calls(calls) {} + void Run(const mojo::String& s) const { (*calls)++; } + + int* calls; +}; + +TEST(CallbackBindingTest, BaseBindToMojoCallbackMojoStringParam) { + // The mojo type is a callback on mojo::String, but it'll expect to invoke + // callbacks with a parameter of type 'const Mojo::String&'. + mojo::Callback mojo_callback; + int calls = 0; + RunnableOneMojoStringParam r(&calls); + mojo_callback = r; + mojo_callback.Run(0); + EXPECT_EQ(1, calls); + + base::Callback base_callback = + base::Bind(&RunnableOneMojoStringParam::Run, base::Unretained(&r)); + mojo_callback = base_callback; + mojo_callback.Run(0); + EXPECT_EQ(2, calls); +} + +using ExampleMoveOnlyType = mojo::Map; + +struct RunnableOneMoveOnlyParam { + explicit RunnableOneMoveOnlyParam(int* calls) : calls(calls) {} + + void Run(ExampleMoveOnlyType m) const { (*calls)++; } + int* calls; +}; + +TEST(CallbackBindingTest, BaseBindToMoveOnlyParam) { + mojo::Callback mojo_callback; + int calls = 0; + RunnableOneMoveOnlyParam r(&calls); + mojo_callback = r; + ExampleMoveOnlyType m; + mojo_callback.Run(m.Clone()); + EXPECT_EQ(1, calls); + + base::Callback base_callback = + base::Bind(&RunnableOneMoveOnlyParam::Run, base::Unretained(&r)); + mojo_callback = base_callback; + mojo_callback.Run(m.Clone()); + EXPECT_EQ(2, calls); +} + +} // namespace diff --git a/mojo/common/common_type_converters_unittest.cc b/mojo/common/common_type_converters_unittest.cc deleted file mode 100644 index 4a360bdb93b1a..0000000000000 --- a/mojo/common/common_type_converters_unittest.cc +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2013 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 "mojo/common/common_type_converters.h" - -#include "base/bind.h" -#include "base/strings/utf_string_conversions.h" -#include "mojo/public/cpp/bindings/callback.h" -#include "mojo/public/cpp/bindings/map.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -namespace mojo { -namespace common { -namespace test { -namespace { - -void ExpectEqualsStringPiece(const std::string& expected, - const base::StringPiece& str) { - EXPECT_EQ(expected, str.as_string()); -} - -void ExpectEqualsMojoString(const std::string& expected, - const String& str) { - EXPECT_EQ(expected, str.get()); -} - -void ExpectEqualsString16(const base::string16& expected, - const base::string16& actual) { - EXPECT_EQ(expected, actual); -} - -void ExpectEqualsMojoString(const base::string16& expected, - const String& str) { - EXPECT_EQ(expected, str.To()); -} - -TEST(CommonTypeConvertersTest, StringPiece) { - std::string kText("hello world"); - - base::StringPiece string_piece(kText); - String mojo_string(String::From(string_piece)); - - ExpectEqualsMojoString(kText, mojo_string); - ExpectEqualsStringPiece(kText, mojo_string.To()); - - // Test implicit construction and conversion: - ExpectEqualsMojoString(kText, String::From(string_piece)); - ExpectEqualsStringPiece(kText, mojo_string.To()); - - // Test null String: - base::StringPiece empty_string_piece = String().To(); - EXPECT_TRUE(empty_string_piece.empty()); -} - -TEST(CommonTypeConvertersTest, String16) { - const base::string16 string16(base::ASCIIToUTF16("hello world")); - const String mojo_string(String::From(string16)); - - ExpectEqualsMojoString(string16, mojo_string); - EXPECT_EQ(string16, mojo_string.To()); - - // Test implicit construction and conversion: - ExpectEqualsMojoString(string16, String::From(string16)); - ExpectEqualsString16(string16, mojo_string.To()); - - // Test empty string conversion. - ExpectEqualsMojoString(base::string16(), String::From(base::string16())); -} - -TEST(CommonTypeConvertersTest, URL) { - GURL url("mojo:foo"); - String mojo_string(String::From(url)); - - ASSERT_EQ(url.spec(), mojo_string); - EXPECT_EQ(url.spec(), mojo_string.To().spec()); - EXPECT_EQ(url.spec(), String::From(url)); - - GURL invalid = String().To(); - ASSERT_TRUE(invalid.spec().empty()); - - String string_from_invalid = String::From(invalid); - EXPECT_FALSE(string_from_invalid.is_null()); - ASSERT_EQ(0U, string_from_invalid.size()); -} - -TEST(CommonTypeConvertersTest, ArrayUint8ToStdString) { - Array data(4); - data[0] = 'd'; - data[1] = 'a'; - data[2] = 't'; - data[3] = 'a'; - - EXPECT_EQ("data", data.To()); -} - -TEST(CommonTypeConvertersTest, StdStringToArrayUint8) { - std::string input("data"); - Array data = Array::From(input); - - ASSERT_EQ(4ul, data.size()); - EXPECT_EQ('d', data[0]); - EXPECT_EQ('a', data[1]); - EXPECT_EQ('t', data[2]); - EXPECT_EQ('a', data[3]); -} - -struct RunnableNoArgs { - RunnableNoArgs(int* calls) : calls(calls) {} - void Run() const { (*calls)++; } - - int* calls; -}; - -TEST(CommonTypeConvertersTest, BaseBindToMojoCallbackNoParams) { - mojo::Callback cb; - int calls = 0; - RunnableNoArgs r(&calls); - cb = r; - cb.Run(); - EXPECT_EQ(1, calls); - - cb = base::Bind(&RunnableNoArgs::Run, base::Unretained(&r)); - cb.Run(); - EXPECT_EQ(2, calls); -} - -struct RunnableOnePrimitiveArg { - explicit RunnableOnePrimitiveArg(int* calls) : calls(calls) {} - void Run(int a) const { (*calls)++; } - - int* calls; -}; - -TEST(CommonTypeConvertersTest, BaseBindToMojoCallbackPrimitiveParam) { - mojo::Callback mojo_callback; - int calls = 0; - RunnableOnePrimitiveArg r(&calls); - mojo_callback = r; - mojo_callback.Run(0); - EXPECT_EQ(1, calls); - - base::Callback base_callback = - base::Bind(&RunnableOnePrimitiveArg::Run, base::Unretained(&r)); - mojo_callback = base_callback; - mojo_callback.Run(0); - EXPECT_EQ(2, calls); -} - -struct RunnableOneMojoStringParam { - explicit RunnableOneMojoStringParam(int* calls) : calls(calls) {} - void Run(const String& s) const { (*calls)++; } - - int* calls; -}; - -TEST(CommonTypeConvertersTest, BaseBindToMojoCallbackMojoStringParam) { - // The mojo type is a callback on mojo::String, but it'll expect to invoke - // callbacks with a parameter of type 'const Mojo::String&'. - mojo::Callback mojo_callback; - int calls = 0; - RunnableOneMojoStringParam r(&calls); - mojo_callback = r; - mojo_callback.Run(0); - EXPECT_EQ(1, calls); - - base::Callback base_callback = - base::Bind(&RunnableOneMojoStringParam::Run, base::Unretained(&r)); - mojo_callback = base_callback; - mojo_callback.Run(0); - EXPECT_EQ(2, calls); -} - -using ExampleMoveOnlyType = Map; - -struct RunnableOneMoveOnlyParam { - explicit RunnableOneMoveOnlyParam(int* calls) : calls(calls) {} - - void Run(ExampleMoveOnlyType m) const { (*calls)++; } - int* calls; -}; - -TEST(CommonTypeConvertersTest, BaseBindToMoveOnlyParam) { - mojo::Callback mojo_callback; - int calls = 0; - RunnableOneMoveOnlyParam r(&calls); - mojo_callback = r; - ExampleMoveOnlyType m; - mojo_callback.Run(m.Clone()); - EXPECT_EQ(1, calls); - - base::Callback base_callback = - base::Bind(&RunnableOneMoveOnlyParam::Run, base::Unretained(&r)); - mojo_callback = base_callback; - mojo_callback.Run(m.Clone()); - EXPECT_EQ(2, calls); -} - -} // namespace -} // namespace test -} // namespace common -} // namespace mojo diff --git a/mojo/common/dart/BUILD.gn b/mojo/common/dart/BUILD.gn index 296e3c9fc5052..e2960779b108a 100644 --- a/mojo/common/dart/BUILD.gn +++ b/mojo/common/dart/BUILD.gn @@ -4,14 +4,14 @@ import("//mojo/public/dart/rules.gni") -dartzip_package("dart") { +dart_pkg("dart") { + libs = [ "lib/tracing_helper.dart" ] sources = [ - "lib/trace_controller_impl.dart", - "lib/tracing_helper.dart", + "lib/trace_provider_impl.dart", "pubspec.yaml", ] deps = [ "//mojo/public/dart", - "//mojo/services/tracing/public/interfaces", + "//mojo/dart/mojo_services", ] } diff --git a/mojo/common/dart/lib/trace_controller_impl.dart b/mojo/common/dart/lib/trace_controller_impl.dart deleted file mode 100644 index 6cbc634562ab5..0000000000000 --- a/mojo/common/dart/lib/trace_controller_impl.dart +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2015 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. - -import 'dart:async'; - -import 'package:mojo/application.dart'; -import 'package:mojo/bindings.dart'; -import 'package:mojo/core.dart'; -import 'package:mojom/tracing/tracing.mojom.dart'; - -class TraceControllerImpl implements TraceController { - TraceControllerStub _stub; - TraceDataCollectorProxy _collector; - // TODO(rudominer) We currently ignore _categories. - String _categories; - - TraceControllerImpl.fromEndpoint(MojoMessagePipeEndpoint e) { - _stub = TraceControllerStub.newFromEndpoint(e); - _stub.impl = this; - } - - @override - void startTracing(String categories, TraceDataCollectorProxy collector) { - assert(_collector == null); - _collector = collector; - _categories = categories; - } - - @override - void stopTracing() { - assert(_collector != null); - _collector.close(); - _collector = null; - } - - bool isActive() { - return _collector != null; - } - - void sendTraceMessage(String message) { - if (_collector != null) { - _collector.ptr.dataCollected(message); - } - } -} diff --git a/mojo/common/dart/lib/trace_provider_impl.dart b/mojo/common/dart/lib/trace_provider_impl.dart new file mode 100644 index 0000000000000..13901e09a7fae --- /dev/null +++ b/mojo/common/dart/lib/trace_provider_impl.dart @@ -0,0 +1,46 @@ +// Copyright 2015 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. + +import 'dart:async'; + +import 'package:mojo/application.dart'; +import 'package:mojo/bindings.dart'; +import 'package:mojo/core.dart'; +import 'package:mojo_services/tracing/tracing.mojom.dart'; + +class TraceProviderImpl implements TraceProvider { + TraceProviderStub _stub; + TraceRecorderProxy _recorder; + // TODO(rudominer) We currently ignore _categories. + String _categories; + + TraceProviderImpl.fromEndpoint(MojoMessagePipeEndpoint e) { + _stub = TraceProviderStub.newFromEndpoint(e); + _stub.impl = this; + } + + @override + void startTracing(String categories, TraceRecorderProxy recorder) { + assert(_recorder == null); + _recorder = recorder; + _categories = categories; + } + + @override + void stopTracing() { + assert(_recorder != null); + _recorder.close(); + _recorder = null; + } + + bool isActive() { + return _recorder != null; + } + + void sendTraceMessage(String message) { + if (_recorder != null) { + _recorder.ptr.record(message); + } + } +} diff --git a/mojo/common/dart/lib/tracing_helper.dart b/mojo/common/dart/lib/tracing_helper.dart index f776d9a3f9cde..23c121b459240 100644 --- a/mojo/common/dart/lib/tracing_helper.dart +++ b/mojo/common/dart/lib/tracing_helper.dart @@ -4,7 +4,7 @@ library tracing; -import 'trace_controller_impl.dart'; +import 'trace_provider_impl.dart'; import 'dart:async'; import 'dart:convert'; @@ -15,12 +15,12 @@ import 'dart:isolate'; import 'package:mojo/application.dart'; import 'package:mojo/bindings.dart'; import 'package:mojo/core.dart'; -import 'package:mojom/tracing/tracing.mojom.dart'; +import 'package:mojo_services/tracing/tracing.mojom.dart'; // TracingHelper is used by Dart code running in the Mojo shell in order // to perform tracing. class TracingHelper { - TraceControllerImpl _impl; + TraceProviderImpl _impl; String _tid; // Construct an instance of TracingHelper from within your application's @@ -36,9 +36,9 @@ class TracingHelper { } _tid = "${appName}/${Isolate.current.hashCode.toString()}"; ApplicationConnection connection = app.connectToApplication("mojo:tracing"); - connection.provideService(TraceControllerName, (e) { + connection.provideService(TraceProviderName, (e) { assert(_impl == null); - _impl = new TraceControllerImpl.fromEndpoint(e); + _impl = new TraceProviderImpl.fromEndpoint(e); }); } diff --git a/mojo/common/interface_ptr_set_unittest.cc b/mojo/common/interface_ptr_set_unittest.cc index 8edd4caaf7621..848b268c09069 100644 --- a/mojo/common/interface_ptr_set_unittest.cc +++ b/mojo/common/interface_ptr_set_unittest.cc @@ -5,8 +5,8 @@ #include "mojo/common/interface_ptr_set.h" #include "base/message_loop/message_loop.h" -#include "mojo/common/message_pump_mojo.h" #include "mojo/common/test_interfaces.mojom.h" +#include "mojo/message_pump/message_pump_mojo.h" #include "mojo/public/cpp/bindings/binding.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/mojo/common/trace_controller_impl.cc b/mojo/common/trace_provider_impl.cc similarity index 62% rename from mojo/common/trace_controller_impl.cc rename to mojo/common/trace_provider_impl.cc index e08f88c3eeaf7..cc4fd77e4fcb6 100644 --- a/mojo/common/trace_controller_impl.cc +++ b/mojo/common/trace_provider_impl.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/common/trace_controller_impl.h" +#include "mojo/common/trace_provider_impl.h" #include "base/logging.h" #include "base/trace_event/trace_config.h" @@ -12,19 +12,18 @@ namespace mojo { -TraceControllerImpl::TraceControllerImpl( - InterfaceRequest request) +TraceProviderImpl::TraceProviderImpl( + InterfaceRequest request) : tracing_already_started_(false), binding_(this, request.Pass()) { } -TraceControllerImpl::~TraceControllerImpl() { +TraceProviderImpl::~TraceProviderImpl() { } -void TraceControllerImpl::StartTracing( - const String& categories, - tracing::TraceDataCollectorPtr collector) { - DCHECK(!collector_.get()); - collector_ = collector.Pass(); +void TraceProviderImpl::StartTracing(const String& categories, + tracing::TraceRecorderPtr collector) { + DCHECK(!recorder_.get()); + recorder_ = collector.Pass(); if (!tracing_already_started_) { std::string categories_str = categories.To(); base::trace_event::TraceLog::GetInstance()->SetEnabled( @@ -34,21 +33,21 @@ void TraceControllerImpl::StartTracing( } } -void TraceControllerImpl::StopTracing() { - DCHECK(collector_); +void TraceProviderImpl::StopTracing() { + DCHECK(recorder_); base::trace_event::TraceLog::GetInstance()->SetDisabled(); base::trace_event::TraceLog::GetInstance()->Flush( - base::Bind(&TraceControllerImpl::SendChunk, base::Unretained(this))); + base::Bind(&TraceProviderImpl::SendChunk, base::Unretained(this))); } -void TraceControllerImpl::SendChunk( +void TraceProviderImpl::SendChunk( const scoped_refptr& events_str, bool has_more_events) { - DCHECK(collector_); - collector_->DataCollected(mojo::String(events_str->data())); + DCHECK(recorder_); + recorder_->Record(mojo::String(events_str->data())); if (!has_more_events) { - collector_.reset(); + recorder_.reset(); } } diff --git a/mojo/common/trace_controller_impl.h b/mojo/common/trace_provider_impl.h similarity index 63% rename from mojo/common/trace_controller_impl.h rename to mojo/common/trace_provider_impl.h index 482f709947dfc..82735a57c8cef 100644 --- a/mojo/common/trace_controller_impl.h +++ b/mojo/common/trace_provider_impl.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MOJO_COMMON_TRACING_CONTROLLER_IMPL_H_ -#define MOJO_COMMON_TRACING_CONTROLLER_IMPL_H_ +#ifndef MOJO_COMMON_TRACE_PROVIDER_IMPL_H_ +#define MOJO_COMMON_TRACE_PROVIDER_IMPL_H_ #include "base/memory/ref_counted_memory.h" #include "mojo/public/cpp/bindings/interface_request.h" @@ -12,11 +12,10 @@ namespace mojo { -class TraceControllerImpl : public tracing::TraceController { +class TraceProviderImpl : public tracing::TraceProvider { public: - explicit TraceControllerImpl( - InterfaceRequest request); - ~TraceControllerImpl() override; + explicit TraceProviderImpl(InterfaceRequest request); + ~TraceProviderImpl() override; // Set to true if base::trace_event::TraceLog is enabled externally to this // class. If this is set to true this class will save the collector but not @@ -27,21 +26,21 @@ class TraceControllerImpl : public tracing::TraceController { } private: - // tracing::TraceController implementation: + // tracing::TraceProvider implementation: void StartTracing(const String& categories, - tracing::TraceDataCollectorPtr collector) override; + tracing::TraceRecorderPtr collector) override; void StopTracing() override; void SendChunk(const scoped_refptr& events_str, bool has_more_events); bool tracing_already_started_; - tracing::TraceDataCollectorPtr collector_; - StrongBinding binding_; + tracing::TraceRecorderPtr recorder_; + StrongBinding binding_; - DISALLOW_COPY_AND_ASSIGN(TraceControllerImpl); + DISALLOW_COPY_AND_ASSIGN(TraceProviderImpl); }; } // namespace mojo -#endif // MOJO_COMMON_TRACING_CONTROLLER_IMPL_H_ +#endif // MOJO_COMMON_TRACE_PROVIDER_IMPL_H_ diff --git a/mojo/common/tracing_impl.cc b/mojo/common/tracing_impl.cc index ec5dfa3e3202f..2a6eac1e92fc0 100644 --- a/mojo/common/tracing_impl.cc +++ b/mojo/common/tracing_impl.cc @@ -5,7 +5,7 @@ #include "mojo/common/tracing_impl.h" #include "base/trace_event/trace_event_impl.h" -#include "mojo/common/trace_controller_impl.h" +#include "mojo/common/trace_provider_impl.h" #include "mojo/public/cpp/application/application_connection.h" #include "mojo/public/cpp/application/application_impl.h" @@ -23,8 +23,8 @@ void TracingImpl::Initialize(ApplicationImpl* app) { } void TracingImpl::Create(ApplicationConnection* connection, - InterfaceRequest request) { - new TraceControllerImpl(request.Pass()); + InterfaceRequest request) { + new TraceProviderImpl(request.Pass()); } } // namespace mojo diff --git a/mojo/common/tracing_impl.h b/mojo/common/tracing_impl.h index e245bd663e8d3..a996d5c4b281c 100644 --- a/mojo/common/tracing_impl.h +++ b/mojo/common/tracing_impl.h @@ -13,7 +13,7 @@ namespace mojo { class ApplicationImpl; -class TracingImpl : public InterfaceFactory { +class TracingImpl : public InterfaceFactory { public: TracingImpl(); ~TracingImpl() override; @@ -23,9 +23,9 @@ class TracingImpl : public InterfaceFactory { void Initialize(ApplicationImpl* app); private: - // InterfaceFactory implementation. + // InterfaceFactory implementation. void Create(ApplicationConnection* connection, - InterfaceRequest request) override; + InterfaceRequest request) override; DISALLOW_COPY_AND_ASSIGN(TracingImpl); }; diff --git a/mojo/converters/array_string/BUILD.gn b/mojo/converters/array_string/BUILD.gn new file mode 100644 index 0000000000000..8a3610322af7b --- /dev/null +++ b/mojo/converters/array_string/BUILD.gn @@ -0,0 +1,28 @@ +# Copyright 2015 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. + +source_set("array_string") { + sources = [ + "array_string_type_converters.cc", + "array_string_type_converters.h", + ] + + deps = [ + "//base", + "//mojo/public/cpp/bindings", + ] +} + +source_set("tests") { + testonly = true + sources = [ + "array_string_type_converters_unittest.cc", + ] + + deps = [ + ":array_string", + "//base", + "//testing/gtest", + ] +} diff --git a/mojo/converters/array_string/array_string_type_converters.cc b/mojo/converters/array_string/array_string_type_converters.cc new file mode 100644 index 0000000000000..02019f00bb652 --- /dev/null +++ b/mojo/converters/array_string/array_string_type_converters.cc @@ -0,0 +1,29 @@ +// Copyright 2013 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 "mojo/converters/array_string/array_string_type_converters.h" + +#include + +#include "base/strings/utf_string_conversions.h" + +namespace mojo { + +std::string TypeConverter>::Convert( + const Array& input) { + if (input.is_null()) + return std::string(); + + return std::string(reinterpret_cast(&input.front()), + input.size()); +} + +Array TypeConverter, std::string>::Convert( + const std::string& input) { + Array result(input.size()); + memcpy(&result.front(), input.c_str(), input.size()); + return result.Pass(); +} + +} // namespace mojo diff --git a/mojo/common/common_type_converters.h b/mojo/converters/array_string/array_string_type_converters.h similarity index 53% rename from mojo/common/common_type_converters.h rename to mojo/converters/array_string/array_string_type_converters.h index 9bd21e8dca71f..f5e199605d473 100644 --- a/mojo/common/common_type_converters.h +++ b/mojo/converters/array_string/array_string_type_converters.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MOJO_COMMON_COMMON_TYPE_CONVERTERS_H_ -#define MOJO_COMMON_COMMON_TYPE_CONVERTERS_H_ +#ifndef MOJO_CONVERTERS_ARRAY_STRING_ARRAY_STRING_TYPE_CONVERTERS_H_ +#define MOJO_CONVERTERS_ARRAY_STRING_ARRAY_STRING_TYPE_CONVERTERS_H_ #include "base/strings/string16.h" #include "base/strings/string_piece.h" @@ -11,40 +11,8 @@ #include "mojo/public/cpp/bindings/string.h" #include "mojo/public/cpp/bindings/type_converter.h" -class GURL; - namespace mojo { -template <> -struct TypeConverter { - static String Convert(const base::StringPiece& input); -}; - -template <> -struct TypeConverter { - static base::StringPiece Convert(const String& input); -}; - -template <> -struct TypeConverter { - static String Convert(const base::string16& input); -}; - -template <> -struct TypeConverter { - static base::string16 Convert(const String& input); -}; - -template <> -struct TypeConverter { - static String Convert(const GURL& input); -}; - -template <> -struct TypeConverter { - static GURL Convert(const String& input); -}; - // TODO(erg): In the very long term, we will want to remove conversion between // std::strings and arrays of unsigned bytes. However, there is too much code // across chrome which uses std::string as a bag of bytes that we probably @@ -61,4 +29,4 @@ struct TypeConverter, std::string> { } // namespace mojo -#endif // MOJO_COMMON_COMMON_TYPE_CONVERTERS_H_ +#endif // MOJO_CONVERTERS_ARRAY_STRING_ARRAY_STRING_TYPE_CONVERTERS_H_ diff --git a/mojo/converters/array_string/array_string_type_converters_unittest.cc b/mojo/converters/array_string/array_string_type_converters_unittest.cc new file mode 100644 index 0000000000000..a28f571bbf675 --- /dev/null +++ b/mojo/converters/array_string/array_string_type_converters_unittest.cc @@ -0,0 +1,38 @@ +// Copyright 2013 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 "mojo/converters/array_string/array_string_type_converters.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace mojo { +namespace common { +namespace test { +namespace { + +TEST(CommonTypeConvertersTest, ArrayUint8ToStdString) { + Array data(4); + data[0] = 'd'; + data[1] = 'a'; + data[2] = 't'; + data[3] = 'a'; + + EXPECT_EQ("data", data.To()); +} + +TEST(CommonTypeConvertersTest, StdStringToArrayUint8) { + std::string input("data"); + Array data = Array::From(input); + + ASSERT_EQ(4ul, data.size()); + EXPECT_EQ('d', data[0]); + EXPECT_EQ('a', data[1]); + EXPECT_EQ('t', data[2]); + EXPECT_EQ('a', data[3]); +} + +} // namespace +} // namespace test +} // namespace common +} // namespace mojo diff --git a/mojo/converters/base/BUILD.gn b/mojo/converters/base/BUILD.gn new file mode 100644 index 0000000000000..3779edfcade37 --- /dev/null +++ b/mojo/converters/base/BUILD.gn @@ -0,0 +1,30 @@ +# Copyright 2015 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. + +source_set("base") { + sources = [ + "base_type_converters.cc", + "base_type_converters.h", + ] + + deps = [ + "//base", + "//mojo/public/cpp/bindings", + ] +} + +source_set("tests") { + testonly = true + + sources = [ + "base_type_converters_unittest.cc", + ] + + deps = [ + ":base", + "//base", + "//mojo/public/cpp/bindings", + "//testing/gtest", + ] +} diff --git a/mojo/common/common_type_converters.cc b/mojo/converters/base/base_type_converters.cc similarity index 53% rename from mojo/common/common_type_converters.cc rename to mojo/converters/base/base_type_converters.cc index 114b409d74882..d4649ce8a5867 100644 --- a/mojo/common/common_type_converters.cc +++ b/mojo/converters/base/base_type_converters.cc @@ -1,13 +1,12 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// Copyright 2015 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 "mojo/common/common_type_converters.h" +#include "mojo/converters/base/base_type_converters.h" #include #include "base/strings/utf_string_conversions.h" -#include "url/gurl.h" namespace mojo { @@ -38,28 +37,4 @@ base::string16 TypeConverter::Convert( return base::UTF8ToUTF16(input.To()); } -String TypeConverter::Convert(const GURL& input) { - return String(input.spec()); -} - -GURL TypeConverter::Convert(const String& input) { - return GURL(input.get()); -} - -std::string TypeConverter >::Convert( - const Array& input) { - if (input.is_null()) - return std::string(); - - return std::string(reinterpret_cast(&input.front()), - input.size()); -} - -Array TypeConverter, std::string>::Convert( - const std::string& input) { - Array result(input.size()); - memcpy(&result.front(), input.c_str(), input.size()); - return result.Pass(); -} - } // namespace mojo diff --git a/mojo/converters/base/base_type_converters.h b/mojo/converters/base/base_type_converters.h new file mode 100644 index 0000000000000..c83bc900e1690 --- /dev/null +++ b/mojo/converters/base/base_type_converters.h @@ -0,0 +1,38 @@ +// Copyright 2015 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. + +#ifndef MOJO_CONVERTERS_BASE_BASE_TYPE_CONVERTERS_H_ +#define MOJO_CONVERTERS_BASE_BASE_TYPE_CONVERTERS_H_ + +#include "base/strings/string16.h" +#include "base/strings/string_piece.h" +#include "mojo/public/cpp/bindings/array.h" +#include "mojo/public/cpp/bindings/string.h" +#include "mojo/public/cpp/bindings/type_converter.h" + +namespace mojo { + +template <> +struct TypeConverter { + static String Convert(const base::StringPiece& input); +}; + +template <> +struct TypeConverter { + static base::StringPiece Convert(const String& input); +}; + +template <> +struct TypeConverter { + static String Convert(const base::string16& input); +}; + +template <> +struct TypeConverter { + static base::string16 Convert(const String& input); +}; + +} // namespace mojo + +#endif // MOJO_CONVERTERS_BASE_BASE_TYPE_CONVERTERS_H_ diff --git a/mojo/converters/base/base_type_converters_unittest.cc b/mojo/converters/base/base_type_converters_unittest.cc new file mode 100644 index 0000000000000..351eebc903ec2 --- /dev/null +++ b/mojo/converters/base/base_type_converters_unittest.cc @@ -0,0 +1,66 @@ +// Copyright 2013 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 "mojo/converters/base/base_type_converters.h" + +#include "base/bind.h" +#include "base/strings/utf_string_conversions.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace mojo { +namespace { + +void ExpectEqualsStringPiece(const std::string& expected, + const base::StringPiece& str) { + EXPECT_EQ(expected, str.as_string()); +} + +void ExpectEqualsMojoString(const std::string& expected, const String& str) { + EXPECT_EQ(expected, str.get()); +} + +void ExpectEqualsString16(const base::string16& expected, + const base::string16& actual) { + EXPECT_EQ(expected, actual); +} + +void ExpectEqualsMojoString(const base::string16& expected, const String& str) { + EXPECT_EQ(expected, str.To()); +} + +TEST(BaseTypeConvertersTest, StringPiece) { + std::string kText("hello world"); + + base::StringPiece string_piece(kText); + String mojo_string(String::From(string_piece)); + + ExpectEqualsMojoString(kText, mojo_string); + ExpectEqualsStringPiece(kText, mojo_string.To()); + + // Test implicit construction and conversion: + ExpectEqualsMojoString(kText, String::From(string_piece)); + ExpectEqualsStringPiece(kText, mojo_string.To()); + + // Test null String: + base::StringPiece empty_string_piece = String().To(); + EXPECT_TRUE(empty_string_piece.empty()); +} + +TEST(BaseTypeConvertersTest, String16) { + const base::string16 string16(base::ASCIIToUTF16("hello world")); + const String mojo_string(String::From(string16)); + + ExpectEqualsMojoString(string16, mojo_string); + EXPECT_EQ(string16, mojo_string.To()); + + // Test implicit construction and conversion: + ExpectEqualsMojoString(string16, String::From(string16)); + ExpectEqualsString16(string16, mojo_string.To()); + + // Test empty string conversion. + ExpectEqualsMojoString(base::string16(), String::From(base::string16())); +} + +} // namespace +} // namespace mojo diff --git a/mojo/converters/url/BUILD.gn b/mojo/converters/url/BUILD.gn new file mode 100644 index 0000000000000..4082c67fb195c --- /dev/null +++ b/mojo/converters/url/BUILD.gn @@ -0,0 +1,30 @@ +# Copyright 2015 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. + +source_set("url") { + sources = [ + "url_type_converters.cc", + "url_type_converters.h", + ] + + deps = [ + "//mojo/public/cpp/bindings", + "//url", + ] +} + +source_set("tests") { + testonly = true + + sources = [ + "url_type_converters_unittest.cc", + ] + + deps = [ + ":url", + "//mojo/public/cpp/bindings", + "//testing/gtest", + "//url", + ] +} diff --git a/mojo/converters/url/url_type_converters.cc b/mojo/converters/url/url_type_converters.cc new file mode 100644 index 0000000000000..8b504ff6cdb54 --- /dev/null +++ b/mojo/converters/url/url_type_converters.cc @@ -0,0 +1,19 @@ +// Copyright 2015 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 "mojo/converters/url/url_type_converters.h" + +#include "url/gurl.h" + +namespace mojo { + +String TypeConverter::Convert(const GURL& input) { + return String(input.spec()); +} + +GURL TypeConverter::Convert(const String& input) { + return GURL(input.get()); +} + +} // namespace mojo diff --git a/mojo/converters/url/url_type_converters.h b/mojo/converters/url/url_type_converters.h new file mode 100644 index 0000000000000..7842d547273fb --- /dev/null +++ b/mojo/converters/url/url_type_converters.h @@ -0,0 +1,26 @@ +// Copyright 2015 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. + +#ifndef MOJO_CONVERTERS_URL_URL_TYPE_CONVERTERS_H_ +#define MOJO_CONVERTERS_URL_URL_TYPE_CONVERTERS_H_ + +#include "mojo/public/cpp/bindings/type_converter.h" +#include "mojo/public/cpp/bindings/string.h" + +class GURL; + +namespace mojo { +template <> +struct TypeConverter { + static String Convert(const GURL& input); +}; + +template <> +struct TypeConverter { + static GURL Convert(const String& input); +}; + +} // namespace mojo + +#endif // MOJO_CONVERTERS_URL_URL_TYPE_CONVERTERS_H_ diff --git a/mojo/converters/url/url_type_converters_unittest.cc b/mojo/converters/url/url_type_converters_unittest.cc new file mode 100644 index 0000000000000..bc9407423dd66 --- /dev/null +++ b/mojo/converters/url/url_type_converters_unittest.cc @@ -0,0 +1,31 @@ +// Copyright 2015 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 "mojo/converters/url/url_type_converters.h" + +#include "mojo/public/cpp/bindings/string.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace mojo { +namespace { + +TEST(UrlTypeConvertersTest, URL) { + GURL url("mojo:foo"); + String mojo_string(String::From(url)); + + ASSERT_EQ(url.spec(), mojo_string); + EXPECT_EQ(url.spec(), mojo_string.To().spec()); + EXPECT_EQ(url.spec(), String::From(url)); + + GURL invalid = String().To(); + ASSERT_TRUE(invalid.spec().empty()); + + String string_from_invalid = String::From(invalid); + EXPECT_FALSE(string_from_invalid.is_null()); + ASSERT_EQ(0U, string_from_invalid.size()); +} + +} // namespace +} // namespace mojo diff --git a/mojo/dart/BUILD.gn b/mojo/dart/BUILD.gn new file mode 100644 index 0000000000000..88cc7fea62d69 --- /dev/null +++ b/mojo/dart/BUILD.gn @@ -0,0 +1,14 @@ +# Copyright 2014 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. + +group("dart") { + deps = [ + "//mojo/dart/apptest", + "//mojo/dart/dart_snapshotter($host_toolchain)", + "//mojo/dart/http_load_test", + "//mojo/dart/mojom", + "//mojo/dart/mojo_services", + "//mojo/dart/observatory_test", + ] +} diff --git a/mojo/dart/apptest/BUILD.gn b/mojo/dart/apptest/BUILD.gn index 8d4092ff3fca2..36e25c4b39542 100644 --- a/mojo/dart/apptest/BUILD.gn +++ b/mojo/dart/apptest/BUILD.gn @@ -4,24 +4,13 @@ import("//mojo/public/dart/rules.gni") -dartzip_package("apptest") { - uses_pub = true +dart_pkg("apptest") { + libs = [ "lib/apptest.dart" ] sources = [ - "lib/apptest.dart", "pubspec.yaml", ] deps = [ "//mojo/public/dart", - ] -} - -dart_pkg("apptest_pkg") { - entrypoints = [ "lib/apptest.dart" ] - sources = [ - "pubspec.yaml", - ] - deps = [ - "//mojo/public/dart:mojo", "//third_party/dart-pkg", ] } diff --git a/mojo/dart/apptest/lib/apptest.dart b/mojo/dart/apptest/lib/apptest.dart index 9d023099e8513..96c76f07a7b13 100644 --- a/mojo/dart/apptest/lib/apptest.dart +++ b/mojo/dart/apptest/lib/apptest.dart @@ -10,8 +10,7 @@ import 'package:mojo/application.dart'; import 'package:mojo/bindings.dart'; import 'package:mojo/core.dart'; -// Import and reexport the test package. We are a *.dartzip file designed to -// be linked into your_apptest.mojo file and are your main entrypoint. +// Import and reexport the test package. import 'package:test/test.dart'; export 'package:test/test.dart'; diff --git a/mojo/dart/dart_snapshotter/BUILD.gn b/mojo/dart/dart_snapshotter/BUILD.gn new file mode 100644 index 0000000000000..4174569a113ea --- /dev/null +++ b/mojo/dart/dart_snapshotter/BUILD.gn @@ -0,0 +1,27 @@ +# Copyright 2014 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. + +executable("dart_snapshotter") { + sources = [ + "main.cc", + "vm.cc", + "vm.h", + ] + + deps = [ + "//base", + "//build/config/sanitizers:deps", + "//dart/runtime/vm:libdart_platform", + "//dart/runtime:libdart", + "//mojo/common", + "//mojo/dart/embedder:dart_snapshot_cc", + "//mojo/edk/system", + "//mojo/environment:chromium", + "//mojo/public/cpp/system", + "//mojo/public/cpp/utility", + "//mojo/public/interfaces/application", + "//third_party/zlib", + "//tonic", + ] +} diff --git a/mojo/dart/dart_snapshotter/main.cc b/mojo/dart/dart_snapshotter/main.cc new file mode 100644 index 0000000000000..48e5341af148b --- /dev/null +++ b/mojo/dart/dart_snapshotter/main.cc @@ -0,0 +1,100 @@ +// Copyright 2015 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 + +#include "base/at_exit.h" +#include "base/basictypes.h" +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/process/memory.h" +#include "dart/runtime/include/dart_api.h" +#include "mojo/dart/dart_snapshotter/vm.h" +#include "mojo/edk/embedder/embedder.h" +#include "mojo/edk/embedder/simple_platform_support.h" +#include "tonic/dart_error.h" +#include "tonic/dart_isolate_scope.h" +#include "tonic/dart_library_loader.h" +#include "tonic/dart_library_provider_files.h" +#include "tonic/dart_script_loader_sync.h" +#include "tonic/dart_state.h" + +const char kHelp[] = "help"; +const char kPackageRoot[] = "package-root"; +const char kSnapshot[] = "snapshot"; + +const uint8_t magic_number[] = { 0xf5, 0xf5, 0xdc, 0xdc }; + +void Usage() { + std::cerr << "Usage: dart_snapshotter" + << " --" << kPackageRoot << " --" << kSnapshot + << " " << std::endl; +} + +void WriteSnapshot(base::FilePath path) { + uint8_t* buffer; + intptr_t size; + CHECK(!tonic::LogIfError(Dart_CreateScriptSnapshot(&buffer, &size))); + + intptr_t magic_number_len = sizeof(magic_number); + CHECK_EQ(base::WriteFile( + path, reinterpret_cast(magic_number), sizeof(magic_number)), + magic_number_len); + CHECK(base::AppendToFile( + path, reinterpret_cast(buffer), size)); +} + +int main(int argc, const char* argv[]) { + base::AtExitManager exit_manager; + base::EnableTerminationOnHeapCorruption(); + base::CommandLine::Init(argc, argv); + + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + + if (command_line.HasSwitch(kHelp) || command_line.GetArgs().empty()) { + Usage(); + return 0; + } + + // Initialize mojo. + mojo::embedder::Init( + make_scoped_ptr(new mojo::embedder::SimplePlatformSupport())); + + InitDartVM(); + + CHECK(command_line.HasSwitch(kPackageRoot)) << "Need --package-root"; + CHECK(command_line.HasSwitch(kSnapshot)) << "Need --snapshot"; + auto args = command_line.GetArgs(); + CHECK(args.size() == 1); + + Dart_Isolate isolate = CreateDartIsolate(); + CHECK(isolate); + + tonic::DartIsolateScope scope(isolate); + tonic::DartApiScope api_scope; + + auto isolate_data = SnapshotterDartState::Current(); + CHECK(isolate_data != nullptr); + + // Use tonic's library tag handler. + CHECK(!tonic::LogIfError(Dart_SetLibraryTagHandler( + tonic::DartLibraryLoader::HandleLibraryTag))); + + // Use tonic's file system library provider. + isolate_data->set_library_provider( + new tonic::DartLibraryProviderFiles( + command_line.GetSwitchValuePath(kPackageRoot))); + + // Load script. + tonic::DartScriptLoaderSync::LoadScript(args[0], + isolate_data->library_provider()); + + // Write snapshot. + WriteSnapshot(command_line.GetSwitchValuePath(kSnapshot)); + + return 0; +} diff --git a/mojo/dart/dart_snapshotter/test/dart_snapshotter_test.py b/mojo/dart/dart_snapshotter/test/dart_snapshotter_test.py new file mode 100755 index 0000000000000..60fb1452c9715 --- /dev/null +++ b/mojo/dart/dart_snapshotter/test/dart_snapshotter_test.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# Copyright 2015 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. + +import argparse +import hashlib +import os +import subprocess +import sys +import tempfile + +SNAPSHOT_TEST_DIR = os.path.dirname(os.path.abspath(__file__)) +SRC_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname( + SNAPSHOT_TEST_DIR)))) +DART_DIR = os.path.join(SRC_ROOT, 'dart') + +VM_SNAPSHOT_FILES=[ + # Header files. + 'datastream.h', + 'object.h', + 'raw_object.h', + 'snapshot.h', + 'snapshot_ids.h', + 'symbols.h', + # Source files. + 'dart.cc', + 'dart_api_impl.cc', + 'object.cc', + 'raw_object.cc', + 'raw_object_snapshot.cc', + 'snapshot.cc', + 'symbols.cc', +] + +def makeSnapshotHashString(): + vmhash = hashlib.md5() + for vmfilename in VM_SNAPSHOT_FILES: + vmfilepath = os.path.join(DART_DIR, 'runtime', 'vm', vmfilename) + with open(vmfilepath) as vmfile: + vmhash.update(vmfile.read()) + return vmhash.hexdigest() + +def main(): + parser = argparse.ArgumentParser(description='Tests Dart snapshotting') + parser.add_argument("--build-dir", + dest="build_dir", + metavar="", + type=str, + required=True, + help="The directory containing the Mojo build.") + args = parser.parse_args() + dart_snapshotter = os.path.join(args.build_dir, 'dart_snapshotter') + package_root = os.path.join(args.build_dir, 'gen', 'dart-pkg', 'packages') + main_dart = os.path.join( + args.build_dir, 'gen', 'dart-pkg', 'mojo_dart_hello', 'lib', 'main.dart') + snapshot = tempfile.mktemp() + + if not os.path.isfile(dart_snapshotter): + print "file not found: " + dart_snapshotter + return 1 + subprocess.check_call([ + dart_snapshotter, + main_dart, + '--package-root=%s' % package_root, + '--snapshot=%s' % snapshot, + ]) + if not os.path.isfile(snapshot): + return 1 + + expected_hash = makeSnapshotHashString() + actual_hash = "" + with open(snapshot) as snapshot_file: + snapshot_file.seek(20) + actual_hash = snapshot_file.read(32) + if not actual_hash == expected_hash: + print ('wrong hash: actual = %s, expected = %s' + % (actual_hash, expected_hash)) + return 1 + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/mojo/dart/dart_snapshotter/vm.cc b/mojo/dart/dart_snapshotter/vm.cc new file mode 100644 index 0000000000000..f95cf5a544c9a --- /dev/null +++ b/mojo/dart/dart_snapshotter/vm.cc @@ -0,0 +1,44 @@ +// Copyright 2015 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 "mojo/dart/dart_snapshotter/vm.h" + +#include "base/logging.h" +#include "tonic/dart_error.h" +#include "tonic/dart_state.h" + +namespace mojo { +namespace dart { +extern const uint8_t* vm_isolate_snapshot_buffer; +extern const uint8_t* isolate_snapshot_buffer; +} +} + +static const char* kDartArgs[] = { + "--enable_mirrors=false", +}; + +void InitDartVM() { + CHECK(Dart_SetVMFlags(arraysize(kDartArgs), kDartArgs)); + CHECK(Dart_Initialize(mojo::dart::vm_isolate_snapshot_buffer, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr)); +} + +Dart_Isolate CreateDartIsolate() { + CHECK(mojo::dart::isolate_snapshot_buffer); + char* error = nullptr; + auto isolate_data = new SnapshotterDartState(); + CHECK(isolate_data != nullptr); + Dart_Isolate isolate = Dart_CreateIsolate("dart:snapshot", + "main", + mojo::dart::isolate_snapshot_buffer, + nullptr, + isolate_data, + &error); + CHECK(isolate) << error; + Dart_ExitIsolate(); + isolate_data->SetIsolate(isolate); + return isolate; +} diff --git a/mojo/dart/dart_snapshotter/vm.h b/mojo/dart/dart_snapshotter/vm.h new file mode 100644 index 0000000000000..f6330dc01022a --- /dev/null +++ b/mojo/dart/dart_snapshotter/vm.h @@ -0,0 +1,45 @@ +// Copyright 2015 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. + +#ifndef MOJO_DART_DART_SNAPSHOTTER_VM_H_ +#define MOJO_DART_DART_SNAPSHOTTER_VM_H_ + +#include "dart/runtime/include/dart_api.h" +#include "tonic/dart_library_provider.h" +#include "tonic/dart_state.h" + +class SnapshotterDartState : public tonic::DartState { + public: + SnapshotterDartState() : library_provider_(nullptr) { + }; + + tonic::DartLibraryProvider* library_provider() const { + return library_provider_.get(); + } + + void set_library_provider(tonic::DartLibraryProvider* library_provider) { + library_provider_.reset(library_provider); + DCHECK(library_provider_.get() == library_provider); + } + + static SnapshotterDartState* From(Dart_Isolate isolate) { + return reinterpret_cast(DartState::From(isolate)); + } + + static SnapshotterDartState* Current() { + return reinterpret_cast(DartState::Current()); + } + + static SnapshotterDartState* Cast(void* data) { + return reinterpret_cast(data); + } + + private: + std::unique_ptr library_provider_; +}; + +void InitDartVM(); +Dart_Isolate CreateDartIsolate(); + +#endif // MOJO_DART_DART_SNAPSHOTTER_VM_H_ diff --git a/mojo/dart/embedder/BUILD.gn b/mojo/dart/embedder/BUILD.gn index ba1e8587fbffe..d21d1ae0bd093 100644 --- a/mojo/dart/embedder/BUILD.gn +++ b/mojo/dart/embedder/BUILD.gn @@ -43,7 +43,7 @@ source_set("dart_controller_no_snapshot") { "//dart/runtime:libdart", "//dart/runtime/bin:libdart_embedder_noio", "//third_party/dart-pkg", - "//mojo/common", + "//mojo/message_pump", "//mojo/public/c/system", "//mojo/public/cpp/system", "//mojo/services/network/public/interfaces", @@ -410,3 +410,13 @@ action("generate_snapshot_file") { rebase_path(output), ] } + +source_set("dart_snapshot_cc") { + sources = [ + "$root_gen_dir/dart_snapshot.cc", + ] + + deps = [ + ":generate_snapshot_file", + ] +} diff --git a/mojo/dart/embedder/dart_controller.cc b/mojo/dart/embedder/dart_controller.cc index ff64c9caf51e1..ad86db99421a2 100644 --- a/mojo/dart/embedder/dart_controller.cc +++ b/mojo/dart/embedder/dart_controller.cc @@ -13,11 +13,11 @@ #include "base/sys_info.h" #include "dart/runtime/include/dart_api.h" #include "dart/runtime/include/dart_native_api.h" -#include "mojo/common/message_pump_mojo.h" #include "mojo/dart/embedder/builtin.h" #include "mojo/dart/embedder/dart_controller.h" #include "mojo/dart/embedder/mojo_dart_state.h" #include "mojo/dart/embedder/vmservice.h" +#include "mojo/message_pump/message_pump_mojo.h" #include "mojo/public/c/system/core.h" #include "tonic/dart_converter.h" #include "tonic/dart_debugger.h" @@ -27,6 +27,7 @@ #include "tonic/dart_library_provider.h" #include "tonic/dart_library_provider_files.h" #include "tonic/dart_library_provider_network.h" +#include "tonic/dart_script_loader_sync.h" namespace mojo { namespace dart { @@ -39,6 +40,8 @@ static const char* kInternalLibURL = "dart:_internal"; static const char* kIsolateLibURL = "dart:isolate"; static const char* kCoreLibURL = "dart:core"; +static uint8_t snapshot_magic_number[] = { 0xf5, 0xf5, 0xdc, 0xdc }; + static Dart_Handle SetWorkingDirectory(Dart_Handle builtin_lib) { base::FilePath current_dir; PathService::Get(base::DIR_CURRENT, ¤t_dir); @@ -299,6 +302,8 @@ Dart_Isolate DartController::CreateIsolateHelper( } else { package_root_str = package_root.c_str(); } + isolate_data->library_loader().set_magic_number( + snapshot_magic_number, sizeof(snapshot_magic_number)); if (use_network_loader) { mojo::NetworkService* network_service = isolate_data->network_service(); isolate_data->set_library_provider( @@ -349,12 +354,21 @@ Dart_Isolate DartController::CreateIsolateHelper( // Special case for starting and stopping the the handle watcher isolate. LoadEmptyScript(script_uri); } else { - LoadScript(script_uri, isolate_data->library_provider()); + tonic::DartScriptLoaderSync::LoadScript( + script_uri, + isolate_data->library_provider()); } InitializeDartMojoIo(); } + if (isolate_data->library_loader().error_during_loading()) { + *error = strdup("Library loader reported error during loading. See log."); + Dart_EnterIsolate(isolate); + Dart_ShutdownIsolate(); + return nullptr; + } + // Make the isolate runnable so that it is ready to handle messages. bool retval = Dart_IsolateMakeRunnable(isolate); if (!retval) { @@ -606,32 +620,22 @@ void DartController::InitVmIfNeeded(Dart_EntropySource entropy, nullptr, nullptr, nullptr, nullptr, entropy); CHECK(result); - // By waiting for the load port, we ensure that the service isolate is fully - // running before returning. - Dart_ServiceWaitForLoadPort(); initialized_ = true; - service_isolate_running_ = true; } -void DartController::BlockWaitingForDependencies( - tonic::DartLibraryLoader* loader, - const std::unordered_set& dependencies) { - { - scoped_refptr task_runner = - base::MessageLoop::current()->task_runner(); - base::RunLoop run_loop; - task_runner->PostTask( - FROM_HERE, - base::Bind( - &tonic::DartLibraryLoader::WaitForDependencies, - base::Unretained(loader), - dependencies, - base::Bind( - base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask), - task_runner.get(), FROM_HERE, - run_loop.QuitClosure()))); - run_loop.Run(); +void DartController::BlockForServiceIsolate() { + base::AutoLock al(lock_); + BlockForServiceIsolateLocked(); +} + +void DartController::BlockForServiceIsolateLocked() { + if (service_isolate_running_) { + return; } + // By waiting for the load port, we ensure that the service isolate is fully + // running before returning. + Dart_ServiceWaitForLoadPort(); + service_isolate_running_ = true; } void DartController::LoadEmptyScript(const std::string& script_uri) { @@ -646,60 +650,11 @@ void DartController::LoadEmptyScript(const std::string& script_uri) { tonic::LogIfError(Dart_FinalizeLoading(true)); } -void DartController::InnerLoadScript( - const std::string& script_uri, - tonic::DartLibraryProvider* library_provider) { - // When spawning isolates, Dart expects the script loading to be completed - // before returning from the isolate creation callback. The mojo dart - // controller also expects the isolate to be finished loading a script - // before the isolate creation callback returns. - - // We block here by creating a nested message pump and waiting for the load - // to complete. - - DCHECK(base::MessageLoop::current() != nullptr); - base::MessageLoop::ScopedNestableTaskAllower allow( - base::MessageLoop::current()); - - // Initiate the load. - auto dart_state = tonic::DartState::Current(); - DCHECK(library_provider != nullptr); - tonic::DartLibraryLoader& loader = dart_state->library_loader(); - loader.set_library_provider(library_provider); - std::unordered_set dependencies; - { - tonic::DartDependencyCatcher dependency_catcher(loader); - loader.LoadScript(script_uri); - // Copy dependencies before dependency_catcher goes out of scope. - dependencies = std::unordered_set( - dependency_catcher.dependencies()); - } - - // Run inner message loop. - BlockWaitingForDependencies(&loader, dependencies); - - // Finalize loading. - tonic::LogIfError(Dart_FinalizeLoading(true)); -} - -void DartController::LoadScript(const std::string& script_uri, - tonic::DartLibraryProvider* library_provider) { - if (base::MessageLoop::current() == nullptr) { - // Threads running on the Dart thread pool may not have a message loop, - // we rely on a message loop during loading. Create a temporary one - // here. - base::MessageLoop message_loop(common::MessagePumpMojo::Create()); - InnerLoadScript(script_uri, library_provider); - } else { - // Thread has a message loop, use it. - InnerLoadScript(script_uri, library_provider); - } -} - bool DartController::RunSingleDartScript(const DartControllerConfig& config) { InitVmIfNeeded(config.entropy, config.vm_flags, config.vm_flags_count); + BlockForServiceIsolate(); Dart_Isolate isolate = CreateIsolateHelper(config.application_data, config.strict_compilation, config.callbacks, @@ -735,6 +690,7 @@ bool DartController::Initialize( } bool DartController::RunDartScript(const DartControllerConfig& config) { + BlockForServiceIsolate(); CHECK(service_isolate_running_); const bool strict = strict_compilation_ || config.strict_compilation; Dart_Isolate isolate = CreateIsolateHelper(config.application_data, @@ -762,6 +718,7 @@ void DartController::Shutdown() { if (!initialized_) { return; } + BlockForServiceIsolateLocked(); StopHandleWatcherIsolate(); Dart_Cleanup(); service_isolate_running_ = false; diff --git a/mojo/dart/embedder/dart_controller.h b/mojo/dart/embedder/dart_controller.h index b0b53a9bda822..46646805105c3 100644 --- a/mojo/dart/embedder/dart_controller.h +++ b/mojo/dart/embedder/dart_controller.h @@ -156,14 +156,10 @@ class DartController { const char** arguments, int arguments_count); - static void BlockWaitingForDependencies( - tonic::DartLibraryLoader* loader, - const std::unordered_set& dependencies); + static void BlockForServiceIsolate(); + static void BlockForServiceIsolateLocked(); + static void LoadEmptyScript(const std::string& script_uri); - static void InnerLoadScript(const std::string& script_uri, - tonic::DartLibraryProvider* library_provider); - static void LoadScript(const std::string& script_uri, - tonic::DartLibraryProvider* library_provider); static tonic::DartLibraryProvider* library_provider_; static base::Lock lock_; diff --git a/mojo/dart/embedder/io/mojo_patch.dart b/mojo/dart/embedder/io/mojo_patch.dart index c31c5fb23cf55..d49c6c4a68501 100644 --- a/mojo/dart/embedder/io/mojo_patch.dart +++ b/mojo/dart/embedder/io/mojo_patch.dart @@ -91,9 +91,14 @@ class _NetworkServiceCodec { r += '${digit}${divider}'; } } else { - for (var i = 0; i < 16; i++) { - var digit = address[i].toRadixString(16); - var divider = (i != 15) ? ':' : ''; + for (var i = 0; i < 16; i += 2) { + var first = ''; + if (address[i] != 0) { + first = address[i].toRadixString(16).padLeft(2, '0'); + } + var second = address[i + 1].toRadixString(16).padLeft(2, '0'); + var digit = '$first$second'; + var divider = (i != 14) ? ':' : ''; r += '${digit}${divider}'; } } diff --git a/mojo/dart/embedder/mojo_dart_state.h b/mojo/dart/embedder/mojo_dart_state.h index 6ebd27c869cbf..a0792eec75b11 100644 --- a/mojo/dart/embedder/mojo_dart_state.h +++ b/mojo/dart/embedder/mojo_dart_state.h @@ -111,4 +111,4 @@ class MojoDartState : public tonic::DartState { } // namespace dart } // namespace mojo -#endif // MOJO_DART_EMBEDDER_DART_STATE_H_ \ No newline at end of file +#endif // MOJO_DART_EMBEDDER_DART_STATE_H_ diff --git a/mojo/dart/embedder/test/BUILD.gn b/mojo/dart/embedder/test/BUILD.gn index 87395a3e30935..2b2d429f545c8 100644 --- a/mojo/dart/embedder/test/BUILD.gn +++ b/mojo/dart/embedder/test/BUILD.gn @@ -22,7 +22,7 @@ test("dart_unittests") { "validation_unittest.cc", ] deps = [ - "//mojo/public/dart:mojo", + "//mojo/public/dart", "//mojo/dart/testing", ":dart_controller_for_test", ":dart_to_cpp_unittests", diff --git a/mojo/dart/http_load_test/BUILD.gn b/mojo/dart/http_load_test/BUILD.gn new file mode 100644 index 0000000000000..67b1688b1cb98 --- /dev/null +++ b/mojo/dart/http_load_test/BUILD.gn @@ -0,0 +1,20 @@ +# Copyright 2015 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. + +import("//mojo/public/dart/rules.gni") + +dart_pkg("http_load_test") { + apps = [ [ + "dart_http_load_test", + "lib/main.dart", + ] ] + sources = [ + "lib/src/part0.dart", + "pubspec.yaml", + ] + deps = [ + "//mojo/public/dart", + "//mojo/dart/mojo_services", + ] +} diff --git a/mojo/dart/http_load_test/tester.dart b/mojo/dart/http_load_test/bin/tester.dart similarity index 79% rename from mojo/dart/http_load_test/tester.dart rename to mojo/dart/http_load_test/bin/tester.dart index 70eb61bc1fb28..e26927215fc48 100644 --- a/mojo/dart/http_load_test/tester.dart +++ b/mojo/dart/http_load_test/bin/tester.dart @@ -17,19 +17,20 @@ class Launcher { // Completer completes once the child process exits. var completer = new Completer(); - String stdout = ''; + String output = ''; process.stdout.transform(UTF8.decoder) .transform(new LineSplitter()).listen((line) { - stdout = '$stdout\n$line'; + output = '$output\n$line'; print(line); }); process.stderr.transform(UTF8.decoder) .transform(new LineSplitter()).listen((line) { + output = '$output\n$line'; print(line); }); process.exitCode.then((ec) { - stdout = '$stdout\nEXIT_CODE=$ec\n'; - completer.complete(stdout); + output = '$output\nEXIT_CODE=$ec\n'; + completer.complete(output); }); return completer.future; } @@ -56,15 +57,18 @@ main(List args) async { } }); - var launchUrl = 'http://127.0.0.1:${server.port}/main.dart'; - var stdout = await Launcher.launch(mojo_shell_executable, [launchUrl]); + var launchUrl = 'http://127.0.0.1:${server.port}/lib/main.dart'; + var output = await Launcher.launch(mojo_shell_executable, [launchUrl]); server.close(); - if (!stdout.contains("\nPASS")) { + if (output.contains("ERROR")) { + throw "test failed."; + } + if (!output.contains("\nEXIT_CODE=0\n")) { throw "Test failed."; } - if (!stdout.contains("\nEXIT_CODE=0\n")) { + if (!output.contains("\nPASS")) { throw "Test failed."; } } diff --git a/mojo/dart/http_load_test/main.dart b/mojo/dart/http_load_test/lib/main.dart similarity index 75% rename from mojo/dart/http_load_test/main.dart rename to mojo/dart/http_load_test/lib/main.dart index 6e35e6931c41f..7e779d7927aac 100644 --- a/mojo/dart/http_load_test/main.dart +++ b/mojo/dart/http_load_test/lib/main.dart @@ -5,7 +5,9 @@ library test; import 'dart:async'; import 'dart:mojo.internal'; -part 'part0.dart'; +import 'package:mojo_services/tracing/tracing.mojom.dart' as tracing; + +part 'src/part0.dart'; main(List args) { // Hang around for a sec and then close the shell handle. diff --git a/mojo/dart/http_load_test/part0.dart b/mojo/dart/http_load_test/lib/src/part0.dart similarity index 100% rename from mojo/dart/http_load_test/part0.dart rename to mojo/dart/http_load_test/lib/src/part0.dart diff --git a/mojo/dart/http_load_test/pubspec.lock b/mojo/dart/http_load_test/pubspec.lock new file mode 100644 index 0000000000000..e7b03b5083bcc --- /dev/null +++ b/mojo/dart/http_load_test/pubspec.lock @@ -0,0 +1,3 @@ +# Generated by pub +# See http://pub.dartlang.org/doc/glossary.html#lockfile +packages: {} diff --git a/mojo/dart/http_load_test/pubspec.yaml b/mojo/dart/http_load_test/pubspec.yaml new file mode 100644 index 0000000000000..335f54aed59c5 --- /dev/null +++ b/mojo/dart/http_load_test/pubspec.yaml @@ -0,0 +1 @@ +name: mojo_dart_http_load_test diff --git a/mojo/dart/http_load_test/runner.py b/mojo/dart/http_load_test/runner.py index 3f72f39994e3d..b3c4785b849d4 100755 --- a/mojo/dart/http_load_test/runner.py +++ b/mojo/dart/http_load_test/runner.py @@ -40,6 +40,8 @@ def main(build_dir, dart_exe, tester_script, tester_dir): help="Path to dart executable.") args = parser.parse_args() tester_directory = os.path.dirname(os.path.realpath(__file__)) - tester_dart_script = os.path.join(tester_directory, 'tester.dart') + tester_dart_script = os.path.join(tester_directory, 'bin', 'tester.dart') + package_directory = os.path.join( + args.build_dir, 'gen', 'dart-pkg', 'mojo_dart_http_load_test') sys.exit(main(args.build_dir, args.dart_exe, tester_dart_script, - tester_directory)) + package_directory)) diff --git a/mojo/dart/mojo_services/BUILD.gn b/mojo/dart/mojo_services/BUILD.gn index abf24374dbc1c..bda57f897cafb 100644 --- a/mojo/dart/mojo_services/BUILD.gn +++ b/mojo/dart/mojo_services/BUILD.gn @@ -3,6 +3,7 @@ # found in the LICENSE file. import("//mojo/public/dart/rules.gni") +import("//mojo/services/mojo_services.gni") dart_pkg("mojo_services") { sources = [ diff --git a/mojo/dart/mojo_services/CHANGELOG.md b/mojo/dart/mojo_services/CHANGELOG.md index ef62915abce89..899759cb9a395 100644 --- a/mojo/dart/mojo_services/CHANGELOG.md +++ b/mojo/dart/mojo_services/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.22 + + - 58 changes: https://github.com/domokit/mojo/compare/e172885...35de44e + ## 0.0.16 - 89 changes: https://github.com/domokit/mojo/compare/0fd4d06...c3119f6 diff --git a/mojo/dart/mojo_services/pubspec.yaml b/mojo/dart/mojo_services/pubspec.yaml index 271ae40c396aa..00156366433f0 100644 --- a/mojo/dart/mojo_services/pubspec.yaml +++ b/mojo/dart/mojo_services/pubspec.yaml @@ -4,4 +4,4 @@ dependencies: description: Generated bindings for mojo services homepage: https://github.com/domokit/mojo name: mojo_services -version: 0.0.21 +version: 0.0.22 diff --git a/mojo/dart/mojom/BUILD.gn b/mojo/dart/mojom/BUILD.gn index c29b19a5a277f..70ff7da59f4f1 100644 --- a/mojo/dart/mojom/BUILD.gn +++ b/mojo/dart/mojom/BUILD.gn @@ -5,7 +5,7 @@ import("//mojo/public/dart/rules.gni") dart_pkg("mojom") { - entrypoints = [ "lib/generate.dart" ] + libs = [ "lib/generate.dart" ] sources = [ "CHANGELOG.md", "README.md", diff --git a/mojo/dart/mojom/CHANGELOG.md b/mojo/dart/mojom/CHANGELOG.md index fe7b30fbfd3ed..3188f5b3e457b 100644 --- a/mojo/dart/mojom/CHANGELOG.md +++ b/mojo/dart/mojom/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.22 + + - 59 changes: https://github.com/domokit/mojo/compare/c73419d...35de44e + ## 0.0.18 - 89 changes: https://github.com/domokit/mojo/compare/0fd4d06...c3119f6 diff --git a/mojo/dart/mojom/pubspec.yaml b/mojo/dart/mojom/pubspec.yaml index 6e53e1f7f0fcb..bf53665dda9b7 100644 --- a/mojo/dart/mojom/pubspec.yaml +++ b/mojo/dart/mojom/pubspec.yaml @@ -9,4 +9,4 @@ environment: sdk: '>=1.9.0 <2.0.0' homepage: https://github.com/domokit/mojo name: mojom -version: 0.0.21 +version: 0.0.22 diff --git a/mojo/dart/observatory_test/BUILD.gn b/mojo/dart/observatory_test/BUILD.gn index 4401b351d676d..b845c9fbfcb1a 100644 --- a/mojo/dart/observatory_test/BUILD.gn +++ b/mojo/dart/observatory_test/BUILD.gn @@ -4,9 +4,13 @@ import("//mojo/public/dart/rules.gni") -dartzip_packaged_application("observatory_test") { +dart_pkg("observatory_test") { + apps = [ [ + "dart_observatory_test", + "lib/main.dart", + ] ] sources = [ - "main.dart", + "pubspec.yaml", ] deps = [ "//mojo/public/dart", diff --git a/mojo/dart/observatory_test/main.dart b/mojo/dart/observatory_test/lib/main.dart similarity index 100% rename from mojo/dart/observatory_test/main.dart rename to mojo/dart/observatory_test/lib/main.dart diff --git a/mojo/dart/observatory_tester/runner.py b/mojo/dart/observatory_tester/runner.py index d78ec7d1a0a3b..4cd1b4b5d02b2 100755 --- a/mojo/dart/observatory_tester/runner.py +++ b/mojo/dart/observatory_tester/runner.py @@ -11,7 +11,7 @@ import sys MOJO_SHELL = 'mojo_shell' -TESTEE = 'mojo:observatory_test' +TESTEE = 'mojo:dart_observatory_test' def main(build_dir, dart_exe, tester_script): shell_exe = os.path.join(build_dir, MOJO_SHELL) diff --git a/mojo/dart/testing/BUILD.gn b/mojo/dart/testing/BUILD.gn index 5bf79a56904d1..e4cbe059600a1 100644 --- a/mojo/dart/testing/BUILD.gn +++ b/mojo/dart/testing/BUILD.gn @@ -5,7 +5,7 @@ import("//mojo/public/dart/rules.gni") dart_pkg("testing") { - entrypoints = [ + libs = [ "lib/async_helper.dart", "lib/expect.dart", "lib/validation_test_input_parser.dart", diff --git a/mojo/data_pipe_utils/BUILD.gn b/mojo/data_pipe_utils/BUILD.gn new file mode 100644 index 0000000000000..d9b5dea9d1d16 --- /dev/null +++ b/mojo/data_pipe_utils/BUILD.gn @@ -0,0 +1,39 @@ +# Copyright 2015 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. + +source_set("data_pipe_utils") { + sources = [ + "data_pipe_drainer.cc", + "data_pipe_drainer.h", + "data_pipe_file_utils.cc", + "data_pipe_utils.cc", + "data_pipe_utils.h", + "data_pipe_utils_internal.h", + ] + + if (is_nacl) { + sources -= [ "data_pipe_file_utils.cc" ] + } + + deps = [ + "//base", + "//mojo/message_pump", + "//mojo/public/cpp/environment:environment", + "//mojo/public/cpp/system", + ] +} + +source_set("tests") { + testonly = true + + sources = [ + "data_pipe_utils_unittest.cc", + ] + + deps = [ + ":data_pipe_utils", + "//base", + "//testing/gtest", + ] +} diff --git a/mojo/common/data_pipe_drainer.cc b/mojo/data_pipe_utils/data_pipe_drainer.cc similarity index 73% rename from mojo/common/data_pipe_drainer.cc rename to mojo/data_pipe_utils/data_pipe_drainer.cc index 547710945d954..8ed8b2d6cc4e0 100644 --- a/mojo/common/data_pipe_drainer.cc +++ b/mojo/data_pipe_utils/data_pipe_drainer.cc @@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/common/data_pipe_drainer.h" +#include "mojo/data_pipe_utils/data_pipe_drainer.h" + #include "base/bind.h" namespace mojo { @@ -10,21 +11,18 @@ namespace common { DataPipeDrainer::DataPipeDrainer(Client* client, mojo::ScopedDataPipeConsumerHandle source) - : client_(client), - source_(source.Pass()), - weak_factory_(this) { + : client_(client), source_(source.Pass()), weak_factory_(this) { DCHECK(client_); ReadData(); } -DataPipeDrainer::~DataPipeDrainer() { -} +DataPipeDrainer::~DataPipeDrainer() {} void DataPipeDrainer::ReadData() { const void* buffer = nullptr; uint32_t num_bytes = 0; - MojoResult rv = BeginReadDataRaw(source_.get(), - &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE); + MojoResult rv = BeginReadDataRaw(source_.get(), &buffer, &num_bytes, + MOJO_READ_DATA_FLAG_NONE); if (rv == MOJO_RESULT_OK) { client_->OnDataAvailable(buffer, num_bytes); EndReadDataRaw(source_.get(), num_bytes); @@ -39,8 +37,8 @@ void DataPipeDrainer::ReadData() { } void DataPipeDrainer::WaitForData() { - handle_watcher_.Start(source_.get(), - MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, + handle_watcher_.Start( + source_.get(), MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, base::Bind(&DataPipeDrainer::WaitComplete, weak_factory_.GetWeakPtr())); } diff --git a/mojo/common/data_pipe_drainer.h b/mojo/data_pipe_utils/data_pipe_drainer.h similarity index 80% rename from mojo/common/data_pipe_drainer.h rename to mojo/data_pipe_utils/data_pipe_drainer.h index c9669be7a8564..80cb933a8e15d 100644 --- a/mojo/common/data_pipe_drainer.h +++ b/mojo/data_pipe_utils/data_pipe_drainer.h @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MOJO_COMMON_DATA_PIPE_DRAINER_H_ -#define MOJO_COMMON_DATA_PIPE_DRAINER_H_ +#ifndef MOJO_DATA_PIPE_UTILS_DATA_PIPE_DRAINER_H_ +#define MOJO_DATA_PIPE_UTILS_DATA_PIPE_DRAINER_H_ #include "base/memory/weak_ptr.h" -#include "mojo/common/handle_watcher.h" +#include "mojo/message_pump/handle_watcher.h" #include "mojo/public/cpp/system/core.h" namespace mojo { @@ -20,7 +20,7 @@ class DataPipeDrainer { virtual void OnDataComplete() = 0; protected: - virtual ~Client() { } + virtual ~Client() {} }; DataPipeDrainer(Client*, mojo::ScopedDataPipeConsumerHandle source); @@ -43,4 +43,4 @@ class DataPipeDrainer { } // namespace common } // namespace mojo -#endif // MOJO_COMMON_DATA_PIPE_DRAINER_H_ +#endif // MOJO_DATA_PIPE_UTILS_DATA_PIPE_DRAINER_H_ diff --git a/mojo/common/data_pipe_file_utils.cc b/mojo/data_pipe_utils/data_pipe_file_utils.cc similarity index 99% rename from mojo/common/data_pipe_file_utils.cc rename to mojo/data_pipe_utils/data_pipe_file_utils.cc index aa14225b3e1f3..e37c8dfe9aeee 100644 --- a/mojo/common/data_pipe_file_utils.cc +++ b/mojo/data_pipe_utils/data_pipe_file_utils.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/common/data_pipe_utils.h" +#include "mojo/data_pipe_utils/data_pipe_utils.h" #include @@ -14,7 +14,7 @@ #include "base/files/scoped_file.h" #include "base/location.h" #include "base/trace_event/trace_event.h" -#include "mojo/common/data_pipe_utils_internal.h" +#include "mojo/data_pipe_utils/data_pipe_utils_internal.h" #include "mojo/public/cpp/environment/async_waiter.h" namespace mojo { diff --git a/mojo/common/data_pipe_utils.cc b/mojo/data_pipe_utils/data_pipe_utils.cc similarity index 83% rename from mojo/common/data_pipe_utils.cc rename to mojo/data_pipe_utils/data_pipe_utils.cc index daaef2cf4bddd..af9f2062bd7c0 100644 --- a/mojo/common/data_pipe_utils.cc +++ b/mojo/data_pipe_utils/data_pipe_utils.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/common/data_pipe_utils.h" +#include "mojo/data_pipe_utils/data_pipe_utils.h" #include @@ -10,18 +10,19 @@ #include "base/task_runner_util.h" #include "base/threading/platform_thread.h" #include "base/trace_event/trace_event.h" -#include "mojo/common/data_pipe_utils_internal.h" +#include "mojo/data_pipe_utils/data_pipe_utils_internal.h" namespace mojo { namespace common { -bool BlockingCopyHelper(ScopedDataPipeConsumerHandle source, +bool BlockingCopyHelper( + ScopedDataPipeConsumerHandle source, const base::Callback& write_bytes) { for (;;) { const void* buffer = nullptr; uint32_t num_bytes = 0; - MojoResult result = BeginReadDataRaw( - source.get(), &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE); + MojoResult result = BeginReadDataRaw(source.get(), &buffer, &num_bytes, + MOJO_READ_DATA_FLAG_NONE); if (result == MOJO_RESULT_OK) { size_t bytes_written = write_bytes.Run(buffer, num_bytes); if (bytes_written < num_bytes) { @@ -39,10 +40,8 @@ bool BlockingCopyHelper(ScopedDataPipeConsumerHandle source, return false; } } else if (result == MOJO_RESULT_SHOULD_WAIT) { - result = Wait(source.get(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE, - nullptr); + result = Wait(source.get(), MOJO_HANDLE_SIGNAL_READABLE, + MOJO_DEADLINE_INDEFINITE, nullptr); if (result != MOJO_RESULT_OK) { // If the producer handle was closed, then treat as EOF. return result == MOJO_RESULT_FAILED_PRECONDITION; @@ -60,13 +59,14 @@ bool BlockingCopyHelper(ScopedDataPipeConsumerHandle source, namespace { -size_t CopyToStringHelper( - std::string* result, const void* buffer, uint32_t num_bytes) { +size_t CopyToStringHelper(std::string* result, + const void* buffer, + uint32_t num_bytes) { result->append(static_cast(buffer), num_bytes); return num_bytes; } -} // namespace +} // namespace // TODO(hansmuller): Add a max_size parameter. bool BlockingCopyToString(ScopedDataPipeConsumerHandle source, @@ -74,8 +74,8 @@ bool BlockingCopyToString(ScopedDataPipeConsumerHandle source, TRACE_EVENT0("data_pipe_utils", "BlockingCopyToString"); CHECK(result); result->clear(); - return BlockingCopyHelper( - source.Pass(), base::Bind(&CopyToStringHelper, result)); + return BlockingCopyHelper(source.Pass(), + base::Bind(&CopyToStringHelper, result)); } bool BlockingCopyFromString(const std::string& source, diff --git a/mojo/common/data_pipe_utils.h b/mojo/data_pipe_utils/data_pipe_utils.h similarity index 92% rename from mojo/common/data_pipe_utils.h rename to mojo/data_pipe_utils/data_pipe_utils.h index 08e6fa0d85be4..289fe12a8eda1 100644 --- a/mojo/common/data_pipe_utils.h +++ b/mojo/data_pipe_utils/data_pipe_utils.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MOJO_SHELL_DATA_PIPE_UTILS_H_ -#define MOJO_SHELL_DATA_PIPE_UTILS_H_ +#ifndef MOJO_DATA_PIPE_UTILS_DATA_PIPE_UTILS_H_ +#define MOJO_DATA_PIPE_UTILS_DATA_PIPE_UTILS_H_ #include @@ -51,4 +51,4 @@ bool BlockingCopyToFile(ScopedDataPipeConsumerHandle source, } // namespace common } // namespace mojo -#endif // MOJO_SHELL_DATA_PIPE_UTILS_H_ +#endif // MOJO_DATA_PIPE_UTILS_DATA_PIPE_UTILS_H_ diff --git a/mojo/common/data_pipe_utils_internal.h b/mojo/data_pipe_utils/data_pipe_utils_internal.h similarity index 75% rename from mojo/common/data_pipe_utils_internal.h rename to mojo/data_pipe_utils/data_pipe_utils_internal.h index 26164ec0bf92f..40086fb129bae 100644 --- a/mojo/common/data_pipe_utils_internal.h +++ b/mojo/data_pipe_utils/data_pipe_utils_internal.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MOJO_COMMON_DATA_PIPE_UTILS_INTERNAL_H_ -#define MOJO_COMMON_DATA_PIPE_UTILS_INTERNAL_H_ +#ifndef MOJO_DATA_PIPE_UTILS_DATA_PIPE_UTILS_INTERNAL_H_ +#define MOJO_DATA_PIPE_UTILS_DATA_PIPE_UTILS_INTERNAL_H_ #include "base/callback_forward.h" #include "mojo/public/cpp/system/core.h" @@ -19,4 +19,4 @@ bool BlockingCopyHelper( } // namespace common } // namespace mojo -#endif // MOJO_COMMON_DATA_PIPE_UTILS_INTERNAL_H_ +#endif // MOJO_DATA_PIPE_UTILS_DATA_PIPE_UTILS_INTERNAL_H_ diff --git a/mojo/common/data_pipe_utils_unittest.cc b/mojo/data_pipe_utils/data_pipe_utils_unittest.cc similarity index 97% rename from mojo/common/data_pipe_utils_unittest.cc rename to mojo/data_pipe_utils/data_pipe_utils_unittest.cc index edfc2c45f47d7..6c0f6006139b7 100644 --- a/mojo/common/data_pipe_utils_unittest.cc +++ b/mojo/data_pipe_utils/data_pipe_utils_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/common/data_pipe_utils.h" +#include "mojo/data_pipe_utils/data_pipe_utils.h" #include "base/bind.h" #include "base/files/file_util.h" diff --git a/mojo/devtools/README.md b/mojo/devtools/README.md deleted file mode 100644 index ff70d863f568d..0000000000000 --- a/mojo/devtools/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Devtools packages - -The `common` subdirectory contains what we currently expose as "devtools", -mirroring it as a [separate repository](https://github.com/domokit/devtools) for -consumption without a Mojo checkout. - -Further subdirectories TBD might be added in the future, to contain heavy -language-specific tooling which we will mirror / expose separately. - -The toolsets are intended for consumption by Mojo consumers as **separate -checkouts**. No dependencies on files outside of devtools are allowed. diff --git a/mojo/devtools/common/README.md b/mojo/devtools/common/README.md deleted file mode 100644 index eb7d5c683a1ee..0000000000000 --- a/mojo/devtools/common/README.md +++ /dev/null @@ -1,136 +0,0 @@ -# Devtools - -Unopinionated tools for **running**, **debugging** and **testing** Mojo apps. - -## Install - -``` -git clone https://github.com/domokit/devtools.git -``` - -## Contents - -Devtools offers the following tools: - - - `mojo_run` - shell runner - - `mojo_test` - apptest runner - - `mojo_debug` - debugger supporting interactive tracing and debugging of a - running mojo shell - -Additionally, `remote_adb_setup` script helps to configure adb on a remote -machine to communicate with a device attached to a local machine, forwarding the -ports used by `mojo_run`. - -### Runner - -`mojo_run` allows you to run a Mojo shell either on the host, or on an attached -Android device. - -```sh -mojo_run APP_URL # Run on the host. -mojo_run APP_URL --android # Run on Android device. -mojo_run "APP_URL APP_ARGUMENTS" # Run an app with startup arguments -``` - -Unless running within a Mojo checkout, we need to indicate the path to the shell -binary: - -```sh -mojo_run --shell-path path/to/shell/binary APP_URL -``` - -Some applications are running embedded inside a window manager. To start such an -app, you have to first start the window manager app, then have it embed the app -you are interested in. It is done as follows using the default window manager: - -```sh -mojo_run "mojo:window_manager APP_URL" -``` - -By default, `mojo_run` uses `mojo:kiosk_wm` as the default window manager. It -can be changed using the `--window-manager` flag. - -#### Sky apps - -To run a [Sky](https://github.com/domokit/sky_engine) app, you need to build -`sky_viewer.mojo` in a Sky checkout, and indicate the path to the binary using -the `--map-url` parameter: - -```sh -mojo_run --map-url mojo:sky_viewer=/path/to/sky/viewer "mojo:window_manager APP_URL" -``` - -If the app does not declare a shebang indicating that it needs to be run in -`sky_viewer`, pass `--sky` to map `sky_viewer` as a default content handler for -dart apps: - -```sh -mojo_run --map-url mojo:sky_viewer=/path/to/sky/viewer "mojo:window_manager APP_URL" --sky -``` - -Note that Sky apps will need the --use-osmesa flag to run -over [chromoting](https://support.google.com/chrome/answer/1649523?hl=en): - -### Debugger - -`mojo_debug` allows you to interactively inspect a running shell, collect -performance traces and attach a gdb debugger. - -#### Tracing -To collect [performance -traces](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool) -and retrieve the result: - -```sh -mojo_debug tracing start -mojo_debug tracing stop [result.json] -``` - -The trace file can be then loaded using the trace viewer in Chrome available at -`about://tracing`. - -#### GDB -It is possible to inspect a Mojo Shell process using GDB. The `mojo_debug` -script can be used to launch GDB and attach it to a running shell process -(android only): - -```sh -mojo_debug gdb attach -``` - -Once started, GDB will first stop the Mojo Shell execution, then load symbols -from loaded Mojo applications. Please note that this initial step can take some -time (up to several minutes in the worst case). - -After each execution pause, GDB will update the set of loaded symbols based on -the selected thread only. If you need symbols for all threads, use the -`update-symbols` GDB command: -```sh -(gdb) update-symbols -``` - -If you only want to update symbols for the current selected thread (for example, -after changing threads), use the `current` option: -```sh -(gdb) update-symbols current -``` - -If you want to debug the startup of your application, you can pass -`--wait-for-debugger` to `mojo_run` to have the Mojo Shell stop and wait to be -attached by `gdb` before continuing. - -#### Android crash stacks -When Mojo shell crashes on Android ("Unfortunately, Mojo shell has stopped.") -due to a crash in native code, `mojo_debug` can be used to find and symbolize -the stack trace present in the device log: - -```sh -mojo_debug device stack -``` - -## Development - -The library is canonically developed [in the mojo -repository](https://github.com/domokit/mojo/tree/master/mojo/devtools/common), -https://github.com/domokit/devtools is a mirror allowing to consume it -separately. diff --git a/mojo/devtools/common/android_gdb/__init__.py b/mojo/devtools/common/android_gdb/__init__.py deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/mojo/devtools/common/android_gdb/config.py b/mojo/devtools/common/android_gdb/config.py deleted file mode 100644 index 4ddaeaed7da35..0000000000000 --- a/mojo/devtools/common/android_gdb/config.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright 2015 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. - -# Path where remote_file_reader should be installed on the device. -REMOTE_FILE_READER_DEVICE_PATH = '/data/local/tmp/remote_file_reader' - -# Path where remote_file_reader is available on Cloud Storage. -REMOTE_FILE_READER_CLOUD_PATH = 'gs://mojo/devtools/remote_file_reader' diff --git a/mojo/devtools/common/android_gdb/install_remote_file_reader.py b/mojo/devtools/common/android_gdb/install_remote_file_reader.py deleted file mode 100644 index 07ba7f77392b9..0000000000000 --- a/mojo/devtools/common/android_gdb/install_remote_file_reader.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2015 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. - -import android_gdb.config as config -import subprocess -import tempfile - - -def install(gsutil, adb='adb'): - verification_call_output = subprocess.check_output( - [adb, 'shell', 'ls', config.REMOTE_FILE_READER_DEVICE_PATH]) - if config.REMOTE_FILE_READER_DEVICE_PATH != verification_call_output.strip(): - with tempfile.NamedTemporaryFile() as temp_file: - subprocess.check_call([gsutil, 'cp', config.REMOTE_FILE_READER_CLOUD_PATH, - temp_file.name]) - subprocess.check_call([adb, 'push', temp_file.name, - config.REMOTE_FILE_READER_DEVICE_PATH]) - subprocess.check_call([adb, 'shell', 'chmod', '777', - config.REMOTE_FILE_READER_DEVICE_PATH]) diff --git a/mojo/devtools/common/android_gdb/remote_file_connection.py b/mojo/devtools/common/android_gdb/remote_file_connection.py deleted file mode 100644 index 9759cdb6ded75..0000000000000 --- a/mojo/devtools/common/android_gdb/remote_file_connection.py +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2015 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. - -import socket -import struct - - -class RemoteFileConnectionException(Exception): - def __init__(self, *args, **kwargs): - Exception.__init__(self, *args, **kwargs) - - -class RemoteFileConnection(object): - """Client for remote_file_reader server, allowing to read files on an - remote device. - """ - def __init__(self, host, port): - self._host = host - self._port = port - self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self._size_struct = struct.Struct("!i") - - def __del__(self): - self.disconnect() - - def connect(self): - self._socket.connect((self._host, self._port)) - - def disconnect(self): - self._socket.close() - - def open(self, filename): - self._send("O %s\n" % filename) - result = self._receive(1) - if result != 'O': - raise RemoteFileConnectionException("Unable to open file " + filename) - - def seek(self, pos, mode=0): - self._send("S %d %d\n" % (pos, mode)) - result = self._receive(1) - if result != 'O': - raise RemoteFileConnectionException("Unable to seek in file.") - - def read(self, size=0): - assert size > 0 - self._send("R %d\n" % size) - result = self._receive(1) - if result != 'O': - raise RemoteFileConnectionException("Unable to read file.") - read_size = self._size_struct.unpack(self._receive(4))[0] - return self._receive(read_size) - - def _send(self, data): - while len(data) > 0: - sent = self._socket.send(data) - if sent == 0: - raise RemoteFileConnectionException("Socket connection broken.") - data = data[sent:] - - def _receive(self, length): - result = [] - while length > 0: - chunk = self._socket.recv(length) - if chunk == '': - raise RemoteFileConnectionException("Socket connection broken.") - result.append(chunk) - length -= len(chunk) - return ''.join(result) diff --git a/mojo/devtools/common/android_gdb/session.py b/mojo/devtools/common/android_gdb/session.py deleted file mode 100644 index e425c40e6be4e..0000000000000 --- a/mojo/devtools/common/android_gdb/session.py +++ /dev/null @@ -1,317 +0,0 @@ -# Copyright 2015 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. - -""" -Manages a debugging session with GDB. - -This module is meant to be imported from inside GDB. Once loaded, the -|DebugSession| attaches GDB to a running Mojo Shell process on an Android -device using a remote gdbserver. - -At startup and each time the execution stops, |DebugSession| associates -debugging symbols for every frame. For more information, see |DebugSession| -documentation. -""" - -import gdb -import glob -import itertools -import logging -import os -import os.path -import shutil -import subprocess -import sys -import tempfile -import traceback -import urllib2 - -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -import android_gdb.config as config -from android_gdb.remote_file_connection import RemoteFileConnection -from android_gdb.signatures import get_signature - - -logging.getLogger().setLevel(logging.INFO) - - -def _gdb_execute(command): - """Executes a GDB command.""" - return gdb.execute(command, to_string=True) - - -class Mapping(object): - """Represents a mapped memory region.""" - def __init__(self, line): - self.start = int(line[0], 16) - self.end = int(line[1], 16) - self.size = int(line[2], 16) - self.offset = int(line[3], 16) - self.filename = line[4] - - -def _get_mapped_files(): - """Retrieves all the files mapped into the debugged process memory. - - Returns: - List of mapped memory regions grouped by files. - """ - # info proc map returns a space-separated table with the following fields: - # start address, end address, size, offset, file path. - mappings = [Mapping(x) for x in - [x.split() for x in - _gdb_execute("info proc map").split('\n')] - if len(x) == 5 and x[4][0] == '/'] - res = {} - for m in mappings: - libname = m.filename[m.filename.rfind('/') + 1:] - res[libname] = res.get(libname, []) + [m] - return res.values() - - -class DebugSession(object): - def __init__(self, build_directory, package_name, pyelftools_dir, adb): - self._build_directory = build_directory - if not os.path.exists(self._build_directory): - logging.fatal("Please pass a valid build directory") - sys.exit(1) - self._package_name = package_name - self._adb = adb - self._remote_file_cache = os.path.join(os.getenv('HOME'), '.mojosymbols') - - if pyelftools_dir != None: - sys.path.append(pyelftools_dir) - try: - import elftools.elf.elffile as elffile - except ImportError: - logging.fatal("Unable to find elftools module; please install pyelftools " - "and specify its path on the command line using " - "--pyelftools-dir.") - sys.exit(1) - - self._elffile_module = elffile - - self._libraries = self._find_libraries(build_directory) - self._rfc = RemoteFileConnection('localhost', 10000) - self._remote_file_reader_process = None - if not os.path.exists(self._remote_file_cache): - os.makedirs(self._remote_file_cache) - self._done_mapping = set() - self._downloaded_files = [] - - def __del__(self): - # Note that, per python interpreter documentation, __del__ is not - # guaranteed to be called when the interpreter (GDB, in our case) quits. - # Also, most (all?) globals are no longer available at this time (launching - # a subprocess does not work). - self.stop() - - def stop(self, _unused_return_value=None): - if self._remote_file_reader_process != None: - self._remote_file_reader_process.kill() - - def _find_libraries(self, lib_dir): - """Finds all libraries in |lib_dir| and key them by their signatures. - """ - res = {} - for fn in glob.glob('%s/*.so' % lib_dir): - with open(fn, 'r') as f: - s = get_signature(f, self._elffile_module) - if s is not None: - res[s] = fn - return res - - def _associate_symbols(self, mapping, local_file): - with open(local_file, "r") as f: - elf = self._elffile_module.ELFFile(f) - s = elf.get_section_by_name(".text") - text_address = mapping[0].start + s['sh_offset'] - _gdb_execute("add-symbol-file %s 0x%x" % (local_file, text_address)) - - def _download_file(self, signature, remote): - """Downloads a remote file either from the cloud or through GDB connection. - - Returns: - The filename of the downloaded file - """ - temp_file = tempfile.NamedTemporaryFile() - logging.info("Trying to download symbols from the cloud.") - symbols_url = "http://storage.googleapis.com/mojo/symbols/%s" % signature - try: - symbol_file = urllib2.urlopen(symbols_url) - try: - with open(temp_file.name, "w") as dst: - shutil.copyfileobj(symbol_file, dst) - logging.info("Getting symbols for %s at %s." % (remote, symbols_url)) - # This allows the deletion of temporary files on disk when the - # debugging session terminates. - self._downloaded_files.append(temp_file) - return temp_file.name - finally: - symbol_file.close() - except urllib2.HTTPError: - pass - logging.info("Downloading file %s" % remote) - _gdb_execute("remote get %s %s" % (remote, temp_file.name)) - # This allows the deletion of temporary files on disk when the debugging - # session terminates. - self._downloaded_files.append(temp_file) - return temp_file.name - - def _find_mapping_for_address(self, mappings, address): - """Returns the list of all mappings of the file occupying the |address| - memory address. - """ - for file_mappings in mappings: - for mapping in file_mappings: - if address >= mapping.start and address <= mapping.end: - return file_mappings - return None - - def _try_to_map(self, mapping): - remote_file = mapping[0].filename - if remote_file in self._done_mapping: - return False - self._done_mapping.add(remote_file) - self._rfc.open(remote_file) - signature = get_signature(self._rfc, self._elffile_module) - if signature is not None: - if signature in self._libraries: - self._associate_symbols(mapping, self._libraries[signature]) - else: - # This library file is not known locally. Download it from the device or - # the cloud and put it in cache so, if it got symbols, we can see them. - local_file = os.path.join(self._remote_file_cache, signature) - if not os.path.exists(local_file): - tmp_output = self._download_file(signature, remote_file) - shutil.move(tmp_output, local_file) - self._associate_symbols(mapping, local_file) - return True - return False - - def _map_symbols_on_current_thread(self, mapped_files): - """Updates the symbols for the current thread using files from mapped_files. - """ - frame = gdb.newest_frame() - while frame and frame.is_valid(): - if frame.name() is None: - m = self._find_mapping_for_address(mapped_files, frame.pc()) - if m is not None and self._try_to_map(m): - # Force gdb to recompute its frames. - _gdb_execute("info threads") - frame = gdb.newest_frame() - assert frame.is_valid() - if (frame.older() is not None and - frame.older().is_valid() and - frame.older().pc() != frame.pc()): - frame = frame.older() - else: - frame = None - - def update_symbols(self, current_thread_only): - """Updates the mapping between symbols as seen from GDB and local library - files. - - If current_thread_only is True, only update symbols for the current thread. - """ - logging.info("Updating symbols") - mapped_files = _get_mapped_files() - # Map all symbols from native libraries packages with the APK. - for file_mappings in mapped_files: - filename = file_mappings[0].filename - if ((filename.startswith('/data/data/') or - filename.startswith('/data/app')) and - not filename.endswith('.apk') and - not filename.endswith('.dex')): - logging.info('Pre-mapping: %s' % file_mappings[0].filename) - self._try_to_map(file_mappings) - - if current_thread_only: - self._map_symbols_on_current_thread(mapped_files) - else: - logging.info('Updating all threads\' symbols') - current_thread = gdb.selected_thread() - nb_threads = len(_gdb_execute("info threads").split("\n")) - 2 - for i in xrange(nb_threads): - try: - _gdb_execute("thread %d" % (i + 1)) - self._map_symbols_on_current_thread(mapped_files) - except gdb.error: - traceback.print_exc() - current_thread.switch() - - def _get_device_application_pid(self, application): - """Gets the PID of an application running on a device.""" - output = subprocess.check_output([self._adb, 'shell', 'ps']) - for line in output.split('\n'): - elements = line.split() - if len(elements) > 0 and elements[-1] == application: - return elements[1] - return None - - def start(self): - """Starts a debugging session.""" - gdbserver_pid = self._get_device_application_pid('gdbserver') - if gdbserver_pid is not None: - subprocess.check_call([self._adb, 'shell', 'kill', gdbserver_pid]) - shell_pid = self._get_device_application_pid(self._package_name) - if shell_pid is None: - raise Exception('Unable to find a running mojo shell.') - subprocess.check_call([self._adb, 'forward', 'tcp:9999', 'tcp:9999']) - subprocess.Popen( - [self._adb, 'shell', 'gdbserver', '--attach', ':9999', shell_pid], - # os.setpgrp ensures signals passed to this file (such as SIGINT) are - # not propagated to child processes. - preexec_fn = os.setpgrp) - - # Kill stray remote reader processes. See __del__ comment for more info. - remote_file_reader_pid = self._get_device_application_pid( - config.REMOTE_FILE_READER_DEVICE_PATH) - if remote_file_reader_pid is not None: - subprocess.check_call([self._adb, 'shell', 'kill', - remote_file_reader_pid]) - self._remote_file_reader_process = subprocess.Popen( - [self._adb, 'shell', config.REMOTE_FILE_READER_DEVICE_PATH], - stdout=subprocess.PIPE, preexec_fn = os.setpgrp) - port = int(self._remote_file_reader_process.stdout.readline()) - subprocess.check_call([self._adb, 'forward', 'tcp:10000', 'tcp:%d' % port]) - self._rfc.connect() - - _gdb_execute('target remote localhost:9999') - - self.update_symbols(current_thread_only=False) - def on_stop(_): - self.update_symbols(current_thread_only=True) - gdb.events.stop.connect(on_stop) - gdb.events.exited.connect(self.stop) - - # Register the update-symbols command. - UpdateSymbols(self) - -class UpdateSymbols(gdb.Command): - """Command to update symbols loaded into GDB. - - GDB usage: update-symbols [all|current] - """ - _UPDATE_COMMAND = "update-symbols" - - def __init__(self, session): - super(UpdateSymbols, self).__init__(self._UPDATE_COMMAND, gdb.COMMAND_STACK) - self._session = session - - def invoke(self, arg, _unused_from_tty): - if arg == 'current': - self._session.update_symbols(current_thread_only=True) - else: - self._session.update_symbols(current_thread_only=False) - - def complete(self, text, _unused_word): - if text == self._UPDATE_COMMAND: - return ('all', 'current') - elif text in self._UPDATE_COMMAND + ' all': - return ['all'] - elif text in self._UPDATE_COMMAND + ' current': - return ['current'] - else: - return [] diff --git a/mojo/devtools/common/android_gdb/signatures.py b/mojo/devtools/common/android_gdb/signatures.py deleted file mode 100644 index d1cc593e19e51..0000000000000 --- a/mojo/devtools/common/android_gdb/signatures.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2015 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. - -import itertools - - -def get_signature(file_object, elffile_module): - """Computes a unique signature of a library file. - - We only hash the .text section of the library in order to make the hash - resistant to stripping (we want the same hash for the same library with debug - symbols kept or stripped). - """ - try: - elf = elffile_module.ELFFile(file_object) - text_section = elf.get_section_by_name('.text') - except elffile_module.common.ELFError: - return None - file_object.seek(text_section['sh_offset']) - data = file_object.read(min(4096, text_section['sh_size'])) - def combine((i, c)): - return i ^ ord(c) - result = 16 * [0] - for i in xrange(0, len(data), len(result)): - result = map(combine, - itertools.izip_longest(result, - data[i:i + len(result)], - fillvalue='\0')) - return ''.join(["%02x" % x for x in result]) diff --git a/mojo/devtools/common/android_stack_parser/LICENSE b/mojo/devtools/common/android_stack_parser/LICENSE deleted file mode 100644 index d645695673349..0000000000000 --- a/mojo/devtools/common/android_stack_parser/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/mojo/devtools/common/android_stack_parser/README.chromium b/mojo/devtools/common/android_stack_parser/README.chromium deleted file mode 100644 index 58f7c9b79502f..0000000000000 --- a/mojo/devtools/common/android_stack_parser/README.chromium +++ /dev/null @@ -1,30 +0,0 @@ -Name: Android Platform engineering tools -Short Name: android platform development -URL: https://android.googlesource.com/platform/development -Version: 0 -Date: 2014/05/02 -Revision: 1b10ec4 -License: Apache 2.0 -License File: NOT_SHIPPED -Security Critical: no - -Description: -Android Platform engineering tools, specifically stack symbolization scripts -and a jar containing the AOSP framework to compile the Android WebView -glue layer against. The sources used to build the AOSP framework jar can be -checked out using repo on the corresponding manifest file. The AOSP framework -jar is built by invoking make on the android_system_stubs target. - -Local Modifications: -Only picked the few scripts needed by chrome. -Updated output directories to use environment variable. -When calling addr2line, check the symbol is a file (and not a directory). -Added support for parsing LOG(FATAL) and DCHECK errors and their - stack traces, as emitted by src/base/debug/stack_trace_android.cc -Added support for finding symbols when library is loaded directly from the APK. -Changed the toolchain to remove references to 4.6 toolchains. -Added support for arch=x64 as an alias to arch=x86_64 -Added support for mojo. Specifically detection of mojo apps downloaded - to temporary files which are in crash stacks. -Taught `stack` to find the output directory and android_tools regardless of - where under the checkout root it is placed. diff --git a/mojo/devtools/common/android_stack_parser/stack b/mojo/devtools/common/android_stack_parser/stack deleted file mode 100755 index 97913ab84191e..0000000000000 --- a/mojo/devtools/common/android_stack_parser/stack +++ /dev/null @@ -1,255 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (C) 2013 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""stack symbolizes native crash dumps.""" - -import getopt -import glob -import os -import re -import sys - -import stack_core -import subprocess -import symbol - -_DEFAULT_SYMROOT = '/tmp/symbols' -_DEFAULT_BUILD_DIR = 'out/android_Debug' -_DEFAULT_NDK_DIR = 'third_party/android_tools/ndk' - - -def PrintUsage(): - """Print usage and exit with error.""" - # pylint: disable-msg=C6310 - print - print " usage: " + sys.argv[0] + " [options] [FILE]" - print - print " --symbols-dir=path" - print " the path to a symbols dir, this is generally for system level" - print " symbols" - print - print " --build-dir=path" - print " the path to a directory containing Mojo symbols (can be" - print " absolute or relative to src), such as =out/android_Debug" - - print " --ndk-dir=path" - print " the path to a directory containing Android NDK" - print - print " --symbols-zip=path" - print " the path to a symbols zip file, such as =dream-symbols-12345.zip" - print - print " --more-info" - print " --less-info" - print " Change the level of detail in the output." - print " --more-info is slower and more verbose, but more functions will" - print " be fully qualified with namespace/classname and have full" - print " argument information. Also, the 'stack data' section will be" - print " printed." - print - print " --arch=arm|arm64|x64|x86|mips" - print " the target architecture" - print - print " FILE should contain a stack trace in it somewhere" - print " the tool will find that and re-print it with" - print " source files and line numbers. If you don't" - print " pass FILE, or if file is -, it reads from" - print " stdin." - print - # pylint: enable-msg=C6310 - sys.exit(1) - -def UnzipSymbols(symbolfile, symdir=None): - """Unzips a file to _DEFAULT_SYMROOT and returns the unzipped location. - - Args: - symbolfile: The .zip file to unzip - symdir: Optional temporary directory to use for extraction - - Returns: - A tuple containing (the directory into which the zip file was unzipped, - the path to the "symbols" directory in the unzipped file). To clean - up, the caller can delete the first element of the tuple. - - Raises: - SymbolDownloadException: When the unzip fails. - """ - if not symdir: - symdir = "%s/%s" % (_DEFAULT_SYMROOT, hash(symbolfile)) - if not os.path.exists(symdir): - os.makedirs(symdir) - - print "extracting %s..." % symbolfile - saveddir = os.getcwd() - os.chdir(symdir) - try: - unzipcode = subprocess.call(["unzip", "-qq", "-o", symbolfile]) - if unzipcode > 0: - os.remove(symbolfile) - raise SymbolDownloadException("failed to extract symbol files (%s)." - % symbolfile) - finally: - os.chdir(saveddir) - - android_symbols = glob.glob("%s/out/target/product/*/symbols" % symdir) - if android_symbols: - return (symdir, android_symbols[0]) - else: - # This is a zip of Chrome symbols, so symbol.CHROME_SYMBOLS_DIR needs to be - # updated to point here. - symbol.CHROME_SYMBOLS_DIR = symdir - return (symdir, symdir) - - -def GetBasenameFromMojoApp(url): - """Used by GetSymbolMapping() to extract the basename from the location the - mojo app was downloaded from. The location is a URL, e.g. - http://foo/bar/x.so.""" - index = url.rfind('/') - return url[(index + 1):] if index != -1 else url - - -def GetSymboledNameForMojoApp(path): - """Used by GetSymbolMapping to get the non-stripped library name for an - installed mojo app.""" - # e.g. tracing.mojo -> libtracing_library.so - name, ext = os.path.splitext(path) - if ext != '.mojo': - return path - return 'lib%s_library.so' % name - - -def GetSymbolMapping(lines): - """Returns a mapping (dictionary) from download file to .so.""" - regex = re.compile('Caching mojo app (\S+) at (\S+)') - mappings = {} - for line in lines: - result = regex.search(line) - if result: - url = GetBasenameFromMojoApp(result.group(1)) - mappings[result.group(2)] = GetSymboledNameForMojoApp(url) - return mappings - - -def _LowestAncestorContainingRelpath(dir_path, relpath): - """Returns the lowest ancestor dir of |dir_path| that contains |relpath|. - """ - cur_dir_path = os.path.abspath(dir_path) - while True: - if os.path.exists(os.path.join(cur_dir_path, relpath)): - return cur_dir_path - - next_dir_path = os.path.dirname(cur_dir_path) - if next_dir_path != cur_dir_path: - cur_dir_path = next_dir_path - else: - return None - - -def _GuessDir(relpath): - """Returns absolute path to location |relpath| in the lowest ancestor of this - file that contains it.""" - lowest_ancestor = _LowestAncestorContainingRelpath( - os.path.dirname(__file__), relpath) - if not lowest_ancestor: - return None - return os.path.join(lowest_ancestor, relpath) - - - -def main(): - try: - options, arguments = getopt.getopt(sys.argv[1:], "", - ["more-info", - "less-info", - "build-dir=", - "ndk-dir=", - "symbols-dir=", - "symbols-zip=", - "arch=", - "help"]) - except getopt.GetoptError, unused_error: - PrintUsage() - - zip_arg = None - more_info = False - for option, value in options: - if option == "--help": - PrintUsage() - elif option == "--symbols-dir": - symbol.SYMBOLS_DIR = os.path.expanduser(value) - elif option == "--symbols-zip": - zip_arg = os.path.expanduser(value) - elif option == "--arch": - symbol.ARCH = value - elif option == "--build-dir": - symbol.BUILD_DIR = value - elif option == "--ndk-dir": - symbol.NDK_DIR = value - elif option == "--more-info": - more_info = True - elif option == "--less-info": - more_info = False - - if not symbol.BUILD_DIR: - guess = _GuessDir(_DEFAULT_BUILD_DIR) - if not guess: - print "Couldn't find the build directory, please pass --build-dir." - return 1 - print "Inferring the build directory path as " + guess - symbol.BUILD_DIR = guess - - if not symbol.NDK_DIR: - guess = _GuessDir(_DEFAULT_NDK_DIR) - if not guess: - print "Couldn't find the Android NDK, please pass --ndk-dir." - return 1 - print "Inferring the Android NDK path as " + guess - symbol.NDK_DIR = guess - - - if len(arguments) > 1: - PrintUsage() - - if not arguments or arguments[0] == "-": - print "Reading native crash info from stdin" - f = sys.stdin - else: - print "Searching for native crashes in %s" % arguments[0] - f = open(arguments[0], "r") - - lines = f.readlines() - f.close() - - rootdir = None - if zip_arg: - rootdir, symbol.SYMBOLS_DIR = UnzipSymbols(zip_arg) - - if symbol.SYMBOLS_DIR: - print "Reading Android symbols from", symbol.SYMBOLS_DIR - - print "Reading Mojo symbols from", symbol.BUILD_DIR - stack_core.ConvertTrace(lines, more_info, GetSymbolMapping(lines)) - - if rootdir: - # be a good citizen and clean up...os.rmdir and os.removedirs() don't work - cmd = "rm -rf \"%s\"" % rootdir - print "\ncleaning up (%s)" % cmd - os.system(cmd) - -if __name__ == "__main__": - main() - -# vi: ts=2 sw=2 diff --git a/mojo/devtools/common/android_stack_parser/stack_core.py b/mojo/devtools/common/android_stack_parser/stack_core.py deleted file mode 100644 index 2148e9da20105..0000000000000 --- a/mojo/devtools/common/android_stack_parser/stack_core.py +++ /dev/null @@ -1,262 +0,0 @@ -# Copyright (C) 2013 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""stack symbolizes native crash dumps.""" - -import re - -import symbol - -def PrintTraceLines(trace_lines): - """Print back trace.""" - maxlen = max(map(lambda tl: len(tl[1]), trace_lines)) - print - print "Stack Trace:" - print " RELADDR " + "FUNCTION".ljust(maxlen) + " FILE:LINE" - for tl in trace_lines: - (addr, symbol_with_offset, location) = tl - print " %8s %s %s" % (addr, symbol_with_offset.ljust(maxlen), location) - return - - -def PrintValueLines(value_lines): - """Print stack data values.""" - maxlen = max(map(lambda tl: len(tl[2]), value_lines)) - print - print "Stack Data:" - print " ADDR VALUE " + "FUNCTION".ljust(maxlen) + " FILE:LINE" - for vl in value_lines: - (addr, value, symbol_with_offset, location) = vl - print " %8s %8s %s %s" % (addr, value, symbol_with_offset.ljust(maxlen), location) - return - -UNKNOWN = "" -HEAP = "[heap]" -STACK = "[stack]" - - -def PrintOutput(trace_lines, value_lines, more_info): - if trace_lines: - PrintTraceLines(trace_lines) - if value_lines: - # TODO(cjhopman): it seems that symbol.SymbolInformation always fails to - # find information for addresses in value_lines in chrome libraries, and so - # value_lines have little value to us and merely clutter the output. - # Since information is sometimes contained in these lines (from system - # libraries), don't completely disable them. - if more_info: - PrintValueLines(value_lines) - -def PrintDivider(): - print - print "-----------------------------------------------------\n" - -def ConvertTrace(lines, more_info, symbol_file_mappings): - """Convert strings containing native crash to a stack. - - Args: - symbol_file_mappings: maps from library pathname to base name of file - containing symbols. If |symbol_file_mappings| doesn't contain a path than - the library pathname is used. See TranslatePathFromDeviceToLocal() for - more information. - """ - process_info_line = re.compile("(pid: [0-9]+, tid: [0-9]+.*)") - signal_line = re.compile("(signal [0-9]+ \(.*\).*)") - register_line = re.compile("(([ ]*[0-9a-z]{2} [0-9a-f]{8}){4})") - thread_line = re.compile("(.*)(\-\-\- ){15}\-\-\-") - dalvik_jni_thread_line = re.compile("(\".*\" prio=[0-9]+ tid=[0-9]+ NATIVE.*)") - dalvik_native_thread_line = re.compile("(\".*\" sysTid=[0-9]+ nice=[0-9]+.*)") - - width = "{8}" - if symbol.ARCH == "arm64" or symbol.ARCH == "x86_64" or symbol.ARCH == "x64": - width = "{16}" - - # Matches LOG(FATAL) lines, like the following example: - # [FATAL:source_file.cc(33)] Check failed: !instances_.empty() - log_fatal_line = re.compile("(\[FATAL\:.*\].*)$") - - # Note that both trace and value line matching allow for variable amounts of - # whitespace (e.g. \t). This is because the we want to allow for the stack - # tool to operate on AndroidFeedback provided system logs. AndroidFeedback - # strips out double spaces that are found in tombsone files and logcat output. - # - # Examples of matched trace lines include lines from tombstone files like: - # #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so - # #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so (symbol) - # Or lines from AndroidFeedback crash report system logs like: - # 03-25 00:51:05.520 I/DEBUG ( 65): #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so - # Please note the spacing differences. - trace_line = re.compile("(.*)\#(?P[0-9]+)[ \t]+(..)[ \t]+(0x)?(?P
[0-9a-f]{0,16})[ \t]+(?P[^\r\n \t]*)(?P \((?P.*)\))?") # pylint: disable-msg=C6310 - - # Matches lines emitted by src/base/debug/stack_trace_android.cc, like: - # #00 0x7324d92d /data/app-lib/org.chromium.native_test-1/libbase.cr.so+0x0006992d - # This pattern includes the unused named capture groups and - # so that it can interoperate with the |trace_line| regex. - debug_trace_line = re.compile( - '(.*)(?P\#[0-9]+ 0x[0-9a-f]' + width + ') ' - '(?P[^+]+)( \(deleted\))+\+0x(?P
[0-9a-f]' + width + ')' - '(?P)(?P)') - - # Examples of matched value lines include: - # bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so - # bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so (symbol) - # 03-25 00:51:05.530 I/DEBUG ( 65): bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so - # Again, note the spacing differences. - value_line = re.compile("(.*)([0-9a-f]" + width + ")[ \t]+([0-9a-f]" + width + ")[ \t]+([^\r\n \t]*)( \((.*)\))?") - # Lines from 'code around' sections of the output will be matched before - # value lines because otheriwse the 'code around' sections will be confused as - # value lines. - # - # Examples include: - # 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8 - # 03-25 00:51:05.530 I/DEBUG ( 65): 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8 - code_line = re.compile("(.*)[ \t]*[a-f0-9]" + width + - "[ \t]*[a-f0-9]" + width + - "[ \t]*[a-f0-9]" + width + - "[ \t]*[a-f0-9]" + width + - "[ \t]*[a-f0-9]" + width + - "[ \t]*[ \r\n]") # pylint: disable-msg=C6310 - - trace_lines = [] - value_lines = [] - last_frame = -1 - - # It is faster to get symbol information with a single call rather than with - # separate calls for each line. Since symbol.SymbolInformation caches results, - # we can extract all the addresses that we will want symbol information for - # from the log and call symbol.SymbolInformation so that the results are - # cached in the following lookups. - code_addresses = {} - for ln in lines: - line = unicode(ln, errors='ignore') - lib, address = None, None - - match = trace_line.match(line) or debug_trace_line.match(line) - if match: - address, lib = match.group('address', 'lib') - - match = value_line.match(line) - if match and not code_line.match(line): - (_0, _1, address, lib, _2, _3) = match.groups() - - if lib: - code_addresses.setdefault(lib, set()).add(address) - - for lib in code_addresses: - symbol.SymbolInformationForSet( - symbol.TranslatePathFromDeviceToLocal( - symbol_file_mappings.get(lib, lib)), - code_addresses[lib], more_info) - - for ln in lines: - # AndroidFeedback adds zero width spaces into its crash reports. These - # should be removed or the regular expresssions will fail to match. - line = unicode(ln, errors='ignore') - process_header = process_info_line.search(line) - signal_header = signal_line.search(line) - register_header = register_line.search(line) - thread_header = thread_line.search(line) - dalvik_jni_thread_header = dalvik_jni_thread_line.search(line) - dalvik_native_thread_header = dalvik_native_thread_line.search(line) - log_fatal_header = log_fatal_line.search(line) - if (process_header or signal_header or register_header or thread_header or - dalvik_jni_thread_header or dalvik_native_thread_header or - log_fatal_header) : - if trace_lines or value_lines: - PrintOutput(trace_lines, value_lines, more_info) - PrintDivider() - trace_lines = [] - value_lines = [] - last_frame = -1 - if process_header: - print process_header.group(1) - if signal_header: - print signal_header.group(1) - if register_header: - print register_header.group(1) - if thread_header: - print thread_header.group(1) - if dalvik_jni_thread_header: - print dalvik_jni_thread_header.group(1) - if dalvik_native_thread_header: - print dalvik_native_thread_header.group(1) - if log_fatal_header: - print log_fatal_header.group(1) - continue - - match = trace_line.match(line) or debug_trace_line.match(line) - if match: - frame, code_addr, area, symbol_present, symbol_name = match.group( - 'frame', 'address', 'lib', 'symbol_present', 'symbol_name') - - if frame <= last_frame and (trace_lines or value_lines): - PrintOutput(trace_lines, value_lines, more_info) - PrintDivider() - trace_lines = [] - value_lines = [] - last_frame = frame - - if area == UNKNOWN or area == HEAP or area == STACK: - trace_lines.append((code_addr, "", area)) - else: - # If a calls b which further calls c and c is inlined to b, we want to - # display "a -> b -> c" in the stack trace instead of just "a -> c" - info = symbol.SymbolInformation(symbol_file_mappings.get(area, area), - code_addr, more_info) - nest_count = len(info) - 1 - for (source_symbol, source_location, object_symbol_with_offset) in info: - if not source_symbol: - if symbol_present: - source_symbol = symbol.CallCppFilt(symbol_name) - else: - source_symbol = UNKNOWN - if not source_location: - source_location = area - if nest_count > 0: - nest_count = nest_count - 1 - trace_lines.append(("v------>", source_symbol, source_location)) - else: - if not object_symbol_with_offset: - object_symbol_with_offset = source_symbol - trace_lines.append((code_addr, - object_symbol_with_offset, - source_location)) - if code_line.match(line): - # Code lines should be ignored. If this were exluded the 'code around' - # sections would trigger value_line matches. - continue; - match = value_line.match(line) - if match: - (unused_, addr, value, area, symbol_present, symbol_name) = match.groups() - if area == UNKNOWN or area == HEAP or area == STACK or not area: - value_lines.append((addr, value, "", area)) - else: - info = symbol.SymbolInformation(symbol_file_mappings.get(area, area), - value, more_info) - (source_symbol, source_location, object_symbol_with_offset) = info.pop() - if not source_symbol: - if symbol_present: - source_symbol = symbol.CallCppFilt(symbol_name) - else: - source_symbol = UNKNOWN - if not source_location: - source_location = area - if not object_symbol_with_offset: - object_symbol_with_offset = source_symbol - value_lines.append((addr, - value, - object_symbol_with_offset, - source_location)) - - PrintOutput(trace_lines, value_lines, more_info) diff --git a/mojo/devtools/common/android_stack_parser/symbol.py b/mojo/devtools/common/android_stack_parser/symbol.py deleted file mode 100644 index 797326c402ea9..0000000000000 --- a/mojo/devtools/common/android_stack_parser/symbol.py +++ /dev/null @@ -1,563 +0,0 @@ -# Copyright (C) 2013 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Module for looking up symbolic debugging information. - -The information can include symbol names, offsets, and source locations. -""" - -import glob -import itertools -import os -import re -import subprocess -import zipfile - -NDK_DIR = "" -BUILD_DIR = "" -SYMBOLS_DIR = "" - -ARCH = "arm" - -TOOLCHAIN_INFO = None - -def Uname(): - """'uname' for constructing prebuilt/<...> and out/host/<...> paths.""" - uname = os.uname()[0] - proc = os.uname()[-1] - if uname == "Darwin": - if proc == "i386": - return "darwin-x86" - elif proc == "x86_64": - return "darwin-x86_64" - return "darwin-ppc" - if uname == "Linux": - if proc == "i386": - return "linux-x86" - else: - return "linux-x86_64" - return uname - -def ToolPath(tool, toolchain_info=None): - """Return a full qualified path to the specified tool""" - # ToolPath looks for the tools in the completely incorrect directory. - # This looks in the checked in android_tools. - if ARCH == "arm": - toolchain_source = "arm-linux-androideabi-4.9" - toolchain_prefix = "arm-linux-androideabi" - elif ARCH == "arm64": - toolchain_source = "aarch64-linux-android-4.9" - toolchain_prefix = "aarch64-linux-android" - elif ARCH == "x86": - toolchain_source = "x86-4.9" - toolchain_prefix = "i686-linux-android" - elif ARCH == "x86_64" or ARCH == "x64": - toolchain_source = "x86_64-4.9" - toolchain_prefix = "x86_64-linux-android" - elif ARCH == "mips": - toolchain_source = "mipsel-linux-android-4.9" - toolchain_prefix = "mipsel-linux-android" - else: - raise Exception("Could not find tool chain") - - toolchain_subdir = ("toolchains/%s/prebuilt/%s/bin" % ( - toolchain_source, Uname())) - - return os.path.join(NDK_DIR, - toolchain_subdir, - toolchain_prefix + "-" + tool) - -def FindToolchain(): - """Look for the latest available toolchain - - Args: - None - - Returns: - A pair of strings containing toolchain label and target prefix. - """ - global TOOLCHAIN_INFO - if TOOLCHAIN_INFO is not None: - return TOOLCHAIN_INFO - - ## Known toolchains, newer ones in the front. - gcc_version = "4.9" - if ARCH == "arm64": - known_toolchains = [ - ("aarch64-linux-android-" + gcc_version, "aarch64", "aarch64-linux-android") - ] - elif ARCH == "arm": - known_toolchains = [ - ("arm-linux-androideabi-" + gcc_version, "arm", "arm-linux-androideabi") - ] - elif ARCH =="x86": - known_toolchains = [ - ("x86-" + gcc_version, "x86", "i686-linux-android") - ] - elif ARCH =="x86_64" or ARCH =="x64": - known_toolchains = [ - ("x86_64-" + gcc_version, "x86_64", "x86_64-linux-android") - ] - elif ARCH == "mips": - known_toolchains = [ - ("mipsel-linux-android-" + gcc_version, "mips", "mipsel-linux-android") - ] - else: - known_toolchains = [] - - # Look for addr2line to check for valid toolchain path. - for (label, platform, target) in known_toolchains: - toolchain_info = (label, platform, target); - if os.path.exists(ToolPath("addr2line", toolchain_info)): - TOOLCHAIN_INFO = toolchain_info - print "Using toolchain from :" + ToolPath("", TOOLCHAIN_INFO) - return toolchain_info - - raise Exception("Could not find tool chain") - -def GetAapt(): - """Returns the path to aapt. - - Args: - None - - Returns: - the pathname of the 'aapt' executable. - """ - sdk_home = os.path.join('third_party', 'android_tools', 'sdk') - sdk_home = os.environ.get('SDK_HOME', sdk_home) - aapt_exe = glob.glob(os.path.join(sdk_home, 'build-tools', '*', 'aapt')) - if not aapt_exe: - return None - return sorted(aapt_exe, key=os.path.getmtime, reverse=True)[0] - -def ApkMatchPackageName(aapt, apk_path, package_name): - """Returns true the APK's package name matches package_name. - - Args: - aapt: pathname for the 'aapt' executable. - apk_path: pathname of the APK file. - package_name: package name to match. - - Returns: - True if the package name matches or aapt is None, False otherwise. - """ - if not aapt: - # Allow false positives - return True - aapt_output = subprocess.check_output( - [aapt, 'dump', 'badging', apk_path]).split('\n') - package_name_re = re.compile(r'package: .*name=\'(\S*)\'') - for line in aapt_output: - match = package_name_re.match(line) - if match: - return package_name == match.group(1) - return False - -def PathListJoin(prefix_list, suffix_list): - """Returns each prefix in prefix_list joined with each suffix in suffix list. - - Args: - prefix_list: list of path prefixes. - suffix_list: list of path suffixes. - - Returns: - List of paths each of which joins a prefix with a suffix. - """ - return [ - os.path.join(prefix, suffix) - for prefix in prefix_list for suffix in suffix_list ] - -def GetCandidates(filepart, candidate_fun, relative_dirs=None): - """Returns a list of candidate filenames. - - Args: - filepart: the file part of the pathname. - candidate_fun: a function to apply to each candidate, returns a list. - relative_dirs: a list of relative directory names to search from. - - Returns: - A list of candidate files ordered by modification time, newest first. - """ - candidates = [BUILD_DIR] - - if relative_dirs: - candidates = PathListJoin(candidates, relative_dirs) - - candidates = PathListJoin(candidates, [filepart]) - candidates = list( - itertools.chain.from_iterable(map(candidate_fun, candidates))) - candidates = sorted(candidates, key=os.path.getmtime, reverse=True) - return candidates - -def GetCandidateApks(): - """Returns a list of APKs which could contain the library. - - Args: - None - - Returns: - list of APK filename which could contain the library. - """ - return GetCandidates('*.apk', glob.glob, relative_dirs=['apks']) - -def GetCrazyLib(apk_filename): - """Returns the name of the first crazy library from this APK. - - Args: - apk_filename: name of an APK file. - - Returns: - Name of the first library which would be crazy loaded from this APK. - """ - zip_file = zipfile.ZipFile(apk_filename, 'r') - for filename in zip_file.namelist(): - match = re.match('lib/[^/]*/crazy.(lib.*[.]so)', filename) - if match: - return match.group(1) - -def GetMatchingApks(device_apk_name): - """Find any APKs which match the package indicated by the device_apk_name. - - Args: - device_apk_name: name of the APK on the device. - - Returns: - A list of APK filenames which could contain the desired library. - """ - match = re.match('(.*)-[0-9]+[.]apk$', device_apk_name) - if not match: - return None - package_name = match.group(1) - return filter( - lambda candidate_apk: - ApkMatchPackageName(GetAapt(), candidate_apk, package_name), - GetCandidateApks()) - -def MapDeviceApkToLibrary(device_apk_name): - """Provide a library name which corresponds with device_apk_name. - - Args: - device_apk_name: name of the APK on the device. - - Returns: - Name of the library which corresponds to that APK. - """ - matching_apks = GetMatchingApks(device_apk_name) - for matching_apk in matching_apks: - crazy_lib = GetCrazyLib(matching_apk) - if crazy_lib: - return crazy_lib - -def GetCandidateLibraries(library_name): - """Returns a list of candidate library filenames. - - Args: - library_name: basename of the library to match. - - Returns: - A list of matching library filenames for library_name. - """ - return GetCandidates( - library_name, - lambda filename: filter(os.path.exists, [filename])) - -def TranslatePathFromDeviceToLocal(lib): - """Maps a path as seen on the device to a path on the local file system - containing symbols. - - Args: - lib: library (or executable) pathname from device. - """ - - # SymbolInformation(lib, addr) receives lib that is either a basename or - # the path from symbols root to the symbols file. This needs to be translated - # to point to the correct .so path. If the user doesn't explicitly specify - # which directory to use, then use the most recently updated one in one of - # the known directories. - library_name = os.path.basename(lib) - - # The filename in the stack trace maybe an APK name rather than a library - # name. This happens when the library was loaded directly from inside the - # APK. If this is the case we try to figure out the library name by looking - # for a matching APK file and finding the name of the library in contains. - # The name of the APK file on the device is of the form - # -.apk. The APK file on the host may have any name - # so we look at the APK badging to see if the package name matches. - if re.search('-[0-9]+[.]apk$', library_name): - mapping = MapDeviceApkToLibrary(library_name) - if mapping: - library_name = mapping - - candidate_libraries = GetCandidateLibraries(library_name) - return (candidate_libraries[0] if candidate_libraries else - os.path.join(SYMBOLS_DIR, lib)) - -def SymbolInformation(lib, addr, get_detailed_info): - """Look up symbol information about an address. - - Args: - lib: library (or executable) pathname containing symbols - addr: string hexidecimal address - - Returns: - A list of the form [(source_symbol, source_location, - object_symbol_with_offset)]. - - If the function has been inlined then the list may contain - more than one element with the symbols for the most deeply - nested inlined location appearing first. The list is - always non-empty, even if no information is available. - - Usually you want to display the source_location and - object_symbol_with_offset from the last element in the list. - """ - lib = TranslatePathFromDeviceToLocal(lib) - info = SymbolInformationForSet(lib, set([addr]), get_detailed_info) - return (info and info.get(addr)) or [(None, None, None)] - - -def SymbolInformationForSet(lib, unique_addrs, get_detailed_info): - """Look up symbol information for a set of addresses from the given library. - - Args: - lib: library (or executable) pathname containing symbols - unique_addrs: set of hexidecimal addresses - - Returns: - A dictionary of the form {addr: [(source_symbol, source_location, - object_symbol_with_offset)]} where each address has a list of - associated symbols and locations. The list is always non-empty. - - If the function has been inlined then the list may contain - more than one element with the symbols for the most deeply - nested inlined location appearing first. The list is - always non-empty, even if no information is available. - - Usually you want to display the source_location and - object_symbol_with_offset from the last element in the list. - """ - if not lib: - return None - - addr_to_line = CallAddr2LineForSet(lib, unique_addrs) - if not addr_to_line: - return None - - if get_detailed_info: - addr_to_objdump = CallObjdumpForSet(lib, unique_addrs) - if not addr_to_objdump: - return None - else: - addr_to_objdump = dict((addr, ("", 0)) for addr in unique_addrs) - - result = {} - for addr in unique_addrs: - source_info = addr_to_line.get(addr) - if not source_info: - source_info = [(None, None)] - if addr in addr_to_objdump: - (object_symbol, object_offset) = addr_to_objdump.get(addr) - object_symbol_with_offset = FormatSymbolWithOffset(object_symbol, - object_offset) - else: - object_symbol_with_offset = None - result[addr] = [(source_symbol, source_location, object_symbol_with_offset) - for (source_symbol, source_location) in source_info] - - return result - - -class MemoizedForSet(object): - def __init__(self, fn): - self.fn = fn - self.cache = {} - - def __call__(self, lib, unique_addrs): - lib_cache = self.cache.setdefault(lib, {}) - - no_cache = filter(lambda x: x not in lib_cache, unique_addrs) - if no_cache: - lib_cache.update((k, None) for k in no_cache) - result = self.fn(lib, no_cache) - if result: - lib_cache.update(result) - - return dict((k, lib_cache[k]) for k in unique_addrs if lib_cache[k]) - - -@MemoizedForSet -def CallAddr2LineForSet(lib, unique_addrs): - """Look up line and symbol information for a set of addresses. - - Args: - lib: library (or executable) pathname containing symbols - unique_addrs: set of string hexidecimal addresses look up. - - Returns: - A dictionary of the form {addr: [(symbol, file:line)]} where - each address has a list of associated symbols and locations - or an empty list if no symbol information was found. - - If the function has been inlined then the list may contain - more than one element with the symbols for the most deeply - nested inlined location appearing first. - """ - if not lib or not os.path.isfile(lib): - return None - - (label, platform, target) = FindToolchain() - cmd = [ToolPath("addr2line"), "--functions", "--inlines", - "--demangle", "--exe=" + lib] - child = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) - - result = {} - addrs = sorted(unique_addrs) - for addr in addrs: - child.stdin.write("0x%s\n" % addr) - child.stdin.flush() - records = [] - first = True - while True: - symbol = child.stdout.readline().strip() - if symbol == "??": - symbol = None - location = child.stdout.readline().strip() - if location == "??:0": - location = None - if symbol is None and location is None: - break - records.append((symbol, location)) - if first: - # Write a blank line as a sentinel so we know when to stop - # reading inlines from the output. - # The blank line will cause addr2line to emit "??\n??:0\n". - child.stdin.write("\n") - first = False - result[addr] = records - child.stdin.close() - child.stdout.close() - return result - - -def StripPC(addr): - """Strips the Thumb bit a program counter address when appropriate. - - Args: - addr: the program counter address - - Returns: - The stripped program counter address. - """ - global ARCH - - if ARCH == "arm": - return addr & ~1 - return addr - -@MemoizedForSet -def CallObjdumpForSet(lib, unique_addrs): - """Use objdump to find out the names of the containing functions. - - Args: - lib: library (or executable) pathname containing symbols - unique_addrs: set of string hexidecimal addresses to find the functions for. - - Returns: - A dictionary of the form {addr: (string symbol, offset)}. - """ - if not lib: - return None - - symbols = SYMBOLS_DIR + lib - if not os.path.exists(symbols): - return None - - symbols = SYMBOLS_DIR + lib - if not os.path.exists(symbols): - return None - - result = {} - - # Function lines look like: - # 000177b0 : - # We pull out the address and function first. Then we check for an optional - # offset. This is tricky due to functions that look like "operator+(..)+0x2c" - func_regexp = re.compile("(^[a-f0-9]*) \<(.*)\>:$") - offset_regexp = re.compile("(.*)\+0x([a-f0-9]*)") - - # A disassembly line looks like: - # 177b2: b510 push {r4, lr} - asm_regexp = re.compile("(^[ a-f0-9]*):[ a-f0-0]*.*$") - - for target_addr in unique_addrs: - start_addr_dec = str(StripPC(int(target_addr, 16))) - stop_addr_dec = str(StripPC(int(target_addr, 16)) + 8) - cmd = [ToolPath("objdump"), - "--section=.text", - "--demangle", - "--disassemble", - "--start-address=" + start_addr_dec, - "--stop-address=" + stop_addr_dec, - symbols] - - current_symbol = None # The current function symbol in the disassembly. - current_symbol_addr = 0 # The address of the current function. - - stream = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout - for line in stream: - # Is it a function line like: - # 000177b0 : - components = func_regexp.match(line) - if components: - # This is a new function, so record the current function and its address. - current_symbol_addr = int(components.group(1), 16) - current_symbol = components.group(2) - - # Does it have an optional offset like: "foo(..)+0x2c"? - components = offset_regexp.match(current_symbol) - if components: - current_symbol = components.group(1) - offset = components.group(2) - if offset: - current_symbol_addr -= int(offset, 16) - - # Is it an disassembly line like: - # 177b2: b510 push {r4, lr} - components = asm_regexp.match(line) - if components: - addr = components.group(1) - i_addr = int(addr, 16) - i_target = StripPC(int(target_addr, 16)) - if i_addr == i_target: - result[target_addr] = (current_symbol, i_target - current_symbol_addr) - stream.close() - - return result - - -def CallCppFilt(mangled_symbol): - cmd = [ToolPath("c++filt")] - process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) - process.stdin.write(mangled_symbol) - process.stdin.write("\n") - process.stdin.close() - demangled_symbol = process.stdout.readline().strip() - process.stdout.close() - return demangled_symbol - -def FormatSymbolWithOffset(symbol, offset): - if offset == 0: - return symbol - return "%s+%d" % (symbol, offset) diff --git a/mojo/devtools/common/devtoolslib/__init__.py b/mojo/devtools/common/devtoolslib/__init__.py deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/mojo/devtools/common/devtoolslib/android_shell.py b/mojo/devtools/common/devtoolslib/android_shell.py deleted file mode 100644 index e07ce773a4379..0000000000000 --- a/mojo/devtools/common/devtoolslib/android_shell.py +++ /dev/null @@ -1,430 +0,0 @@ -# Copyright 2014 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. - -import atexit -import hashlib -import json -import logging -import os -import os.path -import random -import re -import subprocess -import sys -import tempfile -import threading -import time - -from devtoolslib.http_server import start_http_server -from devtoolslib.shell import Shell -from devtoolslib.utils import overrides - - -# Tags used by mojo shell Java logging. -_LOGCAT_JAVA_TAGS = [ - 'AndroidHandler', - 'MojoFileHelper', - 'MojoMain', - 'MojoShellActivity', - 'MojoShellApplication', -] - -# Tags used by native logging reflected in the logcat. -_LOGCAT_NATIVE_TAGS = [ - 'chromium', - 'sky', -] - -_MOJO_SHELL_PACKAGE_NAME = 'org.chromium.mojo.shell' - - -_logger = logging.getLogger() - - -def _exit_if_needed(process): - """Exits |process| if it is still alive.""" - if process.poll() is None: - process.kill() - - -def _find_available_port(netstat_output, max_attempts=10000): - opened = [int(x.strip().split()[3].split(':')[1]) - for x in netstat_output if x.startswith(' tcp')] - for _ in xrange(max_attempts): - port = random.randint(4096, 16384) - if port not in opened: - return port - else: - raise Exception('Failed to identify an available port.') - - -def _find_available_host_port(): - netstat_output = subprocess.check_output(['netstat']) - return _find_available_port(netstat_output) - - -class AndroidShell(Shell): - """Wrapper around Mojo shell running on an Android device. - - Args: - adb_path: Path to adb, optional if adb is in PATH. - target_device: Device to run on, if multiple devices are connected. - logcat_tags: Comma-separated list of additional logcat tags to use. - """ - - def __init__(self, adb_path="adb", target_device=None, logcat_tags=None, - verbose_pipe=None): - self.adb_path = adb_path - self.target_device = target_device - self.stop_shell_registered = False - self.adb_running_as_root = None - self.additional_logcat_tags = logcat_tags - self.verbose_pipe = verbose_pipe if verbose_pipe else open(os.devnull, 'w') - - def _adb_command(self, args): - """Forms an adb command from the given arguments, prepending the adb path - and adding a target device specifier, if needed. - """ - adb_command = [self.adb_path] - if self.target_device: - adb_command.extend(['-s', self.target_device]) - adb_command.extend(args) - return adb_command - - def _read_fifo(self, fifo_path, pipe, on_fifo_closed, max_attempts=5): - """Reads |fifo_path| on the device and write the contents to |pipe|. - - Calls |on_fifo_closed| when the fifo is closed. This method will try to find - the path up to |max_attempts|, waiting 1 second between each attempt. If it - cannot find |fifo_path|, a exception will be raised. - """ - fifo_command = self._adb_command( - ['shell', 'test -e "%s"; echo $?' % fifo_path]) - - def _run(): - def _wait_for_fifo(): - for _ in xrange(max_attempts): - if subprocess.check_output(fifo_command)[0] == '0': - return - time.sleep(1) - if on_fifo_closed: - on_fifo_closed() - raise Exception("Unable to find fifo.") - _wait_for_fifo() - stdout_cat = subprocess.Popen( - self._adb_command(['shell', 'cat', fifo_path]), stdout=pipe) - atexit.register(_exit_if_needed, stdout_cat) - stdout_cat.wait() - if on_fifo_closed: - on_fifo_closed() - - thread = threading.Thread(target=_run, name="StdoutRedirector") - thread.start() - - def _find_available_device_port(self): - netstat_output = subprocess.check_output( - self._adb_command(['shell', 'netstat'])) - return _find_available_port(netstat_output) - - def _forward_device_port_to_host(self, device_port, host_port): - """Maps the device port to the host port. If |device_port| is 0, a random - available port is chosen. - - Returns: - The device port. - """ - assert host_port - # Root is not required for `adb forward` (hence we don't check the return - # value), but if we can run adb as root, we have to do it now, because - # restarting adbd as root clears any port mappings. See - # https://github.com/domokit/devtools/issues/20. - self._run_adb_as_root() - - if device_port == 0: - # TODO(ppi): Should we have a retry loop to handle the unlikely races? - device_port = self._find_available_device_port() - subprocess.check_call(self._adb_command([ - "reverse", "tcp:%d" % device_port, "tcp:%d" % host_port])) - - def _unmap_port(): - unmap_command = self._adb_command([ - "reverse", "--remove", "tcp:%d" % device_port]) - subprocess.Popen(unmap_command) - atexit.register(_unmap_port) - return device_port - - def _forward_host_port_to_device(self, host_port, device_port): - """Maps the host port to the device port. If |host_port| is 0, a random - available port is chosen. - - Returns: - The host port. - """ - assert device_port - self._run_adb_as_root() - - if host_port == 0: - # TODO(ppi): Should we have a retry loop to handle the unlikely races? - host_port = _find_available_host_port() - subprocess.check_call(self._adb_command([ - "forward", 'tcp:%d' % host_port, 'tcp:%d' % device_port])) - - def _unmap_port(): - unmap_command = self._adb_command([ - "forward", "--remove", "tcp:%d" % device_port]) - subprocess.Popen(unmap_command) - atexit.register(_unmap_port) - return host_port - - def _run_adb_as_root(self): - if self.adb_running_as_root is not None: - return self.adb_running_as_root - - if ('cannot run as root' not in subprocess.check_output( - self._adb_command(['root']))): - # Wait for adbd to restart. - subprocess.check_call( - self._adb_command(['wait-for-device']), - stdout=self.verbose_pipe) - self.adb_running_as_root = True - else: - self.adb_running_as_root = False - - return self.adb_running_as_root - - def _is_shell_package_installed(self): - # Adb should print one line if the package is installed and return empty - # string otherwise. - return len(subprocess.check_output(self._adb_command([ - 'shell', 'pm', 'list', 'packages', _MOJO_SHELL_PACKAGE_NAME]))) > 0 - - def check_device(self): - """Verifies if the device configuration allows adb to run. - - If a target device was indicated in the constructor, it checks that the - device is available. Otherwise, it checks that there is exactly one - available device. - - Returns: - A tuple of (result, msg). |result| is True iff if the device is correctly - configured and False otherwise. |msg| is the reason for failure if - |result| is False and None otherwise. - """ - adb_devices_output = subprocess.check_output( - self._adb_command(['devices'])) - # Skip the header line, strip empty lines at the end. - device_list = [line.strip() for line in adb_devices_output.split('\n')[1:] - if line.strip()] - - if self.target_device: - if any([line.startswith(self.target_device) and - line.endswith('device') for line in device_list]): - return True, None - else: - return False, 'Cannot connect to the selected device.' - - if len(device_list) > 1: - return False, ('More than one device connected and target device not ' - 'specified.') - - if not len(device_list): - return False, 'No devices connected.' - - if not device_list[0].endswith('device'): - return False, 'Connected device is not available.' - - return True, None - - def install_apk(self, shell_apk_path): - """Installs the apk on the device. - - This method computes checksum of the APK and skips the installation if the - fingerprint matches the one saved on the device upon the previous - installation. - - Args: - shell_apk_path: Path to the shell Android binary. - """ - device_sha1_path = '/sdcard/%s/%s.sha1' % (_MOJO_SHELL_PACKAGE_NAME, - 'MojoShell') - apk_sha1 = hashlib.sha1(open(shell_apk_path, 'rb').read()).hexdigest() - device_apk_sha1 = subprocess.check_output(self._adb_command([ - 'shell', 'cat', device_sha1_path])) - do_install = (apk_sha1 != device_apk_sha1 or - not self._is_shell_package_installed()) - - if do_install: - subprocess.check_call( - self._adb_command(['install', '-r', shell_apk_path, '-i', - _MOJO_SHELL_PACKAGE_NAME]), - stdout=self.verbose_pipe) - - # Update the stamp on the device. - with tempfile.NamedTemporaryFile() as fp: - fp.write(apk_sha1) - fp.flush() - subprocess.check_call(self._adb_command(['push', fp.name, - device_sha1_path]), - stdout=self.verbose_pipe) - else: - # To ensure predictable state after running install_apk(), we need to stop - # the shell here, as this is what "adb install" implicitly does. - self.stop_shell() - - def start_shell(self, - arguments, - stdout=None, - on_application_stop=None): - """Starts the mojo shell, passing it the given arguments. - - Args: - arguments: List of arguments for the shell. It must contain the - "--origin=" arg. shell_arguments.configure_local_origin() can be used - to set up a local directory on the host machine as origin. - stdout: Valid argument for subprocess.Popen() or None. - """ - if not self.stop_shell_registered: - atexit.register(self.stop_shell) - self.stop_shell_registered = True - - STDOUT_PIPE = "/data/data/%s/stdout.fifo" % _MOJO_SHELL_PACKAGE_NAME - - cmd = self._adb_command(['shell', 'am', 'start', - '-S', - '-a', 'android.intent.action.VIEW', - '-n', '%s/.MojoShellActivity' % - _MOJO_SHELL_PACKAGE_NAME]) - - parameters = [] - if stdout or on_application_stop: - # We need to run as root to access the fifo file we use for stdout - # redirection. - if self._run_adb_as_root(): - # Remove any leftover fifo file after the previous run. - subprocess.check_call(self._adb_command( - ['shell', 'rm', '-f', STDOUT_PIPE])) - - parameters.append('--fifo-path=%s' % STDOUT_PIPE) - self._read_fifo(STDOUT_PIPE, stdout, on_application_stop) - else: - _logger.warning("Running without root access, full stdout of the " - "shell won't be available.") - # The origin has to be specified whether it's local or external. - assert any("--origin=" in arg for arg in arguments) - parameters.extend(arguments) - - if parameters: - encodedParameters = json.dumps(parameters) - cmd += ['--es', 'encodedParameters', encodedParameters] - - subprocess.check_call(cmd, stdout=self.verbose_pipe) - - def stop_shell(self): - """Stops the mojo shell.""" - subprocess.check_call(self._adb_command(['shell', - 'am', - 'force-stop', - _MOJO_SHELL_PACKAGE_NAME])) - - def clean_logs(self): - """Cleans the logs on the device.""" - subprocess.check_call(self._adb_command(['logcat', '-c'])) - - def show_logs(self, include_native_logs=True): - """Displays the log for the mojo shell. - - Returns: - The process responsible for reading the logs. - """ - tags = _LOGCAT_JAVA_TAGS - if include_native_logs: - tags.extend(_LOGCAT_NATIVE_TAGS) - if self.additional_logcat_tags is not None: - tags.extend(self.additional_logcat_tags.split(",")) - logcat = subprocess.Popen( - self._adb_command(['logcat', '-s', ' '.join(tags)]), - stdout=sys.stdout) - atexit.register(_exit_if_needed, logcat) - return logcat - - def forward_observatory_ports(self): - """Forwards the ports used by the dart observatories to the host machine. - """ - logcat = subprocess.Popen(self._adb_command(['logcat']), - stdout=subprocess.PIPE) - atexit.register(_exit_if_needed, logcat) - - def _forward_observatories_as_needed(): - while True: - line = logcat.stdout.readline() - if not line: - break - match = re.search(r'Observatory listening on http://127.0.0.1:(\d+)', - line) - if match: - device_port = int(match.group(1)) - host_port = self._forward_host_port_to_device(0, device_port) - print ("Dart observatory available at the host at http://127.0.0.1:%d" - % host_port) - - logcat_watch_thread = threading.Thread( - target=_forward_observatories_as_needed) - logcat_watch_thread.start() - - @overrides(Shell) - def serve_local_directory(self, local_dir_path, port=0): - assert local_dir_path - mappings = [('', [local_dir_path])] - server_address = start_http_server(mappings, host_port=port) - - return 'http://127.0.0.1:%d/' % self._forward_device_port_to_host( - port, server_address[1]) - - @overrides(Shell) - def serve_local_directories(self, mappings, port=0): - assert mappings - server_address = start_http_server(mappings, host_port=port) - - return 'http://127.0.0.1:%d/' % self._forward_device_port_to_host( - port, server_address[1]) - - @overrides(Shell) - def forward_host_port_to_shell(self, host_port): - self._forward_host_port_to_device(host_port, host_port) - - @overrides(Shell) - def run(self, arguments): - self.clean_logs() - self.forward_observatory_ports() - - # If we are running as root, don't carry over the native logs from logcat - - # we will have these in the stdout. - p = self.show_logs(include_native_logs=(not self._run_adb_as_root())) - self.start_shell(arguments, sys.stdout, p.terminate) - p.wait() - return None - - @overrides(Shell) - def run_and_get_output(self, arguments, timeout=None): - class Results: - """Workaround for Python scoping rules that prevent assigning to variables - from the outer scope. - """ - output = None - - def do_run(): - (r, w) = os.pipe() - with os.fdopen(r, "r") as rf: - with os.fdopen(w, "w") as wf: - self.start_shell(arguments, wf, wf.close) - Results.output = rf.read() - - run_thread = threading.Thread(target=do_run) - run_thread.start() - run_thread.join(timeout) - - if run_thread.is_alive(): - self.stop_shell() - return None, Results.output, True - return None, Results.output, False diff --git a/mojo/devtools/common/devtoolslib/apptest.py b/mojo/devtools/common/devtoolslib/apptest.py deleted file mode 100644 index 59e23e2e007b9..0000000000000 --- a/mojo/devtools/common/devtoolslib/apptest.py +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright 2015 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. - -"""Apptest is a Mojo application that interacts with another Mojo application -and verifies assumptions about behavior of the app being tested. -""" - -import logging -import time - - -_logger = logging.getLogger() - - -def _build_shell_arguments(shell_args, apptest_url, apptest_args): - """Builds the list of arguments for the shell. - - Args: - shell_args: List of arguments for the shell run. - apptest_url: Url of the apptest app to run. - apptest_args: Parameters to be passed to the apptest app. - - Returns: - Single list of shell arguments. - """ - result = list(shell_args) - if apptest_args: - result.append("--args-for=%s %s" % (apptest_url, " ".join(apptest_args))) - result.append(apptest_url) - return result - - -def run_apptest(shell, shell_args, apptest_url, apptest_args, timeout, - output_test): - """Runs shell with the given arguments, retrieves the output and applies - |output_test| to determine if the run was successful. - - Args: - shell: Wrapper around concrete Mojo shell, implementing devtools Shell - interface. - shell_args: List of arguments for the shell run. - apptest_url: Url of the apptest app to run. - apptest_args: Parameters to be passed to the apptest app. - output_test: Function accepting the shell output and returning True iff - the output indicates a successful run. - - Returns: - True iff the test succeeded, False otherwise. - """ - arguments = _build_shell_arguments(shell_args, apptest_url, apptest_args) - command_line = "mojo_shell " + " ".join(["%r" % x for x in arguments]) - - _logger.debug("Starting: " + command_line) - start_time = time.time() - (exit_code, output, did_time_out) = shell.run_and_get_output(arguments, - timeout) - run_time = time.time() - start_time - _logger.debug("Completed: " + command_line) - - # Only log if it took more than 3 second. - if run_time >= 3: - _logger.info("Test took %.3f seconds: %s" % (run_time, command_line)) - - if exit_code or did_time_out or not output_test(output): - print 'Failed test: %r' % command_line - if exit_code: - print ' due to shell exit code %d' % exit_code - elif did_time_out: - print ' due to exceeded timeout of %fs' % timeout - else: - print ' due to test results' - print 72 * '-' - print output - print 72 * '-' - return False - return True diff --git a/mojo/devtools/common/devtoolslib/apptest_dart.py b/mojo/devtools/common/devtoolslib/apptest_dart.py deleted file mode 100644 index fe6131f8ac085..0000000000000 --- a/mojo/devtools/common/devtoolslib/apptest_dart.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2014 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. - -"""Apptest runner specific to the particular Dart apptest framework in -/mojo/dart/apptests, built on top of the general apptest runner.""" - -import logging -import re - -_logging = logging.getLogger() - -from devtoolslib.apptest import run_apptest - -SUCCESS_PATTERN = re.compile('^.+ .+: All tests passed!', re.MULTILINE) - - -def _dart_apptest_output_test(output): - return SUCCESS_PATTERN.search(output) is not None - - -# TODO(erg): Support android, launched services and fixture isolation. -def run_dart_apptest(shell, shell_args, apptest_url, apptest_args, timeout): - """Runs a dart apptest. - - Args: - shell_args: The arguments for mojo_shell. - apptest_url: Url of the apptest app to run. - apptest_args: Parameters to be passed to the apptest app. - - Returns: - True iff the test succeeded, False otherwise. - """ - return run_apptest(shell, shell_args, apptest_url, apptest_args, timeout, - _dart_apptest_output_test) diff --git a/mojo/devtools/common/devtoolslib/apptest_gtest.py b/mojo/devtools/common/devtoolslib/apptest_gtest.py deleted file mode 100644 index fefeab732470e..0000000000000 --- a/mojo/devtools/common/devtoolslib/apptest_gtest.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright 2014 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. - -"""Apptest runner specific to the particular gtest-based apptest framework in -/mojo/public/cpp/application/tests/, built on top of the general apptest -runner.""" - -import logging -import re - -from devtoolslib.apptest import run_apptest - - -_logger = logging.getLogger() - - -def _gtest_apptest_output_test(output): - # Fail on output with gtest's "[ FAILED ]" or a lack of "[ PASSED ]". - # The latter condition ensures failure on broken command lines or output. - # Check output instead of exit codes because mojo_shell always exits with 0. - if (output is None or - (output.find("[ FAILED ]") != -1 or output.find("[ PASSED ]") == -1)): - return False - return True - - -def run_gtest_apptest(shell, shell_args, apptest_url, apptest_args, timeout, - isolate): - """Runs a gtest apptest. - - Args: - shell: Wrapper around concrete Mojo shell, implementing devtools Shell - interface. - shell_args: The arguments for mojo_shell. - apptest_url: Url of the apptest app to run. - apptest_args: Parameters to be passed to the apptest app. - isolate: Iff True, each test in the app will be run in a separate shell run. - - Returns: - True iff the test succeeded, False otherwise. - """ - - if not isolate: - return run_apptest(shell, shell_args, apptest_url, apptest_args, timeout, - _gtest_apptest_output_test) - - # List the apptest fixtures so they can be run independently for isolation. - fixtures = get_fixtures(shell, shell_args, apptest_url) - if not fixtures: - print "No tests to run found in %s." % apptest_url - return False - - apptest_result = True - for fixture in fixtures: - isolated_apptest_args = apptest_args + ["--gtest_filter=%s" % fixture] - success = run_apptest(shell, shell_args, apptest_url, isolated_apptest_args, - timeout, _gtest_apptest_output_test) - - if not success: - apptest_result = False - - return apptest_result - - -def get_fixtures(shell, shell_args, apptest): - """Returns the "Test.Fixture" list from an apptest using mojo_shell. - - Tests are listed by running the given apptest in mojo_shell and passing - --gtest_list_tests. The output is parsed and reformatted into a list like - [TestSuite.TestFixture, ... ] - An empty list is returned on failure, with errors logged. - - Args: - apptest: The URL of the test application to run. - """ - arguments = [] - arguments.extend(shell_args) - arguments.append("--args-for=%s %s" % (apptest, "--gtest_list_tests")) - arguments.append(apptest) - - (exit_code, output, did_time_out) = shell.run_and_get_output(arguments) - if exit_code or did_time_out: - command_line = "mojo_shell " + " ".join(["%r" % x for x in arguments]) - print "Failed to get test fixtures: %r" % command_line - print 72 * '-' - print output - print 72 * '-' - return [] - - _logger.debug("Tests listed:\n%s" % output) - return _gtest_list_tests(output) - - -def _gtest_list_tests(gtest_list_tests_output): - """Returns a list of strings formatted as TestSuite.TestFixture from the - output of running --gtest_list_tests on a GTEST application.""" - - # Remove log lines. - gtest_list_tests_output = re.sub("^(\[|WARNING: linker:).*\n", - "", - gtest_list_tests_output, - flags=re.MULTILINE) - - if not re.match("^(\w*\.\r?\n( \w*\r?\n)+)+", gtest_list_tests_output): - raise Exception("Unrecognized --gtest_list_tests output:\n%s" % - gtest_list_tests_output) - - output_lines = gtest_list_tests_output.split("\n") - - test_list = [] - for line in output_lines: - if not line: - continue - if line[0] != " ": - suite = line.strip() - continue - test_list.append(suite + line.strip()) - - return test_list diff --git a/mojo/devtools/common/devtoolslib/apptest_gtest_unittest.py b/mojo/devtools/common/devtoolslib/apptest_gtest_unittest.py deleted file mode 100644 index db55a300dba6f..0000000000000 --- a/mojo/devtools/common/devtoolslib/apptest_gtest_unittest.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2014 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. - -import imp -import os.path -import sys -import unittest - -try: - imp.find_module("devtoolslib") -except ImportError: - sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -from devtoolslib.apptest_gtest import _gtest_list_tests - - -class GTestListTestsTest(unittest.TestCase): - """Tests |_gtest_list_tests()| handling of --gtest_list_tests output.""" - - def testSingleSuiteAndFixture(self): - """Tests a single suite with a single fixture.""" - gtest_output = "TestSuite.\n TestFixture\n" - expected_test_list = ["TestSuite.TestFixture"] - self.assertEquals(_gtest_list_tests(gtest_output), expected_test_list) - - def testWindowsNewlines(self): - """Tests handling of \r\n newlines.""" - gtest_output = "TestSuite.\r\n TestFixture1\r\n" - expected_test_list = ["TestSuite.TestFixture1"] - self.assertEquals(_gtest_list_tests(gtest_output), expected_test_list) - - def testSingleSuiteAndMultipleFixtures(self): - """Tests a single suite with multiple fixtures.""" - gtest_output = "TestSuite.\n TestFixture1\n TestFixture2\n" - expected_test_list = ["TestSuite.TestFixture1", "TestSuite.TestFixture2"] - self.assertEquals(_gtest_list_tests(gtest_output), expected_test_list) - - def testMultipleSuitesAndFixtures(self): - """Tests multiple suites each with multiple fixtures.""" - gtest_output = ("TestSuite1.\n TestFixture1\n TestFixture2\n" - "TestSuite2.\n TestFixtureA\n TestFixtureB\n") - expected_test_list = ["TestSuite1.TestFixture1", "TestSuite1.TestFixture2", - "TestSuite2.TestFixtureA", "TestSuite2.TestFixtureB"] - self.assertEquals(_gtest_list_tests(gtest_output), expected_test_list) - - def testUnrecognizedFormats(self): - """Tests examples of unrecognized --gtest_list_tests output.""" - self.assertRaises(Exception, _gtest_list_tests, "Foo") - self.assertRaises(Exception, _gtest_list_tests, "Foo\n") - self.assertRaises(Exception, _gtest_list_tests, "Foo.Bar\n") - self.assertRaises(Exception, _gtest_list_tests, "Foo.\nBar\n") - self.assertRaises(Exception, _gtest_list_tests, "Foo.\r\nBar\r\nGaz\r\n") - self.assertRaises(Exception, _gtest_list_tests, "Foo.\nBar.\n Gaz\n") - - -if __name__ == "__main__": - unittest.main() diff --git a/mojo/devtools/common/devtoolslib/http_server.py b/mojo/devtools/common/devtoolslib/http_server.py deleted file mode 100644 index 482e2db53108f..0000000000000 --- a/mojo/devtools/common/devtoolslib/http_server.py +++ /dev/null @@ -1,223 +0,0 @@ -# Copyright 2015 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. - -import atexit -import datetime -import email.utils -import errno -import gzip -import hashlib -import logging -import math -import os.path -import shutil -import socket -import threading -import tempfile - -import SimpleHTTPServer -import SocketServer - -_ZERO = datetime.timedelta(0) - - -class UTC_TZINFO(datetime.tzinfo): - """UTC time zone representation.""" - - def utcoffset(self, _): - return _ZERO - - def tzname(self, _): - return "UTC" - - def dst(self, _): - return _ZERO - -_UTC = UTC_TZINFO() - - -class _SilentTCPServer(SocketServer.TCPServer): - """A TCPServer that won't display any error, unless debugging is enabled. This - is useful because the client might stop while it is fetching an URL, which - causes spurious error messages. - """ - allow_reuse_address = True - - def handle_error(self, request, client_address): - """Override the base class method to have conditional logging.""" - if logging.getLogger().isEnabledFor(logging.DEBUG): - SocketServer.TCPServer.handle_error(self, request, client_address) - - -def _get_handler_class_for_path(mappings): - """Creates a handler override for SimpleHTTPServer. - - Args: - mappings: List of tuples (prefix, local_base_path_list) mapping URLs that - start with |prefix| to one or more local directories enumerated in - |local_base_path_list|. The prefixes should skip the leading slash. - The first matching prefix and the first location that contains the - requested file will be used each time. - """ - for prefix, _ in mappings: - assert not prefix.startswith('/'), ('Prefixes for the http server mappings ' - 'should skip the leading slash.') - - class RequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): - """Handler for SocketServer.TCPServer that will serve the files from - local directiories over http. - - A new instance is created for each request. - """ - - def __init__(self, *args, **kwargs): - self.etag = None - self.gzipped_file = None - SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, *args, **kwargs) - - def get_etag(self): - if self.etag: - return self.etag - - path = self.translate_path(self.path, False) - if not os.path.isfile(path): - return None - - sha256 = hashlib.sha256() - BLOCKSIZE = 65536 - with open(path, 'rb') as hashed: - buf = hashed.read(BLOCKSIZE) - while len(buf) > 0: - sha256.update(buf) - buf = hashed.read(BLOCKSIZE) - self.etag = '"%s"' % sha256.hexdigest() - return self.etag - - def send_head(self): - # Always close the connection after each request, as the keep alive - # support from SimpleHTTPServer doesn't like when the client requests to - # close the connection before downloading the full response content. - # pylint: disable=W0201 - self.close_connection = 1 - - path = self.translate_path(self.path) - if os.path.isfile(path): - # Handle If-None-Match - etag = self.get_etag() - if ('If-None-Match' in self.headers and - etag == self.headers['If-None-Match']): - self.send_response(304) - return None - - # Handle If-Modified-Since - if ('If-None-Match' not in self.headers and - 'If-Modified-Since' in self.headers): - last_modified = datetime.datetime.fromtimestamp( - math.floor(os.stat(path).st_mtime), tz=_UTC) - ims = datetime.datetime( - *email.utils.parsedate(self.headers['If-Modified-Since'])[:6], - tzinfo=_UTC) - if last_modified <= ims: - self.send_response(304) - return None - - return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self) - - def end_headers(self): - path = self.translate_path(self.path) - - if os.path.isfile(path): - self.send_header('Content-Encoding', 'gzip') - etag = self.get_etag() - if etag: - self.send_header('ETag', etag) - self.send_header('Cache-Control', 'must-revalidate') - - return SimpleHTTPServer.SimpleHTTPRequestHandler.end_headers(self) - - # pylint: disable=W0221 - def translate_path(self, path, gzipped=True): - # Parent translate_path() will strip away the query string and fragment - # identifier, but also will prepend the cwd to the path. relpath() gives - # us the relative path back. - normalized_path = os.path.relpath( - SimpleHTTPServer.SimpleHTTPRequestHandler.translate_path(self, path)) - - for prefix, local_base_path_list in mappings: - if normalized_path.startswith(prefix): - for local_base_path in local_base_path_list: - candidate = os.path.join(local_base_path, - normalized_path[len(prefix):]) - if os.path.isfile(candidate): - if gzipped: - if not self.gzipped_file: - self.gzipped_file = tempfile.NamedTemporaryFile(delete=False) - with open(candidate, 'rb') as source: - with gzip.GzipFile(fileobj=self.gzipped_file) as target: - shutil.copyfileobj(source, target) - self.gzipped_file.close() - return self.gzipped_file.name - return candidate - else: - self.send_response(404) - return None - self.send_response(404) - return None - - def guess_type(self, path): - # This is needed so that exploded Sky apps without shebang can still run - # thanks to content-type mappings. - # TODO(ppi): drop this part once we can rely on the Sky files declaring - # correct shebang. - if path.endswith('.dart') or path.endswith('.dart.gz'): - return 'application/dart' - return SimpleHTTPServer.SimpleHTTPRequestHandler.guess_type(self, path) - - def log_message(self, *_): - """Override the base class method to disable logging.""" - pass - - def __del__(self): - if self.gzipped_file: - os.remove(self.gzipped_file.name) - - RequestHandler.protocol_version = 'HTTP/1.1' - return RequestHandler - - -def start_http_server(mappings, host_port=0): - """Starts an http server serving files from |local_dir_path| on |host_port|. - - Args: - mappings: List of tuples (prefix, local_base_path_list) mapping URLs that - start with |prefix| to one or more local directories enumerated in - |local_base_path_list|. The prefixes should skip the leading slash. - The first matching prefix and the first location that contains the - requested file will be used each time. - host_port: Port on the host machine to run the server on. Pass 0 to use a - system-assigned port. - - Returns: - Tuple of the server address and the port on which it runs. - """ - assert mappings - handler_class = _get_handler_class_for_path(mappings) - - try: - httpd = _SilentTCPServer(('127.0.0.1', host_port), handler_class) - atexit.register(httpd.shutdown) - - http_thread = threading.Thread(target=httpd.serve_forever) - http_thread.daemon = True - http_thread.start() - return httpd.server_address - except socket.error as v: - error_code = v[0] - print 'Failed to start http server for %s on port %d: %s.' % ( - str(mappings), host_port, os.strerror(error_code)) - if error_code == errno.EADDRINUSE: - print (' Run `fuser %d/tcp` to find out which process is using the port.' - % host_port) - print '---' - raise diff --git a/mojo/devtools/common/devtoolslib/http_server_unittest.py b/mojo/devtools/common/devtoolslib/http_server_unittest.py deleted file mode 100644 index f279712ce63b1..0000000000000 --- a/mojo/devtools/common/devtoolslib/http_server_unittest.py +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright 2015 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. - -import StringIO -import gzip -import imp -import os.path -import shutil -import sys -import tempfile -import unittest -import urllib2 - -try: - imp.find_module('devtoolslib') -except ImportError: - sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - -from devtoolslib import http_server - - -class HttpServerTest(unittest.TestCase): - """Tests for the http_server module.""" - - def setUp(self): - """Creates a tree of temporary directories and files of the form described - below. - - parent_dir - hello_dir - hello_subdir - hello_file - other_dir - other_file - """ - self.parent_dir = tempfile.mkdtemp() - self.parent_file = tempfile.NamedTemporaryFile(delete=False, - dir=self.parent_dir) - self.hello_dir = tempfile.mkdtemp(dir=self.parent_dir) - self.hello_subdir = tempfile.mkdtemp(dir=self.hello_dir) - self.hello_file = tempfile.NamedTemporaryFile(delete=False, - dir=self.hello_subdir) - self.hello_file.write('hello') - self.hello_file.close() - - self.other_dir = tempfile.mkdtemp(dir=self.parent_dir) - self.other_file = tempfile.NamedTemporaryFile(delete=False, - dir=self.other_dir) - - def tearDown(self): - shutil.rmtree(self.parent_dir) - - def test_mappings(self): - """Maps two directories and verifies that the server serves files placed - there. - """ - mappings = [ - ('hello/', [self.hello_dir]), - ('other/', [self.other_dir]), - ] - server_address = ('http://%s:%u/' % - http_server.start_http_server(mappings)) - - hello_relpath = os.path.relpath(self.hello_file.name, self.hello_dir) - hello_response = urllib2.urlopen(server_address + 'hello/' + - hello_relpath) - self.assertEquals(200, hello_response.getcode()) - - other_relpath = os.path.relpath(self.other_file.name, self.other_dir) - other_response = urllib2.urlopen(server_address + 'other/' + - other_relpath) - self.assertEquals(200, other_response.getcode()) - - def test_unmapped_path(self): - """Verifies that the server returns 404 when a request for unmapped url - prefix is made. - """ - mappings = [ - ('hello/', [self.hello_dir]), - ] - server_address = ('http://%s:%u/' % - http_server.start_http_server(mappings)) - - error_code = None - try: - urllib2.urlopen(server_address + 'unmapped/abc') - except urllib2.HTTPError as error: - error_code = error.code - self.assertEquals(404, error_code) - - def test_multiple_paths(self): - """Verfies mapping multiple local paths under the same url prefix.""" - mappings = [ - ('singularity/', [self.hello_dir, self.other_dir]), - ] - server_address = ('http://%s:%u/' % - http_server.start_http_server(mappings)) - - hello_relpath = os.path.relpath(self.hello_file.name, self.hello_dir) - hello_response = urllib2.urlopen(server_address + 'singularity/' + - hello_relpath) - self.assertEquals(200, hello_response.getcode()) - - other_relpath = os.path.relpath(self.other_file.name, self.other_dir) - other_response = urllib2.urlopen(server_address + 'singularity/' + - other_relpath) - self.assertEquals(200, other_response.getcode()) - - # Verify that a request for a file not present under any of the mapped - # directories results in 404. - error_code = None - try: - urllib2.urlopen(server_address + 'singularity/unavailable') - except urllib2.HTTPError as error: - error_code = error.code - self.assertEquals(404, error_code) - - def test_gzip(self): - """Verifies the gzip content encoding of the files being served.""" - mappings = [ - ('hello/', [self.hello_dir]), - ] - server_address = ('http://%s:%u/' % - http_server.start_http_server(mappings)) - - hello_relpath = os.path.relpath(self.hello_file.name, self.hello_dir) - hello_response = urllib2.urlopen(server_address + 'hello/' + - hello_relpath) - self.assertEquals(200, hello_response.getcode()) - self.assertTrue('Content-Encoding' in hello_response.info()) - self.assertEquals('gzip', hello_response.info().get('Content-Encoding')) - - content = gzip.GzipFile( - fileobj=StringIO.StringIO(hello_response.read())).read() - self.assertEquals('hello', content) - - -if __name__ == "__main__": - unittest.main() diff --git a/mojo/devtools/common/devtoolslib/linux_shell.py b/mojo/devtools/common/devtoolslib/linux_shell.py deleted file mode 100644 index dedee5b3f5ccc..0000000000000 --- a/mojo/devtools/common/devtoolslib/linux_shell.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2015 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. - -import subprocess -import threading - -from devtoolslib import http_server -from devtoolslib.shell import Shell -from devtoolslib.utils import overrides - - -class LinuxShell(Shell): - """Wrapper around Mojo shell running on Linux. - - Args: - executable_path: path to the shell binary - command_prefix: optional list of arguments to prepend to the shell command, - allowing e.g. to run the shell under debugger. - """ - - def __init__(self, executable_path, command_prefix=None): - self.executable_path = executable_path - self.command_prefix = command_prefix if command_prefix else [] - - @overrides(Shell) - def serve_local_directory(self, local_dir_path, port=0): - mappings = [('', [local_dir_path])] - return 'http://%s:%d/' % http_server.start_http_server(mappings, port) - - @overrides(Shell) - def serve_local_directories(self, mappings, port=0): - return 'http://%s:%d/' % http_server.start_http_server(mappings, port) - - @overrides(Shell) - def forward_host_port_to_shell(self, host_port): - pass - - @overrides(Shell) - def run(self, arguments): - command = self.command_prefix + [self.executable_path] + arguments - return subprocess.call(command, stderr=subprocess.STDOUT) - - @overrides(Shell) - def run_and_get_output(self, arguments, timeout=None): - command = self.command_prefix + [self.executable_path] + arguments - p = subprocess.Popen(command, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - - class Results: - """Workaround for Python scoping rules that prevent assigning to variables - from the outer scope. - """ - output = None - - def do_run(): - (Results.output, _) = p.communicate() - - run_thread = threading.Thread(target=do_run) - run_thread.start() - run_thread.join(timeout) - - if run_thread.is_alive(): - p.terminate() - return p.returncode, Results.output, True - return p.returncode, Results.output, False diff --git a/mojo/devtools/common/devtoolslib/paths.py b/mojo/devtools/common/devtoolslib/paths.py deleted file mode 100644 index 502636a06d768..0000000000000 --- a/mojo/devtools/common/devtoolslib/paths.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright 2015 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. - -"""Supports inferring locations of files in default checkout layouts. - -These functions allow devtools scripts to work out-of-the-box with regular Mojo -checkouts. -""" - -import collections -import os.path -import sys - - -def find_ancestor_with(relpath, start_path=None): - """Returns the lowest ancestor of this file that contains |relpath|.""" - cur_dir_path = start_path or os.path.abspath(os.path.dirname(__file__)) - while True: - if os.path.exists(os.path.join(cur_dir_path, relpath)): - return cur_dir_path - - next_dir_path = os.path.dirname(cur_dir_path) - if next_dir_path != cur_dir_path: - cur_dir_path = next_dir_path - else: - return None - - -def find_within_ancestors(target_relpath, start_path=None): - """Returns the absolute path to |target_relpath| in the lowest ancestor of - |start_path| that contains it. - """ - ancestor = find_ancestor_with(target_relpath, start_path) - if not ancestor: - return None - return os.path.join(ancestor, target_relpath) - - -def infer_paths(is_android, is_debug, target_cpu): - """Infers the locations of select build output artifacts in a regular - Chromium-like checkout. This should grow thinner or disappear as we introduce - per-repo config files, see https://github.com/domokit/devtools/issues/28. - - Returns: - Defaultdict with the inferred paths. - """ - build_dir = (('android_' if is_android else '') + - (target_cpu + '_' if target_cpu else '') + - ('Debug' if is_debug else 'Release')) - out_build_dir = os.path.join('out', build_dir) - - root_path = find_ancestor_with(out_build_dir) - paths = collections.defaultdict(lambda: None) - if not root_path: - return paths - - build_dir_path = os.path.join(root_path, out_build_dir) - paths['build_dir_path'] = build_dir_path - if is_android: - paths['shell_path'] = os.path.join(build_dir_path, 'apks', 'MojoShell.apk') - paths['adb_path'] = os.path.join(root_path, 'third_party', 'android_tools', - 'sdk', 'platform-tools', 'adb') - else: - paths['shell_path'] = os.path.join(build_dir_path, 'mojo_shell') - return paths - - -# Based on Chromium //tools/find_depot_tools.py. -def find_depot_tools(): - """Searches for depot_tools. - - Returns: - Path to the depot_tools checkout present on the machine, None if not found. - """ - def _is_real_depot_tools(path): - return os.path.isfile(os.path.join(path, 'gclient.py')) - - # First look if depot_tools is already in PYTHONPATH. - for i in sys.path: - if i.rstrip(os.sep).endswith('depot_tools') and _is_real_depot_tools(i): - return i - # Then look if depot_tools is in PATH, common case. - for i in os.environ['PATH'].split(os.pathsep): - if _is_real_depot_tools(i): - return i - # Rare case, it's not even in PATH, look upward up to root. - root_dir = os.path.dirname(os.path.abspath(__file__)) - previous_dir = os.path.abspath(__file__) - while root_dir and root_dir != previous_dir: - i = os.path.join(root_dir, 'depot_tools') - if _is_real_depot_tools(i): - return i - previous_dir = root_dir - root_dir = os.path.dirname(root_dir) - return None diff --git a/mojo/devtools/common/devtoolslib/shell.py b/mojo/devtools/common/devtoolslib/shell.py deleted file mode 100644 index c142611f15803..0000000000000 --- a/mojo/devtools/common/devtoolslib/shell.py +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright 2015 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. - - -class Shell(object): - """Represents an abstract Mojo shell.""" - - def serve_local_directory(self, local_dir_path, port=0): - """Serves the content of the local (host) directory, making it available to - the shell under the url returned by the function. - - The server will run on a separate thread until the program terminates. The - call returns immediately. - - Args: - local_dir_path: path to the directory to be served - port: port at which the server will be available to the shell - - Returns: - The url that the shell can use to access the content of |local_dir_path|. - """ - raise NotImplementedError() - - def serve_local_directories(self, mappings, port=0): - """Serves the content of the local (host) directories, making it available - to the shell under the url returned by the function. - - The server will run on a separate thread until the program terminates. The - call returns immediately. - - Args: - mappings: List of tuples (prefix, local_base_path_list) mapping URLs that - start with |prefix| to one or more local directories enumerated in - |local_base_path_list|. The prefixes should skip the leading slash. - The first matching prefix and the first location that contains the - requested file will be used each time. - port: port at which the server will be available to the shell - - Returns: - The url that the shell can use to access the server. - """ - raise NotImplementedError() - - def forward_host_port_to_shell(self, host_port): - """Forwards a port on the host machine to the same port wherever the shell - is running. - - This is a no-op if the shell is running locally. - """ - raise NotImplementedError() - - def run(self, arguments): - """Runs the shell with given arguments until shell exits, passing the stdout - mingled with stderr produced by the shell onto the stdout. - - Returns: - Exit code retured by the shell or None if the exit code cannot be - retrieved. - """ - raise NotImplementedError() - - def run_and_get_output(self, arguments, timeout=None): - """Runs the shell with given arguments until shell exits and returns the - output. - - Args: - arguments: list of arguments for the shell - timeout: maximum running time in seconds, after which the shell will be - terminated - - Returns: - A tuple of (return_code, output, did_time_out). |return_code| is the exit - code returned by the shell or None if the exit code cannot be retrieved. - |output| is the stdout mingled with the stderr produced by the shell. - |did_time_out| is True iff the shell was terminated because it exceeded - the |timeout| and False otherwise. - """ - raise NotImplementedError() diff --git a/mojo/devtools/common/devtoolslib/shell_arguments.py b/mojo/devtools/common/devtoolslib/shell_arguments.py deleted file mode 100644 index 3863935b4b0cf..0000000000000 --- a/mojo/devtools/common/devtoolslib/shell_arguments.py +++ /dev/null @@ -1,243 +0,0 @@ -# Copyright 2015 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. - -"""Produces configured shell abstractions. - -This module knows how to produce a configured shell abstraction based on -shell_config.ShellConfig. -""" - -import os.path -import sys -import urlparse - -from devtoolslib.android_shell import AndroidShell -from devtoolslib.linux_shell import LinuxShell -from devtoolslib.shell_config import ShellConfigurationException - -# When spinning up servers for local origins, we want to use predictable ports -# so that caching works between subsequent runs with the same command line. -_LOCAL_ORIGIN_PORT = 31840 -_MAPPINGS_BASE_PORT = 31841 - - -def _is_web_url(dest): - return True if urlparse.urlparse(dest).scheme else False - - -def _host_local_url_destination(shell, dest_file, port): - """Starts a local server to host |dest_file|. - - Returns: - Url of the hosted file. - """ - directory = os.path.dirname(dest_file) - if not os.path.exists(directory): - raise ValueError('local path passed as --map-url destination ' - 'does not exist') - server_url = shell.serve_local_directory(directory, port) - return server_url + os.path.relpath(dest_file, directory) - - -def _host_local_origin_destination(shell, dest_dir, port): - """Starts a local server to host |dest_dir|. - - Returns: - Url of the hosted directory. - """ - return shell.serve_local_directory(dest_dir, port) - - -def _rewrite(mapping, host_destination_functon, shell, port): - """Takes a mapping given as = and rewrites the part to be - hosted locally using the given function if is not a web url. - """ - parts = mapping.split('=') - if len(parts) != 2: - raise ValueError('each mapping value should be in format ' - '"="') - if _is_web_url(parts[1]): - # The destination is a web url, do nothing. - return mapping - - src = parts[0] - dest = host_destination_functon(shell, parts[1], port) - return src + '=' + dest - - -def _apply_mappings(shell, original_arguments, map_urls, map_origins): - """Applies mappings for specified urls and origins. For each local path - specified as destination a local server will be spawned and the mapping will - be rewritten accordingly. - - Args: - shell: The shell that is being configured. - original_arguments: Current list of shell arguments. - map_urls: List of url mappings, each in the form of - =. - map_origins: List of origin mappings, each in the form of - =. - - Returns: - The updated argument list. - """ - next_port = _MAPPINGS_BASE_PORT - args = original_arguments - if map_urls: - # Sort the mappings to preserve caching regardless of argument order. - for map_url in sorted(map_urls): - mapping = _rewrite(map_url, _host_local_url_destination, shell, next_port) - next_port += 1 - # All url mappings need to be coalesced into one shell argument. - args = append_to_argument(args, '--url-mappings=', mapping) - - if map_origins: - for map_origin in sorted(map_origins): - mapping = _rewrite(map_origin, _host_local_origin_destination, shell, - next_port) - next_port += 1 - # Origin mappings are specified as separate, repeated shell arguments. - args.append('--map-origin=' + mapping) - return args - - -def _configure_sky(shell_args): - """Maps mojo:sky_viewer as a content handler for dart applications. - app. - - Args: - shell_args: Current list of shell arguments. - - Returns: - Updated list of shell arguments. - """ - # Configure the content type mappings for the sky_viewer. This is needed - # only for the Sky apps that do not declare mojo:sky_viewer in a shebang. - # TODO(ppi): drop this part once we can rely on the Sky files declaring - # correct shebang. - shell_args = append_to_argument(shell_args, '--content-handlers=', - 'text/sky,mojo:sky_viewer') - shell_args = append_to_argument(shell_args, '--content-handlers=', - 'application/dart,mojo:sky_viewer') - return shell_args - - -def configure_local_origin(shell, local_dir, fixed_port=True): - """Sets up a local http server to serve files in |local_dir| along with - device port forwarding if needed. - - Returns: - The list of arguments to be appended to the shell argument list. - """ - - origin_url = shell.serve_local_directory( - local_dir, _LOCAL_ORIGIN_PORT if fixed_port else 0) - return ["--origin=" + origin_url] - - -def append_to_argument(arguments, key, value, delimiter=","): - """Looks for an argument of the form "key=val1,val2" within |arguments| and - appends |value| to it. - - If the argument is not present in |arguments| it is added. - - Args: - arguments: List of arguments for the shell. - key: Identifier of the argument, including the equal sign, eg. - "--content-handlers=". - value: The value to be appended, after |delimeter|, to the argument. - delimiter: The string used to separate values within the argument. - - Returns: - The updated argument list. - """ - assert key and key.endswith('=') - assert value - - for i, argument in enumerate(arguments): - if not argument.startswith(key): - continue - arguments[i] = argument + delimiter + value - break - else: - arguments.append(key + value) - - return arguments - - -def _configure_dev_server(shell, shell_args, dev_server_config): - """Sets up a dev server on the host according to |dev_server_config|. - - Args: - shell: The shell that is being configured. - shell_arguments: Current list of shell arguments. - dev_server_config: Instance of shell_config.DevServerConfig describing the - dev server to be set up. - - Returns: - The updated argument list. - """ - server_url = shell.serve_local_directories(dev_server_config.mappings) - shell_args.append('--map-origin=%s=%s' % (dev_server_config.host, server_url)) - print "Configured %s locally to serve:" % (dev_server_config.host) - for mapping_prefix, mapping_path in dev_server_config.mappings: - print " /%s -> %s" % (mapping_prefix, mapping_path) - return shell_args - - -def get_shell(shell_config, shell_args): - """ - Produces a shell abstraction configured according to |shell_config|. - - Args: - shell_config: Instance of shell_config.ShellConfig. - shell_args: Additional raw shell arguments to be passed to the shell. We - need to take these into account as some parameters need to appear only - once on the argument list (e.g. url-mappings) so we need to coalesce any - overrides and the existing value into just one argument. - - Returns: - A tuple of (shell, shell_args). |shell| is the configured shell abstraction, - |shell_args| is updated list of shell arguments. - - Throws: - ShellConfigurationException if shell abstraction could not be configured. - """ - if shell_config.android: - verbose_pipe = sys.stdout if shell_config.verbose else None - - shell = AndroidShell(shell_config.adb_path, shell_config.target_device, - logcat_tags=shell_config.logcat_tags, - verbose_pipe=verbose_pipe) - - device_status, error = shell.check_device() - if not device_status: - raise ShellConfigurationException('Device check failed: ' + error) - if shell_config.shell_path: - shell.install_apk(shell_config.shell_path) - else: - if not shell_config.shell_path: - raise ShellConfigurationException('Can not run without a shell binary. ' - 'Please pass --shell-path.') - shell = LinuxShell(shell_config.shell_path) - if shell_config.use_osmesa: - shell_args.append('--args-for=mojo:native_viewport_service --use-osmesa') - - shell_args = _apply_mappings(shell, shell_args, shell_config.map_url_list, - shell_config.map_origin_list) - - if shell_config.origin: - if _is_web_url(shell_config.origin): - shell_args.append('--origin=' + shell_config.origin) - else: - shell_args.extend(configure_local_origin(shell, shell_config.origin, - fixed_port=True)) - - if shell_config.sky: - shell_args = _configure_sky(shell_args) - - for dev_server_config in shell_config.dev_servers: - shell_args = _configure_dev_server(shell, shell_args, dev_server_config) - - return shell, shell_args diff --git a/mojo/devtools/common/devtoolslib/shell_arguments_unittest.py b/mojo/devtools/common/devtoolslib/shell_arguments_unittest.py deleted file mode 100644 index f86b163ce8bc4..0000000000000 --- a/mojo/devtools/common/devtoolslib/shell_arguments_unittest.py +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2015 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. - -import imp -import os.path -import sys -import unittest - -try: - imp.find_module("devtoolslib") -except ImportError: - sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -from devtoolslib import shell_arguments - - -class AppendToArgumentTest(unittest.TestCase): - """Tests AppendToArgument().""" - - def test_append_to_empty(self): - arguments = [] - key = '--something=' - value = 'val' - expected_result = ['--something=val'] - self.assertEquals(expected_result, shell_arguments.append_to_argument( - arguments, key, value)) - - def test_append_to_non_empty(self): - arguments = ['--other'] - key = '--something=' - value = 'val' - expected_result = ['--other', '--something=val'] - self.assertEquals(expected_result, shell_arguments.append_to_argument( - arguments, key, value)) - - def test_append_to_existing(self): - arguments = ['--something=old_val'] - key = '--something=' - value = 'val' - expected_result = ['--something=old_val,val'] - self.assertEquals(expected_result, shell_arguments.append_to_argument( - arguments, key, value)) - - -if __name__ == "__main__": - unittest.main() diff --git a/mojo/devtools/common/devtoolslib/shell_config.py b/mojo/devtools/common/devtoolslib/shell_config.py deleted file mode 100644 index 2b55d54871713..0000000000000 --- a/mojo/devtools/common/devtoolslib/shell_config.py +++ /dev/null @@ -1,196 +0,0 @@ -# Copyright 2015 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. - -"""Configuration for the shell abstraction. - -This module declares ShellConfig and knows how to compute it from command-line -arguments, applying any default paths inferred from the checkout, configuration -file, etc. -""" - -import ast - -from devtoolslib import paths - - -class ShellConfigurationException(Exception): - """Represents an error preventing creating a functional shell abstraction.""" - pass - - -class ShellConfig(object): - """Configuration for the shell abstraction.""" - - def __init__(self): - self.android = None - self.shell_path = None - self.origin = None - self.map_url_list = [] - self.map_origin_list = [] - self.dev_servers = [] - self.sky = None - self.verbose = None - - # Android-only. - self.adb_path = None - self.target_device = None - self.logcat_tags = None - - # Desktop-only. - self.use_osmesa = None - - -class DevServerConfig(object): - """Configuration for a development server running on a host and available to - the shell. - """ - def __init__(self): - self.host = None - self.mappings = None - - -def add_shell_arguments(parser): - """Adds argparse arguments allowing to configure shell abstraction using - configure_shell() below. - """ - # Arguments configuring the shell run. - parser.add_argument('--android', help='Run on Android', - action='store_true') - parser.add_argument('--shell-path', help='Path of the Mojo shell binary.') - parser.add_argument('--origin', help='Origin for mojo: URLs. This can be a ' - 'web url or a local directory path.') - parser.add_argument('--map-url', action='append', - help='Define a mapping for a url in the format ' - '=') - parser.add_argument('--map-origin', action='append', - help='Define a mapping for a url origin in the format ' - '=') - parser.add_argument('--sky', action='store_true', - help='Maps mojo:sky_viewer as the content handler for ' - 'dart apps.') - parser.add_argument('-v', '--verbose', action="store_true", - help="Increase output verbosity") - - android_group = parser.add_argument_group('Android-only', - 'These arguments apply only when --android is passed.') - android_group.add_argument('--adb-path', help='Path of the adb binary.') - android_group.add_argument('--target-device', help='Device to run on.') - android_group.add_argument('--logcat-tags', help='Comma-separated list of ' - 'additional logcat tags to display.') - - desktop_group = parser.add_argument_group('Desktop-only', - 'These arguments apply only when running on desktop.') - desktop_group.add_argument('--use-osmesa', action='store_true', - help='Configure the native viewport service ' - 'for off-screen rendering.') - - config_file_group = parser.add_argument_group('Configuration file', - 'These arguments allow to modify the behavior regarding the mojoconfig ' - 'file.') - config_file_group.add_argument('--config-file', type=file, - help='Path of the configuration file to use.') - config_file_group.add_argument('--no-config-file', action='store_true', - help='Pass to skip automatic discovery of the ' - 'mojoconfig file.') - - # Arguments allowing to indicate the build directory we are targeting when - # running within a Chromium-like checkout (e.g. Mojo checkout). These will go - # away once we have devtools config files, see - # https://github.com/domokit/devtools/issues/28. - chromium_checkout_group = parser.add_argument_group( - 'Chromium-like checkout configuration', - 'These arguments allow to infer paths to tools and build results ' - 'when running within a Chromium-like checkout') - debug_group = chromium_checkout_group.add_mutually_exclusive_group() - debug_group.add_argument('--debug', help='Debug build (default)', - default=True, action='store_true') - debug_group.add_argument('--release', help='Release build', default=False, - dest='debug', action='store_false') - chromium_checkout_group.add_argument('--target-cpu', - help='CPU architecture to run for.', - choices=['x64', 'x86', 'arm']) - - -def _discover_config_file(): - config_file_path = paths.find_within_ancestors('mojoconfig') - if not config_file_path: - return None - return open(config_file_path, 'r') - - -def _read_config_file(config_file, aliases): - spec = config_file.read() - for alias_pattern, alias_value in aliases: - spec = spec.replace(alias_pattern, alias_value) - return ast.literal_eval(spec) - - -def get_shell_config(script_args): - """Processes command-line options defined in add_shell_arguments(), applying - any inferred default paths and produces an instance of ShellConfig. - - Returns: - An instance of ShellConfig. - """ - # Infer paths based on the Chromium configuration options - # (--debug/--release, etc.), if running within a Chromium-like checkout. - inferred_paths = paths.infer_paths(script_args.android, script_args.debug, - script_args.target_cpu) - shell_config = ShellConfig() - - shell_config.android = script_args.android - shell_config.shell_path = (script_args.shell_path or - inferred_paths['shell_path']) - shell_config.origin = script_args.origin - shell_config.map_url_list = script_args.map_url - shell_config.map_origin_list = script_args.map_origin - shell_config.sky = script_args.sky - shell_config.verbose = script_args.verbose - - # Android-only. - shell_config.adb_path = (script_args.adb_path or inferred_paths['adb_path']) - shell_config.target_device = script_args.target_device - shell_config.logcat_tags = script_args.logcat_tags - - # Desktop-only. - shell_config.use_osmesa = script_args.use_osmesa - - if (shell_config.android and not shell_config.origin and - inferred_paths['build_dir_path']): - shell_config.origin = inferred_paths['build_dir_path'] - - # Read the mojoconfig file. - config_file = script_args.config_file - if not script_args.no_config_file: - config_file = config_file or _discover_config_file() - - if config_file: - with config_file: - config_file_aliases = [] - if inferred_paths['build_dir_path']: - config_file_aliases.append(('@{BUILD_DIR}', - inferred_paths['build_dir_path'])) - - config = None - try: - if script_args.verbose: - print 'Reading config file from: ' + config_file.name - config = _read_config_file(config_file, config_file_aliases) - except SyntaxError: - raise ShellConfigurationException('Failed to parse the mojoconfig ' - 'file.') - - if 'dev_servers' in config: - try: - for dev_server_spec in config['dev_servers']: - dev_server_config = DevServerConfig() - dev_server_config.host = dev_server_spec['host'] - dev_server_config.mappings = [] - for prefix, path in dev_server_spec['mappings']: - dev_server_config.mappings.append((prefix, path)) - shell_config.dev_servers.append(dev_server_config) - except (ValueError, KeyError): - raise ShellConfigurationException('Failed to parse dev_servers in ' - 'the mojoconfig file.') - return shell_config diff --git a/mojo/devtools/common/devtoolslib/utils.py b/mojo/devtools/common/devtoolslib/utils.py deleted file mode 100644 index 7bf2e1c641221..0000000000000 --- a/mojo/devtools/common/devtoolslib/utils.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2015 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. - -"""Python utils.""" - - -def overrides(parent_class): - """Inherits the docstring from the method of the same name in the indicated - parent class. - """ - def overriding(method): - assert(method.__name__ in dir(parent_class)) - method.__doc__ = getattr(parent_class, method.__name__).__doc__ - return method - return overriding diff --git a/mojo/devtools/common/mojo_debug b/mojo/devtools/common/mojo_debug deleted file mode 100755 index fb4459f3bd5e0..0000000000000 --- a/mojo/devtools/common/mojo_debug +++ /dev/null @@ -1,330 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -import argparse -import codecs -import logging -import os.path -import requests -import signal -import subprocess -import sys -import tempfile - - -from android_gdb.install_remote_file_reader import install -from devtoolslib import paths - - -_MOJO_DEBUGGER_PORT = 7777 -_DEFAULT_PACKAGE_NAME = 'org.chromium.mojo.shell' - - -# TODO(etiennej): Refactor with similar methods in subdirectories -class DirectoryNotFoundException(Exception): - """Directory has not been found.""" - pass - - -def _get_dir_above(dirname): - """Returns the directory "above" this file containing |dirname|.""" - path = paths.find_ancestor_with(dirname) - if not path: - raise DirectoryNotFoundException(dirname) - return path - - -def _send_request(request, payload=None): - """Sends a request to mojo:debugger.""" - try: - url = 'http://localhost:%s/%s' % (_MOJO_DEBUGGER_PORT, request) - if payload: - return requests.post(url, payload) - else: - return requests.get(url) - except requests.exceptions.ConnectionError: - print 'Failed to connect to mojo:debugger, make sure the shell is running.' - return None - - -def _tracing_start(_): - """Starts tracing.""" - if not _send_request('start_tracing'): - return 1 - print "Started tracing." - return 0 - - -def _tracing_stop(args): - """Stops tracing and writes trace to file.""" - if args.file_name: - file_name = args.file_name - else: - for i in xrange(1000): - candidate_file_name = 'mojo_trace_%03d.json' % i - if not os.path.exists(candidate_file_name): - file_name = candidate_file_name - break - else: - print 'Failed to pick a name for the trace output file.' - return 1 - - response = _send_request('stop_tracing') - if not response: - return 1 - - # https://github.com/domokit/mojo/issues/253 - if int(response.headers['content-length']) != len(response.content): - print 'Response is truncated.' - return 1 - - with open(file_name, "wb") as trace_file: - trace_file.write('{"traceEvents":[') - trace_file.write(response.content) - trace_file.write(']}') - print "Trace saved in %s" % file_name - return 0 - - -def _add_tracing_command(subparsers): - """Sets up the command line parser to manage tracing.""" - tracing_parser = subparsers.add_parser('tracing', - help='trace event profiler') - tracing_subparser = tracing_parser.add_subparsers( - help='the command to run') - - start_tracing_parser = tracing_subparser.add_parser('start', - help='start tracing') - start_tracing_parser.set_defaults(func=_tracing_start) - - stop_tracing_parser = tracing_subparser.add_parser('stop', - help='stop tracing and retrieve the result') - stop_tracing_parser.add_argument('file_name', type=str, nargs='?', - help='name of the output file (optional)') - stop_tracing_parser.set_defaults(func=_tracing_stop) - - -def _wm_load(args): - """Loads (embeds) the given url in the window manager.""" - if not _send_request('load', args.url): - return 1 - return 0 - - -def _add_wm_command(subparsers): - """Sets up the parser for the 'wm' command.""" - wm_parser = subparsers.add_parser('wm', help='window manager') - wm_subparser = wm_parser.add_subparsers( - help='the command to run') - - wm_load_parser = wm_subparser.add_parser('load', - help='load (embed) the given url') - wm_load_parser.add_argument('url', type=str, - help='the url to load') - wm_load_parser.set_defaults(func=_wm_load) - - -def _device_stack(args): - """Runs the device logcat through android_stack_parser.""" - adb_path = args.adb_path if args.adb_path else 'adb' - logcat_cmd = [adb_path, 'logcat', '-d'] - try: - logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE) - except OSError: - print 'failed to call adb, make sure it is in PATH or pass --adb-path' - return 1 - - devtools_dir = os.path.dirname(os.path.abspath(__file__)) - stack_command = [os.path.join(devtools_dir, 'android_stack_parser', 'stack')] - if args.build_dir: - stack_command.append('--build-dir=' + os.path.abspath(args.build_dir)) - if args.ndk_dir: - stack_command.append('--ndk-dir=' + os.path.abspath(args.ndk_dir)) - stack_command.append('-') - stack = subprocess.Popen(stack_command, stdin=logcat.stdout) - - logcat.wait() - stack.wait() - - if logcat.returncode: - print 'adb logcat failed, make sure the device is connected and available' - return logcat.returncode - if stack.returncode: - return stack.returncode - return 0 - - -def _gdb_attach(args): - """Run GDB on an instance of Mojo Shell on an android device.""" - if args.ndk_dir: - ndk_dir = args.ndk_dir - else: - try: - ndk_dir = os.path.join(_get_dir_above('third_party'), 'third_party', - 'android_tools', 'ndk') - if not os.path.exists(ndk_dir): - raise DirectoryNotFoundException() - except DirectoryNotFoundException: - logging.fatal("Unable to find the Android NDK, please specify its path " - "with --ndk-dir.") - return - - install_args = {} - if args.gsutil_dir: - install_args['gsutil'] = os.path.join(args.gsutil_dir, 'gsutil') - else: - try: - depot_tools_path = paths.find_depot_tools() - if not depot_tools_path: - raise DirectoryNotFoundException() - install_args['gsutil'] = os.path.join(depot_tools_path, 'third_party', - 'gsutil', 'gsutil') - if not os.path.exists(install_args['gsutil']): - raise DirectoryNotFoundException() - except DirectoryNotFoundException: - logging.fatal("Unable to find gsutil, please specify its path with " - "--gsutil-dir.") - return - - if args.adb_path: - install_args['adb'] = args.adb_path - else: - install_args['adb'] = 'adb' - - try: - install(**install_args) - except OSError as e: - if e.errno == 2: - # ADB not found in path, print an error message - logging.fatal("Unable to find ADB, please specify its path with " - "--adb-path.") - return - else: - raise - - gdb_path = os.path.join( - ndk_dir, - 'toolchains', - # TODO(etiennej): Always select the most recent toolchain? - 'arm-linux-androideabi-4.9', - 'prebuilt', - # TODO(etiennej): DEPS mac NDK and use it on macs. - 'linux-x86_64', - 'bin', - 'arm-linux-androideabi-gdb') - python_gdb_script_path = os.path.join(os.path.dirname(__file__), - 'android_gdb', 'session.py') - debug_session_arguments = {} - if args.build_dir: - debug_session_arguments["build_directory"] = args.build_dir - else: - try: - debug_session_arguments["build_directory"] = os.path.join( - _get_dir_above('out'), 'out', 'android_Debug') - if not os.path.exists(debug_session_arguments["build_directory"]): - raise DirectoryNotFoundException() - except DirectoryNotFoundException: - logging.fatal("Unable to find the build directory, please specify it " - "using --build-dir.") - return - - if args.package_name: - debug_session_arguments["package_name"] = args.package_name - else: - debug_session_arguments["package_name"] = _DEFAULT_PACKAGE_NAME - debug_session_arguments['adb'] = install_args['adb'] - if args.pyelftools_dir: - debug_session_arguments["pyelftools_dir"] = args.pyelftools_dir - else: - try: - debug_session_arguments["pyelftools_dir"] = os.path.join( - _get_dir_above('third_party'), 'third_party', 'pyelftools') - if not os.path.exists(debug_session_arguments["pyelftools_dir"]): - raise DirectoryNotFoundException() - except DirectoryNotFoundException: - logging.fatal("Unable to find pyelftools python module, please specify " - "its path using --pyelftools-dir.") - return - - debug_session_arguments_str = ', '.join( - [k + '="' + codecs.encode(v, 'string_escape') + '"' - for k, v in debug_session_arguments.items()]) - - # We need to pass some commands to GDB at startup. - gdb_commands_file = tempfile.NamedTemporaryFile() - gdb_commands_file.write('source ' + python_gdb_script_path + '\n') - gdb_commands_file.write('py d = DebugSession(' + debug_session_arguments_str - + ')\n') - gdb_commands_file.write('py d.start()\n') - gdb_commands_file.flush() - - gdb_proc = subprocess.Popen([gdb_path, '-x', gdb_commands_file.name], - stdin=sys.stdin, - stdout=sys.stdout, - stderr=sys.stderr) - - # We don't want SIGINT to stop this program. It is automatically propagated by - # the system to gdb. - signal.signal(signal.SIGINT, signal.SIG_IGN) - gdb_proc.wait() - signal.signal(signal.SIGINT, signal.SIG_DFL) - - -def _add_device_command(subparsers): - """Sets up the parser for the 'device' command.""" - device_parser = subparsers.add_parser('device', - help='interact with the Android device (requires adb in PATH or passing ' - '--adb-path)') - device_parser.add_argument('--adb-path', type=str, - help='path to the adb tool from the Android SDK (optional)') - device_subparser = device_parser.add_subparsers( - help='the command to run') - - device_stack_parser = device_subparser.add_parser('stack', - help='symbolize the crash stacktraces from the device log') - device_stack_parser.add_argument('--ndk-dir', type=str, - help='path to the directory containing the Android NDK') - device_stack_parser.add_argument('--build-dir', type=str, - help='path to the build directory') - device_stack_parser.set_defaults(func=_device_stack) - - -def _add_gdb_command(subparsers): - gdb_parser = subparsers.add_parser( - 'gdb', help='Debug Mojo Shell and its apps using GDB') - gdb_subparser = gdb_parser.add_subparsers( - help='Commands to GDB') - - gdb_attach_parser = gdb_subparser.add_parser( - 'attach', help='Attach GDB to a running Mojo Shell process') - gdb_attach_parser.add_argument('--adb-path', type=str, - help='path to the adb tool from the Android SDK (optional)') - gdb_attach_parser.add_argument('--ndk-dir', type=str, - help='path to the directory containing the Android NDK') - gdb_attach_parser.add_argument('--build-dir', type=str, - help='path to the build directory') - gdb_attach_parser.add_argument('--pyelftools-dir', type=str, - help='Path to a directory containing third party libraries') - gdb_attach_parser.add_argument('--gsutil-dir', type=str, - help='Path to a directory containing gsutil') - gdb_attach_parser.add_argument('--package-name', type=str, - help='Name of the Mojo Shell android package to debug') - gdb_attach_parser.set_defaults(func=_gdb_attach) - - -def main(): - parser = argparse.ArgumentParser(description='Command-line interface for ' - 'mojo:debugger') - subparsers = parser.add_subparsers(help='the tool to run') - _add_device_command(subparsers) - _add_tracing_command(subparsers) - _add_wm_command(subparsers) - _add_gdb_command(subparsers) - - args = parser.parse_args() - return args.func(args) - -if __name__ == '__main__': - sys.exit(main()) diff --git a/mojo/devtools/common/mojo_run b/mojo/devtools/common/mojo_run deleted file mode 100755 index 554eeabb90958..0000000000000 --- a/mojo/devtools/common/mojo_run +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -import argparse -import logging -import sys - -from devtoolslib import shell_arguments -from devtoolslib import shell_config - -_USAGE = ("mojo_run " - "[--args-for=] " - "[--content-handlers=] " - "[--enable-external-applications] " - "[--disable-cache] " - "[--enable-multiprocess] " - "[--wait-for-debugger] " - "[--sky |] " - """ - -A is a Mojo URL or a Mojo URL and arguments within quotes. -Example: mojo_run "mojo:js_standalone test.js". - is searched for shared libraries named by mojo URLs. -The value of is a comma separated list like: -text/html,mojo:html_viewer,application/javascript,mojo:js_content_handler -""") - -_DESCRIPTION = """Runner for Mojo applications. - -Any arguments not recognized by the script will be passed on as shell arguments. -""" - - -# Port on which the mojo:debugger http server will be available on the host -# machine. -_MOJO_DEBUGGER_PORT = 7777 -_DEFAULT_WINDOW_MANAGER = "mojo:kiosk_wm" - - -def _configure_debugger(shell): - """Configures mojo:debugger to run and sets up port forwarding for its http - server if the shell is running on a device. - - Returns: - Arguments that need to be appended to the shell argument list in order to - run with the debugger. - """ - shell.forward_host_port_to_shell(_MOJO_DEBUGGER_PORT) - return ['mojo:debugger %d' % _MOJO_DEBUGGER_PORT] - - -def main(): - logging.basicConfig() - - parser = argparse.ArgumentParser(usage=_USAGE, description=_DESCRIPTION) - shell_config.add_shell_arguments(parser) - - parser.add_argument('--no-debugger', action="store_true", - help='Do not spawn mojo:debugger.') - parser.add_argument('--window-manager', default=_DEFAULT_WINDOW_MANAGER, - help='Window manager app to be mapped as ' - 'mojo:window_manager. By default it is ' + - _DEFAULT_WINDOW_MANAGER) - - script_args, shell_args = parser.parse_known_args() - - try: - config = shell_config.get_shell_config(script_args) - shell, shell_args = shell_arguments.get_shell(config, shell_args) - except shell_config.ShellConfigurationException as e: - print e - return 1 - - if not script_args.no_debugger: - if script_args.verbose: - print 'Spawning mojo:debugger, use `mojo_debug` to inspect the shell.' - print 'Note that mojo:debugger will prevent the shell from terminating,' - print ' pass --no-debugger to skip spawning mojo:debugger.' - shell_args.extend(_configure_debugger(shell)) - - shell_args = shell_arguments.append_to_argument(shell_args, '--url-mappings=', - 'mojo:window_manager=%s' % - script_args.window_manager) - - if script_args.verbose: - print "Shell arguments: " + str(shell_args) - - shell.run(shell_args) - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/mojo/devtools/common/mojo_test b/mojo/devtools/common/mojo_test deleted file mode 100755 index 2cf84b9ba26e9..0000000000000 --- a/mojo/devtools/common/mojo_test +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env python -# Copyright 2015 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. - -"""Test runner for Mojo application tests. - -TODO(vtl|msw): Add a way of specifying data dependencies. -""" - -import argparse -import logging -import sys - -from devtoolslib import apptest_dart -from devtoolslib import apptest_gtest -from devtoolslib import shell_arguments -from devtoolslib import shell_config - -_DESCRIPTION = """Runner for Mojo application tests. - -|test_list_file| has to be a valid Python program that sets a |tests| global -variable, containing entries of the following form: - - { - # Required URL for apptest. - "test": "mojo:test_app_url", - # Optional display name (otherwise the entry for "test" above is used). - "name": "mojo:test_app_url (more details)", - # Optional test type. Valid values: - # * "gtest" (default) - # * "gtest_isolated": like "gtest", but run with fixture isolation, - # i.e., each test in a fresh mojo_shell - # * "dart" - "type": "gtest", - # Optional arguments to be passed to the apptest. - "test-args": ["--an_arg", "another_arg"], - # Optional shell arguments. - "shell-args": ["--some-flag-for-the-shell", "--another-flag"], - # Optional timeout in seconds, 60 by default. - "timeout": 120, - } - -|test_list_file| may reference the |target_os| global that will be any of -['android', 'linux'], indicating the system on which the tests are to be run. - -Any arguments not recognized by the script will be passed on as shell arguments. -""" - -_logger = logging.getLogger() - - -def main(): - parser = argparse.ArgumentParser( - formatter_class=argparse.RawDescriptionHelpFormatter, - description=_DESCRIPTION) - parser.add_argument("test_list_file", type=file, - help="a file listing apptests to run") - shell_config.add_shell_arguments(parser) - - script_args, shell_args = parser.parse_known_args() - - try: - config = shell_config.get_shell_config(script_args) - shell, common_shell_args = shell_arguments.get_shell(config, shell_args) - except shell_config.ShellConfigurationException as e: - print e - return 1 - - target_os = "android" if script_args.android else "linux" - test_list_globals = {"target_os": target_os} - exec script_args.test_list_file in test_list_globals - test_list = test_list_globals["tests"] - - succeeded = True - for test_dict in test_list: - test = test_dict["test"] - test_name = test_dict.get("name", test) - test_type = test_dict.get("type", "gtest") - test_args = test_dict.get("test-args", []) - shell_args = test_dict.get("shell-args", []) + common_shell_args - timeout = test_dict.get("timeout", 60) - - _logger.info("Will start: %s" % test_name) - print "Running %s...." % test_name, - sys.stdout.flush() - - if test_type == "dart": - apptest_result = apptest_dart.run_dart_apptest(shell, shell_args, test, - test_args, timeout) - elif test_type == "gtest": - apptest_result = apptest_gtest.run_gtest_apptest(shell, shell_args, test, - test_args, timeout, - False) - elif test_type == "gtest_isolated": - apptest_result = apptest_gtest.run_gtest_apptest(shell, shell_args, test, - test_args, timeout, - True) - else: - apptest_result = False - print "Unrecognized test type in %r" % test_dict - - print "Succeeded" if apptest_result else "Failed" - _logger.info("Completed: %s" % test_name) - if not apptest_result: - succeeded = False - return 0 if succeeded else 1 - -if __name__ == '__main__': - sys.exit(main()) diff --git a/mojo/devtools/common/remote_adb_setup b/mojo/devtools/common/remote_adb_setup deleted file mode 100755 index d275ff61c9131..0000000000000 --- a/mojo/devtools/common/remote_adb_setup +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash -# Copyright 2015 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. - -if [[ $# -ne 1 && $# -ne 2 ]]; then - cat <<'EOF' -Usage: remote_adb_setup REMOTE_HOST [REMOTE_ADB] - -Configures adb on a remote machine to communicate with a device attached to the -local machine. This is useful for installing APKs, running tests, etc while -working remotely. - -Arguments: - REMOTE_HOST hostname of remote machine - REMOTE_ADB path to adb on the remote machine (you can omit this if adb is in - the remote host's path) -EOF - exit 1 -fi - -remote_host="$1" -remote_adb="${2:-adb}" - -# Ensure adb is in the local machine's path. -if ! which adb >/dev/null; then - echo "error: adb must be in your local machine's path." - exit 1 -fi - -if which kinit >/dev/null; then - # Allow ssh to succeed without typing your password multiple times. - kinit -R || kinit -fi - -# Kill the adb server on the remote host. -ssh "$remote_host" "$remote_adb kill-server" - -# Start the adb server locally. -adb start-server - -# Forward various ports from the remote host to the local host: -# 5037: adb -# and from the local host to the remote host: -# 9998: http server for Sky -# 31840: http server for the local mojo: origin -ssh -C \ - -R 5037:127.0.0.1:5037 \ - -L 9998:127.0.0.1:9998 \ - -L 31840:127.0.0.1:31840 \ - "$remote_host" diff --git a/mojo/edk/system/BUILD.gn b/mojo/edk/system/BUILD.gn index ac292d5c4c3bc..5367be17a3455 100644 --- a/mojo/edk/system/BUILD.gn +++ b/mojo/edk/system/BUILD.gn @@ -204,6 +204,7 @@ test("mojo_system_unittests") { "simple_dispatcher_unittest.cc", "test_channel_endpoint_client.cc", "test_channel_endpoint_client.h", + "test_utils_unittest.cc", "thread_annotations_unittest.cc", "unique_identifier_unittest.cc", "waiter_test_utils.cc", diff --git a/mojo/edk/system/channel_endpoint.cc b/mojo/edk/system/channel_endpoint.cc index 038de8dfa15cc..e7e17b4bb3d7f 100644 --- a/mojo/edk/system/channel_endpoint.cc +++ b/mojo/edk/system/channel_endpoint.cc @@ -16,9 +16,9 @@ namespace system { ChannelEndpoint::ChannelEndpoint(ChannelEndpointClient* client, unsigned client_port, MessageInTransitQueue* message_queue) - : client_(client), + : state_(State::PAUSED), + client_(client), client_port_(client_port), - channel_state_(ChannelState::NOT_YET_ATTACHED), channel_(nullptr) { DCHECK(client_ || message_queue); @@ -31,18 +31,14 @@ bool ChannelEndpoint::EnqueueMessage(scoped_ptr message) { MutexLocker locker(&mutex_); - switch (channel_state_) { - case ChannelState::NOT_YET_ATTACHED: - case ChannelState::DETACHED: - // We may reach here if we haven't been attached/run yet. - // TODO(vtl): We may also reach here if the channel is shut down early for - // some reason (with live message pipes on it). Ideally, we'd return false - // (and not enqueue the message), but we currently don't have a way to - // check this. + switch (state_) { + case State::PAUSED: channel_message_queue_.AddMessage(message.Pass()); return true; - case ChannelState::ATTACHED: + case State::RUNNING: return WriteMessageNoLock(message.Pass()); + case State::DEAD: + return false; } NOTREACHED(); @@ -58,7 +54,7 @@ bool ChannelEndpoint::ReplaceClient(ChannelEndpointClient* client, DCHECK(client != client_.get() || client_port != client_port_); client_ = client; client_port_ = client_port; - return channel_state_ != ChannelState::DETACHED; + return state_ != State::DEAD; } void ChannelEndpoint::DetachFromClient() { @@ -69,7 +65,7 @@ void ChannelEndpoint::DetachFromClient() { if (!channel_) return; channel_->DetachEndpoint(this, local_id_, remote_id_); - ResetChannelNoLock(); + DieNoLock(); } void ChannelEndpoint::AttachAndRun(Channel* channel, @@ -80,11 +76,11 @@ void ChannelEndpoint::AttachAndRun(Channel* channel, DCHECK(remote_id.is_valid()); MutexLocker locker(&mutex_); - DCHECK(channel_state_ == ChannelState::NOT_YET_ATTACHED); + DCHECK(state_ == State::PAUSED); DCHECK(!channel_); DCHECK(!local_id_.is_valid()); DCHECK(!remote_id_.is_valid()); - channel_state_ = ChannelState::ATTACHED; + state_ = State::RUNNING; channel_ = channel; local_id_ = local_id; remote_id_ = remote_id; @@ -96,7 +92,7 @@ void ChannelEndpoint::AttachAndRun(Channel* channel, if (!client_) { channel_->DetachEndpoint(this, local_id_, remote_id_); - ResetChannelNoLock(); + DieNoLock(); } } @@ -131,9 +127,9 @@ void ChannelEndpoint::DetachFromChannel() { // |DetachFromClient()| by calling |Channel::DetachEndpoint()| (and there // are racing detaches). if (channel_) - ResetChannelNoLock(); + DieNoLock(); else - DCHECK(channel_state_ == ChannelState::DETACHED); + DCHECK(state_ == State::DEAD); } // If |ReplaceClient()| is called (from another thread) after the above locked @@ -190,7 +186,7 @@ void ChannelEndpoint::OnReadMessageForClient( MutexLocker locker(&mutex_); if (!channel_ || !client_) { // This isn't a failure per se. (It just means that, e.g., the other end - // of the message point closed first.) + // of the message pipe closed first.) return; } @@ -212,13 +208,13 @@ void ChannelEndpoint::OnReadMessageForClient( } } -void ChannelEndpoint::ResetChannelNoLock() { - DCHECK(channel_state_ == ChannelState::ATTACHED); +void ChannelEndpoint::DieNoLock() { + DCHECK(state_ == State::RUNNING); DCHECK(channel_); DCHECK(local_id_.is_valid()); DCHECK(remote_id_.is_valid()); - channel_state_ = ChannelState::DETACHED; + state_ = State::DEAD; channel_ = nullptr; local_id_ = ChannelEndpointId(); remote_id_ = ChannelEndpointId(); diff --git a/mojo/edk/system/channel_endpoint.h b/mojo/edk/system/channel_endpoint.h index c70e66ed368a0..3ebe386a68567 100644 --- a/mojo/edk/system/channel_endpoint.h +++ b/mojo/edk/system/channel_endpoint.h @@ -168,13 +168,23 @@ class MOJO_SYSTEM_IMPL_EXPORT ChannelEndpoint final // Helper for |OnReadMessage()|, handling messages for the client. void OnReadMessageForClient(scoped_ptr message); - // Resets |channel_| to null (and sets |channel_state_| to - // |ChannelState::DETACHED|). This may only be called if |channel_| is - // non-null. - void ResetChannelNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + // Moves |state_| from |RUNNING| to |DEAD|. |channel_| must be non-null, but + // this does not call |channel_->DetachEndpoint()|. + void DieNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); Mutex mutex_; + enum class State { + // |AttachAndRun()| has not been called yet (|channel_| is null). + PAUSED, + // |AttachAndRun()| has been called, but not |DetachFromChannel()| + // (|channel_| is non-null and valid). + RUNNING, + // |DetachFromChannel()| has been called (|channel_| is null). + DEAD + }; + State state_ MOJO_GUARDED_BY(mutex_); + // |client_| must be valid whenever it is non-null. Before |*client_| gives up // its reference to this object, it must call |DetachFromClient()|. // NOTE: This is a |scoped_refptr<>|, rather than a raw pointer, since the @@ -193,17 +203,6 @@ class MOJO_SYSTEM_IMPL_EXPORT ChannelEndpoint final scoped_refptr client_ MOJO_GUARDED_BY(mutex_); unsigned client_port_ MOJO_GUARDED_BY(mutex_); - // State with respect to interaction with the |Channel|. - enum class ChannelState { - // |AttachAndRun()| has not been called yet (|channel_| is null). - NOT_YET_ATTACHED, - // |AttachAndRun()| has been called, but not |DetachFromChannel()| - // (|channel_| is non-null and valid). - ATTACHED, - // |DetachFromChannel()| has been called (|channel_| is null). - DETACHED - }; - ChannelState channel_state_ MOJO_GUARDED_BY(mutex_); // |channel_| must be valid whenever it is non-null. Before |*channel_| gives // up its reference to this object, it must call |DetachFromChannel()|. // |local_id_| and |remote_id_| are valid if and only |channel_| is non-null. diff --git a/mojo/edk/system/channel_manager.cc b/mojo/edk/system/channel_manager.cc index a2e4bf9768c52..097ffa236581f 100644 --- a/mojo/edk/system/channel_manager.cc +++ b/mojo/edk/system/channel_manager.cc @@ -87,6 +87,13 @@ scoped_refptr ChannelManager::CreateChannelOnIOThread( return dispatcher; } +scoped_refptr ChannelManager::CreateChannelWithoutBootstrapOnIOThread( + ChannelId channel_id, + embedder::ScopedPlatformHandle platform_handle) { + return CreateChannelOnIOThreadHelper(channel_id, platform_handle.Pass(), + nullptr); +} + scoped_refptr ChannelManager::CreateChannel( ChannelId channel_id, embedder::ScopedPlatformHandle platform_handle, @@ -163,19 +170,19 @@ void ChannelManager::ShutdownHelper( } } -void ChannelManager::CreateChannelOnIOThreadHelper( +scoped_refptr ChannelManager::CreateChannelOnIOThreadHelper( ChannelId channel_id, embedder::ScopedPlatformHandle platform_handle, scoped_refptr bootstrap_channel_endpoint) { DCHECK_NE(channel_id, kInvalidChannelId); DCHECK(platform_handle.is_valid()); - DCHECK(bootstrap_channel_endpoint); // Create and initialize a |system::Channel|. scoped_refptr channel = new system::Channel(platform_support_); channel->Init(system::RawChannel::Create(platform_handle.Pass())); - channel->SetBootstrapEndpoint(bootstrap_channel_endpoint); + if (bootstrap_channel_endpoint) + channel->SetBootstrapEndpoint(bootstrap_channel_endpoint); { MutexLocker locker(&mutex_); @@ -183,6 +190,7 @@ void ChannelManager::CreateChannelOnIOThreadHelper( channels_[channel_id] = channel; } channel->SetChannelManager(this); + return channel; } void ChannelManager::CreateChannelHelper( diff --git a/mojo/edk/system/channel_manager.h b/mojo/edk/system/channel_manager.h index 014c1b3a78365..1ff958ddd10bf 100644 --- a/mojo/edk/system/channel_manager.h +++ b/mojo/edk/system/channel_manager.h @@ -72,6 +72,14 @@ class MOJO_SYSTEM_IMPL_EXPORT ChannelManager { ChannelId channel_id, embedder::ScopedPlatformHandle platform_handle); + // Like |CreateChannelOnIOThread()|, but doesn't create a bootstrap message + // pipe. Returns the newly-created |Channel|. + // TODO(vtl): Maybe get rid of the others (and bootstrap message pipes in + // general). + scoped_refptr CreateChannelWithoutBootstrapOnIOThread( + ChannelId channel_id, + embedder::ScopedPlatformHandle platform_handle); + // Like |CreateChannelOnIOThread()|, but may be called from any thread. On // completion, will call |callback| (using |callback_thread_task_runner| if it // is non-null, else on the I/O thread). Note: This will always post a task to @@ -116,8 +124,9 @@ class MOJO_SYSTEM_IMPL_EXPORT ChannelManager { scoped_refptr callback_thread_task_runner); // Used by |CreateChannelOnIOThread()| and |CreateChannelHelper()|. Called on - // the I/O thread. - void CreateChannelOnIOThreadHelper( + // the I/O thread. |bootstrap_channel_endpoint| is optional and may be null. + // Returns the newly-created |Channel|. + scoped_refptr CreateChannelOnIOThreadHelper( ChannelId channel_id, embedder::ScopedPlatformHandle platform_handle, scoped_refptr bootstrap_channel_endpoint); diff --git a/mojo/edk/system/channel_manager_unittest.cc b/mojo/edk/system/channel_manager_unittest.cc index afa9b15b79764..2d38b619d1f1e 100644 --- a/mojo/edk/system/channel_manager_unittest.cc +++ b/mojo/edk/system/channel_manager_unittest.cc @@ -168,6 +168,9 @@ TEST_F(ChannelManagerTest, CallsFromOtherThread) { EXPECT_EQ(MOJO_RESULT_OK, d->Close()); } +// TODO(vtl): Test |CreateChannelWithoutBootstrapOnIOThread()|. (This will +// require additional functionality in |Channel|.) + } // namespace } // namespace system } // namespace mojo diff --git a/mojo/edk/system/data_pipe_impl_unittest.cc b/mojo/edk/system/data_pipe_impl_unittest.cc index 3b0470bb1b19a..0bc7506dbe640 100644 --- a/mojo/edk/system/data_pipe_impl_unittest.cc +++ b/mojo/edk/system/data_pipe_impl_unittest.cc @@ -2394,6 +2394,67 @@ TYPED_TEST(DataPipeImplTest, TwoPhaseMoreInvalidArguments) { this->ConsumerClose(); } +// Tests the behavior of writing, closing the producer, and then doing a +// two-phase read of all the data. +// Note: If this test fails/crashes flakily, this is almost certainly an +// indication of a problem in the implementation and not the test. +TYPED_TEST(DataPipeImplTest, WriteCloseProducerTwoPhaseReadAllData) { + const char kTestData[] = "hello world"; + const uint32_t kTestDataSize = static_cast(sizeof(kTestData)); + + const MojoCreateDataPipeOptions options = { + kSizeOfOptions, // |struct_size|. + MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|. + 1u, // |element_num_bytes|. + 1000u // |capacity_num_bytes|. + }; + this->Create(options); + this->DoTransfer(); + + // Write some data, so we'll have something to read. + uint32_t num_bytes = kTestDataSize; + EXPECT_EQ(MOJO_RESULT_OK, + this->ProducerWriteData(UserPointer(kTestData), + MakeUserPointer(&num_bytes), false)); + EXPECT_EQ(kTestDataSize, num_bytes); + + // TODO(vtl): Hack: We can't currently wait for a specified amount of data to + // be available, so poll. + for (size_t i = 0; i < kMaxPoll; i++) { + num_bytes = 0u; + EXPECT_EQ(MOJO_RESULT_OK, + this->ConsumerQueryData(MakeUserPointer(&num_bytes))); + if (num_bytes >= kTestDataSize) + break; + + test::Sleep(test::EpsilonDeadline()); + } + EXPECT_EQ(kTestDataSize, num_bytes); + + const void* read_buffer_ptr = nullptr; + num_bytes = 0u; + EXPECT_EQ(MOJO_RESULT_OK, + this->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr), + MakeUserPointer(&num_bytes), false)); + EXPECT_EQ(kTestDataSize, num_bytes); + EXPECT_EQ(0, memcmp(read_buffer_ptr, kTestData, kTestDataSize)); + + // Close the producer. + this->ProducerClose(); + + // Note: This tiny sleep is to allow/encourage a certain race. In particular, + // for the remote producer case in + // |RemoteProducerDataPipeImpl::MarkDataAsConsumed()| (caused by + // |ConsumerEndReadData()| below) we want |producer_open()| to be false but + // the call to |channel_endpoint_->EnqueueMessage()| to fail. (This race can + // occur without the sleep, but is much less likely.) + test::Sleep(10u); + + EXPECT_EQ(MOJO_RESULT_OK, this->ConsumerEndReadData(num_bytes)); + + this->ConsumerClose(); +} + } // namespace } // namespace system } // namespace mojo diff --git a/mojo/edk/system/ipc_support_unittest.cc b/mojo/edk/system/ipc_support_unittest.cc index 823f6b9f526c8..695c4ecb82955 100644 --- a/mojo/edk/system/ipc_support_unittest.cc +++ b/mojo/edk/system/ipc_support_unittest.cc @@ -11,6 +11,7 @@ #include "base/command_line.h" #include "base/location.h" #include "base/logging.h" +#include "base/memory/scoped_ptr.h" #include "base/synchronization/waitable_event.h" #include "base/test/test_io_thread.h" #include "base/test/test_timeouts.h" @@ -37,6 +38,84 @@ namespace { const char kConnectionIdFlag[] = "test-connection-id"; +// Tests writing a message (containing just data) to |write_mp| and then reading +// it from |read_mp| (it should be the next message, i.e., there should be no +// other messages already enqueued in that direction). +void TestWriteReadMessage(scoped_refptr write_mp, + scoped_refptr read_mp) { + // Set up waiting on the read end first (to avoid racing). + Waiter waiter; + waiter.Init(); + ASSERT_EQ( + MOJO_RESULT_OK, + read_mp->AddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 0, nullptr)); + + // Write a message with just 'x' through the write end. + EXPECT_EQ(MOJO_RESULT_OK, + write_mp->WriteMessage(UserPointer("x"), 1, nullptr, + MOJO_WRITE_MESSAGE_FLAG_NONE)); + + // Wait for it to arrive. + EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(test::ActionDeadline(), nullptr)); + read_mp->RemoveAwakable(&waiter, nullptr); + + // Read the message from the read end. + char buffer[10] = {}; + uint32_t buffer_size = static_cast(sizeof(buffer)); + EXPECT_EQ(MOJO_RESULT_OK, + read_mp->ReadMessage(UserPointer(buffer), + MakeUserPointer(&buffer_size), 0, nullptr, + MOJO_READ_MESSAGE_FLAG_NONE)); + EXPECT_EQ(1u, buffer_size); + EXPECT_EQ('x', buffer[0]); +} + +// Writes a message pipe dispatcher (in a message) to |write_mp| and reads it +// from |read_mp| (it should be the next message, i.e., there should be no other +// other messages already enqueued in that direction). +scoped_refptr SendMessagePipeDispatcher( + scoped_refptr write_mp, + scoped_refptr read_mp, + scoped_refptr mp_to_send) { + CHECK_NE(mp_to_send, write_mp); + CHECK_NE(mp_to_send, read_mp); + + // Set up waiting on the read end first (to avoid racing). + Waiter waiter; + waiter.Init(); + CHECK_EQ( + read_mp->AddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 0, nullptr), + MOJO_RESULT_OK); + + // Write a message with just |mp_to_send| through the write end. + DispatcherTransport transport( + test::DispatcherTryStartTransport(mp_to_send.get())); + CHECK(transport.is_valid()); + std::vector transports; + transports.push_back(transport); + CHECK_EQ(write_mp->WriteMessage(NullUserPointer(), 0, &transports, + MOJO_WRITE_MESSAGE_FLAG_NONE), + MOJO_RESULT_OK); + transport.End(); + + // Wait for it to arrive. + CHECK_EQ(waiter.Wait(test::ActionDeadline(), nullptr), MOJO_RESULT_OK); + read_mp->RemoveAwakable(&waiter, nullptr); + + // Read the message from the read end. + DispatcherVector dispatchers; + uint32_t num_dispatchers = 10; + CHECK_EQ( + read_mp->ReadMessage(NullUserPointer(), NullUserPointer(), &dispatchers, + &num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE), + MOJO_RESULT_OK); + CHECK_EQ(dispatchers.size(), 1u); + CHECK_EQ(num_dispatchers, 1u); + CHECK_EQ(dispatchers[0]->GetType(), Dispatcher::Type::MESSAGE_PIPE); + return scoped_refptr( + static_cast(dispatchers[0].get())); +} + class TestMasterProcessDelegate : public embedder::MasterProcessDelegate { public: TestMasterProcessDelegate() @@ -203,12 +282,95 @@ class TestSlave { MOJO_DISALLOW_COPY_AND_ASSIGN(TestSlave); }; +// Encapsulates both the master and slave sides for each slave. +class TestSlaveSetup { + public: + TestSlaveSetup(embedder::SimplePlatformSupport* platform_support, + base::TestIOThread* test_io_thread, + TestMasterProcessDelegate* master_process_delegate, + IPCSupport* master_ipc_support) + : platform_support_(platform_support), + test_io_thread_(test_io_thread), + master_process_delegate_(master_process_delegate), + master_ipc_support_(master_ipc_support) {} + ~TestSlaveSetup() { + CHECK(!slave_connection_); + CHECK(!slave_); + } + + void Init() { + // Set up the master side entirely before the slave side, since this + // simulates what's likely to happen "in reality" more closely. + slave_connection_.reset( + new TestSlaveConnection(test_io_thread_, master_ipc_support_)); + master_mp_ = slave_connection_->ConnectToSlave(); + + slave_.reset(new TestSlave(platform_support_, test_io_thread_, + slave_connection_->PassSlavePlatformHandle())); + slave_mp_ = slave_->ConnectToMaster(slave_connection_->connection_id()); + } + + void TestConnection() { + TestWriteReadMessage(master_mp_, slave_mp_); + TestWriteReadMessage(slave_mp_, master_mp_); + } + + scoped_refptr PassMasterMessagePipe() { + return master_mp_.Pass(); + } + + scoped_refptr PassSlaveMessagePipe() { + return slave_mp_.Pass(); + } + + void Shutdown() { + if (master_mp_) { + master_mp_->Close(); + master_mp_ = nullptr; + } + if (slave_mp_) { + slave_mp_->Close(); + slave_mp_ = nullptr; + } + + slave_->ShutdownChannelToMaster(); + slave_->ShutdownIPCSupport(); + EXPECT_TRUE(master_process_delegate_->TryWaitForOnSlaveDisconnect()); + slave_connection_->ShutdownChannelToSlave(); + + slave_.reset(); + slave_connection_.reset(); + } + + TestSlaveConnection* slave_connection() { return slave_connection_.get(); } + // Note: To close the master message pipe, use |PassMasterMessagePipe()|. + MessagePipeDispatcher* master_mp() { return master_mp_.get(); } + + TestSlave* slave() { return slave_.get(); } + // Note: To close the slave message pipe, use |PassSlaveMessagePipe()|. + MessagePipeDispatcher* slave_mp() { return slave_mp_.get(); } + + private: + embedder::SimplePlatformSupport* const platform_support_; + base::TestIOThread* const test_io_thread_; + TestMasterProcessDelegate* const master_process_delegate_; + IPCSupport* const master_ipc_support_; + + scoped_ptr slave_connection_; + scoped_refptr master_mp_; + + scoped_ptr slave_; + scoped_refptr slave_mp_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(TestSlaveSetup); +}; + class IPCSupportTest : public testing::Test { public: // Note: Run master process delegate methods on the I/O thread. IPCSupportTest() : test_io_thread_(base::TestIOThread::kAutoStart), - master_ipc_support_(&platform_support(), + master_ipc_support_(&platform_support_, embedder::ProcessType::MASTER, test_io_thread_.task_runner(), &master_process_delegate_, @@ -216,6 +378,14 @@ class IPCSupportTest : public testing::Test { embedder::ScopedPlatformHandle()) {} ~IPCSupportTest() override {} + scoped_ptr SetupSlave() { + scoped_ptr s( + new TestSlaveSetup(&platform_support_, &test_io_thread_, + &master_process_delegate_, &master_ipc_support_)); + s->Init(); + return s; + } + void ShutdownMasterIPCSupport() { test_io_thread_.PostTaskAndWait( FROM_HERE, base::Bind(&IPCSupport::ShutdownOnIOThread, @@ -242,38 +412,6 @@ class IPCSupportTest : public testing::Test { MOJO_DISALLOW_COPY_AND_ASSIGN(IPCSupportTest); }; -// Tests writing a message (containing just data) to |write_mp| and then reading -// it from |read_mp| (it should be the next message, i.e., there should be no -// other messages already enqueued in that direction). -void TestWriteReadMessage(scoped_refptr write_mp, - scoped_refptr read_mp) { - // Set up waiting on the read end first (to avoid racing). - Waiter waiter; - waiter.Init(); - ASSERT_EQ( - MOJO_RESULT_OK, - read_mp->AddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 0, nullptr)); - - // Write a message with just 'x' through the write end. - EXPECT_EQ(MOJO_RESULT_OK, - write_mp->WriteMessage(UserPointer("x"), 1, nullptr, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - - // Wait for it to arrive. - EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(test::ActionDeadline(), nullptr)); - read_mp->RemoveAwakable(&waiter, nullptr); - - // Read the message from the read end. - char buffer[10] = {}; - uint32_t buffer_size = static_cast(sizeof(buffer)); - EXPECT_EQ(MOJO_RESULT_OK, - read_mp->ReadMessage(UserPointer(buffer), - MakeUserPointer(&buffer_size), 0, nullptr, - MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(1u, buffer_size); - EXPECT_EQ('x', buffer[0]); -} - using MessagePipeDispatcherPair = std::pair, scoped_refptr>; @@ -289,83 +427,23 @@ MessagePipeDispatcherPair CreateMessagePipe() { return rv; } -// Writes a message pipe dispatcher (in a message) to |write_mp| and reads it -// from |read_mp| (it should be the next message, i.e., there should be no other -// other messages already enqueued in that direction). -scoped_refptr SendMessagePipeDispatcher( - scoped_refptr write_mp, - scoped_refptr read_mp, - scoped_refptr mp_to_send) { - CHECK_NE(mp_to_send, write_mp); - CHECK_NE(mp_to_send, read_mp); - - // Set up waiting on the read end first (to avoid racing). - Waiter waiter; - waiter.Init(); - CHECK_EQ( - read_mp->AddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 0, nullptr), - MOJO_RESULT_OK); - - // Write a message with just |mp_to_send| through the write end. - DispatcherTransport transport( - test::DispatcherTryStartTransport(mp_to_send.get())); - CHECK(transport.is_valid()); - std::vector transports; - transports.push_back(transport); - CHECK_EQ(write_mp->WriteMessage(NullUserPointer(), 0, &transports, - MOJO_WRITE_MESSAGE_FLAG_NONE), - MOJO_RESULT_OK); - transport.End(); - - // Wait for it to arrive. - CHECK_EQ(waiter.Wait(test::ActionDeadline(), nullptr), MOJO_RESULT_OK); - read_mp->RemoveAwakable(&waiter, nullptr); - - // Read the message from the read end. - DispatcherVector dispatchers; - uint32_t num_dispatchers = 10; - CHECK_EQ( - read_mp->ReadMessage(NullUserPointer(), NullUserPointer(), &dispatchers, - &num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE), - MOJO_RESULT_OK); - CHECK_EQ(dispatchers.size(), 1u); - CHECK_EQ(num_dispatchers, 1u); - CHECK_EQ(dispatchers[0]->GetType(), Dispatcher::Type::MESSAGE_PIPE); - return scoped_refptr( - static_cast(dispatchers[0].get())); -} - TEST_F(IPCSupportTest, MasterSlave) { - TestSlaveConnection slave_connection(&test_io_thread(), - &master_ipc_support()); - scoped_refptr master_mp = - slave_connection.ConnectToSlave(); + scoped_ptr s(SetupSlave()); - TestSlave slave(&platform_support(), &test_io_thread(), - slave_connection.PassSlavePlatformHandle()); - scoped_refptr slave_mp = - slave.ConnectToMaster(slave_connection.connection_id()); - - // Test that we can send a message from the master to the slave. - TestWriteReadMessage(master_mp, slave_mp); - // And vice versa. - TestWriteReadMessage(slave_mp, master_mp); + s->TestConnection(); // Don't need the message pipe anymore. - master_mp->Close(); - slave_mp->Close(); + s->PassMasterMessagePipe()->Close(); + s->PassSlaveMessagePipe()->Close(); // A message was sent through the message pipe, |Channel|s must have been // established on both sides. The events have thus almost certainly been // signalled, but we'll wait just to be sure. - slave_connection.WaitForChannelToSlave(); - slave.WaitForChannelToMaster(); + s->slave_connection()->WaitForChannelToSlave(); + s->slave()->WaitForChannelToMaster(); - slave.ShutdownChannelToMaster(); - slave.ShutdownIPCSupport(); - EXPECT_TRUE(master_process_delegate().TryWaitForOnSlaveDisconnect()); + s->Shutdown(); - slave_connection.ShutdownChannelToSlave(); ShutdownMasterIPCSupport(); } @@ -378,47 +456,28 @@ TEST_F(IPCSupportTest, MasterSlave) { // TODO(vtl): In this scenario, we can't test the intermediary (the master) // going away. TEST_F(IPCSupportTest, ConnectTwoSlaves) { - TestSlaveConnection slave1_connection(&test_io_thread(), - &master_ipc_support()); - scoped_refptr master_mp1 = - slave1_connection.ConnectToSlave(); - - TestSlave slave1(&platform_support(), &test_io_thread(), - slave1_connection.PassSlavePlatformHandle()); - scoped_refptr slave1_mp = - slave1.ConnectToMaster(slave1_connection.connection_id()); - - TestSlaveConnection slave2_connection(&test_io_thread(), - &master_ipc_support()); - scoped_refptr master_mp2 = - slave2_connection.ConnectToSlave(); - - TestSlave slave2(&platform_support(), &test_io_thread(), - slave2_connection.PassSlavePlatformHandle()); - scoped_refptr slave2_mp = - slave2.ConnectToMaster(slave2_connection.connection_id()); - - TestWriteReadMessage(master_mp1, slave1_mp); - TestWriteReadMessage(slave1_mp, master_mp1); - TestWriteReadMessage(master_mp2, slave2_mp); - TestWriteReadMessage(slave2_mp, master_mp2); + scoped_ptr s1(SetupSlave()); + scoped_ptr s2(SetupSlave()); + s1->TestConnection(); + s2->TestConnection(); // Make a message pipe (logically "in" the master) and send one end to each // slave. - MessagePipeDispatcherPair send_mps = CreateMessagePipe(); + MessagePipeDispatcherPair send_mp = CreateMessagePipe(); scoped_refptr slave1_received_mp = - SendMessagePipeDispatcher(master_mp1, slave1_mp, send_mps.first); + SendMessagePipeDispatcher(s1->master_mp(), s1->slave_mp(), send_mp.first); scoped_refptr slave2_received_mp = - SendMessagePipeDispatcher(master_mp2, slave2_mp, send_mps.second); + SendMessagePipeDispatcher(s2->master_mp(), s2->slave_mp(), + send_mp.second); // These should be connected. TestWriteReadMessage(slave1_received_mp, slave2_received_mp); TestWriteReadMessage(slave2_received_mp, slave1_received_mp); - master_mp1->Close(); - master_mp2->Close(); - slave1_mp->Close(); - slave2_mp->Close(); + s1->PassMasterMessagePipe()->Close(); + s2->PassMasterMessagePipe()->Close(); + s1->PassSlaveMessagePipe()->Close(); + s2->PassSlaveMessagePipe()->Close(); // They should still be connected. TestWriteReadMessage(slave1_received_mp, slave2_received_mp); @@ -427,15 +486,95 @@ TEST_F(IPCSupportTest, ConnectTwoSlaves) { slave1_received_mp->Close(); slave2_received_mp->Close(); - slave1.ShutdownChannelToMaster(); - slave1.ShutdownIPCSupport(); - EXPECT_TRUE(master_process_delegate().TryWaitForOnSlaveDisconnect()); - slave1_connection.ShutdownChannelToSlave(); + s1->Shutdown(); + s2->Shutdown(); - slave2.ShutdownChannelToMaster(); - slave2.ShutdownIPCSupport(); - EXPECT_TRUE(master_process_delegate().TryWaitForOnSlaveDisconnect()); - slave2_connection.ShutdownChannelToSlave(); + ShutdownMasterIPCSupport(); +} + +// Like |ConnectTwoSlaves|, but does it twice, to test reusing a connection. +TEST_F(IPCSupportTest, ConnectTwoSlavesTwice) { + scoped_ptr s1(SetupSlave()); + scoped_ptr s2(SetupSlave()); + s1->TestConnection(); + s2->TestConnection(); + + MessagePipeDispatcherPair send_mp1 = CreateMessagePipe(); + scoped_refptr slave1_received_mp1 = + SendMessagePipeDispatcher(s1->master_mp(), s1->slave_mp(), + send_mp1.first); + scoped_refptr slave2_received_mp1 = + SendMessagePipeDispatcher(s2->master_mp(), s2->slave_mp(), + send_mp1.second); + + MessagePipeDispatcherPair send_mp2 = CreateMessagePipe(); + scoped_refptr slave1_received_mp2 = + SendMessagePipeDispatcher(s1->master_mp(), s1->slave_mp(), + send_mp2.first); + scoped_refptr slave2_received_mp2 = + SendMessagePipeDispatcher(s2->master_mp(), s2->slave_mp(), + send_mp2.second); + + s1->PassMasterMessagePipe()->Close(); + s2->PassMasterMessagePipe()->Close(); + s1->PassSlaveMessagePipe()->Close(); + s2->PassSlaveMessagePipe()->Close(); + + TestWriteReadMessage(slave1_received_mp1, slave2_received_mp1); + TestWriteReadMessage(slave2_received_mp1, slave1_received_mp1); + + TestWriteReadMessage(slave1_received_mp2, slave2_received_mp2); + TestWriteReadMessage(slave2_received_mp2, slave1_received_mp2); + + slave1_received_mp1->Close(); + slave2_received_mp1->Close(); + + TestWriteReadMessage(slave1_received_mp2, slave2_received_mp2); + TestWriteReadMessage(slave2_received_mp2, slave1_received_mp2); + + slave1_received_mp2->Close(); + slave2_received_mp2->Close(); + + s1->Shutdown(); + s2->Shutdown(); + + ShutdownMasterIPCSupport(); +} + +// Creates a message pipe in the slave, which sends both ends (in separate +// messages) to the master. +TEST_F(IPCSupportTest, SlavePassBackToMaster) { + scoped_ptr s(SetupSlave()); + + s->TestConnection(); + + // Make a message pipe (logically "in" the slave) and send both ends + // (separately) to the master. + MessagePipeDispatcherPair send_mp = CreateMessagePipe(); + scoped_refptr received_mp1 = + SendMessagePipeDispatcher(s->slave_mp(), s->master_mp(), send_mp.first); + + TestWriteReadMessage(received_mp1, send_mp.second); + TestWriteReadMessage(send_mp.second, received_mp1); + + scoped_refptr received_mp2 = + SendMessagePipeDispatcher(s->slave_mp(), s->master_mp(), send_mp.second); + + s->PassMasterMessagePipe()->Close(); + s->PassSlaveMessagePipe()->Close(); + + TestWriteReadMessage(received_mp1, received_mp2); + TestWriteReadMessage(received_mp2, received_mp1); + + s->Shutdown(); + + // These should still be connected. + // TODO(vtl): This is not yet implemented, thus will fail here! + // TestWriteReadMessage(received_mp1, received_mp2); + // TestWriteReadMessage(received_mp2, received_mp1); + + received_mp1->Close(); + received_mp2->Close(); ShutdownMasterIPCSupport(); } diff --git a/mojo/edk/system/message_pipe_dispatcher_unittest.cc b/mojo/edk/system/message_pipe_dispatcher_unittest.cc index f93cd9065b371..aebc439b67919 100644 --- a/mojo/edk/system/message_pipe_dispatcher_unittest.cc +++ b/mojo/edk/system/message_pipe_dispatcher_unittest.cc @@ -15,7 +15,6 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_vector.h" -#include "base/rand_util.h" #include "base/threading/simple_thread.h" #include "mojo/edk/system/message_pipe.h" #include "mojo/edk/system/test_utils.h" @@ -504,12 +503,12 @@ class WriterThread : public base::SimpleThread { buffer[i] = static_cast(i); // Number of messages to write. - *messages_written_ = static_cast(base::RandInt(1000, 6000)); + *messages_written_ = static_cast(test::RandomInt(1000, 6000)); // Write messages. for (size_t i = 0; i < *messages_written_; i++) { uint32_t bytes_to_write = static_cast( - base::RandInt(1, static_cast(kMaxMessageSize))); + test::RandomInt(1, static_cast(kMaxMessageSize))); EXPECT_EQ(MOJO_RESULT_OK, write_dispatcher_->WriteMessage(UserPointer(buffer), bytes_to_write, nullptr, diff --git a/mojo/edk/system/raw_channel_unittest.cc b/mojo/edk/system/raw_channel_unittest.cc index a9017915ac74b..2fa3f7b3f05fd 100644 --- a/mojo/edk/system/raw_channel_unittest.cc +++ b/mojo/edk/system/raw_channel_unittest.cc @@ -18,7 +18,6 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" -#include "base/rand_util.h" #include "base/synchronization/waitable_event.h" #include "base/test/test_io_thread.h" #include "base/threading/simple_thread.h" @@ -325,7 +324,7 @@ class RawChannelWriterThread : public base::SimpleThread { while (left_to_write_-- > 0) { EXPECT_TRUE(raw_channel_->WriteMessage(MakeTestMessage( - static_cast(base::RandInt(1, kMaxRandomMessageSize))))); + static_cast(test::RandomInt(1, kMaxRandomMessageSize))))); } } diff --git a/mojo/edk/system/remote_producer_data_pipe_impl.cc b/mojo/edk/system/remote_producer_data_pipe_impl.cc index 8d7fa2676f318..833c505bf9055 100644 --- a/mojo/edk/system/remote_producer_data_pipe_impl.cc +++ b/mojo/edk/system/remote_producer_data_pipe_impl.cc @@ -348,15 +348,20 @@ bool RemoteProducerDataPipeImpl::ConsumerEndSerialize( bool RemoteProducerDataPipeImpl::OnReadMessage(unsigned /*port*/, MessageInTransit* message) { - // Always take ownership of the message. (This means that we should always - // return true.) - scoped_ptr msg(message); - if (!producer_open()) { + // This will happen only on the rare occasion that the call to + // |OnReadMessage()| is racing with us calling + // |ChannelEndpoint::ReplaceClient()|, in which case we reject the message, + // and the |ChannelEndpoint| can retry (calling the new client's + // |OnReadMessage()|). DCHECK(!channel_endpoint_); - return true; + return false; } + // Otherwise, we take ownership of the message. (This means that we should + // always return true below.) + scoped_ptr msg(message); + if (!ValidateIncomingMessage(element_num_bytes(), capacity_num_bytes(), current_num_bytes_, msg.get())) { Disconnect(); @@ -462,12 +467,8 @@ void RemoteProducerDataPipeImpl::Disconnect() { // buffer around. Currently, we won't free it even if it empties later. (We // could do this -- requiring a check on every read -- but that seems to be // optimizing for the uncommon case.) - if (!consumer_open() || !current_num_bytes_) { - // Note: There can only be a two-phase *read* (by the consumer) if we still - // have data. - DCHECK(!consumer_in_two_phase_read()); + if (!consumer_open() || !current_num_bytes_) DestroyBuffer(); - } } } // namespace system diff --git a/mojo/edk/system/simple_dispatcher_unittest.cc b/mojo/edk/system/simple_dispatcher_unittest.cc index 051e10829c2bb..9e1bd7bb42356 100644 --- a/mojo/edk/system/simple_dispatcher_unittest.cc +++ b/mojo/edk/system/simple_dispatcher_unittest.cc @@ -12,7 +12,6 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_vector.h" -#include "base/synchronization/lock.h" #include "mojo/edk/system/test_utils.h" #include "mojo/edk/system/waiter.h" #include "mojo/edk/system/waiter_test_utils.h" diff --git a/mojo/edk/system/test_utils.cc b/mojo/edk/system/test_utils.cc index 8bd16ebc37a8d..823bcf4ea3d4c 100644 --- a/mojo/edk/system/test_utils.cc +++ b/mojo/edk/system/test_utils.cc @@ -4,6 +4,9 @@ #include "mojo/edk/system/test_utils.h" +#include +#include + #include #include "base/logging.h" @@ -52,6 +55,23 @@ void Sleep(MojoDeadline deadline) { base::TimeDelta::FromMicroseconds(static_cast(deadline))); } +// TODO(vtl): Replace all of this implementation with suitable use of C++11 +// when we can. +int RandomInt(int min, int max) { + DCHECK_LE(min, max); + DCHECK_LE(static_cast(max) - min, RAND_MAX); + DCHECK_LT(static_cast(max) - min, std::numeric_limits::max()); + + // This is in-range for an |int| due to the above. + int range = max - min + 1; + int max_valid = (RAND_MAX / range) * range - 1; + int value; + do { + value = rand(); + } while (value > max_valid); + return min + (value % range); +} + Stopwatch::Stopwatch() { } diff --git a/mojo/edk/system/test_utils.h b/mojo/edk/system/test_utils.h index 144e07bf0448e..59f9dd53bbf38 100644 --- a/mojo/edk/system/test_utils.h +++ b/mojo/edk/system/test_utils.h @@ -13,6 +13,8 @@ namespace mojo { namespace system { namespace test { +// Deadlines/timeouts and sleeping --------------------------------------------- + MojoDeadline DeadlineFromMilliseconds(unsigned milliseconds); // A timeout smaller than |TestTimeouts::tiny_timeout()|, as a |MojoDeadline|. @@ -32,6 +34,13 @@ MojoDeadline ActionDeadline(); // Sleeps for at least the specified duration. void Sleep(MojoDeadline deadline); +// Pseudorandom numbers for testing -------------------------------------------- + +// Returns a (uniformly) (pseudo)random integer in the interval [min, max]. +// Currently, |max - min| must be at most |RAND_MAX| and must also be (strictly) +// less than |INT_MAX|. +int RandomInt(int min, int max); + // Stopwatch ------------------------------------------------------------------- // A simple "stopwatch" for measuring time elapsed from a given starting point. diff --git a/mojo/edk/system/test_utils_unittest.cc b/mojo/edk/system/test_utils_unittest.cc new file mode 100644 index 0000000000000..5a3eda55ff643 --- /dev/null +++ b/mojo/edk/system/test_utils_unittest.cc @@ -0,0 +1,53 @@ +// Copyright 2015 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 "mojo/edk/system/test_utils.h" + +#include + +#include "testing/gtest/include/gtest/gtest.h" + +namespace mojo { +namespace system { +namespace test { +namespace { + +TEST(TestUtilsTest, RandomInt) { + static const int kMin = -3; + static const int kMax = 6; + static const unsigned kNumBuckets = kMax - kMin + 1; + unsigned buckets[kNumBuckets]; + + static const unsigned kIterations = 10000; + for (unsigned i = 0; i < kIterations; i++) { + int value = RandomInt(kMin, kMax); + ASSERT_GE(value, kMin); + ASSERT_LE(value, kMax); + buckets[value - kMin]++; + } + + for (unsigned i = 0; i < kNumBuckets; i++) { + // The odds that a value in any bucket is less than the expected value + // should be very small (if |kIterations| is sufficiently large compared to + // |kNumBuckets|). + // TODO(vtl): Actually calculate these odds, and maybe raise the proportion + // to something (much) larger than "half". + EXPECT_GE(buckets[i], kIterations / kNumBuckets / 2); + } +} + +TEST(TestUtilsTest, RandomIntSameValues) { + static const int kIntMin = std::numeric_limits::min(); + EXPECT_EQ(kIntMin, RandomInt(kIntMin, kIntMin)); + + static const int kIntMax = std::numeric_limits::max(); + EXPECT_EQ(kIntMax, RandomInt(kIntMax, kIntMax)); + + EXPECT_EQ(0, RandomInt(0, 0)); +} + +} // namespace +} // namespace test +} // namespace system +} // namespace mojo diff --git a/mojo/edk/system/unique_identifier.cc b/mojo/edk/system/unique_identifier.cc index 6e036c81f0c37..984fb526c93d0 100644 --- a/mojo/edk/system/unique_identifier.cc +++ b/mojo/edk/system/unique_identifier.cc @@ -4,16 +4,25 @@ #include "mojo/edk/system/unique_identifier.h" -#include - -#include - -#include "base/strings/string_number_conversions.h" #include "mojo/edk/embedder/platform_support.h" namespace mojo { namespace system { +namespace { + +bool CapitalizedHexDigitToNumber(char c, unsigned char* number) { + if (c >= '0' && c <= '9') + *number = static_cast(c - '0'); + else if (c >= 'A' && c <= 'F') + *number = static_cast(c - 'A' + 10); + else + return false; + return true; +} + +} // namespace + // static UniqueIdentifier UniqueIdentifier::Generate( embedder::PlatformSupport* platform_support) { @@ -25,20 +34,39 @@ UniqueIdentifier UniqueIdentifier::Generate( // static UniqueIdentifier UniqueIdentifier::FromString(const std::string& s, bool* success) { - UniqueIdentifier rv; - std::vector bytes; - if (base::HexStringToBytes(s, &bytes) && bytes.size() == sizeof(rv.data_)) { - memcpy(rv.data_, &bytes[0], sizeof(rv.data_)); - *success = true; - } else { + if (s.size() != 2 * sizeof(UniqueIdentifier::data_)) { *success = false; + return UniqueIdentifier(); } + + UniqueIdentifier rv; + for (size_t i = 0; i < sizeof(rv.data_); i++) { + unsigned char high_digit; + unsigned char low_digit; + // Note: |ToString()| always produces capitalized hex digits, so we should + // never get 'a' through 'f'. + if (!CapitalizedHexDigitToNumber(s[2 * i], &high_digit) || + !CapitalizedHexDigitToNumber(s[2 * i + 1], &low_digit)) { + *success = false; + return UniqueIdentifier(); + } + rv.data_[i] = (high_digit << 4) | low_digit; + } + + *success = true; return rv; } std::string UniqueIdentifier::ToString() const { + // Currently, we encode as hexadecimal (using capitalized digits). // TODO(vtl): Maybe we should base-64 encode instead? - return base::HexEncode(data_, sizeof(data_)); + static const char kHexDigits[] = "0123456789ABCDEF"; + std::string rv(sizeof(data_) * 2, '\0'); + for (size_t i = 0; i < sizeof(data_); i++) { + rv[2 * i] = kHexDigits[data_[i] >> 4]; + rv[2 * i + 1] = kHexDigits[data_[i] & 0xf]; + } + return rv; } } // namespace system diff --git a/mojo/edk/system/unique_identifier.h b/mojo/edk/system/unique_identifier.h index 7db5e383951af..52ca57d7089a9 100644 --- a/mojo/edk/system/unique_identifier.h +++ b/mojo/edk/system/unique_identifier.h @@ -74,7 +74,7 @@ class MOJO_SYSTEM_IMPL_EXPORT UniqueIdentifier { explicit UniqueIdentifier() {} - char data_[16]; + unsigned char data_[16]; // Copying and assignment allowed. }; diff --git a/mojo/edk/system/unique_identifier_unittest.cc b/mojo/edk/system/unique_identifier_unittest.cc index 1522446246f8e..1914af293c3dd 100644 --- a/mojo/edk/system/unique_identifier_unittest.cc +++ b/mojo/edk/system/unique_identifier_unittest.cc @@ -93,19 +93,23 @@ TEST_F(UniqueIdentifierTest, FromStringFailures) { // encoding. So first check something that we know should succeed, to roughly // confirm our knowledge. success = false; - UniqueIdentifier::FromString("0123456789abcdef0123456789ABCDEF", &success); + UniqueIdentifier::FromString("0123456789ABCDEF0123456789ABCDEF", &success); EXPECT_TRUE(success); + success = true; + UniqueIdentifier::FromString("0123456789abcdef0123456789abcdef", &success); + EXPECT_FALSE(success); + success = true; UniqueIdentifier::FromString("!@#$%^&*()_+-=/\\,.<>[]{};':\"|", &success); EXPECT_FALSE(success); success = true; - UniqueIdentifier::FromString("0123456789abcdef0123456789ABCDE", &success); + UniqueIdentifier::FromString("0123456789ABCDEF0123456789ABCDE", &success); EXPECT_FALSE(success); success = true; - UniqueIdentifier::FromString("0123456789abcdef0123456789ABCD", &success); + UniqueIdentifier::FromString("0123456789ABCDEF0123456789ABCD", &success); EXPECT_FALSE(success); } diff --git a/mojo/environment/BUILD.gn b/mojo/environment/BUILD.gn index 53719351e3002..5c7a9f0691755 100644 --- a/mojo/environment/BUILD.gn +++ b/mojo/environment/BUILD.gn @@ -3,8 +3,6 @@ # found in the LICENSE file. source_set("chromium") { - output_name = "mojo_environment_chromium" - sources = [ "default_async_waiter.cc", "default_async_waiter.h", @@ -27,6 +25,7 @@ source_set("chromium") { "//base", "//base/third_party/dynamic_annotations", "//mojo/common", + "//mojo/message_pump", "//mojo/public/c/environment", "//mojo/public/cpp/bindings:callback", "//mojo/public/cpp/environment", diff --git a/mojo/environment/default_async_waiter.cc b/mojo/environment/default_async_waiter.cc index 863cfe31582a7..014e5c1ab3e29 100644 --- a/mojo/environment/default_async_waiter.cc +++ b/mojo/environment/default_async_waiter.cc @@ -5,7 +5,7 @@ #include "mojo/environment/default_async_waiter.h" #include "base/bind.h" -#include "mojo/common/handle_watcher.h" +#include "mojo/message_pump/handle_watcher.h" #include "mojo/public/c/environment/async_waiter.h" namespace mojo { diff --git a/mojo/gles2/BUILD.gn b/mojo/gles2/BUILD.gn index 92b2375501f57..196ee6ed3df2f 100644 --- a/mojo/gles2/BUILD.gn +++ b/mojo/gles2/BUILD.gn @@ -12,15 +12,38 @@ config("gles2_use_mojo") { defines = [ "GLES2_USE_MOJO" ] } -source_set("gles2") { +source_set("control_thunks") { sources = [ "command_buffer_client_impl.cc", "command_buffer_client_impl.h", - "gles2_impl.cc", + "control_thunks_impl.cc", + "control_thunks_impl.h", "gles2_context.cc", "gles2_context.h", ] + deps = [ + "//base", + "//mojo/public/c/system", + "//gpu/command_buffer/client", + "//gpu/command_buffer/client:gles2_cmd_helper", + "//gpu/command_buffer/client:gles2_implementation", + "//gpu/command_buffer/common", + "//mojo/public/c/gles2:headers", + "//mojo/public/c/gpu:MGL", + "//mojo/public/c/gpu:MGL_onscreen", + "//mojo/public/cpp/bindings", + "//mojo/public/cpp/system", + "//services/gles2:lib", + "//mojo/services/gpu/public/interfaces", + ] +} + +source_set("gles2") { + sources = [ + "gles2_impl.cc", + ] + defines = [ "GL_GLEXT_PROTOTYPES", "MOJO_GLES2_IMPLEMENTATION", @@ -34,19 +57,26 @@ source_set("gles2") { all_dependent_configs = [ ":mojo_use_gles2" ] deps = [ - "//base", - "//base/third_party/dynamic_annotations", - "//gpu/command_buffer/client", - "//gpu/command_buffer/client:gles2_cmd_helper", - "//gpu/command_buffer/client:gles2_implementation", + ":control_thunks", "//gpu/command_buffer/client:gles2_interface", - "//gpu/command_buffer/common", - "//mojo/environment:chromium", "//mojo/public/c/gles2:headers", - "//mojo/public/c/system", - "//mojo/public/cpp/bindings", + "//mojo/public/c/gpu:MGL", + ] +} + +source_set("mgl") { + sources = [ + "mgl_impl.cc", + ] + + configs += [ ":gles2_use_mojo" ] + + deps = [ + ":control_thunks", + ":gles2", + "//mojo/public/c/gles2:headers", + "//mojo/public/c/gpu:MGL", + "//mojo/public/c/gpu:MGL_onscreen", "//mojo/public/cpp/system", - "//mojo/services/gpu/public/interfaces", - "//services/gles2:lib", ] } diff --git a/mojo/gles2/control_thunks_impl.cc b/mojo/gles2/control_thunks_impl.cc new file mode 100644 index 0000000000000..d428607c8f2b0 --- /dev/null +++ b/mojo/gles2/control_thunks_impl.cc @@ -0,0 +1,82 @@ +// Copyright 2015 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 "mojo/gles2/control_thunks_impl.h" + +#include "mojo/gles2/gles2_context.h" +#include "mojo/public/cpp/system/message_pipe.h" + +namespace gles2 { + +// static +ControlThunksImpl* ControlThunksImpl::Get() { + static base::LazyInstance::Leaky thunks; + return thunks.Pointer(); +} + +MGLContext ControlThunksImpl::CreateContext( + MGLOpenGLAPIVersion version, + MojoHandle command_buffer_handle, + MGLContext share_group, + MGLContextLostCallback lost_callback, + void* lost_callback_closure, + const struct MojoAsyncWaiter* async_waiter) { + mojo::MessagePipeHandle mph(command_buffer_handle); + mojo::ScopedMessagePipeHandle scoped_handle(mph); + scoped_ptr client( + new GLES2Context(async_waiter, scoped_handle.Pass(), lost_callback, + lost_callback_closure)); + if (!client->Initialize()) + client.reset(); + return client.release(); +} + +void ControlThunksImpl::DestroyContext(MGLContext context) { + delete static_cast(context); +} + +void ControlThunksImpl::MakeCurrent(MGLContext context) { + current_context_tls_.Set(static_cast(context)); +} + +MGLContext ControlThunksImpl::GetCurrentContext() { + return current_context_tls_.Get(); +} + +void ControlThunksImpl::ResizeSurface(uint32_t width, uint32_t height) { + current_context_tls_.Get()->interface()->ResizeCHROMIUM(width, height, 1.f); +} + +void ControlThunksImpl::SwapBuffers() { + current_context_tls_.Get()->interface()->SwapBuffers(); +} + +void* ControlThunksImpl::GetGLES2Interface(MojoGLES2Context context) { + GLES2Context* client = reinterpret_cast(context); + DCHECK(client); + return client->interface(); +} + +void ControlThunksImpl::SignalSyncPoint( + MojoGLES2Context context, + uint32_t sync_point, + MojoGLES2SignalSyncPointCallback callback, + void* closure) { + current_context_tls_.Get()->context_support()->SignalSyncPoint( + sync_point, base::Bind(callback, closure)); +} + +gpu::gles2::GLES2Interface* ControlThunksImpl::CurrentGLES2Interface() { + if (!current_context_tls_.Get()) + return nullptr; + return current_context_tls_.Get()->interface(); +} + +ControlThunksImpl::ControlThunksImpl() { +} + +ControlThunksImpl::~ControlThunksImpl() { +} + +} // namespace gles2 diff --git a/mojo/gles2/control_thunks_impl.h b/mojo/gles2/control_thunks_impl.h new file mode 100644 index 0000000000000..0543adfb81a9f --- /dev/null +++ b/mojo/gles2/control_thunks_impl.h @@ -0,0 +1,69 @@ +// Copyright 2015 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. + +#ifndef MOJO_GLES2_CONTROL_THUNKS_IMPL_H_ +#define MOJO_GLES2_CONTROL_THUNKS_IMPL_H_ + +#include "base/lazy_instance.h" +#include "base/macros.h" +#include "base/threading/thread_local.h" +#include "gpu/GLES2/gl2extchromium.h" +#include "mojo/gles2/gles2_context.h" +#include "mojo/public/c/gles2/gles2.h" +#include "mojo/public/c/gpu/MGL/mgl.h" + +namespace gpu { +namespace gles2 { +class GLES2Interface; +} +} + +namespace gles2 { + +// ControlThunksImpl is a singleton class that implements the MGL and MojoGLES2 +// control functions. The class maintains a lazily allocated TLS slot on each +// thread for the current GL context. +class ControlThunksImpl { + public: + static ControlThunksImpl* Get(); + + MGLContext CreateContext(MGLOpenGLAPIVersion version, + MojoHandle command_buffer_handle, + MGLContext share_group, + MGLContextLostCallback lost_callback, + void* lost_callback_closure, + const struct MojoAsyncWaiter* async_waiter); + + void DestroyContext(MGLContext context); + + void MakeCurrent(MGLContext context); + + MGLContext GetCurrentContext(); + + void ResizeSurface(uint32_t width, uint32_t height); + + void SwapBuffers(); + + void* GetGLES2Interface(MojoGLES2Context context); + + void SignalSyncPoint(MojoGLES2Context context, + uint32_t sync_point, + MojoGLES2SignalSyncPointCallback callback, + void* closure); + + gpu::gles2::GLES2Interface* CurrentGLES2Interface(); + + private: + friend base::DefaultLazyInstanceTraits; + ControlThunksImpl(); + ~ControlThunksImpl(); + + base::ThreadLocalPointer current_context_tls_; + + DISALLOW_COPY_AND_ASSIGN(ControlThunksImpl); +}; + +} // namespace gles2 + +#endif // MOJO_GLES2_CONTROL_THUNKS_IMPL_H_ diff --git a/mojo/gles2/gles2_context.cc b/mojo/gles2/gles2_context.cc index 27b7c099ae067..dff790c1e036a 100644 --- a/mojo/gles2/gles2_context.cc +++ b/mojo/gles2/gles2_context.cc @@ -21,7 +21,7 @@ const size_t kDefaultMaxTransferBufferSize = 16 * 1024 * 1024; GLES2Context::GLES2Context(const MojoAsyncWaiter* async_waiter, mojo::ScopedMessagePipeHandle command_buffer_handle, - MojoGLES2ContextLost lost_callback, + MGLContextLostCallback lost_callback, void* closure) : command_buffer_(this, async_waiter, command_buffer_handle.Pass()), lost_callback_(lost_callback), diff --git a/mojo/gles2/gles2_context.h b/mojo/gles2/gles2_context.h index 87ccfd6220719..f725e25add96f 100644 --- a/mojo/gles2/gles2_context.h +++ b/mojo/gles2/gles2_context.h @@ -10,8 +10,9 @@ #include "gpu/command_buffer/client/gles2_implementation.h" #include "mojo/gles2/command_buffer_client_impl.h" #include "mojo/public/c/gles2/gles2.h" +#include "mojo/public/c/gpu/MGL/mgl_types.h" -struct MojoGLES2ContextPrivate {}; +struct MGLContextPrivate {}; namespace gpu { class TransferBuffer; @@ -23,12 +24,11 @@ class GLES2Implementation; namespace gles2 { -class GLES2Context : public CommandBufferDelegate, - public MojoGLES2ContextPrivate { +class GLES2Context : public CommandBufferDelegate, public MGLContextPrivate { public: explicit GLES2Context(const MojoAsyncWaiter* async_waiter, mojo::ScopedMessagePipeHandle command_buffer_handle, - MojoGLES2ContextLost lost_callback, + MGLContextLostCallback lost_callback, void* closure); ~GLES2Context() override; bool Initialize(); @@ -49,7 +49,7 @@ class GLES2Context : public CommandBufferDelegate, scoped_ptr gles2_helper_; scoped_ptr transfer_buffer_; scoped_ptr implementation_; - MojoGLES2ContextLost lost_callback_; + MGLContextLostCallback lost_callback_; void* closure_; MOJO_DISALLOW_COPY_AND_ASSIGN(GLES2Context); diff --git a/mojo/gles2/gles2_impl.cc b/mojo/gles2/gles2_impl.cc index 50e1d3f04b135..dac1a005d067c 100644 --- a/mojo/gles2/gles2_impl.cc +++ b/mojo/gles2/gles2_impl.cc @@ -2,78 +2,63 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/public/c/gles2/gles2.h" - -#include "base/lazy_instance.h" -#include "base/threading/thread_local.h" -#include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/gles2_interface.h" -#include "mojo/gles2/gles2_context.h" - -using gles2::GLES2Context; - -namespace { - -base::LazyInstance >::Leaky - g_gpu_interface; - -} // namespace +#include "mojo/gles2/control_thunks_impl.h" +#include "mojo/public/c/gles2/gles2.h" +#include "mojo/public/c/gpu/MGL/mgl.h" extern "C" { + MojoGLES2Context MojoGLES2CreateContext(MojoHandle handle, MojoGLES2ContextLost lost_callback, void* closure, const MojoAsyncWaiter* async_waiter) { - mojo::MessagePipeHandle mph(handle); - mojo::ScopedMessagePipeHandle scoped_handle(mph); - scoped_ptr client(new GLES2Context( - async_waiter, scoped_handle.Pass(), lost_callback, closure)); - if (!client->Initialize()) - client.reset(); - return client.release(); + MGLContext context = gles2::ControlThunksImpl::Get()->CreateContext( + MGL_API_VERSION_GLES2, // version + handle, // command_buffer_handle + MGL_NO_CONTEXT, // share_group + static_cast(lost_callback), closure, + async_waiter); + return reinterpret_cast(context); } void MojoGLES2DestroyContext(MojoGLES2Context context) { - delete static_cast(context); + gles2::ControlThunksImpl::Get()->DestroyContext( + reinterpret_cast(context)); } void MojoGLES2MakeCurrent(MojoGLES2Context context) { - gpu::gles2::GLES2Interface* interface = NULL; - if (context) { - GLES2Context* client = static_cast(context); - interface = client->interface(); - DCHECK(interface); - } - g_gpu_interface.Get().Set(interface); + gles2::ControlThunksImpl::Get()->MakeCurrent( + reinterpret_cast(context)); } void MojoGLES2SwapBuffers() { - DCHECK(g_gpu_interface.Get().Get()); - g_gpu_interface.Get().Get()->SwapBuffers(); + gles2::ControlThunksImpl::Get()->SwapBuffers(); } void* MojoGLES2GetGLES2Interface(MojoGLES2Context context) { - return static_cast(context)->interface(); + return gles2::ControlThunksImpl::Get()->GetGLES2Interface(context); } void MojoGLES2SignalSyncPoint(MojoGLES2Context context, uint32_t sync_point, MojoGLES2SignalSyncPointCallback callback, void* closure) { - DCHECK(context); - GLES2Context* client = static_cast(context); - client->SignalSyncPoint(sync_point, callback, closure); + gles2::ControlThunksImpl::Get()->SignalSyncPoint(context, sync_point, + callback, closure); } -#define VISIT_GL_CALL(Function, ReturnType, PARAMETERS, ARGUMENTS) \ - ReturnType gl##Function PARAMETERS { \ - DCHECK(g_gpu_interface.Get().Get()); \ - return g_gpu_interface.Get().Get()->Function ARGUMENTS; \ +#define VISIT_GL_CALL(Function, ReturnType, PARAMETERS, ARGUMENTS) \ + ReturnType GL_APIENTRY gl##Function PARAMETERS { \ + auto interface = gles2::ControlThunksImpl::Get()->CurrentGLES2Interface(); \ + DCHECK(interface); \ + return interface->Function ARGUMENTS; \ } #include "mojo/public/c/gles2/gles2_call_visitor_autogen.h" +#include "mojo/public/c/gles2/gles2_call_visitor_chromium_bind_uniform_location_autogen.h" +#include "mojo/public/c/gles2/gles2_call_visitor_chromium_map_sub_autogen.h" #include "mojo/public/c/gles2/gles2_call_visitor_chromium_miscellaneous_autogen.h" #include "mojo/public/c/gles2/gles2_call_visitor_chromium_resize_autogen.h" -#include "mojo/public/c/gles2/gles2_call_visitor_chromium_sub_image_autogen.h" #include "mojo/public/c/gles2/gles2_call_visitor_chromium_sync_point_autogen.h" #include "mojo/public/c/gles2/gles2_call_visitor_chromium_texture_mailbox_autogen.h" #include "mojo/public/c/gles2/gles2_call_visitor_ext_debug_marker_autogen.h" diff --git a/mojo/gles2/mgl_impl.cc b/mojo/gles2/mgl_impl.cc new file mode 100644 index 0000000000000..95eb093880907 --- /dev/null +++ b/mojo/gles2/mgl_impl.cc @@ -0,0 +1,46 @@ +// Copyright 2015 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. + +// This file implements the MGL and MGL onscreen entry points exposed to the +// Mojo application by the shell. + +#include "mojo/gles2/control_thunks_impl.h" +#include "mojo/public/c/gles2/gles2.h" +#include "mojo/public/c/gpu/MGL/mgl.h" +#include "mojo/public/c/gpu/MGL/mgl_onscreen.h" + +extern "C" { + +MGLContext MGLCreateContext(MGLOpenGLAPIVersion version, + MojoHandle command_buffer_handle, + MGLContext share_group, + MGLContextLostCallback lost_callback, + void* lost_callback_closure, + const struct MojoAsyncWaiter* async_waiter) { + return gles2::ControlThunksImpl::Get()->CreateContext( + version, command_buffer_handle, share_group, lost_callback, + lost_callback_closure, async_waiter); +} + +void MGLDestroyContext(MGLContext context) { + return gles2::ControlThunksImpl::Get()->DestroyContext(context); +} + +void MGLMakeCurrent(MGLContext context) { + return gles2::ControlThunksImpl::Get()->MakeCurrent(context); +} + +MGLContext MGLGetCurrentContext() { + return gles2::ControlThunksImpl::Get()->GetCurrentContext(); +} + +void MGLResizeSurface(uint32_t width, uint32_t height) { + return gles2::ControlThunksImpl::Get()->ResizeSurface(width, height); +} + +void MGLSwapBuffers() { + return gles2::ControlThunksImpl::Get()->SwapBuffers(); +} + +} // extern "C" diff --git a/mojo/go/BUILD.gn b/mojo/go/BUILD.gn deleted file mode 100644 index 9b3ef6281ddf6..0000000000000 --- a/mojo/go/BUILD.gn +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright 2014 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. - -import("rules.gni") - -go_library("application") { - sources = [ - "//mojo/public/go/application/application_impl.go", - "//mojo/public/go/application/connection.go", - ] - deps = [ - ":bindings", - ":system", - ] -} - -go_library("bindings") { - sources = [ - "//mojo/public/go/bindings/async_waiter.go", - "//mojo/public/go/bindings/connector.go", - "//mojo/public/go/bindings/decoder.go", - "//mojo/public/go/bindings/encoder.go", - "//mojo/public/go/bindings/interface.go", - "//mojo/public/go/bindings/invalid_handle.go", - "//mojo/public/go/bindings/message.go", - "//mojo/public/go/bindings/router.go", - "//mojo/public/go/bindings/stub.go", - "//mojo/public/go/bindings/util.go", - ] - deps = [ - ":system", - ] -} - -go_library("system") { - sources = [ - "//mojo/public/go/system/core.go", - "//mojo/public/go/system/data_pipe.go", - "//mojo/public/go/system/handle.go", - "//mojo/public/go/system/message_pipe.go", - "//mojo/public/go/system/mojo_types.go", - "//mojo/public/go/system/shared_buffer.go", - "//mojo/public/go/system/system.go", - "//mojo/public/go/system/system_android.go", - "//mojo/public/go/system/system_linux.go", - "//mojo/public/go/system/system_nacl.go", - ] -} - -go_library("platform_cgo") { - sources = [ - "//mojo/public/platform/native_cgo/system_cgo.go", - ] -} - -if (is_linux) { - group("go") { - testonly = true - deps = [ - ":system_test", - ] - } - go_test_binary("system_test") { - sources = [ - "tests/application_impl_test.go", - "tests/async_waiter_test.go", - "tests/encoding_test.go", - "tests/interface_test.go", - "tests/message_test.go", - "tests/request_response_test.go", - "tests/router_test.go", - "tests/system_test.go", - "tests/testutil.go", - "tests/testutil_test.go", - "tests/union_test.go", - "tests/validation_test.go", - ] - static_library_sources = [ - "c_embedder/c_embedder.cc", - "c_embedder/c_embedder.h", - ] - deps = [ - ":application", - ":platform_cgo", - "//examples/echo", - "//mojo/edk/system", - "//mojo/public/interfaces/bindings/tests:test_interfaces", - "//mojo/public/interfaces/bindings/tests:test_interfaces_experimental", - ] - } -} diff --git a/mojo/go/c_embedder/c_embedder.cc b/mojo/go/c_embedder/c_embedder.cc deleted file mode 100644 index c0fa1118aedde..0000000000000 --- a/mojo/go/c_embedder/c_embedder.cc +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2014 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 "mojo/go/c_embedder/c_embedder.h" - -#include "mojo/edk/embedder/test_embedder.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void InitializeMojoEmbedder() { - mojo::embedder::test::InitWithSimplePlatformSupport(); -} - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/mojo/go/c_embedder/c_embedder.h b/mojo/go/c_embedder/c_embedder.h deleted file mode 100644 index f2961d63cd610..0000000000000 --- a/mojo/go/c_embedder/c_embedder.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2014 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. - -#ifndef MOJO_GO_C_EMBEDDER_C_EMBEDDER_H_ -#define MOJO_GO_C_EMBEDDER_C_EMBEDDER_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -__attribute__((visibility("default"))) void InitializeMojoEmbedder(); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // MOJO_GO_C_EMBEDDER_C_EMBEDDER_H__ diff --git a/mojo/go/go.py b/mojo/go/go.py deleted file mode 100755 index a0f93f213e2bd..0000000000000 --- a/mojo/go/go.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2012 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. - -""" -This script invokes the go build tool. -Must be called as follows: -python go.py [--android] - -eg. -python go.py /usr/lib/google-golang/bin/go out/build out/a.out .. "-I." -"-L. -ltest" test -c test/test.go -""" - -import argparse -import os -import shutil -import subprocess -import sys - -NDK_PLATFORM = 'android-16' -NDK_TOOLCHAIN = 'arm-linux-androideabi-4.9' - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument('--android', action='store_true') - parser.add_argument('go_tool') - parser.add_argument('build_directory') - parser.add_argument('output_file') - parser.add_argument('src_root') - parser.add_argument('out_root') - parser.add_argument('cgo_cflags') - parser.add_argument('cgo_ldflags') - parser.add_argument('go_option', nargs='*') - args = parser.parse_args() - go_tool = os.path.abspath(args.go_tool) - build_dir = args.build_directory - out_file = os.path.abspath(args.output_file) - # The src directory specified is relative. We need this as an absolute path. - src_root = os.path.abspath(args.src_root) - # GOPATH must be absolute, and point to one directory up from |src_Root| - go_path = os.path.abspath(os.path.join(src_root, '..')) - # GOPATH also includes any third_party/go libraries that have been imported - go_path += ':' + os.path.join(src_root, 'third_party', 'go') - go_path += ':' + os.path.abspath(os.path.join(args.out_root, 'gen', 'go')) - if 'MOJO_GOPATH' in os.environ: - go_path += ':' + os.environ['MOJO_GOPATH'] - go_options = args.go_option - try: - shutil.rmtree(build_dir, True) - os.mkdir(build_dir) - except Exception: - pass - old_directory = os.getcwd() - os.chdir(build_dir) - env = os.environ.copy() - env['GOPATH'] = go_path - env['GOROOT'] = os.path.dirname(os.path.dirname(go_tool)) - env['CGO_CFLAGS'] = args.cgo_cflags - env['CGO_LDFLAGS'] = args.cgo_ldflags - if args.android: - env['CGO_ENABLED'] = '1' - env['GOOS'] = 'android' - env['GOARCH'] = 'arm' - env['GOARM'] = '7' - # The Android go tool prebuilt binary has a default path to the compiler, - # which with high probability points to an invalid path, so we override the - # CC env var that will be used by the go tool. - if 'CC' not in env: - ndk_path = os.path.join(src_root, 'third_party', 'android_tools', 'ndk') - if sys.platform.startswith('linux'): - arch = 'linux-x86_64' - elif sys.platform == 'darwin': - arch = 'darwin-x86_64' - else: - raise Exception('unsupported platform: ' + sys.platform) - ndk_cc = os.path.join(ndk_path, 'toolchains', NDK_TOOLCHAIN, - 'prebuilt', arch, 'bin', 'arm-linux-androideabi-gcc') - sysroot = os.path.join(ndk_path, 'platforms', NDK_PLATFORM, 'arch-arm') - env['CGO_CFLAGS'] += ' --sysroot %s' % sysroot - env['CGO_LDFLAGS'] += ' --sysroot %s' % sysroot - env['CC'] = '%s --sysroot %s' % (ndk_cc, sysroot) - - call_result = subprocess.call([go_tool] + go_options, env=env) - if call_result != 0: - return call_result - out_files = sorted([ f for f in os.listdir('.') if os.path.isfile(f)]) - if (len(out_files) > 0): - shutil.move(out_files[0], out_file) - os.chdir(old_directory) - try: - shutil.rmtree(build_dir, True) - except Exception: - pass - -if __name__ == '__main__': - sys.exit(main()) diff --git a/mojo/go/rules.gni b/mojo/go/rules.gni deleted file mode 100644 index 60714f0f08838..0000000000000 --- a/mojo/go/rules.gni +++ /dev/null @@ -1,156 +0,0 @@ -# Copyright 2014 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. - -declare_args() { - # By default, there is no go build tool, because go builds are not supported. - go_build_tool = "" -} - -# Declare a go library. -# -# The target only writes a time stamp for input sources as the build is manages -# by the go tool. -# -# Variables: -# sources(required): list of .go files -# deps: dependencies for the go library - -template("go_library") { - action(target_name) { - sources = invoker.sources - script = "//mojo/go/stamp.py" - outputs = [ - "${target_out_dir}/${target_name}.script.stamp", - ] - if (defined(invoker.deps)) { - deps = invoker.deps - } - args = [ rebase_path(target_out_dir, root_build_dir) + - "/${target_name}.script.stamp" ] - } -} - -# Declare a go test binary target. -# -# The target generates a go test executable, linking against other C code, -# which is compiled into a static library and linked against Go. -# -# Only works on linux. |go_build_tool| must be set to the absolute path -# of the go build tool. -# -# Variables (all required) -# sources: list of .go files to compile -# static_library_sources: list of C sources needed for the static library -# deps: dependencies for the static library - -template("go_test_binary") { - # Only available on linux for now. - assert(is_linux) - assert(defined(invoker.sources)) - assert(go_build_tool != "") - - static_library_name = target_name + "_static_library" - - static_library(static_library_name) { - testonly = true - sources = invoker.static_library_sources - deps = invoker.deps - complete_static_lib = true - } - - action(target_name) { - testonly = true - deps = [ - ":$static_library_name", - ] - script = "//mojo/go/go.py" - inputs = invoker.sources - outputs = [ - "${target_out_dir}/${target_name}", - ] - - # Since go test does not permit specifying an output directory or output - # binary name, we create a temporary build directory, and the python - # script will later identify the output, copy it to the target location, - # and clean up the temporary build directory. - build_dir = "${target_out_dir}/${target_name}_build" - args = [ - "--", - "${go_build_tool}", - rebase_path(build_dir, root_build_dir), - rebase_path(target_out_dir, root_build_dir) + "/${target_name}", - rebase_path("//", root_build_dir), - rebase_path(root_out_dir, root_build_dir), - "-I" + rebase_path("//"), - "-L" + rebase_path(target_out_dir) + " -l" + static_library_name + - " -lstdc++ -lpthread -lm -lglib-2.0 -lrt", - "test", - "-c", - ] + rebase_path(invoker.sources, build_dir) - } -} - -template("go_mojo_application") { - assert(is_android || is_linux) - assert(defined(invoker.sources)) - assert(go_build_tool != "") - - static_library_name = target_name + "_static_library" - static_library(static_library_name) { - complete_static_lib = true - deps = [ - "//mojo/public/platform/native:system", - ] - } - - go_library_name = target_name + "_go" - action(go_library_name) { - deps = invoker.deps + [ - ":${static_library_name}", - "//mojo/go:application", - "//mojo/go:platform_cgo", - "//mojo/public/c/system", - ] - script = "//mojo/go/go.py" - inputs = invoker.sources - outputs = [ - "${target_out_dir}/${target_name}", - ] - - # Since go test does not permit specifying an output directory or output - # binary name, we create a temporary build directory, and the python - # script will later identify the output, copy it to the target location, - # and clean up the temporary build directory. - build_dir = "${target_out_dir}/${target_name}_build" - args = [] - if (is_android) { - args += [ "--android" ] - } - args += [ - "--", - "${go_build_tool}", - rebase_path(build_dir, root_build_dir), - rebase_path(target_out_dir, root_build_dir) + "/${target_name}", - rebase_path("//", root_build_dir), - rebase_path(root_out_dir, root_build_dir), - "-I" + rebase_path("//"), - "-L" + rebase_path(target_out_dir) + " -l" + static_library_name + "", - "build", - ] - args += [ "-buildmode=c-shared" ] - args += rebase_path(invoker.sources, build_dir) - } - - copy(target_name) { - deps = [ - ":${go_library_name}", - ] - sources = [ - "${target_out_dir}/${go_library_name}", - ] - outputs = [ - "${root_out_dir}/${target_name}.mojo", - ] - } -} diff --git a/mojo/go/stamp.py b/mojo/go/stamp.py deleted file mode 100644 index 78db987e47e16..0000000000000 --- a/mojo/go/stamp.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2015 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. - -""" -This script writes a time stamp. -Has one argument - time stamp file. Usage: -python stamp.py path/to/file -""" - -import sys - -def WriteStampFile(stamp_file): - with open(stamp_file, "w"): - pass - - -def main(argv): - stamp_file = argv[1] - WriteStampFile(stamp_file) - return 0 - -if __name__ == '__main__': - sys.exit(main(sys.argv)) diff --git a/mojo/go/system/embedder/embedder.go b/mojo/go/system/embedder/embedder.go deleted file mode 100644 index c0e4aaef8c55d..0000000000000 --- a/mojo/go/system/embedder/embedder.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2014 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. - -package embedder - -/* -#include "mojo/go/c_embedder/c_embedder.h" -*/ -import "C" - -func InitializeMojoEmbedder() { - C.InitializeMojoEmbedder() -} diff --git a/mojo/go/tests/README.txt b/mojo/go/tests/README.txt deleted file mode 100644 index 6cdda941ffc25..0000000000000 --- a/mojo/go/tests/README.txt +++ /dev/null @@ -1,10 +0,0 @@ -Instructions to run system_test (Linux-only) - -1) Follow instructions in src/README.md file - -2) Build -$ mojo/tools/mojob.py gn -$ mojo/tools/mojob.py build - -3) Run -$ out/Debug/obj/mojo/go/system_test -test.v diff --git a/mojo/go/tests/application_impl_test.go b/mojo/go/tests/application_impl_test.go deleted file mode 100644 index b28c95f2d109f..0000000000000 --- a/mojo/go/tests/application_impl_test.go +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2015 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. - -package tests - -import ( - "fmt" - "sync" - "testing" - - "mojo/public/go/application" - "mojo/public/go/bindings" - - "examples/echo/echo" - mojoApp "mojo/public/interfaces/application/application" - sp "mojo/public/interfaces/application/service_provider" - "mojo/public/interfaces/application/shell" -) - -var urls = [2]string{"first.example.com", "second.example.com"} - -func pairedURL(url string) string { - switch url { - case urls[0]: - return urls[1] - case urls[1]: - return urls[0] - default: - panic(fmt.Sprintf("unexpected URL %v", url)) - } -} - -func checkEcho(echoPointer echo.Echo_Pointer) { - echo := echo.NewEchoProxy(echoPointer, bindings.GetAsyncWaiter()) - str := fmt.Sprintf("Hello, world") - response, err := echo.EchoString(&str) - if err != nil { - panic(err) - } - if *response != str { - panic(fmt.Sprintf("invalid response: want %v, got %v", str, *response)) - } - echo.Close_Proxy() -} - -type EchoImpl struct{} - -func (echo *EchoImpl) EchoString(inValue *string) (outValue *string, err error) { - return inValue, nil -} - -// EchoDelegate implements mojo application. In this test configuration we -// have two instances of this implementation that talk to each other. -type EchoDelegate struct { - Wg *sync.WaitGroup - localURL string -} - -func (delegate *EchoDelegate) Create(request echo.Echo_Request) { - stub := echo.NewEchoStub(request, &EchoImpl{}, bindings.GetAsyncWaiter()) - go func() { - if err := stub.ServeRequest(); err != nil { - panic(err) - } - stub.Close() - delegate.Wg.Done() - }() -} - -// Initialize connects to other instance, providing and asking for echo service. -func (delegate *EchoDelegate) Initialize(ctx application.Context) { - if ctx.URL() != delegate.localURL { - panic(fmt.Sprintf("invalid URL: want %v, got %v", delegate.localURL, ctx.URL())) - } - if len(ctx.Args()) != 1 || ctx.Args()[0] != delegate.localURL { - panic(fmt.Sprintf("invalid args: want %v, got %v", []string{delegate.localURL}, ctx.Args())) - } - go func() { - echoRequest, echoPointer := echo.CreateMessagePipeForEcho() - conn := ctx.ConnectToApplication(pairedURL(delegate.localURL), &echo.Echo_ServiceFactory{delegate}) - if conn.RequestorURL() != delegate.localURL { - panic(fmt.Sprintf("invalid requestor URL: want %v, got %v", delegate.localURL, conn.RequestorURL())) - } - if conn.ConnectionURL() != pairedURL(delegate.localURL) { - panic(fmt.Sprintf("invalid connection URL: want %v, got %v", pairedURL(delegate.localURL), conn.ConnectionURL())) - } - conn.ConnectToService(&echoRequest) - checkEcho(echoPointer) - }() -} - -// AcceptConnection accepts incoming connection, providing and asking for echo -// service. -func (delegate *EchoDelegate) AcceptConnection(conn *application.Connection) { - if conn.RequestorURL() != pairedURL(delegate.localURL) { - panic(fmt.Sprintf("invalid requestor URL: want %v, got %v", pairedURL(delegate.localURL), conn.RequestorURL())) - } - if conn.ConnectionURL() != delegate.localURL { - panic(fmt.Sprintf("invalid connection URL: want %v, got %v", delegate.localURL, conn.ConnectionURL())) - } - echoRequest, echoPointer := echo.CreateMessagePipeForEcho() - conn.ProvideServices(&echo.Echo_ServiceFactory{delegate}).ConnectToService(&echoRequest) - checkEcho(echoPointer) -} - -func (delegate *EchoDelegate) Quit() {} - -// shellImpl forward connection from local EchoDelegate instance to remote. -type shellImpl struct { - remoteApp *mojoApp.Application_Proxy - localURL string -} - -func (s *shellImpl) ConnectToApplication(URL string, services *sp.ServiceProvider_Request, exposedServices *sp.ServiceProvider_Pointer) error { - if URL != pairedURL(s.localURL) { - return fmt.Errorf("invalid URL: want %v, got %v", pairedURL(s.localURL), URL) - } - s.remoteApp.AcceptConnection(s.localURL, services, exposedServices, pairedURL(s.localURL)) - return nil -} - -func TestApplication(t *testing.T) { - var apps []*mojoApp.Application_Proxy - var responsesSent, appsTerminated sync.WaitGroup - // Create and run applications. - for i := 0; i < 2; i++ { - request, pointer := mojoApp.CreateMessagePipeForApplication() - apps = append(apps, mojoApp.NewApplicationProxy(pointer, bindings.GetAsyncWaiter())) - // Each app instance provides echo service once when it creates - // a connection and once other instance creates a connection. - responsesSent.Add(2) - appsTerminated.Add(1) - delegate := &EchoDelegate{&responsesSent, urls[i]} - go func() { - application.Run(delegate, request.PassMessagePipe().ReleaseNativeHandle()) - appsTerminated.Done() - }() - } - // Provide a shell for each application. - for i := 0; i < 2; i++ { - shellRequest, shellPointer := shell.CreateMessagePipeForShell() - shellStub := shell.NewShellStub(shellRequest, &shellImpl{apps[i^1], urls[i]}, bindings.GetAsyncWaiter()) - go func() { - if err := shellStub.ServeRequest(); err != nil { - panic(err) - } - shellStub.Close() - }() - apps[i].Initialize(shellPointer, &[]string{urls[i]}, urls[i]) - } - // Wait and then close pipes. - responsesSent.Wait() - for i := 0; i < 2; i++ { - apps[i].RequestQuit() - } - appsTerminated.Wait() - for i := 0; i < 2; i++ { - apps[i].Close_Proxy() - } -} diff --git a/mojo/go/tests/async_waiter_test.go b/mojo/go/tests/async_waiter_test.go deleted file mode 100644 index 8f137f8196ea9..0000000000000 --- a/mojo/go/tests/async_waiter_test.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2015 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. - -package tests - -import ( - "fmt" - "sync" - "testing" - - "mojo/public/go/bindings" - "mojo/public/go/system" -) - -func checkWait(handle system.Handle, signals system.MojoHandleSignals, expected system.MojoResult, wg *sync.WaitGroup) { - wg.Add(1) - responseChan := make(chan bindings.WaitResponse) - bindings.GetAsyncWaiter().AsyncWait(handle, signals, responseChan) - go func() { - response := <-responseChan - if expected != response.Result { - panic(fmt.Sprintf("unexpected wait result: expected %v, got %v", expected, response.Result)) - } - wg.Done() - }() -} - -func checkCancel(handle system.Handle, wg *sync.WaitGroup) { - wg.Add(1) - responseChan := make(chan bindings.WaitResponse) - id := waiter.AsyncWait(handle, system.MOJO_HANDLE_SIGNAL_READABLE, responseChan) - go func() { - waiter.CancelWait(id) - response := <-responseChan - if expected := system.MOJO_RESULT_ABORTED; expected != response.Result { - panic(fmt.Sprintf("unexpected wait result: expected %v, got %v", expected, response.Result)) - } - wg.Done() - }() -} - -func TestAsyncWait(t *testing.T) { - r, h0, h1 := core.CreateMessagePipe(nil) - defer h0.Close() - defer h1.Close() - if r != system.MOJO_RESULT_OK { - t.Fatalf("error creating a message pipe %v", r) - } - var wg sync.WaitGroup - h0.WriteMessage([]byte{0}, nil, system.MOJO_WRITE_MESSAGE_FLAG_NONE) - checkWait(h0, system.MOJO_HANDLE_SIGNAL_WRITABLE, system.MOJO_RESULT_OK, &wg) - checkWait(h1, system.MOJO_HANDLE_SIGNAL_READABLE, system.MOJO_RESULT_OK, &wg) - - if r, h0, h1 = core.CreateMessagePipe(nil); r != system.MOJO_RESULT_OK { - t.Fatalf("error creating a message pipe %v", r) - } - defer h1.Close() - h0.Close() - checkWait(h0, system.MOJO_HANDLE_SIGNAL_PEER_CLOSED, system.MOJO_RESULT_INVALID_ARGUMENT, &wg) - checkWait(h1, system.MOJO_HANDLE_SIGNAL_PEER_CLOSED, system.MOJO_RESULT_OK, &wg) - - if r, h0, h1 = core.CreateMessagePipe(nil); r != system.MOJO_RESULT_OK { - t.Fatalf("error creating a message pipe %v", r) - } - defer h1.Close() - h0.Close() - checkWait(h0, system.MOJO_HANDLE_SIGNAL_PEER_CLOSED, system.MOJO_RESULT_INVALID_ARGUMENT, &wg) - checkWait(h1, system.MOJO_HANDLE_SIGNAL_READABLE, system.MOJO_RESULT_FAILED_PRECONDITION, &wg) - wg.Wait() -} - -func TestAsyncWaitCancel(t *testing.T) { - r, h0, h1 := core.CreateMessagePipe(nil) - defer h0.Close() - defer h1.Close() - if r != system.MOJO_RESULT_OK { - t.Fatalf("error creating a message pipe %v", r) - } - var wg sync.WaitGroup - checkCancel(h0, &wg) - checkCancel(h1, &wg) - - if r, h0, h1 = core.CreateMessagePipe(nil); r != system.MOJO_RESULT_OK { - t.Fatalf("error creating a message pipe %v", r) - } - defer h0.Close() - defer h1.Close() - checkCancel(h0, &wg) - checkCancel(h1, &wg) - wg.Wait() -} diff --git a/mojo/go/tests/encoding_test.go b/mojo/go/tests/encoding_test.go deleted file mode 100644 index 41a3355d9ab44..0000000000000 --- a/mojo/go/tests/encoding_test.go +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2015 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. - -package tests - -import ( - "reflect" - "testing" - - "mojo/public/go/bindings" - "mojo/public/go/system" - "mojo/public/interfaces/bindings/tests/rect" - test "mojo/public/interfaces/bindings/tests/serialization_test_structs" - "mojo/public/interfaces/bindings/tests/test_structs" -) - -func check(t *testing.T, value, zeroValue bindings.Payload) { - message, err := bindings.EncodeMessage(bindings.MessageHeader{}, value) - if err != nil { - t.Fatalf("error encoding value %v: %v", value, err) - } - decodedMessage, err := bindings.ParseMessage(message.Bytes, message.Handles) - if err != nil { - t.Fatalf("error decoding message header from bytes %v for tested value %v: %v", message.Bytes, value, err) - } - if err = decodedMessage.DecodePayload(zeroValue); err != nil { - t.Fatalf("error decoding message payload from bytes %v for tested value %v: %v", message.Payload, value, err) - } - if !reflect.DeepEqual(value, zeroValue) { - t.Fatalf("unexpected value after decoding: expected %v, got %v", value, zeroValue) - } -} - -func TestSerializationTestStructs(t *testing.T) { - check(t, &test.Struct1{1}, &test.Struct1{}) - check(t, &test.Struct2{&mockHandle{handle: 1}}, &test.Struct2{}) - check(t, &test.Struct3{test.Struct1{2}}, &test.Struct3{}) - check(t, &test.Struct4{[]test.Struct1{test.Struct1{1}, test.Struct1{2}}}, &test.Struct4{}) - check(t, &test.Struct5{[2]test.Struct1{test.Struct1{1}, test.Struct1{2}}}, &test.Struct5{}) - check(t, &test.Struct6{"hello, world!"}, &test.Struct6{}) - - check(t, &test.StructOfNullables{nil, nil, nil}, &test.StructOfNullables{}) - handle := system.Handle(&mockHandle{handle: 1}) - s := "hello, world" - check(t, &test.StructOfNullables{&handle, nil, nil}, &test.StructOfNullables{}) - check(t, &test.StructOfNullables{&handle, &test.Struct1{3}, nil}, &test.StructOfNullables{}) - check(t, &test.StructOfNullables{&handle, &test.Struct1{3}, &s}, &test.StructOfNullables{}) - check(t, &test.StructOfNullables{&handle, nil, &s}, &test.StructOfNullables{}) -} - -func TestStructs(t *testing.T) { - s1 := "hello, world!" - s2 := "world, hello!" - handle := system.Handle(&mockHandle{handle: 1}) - messagePipeHandle := system.MessagePipeHandle(&mockHandle{handle: 2}) - consumerHandle := system.ConsumerHandle(&mockHandle{handle: 3}) - producerHandle := system.ProducerHandle(&mockHandle{handle: 4}) - sharedBufferHandle := system.SharedBufferHandle(&mockHandle{handle: 5}) - value := bindings.Payload(&test_structs.NoDefaultFieldValues{ - F0: true, // bool - F1: -2, // int8 - F2: 3, // uint8 - F3: -4000, // int16 - F4: 5000, // uint16 - F5: -6000000, // int32 - F6: 7000000, // uint32 - F7: -8000000000000, // int64 - F8: 9000000000000, // uint64 - F9: 1e-45, // float - F10: -1e45, // double - F11: s1, // string - F12: &s2, // string? - F13: messagePipeHandle, // handle - F14: consumerHandle, // handle - F15: producerHandle, // handle - F16: &messagePipeHandle, // handle? - F17: &consumerHandle, // handle? - F18: &producerHandle, // handle? - F19: handle, // handle - F20: &handle, // handle? - F21: sharedBufferHandle, // handle - F22: &sharedBufferHandle, // handle? - F23: []string{s1, s2}, // array - F24: []*string{&s1, &s2}, // array - F25: &[]string{s1, s2}, // array? - F26: &[]*string{&s1, &s2}, // array? - F27: test_structs.EmptyStruct{}, // EmptyStruct - F28: &test_structs.EmptyStruct{}, // EmptyStruct? - }) - check(t, value, &test_structs.NoDefaultFieldValues{}) - - value = &test_structs.ScopedConstants{ - test_structs.ScopedConstants_EType_E0, - test_structs.ScopedConstants_EType_E1, - test_structs.ScopedConstants_EType_E2, - test_structs.ScopedConstants_EType_E3, - test_structs.ScopedConstants_EType_E4, - 10, - 25, - } - check(t, value, &test_structs.ScopedConstants{}) - - value = &test_structs.MapKeyTypes{ - F0: map[bool]bool{false: true, true: false}, - F1: map[int8]int8{15: -45, -42: 50}, - F2: map[uint8]uint8{15: 45, 42: 50}, - F3: map[int16]int16{-15: 45, -42: 50}, - F4: map[uint16]uint16{15: 45, 42: 50}, - F5: map[int32]int32{15: -45, 42: 50}, - F6: map[uint32]uint32{15: 45, 42: 50}, - F7: map[int64]int64{15: 45, 42: -50}, - F8: map[uint64]uint64{15: 45, 42: 50}, - F9: map[float32]float32{1.5: 2.5, 3.5: 1e-9}, - F10: map[float64]float64{1.5: 2.5, 3.5: 1e-9}, - F11: map[string]string{s1: s2, s2: s1}, - } - check(t, value, &test_structs.MapKeyTypes{}) - - value = &test_structs.MapValueTypes{ - F0: map[string][]string{ - s1: []string{s1, s2}, - s2: []string{s2, s1}, - }, - F1: map[string]*[]string{ - s1: &[]string{s1, s2}, - s2: &[]string{s2, s1}, - }, - F2: map[string][]*string{ - s1: []*string{&s1, &s2}, - s2: []*string{&s2, &s1}, - }, - F3: map[string][2]string{ - s1: [2]string{s1, s2}, - s2: [2]string{s2, s1}, - }, - F4: map[string][]*[2]string{ - s1: []*[2]string{&[2]string{s1, s2}}, - s2: []*[2]string{&[2]string{s1, s2}}, - }, - F5: map[string][1][2]string{ - s1: [1][2]string{[2]string{s1, s2}}, - s2: [1][2]string{[2]string{s1, s2}}, - }, - F6: map[string]*rect.Rect{ - s1: &rect.Rect{}, - s2: &rect.Rect{3, 4, 5, 6}, - }, - F7: map[string]map[string]string{ - s1: map[string]string{s1: s1, s2: s2}, - s2: map[string]string{s1: s2, s2: s1}, - }, - F8: map[string][]map[string]string{ - s1: []map[string]string{ - map[string]string{s1: s1, s2: s2}, - map[string]string{s1: s2, s2: s1}, - }, - s2: []map[string]string{ - map[string]string{s1: s1, s2: s2}, - map[string]string{s1: s2, s2: s1}, - }, - }, - F9: map[string]system.Handle{ - s1: handle, - s2: handle, - }, - F10: map[string][]system.Handle{ - s1: []system.Handle{handle}, - s2: []system.Handle{}, - }, - F11: map[string]map[string]system.Handle{ - s1: map[string]system.Handle{s1: handle}, - s2: map[string]system.Handle{s2: handle}, - }, - } - check(t, value, &test_structs.MapValueTypes{}) - - value = &test_structs.BitArrayValues{ - F0: [1]bool{true}, - F1: [7]bool{true, false, true, false, true, false, true}, - F2: [9]bool{true, true, true, false, false, false, true, true, true}, - F3: []bool{true, false, true, false}, - F4: [][]bool{[]bool{true}}, - F5: []*[]bool{ - &[]bool{true, false, true}, - &[]bool{false, true}, - }, - F6: []*[2]bool{ - &[2]bool{false, false}, - &[2]bool{false, true}, - &[2]bool{true, false}, - &[2]bool{true, true}, - }, - } - check(t, value, &test_structs.BitArrayValues{}) -} diff --git a/mojo/go/tests/interface_test.go b/mojo/go/tests/interface_test.go deleted file mode 100644 index a3f8f901dca09..0000000000000 --- a/mojo/go/tests/interface_test.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2015 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. - -package tests - -import ( - "testing" - - "mojo/public/go/bindings" -) - -func TestPassMessagePipe(t *testing.T) { - r, p := bindings.CreateMessagePipeForMojoInterface() - r1, p1 := r, p - handle := r1.PassMessagePipe() - defer handle.Close() - p1.Close() - rhandle, phandle := r.PassMessagePipe(), p.PassMessagePipe() - if rhandle.IsValid() || phandle.IsValid() { - t.Fatal("message pipes should be invalid after PassMessagePipe() or Close()") - } - rhandle.Close() - phandle.Close() -} diff --git a/mojo/go/tests/message_test.go b/mojo/go/tests/message_test.go deleted file mode 100644 index 0b0d63efcb0b6..0000000000000 --- a/mojo/go/tests/message_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015 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. - -package tests - -import ( - "testing" - - "mojo/public/go/bindings" -) - -func checkMessageEncoding(t *testing.T, header, payload bindings.MessageHeader) { - var encodedMessage, decodedMessage *bindings.Message - var err error - var decodedHeader, decodedPayload bindings.MessageHeader - - if encodedMessage, err = bindings.EncodeMessage(header, &payload); err != nil { - t.Fatalf("Failed encoding message: %v", err) - } - - if decodedMessage, err = bindings.ParseMessage(encodedMessage.Bytes, nil); err != nil { - t.Fatalf("Failed decoding message header: %v", err) - } - if decodedHeader = decodedMessage.Header; decodedHeader != header { - t.Fatalf("Unexpected header decoded: got %v, want %v", decodedHeader, header) - } - if err = decodedMessage.DecodePayload(&decodedPayload); err != nil { - t.Fatalf("Failed decoding message payload: %v", err) - } - if decodedPayload != payload { - t.Fatalf("Unexpected header with request id decoded: got %v, want %v", decodedPayload, payload) - } -} - -// TestMessageHeader tests that headers are identical after being -// encoded/decoded. -func TestMessageHeader(t *testing.T) { - header := bindings.MessageHeader{2, 0, 0} - headerWithId := bindings.MessageHeader{1, 2, 3} - checkMessageEncoding(t, header, headerWithId) - checkMessageEncoding(t, headerWithId, header) - headerWithZeroId := bindings.MessageHeader{1, 2, 0} - checkMessageEncoding(t, headerWithZeroId, header) -} diff --git a/mojo/go/tests/request_response_test.go b/mojo/go/tests/request_response_test.go deleted file mode 100644 index 0b79f695fbfb7..0000000000000 --- a/mojo/go/tests/request_response_test.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2015 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. - -package tests - -import ( - "testing" - - "examples/echo/echo" - "mojo/public/go/bindings" - "mojo/public/go/system" -) - -func TestProxyClosesPipe(t *testing.T) { - request, pointer := echo.CreateMessagePipeForEcho() - // Create a message with valid header and invalid payload and send it. - header := bindings.MessageHeader{0, bindings.MessageIsResponseFlag, 1} - message, err := bindings.EncodeMessage(header, &header) - if err != nil { - t.Fatalf("Error encoding message: %v", err) - } - requestPipe := request.PassMessagePipe() - if r := requestPipe.WriteMessage(message.Bytes, nil, system.MOJO_WRITE_MESSAGE_FLAG_NONE); r != system.MOJO_RESULT_OK { - t.Fatalf("Can't send a message: %v", r) - } - - // Make echo request with response (that is already sent). - echoProxy := echo.NewEchoProxy(pointer, waiter) - _, err = echoProxy.EchoString(bindings.StringPointer("hello, world")) - if err == nil { - t.Fatalf("Message is invalid, error expected") - } - - // Wait for the pipe to be closed. - waitResponseChan := make(chan bindings.WaitResponse) - waiter.AsyncWait(requestPipe, system.MOJO_HANDLE_SIGNAL_PEER_CLOSED, waitResponseChan) - waitResponse := <-waitResponseChan - if waitResponse.Result != system.MOJO_RESULT_OK { - t.Fatalf("Error waiting on pipe to be closed: %v", waitResponse.Result) - } - requestPipe.Close() -} - -type echoImpl struct{} - -func (impl *echoImpl) EchoString(in *string) (*string, error) { - return nil, nil -} - -func TestStubClosesPipe(t *testing.T) { - request, pointer := echo.CreateMessagePipeForEcho() - // Create a message with valid header and invalid payload and send it. - header := bindings.MessageHeader{0, bindings.MessageIsResponseFlag, 1} - message, err := bindings.EncodeMessage(header, &header) - if err != nil { - t.Fatalf("Error encoding message: %v", err) - } - pointerPipe := pointer.PassMessagePipe() - if r := pointerPipe.WriteMessage(message.Bytes, nil, system.MOJO_WRITE_MESSAGE_FLAG_NONE); r != system.MOJO_RESULT_OK { - t.Fatalf("Can't send a message: %v", r) - } - - // Make echo request with response (that is already sent). - echoStub := echo.NewEchoStub(request, &echoImpl{}, waiter) - if err := echoStub.ServeRequest(); err == nil { - t.Fatalf("Message is invalid, error expected") - } - - // Wait for the pipe to be closed. - waitResponseChan := make(chan bindings.WaitResponse) - waiter.AsyncWait(pointerPipe, system.MOJO_HANDLE_SIGNAL_PEER_CLOSED, waitResponseChan) - waitResponse := <-waitResponseChan - if waitResponse.Result != system.MOJO_RESULT_OK { - t.Fatalf("Error waiting on pipe to be closed: %v", waitResponse.Result) - } - pointerPipe.Close() -} diff --git a/mojo/go/tests/router_test.go b/mojo/go/tests/router_test.go deleted file mode 100644 index ec8ebb311e2c8..0000000000000 --- a/mojo/go/tests/router_test.go +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2015 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. - -package tests - -import ( - "regexp" - "sync" - "testing" - - "mojo/public/go/bindings" - "mojo/public/go/system" -) - -func expectError(t *testing.T, expected string, err error) { - if err == nil { - t.Fatalf("unexpected nil error, expected %v", expected) - } - if ok, _ := regexp.MatchString(expected, err.Error()); !ok { - t.Fatalf("unexpected error: expected %v, got %v", expected, err.Error()) - } -} - -func encodeMessage(header bindings.MessageHeader, payload bindings.Payload) *bindings.Message { - message, err := bindings.EncodeMessage(header, payload) - if err != nil { - panic(err) - } - return message -} - -func TestAccept(t *testing.T) { - r, h0, h1 := core.CreateMessagePipe(nil) - defer h1.Close() - if r != system.MOJO_RESULT_OK { - t.Fatalf("can't create a message pipe: %v", r) - } - router := bindings.NewRouter(h0, bindings.GetAsyncWaiter()) - header := bindings.MessageHeader{0, 0, 0} - if err := router.Accept(encodeMessage(header, &header)); err != nil { - t.Fatal(err) - } - header = bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, 1} - err := router.Accept(encodeMessage(header, &header)) - expectError(t, "message header should have a zero request ID", err) - router.Close() -} - -func TestAcceptWithResponse(t *testing.T) { - r, h0, h1 := core.CreateMessagePipe(nil) - defer h1.Close() - if r != system.MOJO_RESULT_OK { - t.Fatalf("can't create a message pipe: %v", r) - } - router := bindings.NewRouter(h0, bindings.GetAsyncWaiter()) - header := bindings.MessageHeader{0, bindings.MessageIsResponseFlag, 1} - bindings.WriteMessage(h1, encodeMessage(header, &header)) - header = bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, 1} - if result := <-router.AcceptWithResponse(encodeMessage(header, &header)); result.Error != nil { - t.Fatal(result.Error) - } - header = bindings.MessageHeader{0, 0, 0} - err := (<-router.AcceptWithResponse(encodeMessage(header, &header))).Error - expectError(t, "message header should have a request ID", err) - router.Close() -} - -const numberOfRequests = 50 - -func TestAcceptWithResponseMultiple(t *testing.T) { - r, h0, h1 := core.CreateMessagePipe(nil) - defer h1.Close() - if r != system.MOJO_RESULT_OK { - t.Fatalf("can't create a message pipe: %v", r) - } - router := bindings.NewRouter(h0, bindings.GetAsyncWaiter()) - var wg sync.WaitGroup - wg.Add(numberOfRequests + 1) - // Serve requests. - go func() { - for i := 0; i < numberOfRequests; i++ { - c := make(chan bindings.WaitResponse, 1) - bindings.GetAsyncWaiter().AsyncWait(h1, system.MOJO_HANDLE_SIGNAL_READABLE, c) - r, bytes, handles := h1.ReadMessage(system.MOJO_READ_MESSAGE_FLAG_NONE) - if r != system.MOJO_RESULT_OK { - t.Fatalf("can't read from a message pipe: %v", r) - } - r = h1.WriteMessage(bytes, handles, system.MOJO_WRITE_MESSAGE_FLAG_NONE) - if r != system.MOJO_RESULT_OK { - t.Fatalf("can't write to a message pipe: %v", r) - } - } - wg.Done() - }() - // Send concurrent requests. - for i := 0; i < numberOfRequests; i++ { - go func(i int) { - header := bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, uint64(i + 1)} - err := (<-router.AcceptWithResponse(encodeMessage(header, &header))).Error - if err != nil { - panic(err) - } - wg.Done() - }(i) - } - wg.Wait() - router.Close() -} - -func TestClose(t *testing.T) { - r, h0, h1 := core.CreateMessagePipe(nil) - defer h1.Close() - if r != system.MOJO_RESULT_OK { - t.Fatalf("can't create a message pipe: %v", r) - } - router := bindings.NewRouter(h0, bindings.GetAsyncWaiter()) - var wg sync.WaitGroup - wg.Add(numberOfRequests*2 + 1) - - // Send requests from the same go routine. - for i := 0; i < numberOfRequests; i++ { - header := bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, uint64(i + 1)} - c := router.AcceptWithResponse(encodeMessage(header, &header)) - go func() { - if err := (<-c).Error; err == nil { - panic("unexpected nil error") - } - wg.Done() - }() - } - // Send requests from different go routines. - for i := 0; i < numberOfRequests; i++ { - go func(i int) { - header := bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, uint64(i + 1)} - err := (<-router.AcceptWithResponse(encodeMessage(header, &header))).Error - if err == nil { - panic("unexpected nil error") - } - wg.Done() - }(i + numberOfRequests) - } - go func() { - router.Close() - wg.Done() - }() - wg.Wait() -} diff --git a/mojo/go/tests/system_test.go b/mojo/go/tests/system_test.go deleted file mode 100644 index 77b80fe6363e8..0000000000000 --- a/mojo/go/tests/system_test.go +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright 2014 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. - -package tests - -import ( - "bytes" - "testing" - - "mojo/public/go/system" -) - -const ( - MOJO_HANDLE_SIGNAL_READWRITABLE = system.MojoHandleSignals(system.MOJO_HANDLE_SIGNAL_READABLE | - system.MOJO_HANDLE_SIGNAL_WRITABLE) - MOJO_HANDLE_SIGNAL_ALL = system.MojoHandleSignals(system.MOJO_HANDLE_SIGNAL_READABLE | - system.MOJO_HANDLE_SIGNAL_WRITABLE | - system.MOJO_HANDLE_SIGNAL_PEER_CLOSED) -) - -func TestGetTimeTicksNow(t *testing.T) { - x := core.GetTimeTicksNow() - if x < 10 { - t.Error("Invalid GetTimeTicksNow return value") - } -} - -func TestHandle(t *testing.T) { - var handle system.SharedBufferHandle - var r system.MojoResult - - if r, handle = core.CreateSharedBuffer(nil, 1); r != system.MOJO_RESULT_OK { - t.Fatalf("CreateSharedBuffer failed:%v", r) - } - if !handle.IsValid() { - t.Fatalf("CreateSharedBuffer returned invalid handle:%v", handle) - } - duplicate := handle - if duplicate.NativeHandle() != handle.NativeHandle() { - t.Fatalf("duplicate(%v) and handle(%v) point to different handles", duplicate.NativeHandle(), handle.NativeHandle()) - } - releasedHandle := handle.ReleaseNativeHandle() - if duplicate.IsValid() || handle.IsValid() { - t.Fatalf("duplicate(%v) and handle(%v) should be invalid after releasing native handle", duplicate.NativeHandle(), handle.NativeHandle()) - } - handle = core.AcquireNativeHandle(releasedHandle).ToSharedBufferHandle() - if handle.NativeHandle() != releasedHandle || !handle.IsValid() { - t.Fatalf("handle(%v) should be valid after AcquireNativeHandle", handle.NativeHandle()) - } - untypedHandle := handle.ToUntypedHandle() - if handle.IsValid() { - t.Fatalf("handle(%v) should be invalid after call ToUntypedHandle", handle.NativeHandle()) - } - handle = untypedHandle.ToSharedBufferHandle() - if untypedHandle.IsValid() { - t.Fatalf("untypedHandle(%v) should be invalid after call ToSharedBufferHandle", untypedHandle.NativeHandle()) - } - if handle.NativeHandle() != releasedHandle { - t.Fatalf("handle(%v) should be wrapping %v", handle.NativeHandle(), releasedHandle) - } - if r = handle.Close(); r != system.MOJO_RESULT_OK { - t.Fatalf("Close on handle failed:%v", r) - } -} - -func TestMessagePipe(t *testing.T) { - var h0, h1 system.MessagePipeHandle - var r system.MojoResult - var state system.MojoHandleSignalsState - - if r, h0, h1 = core.CreateMessagePipe(nil); r != system.MOJO_RESULT_OK { - t.Fatalf("CreateMessagePipe failed:%v", r) - } - if !h0.IsValid() || !h1.IsValid() { - t.Fatalf("CreateMessagePipe returned invalid handles h0:%v h1:%v", h0, h1) - } - - r, state = h0.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, 0) - if r != system.MOJO_RESULT_DEADLINE_EXCEEDED { - t.Fatalf("h0 should not be readable:%v", r) - } - if state.SatisfiedSignals != system.MOJO_HANDLE_SIGNAL_WRITABLE { - t.Fatalf("state should be not be signaled readable after CreateMessagePipe:%v", state.SatisfiedSignals) - } - if state.SatisfiableSignals != MOJO_HANDLE_SIGNAL_ALL { - t.Fatalf("state should allow all signals after CreateMessagePipe:%v", state.SatisfiableSignals) - } - - r, state = h0.Wait(system.MOJO_HANDLE_SIGNAL_WRITABLE, system.MOJO_DEADLINE_INDEFINITE) - if r != system.MOJO_RESULT_OK { - t.Fatalf("h0 should be writable:%v", r) - } - if state.SatisfiedSignals != system.MOJO_HANDLE_SIGNAL_WRITABLE { - t.Fatalf("state should be signaled writable after core.Wait:%v", state.SatisfiedSignals) - } - if state.SatisfiableSignals != MOJO_HANDLE_SIGNAL_ALL { - t.Fatalf("state should allow all signals after core.Wait:%v", state.SatisfiableSignals) - } - - if r, _, _ = h0.ReadMessage(system.MOJO_READ_MESSAGE_FLAG_NONE); r != system.MOJO_RESULT_SHOULD_WAIT { - t.Fatalf("Read on h0 did not return wait:%v", r) - } - kHello := []byte("hello") - if r = h1.WriteMessage(kHello, nil, system.MOJO_WRITE_MESSAGE_FLAG_NONE); r != system.MOJO_RESULT_OK { - t.Fatalf("Failed WriteMessage on h1:%v", r) - } - - r, state = h0.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, system.MOJO_DEADLINE_INDEFINITE) - if r != system.MOJO_RESULT_OK { - t.Fatalf("h0 should be readable after WriteMessage to h1:%v", r) - } - if state.SatisfiedSignals != MOJO_HANDLE_SIGNAL_READWRITABLE { - t.Fatalf("h0 should be signaled readable after WriteMessage to h1:%v", state.SatisfiedSignals) - } - if state.SatisfiableSignals != MOJO_HANDLE_SIGNAL_ALL { - t.Fatalf("h0 should be readable/writable after WriteMessage to h1:%v", state.SatisfiableSignals) - } - if !state.SatisfiableSignals.IsReadable() || !state.SatisfiableSignals.IsWritable() || !state.SatisfiableSignals.IsClosed() { - t.Fatalf("Helper functions are misbehaving") - } - - r, msg, _ := h0.ReadMessage(system.MOJO_READ_MESSAGE_FLAG_NONE) - if r != system.MOJO_RESULT_OK { - t.Fatalf("Failed ReadMessage on h0:%v", r) - } - if !bytes.Equal(msg, kHello) { - t.Fatalf("Invalid message expected:%s, got:%s", kHello, msg) - } - - r, index, states := core.WaitMany([]system.Handle{h0}, []system.MojoHandleSignals{system.MOJO_HANDLE_SIGNAL_READABLE}, 10) - if r != system.MOJO_RESULT_DEADLINE_EXCEEDED { - t.Fatalf("h0 should not be readable after reading message:%v", r) - } - if index != -1 { - t.Fatalf("should be no index after MOJO_RESULT_DEADLINE_EXCEEDED:%v", index) - } - if len(states) != 1 { - t.Fatalf("states should be set after WaitMany:%v", states) - } - if states[0].SatisfiedSignals != system.MOJO_HANDLE_SIGNAL_WRITABLE { - t.Fatalf("h0 should be signaled readable WaitMany:%v", states[0].SatisfiedSignals) - } - if states[0].SatisfiableSignals != MOJO_HANDLE_SIGNAL_ALL { - t.Fatalf("h0 should be readable/writable after WaitMany:%v", states[0].SatisfiableSignals) - } - - if r = h0.Close(); r != system.MOJO_RESULT_OK { - t.Fatalf("Close on h0 failed:%v", r) - } - - r, state = h1.Wait(MOJO_HANDLE_SIGNAL_READWRITABLE, system.MOJO_DEADLINE_INDEFINITE) - if r != system.MOJO_RESULT_FAILED_PRECONDITION { - t.Fatalf("h1 should not be readable/writable after Close(h0):%v", r) - } - if state.SatisfiedSignals != system.MOJO_HANDLE_SIGNAL_PEER_CLOSED { - t.Fatalf("state should be signaled closed after Close(h0):%v", state.SatisfiedSignals) - } - if state.SatisfiableSignals != system.MOJO_HANDLE_SIGNAL_PEER_CLOSED { - t.Fatalf("state should only be closable after Close(h0):%v", state.SatisfiableSignals) - } - - if r = h1.Close(); r != system.MOJO_RESULT_OK { - t.Fatalf("Close on h1 failed:%v", r) - } -} - -func TestDataPipe(t *testing.T) { - var hp system.ProducerHandle - var hc system.ConsumerHandle - var r system.MojoResult - - if r, hp, hc = core.CreateDataPipe(nil); r != system.MOJO_RESULT_OK { - t.Fatalf("CreateDataPipe failed:%v", r) - } - if !hp.IsValid() || !hc.IsValid() { - t.Fatalf("CreateDataPipe returned invalid handles hp:%v hc:%v", hp, hc) - } - if r, _ = hc.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, 0); r != system.MOJO_RESULT_DEADLINE_EXCEEDED { - t.Fatalf("hc should not be readable:%v", r) - } - if r, _ = hp.Wait(system.MOJO_HANDLE_SIGNAL_WRITABLE, system.MOJO_DEADLINE_INDEFINITE); r != system.MOJO_RESULT_OK { - t.Fatalf("hp should be writeable:%v", r) - } - - // Test one-phase read/write. - // Writing. - kHello := []byte("hello") - r, numBytes := hp.WriteData(kHello, system.MOJO_WRITE_DATA_FLAG_NONE) - if r != system.MOJO_RESULT_OK || numBytes != len(kHello) { - t.Fatalf("Failed WriteData on hp:%v numBytes:%d", r, numBytes) - } - // Reading. - if r, _ = hc.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, system.MOJO_DEADLINE_INDEFINITE); r != system.MOJO_RESULT_OK { - t.Fatalf("hc should be readable after WriteData on hp:%v", r) - } - r, data := hc.ReadData(system.MOJO_READ_DATA_FLAG_NONE) - if r != system.MOJO_RESULT_OK { - t.Fatalf("Failed ReadData on hc:%v", r) - } - if !bytes.Equal(data, kHello) { - t.Fatalf("Invalid data expected:%s, got:%s", kHello, data) - } - - // Test two-phase read/write. - // Writing. - kHello = []byte("Hello, world!") - r, buf := hp.BeginWriteData(len(kHello), system.MOJO_WRITE_DATA_FLAG_ALL_OR_NONE) - if r != system.MOJO_RESULT_OK { - t.Fatalf("Failed BeginWriteData on hp:%v numBytes:%d", r, len(kHello)) - } - if len(buf) < len(kHello) { - t.Fatalf("Buffer size(%d) should be at least %d", len(buf), len(kHello)) - } - copy(buf, kHello) - if r, _ := hp.WriteData(kHello, system.MOJO_WRITE_DATA_FLAG_NONE); r != system.MOJO_RESULT_BUSY { - t.Fatalf("hp should be busy during a two-phase write: %v", r) - } - if r, _ = hc.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, 0); r != system.MOJO_RESULT_DEADLINE_EXCEEDED { - t.Fatalf("hc shouldn't be readable before EndWriteData on hp:%v", r) - } - if r := hp.EndWriteData(len(kHello)); r != system.MOJO_RESULT_OK { - t.Fatalf("Failed EndWriteData on hp:%v", r) - } - // Reading. - if r, _ = hc.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, system.MOJO_DEADLINE_INDEFINITE); r != system.MOJO_RESULT_OK { - t.Fatalf("hc should be readable after EndWriteData on hp:%v", r) - } - if r, buf = hc.BeginReadData(len(kHello), system.MOJO_READ_DATA_FLAG_ALL_OR_NONE); r != system.MOJO_RESULT_OK { - t.Fatalf("Failed BeginReadData on hc:%v numBytes:%d", r, len(kHello)) - } - if len(buf) != len(kHello) { - t.Fatalf("Buffer size(%d) should be equal to %d", len(buf), len(kHello)) - } - if r, _ := hc.ReadData(system.MOJO_READ_DATA_FLAG_NONE); r != system.MOJO_RESULT_BUSY { - t.Fatalf("hc should be busy during a two-phase read: %v", r) - } - if !bytes.Equal(buf, kHello) { - t.Fatalf("Invalid data expected:%s, got:%s", kHello, buf) - } - if r := hc.EndReadData(len(buf)); r != system.MOJO_RESULT_OK { - t.Fatalf("Failed EndReadData on hc:%v", r) - } - - if r = hp.Close(); r != system.MOJO_RESULT_OK { - t.Fatalf("Close on hp failed:%v", r) - } - if r, _ = hc.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, system.MOJO_DEADLINE_INDEFINITE); r != system.MOJO_RESULT_FAILED_PRECONDITION { - t.Fatalf("hc should not be readable after hp closed:%v", r) - } - if r = hc.Close(); r != system.MOJO_RESULT_OK { - t.Fatalf("Close on hc failed:%v", r) - } -} - -func TestSharedBuffer(t *testing.T) { - var h0, h1 system.SharedBufferHandle - var buf []byte - var r system.MojoResult - - if r, h0 = core.CreateSharedBuffer(nil, 100); r != system.MOJO_RESULT_OK { - t.Fatalf("CreateSharedBuffer failed:%v", r) - } - if !h0.IsValid() { - t.Fatalf("CreateSharedBuffer returned an invalid handle h0:%v", h0) - } - if r, buf = h0.MapBuffer(0, 100, system.MOJO_MAP_BUFFER_FLAG_NONE); r != system.MOJO_RESULT_OK { - t.Fatalf("MapBuffer failed to map buffer with h0:%v", r) - } - if len(buf) != 100 || cap(buf) != 100 { - t.Fatalf("Buffer length(%d) and capacity(%d) should be %d", len(buf), cap(buf), 100) - } - buf[50] = 'x' - if r, h1 = h0.DuplicateBufferHandle(nil); r != system.MOJO_RESULT_OK { - t.Fatalf("DuplicateBufferHandle of h0 failed:%v", r) - } - if !h1.IsValid() { - t.Fatalf("DuplicateBufferHandle returned an invalid handle h1:%v", h1) - } - if r = h0.Close(); r != system.MOJO_RESULT_OK { - t.Fatalf("Close on h0 failed:%v", r) - } - buf[51] = 'y' - if r = h1.UnmapBuffer(buf); r != system.MOJO_RESULT_OK { - t.Fatalf("UnmapBuffer failed:%v", r) - } - if r, buf = h1.MapBuffer(50, 50, system.MOJO_MAP_BUFFER_FLAG_NONE); r != system.MOJO_RESULT_OK { - t.Fatalf("MapBuffer failed to map buffer with h1:%v", r) - } - if len(buf) != 50 || cap(buf) != 50 { - t.Fatalf("Buffer length(%d) and capacity(%d) should be %d", len(buf), cap(buf), 50) - } - if buf[0] != 'x' || buf[1] != 'y' { - t.Fatalf("Failed to validate shared buffer. expected:x,y got:%s,%s", buf[0], buf[1]) - } - if r = h1.UnmapBuffer(buf); r != system.MOJO_RESULT_OK { - t.Fatalf("UnmapBuffer failed:%v", r) - } - if r = h1.Close(); r != system.MOJO_RESULT_OK { - t.Fatalf("Close on h1 failed:%v", r) - } -} diff --git a/mojo/go/tests/testutil.go b/mojo/go/tests/testutil.go deleted file mode 100644 index 99d33f727f7c4..0000000000000 --- a/mojo/go/tests/testutil.go +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2015 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. - -package tests - -import ( - "encoding/binary" - "fmt" - "math" - "strings" - - "mojo/go/system/embedder" - "mojo/public/go/bindings" - "mojo/public/go/system" -) - -var core system.Core -var waiter bindings.AsyncWaiter - -func init() { - embedder.InitializeMojoEmbedder() - core = system.GetCore() - waiter = bindings.GetAsyncWaiter() -} - -type mockHandle struct { - bindings.InvalidHandle - handle system.MojoHandle -} - -func (h *mockHandle) IsValid() bool { - return true -} - -func (h *mockHandle) ReleaseNativeHandle() system.MojoHandle { - return h.handle -} - -func (h *mockHandle) ToUntypedHandle() system.UntypedHandle { - return h -} - -func (h *mockHandle) ToConsumerHandle() system.ConsumerHandle { - return h -} - -func (h *mockHandle) ToProducerHandle() system.ProducerHandle { - return h -} - -func (h *mockHandle) ToMessagePipeHandle() system.MessagePipeHandle { - return h -} - -func (h *mockHandle) ToSharedBufferHandle() system.SharedBufferHandle { - return h -} - -// inputParser parses validation tests input format as described in -// |mojo/public/cpp/bindings/tests/validation_test_input_parser.h| -type inputParser struct { -} - -type dataItem struct { - Type string - Value string -} - -type pointerPlaceholder struct { - Position int - Size int -} - -func (p *inputParser) parseToDataItems(s string) []dataItem { - var items []dataItem - s = strings.TrimSpace(s) - for len(s) > 0 { - // Parsing data item type. - var itemType string - if s[0] == '[' { - closeBracket := strings.Index(s, "]") - if closeBracket == -1 { - panic("unmatched left [") - } - itemType = strings.TrimSpace(s[1:closeBracket]) - s = strings.TrimSpace(s[closeBracket+1:]) - } else { - itemType = "u1" - } - - // Parsing data item value. - itemEnd := strings.IndexAny(s, "[ \t\n\r") - if itemEnd == -1 { - items = append(items, dataItem{itemType, strings.TrimSpace(s)}) - s = "" - } else { - items = append(items, dataItem{itemType, strings.TrimSpace(s[:itemEnd])}) - s = strings.TrimSpace(s[itemEnd:]) - } - } - return items -} - -// Parse parses a validation tests input string that has no comments. -// Panics if input has errors. -func (p *inputParser) Parse(s string) ([]byte, []system.UntypedHandle) { - var bytes []byte - var buf [8]byte - // We need non-nil slice for comparing values with reflect.DeepEqual. - handles := []system.UntypedHandle{} - pointers := make(map[string]pointerPlaceholder) - for _, item := range p.parseToDataItems(s) { - switch item.Type { - case "u1": - var value uint8 - fmt.Sscan(item.Value, &value) - bytes = append(bytes, byte(value)) - case "u2": - var value uint16 - fmt.Sscan(item.Value, &value) - binary.LittleEndian.PutUint16(buf[:2], value) - bytes = append(bytes, buf[:2]...) - case "u4": - var value uint32 - fmt.Sscan(item.Value, &value) - binary.LittleEndian.PutUint32(buf[:4], value) - bytes = append(bytes, buf[:4]...) - case "u8": - var value uint64 - fmt.Sscan(item.Value, &value) - binary.LittleEndian.PutUint64(buf[:8], value) - bytes = append(bytes, buf[:8]...) - case "s1": - var value int8 - fmt.Sscan(item.Value, &value) - bytes = append(bytes, byte(value)) - case "s2": - var value int16 - fmt.Sscan(item.Value, &value) - binary.LittleEndian.PutUint16(buf[:2], uint16(value)) - bytes = append(bytes, buf[:2]...) - case "s4": - var value int32 - fmt.Sscan(item.Value, &value) - binary.LittleEndian.PutUint32(buf[:4], uint32(value)) - bytes = append(bytes, buf[:4]...) - case "s8": - var value int64 - fmt.Sscan(item.Value, &value) - binary.LittleEndian.PutUint64(buf[:8], uint64(value)) - bytes = append(bytes, buf[:8]...) - case "b": - var value byte - for i := 0; i < 8; i++ { - value <<= 1 - if item.Value[i] == '1' { - value++ - } - } - bytes = append(bytes, value) - case "f": - var value float32 - fmt.Sscan(item.Value, &value) - binary.LittleEndian.PutUint32(buf[:4], math.Float32bits(value)) - bytes = append(bytes, buf[:4]...) - case "d": - var value float64 - fmt.Sscan(item.Value, &value) - binary.LittleEndian.PutUint64(buf[:8], math.Float64bits(value)) - bytes = append(bytes, buf[:8]...) - case "dist4": - pointers[item.Value] = pointerPlaceholder{len(bytes), 4} - bytes = append(bytes, buf[:4]...) - case "dist8": - pointers[item.Value] = pointerPlaceholder{len(bytes), 8} - bytes = append(bytes, buf[:8]...) - case "anchr": - placeholder := pointers[item.Value] - dist := len(bytes) - placeholder.Position - switch placeholder.Size { - case 4: - binary.LittleEndian.PutUint32(bytes[placeholder.Position:], uint32(dist)) - case 8: - binary.LittleEndian.PutUint64(bytes[placeholder.Position:], uint64(dist)) - } - delete(pointers, item.Value) - case "handles": - var value int - fmt.Sscan(item.Value, &value) - handles = make([]system.UntypedHandle, value) - for i, _ := range handles { - handles[i] = &mockHandle{handle: system.MojoHandle(i + 1)} - } - default: - panic(fmt.Sprintf("unsupported item type: %v", item.Type)) - } - } - if len(pointers) != 0 { - panic(fmt.Sprintf("unmatched pointers: %v", pointers)) - } - return bytes, handles -} diff --git a/mojo/go/tests/testutil_test.go b/mojo/go/tests/testutil_test.go deleted file mode 100644 index 36c0e7cc17566..0000000000000 --- a/mojo/go/tests/testutil_test.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2015 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. - -package tests - -import ( - "bytes" - "encoding/binary" - "math" - "testing" -) - -func verifyInputParser(t *testing.T, s string, expected []byte, handlesCount int) { - parser := &inputParser{} - b, h := parser.Parse(s) - if !bytes.Equal(b, expected) { - t.Fatalf("unexpected byte slice after parsing %v: expected %v, got %v", s, expected, b) - } - if len(h) != handlesCount { - t.Fatalf("unexpected handles count after parsing %v: expected %v, got %v", s, handlesCount, len(h)) - } -} - -func TestInputParser(t *testing.T) { - var buf []byte - buf = make([]byte, 1+2+4+8+1+1) - buf[0] = 0x10 - binary.LittleEndian.PutUint16(buf[1:], 65535) - binary.LittleEndian.PutUint32(buf[3:], 65536) - binary.LittleEndian.PutUint64(buf[7:], 0xFFFFFFFFFFFFFFFF) - buf[15] = 0 - buf[16] = 0xFF - verifyInputParser(t, "[u1]0x10 [u2]65535 [u4]65536 [u8]0xFFFFFFFFFFFFFFFF 0 0Xff", buf, 0) - - buf = make([]byte, 8+1+2+4) - binary.LittleEndian.PutUint64(buf[0:], math.MaxUint64-0x800+1) - buf[8] = math.MaxUint8 - 128 + 1 - binary.LittleEndian.PutUint16(buf[9:], 0) - binary.LittleEndian.PutUint32(buf[11:], math.MaxUint32-40+1) - verifyInputParser(t, "[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40", buf, 0) - - buf = make([]byte, 1+1+1) - buf[0] = 11 - buf[1] = 0x80 - buf[2] = 0 - verifyInputParser(t, "[b]00001011 [b]10000000 \r [b]00000000", buf, 0) - - buf = make([]byte, 4+8) - binary.LittleEndian.PutUint32(buf[0:], math.Float32bits(+.3e9)) - binary.LittleEndian.PutUint64(buf[4:], math.Float64bits(-10.03)) - verifyInputParser(t, "[f]+.3e9 [d]-10.03", buf, 0) - - buf = make([]byte, 4+1+8+1) - binary.LittleEndian.PutUint32(buf[0:], 14) - buf[4] = 0 - binary.LittleEndian.PutUint64(buf[5:], 9) - buf[13] = 0 - verifyInputParser(t, "[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar", buf, 0) - - buf = make([]byte, 8) - binary.LittleEndian.PutUint64(buf[0:], 2) - verifyInputParser(t, "[handles]50 [u8]2", buf, 50) -} diff --git a/mojo/go/tests/union_test.go b/mojo/go/tests/union_test.go deleted file mode 100644 index 9e8847c4cc8db..0000000000000 --- a/mojo/go/tests/union_test.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2015 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. - -package tests - -import ( - "testing" - - "mojo/public/go/bindings" - "mojo/public/go/system" - "mojo/public/interfaces/bindings/tests/test_unions" -) - -type Encodable interface { - Encode(encoder *bindings.Encoder) error -} - -func TestPodUnion(t *testing.T) { - tests := []test_unions.PodUnion{ - &test_unions.PodUnionFInt8{8}, - &test_unions.PodUnionFInt16{16}, - &test_unions.PodUnionFUint64{64}, - &test_unions.PodUnionFBool{true}, - &test_unions.PodUnionFEnum{test_unions.AnEnum_Second}, - } - - for _, union := range tests { - var wrapper, zeroWrapper test_unions.WrapperStruct - wrapper.PodUnion = union - check(t, &wrapper, &zeroWrapper) - } -} - -func TestHandleUnion(t *testing.T) { - tests := []test_unions.HandleUnion{ - &test_unions.HandleUnionFHandle{system.Handle(&mockHandle{handle: 1})}, - &test_unions.HandleUnionFMessagePipe{system.MessagePipeHandle(&mockHandle{handle: 2})}, - &test_unions.HandleUnionFDataPipeConsumer{system.ConsumerHandle(&mockHandle{handle: 3})}, - &test_unions.HandleUnionFDataPipeProducer{system.ProducerHandle(&mockHandle{handle: 4})}, - &test_unions.HandleUnionFSharedBuffer{system.SharedBufferHandle(&mockHandle{handle: 5})}, - } - - for _, union := range tests { - var wrapper, zeroWrapper test_unions.WrapperStruct - wrapper.HandleUnion = union - check(t, &wrapper, &zeroWrapper) - } -} - -func TestObjectUnion(t *testing.T) { - tests := []test_unions.ObjectUnion{ - &test_unions.ObjectUnionFDummy{test_unions.DummyStruct{10}}, - &test_unions.ObjectUnionFArrayInt8{[]int8{1, 2, 3, 4}}, - &test_unions.ObjectUnionFMapInt8{map[string]int8{"hello": 1, "world": 2}}, - &test_unions.ObjectUnionFNullable{}, - &test_unions.ObjectUnionFPodUnion{&test_unions.PodUnionFInt8{8}}, - &test_unions.ObjectUnionFPodUnion{&test_unions.PodUnionFInt64{64}}, - &test_unions.ObjectUnionFPodUnion{&test_unions.PodUnionFBool{true}}, - &test_unions.ObjectUnionFPodUnion{&test_unions.PodUnionFEnum{test_unions.AnEnum_Second}}, - } - - for _, union := range tests { - var wrapper, zeroWrapper test_unions.WrapperStruct - wrapper.ObjectUnion = union - check(t, &wrapper, &zeroWrapper) - } -} - -func encode(t *testing.T, value Encodable) ([]byte, []system.UntypedHandle, error) { - encoder := bindings.NewEncoder() - err := value.Encode(encoder) - if err != nil { - return nil, nil, err - } - - bytes, handles, err := encoder.Data() - if err != nil { - return nil, nil, err - } - - return bytes, handles, nil -} - -func TestNonNullableNullInUnion(t *testing.T) { - var wrapper test_unions.WrapperStruct - fdummy := test_unions.ObjectUnionFDummy{test_unions.DummyStruct{10}} - wrapper.ObjectUnion = &fdummy - - bytes, handles, _ := encode(t, &wrapper) - bytes[16] = 0 - - var decoded test_unions.WrapperStruct - decoder := bindings.NewDecoder(bytes, handles) - - if err := decoded.Decode(decoder); err == nil { - t.Fatalf("Null non-nullable should have failed validation.") - } -} - -func TestUnionInStruct(t *testing.T) { - var ss, out test_unions.SmallStruct - ss.PodUnion = &test_unions.PodUnionFInt8{10} - check(t, &ss, &out) - - bytes, _, _ := encode(t, &ss) - if int(bytes[8*2]) != 16 { - t.Fatalf("Union does not start at the correct location in struct.") - } -} - -func TestUnionInArray(t *testing.T) { - var ss, out test_unions.SmallStruct - ss.PodUnionArray = &[]test_unions.PodUnion{ - &test_unions.PodUnionFInt8{8}, - &test_unions.PodUnionFInt16{16}, - &test_unions.PodUnionFUint64{64}, - &test_unions.PodUnionFBool{true}, - &test_unions.PodUnionFEnum{test_unions.AnEnum_Second}, - } - check(t, &ss, &out) -} - -func TestUnionInArrayNullNullable(t *testing.T) { - var ss, out test_unions.SmallStruct - ss.NullablePodUnionArray = &[]test_unions.PodUnion{ - nil, - &test_unions.PodUnionFInt8{8}, - &test_unions.PodUnionFInt16{16}, - &test_unions.PodUnionFUint64{64}, - &test_unions.PodUnionFBool{true}, - &test_unions.PodUnionFEnum{test_unions.AnEnum_Second}, - } - check(t, &ss, &out) -} - -func TestUnionInArrayNonNullableNull(t *testing.T) { - // Encoding should fail - var ss test_unions.SmallStruct - ss.PodUnionArray = &[]test_unions.PodUnion{ - nil, - &test_unions.PodUnionFInt8{8}, - &test_unions.PodUnionFInt16{16}, - &test_unions.PodUnionFUint64{64}, - &test_unions.PodUnionFBool{true}, - &test_unions.PodUnionFEnum{test_unions.AnEnum_Second}, - } - - _, _, err := encode(t, &ss) - if typedErr := err.(*bindings.ValidationError); typedErr.ErrorCode != bindings.UnexpectedNullUnion { - t.Fatalf("Non-nullable null should have failed to encode.") - } - - // Decoding should also fail - ss.PodUnionArray = &[]test_unions.PodUnion{ - &test_unions.PodUnionFInt8{8}, - &test_unions.PodUnionFInt16{16}, - &test_unions.PodUnionFUint64{64}, - &test_unions.PodUnionFBool{true}, - &test_unions.PodUnionFEnum{test_unions.AnEnum_Second}, - } - bytes, handles, _ := encode(t, &ss) - - // Set first union to null. - bytes[8*10] = 0 - var decoded test_unions.SmallStruct - decoder := bindings.NewDecoder(bytes, handles) - err = decoded.Decode(decoder) - if typedErr := err.(*bindings.ValidationError); typedErr.ErrorCode != bindings.UnexpectedNullUnion { - t.Fatalf("Null non-nullable should have failed to decode.") - } -} - -func TestUnionInMap(t *testing.T) { - var ss, out test_unions.SmallStruct - ss.PodUnionMap = &map[string]test_unions.PodUnion{ - "eight": &test_unions.PodUnionFInt8{8}, - "sixteen": &test_unions.PodUnionFInt16{16}, - "sixty-four": &test_unions.PodUnionFUint64{64}, - "bool": &test_unions.PodUnionFBool{true}, - "enum": &test_unions.PodUnionFEnum{test_unions.AnEnum_Second}, - } - check(t, &ss, &out) -} diff --git a/mojo/go/tests/validation_test.go b/mojo/go/tests/validation_test.go deleted file mode 100644 index b3120e06bc568..0000000000000 --- a/mojo/go/tests/validation_test.go +++ /dev/null @@ -1,453 +0,0 @@ -// Copyright 2015 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. - -package tests - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "reflect" - "strings" - "testing" - - "mojo/public/go/bindings" - "mojo/public/go/system" - test "mojo/public/interfaces/bindings/tests/validation_test_interfaces" -) - -func getTestPath(name string) string { - // TODO(rogulenko): try to get a better solution. - // This should be .../out/name{Debug|Release}/obj/mojo/go. - dir, err := filepath.Abs(filepath.Dir(os.Args[0])) - if err != nil { - panic(err) - } - // Go 5 folders up. - for i := 0; i < 5; i++ { - dir = filepath.Dir(dir) - } - testsFolder := filepath.Join("mojo", "public", "interfaces", "bindings", "tests", "data", "validation") - if name != "" { - return filepath.Join(dir, testsFolder, name) - } else { - return filepath.Join(dir, testsFolder) - } -} - -func listTestFiles() []string { - files, err := ioutil.ReadDir(getTestPath("")) - if err != nil { - panic(err) - } - var fileNames []string - for _, file := range files { - if file.Mode().IsRegular() { - fileNames = append(fileNames, file.Name()) - } - } - return fileNames -} - -func getMatchingTests(fileNames []string, prefix string) []string { - var result []string - extension := ".data" - for _, fileName := range fileNames { - if strings.HasPrefix(fileName, prefix) && strings.HasSuffix(fileName, extension) { - result = append(result, strings.TrimSuffix(fileName, extension)) - } - } - if len(result) == 0 { - panic("empty test list") - } - return result -} - -func readTest(testName string) ([]byte, []system.UntypedHandle) { - content, err := ioutil.ReadFile(getTestPath(testName + ".data")) - if err != nil { - panic(err) - } - lines := strings.Split(strings.Replace(string(content), "\r", "\n", -1), "\n") - for i, _ := range lines { - lines[i] = strings.Split(lines[i], "//")[0] - } - parser := &inputParser{} - bytes, handles := parser.Parse(strings.Join(lines, " ")) - return bytes, handles -} - -func readAnswer(testName string) string { - content, err := ioutil.ReadFile(getTestPath(testName + ".expected")) - if err != nil { - panic(err) - } - return strings.TrimSpace(string(content)) -} - -func pipeOwner(h system.MessagePipeHandle) bindings.MessagePipeHandleOwner { - return bindings.NewMessagePipeHandleOwner(h) -} - -type rawMessage struct { - Bytes []byte - Handles []system.UntypedHandle -} - -type mockMessagePipeHandle struct { - bindings.InvalidHandle - messages chan rawMessage -} - -func NewMockMessagePipeHandle() *mockMessagePipeHandle { - h := &mockMessagePipeHandle{} - h.messages = make(chan rawMessage, 10) - return h -} - -func (h *mockMessagePipeHandle) reset() { - h.messages = make(chan rawMessage, 10) -} - -func (h *mockMessagePipeHandle) IsValid() bool { - return true -} - -func (h *mockMessagePipeHandle) ToUntypedHandle() system.UntypedHandle { - return h -} - -func (h *mockMessagePipeHandle) ToMessagePipeHandle() system.MessagePipeHandle { - return h -} - -func (h *mockMessagePipeHandle) ReadMessage(flags system.MojoReadMessageFlags) (system.MojoResult, []byte, []system.UntypedHandle) { - message := <-h.messages - return system.MOJO_RESULT_OK, message.Bytes, message.Handles -} - -func (h *mockMessagePipeHandle) WriteMessage(bytes []byte, handles []system.UntypedHandle, flags system.MojoWriteMessageFlags) system.MojoResult { - h.messages <- rawMessage{bytes, handles} - return system.MOJO_RESULT_OK -} - -type conformanceValidator struct { - CheckArgs bool - Proxy test.ConformanceTestInterface -} - -func (v *conformanceValidator) Method0(inParam0 float32) error { - if !v.CheckArgs { - return nil - } - param0 := float32(-1) - if inParam0 != param0 { - return fmt.Errorf("unexpected value (Method0, inParam0): expected %v, got %v", param0, inParam0) - } - return v.Proxy.Method0(inParam0) -} - -func (v *conformanceValidator) Method1(inParam0 test.StructA) error { - if !v.CheckArgs { - return nil - } - param0 := test.StructA{1234} - if !reflect.DeepEqual(inParam0, param0) { - return fmt.Errorf("unexpected value (Method1, inParam0): expected %v, got %v", param0, inParam0) - } - return v.Proxy.Method1(inParam0) -} - -func (v *conformanceValidator) Method2(inParam0 test.StructB, inParam1 test.StructA) error { - if !v.CheckArgs { - return nil - } - param0 := test.StructB{test.StructA{12345}} - param1 := test.StructA{67890} - if !reflect.DeepEqual(inParam0, param0) { - return fmt.Errorf("unexpected value (Method2, inParam0): expected %v, got %v", param0, inParam0) - } - if !reflect.DeepEqual(inParam1, param1) { - return fmt.Errorf("unexpected value (Method2, inParam1): expected %v, got %v", param1, inParam1) - } - return v.Proxy.Method2(inParam0, inParam1) -} - -func (v *conformanceValidator) Method3(inParam0 []bool) error { - if !v.CheckArgs { - return nil - } - param0 := []bool{true, false, true, false, true, false, true, false, true, true, true, true} - if !reflect.DeepEqual(inParam0, param0) { - return fmt.Errorf("unexpected value (Method3, inParam0): expected %v, got %v", param0, inParam0) - } - return v.Proxy.Method3(inParam0) -} - -func (v *conformanceValidator) Method4(inParam0 test.StructC, inParam1 []uint8) error { - if !v.CheckArgs { - return nil - } - param0 := test.StructC{[]uint8{0, 1, 2}} - param1 := []uint8{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} - if !reflect.DeepEqual(inParam0, param0) { - return fmt.Errorf("unexpected value (Method4, inParam0): expected %v, got %v", param0, inParam0) - } - if !reflect.DeepEqual(inParam1, param1) { - return fmt.Errorf("unexpected value (Method4, inParam1): expected %v, got %v", param1, inParam1) - } - return v.Proxy.Method4(inParam0, inParam1) -} - -func (v *conformanceValidator) Method5(inParam0 test.StructE, inParam1 system.ProducerHandle) error { - if !v.CheckArgs { - return nil - } - param0 := test.StructE{ - test.StructD{[]system.MessagePipeHandle{ - &mockHandle{handle: 1}, - &mockHandle{handle: 2}, - }}, - &mockHandle{handle: 4}, - } - param1 := &mockHandle{handle: 5} - if !reflect.DeepEqual(inParam0, param0) { - return fmt.Errorf("unexpected value (Method5, inParam0): expected %v, got %v", param0, inParam0) - } - if !reflect.DeepEqual(inParam1, param1) { - return fmt.Errorf("unexpected value (Method5, inParam1): expected %v, got %v", param1, inParam1) - } - return v.Proxy.Method5(inParam0, inParam1) -} - -func (v *conformanceValidator) Method6(inParam0 [][]uint8) error { - if !v.CheckArgs { - return nil - } - param0 := [][]uint8{[]uint8{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}} - if !reflect.DeepEqual(inParam0, param0) { - return fmt.Errorf("unexpected value (Method6, inParam0): expected %v, got %v", param0, inParam0) - } - return v.Proxy.Method6(inParam0) -} - -func (v *conformanceValidator) Method7(inParam0 test.StructF, inParam1 [2]*[3]uint8) error { - if !v.CheckArgs { - return nil - } - param0 := test.StructF{[3]uint8{0, 1, 2}} - param1 := [2]*[3]uint8{ - nil, - &[3]uint8{0, 1, 2}, - } - if !reflect.DeepEqual(inParam0, param0) { - return fmt.Errorf("unexpected value (Method7, inParam0): expected %v, got %v", param0, inParam0) - } - if !reflect.DeepEqual(inParam1, param1) { - return fmt.Errorf("unexpected value (Method7, inParam1): expected %v, got %v", param1, inParam1) - } - return v.Proxy.Method7(inParam0, inParam1) -} - -func (v *conformanceValidator) Method8(inParam0 []*[]string) error { - if !v.CheckArgs { - return nil - } - param0 := []*[]string{ - nil, - &[]string{string([]byte{0, 1, 2, 3, 4})}, - nil, - } - if !reflect.DeepEqual(inParam0, param0) { - return fmt.Errorf("unexpected value (Method8, inParam0): expected %v, got %v", param0, inParam0) - } - return v.Proxy.Method8(inParam0) -} - -func (v *conformanceValidator) Method9(inParam0 *[][]*system.Handle) error { - if !v.CheckArgs { - return nil - } - handles := []system.Handle{ - &mockHandle{handle: 1}, - &mockHandle{handle: 3}, - &mockHandle{handle: 4}, - } - param0 := &[][]*system.Handle{ - []*system.Handle{&handles[0], nil}, - []*system.Handle{&handles[1], nil, &handles[2]}, - } - if !reflect.DeepEqual(inParam0, param0) { - return fmt.Errorf("unexpected value (Method9, inParam0): expected %v, got %v", param0, inParam0) - } - return v.Proxy.Method9(inParam0) -} - -func (v *conformanceValidator) Method10(inParam0 map[string]uint8) error { - if !v.CheckArgs { - return nil - } - param0 := map[string]uint8{ - string([]byte{0, 1, 2, 3, 4}): 1, - string([]byte{5, 6, 7, 8, 9}): 2, - } - if !reflect.DeepEqual(inParam0, param0) { - return fmt.Errorf("unexpected value (Method10, inParam0): expected %v, got %v", param0, inParam0) - } - return v.Proxy.Method10(inParam0) -} - -func (v *conformanceValidator) Method11(test.StructG) error { - return nil -} - -func (v *conformanceValidator) Method12(float32) (float32, error) { - return 0, nil -} - -func (v *conformanceValidator) Method13(*test.InterfaceA_Pointer, uint32, *test.InterfaceA_Pointer) error { - return nil -} - -func verifyValidationError(t *testing.T, test string, err error, answer string) { - if (err == nil) != (answer == "PASS") { - t.Fatalf("unexpected result for test %v: %v", test, err) - } - if answer != "PASS" { - validationError, ok := err.(*bindings.ValidationError) - if !ok { - t.Fatalf("can't convert err '%v' to ValidationError in test %v", err, test) - } - code := validationError.ErrorCode - if code != answer { - t.Fatalf("unexpected error code in test %v: got %v(%v), want %v", test, code, err, answer) - } - } -} - -func TestConformanceValidation(t *testing.T) { - tests := getMatchingTests(listTestFiles(), "conformance_") - - h := NewMockMessagePipeHandle() - proxyIn, proxyOut := h, h - interfacePointer := test.ConformanceTestInterface_Pointer{pipeOwner(proxyIn)} - impl := &conformanceValidator{false, test.NewConformanceTestInterfaceProxy(interfacePointer, waiter)} - - h = NewMockMessagePipeHandle() - stubIn, stubOut := h, h - interfaceRequest := test.ConformanceTestInterface_Request{pipeOwner(stubOut)} - stub := test.NewConformanceTestInterfaceStub(interfaceRequest, impl, waiter) - for _, test := range tests { - bytes, handles := readTest(test) - answer := readAnswer(test) - impl.CheckArgs = strings.HasSuffix(test, "_good") - stubIn.WriteMessage(bytes, handles, system.MOJO_WRITE_MESSAGE_FLAG_NONE) - err := stub.ServeRequest() - verifyValidationError(t, test, err, answer) - - if !impl.CheckArgs { - continue - } - // Decode again to verify correctness of encoding. - _, bytes, handles = proxyOut.ReadMessage(system.MOJO_READ_MESSAGE_FLAG_NONE) - stubIn.WriteMessage(bytes, handles, system.MOJO_WRITE_MESSAGE_FLAG_NONE) - if err := stub.ServeRequest(); err != nil { - t.Fatalf("error processing encoded data for test %v: %v", test, err) - } - proxyOut.ReadMessage(system.MOJO_READ_MESSAGE_FLAG_NONE) - // Do not compare encoded bytes, as some tests contain maps, that - // can be encoded randomly. - } -} - -func runTests(t *testing.T, prefix string, in *mockMessagePipeHandle, check func() error) { - tests := getMatchingTests(listTestFiles(), prefix) - for _, test := range tests { - bytes, handles := readTest(test) - answer := readAnswer(test) - // Replace request ID to match proxy numbers. - if bytes[0] == 24 { - bytes[16] = 1 - } - in.WriteMessage(bytes, handles, system.MOJO_WRITE_MESSAGE_FLAG_NONE) - verifyValidationError(t, test, check(), answer) - } -} - -type integrationStubImpl struct{} - -func (s *integrationStubImpl) Method0(test.BasicStruct) ([]uint8, error) { - return nil, nil -} - -func TestIntegrationTests(t *testing.T) { - h := NewMockMessagePipeHandle() - checkStub := func() error { - interfaceRequest := test.IntegrationTestInterface_Request{pipeOwner(h)} - stub := test.NewIntegrationTestInterfaceStub(interfaceRequest, &integrationStubImpl{}, waiter) - err := stub.ServeRequest() - stub.Close() - h.reset() - return err - } - runTests(t, "integration_intf_rqst_", h, checkStub) - runTests(t, "integration_msghdr_", h, checkStub) - - checkProxy := func() error { - interfacePointer := test.IntegrationTestInterface_Pointer{pipeOwner(h)} - proxy := test.NewIntegrationTestInterfaceProxy(interfacePointer, waiter) - _, err := proxy.Method0(test.BasicStruct{}) - proxy.Close_Proxy() - h.reset() - return err - } - runTests(t, "integration_intf_resp_", h, checkProxy) - runTests(t, "integration_msghdr_", h, checkProxy) -} - -type boundsCheckStubImpl struct{} - -func (s *boundsCheckStubImpl) Method0(uint8) (uint8, error) { - return 0, nil -} - -func (s *boundsCheckStubImpl) Method1(uint8) error { - return nil -} - -func TestBoundsCheck(t *testing.T) { - h := NewMockMessagePipeHandle() - checkStub := func() error { - interfaceRequest := test.BoundsCheckTestInterface_Request{pipeOwner(h)} - stub := test.NewBoundsCheckTestInterfaceStub(interfaceRequest, &boundsCheckStubImpl{}, waiter) - err := stub.ServeRequest() - stub.Close() - return err - } - runTests(t, "boundscheck_", h, checkStub) - - checkProxy := func() error { - interfacePointer := test.BoundsCheckTestInterface_Pointer{pipeOwner(h)} - proxy := test.NewBoundsCheckTestInterfaceProxy(interfacePointer, waiter) - _, err := proxy.Method0(0) - proxy.Close_Proxy() - h.reset() - return err - } - runTests(t, "resp_boundscheck_", h, checkProxy) -} - -func TestConformanceResponse(t *testing.T) { - h := NewMockMessagePipeHandle() - checkProxy := func() error { - interfacePointer := test.ConformanceTestInterface_Pointer{pipeOwner(h)} - proxy := test.NewConformanceTestInterfaceProxy(interfacePointer, waiter) - _, err := proxy.Method12(0) - proxy.Close_Proxy() - h.reset() - return err - } - runTests(t, "resp_conformance_", h, checkProxy) -} diff --git a/mojo/gpu/BUILD.gn b/mojo/gpu/BUILD.gn index fb0e4d86cd3bf..44faf9192d2cf 100644 --- a/mojo/gpu/BUILD.gn +++ b/mojo/gpu/BUILD.gn @@ -28,6 +28,7 @@ source_set("gpu") { "//gpu/command_buffer/common", "//mojo/environment:chromium", "//mojo/public/c/gles2", + "//mojo/public/c/gpu:gpu_onscreen", "//mojo/public/c/system", "//mojo/public/cpp/application", "//mojo/public/cpp/bindings", diff --git a/mojo/gpu/gl_context.cc b/mojo/gpu/gl_context.cc index 73941d64488c8..3b4830a779915 100644 --- a/mojo/gpu/gl_context.cc +++ b/mojo/gpu/gl_context.cc @@ -7,6 +7,7 @@ #include "mojo/public/cpp/application/connect.h" #include "mojo/public/interfaces/application/shell.mojom.h" #include "mojo/services/gpu/public/interfaces/gpu.mojom.h" +#include "mojo/gpu/mojo_gles2_impl_autogen.h" namespace mojo { @@ -24,8 +25,7 @@ GLContext::GLContext(Shell* shell) : weak_factory_(this) { context_ = MojoGLES2CreateContext( command_buffer.PassInterface().PassHandle().release().value(), &ContextLostThunk, this, Environment::GetDefaultAsyncWaiter()); - gl_ = static_cast( - MojoGLES2GetGLES2Interface(context_)); + gl_impl_.reset(new MojoGLES2Impl(context_)); } GLContext::~GLContext() { @@ -44,6 +44,10 @@ void GLContext::Destroy() { delete this; } +gpu::gles2::GLES2Interface* GLContext::gl() const { + return gl_impl_.get(); +} + void GLContext::AddObserver(Observer* observer) { observers_.AddObserver(observer); } diff --git a/mojo/gpu/gl_context.h b/mojo/gpu/gl_context.h index 79ef518552bdb..9c5eb3ab35180 100644 --- a/mojo/gpu/gl_context.h +++ b/mojo/gpu/gl_context.h @@ -17,6 +17,7 @@ class GLES2Interface; } namespace mojo { +class MojoGLES2Impl; class Shell; class GLContext { @@ -34,7 +35,7 @@ class GLContext { void MakeCurrent(); void Destroy(); - gpu::gles2::GLES2Interface* gl() const { return gl_; } + gpu::gles2::GLES2Interface* gl() const; void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); @@ -47,7 +48,7 @@ class GLContext { void OnContextLost(); MojoGLES2Context context_; - gpu::gles2::GLES2Interface* gl_; + scoped_ptr gl_impl_; base::ObserverList observers_; base::WeakPtrFactory weak_factory_; diff --git a/mojo/gpu/mojo_gles2_impl_autogen.cc b/mojo/gpu/mojo_gles2_impl_autogen.cc index a716a4d48659d..fb55202642917 100644 --- a/mojo/gpu/mojo_gles2_impl_autogen.cc +++ b/mojo/gpu/mojo_gles2_impl_autogen.cc @@ -11,9 +11,16 @@ #include "mojo/gpu/mojo_gles2_impl_autogen.h" #include "base/logging.h" +#include "mojo/public/c/gles2/chromium_bind_uniform_location.h" +#include "mojo/public/c/gles2/chromium_map_sub.h" +#include "mojo/public/c/gles2/chromium_miscellaneous.h" #include "mojo/public/c/gles2/chromium_sync_point.h" #include "mojo/public/c/gles2/chromium_texture_mailbox.h" +#include "mojo/public/c/gles2/ext_debug_marker.h" #include "mojo/public/c/gles2/gles2.h" +#include "mojo/public/c/gles2/occlusion_query_ext.h" +#include "mojo/public/c/gles2/oes_vertex_array_object.h" +#include "mojo/public/c/gpu/MGL/mgl_onscreen.h" namespace mojo { @@ -771,8 +778,8 @@ void MojoGLES2Impl::ShallowFinishCHROMIUM() { NOTREACHED() << "Unimplemented ShallowFinishCHROMIUM."; } void MojoGLES2Impl::ShallowFlushCHROMIUM() { - return static_cast( - MojoGLES2GetGLES2Interface(context_))->ShallowFlushCHROMIUM(); + MojoGLES2MakeCurrent(context_); + glShallowFlushCHROMIUM(); } void MojoGLES2Impl::OrderingBarrierCHROMIUM() { NOTREACHED() << "Unimplemented OrderingBarrierCHROMIUM."; @@ -1203,63 +1210,68 @@ void MojoGLES2Impl::TexStorage2DEXT(GLenum target, NOTREACHED() << "Unimplemented TexStorage2DEXT."; } void MojoGLES2Impl::GenQueriesEXT(GLsizei n, GLuint* queries) { - return static_cast( - MojoGLES2GetGLES2Interface(context_))->GenQueriesEXT(n, queries); + MojoGLES2MakeCurrent(context_); + glGenQueriesEXT(n, queries); } void MojoGLES2Impl::DeleteQueriesEXT(GLsizei n, const GLuint* queries) { - return static_cast( - MojoGLES2GetGLES2Interface(context_)) - ->DeleteQueriesEXT(n, queries); + MojoGLES2MakeCurrent(context_); + glDeleteQueriesEXT(n, queries); } GLboolean MojoGLES2Impl::IsQueryEXT(GLuint id) { - NOTREACHED() << "Unimplemented IsQueryEXT."; - return 0; + MojoGLES2MakeCurrent(context_); + return glIsQueryEXT(id); } void MojoGLES2Impl::BeginQueryEXT(GLenum target, GLuint id) { - return static_cast( - MojoGLES2GetGLES2Interface(context_))->BeginQueryEXT(target, id); + MojoGLES2MakeCurrent(context_); + glBeginQueryEXT(target, id); } void MojoGLES2Impl::BeginTransformFeedback(GLenum primitivemode) { NOTREACHED() << "Unimplemented BeginTransformFeedback."; } void MojoGLES2Impl::EndQueryEXT(GLenum target) { - return static_cast( - MojoGLES2GetGLES2Interface(context_))->EndQueryEXT(target); + MojoGLES2MakeCurrent(context_); + glEndQueryEXT(target); } void MojoGLES2Impl::EndTransformFeedback() { NOTREACHED() << "Unimplemented EndTransformFeedback."; } void MojoGLES2Impl::GetQueryivEXT(GLenum target, GLenum pname, GLint* params) { - NOTREACHED() << "Unimplemented GetQueryivEXT."; + MojoGLES2MakeCurrent(context_); + glGetQueryivEXT(target, pname, params); } void MojoGLES2Impl::GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) { - return static_cast( - MojoGLES2GetGLES2Interface(context_)) - ->GetQueryObjectuivEXT(id, pname, params); + MojoGLES2MakeCurrent(context_); + glGetQueryObjectuivEXT(id, pname, params); } void MojoGLES2Impl::InsertEventMarkerEXT(GLsizei length, const GLchar* marker) { - NOTREACHED() << "Unimplemented InsertEventMarkerEXT."; + MojoGLES2MakeCurrent(context_); + glInsertEventMarkerEXT(length, marker); } void MojoGLES2Impl::PushGroupMarkerEXT(GLsizei length, const GLchar* marker) { - NOTREACHED() << "Unimplemented PushGroupMarkerEXT."; + MojoGLES2MakeCurrent(context_); + glPushGroupMarkerEXT(length, marker); } void MojoGLES2Impl::PopGroupMarkerEXT() { - NOTREACHED() << "Unimplemented PopGroupMarkerEXT."; + MojoGLES2MakeCurrent(context_); + glPopGroupMarkerEXT(); } void MojoGLES2Impl::GenVertexArraysOES(GLsizei n, GLuint* arrays) { - NOTREACHED() << "Unimplemented GenVertexArraysOES."; + MojoGLES2MakeCurrent(context_); + glGenVertexArraysOES(n, arrays); } void MojoGLES2Impl::DeleteVertexArraysOES(GLsizei n, const GLuint* arrays) { - NOTREACHED() << "Unimplemented DeleteVertexArraysOES."; + MojoGLES2MakeCurrent(context_); + glDeleteVertexArraysOES(n, arrays); } GLboolean MojoGLES2Impl::IsVertexArrayOES(GLuint array) { - NOTREACHED() << "Unimplemented IsVertexArrayOES."; - return 0; + MojoGLES2MakeCurrent(context_); + return glIsVertexArrayOES(array); } void MojoGLES2Impl::BindVertexArrayOES(GLuint array) { - NOTREACHED() << "Unimplemented BindVertexArrayOES."; + MojoGLES2MakeCurrent(context_); + glBindVertexArrayOES(array); } void MojoGLES2Impl::SwapBuffers() { NOTREACHED() << "Unimplemented SwapBuffers."; @@ -1287,11 +1299,12 @@ void* MojoGLES2Impl::MapBufferSubDataCHROMIUM(GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) { - NOTREACHED() << "Unimplemented MapBufferSubDataCHROMIUM."; - return 0; + MojoGLES2MakeCurrent(context_); + return glMapBufferSubDataCHROMIUM(target, offset, size, access); } void MojoGLES2Impl::UnmapBufferSubDataCHROMIUM(const void* mem) { - NOTREACHED() << "Unimplemented UnmapBufferSubDataCHROMIUM."; + MojoGLES2MakeCurrent(context_); + glUnmapBufferSubDataCHROMIUM(mem); } void* MojoGLES2Impl::MapBufferRange(GLenum target, GLintptr offset, @@ -1313,20 +1326,19 @@ void* MojoGLES2Impl::MapTexSubImage2DCHROMIUM(GLenum target, GLenum format, GLenum type, GLenum access) { - return static_cast( - MojoGLES2GetGLES2Interface(context_)) - ->MapTexSubImage2DCHROMIUM(target, level, xoffset, yoffset, width, height, - format, type, access); + MojoGLES2MakeCurrent(context_); + return glMapTexSubImage2DCHROMIUM(target, level, xoffset, yoffset, width, + height, format, type, access); } void MojoGLES2Impl::UnmapTexSubImage2DCHROMIUM(const void* mem) { - return static_cast( - MojoGLES2GetGLES2Interface(context_)) - ->UnmapTexSubImage2DCHROMIUM(mem); + MojoGLES2MakeCurrent(context_); + glUnmapTexSubImage2DCHROMIUM(mem); } void MojoGLES2Impl::ResizeCHROMIUM(GLuint width, GLuint height, GLfloat scale_factor) { - NOTREACHED() << "Unimplemented ResizeCHROMIUM."; + MojoGLES2MakeCurrent(context_); + MGLResizeSurface(width, height); } const GLchar* MojoGLES2Impl::GetRequestableExtensionsCHROMIUM() { NOTREACHED() << "Unimplemented GetRequestableExtensionsCHROMIUM."; @@ -1460,7 +1472,8 @@ GLuint MojoGLES2Impl::CreateAndConsumeTextureCHROMIUM(GLenum target, void MojoGLES2Impl::BindUniformLocationCHROMIUM(GLuint program, GLint location, const char* name) { - NOTREACHED() << "Unimplemented BindUniformLocationCHROMIUM."; + MojoGLES2MakeCurrent(context_); + glBindUniformLocationCHROMIUM(program, location, name); } void MojoGLES2Impl::GenValuebuffersCHROMIUM(GLsizei n, GLuint* buffers) { NOTREACHED() << "Unimplemented GenValuebuffersCHROMIUM."; diff --git a/mojo/message_pump/BUILD.gn b/mojo/message_pump/BUILD.gn new file mode 100644 index 0000000000000..14daad6df93d3 --- /dev/null +++ b/mojo/message_pump/BUILD.gn @@ -0,0 +1,39 @@ +# Copyright 2015 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. + +source_set("message_pump") { + sources = [ + "handle_watcher.cc", + "handle_watcher.h", + "message_pump_mojo.cc", + "message_pump_mojo.h", + "message_pump_mojo_handler.h", + "time_helper.cc", + "time_helper.h", + ] + + deps = [ + "//base", + "//mojo/public/cpp/system", + ] +} + +source_set("tests") { + testonly = true + + sources = [ + "handle_watcher_unittest.cc", + "message_pump_mojo_unittest.cc", + ] + + deps = [ + ":message_pump", + "//base", + "//base/test:test_support", + "//base:message_loop_tests", + "//mojo/public/cpp/system", + "//mojo/public/cpp/test_support:test_utils", + "//testing/gtest", + ] +} diff --git a/mojo/common/handle_watcher.cc b/mojo/message_pump/handle_watcher.cc similarity index 98% rename from mojo/common/handle_watcher.cc rename to mojo/message_pump/handle_watcher.cc index c7fa81fd8a10a..2465579261945 100644 --- a/mojo/common/handle_watcher.cc +++ b/mojo/message_pump/handle_watcher.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/common/handle_watcher.h" +#include "mojo/message_pump/handle_watcher.h" #include @@ -20,9 +20,9 @@ #include "base/threading/thread.h" #include "base/threading/thread_restrictions.h" #include "base/time/time.h" -#include "mojo/common/message_pump_mojo.h" -#include "mojo/common/message_pump_mojo_handler.h" -#include "mojo/common/time_helper.h" +#include "mojo/message_pump/message_pump_mojo.h" +#include "mojo/message_pump/message_pump_mojo_handler.h" +#include "mojo/message_pump/time_helper.h" namespace mojo { namespace common { diff --git a/mojo/common/handle_watcher.h b/mojo/message_pump/handle_watcher.h similarity index 93% rename from mojo/common/handle_watcher.h rename to mojo/message_pump/handle_watcher.h index fb89716c44cfa..f024d94f12f95 100644 --- a/mojo/common/handle_watcher.h +++ b/mojo/message_pump/handle_watcher.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MOJO_COMMON_HANDLE_WATCHER_H_ -#define MOJO_COMMON_HANDLE_WATCHER_H_ +#ifndef MOJO_MESSAGE_PUMP_HANDLE_WATCHER_H_ +#define MOJO_MESSAGE_PUMP_HANDLE_WATCHER_H_ #include "base/basictypes.h" #include "base/callback_forward.h" @@ -60,4 +60,4 @@ class HandleWatcher { } // namespace common } // namespace mojo -#endif // MOJO_COMMON_HANDLE_WATCHER_H_ +#endif // MOJO_MESSAGE_PUMP_HANDLE_WATCHER_H_ diff --git a/mojo/common/handle_watcher_unittest.cc b/mojo/message_pump/handle_watcher_unittest.cc similarity index 99% rename from mojo/common/handle_watcher_unittest.cc rename to mojo/message_pump/handle_watcher_unittest.cc index 46d2a27c56232..36f15accac566 100644 --- a/mojo/common/handle_watcher_unittest.cc +++ b/mojo/message_pump/handle_watcher_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/common/handle_watcher.h" +#include "mojo/message_pump/handle_watcher.h" #include @@ -13,8 +13,8 @@ #include "base/run_loop.h" #include "base/test/simple_test_tick_clock.h" #include "base/threading/thread.h" -#include "mojo/common/message_pump_mojo.h" -#include "mojo/common/time_helper.h" +#include "mojo/message_pump/message_pump_mojo.h" +#include "mojo/message_pump/time_helper.h" #include "mojo/public/cpp/system/core.h" #include "mojo/public/cpp/test_support/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/mojo/common/message_pump_mojo.cc b/mojo/message_pump/message_pump_mojo.cc similarity index 98% rename from mojo/common/message_pump_mojo.cc rename to mojo/message_pump/message_pump_mojo.cc index 544960be739b7..e7f7d10601128 100644 --- a/mojo/common/message_pump_mojo.cc +++ b/mojo/message_pump/message_pump_mojo.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/common/message_pump_mojo.h" +#include "mojo/message_pump/message_pump_mojo.h" #include #include @@ -12,8 +12,8 @@ #include "base/logging.h" #include "base/threading/thread_local.h" #include "base/time/time.h" -#include "mojo/common/message_pump_mojo_handler.h" -#include "mojo/common/time_helper.h" +#include "mojo/message_pump/message_pump_mojo_handler.h" +#include "mojo/message_pump/time_helper.h" namespace mojo { namespace common { diff --git a/mojo/common/message_pump_mojo.h b/mojo/message_pump/message_pump_mojo.h similarity index 96% rename from mojo/common/message_pump_mojo.h rename to mojo/message_pump/message_pump_mojo.h index fc1e40b1032cd..522b0e51a1ac0 100644 --- a/mojo/common/message_pump_mojo.h +++ b/mojo/message_pump/message_pump_mojo.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MOJO_COMMON_MESSAGE_PUMP_MOJO_H_ -#define MOJO_COMMON_MESSAGE_PUMP_MOJO_H_ +#ifndef MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_H_ +#define MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_H_ #include #include @@ -135,4 +135,4 @@ class MessagePumpMojo : public base::MessagePump { } // namespace common } // namespace mojo -#endif // MOJO_COMMON_MESSAGE_PUMP_MOJO_H_ +#endif // MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_H_ diff --git a/mojo/common/message_pump_mojo_handler.h b/mojo/message_pump/message_pump_mojo_handler.h similarity index 79% rename from mojo/common/message_pump_mojo_handler.h rename to mojo/message_pump/message_pump_mojo_handler.h index b55132de1e8ff..3a4ecccb0c75f 100644 --- a/mojo/common/message_pump_mojo_handler.h +++ b/mojo/message_pump/message_pump_mojo_handler.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MOJO_COMMON_MESSAGE_PUMP_MOJO_HANDLER_H_ -#define MOJO_COMMON_MESSAGE_PUMP_MOJO_HANDLER_H_ +#ifndef MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_HANDLER_H_ +#define MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_HANDLER_H_ #include "mojo/public/cpp/system/core.h" @@ -25,4 +25,4 @@ class MessagePumpMojoHandler { } // namespace common } // namespace mojo -#endif // MOJO_COMMON_MESSAGE_PUMP_MOJO_HANDLER_H_ +#endif // MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_HANDLER_H_ diff --git a/mojo/common/message_pump_mojo_unittest.cc b/mojo/message_pump/message_pump_mojo_unittest.cc similarity index 97% rename from mojo/common/message_pump_mojo_unittest.cc rename to mojo/message_pump/message_pump_mojo_unittest.cc index 09cbe54a63a1e..687d5f39dc0e9 100644 --- a/mojo/common/message_pump_mojo_unittest.cc +++ b/mojo/message_pump/message_pump_mojo_unittest.cc @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/common/message_pump_mojo.h" +#include "mojo/message_pump/message_pump_mojo.h" #include "base/message_loop/message_loop_test.h" #include "base/run_loop.h" -#include "mojo/common/message_pump_mojo_handler.h" +#include "mojo/message_pump/message_pump_mojo_handler.h" #include "mojo/public/cpp/system/core.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/mojo/common/time_helper.cc b/mojo/message_pump/time_helper.cc similarity index 93% rename from mojo/common/time_helper.cc rename to mojo/message_pump/time_helper.cc index 36fd0879e349a..ffd667e47d7e6 100644 --- a/mojo/common/time_helper.cc +++ b/mojo/message_pump/time_helper.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/common/time_helper.h" +#include "mojo/message_pump/time_helper.h" #include "base/time/tick_clock.h" diff --git a/mojo/common/time_helper.h b/mojo/message_pump/time_helper.h similarity index 84% rename from mojo/common/time_helper.h rename to mojo/message_pump/time_helper.h index 84029ecaf7e04..dfdc7bb872a6c 100644 --- a/mojo/common/time_helper.h +++ b/mojo/message_pump/time_helper.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MOJO_COMMON_TIME_HELPER_H_ -#define MOJO_COMMON_TIME_HELPER_H_ +#ifndef MOJO_MESSAGE_PUMP_TIME_HELPER_H_ +#define MOJO_MESSAGE_PUMP_TIME_HELPER_H_ #include "base/time/time.h" @@ -30,4 +30,4 @@ base::TimeTicks NowTicks(); } // namespace common } // namespace mojo -#endif // MOJO_COMMON_TIME_HELPER_H_ +#endif // MOJO_MESSAGE_PUMP_TIME_HELPER_H_ diff --git a/mojo/mojo_apps_js_unittests.isolate b/mojo/mojo_apps_js_unittests.isolate deleted file mode 100644 index 6921a46ce388a..0000000000000 --- a/mojo/mojo_apps_js_unittests.isolate +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2014 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. -{ - 'includes': [ - '../third_party/icu/icu.isolate', - ], - 'conditions': [ - ['OS=="win" or OS=="mac" or OS=="linux"', { - 'variables': { - 'command': [ - '../testing/test_env.py', - '<(PRODUCT_DIR)/mojo_apps_js_unittests<(EXECUTABLE_SUFFIX)', - '--brave-new-test-launcher', - '--test-launcher-bot-mode', - ], - 'files': [ - '../gin/test/expect.js', - '../testing/test_env.py', - '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/', - '<(PRODUCT_DIR)/mojo_apps_js_unittests<(EXECUTABLE_SUFFIX)', - 'apps/js/', - 'bindings/js/', - 'public/js/bindings/', - ], - }, - }], - ['OS=="win"', { - 'variables': { - 'files': [ - '<(PRODUCT_DIR)/mojo_test_support.dll', - ], - }, - }], - ['OS=="linux"', { - 'variables': { - 'files': [ - '<(PRODUCT_DIR)/lib/libmojo_test_support.so', - ], - }, - }], - ['OS=="mac"', { - 'variables': { - 'files': [ - '<(PRODUCT_DIR)/libmojo_test_support.dylib', - ], - }, - }], - ], -} diff --git a/mojo/mojo_js_unittests.isolate b/mojo/mojo_js_unittests.isolate deleted file mode 100644 index 2b3131b2b3c67..0000000000000 --- a/mojo/mojo_js_unittests.isolate +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright 2014 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. -{ - 'includes': [ - '../third_party/icu/icu.isolate', - ], - 'conditions': [ - ['OS=="win" or OS=="mac" or OS=="linux"', { - 'variables': { - 'command': [ - '../testing/test_env.py', - '<(PRODUCT_DIR)/mojo_js_unittests<(EXECUTABLE_SUFFIX)', - '--brave-new-test-launcher', - '--test-launcher-bot-mode', - ], - 'files': [ - '../gin/test/expect.js', - '../testing/test_env.py', - '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/', - '<(PRODUCT_DIR)/mojo_js_unittests<(EXECUTABLE_SUFFIX)', - 'bindings/js/', - 'public/js/bindings/', - ], - }, - }], - ['OS=="win"', { - 'variables': { - 'files': [ - '<(PRODUCT_DIR)/mojo_test_support.dll', - ], - }, - }], - ['OS=="linux"', { - 'variables': { - 'files': [ - '<(PRODUCT_DIR)/lib/libmojo_test_support.so', - ], - }, - }], - ['OS=="mac"', { - 'variables': { - 'files': [ - '<(PRODUCT_DIR)/libmojo_test_support.dylib', - ], - }, - }], - ], -} diff --git a/mojo/mojo_python_unittests.isolate b/mojo/mojo_python_unittests.isolate deleted file mode 100644 index 4fea84ae1d073..0000000000000 --- a/mojo/mojo_python_unittests.isolate +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2014 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. -{ - 'conditions': [ - ['OS=="linux"', { - 'variables': { - 'command': [ - 'tools/run_mojo_python_bindings_tests.py', - '--build-dir=<(PRODUCT_DIR)', - ], - 'files': [ - '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/', - '<(PRODUCT_DIR)/python/', - 'python/tests/', - 'tools/pylib/mojo_python_tests_runner.py', - 'tools/run_mojo_python_bindings_tests.py', - ], - }, - }], - ], -} diff --git a/mojo/nacl/BUILD.gn b/mojo/nacl/BUILD.gn deleted file mode 100644 index 0c37c18234832..0000000000000 --- a/mojo/nacl/BUILD.gn +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright 2015 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. - -# Trusted code -if (!is_nacl) { - # A simple shell for running untrusted binaries that talk to the Mojo - # embedder. (No services.) - executable("monacl_shell") { - testonly = true - sources = [ - "monacl_shell.cc", - ] - deps = [ - "//base:base", - "//mojo/edk/system:system", - "//nacl_bindings:monacl_sel", - ] - - data_deps = [ "//nacl_bindings:irt_mojo(//native_client/build/toolchain/nacl:irt_${target_cpu})" ] - } -} - -# Untrusted code -if (is_nacl) { - # Unit test for the Mojo public API. - executable("monacl_test") { - testonly = true - sources = [ - "//mojo/public/cpp/system/tests/core_unittest.cc", - "//mojo/public/cpp/system/tests/macros_unittest.cc", - ] - deps = [ - "//mojo/public/c/system/tests:tests", - "//mojo/public/cpp/system:system", - "//mojo/public/platform/nacl:mojo", - "//testing/gtest:gtest", - "//testing/gtest:gtest_main", - ] - } - - group("mojo_nacl_tests_untrusted") { - testonly = true - deps = [ - ":monacl_test", - "//examples/apptest", - "//examples/wget", - "//services/clipboard", - "//services/clipboard:apptests", - "//services/files:apptests", - - # TODO(ncbray): enable when NaCl has pthread rw locks. - #"//services/http_server", - "//services/http_server:apptests", - "//services/view_manager:mojo_view_manager_client_apptests", - "//services/view_manager:view_manager_service_apptests", - "//services/window_manager:window_manager_apptests", - "//shell:apptests", - ] - } -} - -group("mojo_nacl") { - deps = [ - "//services/nacl:nacl_content_handler", - ] -} - -group("mojo_nacl_tests") { - testonly = true - deps = [ - ":mojo_nacl_tests_untrusted(//native_client/build/toolchain/nacl:clang_newlib_${current_cpu})", - ":monacl_shell", - ] -} diff --git a/mojo/nacl/README.md b/mojo/nacl/README.md deleted file mode 100644 index 412c4de185f60..0000000000000 --- a/mojo/nacl/README.md +++ /dev/null @@ -1,37 +0,0 @@ -About -===== - -This is a prototype for plumbing Mojo into the NaCl sandbox. It is -currently insecure (see below), does not provide a stable ABI (IRT -support must be added), and does not support Mojo functions that -return pointers (for example, `MojoMapBuffer`). - - -Using -===== - -To use this prototype run `mojo/tools/mojob.py gn --nacl` and then build -and test as usual. - -Run `mojo/tools/mojob.py nacltest` for additional nacl-specific tests. - - -Notes -===== - -`generator/interface.py` contains a programmatic description of the -stable Mojo interface. This will need to be updated as the interface -changes. Run `generator/generate_nacl_bindings.py` to generate the -bindings that plumb this interface into the NaCl sandbox. - - -Security TODO -============= - -* Separate trusted and untrusted Mojo handles. -* Validate and copy option structures. -* Protect untrusted buffers passed into Mojo: - * `NaClVmIoWillStart/HasEnded`. - * volatile accesses to untrusted memory (untrusted code could race). -* Overflow checking in array bounds validation. - diff --git a/mojo/nacl/monacl_shell.cc b/mojo/nacl/monacl_shell.cc deleted file mode 100644 index 714c04f63318a..0000000000000 --- a/mojo/nacl/monacl_shell.cc +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2014 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 - -#include "base/files/file.h" -#include "base/files/file_path.h" -#include "base/logging.h" -#include "mojo/edk/embedder/embedder.h" -#include "mojo/edk/embedder/simple_platform_support.h" -#include "nacl_bindings/monacl_sel_main.h" -#include "native_client/src/public/nacl_desc.h" - -NaClDesc* OpenFile(const char* filename) { - base::FilePath path(filename); - base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); - if (!file.IsValid()) { - perror(filename); - exit(1); - } - return NaClDescCreateWithFilePathMetadata(file.TakePlatformFile(), ""); -} - -int main(int argc, char* argv[]) { - if (argc < 3) { - std::cout << "Usage: " << argv[0] << " irt.nexe app.nexe [args for app]" << - std::endl; - return 1; - } - - const char* irt_file = argv[1]; - const char* nexe_file = argv[2]; - - NaClDesc* irt_desc = OpenFile(irt_file); - NaClDesc* nexe_desc = OpenFile(nexe_file); - - mojo::embedder::Init(scoped_ptr( - new mojo::embedder::SimplePlatformSupport())); - - int exit_code = mojo::LaunchNaCl(nexe_desc, irt_desc, argc - 2, argv + 2, - MOJO_HANDLE_INVALID); - - // Exits the process cleanly, does not return. - mojo::NaClExit(exit_code); - NOTREACHED(); - return 1; -} diff --git a/mojo/python/BUILD.gn b/mojo/python/BUILD.gn deleted file mode 100644 index 92bfd60a8c9df..0000000000000 --- a/mojo/python/BUILD.gn +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2014 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. - -import("//mojo/public/python/rules.gni") -import("//third_party/cython/rules.gni") - -group("python") { - deps = [ - ":mojo_embedder", - ":packaged_utils", - ":utils", - ":validation_util", - "//mojo/public/python", - ] -} - -copy("utils") { - sources = [ - "mojo_utils/__init__.py", - "mojo_utils/data_pipe_utils.py", - ] - outputs = [ - "$root_out_dir/python/mojo_utils/{{source_file_part}}", - ] -} - -python_package("packaged_utils") { - sources = [ - "mojo_utils/__init__.py", - "mojo_utils/data_pipe_utils.py", - ] - datadeps = [ - "//mojo/public/python:mojo_system", - ] -} - -python_binary_module("mojo_embedder") { - cython_sources = [ "system/mojo_embedder.pyx" ] - deps = [ - "//mojo/edk/system", - ] - datadeps = [ - "//mojo/public/python:mojo_system", - ] -} - -copy("tests_module") { - sources = [ - "system/mojo_tests/__init__.py", - ] - outputs = [ - "$root_out_dir/python/mojo_tests/{{source_file_part}}", - ] -} - -python_binary_module("validation_util") { - python_base_module = "mojo_tests" - cython_sources = [ "system/mojo_tests/validation_util.pyx" ] - deps = [ - "//mojo/public/cpp/bindings/tests:mojo_public_bindings_test_utils", - ] - datadeps = [ - ":tests_module", - ] -} diff --git a/mojo/python/mojo_utils/__init__.py b/mojo/python/mojo_utils/__init__.py deleted file mode 100644 index 50b23dff631db..0000000000000 --- a/mojo/python/mojo_utils/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright 2015 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. diff --git a/mojo/python/mojo_utils/data_pipe_utils.py b/mojo/python/mojo_utils/data_pipe_utils.py deleted file mode 100644 index 2a46ea5fc0882..0000000000000 --- a/mojo/python/mojo_utils/data_pipe_utils.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright 2015 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. - -import itertools -import sys - -import mojo_system -from mojo_bindings import promise - -class DataPipeCopyException(Exception): - def __init__(self, *args, **kwargs): - Exception.__init__(self, *args, **kwargs) - self.__traceback__ = sys.exc_info()[2] - - -def CopyFromDataPipe(data_pipe, deadline): - """ - Returns a Promise that operates as follows: - - If |data_pipe| is successfully read from, the promise resolves with the - bytes that were read. - - Otherwise, the promise rejects with an exception whose message contains the - status from the attempted read. - """ - class DataPipeCopyHelper(): - def __init__(self, data_pipe, deadline, resolve, reject): - self.data_pipe = data_pipe - self.original_deadline = deadline - self.start_time = mojo_system.GetTimeTicksNow() - self.resolve = resolve - self.reject = reject - self.buffer_size = 1024 - self.data = bytearray(self.buffer_size) - self.index = 0 - - def _ComputeCurrentDeadline(self): - if self.original_deadline == mojo_system.DEADLINE_INDEFINITE: - return self.original_deadline - elapsed_time = mojo_system.GetTimeTicksNow() - self.start_time - return max(0, self.original_deadline - elapsed_time) - - def CopyFromDataPipeAsync(self, result): - while result == mojo_system.RESULT_OK: - assert self.index <= len(self.data) - if self.index == len(self.data): - self.buffer_size *= 2 - self.data.extend(itertools.repeat(0, self.buffer_size)) - - # Careful! Have to construct a memoryview object here as otherwise the - # slice operation will create a copy of |data| and hence not write into - # |data| as desired. - result, read_bytes = self.data_pipe.ReadData( - memoryview(self.data)[self.index:]) - if read_bytes: - self.index += len(read_bytes) - del read_bytes - - if result == mojo_system.RESULT_SHOULD_WAIT: - data_pipe.AsyncWait(mojo_system.HANDLE_SIGNAL_READABLE, - self._ComputeCurrentDeadline(), - self.CopyFromDataPipeAsync) - return - - # Treat a failed precondition as EOF. - if result == mojo_system.RESULT_FAILED_PRECONDITION: - self.resolve(self.data[:self.index]) - return - - self.reject(DataPipeCopyException("Result: %d" % result)) - - - def GenerationMethod(resolve, reject): - helper = DataPipeCopyHelper(data_pipe, deadline, resolve, reject) - helper.CopyFromDataPipeAsync(mojo_system.RESULT_OK) - - return promise.Promise(GenerationMethod) diff --git a/mojo/python/system/mojo_embedder.pyx b/mojo/python/system/mojo_embedder.pyx deleted file mode 100644 index 75ae38797f46c..0000000000000 --- a/mojo/python/system/mojo_embedder.pyx +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2014 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. - -# distutils: language = c++ - -from libc.stdint cimport uintptr_t -from libcpp cimport bool - -import mojo_system -import mojo_system_impl - -cdef extern from "third_party/cython/python_export.h": - pass - -cdef extern from "base/memory/scoped_ptr.h": - cdef cppclass scoped_ptr[T]: - scoped_ptr(T*) - -cdef extern from "mojo/edk/embedder/platform_support.h" \ - namespace "mojo::embedder" nogil: - cdef cppclass PlatformSupport: - pass - -cdef extern from "mojo/edk/embedder/simple_platform_support.h" \ - namespace "mojo::embedder" nogil: - cdef cppclass SimplePlatformSupport(PlatformSupport): - SimplePlatformSupport() - -cdef extern from "mojo/edk/embedder/embedder.h" nogil: - cdef void InitCEmbedder "mojo::embedder::Init"( - scoped_ptr[PlatformSupport] platform_support) - -cdef extern from "mojo/public/platform/native/system_thunks.h" nogil: - cdef struct MojoSystemThunks: - pass - cdef MojoSystemThunks MojoMakeSystemThunks() - -cdef extern from "mojo/edk/embedder/test_embedder.h" nogil: - cdef bool ShutdownCEmbedderForTest "mojo::embedder::test::Shutdown"() - -def Init(): - InitCEmbedder(scoped_ptr[PlatformSupport]( - new SimplePlatformSupport())) - cdef MojoSystemThunks thunks = MojoMakeSystemThunks() - mojo_system.SetSystemThunks((&thunks)) - mojo_system_impl.SetSystemThunks((&thunks)) - -def ShutdownForTest(): - return ShutdownCEmbedderForTest() diff --git a/mojo/python/system/mojo_tests/__init__.py b/mojo/python/system/mojo_tests/__init__.py deleted file mode 100644 index 4d6aabb953d6f..0000000000000 --- a/mojo/python/system/mojo_tests/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright 2014 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. diff --git a/mojo/python/system/mojo_tests/validation_util.pyx b/mojo/python/system/mojo_tests/validation_util.pyx deleted file mode 100644 index e7bdbcdd55466..0000000000000 --- a/mojo/python/system/mojo_tests/validation_util.pyx +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2014 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. - -# distutils: language = c++ - -from libc.stdint cimport uint8_t -from libcpp cimport bool -from libcpp.string cimport string -from libcpp.vector cimport vector - -cdef extern from "third_party/cython/python_export.h": - pass - -cdef extern from "mojo/public/cpp/bindings/tests/validation_test_input_parser.h": - cdef bool ParseValidationTestInput "mojo::test::ParseValidationTestInput"( - string input, - vector[uint8_t]* data, - size_t* num_handles, - string* error_message) - -class Data(object): - def __init__(self, data, num_handles, error_message): - self.data = data - self.num_handles = num_handles - self.error_message = error_message - -def ParseData(value): - cdef string value_as_string = value - cdef vector[uint8_t] data_as_vector - cdef size_t num_handles - cdef string error_message - ParseValidationTestInput( - value, &data_as_vector, &num_handles, &error_message) - return Data(bytearray(data_as_vector), num_handles, error_message) diff --git a/mojo/python/tests/async_wait_unittest.py b/mojo/python/tests/async_wait_unittest.py deleted file mode 100644 index 61b0c2cd8bf86..0000000000000 --- a/mojo/python/tests/async_wait_unittest.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2014 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. - -import mojo_unittest - -# pylint: disable=E0611 -import mojo_system as system - - -class AsyncWaitTest(mojo_unittest.MojoTestCase): - - def setUp(self): - super(AsyncWaitTest, self).setUp() - self.array = [] - self.handles = system.MessagePipe() - self.cancel = self.handles.handle0.AsyncWait(system.HANDLE_SIGNAL_READABLE, - system.DEADLINE_INDEFINITE, - self._OnResult) - - def tearDown(self): - self.cancel() - self.handles = None - self.array = None - super(AsyncWaitTest, self).tearDown() - - def _OnResult(self, value): - self.array.append(value) - - def _WriteToHandle(self): - self.handles.handle1.WriteMessage() - - def _PostWriteAndRun(self): - self.loop.PostDelayedTask(self._WriteToHandle, 0) - self.loop.RunUntilIdle() - - def testAsyncWait(self): - self._PostWriteAndRun() - self.assertEquals(len(self.array), 1) - self.assertEquals(system.RESULT_OK, self.array[0]) - - def testAsyncWaitCancel(self): - self.loop.PostDelayedTask(self.cancel, 0) - self._PostWriteAndRun() - self.assertEquals(len(self.array), 0) - - def testAsyncWaitImmediateCancel(self): - self.cancel() - self._PostWriteAndRun() - self.assertEquals(len(self.array), 0) diff --git a/mojo/python/tests/bindings_constants_unittest.py b/mojo/python/tests/bindings_constants_unittest.py deleted file mode 100644 index 4db08c1ad06a4..0000000000000 --- a/mojo/python/tests/bindings_constants_unittest.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2014 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. - -import math -import unittest - -# Generated files -# pylint: disable=F0401 -import sample_service_mojom -import test_constants_mojom - -class ConstantBindingsTest(unittest.TestCase): - - def testConstantGeneration(self): - self.assertEquals(test_constants_mojom.INT8_VALUE, -2) - self.assertEquals(test_constants_mojom.UINT64_VALUE, 9999999999999999999) - self.assertEquals(test_constants_mojom.DOUBLE_INFINITY, - float('inf')) - self.assertEquals(test_constants_mojom.DOUBLE_NEGATIVE_INFINITY, - float('-inf')) - self.assertTrue(math.isnan(test_constants_mojom.DOUBLE_NA_N)) - self.assertEquals(test_constants_mojom.FLOAT_INFINITY, - float('inf')) - self.assertEquals(test_constants_mojom.FLOAT_NEGATIVE_INFINITY, - float('-inf')) - self.assertTrue(math.isnan(test_constants_mojom.FLOAT_NA_N)) - - def testConstantOnStructGeneration(self): - self.assertEquals(test_constants_mojom.StructWithConstants.INT8_VALUE, 5) - - def testStructImmutability(self): - with self.assertRaises(AttributeError): - sample_service_mojom.Foo.FOOBY = 0 - with self.assertRaises(AttributeError): - del sample_service_mojom.Foo.FOOBY - with self.assertRaises(AttributeError): - sample_service_mojom.Foo.BAR = 1 diff --git a/mojo/python/tests/bindings_control_messages_unittest.py b/mojo/python/tests/bindings_control_messages_unittest.py deleted file mode 100644 index 12dcfe45860ed..0000000000000 --- a/mojo/python/tests/bindings_control_messages_unittest.py +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright 2015 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. - -# pylint: disable=F0401,E0611 -import mojo_bindings.promise as promise -import mojo_system as system -import mojo_unittest -import sample_interfaces_mojom - - -def _BuildProxy(impl): - pipe = system.MessagePipe() - impl.__class__.manager.Bind(impl, pipe.handle0) - return impl.__class__.manager.Proxy(pipe.handle1) - - -def _ExtractValue(v_promise): - container = [] - @promise.async - def GetInternalValue(value): - container.append(value) - GetInternalValue(v_promise) - assert len(container) - return container[0] - - -class IntegerAccessorImpl(sample_interfaces_mojom.IntegerAccessor): - """ - Interface definition is in - mojo/public/interfaces/bindings/tests/sample_interfaces.mojom - """ - def __init__(self): - self.values = { - 'data': 0, - 'type': 0, - } - - def GetInteger(self): - return self.values; - - def SetInteger(self, **values): - self.values = values - - def GetInternalValue(self): - return self.values['data'] - - -class ControlMessagesTest(mojo_unittest.MojoTestCase): - - def testQueryVersion(self): - p = _BuildProxy(IntegerAccessorImpl()) - self.assertEquals(p.manager.version, 0) - v_promise = p.manager.QueryVersion() - self.loop.RunUntilIdle() - self.assertEquals(v_promise.state, promise.Promise.STATE_FULLFILLED) - self.assertEquals(_ExtractValue(v_promise), 3) - self.assertEquals(p.manager.version, 3) - - def testRequireVersion(self): - impl = IntegerAccessorImpl() - errors = [] - p = _BuildProxy(impl) - p.manager.AddOnErrorCallback(lambda: errors.append(0)) - - self.assertEquals(p.manager.version, 0) - - p.manager.RequireVersion(1) - self.assertEquals(p.manager.version, 1) - p.SetInteger(123, sample_interfaces_mojom.Enum.VALUE) - self.loop.RunUntilIdle() - self.assertEquals(len(errors), 0) - self.assertEquals(impl.GetInternalValue(), 123) - - p.manager.RequireVersion(3) - self.assertEquals(p.manager.version, 3) - p.SetInteger(456, sample_interfaces_mojom.Enum.VALUE) - self.loop.RunUntilIdle() - self.assertEquals(len(errors), 0) - self.assertEquals(impl.GetInternalValue(), 456) - - # Require a version that is not supported by the implementation side. - p.manager.RequireVersion(4) - # version is updated synchronously. - self.assertEquals(p.manager.version, 4) - p.SetInteger(789, sample_interfaces_mojom.Enum.VALUE) - self.loop.RunUntilIdle() - self.assertEquals(len(errors), 1) - # The call to SetInteger() after RequireVersion() is ignored. - self.assertEquals(impl.GetInternalValue(), 456) diff --git a/mojo/python/tests/bindings_enums_unittest.py b/mojo/python/tests/bindings_enums_unittest.py deleted file mode 100644 index 6ec5d8c225e55..0000000000000 --- a/mojo/python/tests/bindings_enums_unittest.py +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright 2014 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. - -import unittest - -# Generated files -# pylint: disable=F0401 -import sample_import_mojom -import sample_service_mojom - - -class EnumBindingsTest(unittest.TestCase): - - # Testing enum classes are in the right module. - def testModule(self): - self.assertEquals(sample_import_mojom.Shape.__module__, - 'sample_import_mojom') - - # Testing that enum class have expected constant values. - def testTopLevelEnumGeneration(self): - self.assertEquals(sample_import_mojom.Shape.RECTANGLE, 1) - self.assertEquals(sample_import_mojom.Shape.CIRCLE, 2) - self.assertEquals(sample_import_mojom.Shape.TRIANGLE, 3) - self.assertEquals(sample_import_mojom.Shape.LAST, - sample_import_mojom.Shape.TRIANGLE) - - self.assertEquals(sample_import_mojom.AnotherShape.RECTANGLE, 10) - self.assertEquals(sample_import_mojom.AnotherShape.CIRCLE, 11) - self.assertEquals(sample_import_mojom.AnotherShape.TRIANGLE, 12) - - self.assertEquals(sample_import_mojom.YetAnotherShape.RECTANGLE, 20) - self.assertEquals(sample_import_mojom.YetAnotherShape.CIRCLE, 21) - self.assertEquals(sample_import_mojom.YetAnotherShape.TRIANGLE, 22) - - # Testing that internal enum class have expected constant values. - def testInternalEnumGeneration(self): - self.assertEquals(sample_service_mojom.Bar.Type.VERTICAL, 1) - self.assertEquals(sample_service_mojom.Bar.Type.HORIZONTAL, 2) - self.assertEquals(sample_service_mojom.Bar.Type.BOTH, 3) - self.assertEquals(sample_service_mojom.Bar.Type.INVALID, 4) - - # Testing an enum class cannot be instantiated. - def testNonInstantiableEnum(self): - with self.assertRaises(TypeError): - sample_import_mojom.Shape() - - # Testing an enum does not contain the VALUES constant. - def testNoVALUESConstant(self): - with self.assertRaises(AttributeError): - # pylint: disable=W0104 - sample_import_mojom.Shape.VALUES - - # Testing enum values are frozen. - def testEnumFrozen(self): - with self.assertRaises(AttributeError): - sample_import_mojom.Shape.RECTANGLE = 2 - with self.assertRaises(AttributeError): - del sample_import_mojom.Shape.RECTANGLE - with self.assertRaises(AttributeError): - sample_import_mojom.Shape.NewShape = 4 diff --git a/mojo/python/tests/bindings_interface_unittest.py b/mojo/python/tests/bindings_interface_unittest.py deleted file mode 100644 index ac42ed306bbe6..0000000000000 --- a/mojo/python/tests/bindings_interface_unittest.py +++ /dev/null @@ -1,123 +0,0 @@ -# Copyright 2014 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. - -import gc -import weakref - -# pylint: disable=F0401,E0611 -import mojo_bindings.promise as promise -import mojo_system as system -import mojo_unittest -import regression_tests_mojom -import sample_factory_mojom -import sample_service_mojom - - -def _BuildProxy(impl): - pipe = system.MessagePipe() - impl.__class__.manager.Bind(impl, pipe.handle0) - return impl.__class__.manager.Proxy(pipe.handle1) - - -def _ExtractValue(p): - container = [] - @promise.async - def GetValue(value): - container.append(value) - GetValue(p) - assert len(container) - return container[0] - - -class EmptyServiceImpl(sample_service_mojom.Service): - - def __init__(self): - pass - - -class ServiceImpl(sample_service_mojom.Service): - - def __init__(self): - pass - - # pylint: disable=C0102,W0613 - def Frobinate(self, foo, baz, port): - return baz - - -class NamedObjectImpl(sample_factory_mojom.NamedObject): - - def __init__(self): - self.name = 'name' - - def SetName(self, name): - self.name = name - - def GetName(self): - return self.name - - -class DelegatingNamedObject(sample_factory_mojom.NamedObject): - - def __init__(self): - self.proxy = _BuildProxy(NamedObjectImpl()) - - def SetName(self, name): - self.proxy.SetName(name) - - def GetName(self): - return self.proxy.GetName() - -class InterfaceTest(mojo_unittest.MojoTestCase): - - def testBaseInterface(self): - service = sample_service_mojom.Service() - with self.assertRaises(AttributeError): - service.NotExisting() - with self.assertRaises(NotImplementedError): - service.Frobinate() - - def testEmpty(self): - service = EmptyServiceImpl() - with self.assertRaises(NotImplementedError): - service.Frobinate() - - def testServiceWithReturnValue(self): - proxy = _BuildProxy(DelegatingNamedObject()) - p1 = proxy.GetName() - - self.assertEquals(p1.state, promise.Promise.STATE_PENDING) - self.loop.RunUntilIdle() - self.assertEquals(p1.state, promise.Promise.STATE_FULLFILLED) - name = _ExtractValue(p1) - self.assertEquals(name, 'name') - - proxy.SetName('hello') - p2 = proxy.GetName() - - self.assertEquals(p2.state, promise.Promise.STATE_PENDING) - self.loop.RunUntilIdle() - self.assertEquals(p2.state, promise.Promise.STATE_FULLFILLED) - name = _ExtractValue(p2) - self.assertEquals(name, 'hello') - - def testCloseProxy(self): - named_object_impl = NamedObjectImpl() - proxy = _BuildProxy(named_object_impl) - response = proxy.GetName() - proxy.manager.Close() - - self.assertEquals(response.state, promise.Promise.STATE_REJECTED) - - def testCloseImplementationWithResponse(self): - impl = DelegatingNamedObject() - proxy = _BuildProxy(impl) - p1 = proxy.GetName() - - self.assertEquals(p1.state, promise.Promise.STATE_PENDING) - - impl.manager.Close() - self.loop.RunUntilIdle() - - self.assertEquals(p1.state, promise.Promise.STATE_REJECTED) diff --git a/mojo/python/tests/bindings_serialization_deserialization_unittest.py b/mojo/python/tests/bindings_serialization_deserialization_unittest.py deleted file mode 100644 index 64397c2c47ad2..0000000000000 --- a/mojo/python/tests/bindings_serialization_deserialization_unittest.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright 2014 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. - -import math - -import mojo_unittest - -# pylint: disable=E0611,F0401 -import mojo_bindings.serialization as serialization -import mojo_system - -# Generated files -# pylint: disable=F0401 -import sample_import_mojom -import sample_import2_mojom -import sample_service_mojom - - -def _NewHandle(): - return mojo_system.MessagePipe().handle0 - - -def _NewBar(): - bar_instance = sample_service_mojom.Bar() - bar_instance.alpha = 22 - bar_instance.beta = 87 - bar_instance.gamma = 122 - bar_instance.type = sample_service_mojom.Bar.Type.BOTH - return bar_instance - - -def _NewFoo(): - foo_instance = sample_service_mojom.Foo() - foo_instance.name = "Foo.name" - foo_instance.x = 23 - foo_instance.y = -23 - foo_instance.a = False - foo_instance.b = True - foo_instance.c = True - foo_instance.bar = _NewBar() - foo_instance.extra_bars = [ - _NewBar(), - _NewBar(), - ] - foo_instance.data = 'Hello world' - foo_instance.source = _NewHandle() - foo_instance.input_streams = [ _NewHandle() ] - foo_instance.output_streams = [ _NewHandle(), _NewHandle() ] - foo_instance.array_of_array_of_bools = [ [ True, False ], [] ] - foo_instance.multi_array_of_strings = [ - [ - [ "1", "2" ], - [], - [ "3", "4" ], - ], - [], - ] - foo_instance.array_of_bools = [ True, 0, 1, 2, 0, 0, 0, 0, 0, True ] - return foo_instance - - -class SerializationDeserializationTest(mojo_unittest.MojoTestCase): - - def testFooSerialization(self): - (data, _) = _NewFoo().Serialize() - self.assertTrue(len(data)) - self.assertEquals(len(data) % 8, 0) - - def testFooDeserialization(self): - (data, handles) = _NewFoo().Serialize() - context = serialization.RootDeserializationContext(data, handles) - self.assertTrue( - sample_service_mojom.Foo.Deserialize(context)) - - def testFooSerializationDeserialization(self): - foo1 = _NewFoo() - (data, handles) = foo1.Serialize() - context = serialization.RootDeserializationContext(data, handles) - foo2 = sample_service_mojom.Foo.Deserialize(context) - self.assertEquals(foo1, foo2) - - def testDefaultsTestSerializationDeserialization(self): - v1 = sample_service_mojom.DefaultsTest() - v1.a18 = [] - v1.a19 = "" - v1.a21 = sample_import_mojom.Point() - v1.a22.location = sample_import_mojom.Point() - v1.a22.size = sample_import2_mojom.Size() - (data, handles) = v1.Serialize() - context = serialization.RootDeserializationContext(data, handles) - v2 = sample_service_mojom.DefaultsTest.Deserialize(context) - # NaN needs to be a special case. - self.assertNotEquals(v1, v2) - self.assertTrue(math.isnan(v2.a28)) - self.assertTrue(math.isnan(v2.a31)) - v1.a28 = v2.a28 = v1.a31 = v2.a31 = 0 - self.assertEquals(v1, v2) - - def testFooDeserializationError(self): - with self.assertRaises(Exception): - sample_service_mojom.Foo.Deserialize("", []) diff --git a/mojo/python/tests/bindings_structs_unittest.py b/mojo/python/tests/bindings_structs_unittest.py deleted file mode 100644 index c53c1a007788a..0000000000000 --- a/mojo/python/tests/bindings_structs_unittest.py +++ /dev/null @@ -1,217 +0,0 @@ -# Copyright 2014 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. - -import math -import unittest - -# pylint: disable=E0611,F0401 -import mojo_system - -# Generated files -# pylint: disable=F0401 -import regression_tests_mojom -import sample_import_mojom -import sample_import2_mojom -import sample_service_mojom - - -class StructBindingsTest(unittest.TestCase): - - def testModule(self): - self.assertEquals(sample_service_mojom.DefaultsTest.__module__, - 'sample_service_mojom') - - def testDefaultsTest(self): - defaults_test = sample_service_mojom.DefaultsTest() - self.assertEquals(defaults_test.a0, -12) - self.assertEquals(defaults_test.a1, 12) - self.assertEquals(defaults_test.a2, 1234) - self.assertEquals(defaults_test.a3, 34567) - self.assertEquals(defaults_test.a4, 123456) - self.assertEquals(defaults_test.a5, 3456789012) - self.assertEquals(defaults_test.a6, -111111111111) - self.assertEquals(defaults_test.a7, 9999999999999999999) - self.assertEquals(defaults_test.a8, 0x12345) - self.assertEquals(defaults_test.a9, -0x12345) - self.assertEquals(defaults_test.a10, 1234) - self.assertEquals(defaults_test.a11, True) - self.assertEquals(defaults_test.a12, False) - self.assertEquals(defaults_test.a13, 123.25) - self.assertEquals(defaults_test.a14, 1234567890.123) - self.assertEquals(defaults_test.a15, 1E10) - self.assertEquals(defaults_test.a16, -1.2E+20) - self.assertEquals(defaults_test.a17, 1.23E-20) - self.assertEquals(defaults_test.a18, None) - self.assertEquals(defaults_test.a19, None) - self.assertEquals(defaults_test.a20, sample_service_mojom.Bar.Type.BOTH) - self.assertEquals(defaults_test.a21, None) - self.assertTrue(isinstance(defaults_test.a22, sample_import2_mojom.Thing)) - self.assertEquals(defaults_test.a23, 0xFFFFFFFFFFFFFFFF) - self.assertEquals(defaults_test.a24, 0x123456789) - self.assertEquals(defaults_test.a25, -0x123456789) - self.assertEquals(defaults_test.a26, float('inf')) - self.assertEquals(defaults_test.a27, float('-inf')) - self.assertTrue(math.isnan(defaults_test.a28)) - self.assertEquals(defaults_test.a29, float('inf')) - self.assertEquals(defaults_test.a30, float('-inf')) - self.assertTrue(math.isnan(defaults_test.a31)) - - def testNoAliasing(self): - foo1 = sample_service_mojom.Foo() - foo2 = sample_service_mojom.Foo() - foo1.name = "foo1" - foo2.name = "foo2" - self.assertEquals(foo1.name, "foo1") - self.assertEquals(foo2.name, "foo2") - - defaults_test1 = sample_service_mojom.DefaultsTest() - defaults_test2 = sample_service_mojom.DefaultsTest() - self.assertIsNot(defaults_test1.a22, defaults_test2.a22) - - def testImmutableAttributeSet(self): - foo_instance = sample_service_mojom.Foo() - with self.assertRaises(AttributeError): - foo_instance.new_attribute = None - with self.assertRaises(AttributeError): - del foo_instance.name - - def _TestIntegerField(self, entity, field_name, bits, signed): - if signed: - min_value = -(1 << (bits - 1)) - max_value = (1 << (bits - 1)) - 1 - else: - min_value = 0 - max_value = (1 << bits) - 1 - entity.__setattr__(field_name, min_value) - entity.__setattr__(field_name, max_value) - with self.assertRaises(TypeError): - entity.__setattr__(field_name, None) - with self.assertRaises(OverflowError): - entity.__setattr__(field_name, min_value - 1) - with self.assertRaises(OverflowError): - entity.__setattr__(field_name, max_value + 1) - with self.assertRaises(TypeError): - entity.__setattr__(field_name, 'hello world') - - def testTypes(self): - defaults_test = sample_service_mojom.DefaultsTest() - # Integer types - self._TestIntegerField(defaults_test, 'a0', 8, True) - self._TestIntegerField(defaults_test, 'a1', 8, False) - self._TestIntegerField(defaults_test, 'a2', 16, True) - self._TestIntegerField(defaults_test, 'a3', 16, False) - self._TestIntegerField(defaults_test, 'a4', 32, True) - self._TestIntegerField(defaults_test, 'a5', 32, False) - self._TestIntegerField(defaults_test, 'a6', 64, True) - self._TestIntegerField(defaults_test, 'a7', 64, False) - - # Boolean types - defaults_test.a11 = False - self.assertEquals(defaults_test.a11, False) - defaults_test.a11 = None - self.assertEquals(defaults_test.a11, False) - defaults_test.a11 = [] - self.assertEquals(defaults_test.a11, False) - defaults_test.a12 = True - self.assertEquals(defaults_test.a12, True) - defaults_test.a12 = 1 - self.assertEquals(defaults_test.a12, True) - defaults_test.a12 = [[]] - self.assertEquals(defaults_test.a12, True) - - # Floating point types - with self.assertRaises(TypeError): - defaults_test.a13 = 'hello' - with self.assertRaises(TypeError): - defaults_test.a14 = 'hello' - - # Array type - defaults_test.a18 = None - defaults_test.a18 = [] - defaults_test.a18 = [ 0 ] - defaults_test.a18 = [ 255 ] - defaults_test.a18 = [ 0, 255 ] - with self.assertRaises(TypeError): - defaults_test.a18 = [[]] - with self.assertRaises(OverflowError): - defaults_test.a18 = [ -1 ] - with self.assertRaises(OverflowError): - defaults_test.a18 = [ 256 ] - - # String type - defaults_test.a19 = None - defaults_test.a19 = '' - defaults_test.a19 = 'hello world' - with self.assertRaises(TypeError): - defaults_test.a19 = [[]] - with self.assertRaises(TypeError): - defaults_test.a19 = [ -1 ] - with self.assertRaises(TypeError): - defaults_test.a19 = [ 256 ] - - # Structs - defaults_test.a21 = None - defaults_test.a21 = sample_import_mojom.Point() - with self.assertRaises(TypeError): - defaults_test.a21 = 1 - with self.assertRaises(TypeError): - defaults_test.a21 = sample_import2_mojom.Thing() - - # Handles - foo_instance = sample_service_mojom.Foo() - foo_instance.source = None - foo_instance.source = mojo_system.Handle() - with self.assertRaises(TypeError): - foo_instance.source = 1 - with self.assertRaises(TypeError): - foo_instance.source = object() - - def testConstructor(self): - bar_instance = sample_service_mojom.Bar() - foo_instance = sample_service_mojom.Foo(name="Foo", - x=-1, - y=5, - a=False, - bar=bar_instance) - self.assertEquals(foo_instance.name, "Foo") - self.assertEquals(foo_instance.x, -1) - self.assertEquals(foo_instance.y, 5) - self.assertEquals(foo_instance.a, False) - self.assertEquals(foo_instance.bar, bar_instance) - - def testPositionalConstructor(self): - p = sample_import_mojom.Point() - self.assertEquals(p.x, 0) - self.assertEquals(p.y, 0) - - p = sample_import_mojom.Point(34) - self.assertEquals(p.x, 34) - self.assertEquals(p.y, 0) - - p = sample_import_mojom.Point(34, 12) - self.assertEquals(p.x, 34) - self.assertEquals(p.y, 12) - - p = sample_import_mojom.Point(x=34, y=12) - self.assertEquals(p.x, 34) - self.assertEquals(p.y, 12) - - p = sample_import_mojom.Point(34, y=12) - self.assertEquals(p.x, 34) - self.assertEquals(p.y, 12) - - with self.assertRaises(TypeError): - p = sample_import_mojom.Point(0, 0, 0) - with self.assertRaises(TypeError): - p = sample_import_mojom.Point(0, x=0) - with self.assertRaises(TypeError): - p = sample_import_mojom.Point(c=0) - - def testCyclicDefinition(self): - a = regression_tests_mojom.A() - b = regression_tests_mojom.B() - self.assertIsNone(a.b) - self.assertIsNone(b.a) - a.b = b - self.assertIs(a.b, b) diff --git a/mojo/python/tests/bindings_structs_version_unittest.py b/mojo/python/tests/bindings_structs_version_unittest.py deleted file mode 100644 index 231f240c612c5..0000000000000 --- a/mojo/python/tests/bindings_structs_version_unittest.py +++ /dev/null @@ -1,150 +0,0 @@ -# Copyright 2015 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. - -import math -import unittest - -import mojo_unittest - -# pylint: disable=E0611,F0401 -import mojo_bindings.serialization as serialization -import mojo_system - -# Generated files -# pylint: disable=F0401 -import rect_mojom -import test_structs_mojom - - -class StructVersionBindingsTest(mojo_unittest.MojoTestCase): - - def SerializeAndDeserialize(self, target_class, input_instance): - (data, handles) = input_instance.Serialize() - context = serialization.RootDeserializationContext(data, handles) - return target_class.Deserialize(context) - - def MakeRect(self, factor): - return rect_mojom.Rect( - x=factor, y=2*factor, width=10*factor, height=20*factor) - - def testOldToNew(self): - v0 = test_structs_mojom.MultiVersionStructV0() - v0.f_int32 = 123 - expected = test_structs_mojom.MultiVersionStruct() - expected.f_int32 = 123 - - output = self.SerializeAndDeserialize( - test_structs_mojom.MultiVersionStruct, v0) - self.assertEquals(output, expected) - - v1 = test_structs_mojom.MultiVersionStructV1() - v1.f_int32 = 123 - v1.f_rect = self.MakeRect(5) - expected = test_structs_mojom.MultiVersionStruct() - expected.f_int32 = 123 - expected.f_rect = self.MakeRect(5) - - output = self.SerializeAndDeserialize( - test_structs_mojom.MultiVersionStruct, v1) - self.assertEquals(output, expected) - - v3 = test_structs_mojom.MultiVersionStructV3() - v3.f_int32 = 123 - v3.f_rect = self.MakeRect(5) - v3.f_string = 'hello' - expected = test_structs_mojom.MultiVersionStruct() - expected.f_int32 = 123 - expected.f_rect = self.MakeRect(5) - expected.f_string = 'hello' - - output = self.SerializeAndDeserialize( - test_structs_mojom.MultiVersionStruct, v3) - self.assertEquals(output, expected) - - v5 = test_structs_mojom.MultiVersionStructV5() - v5.f_int32 = 123 - v5.f_rect = self.MakeRect(5) - v5.f_string = 'hello' - v5.f_array = [10, 9, 8] - expected = test_structs_mojom.MultiVersionStruct() - expected.f_int32 = 123 - expected.f_rect = self.MakeRect(5) - expected.f_string = 'hello' - expected.f_array = [10, 9, 8] - - output = self.SerializeAndDeserialize( - test_structs_mojom.MultiVersionStruct, v5) - self.assertEquals(output, expected) - - pipe = mojo_system.MessagePipe() - v7 = test_structs_mojom.MultiVersionStructV7() - v7.f_int32 = 123 - v7.f_rect = self.MakeRect(5) - v7.f_string = 'hello' - v7.f_array = [10, 9, 8] - v7.f_message_pipe = pipe.handle0 - v7.f_bool = True - expected = test_structs_mojom.MultiVersionStruct() - expected.f_int32 = 123 - expected.f_rect = self.MakeRect(5) - expected.f_string = 'hello' - expected.f_array = [10, 9, 8] - expected.f_message_pipe = pipe.handle0 - expected.f_bool = True - - output = self.SerializeAndDeserialize( - test_structs_mojom.MultiVersionStruct, v7) - self.assertEquals(output, expected) - - def testNewToNew(self): - pipe = mojo_system.MessagePipe() - input_struct = test_structs_mojom.MultiVersionStruct() - input_struct.f_int32 = 123 - input_struct.f_rect = self.MakeRect(5) - input_struct.f_string = 'hello' - input_struct.f_array = [10, 9, 8] - input_struct.f_message_pipe = pipe.handle0 - input_struct.f_bool = True - input_struct.f_int16 = 256 - - expected = test_structs_mojom.MultiVersionStructV7() - expected.f_int32 = 123 - expected.f_rect = self.MakeRect(5) - expected.f_string = 'hello' - expected.f_array = [10, 9, 8] - expected.f_message_pipe = pipe.handle0 - expected.f_bool = True - output = self.SerializeAndDeserialize( - test_structs_mojom.MultiVersionStructV7, input_struct) - self.assertEquals(output, expected) - - expected = test_structs_mojom.MultiVersionStructV5() - expected.f_int32 = 123 - expected.f_rect = self.MakeRect(5) - expected.f_string = 'hello' - expected.f_array = [10, 9, 8] - output = self.SerializeAndDeserialize( - test_structs_mojom.MultiVersionStructV5, input_struct) - self.assertEquals(output, expected) - - expected = test_structs_mojom.MultiVersionStructV3() - expected.f_int32 = 123 - expected.f_rect = self.MakeRect(5) - expected.f_string = 'hello' - output = self.SerializeAndDeserialize( - test_structs_mojom.MultiVersionStructV3, input_struct) - self.assertEquals(output, expected) - - expected = test_structs_mojom.MultiVersionStructV1() - expected.f_int32 = 123 - expected.f_rect = self.MakeRect(5) - output = self.SerializeAndDeserialize( - test_structs_mojom.MultiVersionStructV1, input_struct) - self.assertEquals(output, expected) - - expected = test_structs_mojom.MultiVersionStructV0() - expected.f_int32 = 123 - output = self.SerializeAndDeserialize( - test_structs_mojom.MultiVersionStructV0, input_struct) - self.assertEquals(output, expected) diff --git a/mojo/python/tests/bindings_unions_unittest.py b/mojo/python/tests/bindings_unions_unittest.py deleted file mode 100644 index b1d742fd551c2..0000000000000 --- a/mojo/python/tests/bindings_unions_unittest.py +++ /dev/null @@ -1,188 +0,0 @@ -# Copyright 2015 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. - -import struct -import unittest - -# Generated files -# pylint: disable=F0401 -import test_unions_mojom -import mojo_bindings.serialization as serialization - -class UnionBindingsTest(unittest.TestCase): - - def testBasics(self): - u = test_unions_mojom.PodUnion() - self.assertTrue(u.IsUnknown()) - - u.f_uint32 = 32 - self.assertEquals(u.f_uint32, 32) - self.assertEquals(u.data, 32) - self.assertEquals(test_unions_mojom.PodUnion.Tags.f_uint32, u.tag) - self.assertFalse(u.IsUnknown()) - - u = test_unions_mojom.PodUnion(f_uint8=8) - self.assertEquals(u.f_uint8, 8) - self.assertEquals(u.data, 8) - self.assertEquals(test_unions_mojom.PodUnion.Tags.f_uint8, u.tag) - - with self.assertRaises(TypeError): - test_unions_mojom.PodUnion(f_uint8=8, f_int16=10) - - with self.assertRaises(AttributeError): - test_unions_mojom.PodUnion(bad_field=10) - - with self.assertRaises(AttributeError): - u = test_unions_mojom.PodUnion() - u.bad_field = 32 - - with self.assertRaises(AttributeError): - _ = u.f_uint16 - - def testPodUnionSerialization(self): - u = test_unions_mojom.PodUnion(f_uint32=32) - (data, handles) = u.Serialize() - context = serialization.RootDeserializationContext(data, handles) - decoded = test_unions_mojom.PodUnion.Deserialize(context) - - self.assertFalse(decoded.IsUnknown()) - self.assertEquals(u, decoded) - - def testUnionUnknownTag(self): - u = test_unions_mojom.NewUnion(f_int16=10) - (data, handles) = u.Serialize() - context = serialization.RootDeserializationContext(data, handles) - decoded = test_unions_mojom.OldUnion.Deserialize(context) - - self.assertTrue(decoded.IsUnknown()) - - def testObjectInUnionSerialization(self): - u = test_unions_mojom.ObjectUnion( - f_dummy=test_unions_mojom.DummyStruct()) - u.f_dummy.f_int8 = 8 - (data, handles) = u.Serialize() - context = serialization.RootDeserializationContext(data, handles) - decoded = test_unions_mojom.ObjectUnion.Deserialize(context) - - self.assertEquals(u, decoded) - - def testObjectInUnionInObjectSerialization(self): - s = test_unions_mojom.SmallObjStruct() - s.obj_union = test_unions_mojom.ObjectUnion( - f_dummy=test_unions_mojom.DummyStruct()) - s.obj_union.f_dummy.f_int8 = 25 - (data, handles) = s.Serialize() - context = serialization.RootDeserializationContext(data, handles) - decoded = test_unions_mojom.SmallObjStruct.Deserialize(context) - - self.assertEquals(s, decoded) - - def testNestedUnionSerialization(self): - u = test_unions_mojom.ObjectUnion( - f_pod_union=test_unions_mojom.PodUnion(f_int32=32)) - - (data, handles) = u.Serialize() - context = serialization.RootDeserializationContext(data, handles) - decoded = test_unions_mojom.ObjectUnion.Deserialize(context) - - self.assertEquals(u, decoded) - - def testNullableNullObjectInUnionSerialization(self): - u = test_unions_mojom.ObjectUnion(f_nullable=None) - (data, handles) = u.Serialize() - context = serialization.RootDeserializationContext(data, handles) - decoded = test_unions_mojom.ObjectUnion.Deserialize(context) - - self.assertEquals(u, decoded) - - def testNonNullableNullObjectInUnionSerialization(self): - u = test_unions_mojom.ObjectUnion(f_dummy=None) - with self.assertRaises(serialization.SerializationException): - u.Serialize() - - def testArrayInUnionSerialization(self): - u = test_unions_mojom.ObjectUnion( - f_array_int8=[1, 2, 3, 4, 5]) - (data, handles) = u.Serialize() - context = serialization.RootDeserializationContext(data, handles) - decoded = test_unions_mojom.ObjectUnion.Deserialize(context) - - self.assertEquals(u, decoded) - - def testMapInUnionSerialization(self): - u = test_unions_mojom.ObjectUnion( - f_map_int8={'one': 1, 'two': 2, 'three': 3}) - (data, handles) = u.Serialize() - context = serialization.RootDeserializationContext(data, handles) - decoded = test_unions_mojom.ObjectUnion.Deserialize(context) - - self.assertEquals(u, decoded) - - def testUnionInObject(self): - s = test_unions_mojom.SmallStruct() - s.pod_union = test_unions_mojom.PodUnion(f_uint32=32) - (data, handles) = s.Serialize() - - # This is where the data should be serialized to. - size, tag, value = struct.unpack_from(' stream, string categories); diff --git a/mojo/services/vanadium/security/public/interfaces/BUILD.gn b/mojo/services/vanadium/security/public/interfaces/BUILD.gn new file mode 100644 index 0000000000000..48eea5b7c75ad --- /dev/null +++ b/mojo/services/vanadium/security/public/interfaces/BUILD.gn @@ -0,0 +1,12 @@ +# Copyright 2015 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. + +import("//build/module_args/mojo.gni") +import("$mojo_sdk_root/mojo/public/tools/bindings/mojom.gni") + +mojom("interfaces") { + sources = [ + "principal.mojom", + ] +} diff --git a/mojo/services/vanadium/security/public/interfaces/principal.mojom b/mojo/services/vanadium/security/public/interfaces/principal.mojom new file mode 100644 index 0000000000000..9c58834801e7a --- /dev/null +++ b/mojo/services/vanadium/security/public/interfaces/principal.mojom @@ -0,0 +1,49 @@ +// Copyright 2015 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. + +module vanadium; + +// Represents the name of an application. |url| is the url of the +// application. |qualifier| is a string that allows to tie a specific +// instance of an application to another. +struct AppInstanceName { + string url; + string? qualifier; +}; + +// Certificate represents a human-readable name and public-key (DER encoded) pair. +// The private-key for a certificate is only available for signing operations +// within the principal service application. +struct Certificate { + string extension; + array? publickey; +}; + +// Blessing is a credential binding a user identity to a public key. The corresponding +// private key is only available for signing within the PrincipalService application. +struct Blessing { + array chain; +}; + +// ChainSeparator is the separator used to join name extensions in a certificate chain. +const string ChainSeparator = "/"; + +// A service that binds user identities to an application instance running in Mojo +interface PrincipalService { + // Login is called by an application instance (requestor_url/qualifier) that + // wants to get a user blessing. The service may obtain the user blessing + // through a third-party authentication flow (eg:oauth2). The user blessing + // is bound to a public/private key-pair that this service generates and + // persists for this application instance. Returns null if login fails. + Login() => (Blessing? user_blessing); + + // Removes the user blessing for the application instance that invokes the + // Logout method. + Logout(); + + // GetUserBlessing returns the user blessing for a given application instance. + // It returns an error if the application instance has not invoked Login(). + GetUserBlessing(AppInstanceName app) => (Blessing? user_blessing); +}; + diff --git a/mojo/tests/BUILD.gn b/mojo/tests/BUILD.gn deleted file mode 100644 index 03411fec887c3..0000000000000 --- a/mojo/tests/BUILD.gn +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2015 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. - -import("//testing/test.gni") -import("//mojo/public/mojo.gni") - -test("mojo_task_tracker_perftests") { - deps = [ - "//base/test:test_support", - "//mojo/common", - "//mojo/edk/system", - "//mojo/edk/test:test_support", - "//mojo/edk/test:test_support_impl", - "//mojo/environment:chromium", - "//mojo/public/c/test_support", - "//mojo/public/cpp/bindings", - "//mojo/public/cpp/bindings:callback", - "//mojo/public/cpp/environment", - "//mojo/public/cpp/system", - "//mojo/public/cpp/test_support:test_utils", - "//mojo/public/cpp/utility", - "//mojo/public/interfaces/bindings/tests:test_interfaces", - "//base", - "//testing/gtest", - ] - - sources = [ - "../edk/test/run_all_perftests.cc", - "task_tracker_perftest.cc", - ] -} diff --git a/mojo/tests/task_tracker_perftest.cc b/mojo/tests/task_tracker_perftest.cc deleted file mode 100644 index a2ffdb39170d5..0000000000000 --- a/mojo/tests/task_tracker_perftest.cc +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2015 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 - -#include "base/logging.h" -#include "base/message_loop/message_loop.h" -#include "base/timer/elapsed_timer.h" -#include "base/tracked_objects.h" -#include "mojo/common/message_pump_mojo.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/environment/environment.h" -#include "mojo/public/cpp/environment/task_tracker.h" -#include "mojo/public/cpp/test_support/test_support.h" -#include "mojo/public/cpp/test_support/test_utils.h" -#include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace { - -class ProviderImpl : public sample::Provider { - public: - explicit ProviderImpl(InterfaceRequest request) - : binding_(this, request.Pass()) {} - - void EchoString(const String& a, - const Callback& callback) override { - callback.Run(a); - } - - void EchoStrings(const String& a, - const String& b, - const Callback& callback) override { - CHECK(false); - } - - void EchoMessagePipeHandle( - ScopedMessagePipeHandle a, - const Callback& callback) override { - CHECK(false); - } - - void EchoEnum(sample::Enum a, - const Callback& callback) override { - CHECK(false); - } - - void EchoInt(int32_t a, const EchoIntCallback& callback) override { - CHECK(false); - } - - Binding binding_; -}; - -class RequestResponsePerfTest : public testing::Test { - public: - RequestResponsePerfTest() - : loop_(make_scoped_ptr(new common::MessagePumpMojo())) {} - - ~RequestResponsePerfTest() override { loop_.RunUntilIdle(); } - - void Iterate(size_t count); - void Measure(const char* case_nam); - - void SetUp() override { - tracked_objects::ThreadData::InitializeAndSetTrackingStatus( - tracked_objects::ThreadData::PROFILING_ACTIVE); - } - - void TearDown() override { - tracked_objects::ThreadData::InitializeAndSetTrackingStatus( - tracked_objects::ThreadData::DEACTIVATED); - } - - void PumpMessages() { loop_.RunUntilIdle(); } - - private: - base::MessageLoop loop_; -}; - -const size_t kCallsPerIteration = 1000; -const size_t kIterations = 1000; - -void RequestResponsePerfTest::Iterate(size_t count) { - sample::ProviderPtr provider; - ProviderImpl provider_impl(GetProxy(&provider)); - - size_t remaining = count; - Callback reply = - [&provider, &reply, &remaining](const String& a) { - if (!remaining) - return; - remaining--; - provider->EchoString(a, reply); - }; - - provider->EchoString(String::From("hello"), reply); - PumpMessages(); -} - -void RequestResponsePerfTest::Measure(const char* case_name) { - std::vector laps; - for (size_t i = 0; i < kIterations; ++i) { - base::ElapsedTimer timer; - Iterate(kCallsPerIteration); - laps.push_back(timer.Elapsed().InMillisecondsF()); - } - - double avg = std::accumulate(laps.begin(), laps.end(), 0.0) / laps.size(); - double var = std::accumulate(laps.begin(), laps.end(), 0.0, [avg](double acc, - double x) { - return acc + (x - avg) * (x - avg); - }) / laps.size(); - - double sd = sqrt(var); - mojo::test::LogPerfResult(case_name, "Avg", avg, "ms/1000call"); - mojo::test::LogPerfResult(case_name, "SD", sd, "ms/1000call"); -} - -TEST_F(RequestResponsePerfTest, TrackingEnabled) { - Environment::GetDefaultTaskTracker()->SetEnabled(true); - Measure(__FUNCTION__); - Environment::GetDefaultTaskTracker()->SetEnabled(false); -} - -TEST_F(RequestResponsePerfTest, TrackingDisabled) { - Measure(__FUNCTION__); -} - -} // namespace -} // namespace test -} // namespace mojo diff --git a/mojo/tools/BUILD.gn b/mojo/tools/BUILD.gn deleted file mode 100644 index dbeaf7e2d9ace..0000000000000 --- a/mojo/tools/BUILD.gn +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2014 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. - -executable("message_generator") { - testonly = true - output_name = "mojo_message_generator" - - sources = [ - "message_generator.cc", - ] - - deps = [ - "//base", - "//build/config/sanitizers:deps", - "//mojo/common", - "//mojo/edk/system", - "//mojo/environment:chromium", - "//mojo/public/cpp/bindings", - "//testing/gtest", - ] -} - -executable("remote_file_reader") { - sources = [ - "remote_file_reader.cc", - ] -} diff --git a/mojo/tools/analyze_bloat.py b/mojo/tools/analyze_bloat.py deleted file mode 100755 index 90ced08f2c9d9..0000000000000 --- a/mojo/tools/analyze_bloat.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env python -# Copyright 2015 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. - -import argparse -import logging -import os -import re -import subprocess -import sys - -from mopy.paths import Paths - -ANDROID_TOOLS_DIR = ('third_party/android_tools/ndk/toolchains/' + - 'arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin') - -def binaries(path): - for item in os.listdir(path): - match = re.match(r'^(\w+)\.mojo$', item) - if match: - name = match.group(1) - if name.endswith('apptests'): - continue - binary = os.path.join(path, 'lib%s_library.so' % name) - if os.path.exists(binary): - yield name, binary - -def check_deps(): - success = True - if not os.path.exists('bloat'): - print ("Can't find bloat.py. Did you " + - "'git clone https://github.com/martine/bloat.git' ?") - success = False - if not os.path.exists('webtreemap'): - print ("Can't find webtreemap. Did you " + - "'git clone https://github.com/martine/webtreemap.git' ?") - success = False - if not success: - sys.exit(1) - -def main(): - logging.basicConfig(level=logging.WARN) - parser = argparse.ArgumentParser(description='Dump bloat treeview.') - args = parser.parse_args() - check_deps() - - # Always use android release? - rel_build_dir = os.path.join('out', 'android_Release') - src_root = Paths().src_root - build_dir = os.path.join(src_root, rel_build_dir) - - tools_dir = os.path.join(src_root, ANDROID_TOOLS_DIR) - tools_prefix = 'arm-linux-androideabi-' - - nm = os.path.join(tools_dir, tools_prefix + 'nm') - objdump = os.path.join(tools_dir, tools_prefix + 'objdump') - - for name, binary in binaries(build_dir): - print 'Analyzing', name - - nm_path = name + '.nm' - objdump_path = name + '.objdump' - json_path = name + '.json' - html_path = name + '.html' - - with open(nm_path, 'w') as nm_file: - args = [nm, '-C', '-S', '-l', binary] - subprocess.check_call(args, stdout=nm_file) - - with open(objdump_path, 'w') as objdump_file: - subprocess.check_call([objdump, '-h', binary], stdout=objdump_file) - - with open(json_path, 'w') as json_file: - subprocess.check_call([ - sys.executable, - 'bloat/bloat.py', - '--nm-output=' + nm_path, - '--objdump-output=' + objdump_path, - '--strip-prefix=' + src_root + '/', - 'syms' - ], stdout=json_file) - - source = None - with open('bloat/index.html', 'r') as source_file: - source = source_file.read().replace('bloat.json', json_path) - - with open(html_path, 'w') as html_file: - html_file.write(source) - - -if __name__ == '__main__': - main() diff --git a/mojo/tools/android_shortcuts/BUILD.gn b/mojo/tools/android_shortcuts/BUILD.gn deleted file mode 100644 index e560661b01f7a..0000000000000 --- a/mojo/tools/android_shortcuts/BUILD.gn +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2015 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. - -assert(is_android) - -import("//build/config/android/config.gni") -import("//build/config/android/rules.gni") - -group("android_shortcuts") { - deps = [ - ":java", - ":shortcuts_apk", - ] -} - -android_library("java") { - java_files = [ - "apk/src/org/chromium/mojo/shortcuts/AlarmReceiver.java", - "apk/src/org/chromium/mojo/shortcuts/ApplicationUpdater.java", - "apk/src/org/chromium/mojo/shortcuts/ShortcutsActivity.java", - ] -} - -android_resources("resources") { - resource_dirs = [ "apk/res" ] - custom_package = "org.chromium.mojo.shortcuts" -} - -android_apk("shortcuts_apk") { - apk_name = "MojoShortcuts" - - android_manifest = "apk/AndroidManifest.xml" - - asset_location = "apk/res" - - deps = [ - ":java", - ":resources", - ] -} diff --git a/mojo/tools/android_shortcuts/apk/AndroidManifest.xml b/mojo/tools/android_shortcuts/apk/AndroidManifest.xml deleted file mode 100644 index 12a93fe370367..0000000000000 --- a/mojo/tools/android_shortcuts/apk/AndroidManifest.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mojo/tools/android_shortcuts/apk/res/values/strings.xml b/mojo/tools/android_shortcuts/apk/res/values/strings.xml deleted file mode 100644 index fe96745e24769..0000000000000 --- a/mojo/tools/android_shortcuts/apk/res/values/strings.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - -Mojo Shortcuts - diff --git a/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/AlarmReceiver.java b/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/AlarmReceiver.java deleted file mode 100644 index 98f540a81c680..0000000000000 --- a/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/AlarmReceiver.java +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2015 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. - -package org.chromium.mojo.shortcuts; - -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; - -/** - * Receives broadcast when device is rebooted or through the {@link AlarmManager}. - */ -public class AlarmReceiver extends BroadcastReceiver { - private static final ScheduledExecutorService EXECUTOR = - Executors.newSingleThreadScheduledExecutor(); - - public static void setupAlarm(Context context) { - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - Intent intent = new Intent(context, AlarmReceiver.class); - PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0); - alarmManager.cancel(alarmIntent); - alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, - AlarmManager.INTERVAL_DAY, AlarmManager.INTERVAL_DAY, alarmIntent); - } - - /** - * @see android.content.BroadcastReceiver#onReceive(android.content.Context, - * android.content.Intent) - */ - @Override - public void onReceive(final Context context, Intent intent) { - // This receiver listen to android.intent.action.BOOT_COMPLETED through the application - // manifest. When this happens, register the alarm. - if (intent.getAction() != null - && intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { - setupAlarm(context); - } - // In all cases, whether this is called through the alarm or at boot, check for applications - // to update. - EXECUTOR.execute(new Runnable() { - - @Override - public void run() { - ApplicationUpdater.checkAndUpdateApplications(context); - } - }); - } -} diff --git a/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ApplicationUpdater.java b/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ApplicationUpdater.java deleted file mode 100644 index 33d59701e424d..0000000000000 --- a/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ApplicationUpdater.java +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2015 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. - -package org.chromium.mojo.shortcuts; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.Environment; -import android.util.Log; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; - -/** - * Helper class to update apks. - */ -public class ApplicationUpdater { - private static final String TAG = "ApplicationUpdater"; - - private static class ApplicationLocation { - private final String mPackageName; - private final String mURL; - - public ApplicationLocation(String packageName, String url) { - mPackageName = packageName; - mURL = url; - } - - /** - * Returns the application package. - */ - public String getPackageName() { - return mPackageName; - } - - /** - * Returns the application update URL. - */ - public URL getURL() { - try { - return new URL(mURL); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - } - } - - private static final ApplicationLocation[] APPLICATIONS = { - new ApplicationLocation( - "org.chromium.mojo.shortcuts", "http://domokit.github.io/MojoShortcuts.apk"), - new ApplicationLocation( - "org.chromium.mojo.shell", "http://domokit.github.io/MojoShell.apk")}; - - private static boolean applicationNeedsUpdate( - Context context, ApplicationLocation application) { - PackageManager pm = context.getPackageManager(); - try { - PackageInfo pi = pm.getPackageInfo(application.getPackageName(), 0); - HttpURLConnection urlConnection = - (HttpURLConnection) application.getURL().openConnection(); - urlConnection.setRequestMethod("HEAD"); - urlConnection.connect(); - long application_timestamp = urlConnection.getHeaderFieldDate("Last-Modified", 0); - return application_timestamp > pi.lastUpdateTime; - } catch (PackageManager.NameNotFoundException e) { - return true; - } catch (IOException e) { - Log.e(TAG, - "Unable to retrieve information for package: " + application.getPackageName(), - e); - } - return false; - } - - private static String hex(byte bytes[]) { - StringBuilder sb = new StringBuilder(); - for (byte b : bytes) { - sb.append(String.format("%02x", b & 0xff)); - } - return sb.toString(); - } - - private static String getFilename(URL url) { - try { - return hex(url.toString().getBytes("UTF8")); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - - private static void cleanDownloadDirectory() { - File directory = getDownloadDirectory(); - for (File file : directory.listFiles()) { - file.delete(); - } - } - - private static File getDownloadDirectory() { - File directory = new File(Environment.getExternalStorageDirectory(), "mojo_shortcuts"); - directory.mkdirs(); - return directory; - } - - private static void updateApplication(Context context, ApplicationLocation application) { - try { - URL url = application.getURL(); - HttpURLConnection c = (HttpURLConnection) url.openConnection(); - c.setRequestMethod("GET"); - c.connect(); - - File outputFile = new File(getDownloadDirectory(), getFilename(url)); - - FileOutputStream fos = new FileOutputStream(outputFile); - try { - InputStream is = c.getInputStream(); - try { - byte[] buffer = new byte[4096]; - int len1 = 0; - while ((len1 = is.read(buffer)) != -1) { - fos.write(buffer, 0, len1); - } - } finally { - is.close(); - } - } finally { - fos.close(); - } - - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType( - Uri.fromFile(outputFile), "application/vnd.android.package-archive"); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); - } catch (IOException e) { - Log.e(TAG, "Unable to update package: " + application.getPackageName(), e); - } - } - - public static void checkAndUpdateApplications(Context context) { - cleanDownloadDirectory(); - for (ApplicationLocation application : APPLICATIONS) { - if (applicationNeedsUpdate(context, application)) { - updateApplication(context, application); - } - } - } -} diff --git a/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ShortcutsActivity.java b/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ShortcutsActivity.java deleted file mode 100644 index 4f8fcb6a51d70..0000000000000 --- a/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ShortcutsActivity.java +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2015 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. - -package org.chromium.mojo.shortcuts; - -import android.app.Activity; -import android.content.ComponentName; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.os.Bundle; -import android.util.JsonWriter; -import android.util.Log; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.List; - -/** - * Main activity for the shortcuts application. It installs default shortcuts and sets up the alarm - * for the auto-update process. - */ -public class ShortcutsActivity extends Activity { - private static final String TAG = "ShortcutsActivity"; - - private static class Shortcut { - private final String mName; - private final String mUrl; - - public Shortcut(String name, String url) { - mName = name; - mUrl = url; - } - - public String getName() { - return mName; - } - - public String getUrl() { - return mUrl; - } - - public Intent getIntent() throws IOException { - List commandLine = new ArrayList(); - commandLine.add("--origin=https://domokit.github.io/mojo"); - commandLine.add("--url-mappings=mojo:window_manager=mojo:kiosk_wm"); - commandLine.add("--args-for=mojo:window_manager " + getUrl()); - commandLine.add("mojo:window_manager"); - Intent intent = new Intent(); - intent.setComponent(new ComponentName( - "org.chromium.mojo.shell", "org.chromium.mojo.shell.MojoShellActivity")); - intent.setAction(Intent.ACTION_VIEW); - intent.putExtra("encodedParameters", jsonEncode(commandLine)); - return intent; - } - - private static String jsonEncode(List list) throws IOException { - StringWriter sw = new StringWriter(); - JsonWriter json = new JsonWriter(sw); - json.beginArray(); - for (String p : list) { - json.value(p); - } - json.endArray(); - json.close(); - return sw.toString(); - } - } - - private static final Shortcut[] SHORTCUTS = { - new Shortcut("Home", "https://domokit.github.io/home")}; - - /** - * @see android.app.Activity#onCreate(android.os.Bundle) - */ - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - SharedPreferences shortcuts = getSharedPreferences("shortcuts", MODE_PRIVATE); - Editor editor = shortcuts.edit(); - - for (Shortcut shortcut : SHORTCUTS) { - try { - Intent intent = new Intent(); - intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcut.getIntent()); - intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, shortcut.getName()); - intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT"); - sendBroadcast(intent); - - intent = new Intent(); - intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcut.getIntent()); - intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, shortcut.getName()); - intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); - sendBroadcast(intent); - } catch (IOException e) { - Log.e(TAG, "Unable to install shortcut", e); - } - editor.putString(shortcut.getName(), shortcut.getUrl()); - } - editor.apply(); - AlarmReceiver.setupAlarm(this); - finish(); - } -} diff --git a/mojo/tools/apptest_runner.py b/mojo/tools/apptest_runner.py deleted file mode 100755 index b3378efafb602..0000000000000 --- a/mojo/tools/apptest_runner.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -"""A test runner for application tests.""" - -import argparse -import logging -import os.path -import subprocess -import sys - -from mopy import gtest -from mopy.config import Config -from mopy.gn import ConfigForGNArgs, ParseGNConfig -from mopy.log import InitLogging -from mopy.paths import Paths - - -_logger = logging.getLogger() - - -def main(): - parser = argparse.ArgumentParser(description="A test runner for application " - "tests.") - - parser.add_argument("--verbose", help="be verbose (multiple times for more)", - default=0, dest="verbose_count", action="count") - parser.add_argument("test_list_file", type=str, - help="a file listing apptests to run") - parser.add_argument("build_dir", type=str, - help="the build output directory") - args = parser.parse_args() - - InitLogging(args.verbose_count) - config = ConfigForGNArgs(ParseGNConfig(args.build_dir)) - paths = Paths(config) - command_line = [os.path.join(os.path.dirname(__file__), os.path.pardir, - "devtools", "common", "mojo_test"), - str(args.test_list_file)] - - if config.target_os == Config.OS_ANDROID: - command_line.append("--android") - command_line.append("--adb-path=" + paths.adb_path) - command_line.append("--origin=" + paths.build_dir) - - command_line.append("--shell-path=" + paths.target_mojo_shell_path) - if args.verbose_count: - command_line.append("--verbose") - - gtest.set_color() - print "Running " + str(command_line) - ret = subprocess.call(command_line) - return ret - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/mojo/tools/check_mojom_golden_files.py b/mojo/tools/check_mojom_golden_files.py deleted file mode 100755 index ae80cebd61e1d..0000000000000 --- a/mojo/tools/check_mojom_golden_files.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -import argparse -import os.path -import sys -from filecmp import dircmp -from shutil import rmtree -from tempfile import mkdtemp -from mopy.paths import Paths - -paths = Paths() - -sys.path.insert(0, os.path.join(paths.mojo_dir, "public", "tools", "bindings", - "pylib")) -from mojom_tests.support.find_files import FindFiles -from mojom_tests.support.run_bindings_generator import RunBindingsGenerator - - -def _ProcessDircmpResults(results, verbose=False): - """Prints results of directory comparison and returns true if they are - identical (note: the "left" directory should be the golden directory).""" - rv = not (bool(results.left_only) or bool(results.right_only) or \ - bool(results.common_funny) or bool(results.funny_files) or \ - bool(results.diff_files)) - if verbose: - for f in results.left_only: - print "%s exists in golden directory but not in current output" % f - for f in results.right_only: - print "%s exists in current output but not in golden directory" % f - for f in results.common_funny + results.funny_files: - print "Unable to compare %s between golden directory and current output" \ - % f - for f in results.diff_files: - print "%s differs between golden directory and current output" % f - for r in results.subdirs.values(): - # If we're being verbose, check subdirectories even if we know that there - # are differences. Note that it's "... and rv" to avoid the short-circuit. - if rv or verbose: - rv = _ProcessDircmpResults(r, verbose=verbose) and rv - return rv - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument("--generate_golden_files", action="store_true", - help=("generate golden files (does not obliterate " - "directory")) - parser.add_argument("--keep_temp_dir", action="store_true", - help="don't delete the temporary directory") - parser.add_argument("--verbose", action="store_true", - help="spew excess verbiage") - parser.add_argument("golden_dir", metavar="GOLDEN_DIR", - help="directory with the golden files") - args = parser.parse_args() - - if args.generate_golden_files: - if os.path.exists(args.golden_dir): - print "WARNING: golden directory %s already exists" % args.golden_dir - out_dir = args.golden_dir - else: - if not os.path.exists(args.golden_dir): - print "ERROR: golden directory %s does not exist" % args.golden_dir - return 1 - out_dir = mkdtemp() - if args.verbose: - print "Generating files to %s ..." % out_dir - - mojom_files = FindFiles(paths.mojo_dir, "*.mojom") - for mojom_file in mojom_files: - if args.verbose: - print " Processing %s ..." % os.path.relpath(mojom_file, paths.mojo_dir) - # TODO(vtl): This may wrong, since the path can be overridden in the .gyp - # file. - RunBindingsGenerator(out_dir, paths.mojo_dir, mojom_file, - ["-I", paths.src_root]) - - if args.generate_golden_files: - return 0 - - identical = _ProcessDircmpResults(dircmp(args.golden_dir, out_dir, ignore=[]), - verbose=args.verbose) - - if args.keep_temp_dir: - if args.verbose: - print "Not removing %s ..." % out_dir - else: - if args.verbose: - print "Removing %s ..." % out_dir - rmtree(out_dir) - - if not identical: - print "FAILURE: current output differs from golden files" - return 1 - - print "SUCCESS: current output identical to golden files" - return 0 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/mojo/tools/data/apptests b/mojo/tools/data/apptests deleted file mode 100644 index 6cada410ae67f..0000000000000 --- a/mojo/tools/data/apptests +++ /dev/null @@ -1,127 +0,0 @@ -# This file contains a list of Mojo apptests. For description of the file -# format, see `mojo_test` in devtools. - -tests = [ - { - "test": "mojo:asset_bundle_apptests", - }, - { - "test": "mojo:authenticating_url_loader_interceptor_apptests", - }, - { - "test": "mojo:clipboard_apptests", - }, - { - "test": "mojo:example_apptests", - # ExampleApplicationTest.CheckCommandLineArg checks --example_apptest_arg. - "test-args": ["--example_apptest_arg"], - }, - { - "test": "mojo:example_apptests", - "name": "mojo:example_apptests (multiprocess)", - # ExampleApplicationTest.CheckCommandLineArg checks --example_apptest_arg. - "test-args": ["--example_apptest_arg"], - "shell-args": ["--enable-multiprocess"], - }, - { - "test": "mojo:files_apptests", - }, - { - "test": "mojo:http_server_apptests", - }, - { - "test": "mojo:mojio_apptests", - }, - { - "test": "mojo:moterm_apptests", - "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"], - }, - { - "test": "mojo:texture_apptests", - "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"], - }, - { - "test": "mojo:mojo_view_manager_client_apptests", - "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"], - }, - { - "test": "mojo:prediction_apptests", - }, - { - "test": "mojo:view_manager_service_apptests", - "type": "gtest_isolated", - "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"], - }, - { - "test": "mojo:network_service_apptests", - }, - { - "test": "mojo:window_manager_apptests", - "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"], - }, - { - "test": "mojo:versioning_apptests", - }, - { - "test": "mojo:url_response_disk_cache_apptests", - }, -] - -if target_os == 'linux': - tests += [ - { - "test": "mojo:example_apptests", - "name": "mojo:example_apptests (python_example_service)", - # ExampleApplicationTest.CheckCommandLineArg checks --example_apptest_arg. - "test-args": ["--example_apptest_arg"], - "shell-args": [ - "--url-mappings=mojo:example_service=mojo:python_example_service" - ], - }, - { - "test": "mojo:mojo_url_redirector_apptests", - "test-args": ["--redirector_port=49152", - "--app_location_files_port=49153"], - "shell-args": ["--args-for=mojo:mojo_url_redirector 0.0.0.0:49152 http://localhost:49153"], - } - ] - -if target_os == 'android': - tests += [ - { - "test": "mojo:example_apptests", - "name": "mojo:example_apptests (android_example_service)", - # ExampleApplicationTest.CheckCommandLineArg checks --example_apptest_arg. - "test-args": ["--example_apptest_arg"], - "shell-args": [ - "--url-mappings=mojo:example_service=mojo:android_example_service" - ], - }, - { - "test": "mojo:notification_apptests", - }, - { - "test": "mojo:shell_nfc_apptests", - }, - ] - -if target_os != 'android': - tests += [ - { - "test": "mojo:js_apptests", - "type": "gtest_isolated", - }, - { - "test": "mojo:reaper_apptests", - }, - { - "test": "mojo:dart_apptests", - "type": "dart", - }, - { - # https://github.com/domokit/mojo/issues/61 - # Sometime the shell get a trucated application when exposed through the - # http server. - "test": "mojo:shell_apptests", - }, - ] diff --git a/mojo/tools/data/nacl_apptests b/mojo/tools/data/nacl_apptests deleted file mode 100644 index eeba8ca90e8bc..0000000000000 --- a/mojo/tools/data/nacl_apptests +++ /dev/null @@ -1,33 +0,0 @@ -# This file contains a list of NaCl Mojo gtest unit tests. -# This must be a valid python dictionary. -# TODO(vtl|msw): Add a way of specifying data dependencies. -tests = [ - # TODO(ncbray): support other architectures. - { - "test": "mojo:clipboard_apptests_x64.nexe", - }, - { - "test": "mojo:example_apptests_x64.nexe", - # ExampleApplicationTest.CheckCommandLineArg checks --example_apptest_arg. - "test-args": ["--example_apptest_arg"], - }, - { - "test": "mojo:files_apptests_x64.nexe", - }, - { - "test": "mojo:mojo_view_manager_client_apptests_x64.nexe", - "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"], - }, - { - "test": "mojo:view_manager_service_apptests_x64.nexe", - "type": "gtest_isolated", - "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"], - }, - { - "test": "mojo:window_manager_apptests_x64.nexe", - }, - { - "test": "mojo:shell_apptests_x64.nexe", - }, - # TODO(ncbray): http_server_apptests (uses two-stage data pipe reads) -] diff --git a/mojo/tools/data/unittests b/mojo/tools/data/unittests deleted file mode 100644 index 39af3241aaf6f..0000000000000 --- a/mojo/tools/data/unittests +++ /dev/null @@ -1,96 +0,0 @@ -# This file contains a list of Mojo gtest unit tests. -# This must be valid python. It can use the |config| global that will be a -# mopy.config.Config object and must set a |tests| global that will contain the -# tests to run. -# TODO(vtl): Add a way of specifying data dependencies instead of cacheable. - -tests = [ - # System tests: - { - "test": "mojo_system_unittests", - }, - - # Public tests: - { - "test": "mojo_public_bindings_unittests", - "cacheable": False, - }, - { - "test": "mojo_public_environment_unittests", - }, - { - "test": "mojo_public_system_unittests", - }, - { - "test": "mojo_public_utility_unittests", - }, - { - "test": "mojo_system_impl_private_unittests", - }, - - # Non-system, non-public tests: - { - "test": "crypto_unittests", - }, - { - "test": "mojo_application_manager_unittests", - }, - { - "test": "mojo_common_unittests", - }, - { - "test": "mojo_view_manager_lib_unittests", - }, - { - "test": "mojo_surfaces_lib_unittests", - }, - { - "test": "view_manager_service_unittests", - }, - { - "test": "window_manager_unittests", - }, - - # Shell integration tests: - { - "test": "mojo_shell_tests", - "cacheable": False, - }, - { - "test": "crash_unittests", - }, -] - -if config.target_os != config.OS_ANDROID: - tests += [ - # Tests for components we depend on: - { - "test": "gfx_unittests", - }, - { - "test": "events_unittests", - }, - - # JavaScript tests: - { - "test": "js_unittests", - "cacheable": False, - }, - { - "test": "js_integration_tests", - "cacheable": False, - }, - { - "test": "js_services_unittests", - "cacheable": False, - }, - ] - -# TODO: get dart unittests working with android. -if config.target_os != config.OS_ANDROID: - tests += [ - { - "test": "dart_unittests", - "cacheable": False, - }, - ] diff --git a/mojo/tools/deploy_domokit_site.py b/mojo/tools/deploy_domokit_site.py deleted file mode 100755 index 7175092ba1499..0000000000000 --- a/mojo/tools/deploy_domokit_site.py +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env python -# Copyright 2015 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. - -"""Deploy domokit.github.io""" - -# NOTE: Requires that download_material_design_icons to have been run from -# $build_dir/gen/dart-dpkg/sky. - -import argparse -import logging -import os -import shutil -import subprocess - -from mopy.paths import Paths - - -def git_revision(): - return subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip() - - -def mojo_filter(path): - if not os.path.isfile(path): - return False - _, ext = os.path.splitext(path) - if ext != '.mojo': - return False - return 'apptests' not in os.path.basename(path) - - -def gen_filter(path): - if os.path.isdir(path): - return True - _, ext = os.path.splitext(path) - # Don't include all .dart, just .mojom.dart. - return ext == '.sky' or path.endswith('.mojom.dart') - - -def examples_filter(path): - if os.path.isdir(path): - return True - return 'packages' != os.path.basename(path) - - -def sky_or_dart_filter(path): - if os.path.isdir(path): - return True - _, ext = os.path.splitext(path) - # .dart includes '.mojom.dart' - return ext == '.sky' or ext == '.dart' - - -def assets_filter(path): - if os.path.isdir(path): - return True - if os.path.basename(os.path.dirname(path)) != 'drawable-xxhdpi': - return False - # We only use the 18 and 24s for now. - return '18dp' in path or '24dp' in path - - -def packages_filter(path): - if 'packages/sky/assets/material-design-icons/' in path: - return assets_filter(path) - if '.gitignore' in path: - return False - return True - - -def ensure_dir_exists(path): - if not os.path.exists(path): - os.makedirs(path) - - -def copy(from_root, to_root, filter_func=None, followlinks=False): - assert os.path.exists(from_root), "%s does not exist!" % from_root - if os.path.isfile(from_root): - ensure_dir_exists(os.path.dirname(to_root)) - shutil.copy(from_root, to_root) - return - - if os.path.exists(to_root): - shutil.rmtree(to_root) - os.makedirs(to_root) - - for root, dirs, files in os.walk(from_root, followlinks=followlinks): - # filter_func expects paths not names, so wrap it to make them absolute. - wrapped_filter = None - if filter_func: - wrapped_filter = lambda name: filter_func(os.path.join(root, name)) - - for name in filter(wrapped_filter, files): - from_path = os.path.join(root, name) - root_rel_path = os.path.relpath(from_path, from_root) - to_path = os.path.join(to_root, root_rel_path) - to_dir = os.path.dirname(to_path) - if not os.path.exists(to_dir): - os.makedirs(to_dir) - shutil.copyfile(from_path, to_path) - - dirs[:] = filter(wrapped_filter, dirs) - - -def main(): - logging.basicConfig(level=logging.WARN) - parser = argparse.ArgumentParser(description='Deploy a new build of mojo.') - parser.add_argument('deploy_root', type=str) - args = parser.parse_args() - - # Always use android release? - rel_build_dir = os.path.join('out', 'android_Release') - build_dir = os.path.join(Paths().src_root, rel_build_dir) - paths = Paths(build_dir=build_dir) - dart_pkg_dir = os.path.join(paths.build_dir, 'gen', 'dart-pkg') - sky_pkg_dir = os.path.join(dart_pkg_dir, 'sky') - sky_pkg_lib_dir = os.path.join(sky_pkg_dir, 'lib') - dart_pkg_packages_dir = os.path.join(dart_pkg_dir, 'packages') - - def deploy_path(rel_path): - return os.path.join(args.deploy_root, rel_path) - - def src_path(rel_path): - return os.path.join(paths.src_root, rel_path) - - # Verify that material-design-icons have been downloaded. - icons_dir = os.path.join(dart_pkg_packages_dir, - 'sky/assets/material-design-icons') - if not os.path.isdir(icons_dir): - print('NOTE: Running `download_material_design_icons` for you.'); - subprocess.check_call([ - os.path.join(sky_pkg_lib_dir, 'download_material_design_icons') - ]) - - # Copy sky/sdk/example into example/ - copy(src_path('sky/sdk/example'), deploy_path('example'), examples_filter) - - # Deep copy packages/. This follows symlinks and flattens them. - packages_root = deploy_path('packages') - copy(dart_pkg_packages_dir, packages_root, packages_filter, True) - - # Write out license. - with open(deploy_path('LICENSES.sky'), 'w') as license_file: - subprocess.check_call([src_path('tools/licenses.py'), 'credits'], - stdout=license_file) - - # Run git commands. - subprocess.check_call(['git', 'add', '.'], cwd=args.deploy_root) - subprocess.check_call([ - 'git', 'commit', - '-m', '%s from %s' % (rel_build_dir, git_revision()) - ], cwd=args.deploy_root) - - -if __name__ == '__main__': - main() diff --git a/mojo/tools/devtools.py b/mojo/tools/devtools.py deleted file mode 100644 index 28a0d91995185..0000000000000 --- a/mojo/tools/devtools.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2015 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. - -import os -import sys - - -def add_lib_to_path(): - """ Adds the devtools pylib to path, allowing to use it in the internal - /mojo/tools/ tooling. """ - sys.path.append(os.path.join(os.path.dirname(__file__), - os.pardir, - "devtools", - "common")) diff --git a/mojo/tools/download_keystore.py b/mojo/tools/download_keystore.py deleted file mode 100755 index 97ed4b5d1ae4e..0000000000000 --- a/mojo/tools/download_keystore.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env python -# Copyright 2015 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. - -"""Tool to download keys needed to sign the official Mojo Shell APK build. -""" - -import argparse -import os -import subprocess -import sys - -import mopy.gn as gn -from mopy.config import Config -from mopy.paths import Paths - - -# Google Storage path of the official keystore to download. -_KEYSTORE_PATH = "gs://mojo/android/keys/mojo_shell-official.keystore" -_KEYSTORE_PWD_PATH = "gs://mojo/android/keys/mojo_shell-official.pwd" - - -def _get_gsutil_exe(): - """Get the path to gsutil executable.""" - config = Config(target_os=Config.OS_ANDROID, is_debug=False, - is_official_build=True) - paths = Paths(config) - sys.path.insert(0, os.path.join(paths.src_root, "tools")) - # pylint: disable=F0401 - import find_depot_tools - depot_tools_path = find_depot_tools.add_depot_tools_to_path() - gsutil_exe = os.path.join(depot_tools_path, "third_party", "gsutil", - "gsutil") - return gsutil_exe - - -def _download_keystore(args): - """Downloads the keystore file on local disk.""" - directory_path = args.output[0] - if args.verbose: - print "Downloading " + _KEYSTORE_PATH + " to " + directory_path - gsutil_exe = _get_gsutil_exe() - if args.dry_run: - print str([gsutil_exe, "cp", _KEYSTORE_PATH, directory_path]) - else: - subprocess.check_call([gsutil_exe, "cp", _KEYSTORE_PATH, directory_path]) - - -def _output_password(args): - """Outputs the keystore password on the standard output.""" - # The build system cannot read a file that is generated by a script and - # use its content as a variable. It can either 1/ read a file already there - # or 2/ put a script output in a variable. Hence the fact that we do not - # download the password to a file, but output it on the standard output. - gsutil_exe = _get_gsutil_exe() - - if args.dry_run: - print str([gsutil_exe, "cat", _KEYSTORE_PWD_PATH]) - else: - subprocess.check_call([gsutil_exe, "cat", _KEYSTORE_PWD_PATH], - stdout=sys.stdout) - - -def main(): - parser = argparse.ArgumentParser( - description="Downloads the keystore used to sign official APK builds.") - parser.add_argument("-n", "--dry_run", help="Dry run, do not actually "+ - "download", action="store_true") - parser.add_argument("-v", "--verbose", help="Verbose mode", - action="store_true") - - subparsers = parser.add_subparsers() - - keystore_file_parser = subparsers.add_parser( - "keystore_file", help="Downloads the keystore file") - keystore_file_parser.add_argument("output", nargs=1, type=str, - help="Output path to save the keystore to") - keystore_file_parser.set_defaults(func=_download_keystore) - - keystore_pwd_parser = subparsers.add_parser( - "keystore_password", help="Outputs the keystore password") - keystore_pwd_parser.set_defaults(func=_output_password) - - args = parser.parse_args() - args.func(args) - - - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/mojo/tools/embed/data.h b/mojo/tools/embed/data.h deleted file mode 100644 index 50bf074497469..0000000000000 --- a/mojo/tools/embed/data.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2015 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. - -#ifndef MOJO_TOOLS_EMBED_DATA_H_ -#define MOJO_TOOLS_EMBED_DATA_H_ - -#include // For size_t. - -namespace mojo { -namespace embed { - -struct Data { - const char* const hash; - const char* const data; - const size_t size; -}; - -} // namespace embed -} // namespace mojo - -#endif // MOJO_TOOLS_EMBED_DATA_H_ diff --git a/mojo/tools/embed/embed_data.py b/mojo/tools/embed/embed_data.py deleted file mode 100755 index f34348ae5c84c..0000000000000 --- a/mojo/tools/embed/embed_data.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python -# Copyright 2015 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. - -import argparse -import hashlib -import os -import sys - -def main(): - """Command line utility to embed file in a C executable.""" - parser = argparse.ArgumentParser( - description='Generate a source file to embed the content of a file') - - parser.add_argument('source') - parser.add_argument('out_dir') - parser.add_argument('namespace') - parser.add_argument('variable') - - opts = parser.parse_args() - - if not os.path.exists(opts.out_dir): - os.makedirs(opts.out_dir) - - header = os.path.join(opts.out_dir, '%s.h' % opts.variable) - c_file = os.path.join(opts.out_dir, '%s.cc' % opts.variable) - namespaces = opts.namespace.split('::') - - data = None - with open(opts.source, "rb") as f: - data = f.read() - - with open(header, "w") as f: - f.write('// Generated file. Do not modify.\n') - f.write('\n') - f.write('#include "mojo/tools/embed/data.h"\n') - f.write('\n') - for n in namespaces: - f.write('namespace %s {\n' % n) - f.write('extern const mojo::embed::Data %s;\n' % opts.variable); - for n in reversed(namespaces): - f.write('} // namespace %s\n' % n) - - sha1hash = hashlib.sha1(data).hexdigest() - values = ["0x%02x" % ord(c) for c in data] - lines = [] - chunk_size = 16 - for i in range(0, len(values), chunk_size): - lines.append(" " + ", ".join(values[i: i + chunk_size])) - - with open(c_file, "w") as f: - f.write('// Generated file. Do not modify.\n') - f.write('\n') - f.write('#include "mojo/tools/embed/data.h"\n') - f.write('\n') - for n in namespaces: - f.write('namespace %s {\n' % n) - f.write('namespace {\n') - f.write("const char data[%d] = {\n" % len(data)) - f.write(",\n".join(lines)) - f.write("\n};\n") - f.write('} // namespace\n') - f.write('\n') - f.write('extern const mojo::embed::Data %s;\n' % opts.variable); - f.write('const mojo::embed::Data %s = {\n' % opts.variable); - f.write(' "%s",\n' % sha1hash) - f.write(' data,\n') - f.write(' sizeof(data)\n') - f.write('};\n'); - f.write('\n') - for n in reversed(namespaces): - f.write('} // namespace %s\n' % n) - -if __name__ == '__main__': - main() diff --git a/mojo/tools/embed/rules.gni b/mojo/tools/embed/rules.gni deleted file mode 100644 index 6171812669126..0000000000000 --- a/mojo/tools/embed/rules.gni +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright 2015 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. - -template("embed_file") { - assert(defined(invoker.variable)) - assert(defined(invoker.source)) - assert(defined(invoker.namespace)) - - variable = invoker.variable - generator_target_name = "__${target_name}_generator" - generator_outputs = [ - "${target_gen_dir}/${variable}.cc", - "${target_gen_dir}/${variable}.h", - ] - - action(generator_target_name) { - script = "//mojo/tools/embed/embed_data.py" - sources = [ - invoker.source, - ] - outputs = generator_outputs - args = [ - rebase_path(invoker.source), - rebase_path(target_gen_dir), - invoker.namespace, - variable, - ] - - if (defined(invoker.testonly)) { - testonly = invoker.testonly - } - if (defined(invoker.deps)) { - deps = invoker.deps - } - } - - source_set(target_name) { - sources = generator_outputs - - if (defined(invoker.testonly)) { - testonly = invoker.testonly - } - - deps = [ - ":${generator_target_name}", - ] - } -} diff --git a/mojo/tools/generate_java_callback_interfaces.py b/mojo/tools/generate_java_callback_interfaces.py deleted file mode 100644 index 257a5403e07ab..0000000000000 --- a/mojo/tools/generate_java_callback_interfaces.py +++ /dev/null @@ -1,69 +0,0 @@ -"""Generate the org.chromium.mojo.bindings.Callbacks interface""" - -import argparse -import sys - -CALLBACK_TEMPLATE = (""" - /** - * A generic %d-argument callback. - * - * %s - */ - interface Callback%d<%s> { - /** - * Call the callback. - */ - public void call(%s); - } -""") - -INTERFACE_TEMPLATE = ( -"""// Copyright 2014 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. - -// This file was generated using -// mojo/tools/generate_java_callback_interfaces.py - -package org.chromium.mojo.bindings; - -/** - * Contains a generic interface for callbacks. - */ -public interface Callbacks { - - /** - * A generic callback. - */ - interface Callback0 { - /** - * Call the callback. - */ - public void call(); - } -%s -}""") - -def GenerateCallback(nb_args): - params = '\n * '.join( - ['@param the type of argument %d.' % (i+1, i+1) - for i in xrange(nb_args)]) - template_parameters = ', '.join(['T%d' % (i+1) for i in xrange(nb_args)]) - callback_parameters = ', '.join(['T%d arg%d' % ((i+1), (i+1)) - for i in xrange(nb_args)]) - return CALLBACK_TEMPLATE % (nb_args, params, nb_args, template_parameters, - callback_parameters) - -def main(): - parser = argparse.ArgumentParser( - description="Generate org.chromium.mojo.bindings.Callbacks") - parser.add_argument("max_args", nargs=1, type=int, - help="maximal number of arguments to generate callbacks for") - args = parser.parse_args() - max_args = args.max_args[0] - print INTERFACE_TEMPLATE % ''.join([GenerateCallback(i+1) - for i in xrange(max_args)]) - return 0 - -if __name__ == "__main__": - sys.exit(main()) diff --git a/mojo/tools/get_test_list.py b/mojo/tools/get_test_list.py deleted file mode 100755 index 341b3d803e732..0000000000000 --- a/mojo/tools/get_test_list.py +++ /dev/null @@ -1,243 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -"""Central list of tests to run (as appropriate for a given config). Add tests -to run by modifying this file. - -Note that this file is both imported (by mojob.py) and run directly (via a -recipe).""" - - -import argparse -import json -import os -import sys - -from mopy.config import Config -from mopy.paths import Paths - - -def GetTestList(config, verbose_count=0): - """Gets the list of tests to run for the given config. The test list (which is - returned) is just a list of dictionaries, each dictionary having two required - fields: - { - "name": "Short name", - "command": ["python", "test_runner.py", "--some", "args"] - } - """ - - types_to_run = set(config.test_types) - - # See above for a description of the test list. - test_list = [] - - paths = Paths(config) - build_dir = paths.SrcRelPath(paths.build_dir) - target_os = config.target_os - - verbose_flags = verbose_count * ["--verbose"] - - # Utility functions ---------------------------------------------------------- - - # Call this to determine if a test matching classes this_tests_types should - # run: e.g., ShouldRunTest(Config.TEST_TYPE_DEFAULT, "sky") returns true if - # the test list being requested specifies the default set or the "sky" set. - def ShouldRunTest(*this_tests_types): - return not types_to_run.isdisjoint(this_tests_types) - - # Call this to add the given command to the test list. - def AddEntry(name, command): - if config.sanitizer == Config.SANITIZER_ASAN: - command = (["python", os.path.join("mojo", "tools", - "run_command_through_symbolizer.py")] + - command) - test_list.append({"name": name, "command": command}) - - # Call this to add the given command to the test list. If appropriate, the - # command will be run under xvfb. - def AddXvfbEntry(name, command): - real_command = ["python"] - if config.target_os == Config.OS_LINUX: - real_command += ["./testing/xvfb.py", paths.SrcRelPath(paths.build_dir)] - real_command += command - AddEntry(name, real_command) - - # ---------------------------------------------------------------------------- - - # TODO(vtl): Currently, we only know how to run tests for Android, Linux, or - # Windows. - if target_os not in (Config.OS_ANDROID, Config.OS_LINUX, Config.OS_WINDOWS, - Config.OS_IOS): - return test_list - - # Tests run by default ------------------------------------------------------- - - # C++ unit tests: - if ShouldRunTest(Config.TEST_TYPE_DEFAULT, Config.TEST_TYPE_UNIT): - AddXvfbEntry("Unit tests", - [os.path.join("mojo", "tools", "test_runner.py"), - os.path.join("mojo", "tools", "data", "unittests"), - build_dir] + verbose_flags) - # NaCl tests (Linux only): - if (target_os == Config.OS_LINUX and - config.sanitizer != Config.SANITIZER_ASAN): - AddEntry("NaCl tests", - [os.path.join(build_dir, "monacl_shell"), - os.path.join(build_dir, "irt_" + config.target_cpu, - "irt_mojo.nexe"), - os.path.join(build_dir, "clang_newlib_" + config.target_cpu, - "monacl_test.nexe")]) - - # C++ app tests: - if ShouldRunTest(Config.TEST_TYPE_DEFAULT, "app"): - AddXvfbEntry("App tests", - [os.path.join("mojo", "tools", "apptest_runner.py"), - os.path.join("mojo", "tools", "data", "apptests"), - build_dir] + verbose_flags) - # NaCl app tests (Linux only): - if (target_os == Config.OS_LINUX and - config.sanitizer != Config.SANITIZER_ASAN): - AddXvfbEntry("NaCl app tests", - [os.path.join("mojo", "tools", "apptest_runner.py"), - os.path.join("mojo", "tools", "data", "nacl_apptests"), - build_dir] + verbose_flags) - - # Go unit tests (Linux-only): - if (target_os == Config.OS_LINUX and - config.sanitizer != Config.SANITIZER_ASAN and - ShouldRunTest(Config.TEST_TYPE_DEFAULT, Config.TEST_TYPE_UNIT, "go")): - AddEntry("Go unit tests", - [os.path.join(build_dir, "obj", "mojo", "go", "system_test")]) - - # Python unit tests: - if ShouldRunTest(Config.TEST_TYPE_DEFAULT, Config.TEST_TYPE_UNIT, "python"): - AddEntry("Python unit tests", - ["python", os.path.join("mojo", "tools", - "run_mojo_python_tests.py")]) - - # Python bindings tests (Linux-only): - # See http://crbug.com/438781 for details on asan exclusion. - if (target_os == Config.OS_LINUX and - ShouldRunTest(Config.TEST_TYPE_DEFAULT, Config.TEST_TYPE_UNIT, - "python") and - config.sanitizer != Config.SANITIZER_ASAN): - AddEntry("Python bindings tests", - ["python", - os.path.join("mojo", "tools", - "run_mojo_python_bindings_tests.py"), - "--build-dir=" + build_dir]) - - # Sky tests (Linux-only): - # TODO(abarth): Re-enabled in ASAN once the DartVM works in ASAN. - # See https://code.google.com/p/dart/issues/detail?id=22122 - if (target_os == Config.OS_LINUX and - ShouldRunTest(Config.TEST_TYPE_DEFAULT, "sky") and - config.sanitizer != Config.SANITIZER_ASAN): - sky_command = ["python", - "sky/tools/test_sky", - "-t", os.path.basename(build_dir), - "--no-new-test-results", "--no-show-results", "--verbose"] - if config.values.get("builder_name"): - sky_command += ["--builder-name", config.values["builder_name"]] - if config.values.get("build_number"): - sky_command += ["--build-number", config.values["build_number"]] - if config.values.get("master_name"): - sky_command += ["--master-name", config.values["master_name"]] - if config.values.get("test_results_server"): - sky_command += ["--test-results-server", - config.values["test_results_server"]] - AddXvfbEntry("Sky tests", sky_command) - - # Observatory tests (Linux-only): - if target_os == Config.OS_LINUX: - AddEntry("Dart Observatory tests", - ["python", - os.path.join("mojo", "dart", "observatory_tester", "runner.py"), - "--build-dir=" + build_dir, - "--dart-exe=third_party/dart-sdk/dart-sdk/bin/dart"]) - - AddEntry("Dart HTTP Load test", - ["python", - os.path.join("mojo", "dart", "http_load_test", "runner.py"), - "--build-dir=" + build_dir, - "--dart-exe=third_party/dart-sdk/dart-sdk/bin/dart"]) - - # mojo tools unit tests: - if ShouldRunTest(Config.TEST_TYPE_DEFAULT, Config.TEST_TYPE_UNIT, "tools"): - AddEntry("Mojo tools unit tests", - ["python", os.path.join("mojo", "tools", "testing", - "mojom_fetcher", - "mojom_fetcher_tests.py")]) - - # Dart mojom package generate.dart script tests: - if target_os == Config.OS_LINUX: - AddEntry("Dart mojom package generate tests", - [os.path.join("third_party", "dart-sdk", "dart-sdk", "bin", "dart"), - "--checked", - "-p", os.path.join("mojo", "dart", "mojom", "packages"), - os.path.join("mojo", "dart", "mojom", "test", "generate_test.dart")]) - - # Perf tests ----------------------------------------------------------------- - - if target_os == Config.OS_LINUX and ShouldRunTest(Config.TEST_TYPE_PERF): - perf_id = "linux_%s" % ("debug" if config.is_debug else "release") - test_names = ["mojo_public_system_perftests", - "mojo_public_bindings_perftests"] - - for test_name in test_names: - command = ["python", - os.path.join("mojo", "tools", "perf_test_runner.py"), - "--perf-id", perf_id, - "--test-name", test_name, - "--perf-data-path", - os.path.join(build_dir, test_name + "_perf.log"), - "--production-dashboard"] - if config.values.get("builder_name"): - command += ["--builder-name", config.values["builder_name"]] - if config.values.get("build_number"): - command += ["--build-number", config.values["build_number"]] - if config.values.get("master_name"): - command += ["--master-name", config.values["master_name"]] - command += [os.path.join(build_dir, test_name)] - - AddEntry(test_name, command) - - # Integration tests ---------------------------------------------------------- - - if target_os == Config.OS_ANDROID and ShouldRunTest( - Config.TEST_TYPE_DEFAULT, Config.TEST_TYPE_INTEGRATION): - AddEntry("Integration test (MojoTest)", - ["python", - os.path.join("build", "android", "test_runner.py"), - "instrumentation", - "--test-apk=MojoTest", - "--output-directory=%s" % build_dir, - "--test_data=bindings:mojo/public/interfaces/bindings/tests/data"] - + verbose_flags) - - return test_list - - -def main(): - parser = argparse.ArgumentParser(description="Gets tests to execute.") - parser.add_argument("config_file", metavar="config.json", - type=argparse.FileType("rb"), - help="Input JSON file with test configuration.") - parser.add_argument("test_list_file", metavar="test_list.json", nargs="?", - type=argparse.FileType("wb"), default=sys.stdout, - help="Output JSON file with test list.") - args = parser.parse_args() - - config = Config(**json.load(args.config_file)) - test_list = GetTestList(config) - json.dump(test_list, args.test_list_file, indent=2) - args.test_list_file.write("\n") - - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/mojo/tools/linux64/dump_syms.sha1 b/mojo/tools/linux64/dump_syms.sha1 deleted file mode 100644 index fd689489d1fa7..0000000000000 --- a/mojo/tools/linux64/dump_syms.sha1 +++ /dev/null @@ -1 +0,0 @@ -4bd8f841d0cebc3f7dac4c5bf2cdf86694605692 diff --git a/mojo/tools/linux64/symupload.sha1 b/mojo/tools/linux64/symupload.sha1 deleted file mode 100644 index d4563e44cc0f6..0000000000000 --- a/mojo/tools/linux64/symupload.sha1 +++ /dev/null @@ -1 +0,0 @@ -5d03513c81fba7f0acdc3ea314c46667d6624eb6 \ No newline at end of file diff --git a/mojo/tools/message_generator.cc b/mojo/tools/message_generator.cc deleted file mode 100644 index 08b7dccb59338..0000000000000 --- a/mojo/tools/message_generator.cc +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2014 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/files/file_path.h" -#include "base/files/file_util.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "mojo/public/cpp/bindings/lib/message_builder.h" -#include "mojo/public/cpp/bindings/lib/message_internal.h" -#include "mojo/public/cpp/bindings/message.h" - -// This file is used to generate various files corresponding to mojo -// messages. The various binding implementations can parse these to verify they -// correctly decode messages. -// -// The output consists of each byte of the message encoded in a hex string with -// a newline after it. -namespace mojo { -namespace { - -std::string BinaryToHex(const base::StringPiece& piece) { - std::string result("// File generated by mojo_message_generator.\n");; - result.reserve(result.size() + (piece.size() * 5)); - for (size_t i = 0; i < piece.size(); ++i) - base::StringAppendF(&result, "0X%.2X\n", static_cast(piece.data()[i])); - return result; -} - -void WriteMessageToFile(const Message& message, const base::FilePath& path) { - const std::string hex_message(BinaryToHex( - base::StringPiece(reinterpret_cast(message.data()), - message.data_num_bytes()))); - CHECK_EQ(static_cast(hex_message.size()), - base::WriteFile(path, hex_message.data(), - static_cast(hex_message.size()))); -} - -// Generates a message of type MessageData. The message uses the name 21, -// with 4 bytes of payload: 0x9, 0x8, 0x7, 0x6. -void GenerateMessageDataMessage() { - internal::MessageBuilder builder(static_cast(21), - static_cast(4)); - char* data = static_cast(builder.buffer()->Allocate(4)); - DCHECK(data); - data[0] = 9; - data[1] = 8; - data[2] = 7; - data[3] = 6; - - Message message; - builder.Finish(&message); - WriteMessageToFile(message, - base::FilePath(FILE_PATH_LITERAL("message_data"))); -} - -} // namespace -} // namespace mojo - -int main(int argc, char** argv) { - mojo::GenerateMessageDataMessage(); - return 0; -} diff --git a/mojo/tools/mojob.py b/mojo/tools/mojob.py deleted file mode 100755 index e7bda9373d3a2..0000000000000 --- a/mojo/tools/mojob.py +++ /dev/null @@ -1,318 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -"""A simple script to make building/testing Mojo components easier.""" - -import argparse -from copy import deepcopy -import logging -from multiprocessing import cpu_count -import os -import subprocess -import sys - -from get_test_list import GetTestList -from mopy.config import Config -from mopy.paths import Paths -from mopy.gn import GNArgsForConfig, ParseGNConfig, CommandLineForGNArgs -from mopy.log import InitLogging - - -_logger = logging.getLogger() -_verbose_count = 0 - - -def _args_to_config(args): - # Default to host OS. - target_os = None - if args.android: - target_os = Config.OS_ANDROID - elif args.ios: - target_os = Config.OS_IOS - - target_cpu = args.target_cpu - - additional_args = {} - - if 'clang' in args: - additional_args['is_clang'] = args.clang - - if 'asan' in args and args.asan: - additional_args['sanitizer'] = Config.SANITIZER_ASAN - - # Additional non-standard config entries: - - if 'goma' in args: - goma_dir = os.environ.get('GOMA_DIR') - goma_home_dir = os.path.join(os.getenv('HOME', ''), 'goma') - if args.goma and goma_dir: - additional_args['use_goma'] = True - additional_args['goma_dir'] = goma_dir - elif args.goma and os.path.exists(goma_home_dir): - additional_args['use_goma'] = True - additional_args['goma_dir'] = goma_home_dir - else: - additional_args['use_goma'] = False - additional_args['goma_dir'] = None - - if 'nacl' in args: - additional_args['use_nacl'] = args.nacl - - if not ('asan' in args and args.asan): - go_dir = os.path.join(Paths().src_root, 'third_party', 'go', 'tool') - if args.android: - additional_args['mojo_use_go'] = True - additional_args['go_build_tool'] = os.path.join( - go_dir, 'android_arm', 'bin', 'go') - elif target_os is None and Config.GetHostOS() == Config.OS_LINUX: - additional_args['mojo_use_go'] = True - additional_args['go_build_tool'] = os.path.join( - go_dir, 'linux_amd64', 'bin', 'go') - - if 'dry_run' in args: - additional_args['dry_run'] = args.dry_run - - if 'builder_name' in args: - additional_args['builder_name'] = args.builder_name - if 'build_number' in args: - additional_args['build_number'] = args.build_number - if 'master_name' in args: - additional_args['master_name'] = args.master_name - if 'test_results_server' in args: - additional_args['test_results_server'] = args.test_results_server - - if 'gn_args' in args: - additional_args['gn_args'] = args.gn_args - - is_debug = args.debug and not args.official - - return Config(target_os=target_os, target_cpu=target_cpu, - is_debug=is_debug, is_official_build=args.official, - dcheck_always_on=args.dcheck_always_on, - is_simulator=args.simulator, **additional_args) - - -def _get_out_dir(config): - """Gets the build output directory (e.g., out/Debug), relative to src, for the - given config.""" - - paths = Paths(config) - return paths.SrcRelPath(paths.build_dir) - - -def _sync(config): # pylint: disable=W0613 - """Runs gclient sync for the given config.""" - - _logger.debug('_sync()') - return subprocess.call(['gclient', 'sync']) - - -def _gn(config): - """Runs gn gen for the given config.""" - - _logger.debug('_gn()') - - command = ['gn', 'gen', '--check'] - - gn_args = CommandLineForGNArgs(GNArgsForConfig(config)) - out_dir = _get_out_dir(config) - command.append(out_dir) - command.append('--args=%s' % ' '.join(gn_args)) - - print 'Running %s %s ...' % (command[0], - ' '.join('\'%s\'' % x for x in command[1:])) - return subprocess.call(command) - - -def _build(config): - """Builds for the given config.""" - - _logger.debug('_build()') - - out_dir = _get_out_dir(config) - gn_args = ParseGNConfig(out_dir) - print 'Building in %s ...' % out_dir - if gn_args.get('use_goma'): - # Use the configured goma directory. - local_goma_dir = gn_args.get('goma_dir') - print 'Ensuring goma (in %s) started ...' % local_goma_dir - command = ['python', - os.path.join(local_goma_dir, 'goma_ctl.py'), - 'ensure_start'] - exit_code = subprocess.call(command) - if exit_code: - return exit_code - - # Goma allows us to run many more jobs in parallel, say 32 per core/thread - # (= 1024 on a 16-core, 32-thread Z620). Limit the load average to 4 per - # core/thread (= 128 on said Z620). - jobs = cpu_count() * 32 - limit = cpu_count() * 4 - return subprocess.call(['ninja', '-j', str(jobs), '-l', str(limit), - '-C', out_dir]) - else: - return subprocess.call(['ninja', '-C', out_dir]) - - -def _run_tests(config, test_types): - """Runs the tests of the given type(s) for the given config.""" - - assert isinstance(test_types, list) - config = deepcopy(config) - config.values['test_types'] = test_types - - test_list = GetTestList(config, verbose_count=_verbose_count) - dry_run = config.values.get('dry_run') - final_exit_code = 0 - failure_list = [] - for entry in test_list: - print 'Running: %s' % entry['name'] - print 'Command: %s' % ' '.join(entry['command']) - if dry_run: - continue - - _logger.info('Starting: %s' % ' '.join(entry['command'])) - exit_code = subprocess.call(entry['command']) - _logger.info('Completed: %s' % ' '.join(entry['command'])) - if exit_code: - if not final_exit_code: - final_exit_code = exit_code - failure_list.append(entry['name']) - - print 72 * '=' - print 'SUMMARY:', - if dry_run: - print 'Dry run: no tests run' - elif not failure_list: - assert not final_exit_code - print 'All tests passed' - else: - assert final_exit_code - print 'The following had failures:', ', '.join(failure_list) - - return final_exit_code - - -def _test(config): - _logger.debug('_test()') - return _run_tests(config, [Config.TEST_TYPE_DEFAULT]) - - -def _perftest(config): - _logger.debug('_perftest()') - return _run_tests(config, [Config.TEST_TYPE_PERF]) - - -def _pytest(config): - _logger.debug('_pytest()') - return _run_tests(config, ['python']) - - -def main(): - os.chdir(Paths().src_root) - - parser = argparse.ArgumentParser(description='A script to make building' - '/testing Mojo components easier.') - - parent_parser = argparse.ArgumentParser(add_help=False) - - parent_parser.add_argument('--verbose', - help='Be verbose (multiple times for more)', - default=0, dest='verbose_count', action='count') - - parent_parser.add_argument('--asan', help='Use Address Sanitizer', - action='store_true') - parent_parser.add_argument('--dcheck_always_on', - help='DCHECK and MOJO_DCHECK are fatal even in ' - 'release builds', - action='store_true') - - debug_group = parent_parser.add_mutually_exclusive_group() - debug_group.add_argument('--debug', help='Debug build (default)', - default=True, action='store_true') - debug_group.add_argument('--release', help='Release build', default=False, - dest='debug', action='store_false') - # The official build is a release build suitable for distribution, with a - # different package name. - debug_group.add_argument('--official', help='Official build', default=False, - dest='official', action='store_true') - - os_group = parent_parser.add_mutually_exclusive_group() - os_group.add_argument('--android', help='Build for Android', - action='store_true') - os_group.add_argument('--ios', help='Build for iOS', - action='store_true') - - parent_parser.add_argument('--simulator', - help='Build for a simulator of the target', - action='store_true') - - parent_parser.add_argument('--target-cpu', - help='CPU architecture to build for.', - choices=['x64', 'x86', 'arm']) - - subparsers = parser.add_subparsers() - - sync_parser = subparsers.add_parser('sync', parents=[parent_parser], - help='Sync using gclient (does not run gn).') - sync_parser.set_defaults(func=_sync) - - gn_parser = subparsers.add_parser('gn', parents=[parent_parser], - help='Run gn for mojo (does not sync).') - gn_parser.set_defaults(func=_gn) - gn_parser.add_argument('--args', help='Specify extra args', - default=None, dest='gn_args') - # Note: no default, if nothing is specified on the command line GN decides. - gn_parser.add_argument('--nacl', help='Add in NaCl', action='store_true', - default=argparse.SUPPRESS) - gn_parser.add_argument('--no-nacl', help='Remove NaCl', action='store_false', - default=argparse.SUPPRESS, dest='nacl') - - clang_group = gn_parser.add_mutually_exclusive_group() - clang_group.add_argument('--clang', help='Use Clang (default)', default=None, - action='store_true') - clang_group.add_argument('--gcc', help='Use GCC', - dest='clang', action='store_false') - goma_group = gn_parser.add_mutually_exclusive_group() - goma_group.add_argument('--goma', - help='Use Goma (if $GOMA_DIR is set or $HOME/goma ' - 'exists; default)', - default=True, - action='store_true') - goma_group.add_argument('--no-goma', help='Don\'t use Goma', default=False, - dest='goma', action='store_false') - - build_parser = subparsers.add_parser('build', parents=[parent_parser], - help='Build') - build_parser.set_defaults(func=_build) - - test_parser = subparsers.add_parser('test', parents=[parent_parser], - help='Run unit tests (does not build).') - test_parser.set_defaults(func=_test) - test_parser.add_argument('--dry-run', - help='Print instead of executing commands', - default=False, action='store_true') - - perftest_parser = subparsers.add_parser('perftest', parents=[parent_parser], - help='Run perf tests (does not build).') - perftest_parser.set_defaults(func=_perftest) - - pytest_parser = subparsers.add_parser('pytest', parents=[parent_parser], - help='Run Python unit tests (does not build).') - pytest_parser.set_defaults(func=_pytest) - - args = parser.parse_args() - global _verbose_count - _verbose_count = args.verbose_count - InitLogging(_verbose_count) - - if args.simulator and not args.ios: - sys.exit("Currently, the simulator target is only configured for iOS") - - return args.func(_args_to_config(args)) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/mojo/tools/mopy/__init__.py b/mojo/tools/mopy/__init__.py deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/mojo/tools/mopy/config.py b/mojo/tools/mopy/config.py deleted file mode 100644 index a0df490a2a102..0000000000000 --- a/mojo/tools/mopy/config.py +++ /dev/null @@ -1,148 +0,0 @@ -# Copyright 2014 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. - -"""Build/test configurations, which are just dictionaries. This -"defines" the schema and provides some wrappers.""" - - -import platform -import sys - - -class Config(object): - """A Config is basically just a wrapper around a dictionary that species a - build/test configuration. The dictionary is accessible through the values - member.""" - - # Valid values for target_os (None is also valid): - OS_ANDROID = "android" - OS_IOS = "ios" - OS_LINUX = "linux" - OS_MAC = "mac" - OS_WINDOWS = "windows" - - # Valid values for target_cpu (None is also valid): - ARCH_X86 = "x86" - ARCH_X64 = "x64" - ARCH_ARM = "arm" - - # Valid values for sanitizer (None is also valid): - SANITIZER_ASAN = "asan" - - # Standard values for test types (test types are arbitrary strings; other - # values are allowed). - TEST_TYPE_DEFAULT = "default" - TEST_TYPE_UNIT = "unit" - TEST_TYPE_PERF = "perf" - TEST_TYPE_INTEGRATION = "integration" - - def __init__(self, target_os=None, target_cpu=None, is_debug=True, - is_clang=None, sanitizer=None, dcheck_always_on=False, - is_simulator=False, is_official_build=False, **kwargs): - """Constructs a Config with key-value pairs specified via keyword arguments. - If target_os is not specified, it will be set to the host OS.""" - - assert target_os in (None, Config.OS_ANDROID, Config.OS_IOS, - Config.OS_LINUX, Config.OS_MAC, - Config.OS_WINDOWS) - assert target_cpu in (None, Config.ARCH_X86, Config.ARCH_X64, - Config.ARCH_ARM) - assert isinstance(is_debug, bool) - assert isinstance(is_official_build, bool) - assert is_clang is None or isinstance(is_clang, bool) - assert sanitizer in (None, Config.SANITIZER_ASAN) - if "test_types" in kwargs: - assert isinstance(kwargs["test_types"], list) - - self.values = {} - self.values["target_os"] = (self.GetHostOS() if target_os is None else - target_os) - - if target_cpu is None: - if target_os == Config.OS_ANDROID: - target_cpu = Config.ARCH_ARM - elif target_os == Config.OS_IOS: - target_cpu = Config.ARCH_X64 if is_simulator else Config.ARCH_ARM - else: - target_cpu = self.GetHostCPUArch() - - self.values["target_cpu"] = target_cpu - self.values["is_simulator"] = is_simulator - self.values["is_debug"] = is_debug - self.values["is_official_build"] = is_official_build - self.values["is_clang"] = is_clang - self.values["sanitizer"] = sanitizer - self.values["dcheck_always_on"] = dcheck_always_on - - self.values.update(kwargs) - - @staticmethod - def GetHostOS(): - if sys.platform == "linux2": - return Config.OS_LINUX - if sys.platform == "darwin": - return Config.OS_MAC - if sys.platform == "win32": - return Config.OS_WINDOWS - raise NotImplementedError("Unsupported host OS") - - @staticmethod - def GetHostCPUArch(): - # Derived from //native_client/pynacl/platform.py - machine = platform.machine() - if machine in ("x86", "x86-32", "x86_32", "x8632", "i386", "i686", "ia32", - "32"): - return Config.ARCH_X86 - if machine in ("x86-64", "amd64", "x86_64", "x8664", "64"): - return Config.ARCH_X64 - if machine.startswith("arm"): - return Config.ARCH_ARM - raise Exception("Cannot identify CPU arch: %s" % machine) - - # Getters for standard fields ------------------------------------------------ - - @property - def target_os(self): - """OS of the build/test target.""" - return self.values["target_os"] - - @property - def target_cpu(self): - """CPU arch of the build/test target.""" - return self.values["target_cpu"] - - @property - def is_simulator(self): - """Is a simulator build?""" - return self.values["is_simulator"] - - @property - def is_debug(self): - """Is Debug build?""" - return self.values["is_debug"] - - @property - def is_official_build(self): - """Is Official build?""" - return self.values["is_official_build"] - - @property - def dcheck_always_on(self): - """DCHECK and MOJO_DCHECK are fatal even in release builds""" - return self.values["dcheck_always_on"] - - @property - def is_clang(self): - """Should use clang?""" - return self.values["is_clang"] - - @property - def sanitizer(self): - """Sanitizer to use, if any.""" - return self.values["sanitizer"] - - @property - def test_types(self): - """List of test types to run.""" - return self.values.get("test_types", [Config.TEST_TYPE_DEFAULT]) diff --git a/mojo/tools/mopy/file_hash.py b/mojo/tools/mopy/file_hash.py deleted file mode 100644 index abdd821c985b2..0000000000000 --- a/mojo/tools/mopy/file_hash.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2014 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. - -import logging - -# pylint: disable=E0611 -from hashlib import sha256 - -from mopy.memoize import memoize - -_logging = logging.getLogger() - -@memoize -def file_hash(filename): - """Returns a string representing the hash of the given file.""" - _logging.debug("Hashing %s ...", filename) - with open(filename, mode='rb') as f: - m = sha256() - while True: - block = f.read(4096) - if not block: - break - m.update(block) - _logging.debug(" => %s", m.hexdigest()) - return m.hexdigest() diff --git a/mojo/tools/mopy/gn.py b/mojo/tools/mopy/gn.py deleted file mode 100644 index 47253ea3f1821..0000000000000 --- a/mojo/tools/mopy/gn.py +++ /dev/null @@ -1,157 +0,0 @@ -# Copyright 2015 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. - -""" -GN-related configuration functions, e.g., to produce a Config object from a GN -args.gn file). -""" - - -import ast -import os.path -import re - -from .config import Config - - -def BuildDirectoryForConfig(config, src_root): - """ - Returns the build directory for the given configuration. - """ - subdir = "" - if config.target_os == Config.OS_ANDROID: - subdir += "android_" - if config.target_cpu != Config.ARCH_ARM: - subdir += config.target_cpu + "_" - elif config.target_os == Config.OS_IOS: - subdir += "ios_" - if config.is_simulator: - subdir += "sim_" - if config.is_official_build: - subdir += "Official" - elif config.is_debug: - subdir += "Debug" - else: - subdir += "Release" - if config.sanitizer == Config.SANITIZER_ASAN: - subdir += "_asan" - if not(config.is_debug) and config.dcheck_always_on: - subdir += "_dcheck" - return os.path.join(src_root, "out", subdir) - - -def GNArgsForConfig(config): - """ - Return the arguments for gn for the given configuration. This function returns - a dictionary with boolean values as boolean. - """ - gn_args = {} - - gn_args["is_debug"] = bool(config.is_debug) - gn_args["is_official_build"] = bool(config.is_official_build) - gn_args["is_asan"] = config.sanitizer == Config.SANITIZER_ASAN - - if config.is_clang is not None: - gn_args["is_clang"] = bool(config.is_clang) - else: - gn_args["is_clang"] = config.target_os not in (Config.OS_ANDROID, - Config.OS_WINDOWS) - - if config.values.get("use_goma"): - gn_args["use_goma"] = True - gn_args["goma_dir"] = config.values["goma_dir"] - else: - gn_args["use_goma"] = False - - gn_args["dcheck_always_on"] = config.dcheck_always_on - - if config.target_os == Config.OS_ANDROID: - gn_args["target_os"] = "android" - elif config.target_os == Config.OS_IOS: - gn_args["target_os"] = "ios" - gn_args["ios_deployment_target"] = "7.0" - gn_args["clang_use_chrome_plugins"] = False - if config.is_simulator: - gn_args["use_libjpeg_turbo"] = False - gn_args["use_ios_simulator"] = config.is_simulator - elif config.target_os == Config.OS_LINUX: - gn_args["use_aura"] = False - gn_args["use_glib"] = False - gn_args["use_system_harfbuzz"] = False - - gn_args["target_cpu"] = config.target_cpu - - if "use_nacl" in config.values: - gn_args["mojo_use_nacl"] = config.values.get("use_nacl", False) - - if "mojo_use_go" in config.values: - gn_args["mojo_use_go"] = config.values.get("mojo_use_go", False) - if gn_args["mojo_use_go"]: - gn_args["go_build_tool"] = config.values.get("go_build_tool") - - extra_args = config.values.get("gn_args") - if extra_args: - for arg in extra_args.split(): - (name, val) = arg.split('=') - gn_args[name] = val - - return gn_args - - -def CommandLineForGNArgs(gn_args): - """ - Returns the list of gn arguments to use with the gn command line. - """ - def _ToCommandLine(key, value): - if type(value) is bool: - return "%s=%s" % (key, "true" if value else "false") - return "%s=\"%s\"" % (key, value) - return [_ToCommandLine(x, y) for x, y in gn_args.iteritems()] - - -def ConfigForGNArgs(args): - """ - Return the Config object for the given gn arguments. This function takes a - dictionary with boolean values as boolean. - """ - config_args = {} - config_args["is_debug"] = args.get("is_debug", True) - config_args["is_official_build"] = args.get("is_official_build", False) - config_args["sanitizer"] = ( - Config.SANITIZER_ASAN if args.get("is_asan") else None) - config_args["is_clang"] = args.get("is_clang", False) - config_args["use_goma"] = args.get("use_goma", False) - if config_args["use_goma"]: - config_args["goma_dir"] = args.get("goma_dir") - config_args["use_nacl"] = args.get("mojo_use_nacl", False) - config_args["mojo_use_go"] = args.get("mojo_use_go", False) - if config_args["mojo_use_go"]: - config_args["go_build_tool"] = args.get("go_build_tool") - config_args["target_os"] = args.get("target_os") - config_args["target_cpu"] = args.get("target_cpu") - config_args["dcheck_always_on"] = args.get("dcheck_always_on") - config_args["is_simulator"] = args.get("use_ios_simulator", False) - return Config(**config_args) - - -def ParseGNConfig(build_dir): - """ - Parse the gn config file present in |build_dir|. This function returns a - dictionary with boolean values as boolean. - """ - TRANSLATIONS = { - "true": "True", - "false": "False", - } - gn_file = os.path.join(build_dir, "args.gn") - values = {} - with open(gn_file, "r") as f: - for line in f.readlines(): - line = re.sub("\s*#.*", "", line) - result = re.match("^\s*(\w+)\s*=\s*(.*)\s*$", line) - if result: - key = result.group(1) - value = result.group(2) - values[key] = ast.literal_eval(TRANSLATIONS.get(value, value)) - return values diff --git a/mojo/tools/mopy/gn_unittest.py b/mojo/tools/mopy/gn_unittest.py deleted file mode 100644 index b1b29a7fc3e60..0000000000000 --- a/mojo/tools/mopy/gn_unittest.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright 2014 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. - -import itertools -import sys -import unittest - -import mopy.gn as gn - -from mopy.config import Config - - -class GTestListTestsTest(unittest.TestCase): - """Tests mopy.gn.""" - - def testConfigToGNToConfig(self): - """Tests that config to gn to config is the identity""" - configs_to_test = { - "target_os": [None, "android", "linux", "ios"], - "target_cpu": [None, "x86", "x64", "arm"], - "is_simulator": [False, True], - "is_debug": [False, True], - "is_official_build": [False, True], - "is_clang": [False, True], - "sanitizer": [None, Config.SANITIZER_ASAN], - "use_goma": [False], - "use_nacl": [False, True], - "mojo_use_go": [False], - "dcheck_always_on": [False, True], - } - if sys.platform == "darwin": - configs_to_test["target_os"].remove("linux") - - for args in _iterate_over_config(configs_to_test): - if args.get("target_os") != "ios" and args["is_simulator"]: - continue - config = Config(**args) - gn_args = gn.GNArgsForConfig(config) - new_config = gn.ConfigForGNArgs(gn_args) - self.assertDictEqual(config.values, new_config.values) - - def testGNToConfigToGN(self): - """Tests that gn to config to gn is the identity""" - # TODO(vtl): Test OSes other than None (== host?) and "android". - configs_to_test = { - "target_os": [None, "android"], - "target_cpu": ["x86", "x64", "arm"], - "is_debug": [False, True], - "is_official_build": [False, True], - "is_clang": [False, True], - "is_asan": [False, True], - "use_goma": [False], - "mojo_use_nacl": [False, True], - "mojo_use_go": [False], - "dcheck_always_on": [False, True], - } - - for args in _iterate_over_config(configs_to_test): - if args.get("target_os", None) is None and sys.platform[:5] == "linux": - args["use_aura"] = False - args["use_glib"] = False - args["use_system_harfbuzz"] = False - config = gn.ConfigForGNArgs(args) - new_args = gn.GNArgsForConfig(config) - self.assertDictEqual(args, new_args) - - -def _iterate_over_config(config): - def product_to_dict(p): - return dict(filter(lambda x: x[1] is not None, zip(config.keys(), p))) - return itertools.imap(product_to_dict, itertools.product(*config.values())) - - -if __name__ == "__main__": - unittest.main() diff --git a/mojo/tools/mopy/gtest.py b/mojo/tools/mopy/gtest.py deleted file mode 100644 index e557937280171..0000000000000 --- a/mojo/tools/mopy/gtest.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2014 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. - -import os -import sys -import logging - -_logger = logging.getLogger() - - -def set_color(): - """Run gtests with color if we're on a TTY (and we're not being told - explicitly what to do).""" - if sys.stdout.isatty() and "GTEST_COLOR" not in os.environ: - _logger.debug("Setting GTEST_COLOR=yes") - os.environ["GTEST_COLOR"] = "yes" diff --git a/mojo/tools/mopy/log.py b/mojo/tools/mopy/log.py deleted file mode 100644 index af572320818ef..0000000000000 --- a/mojo/tools/mopy/log.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2015 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. - -"""Logging utilities, for use with the standard logging module.""" - - -import logging - - -def InitLogging(verbose_count): - """Ensures that the logger (obtained via logging.getLogger(), as usual) is - initialized, with the log level set as appropriate for |verbose_count| - instances of --verbose on the command line.""" - - assert(verbose_count >= 0) - if verbose_count == 0: - level = logging.WARNING - elif verbose_count == 1: - level = logging.INFO - else: # verbose_count >= 2 - level = logging.DEBUG - - logging.basicConfig(format="%(relativeCreated).3f:%(levelname)s:%(message)s") - logger = logging.getLogger() - logger.setLevel(level) - - logger.debug("Initialized logging: verbose_count=%d, level=%d" % - (verbose_count, level)) diff --git a/mojo/tools/mopy/memoize.py b/mojo/tools/mopy/memoize.py deleted file mode 100644 index 765b8a9382379..0000000000000 --- a/mojo/tools/mopy/memoize.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2014 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. - - -# pylint: disable=C0301 -# Based on/taken from -# http://code.activestate.com/recipes/578231-probably-the-fastest-memoization-decorator-in-the-/ -# (with cosmetic changes). -# pylint: enable=C0301 -def memoize(f): - """Memoization decorator for a function taking a single argument.""" - class Memoize(dict): - def __missing__(self, key): - rv = self[key] = f(key) - return rv - return Memoize().__getitem__ diff --git a/mojo/tools/mopy/mojo_python_tests_runner.py b/mojo/tools/mopy/mojo_python_tests_runner.py deleted file mode 100644 index ef9a6b2b318b0..0000000000000 --- a/mojo/tools/mopy/mojo_python_tests_runner.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright 2014 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. - -import argparse -import os -import sys -import unittest - -import mopy.paths - - -class MojoPythonTestRunner(object): - """Helper class to run python tests on the bots.""" - - def __init__(self, test_dir): - self._test_dir = test_dir - - def run(self): - parser = argparse.ArgumentParser() - parser.add_argument('-v', '--verbose', action='count', default=0) - parser.add_argument('tests', nargs='*') - - self.add_custom_commandline_options(parser) - args = parser.parse_args() - self.apply_customization(args) - - loader = unittest.loader.TestLoader() - print "Running Python unit tests under %s..." % self._test_dir - - src_root = mopy.paths.Paths().src_root - pylib_dir = os.path.abspath(os.path.join(src_root, self._test_dir)) - if args.tests: - if pylib_dir not in sys.path: - sys.path.append(pylib_dir) - suite = unittest.TestSuite() - for test_name in args.tests: - suite.addTests(loader.loadTestsFromName(test_name)) - else: - suite = loader.discover(pylib_dir, pattern='*_unittest.py') - - runner = unittest.runner.TextTestRunner(verbosity=(args.verbose + 1)) - result = runner.run(suite) - return 0 if result.wasSuccessful() else 1 - - def add_custom_commandline_options(self, parser): - """Allow to add custom option to the runner script.""" - pass - - def apply_customization(self, args): - """Allow to apply any customization to the runner.""" - pass diff --git a/mojo/tools/mopy/paths.py b/mojo/tools/mopy/paths.py deleted file mode 100644 index 2ba8ec831e6d9..0000000000000 --- a/mojo/tools/mopy/paths.py +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright 2014 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. - -import os - -from .config import Config -from .gn import BuildDirectoryForConfig - -class Paths(object): - """Provides commonly used paths""" - - def __init__(self, config=None, build_dir=None): - """Specify either a config or a build_dir to generate paths to binary - artifacts.""" - self.src_root = os.path.abspath(os.path.join(__file__, - os.pardir, os.pardir, os.pardir, os.pardir)) - self.mojo_dir = os.path.join(self.src_root, "mojo") - self.adb_path = os.path.join(self.src_root, 'third_party', 'android_tools', - 'sdk', 'platform-tools', 'adb') - - if config: - self.build_dir = BuildDirectoryForConfig(config, self.src_root) - elif build_dir is not None: - self.build_dir = os.path.abspath(build_dir) - else: - self.build_dir = None - - if self.build_dir is not None: - self.mojo_shell_path = os.path.join(self.build_dir, "mojo_shell") - self.sky_shell_path = os.path.join(self.build_dir, "sky_shell") - # TODO(vtl): Use the host OS here, since |config| may not be available. - # In any case, if the target is Windows, but the host isn't, using - # |os.path| isn't correct.... - if Config.GetHostOS() == Config.OS_WINDOWS: - self.mojo_shell_path += ".exe" - self.sky_shell_path += ".exe" - if config and config.target_os == Config.OS_ANDROID: - self.target_mojo_shell_path = os.path.join(self.build_dir, - "apks", - "MojoShell.apk") - self.target_sky_shell_path = os.path.join(self.build_dir, - "apks", - "SkyDemo.apk") - else: - self.target_mojo_shell_path = self.mojo_shell_path - self.target_sky_shell_path = self.sky_shell_path - else: - self.mojo_shell_path = None - self.sky_shell_path = None - self.target_mojo_shell_path = None - self.target_sky_shell_path = None - - def RelPath(self, path): - """Returns the given path, relative to the current directory.""" - return os.path.relpath(path) - - def SrcRelPath(self, path): - """Returns the given path, relative to self.src_root.""" - return os.path.relpath(path, self.src_root) - - def FileFromUrl(self, url): - """Given an app URL (:), return 'build_dir/appname.mojo'. - If self.build_dir is None, just return appname.mojo - """ - (_, name) = url.split(':') - if self.build_dir: - return os.path.join(self.build_dir, name + '.mojo') - return name + '.mojo' - - @staticmethod - def IsValidAppUrl(url): - """Returns False if url is malformed, True otherwise.""" - try: - return len(url.split(':')) == 2 - except ValueError: - return False diff --git a/mojo/tools/mopy/perf_data_uploader.py b/mojo/tools/mopy/perf_data_uploader.py deleted file mode 100755 index 84e5280ab7bf1..0000000000000 --- a/mojo/tools/mopy/perf_data_uploader.py +++ /dev/null @@ -1,200 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -"""A tool that uploads data to the performance dashboard.""" - -import argparse -import httplib -import json -import pprint -import re -import sys -import urllib -import urllib2 - -# TODO(yzshen): The following are missing currently: -# (1) CL range on the dashboard; -# (2) improvement direction on the dashboard; -# (3) a link from the build step pointing to the dashboard page. - - -_PERF_LINE_FORMAT = r"""^\s*([^\s/]+) # chart name - (/([^\s/]+))? # trace name (optional, separated with - # the chart name by a '/') - \s+(\S+) # value - \s+(\S+) # units - \s*$""" - -_PRODUCTION_SERVER = "https://chromeperf.appspot.com" -_TESTING_SERVER = "https://chrome-perf.googleplex.com" - - -def UploadPerfData(master_name, perf_id, test_name, builder_name, build_number, - revision, perf_data, point_id, dry_run=False, - testing_dashboard=True): - """Uploads perf data. - - Args: - Please see the help for command-line args. - - Returns: - A boolean value indicating whether the operation succeeded or not. - """ - - def _ConvertToUploadFormat(): - """Converts perf data to the format that the server understands. - - Returns: - A dictionary that (after being converted to JSON) conforms to the server - format. - """ - charts = {} - line_format = re.compile(_PERF_LINE_FORMAT, re.VERBOSE) - for line in perf_data: - match = re.match(line_format, line) - assert match, "Unable to parse the following input: %s" % line - - chart_name = match.group(1) - trace_name = match.group(3) if match.group(3) else "summary" - - if chart_name not in charts: - charts[chart_name] = {} - charts[chart_name][trace_name] = { - "type": "scalar", - "value": float(match.group(4)), - "units": match.group(5) - } - - return { - "master": master_name, - "bot": perf_id, - "masterid": master_name, - "buildername": builder_name, - "buildnumber": build_number, - "versions": { - "mojo": revision - }, - "point_id": point_id, - "supplemental": {}, - "chart_data": { - "format_version": "1.0", - "benchmark_name": test_name, - "charts": charts - } - } - - class _UploadException(Exception): - pass - - def _Upload(server_url, json_data): - """Make an HTTP POST with the given data to the performance dashboard. - - Args: - server_url: URL of the performance dashboard instance. - json_data: JSON string that contains the data to be sent. - - Raises: - _UploadException: An error occurred during uploading. - """ - # When data is provided to urllib2.Request, a POST is sent instead of GET. - # The data must be in the application/x-www-form-urlencoded format. - data = urllib.urlencode({"data": json_data}) - req = urllib2.Request("%s/add_point" % server_url, data) - try: - urllib2.urlopen(req) - except urllib2.HTTPError as e: - raise _UploadException("HTTPError: %d. Response: %s\n" - "JSON: %s\n" % (e.code, e.read(), json_data)) - except urllib2.URLError as e: - raise _UploadException("URLError: %s for JSON %s\n" % - (str(e.reason), json_data)) - except httplib.HTTPException as e: - raise _UploadException("HTTPException for JSON %s\n" % json_data) - - formatted_data = _ConvertToUploadFormat() - - server_url = _TESTING_SERVER if testing_dashboard else _PRODUCTION_SERVER - - if dry_run: - print "Won't upload because --dry-run is specified." - print "Server: %s" % server_url - print "Data:" - pprint.pprint(formatted_data) - else: - print "Uploading data to %s ..." % server_url - try: - _Upload(server_url, json.dumps(formatted_data)) - except _UploadException as e: - print e - return False - - print "Done." - - dashboard_params = urllib.urlencode({ - "masters": master_name, - "bots": perf_id, - "tests": test_name, - "rev": point_id - }) - print "Results Dashboard: %s/report?%s" % (server_url, dashboard_params) - - return True - - -def main(): - parser = argparse.ArgumentParser( - description="A tool that uploads data to the performance dashboard.") - - parser.add_argument( - "--master-name", required=True, - help="Buildbot master name, used to construct link to buildbot log by " - "the dashboard, and also as the top-level category for the data.") - parser.add_argument( - "--perf-id", required=True, - help="Used as the second-level category for the data, usually the " - "platform type.") - parser.add_argument( - "--test-name", required=True, - help="Name of the test that the perf data was generated from.") - parser.add_argument( - "--builder-name", required=True, - help="Buildbot builder name, used to construct link to buildbot log by " - "the dashboard.") - parser.add_argument( - "--build-number", required=True, type=int, - help="Build number, used to construct link to buildbot log by the " - "dashboard.") - parser.add_argument( - "--revision", required=True, help="The mojo git commit hash.") - parser.add_argument( - "--perf-data", required=True, metavar="foo_perf.log", - type=argparse.FileType("r"), - help="A text file containing the perf data. Each line is a data point in " - "the following format: chart_name[/trace_name] value units") - parser.add_argument( - "--point-id", required=True, type=int, - help="The x coordinate for the data points.") - parser.add_argument( - "--dry-run", action="store_true", - help="Display the server URL and the data to upload, but not actually " - "upload the data.") - server_group = parser.add_mutually_exclusive_group() - server_group.add_argument( - "--testing-dashboard", action="store_true", default=True, - help="Upload the data to the testing dashboard (default).") - server_group.add_argument( - "--production-dashboard", dest="testing_dashboard", action="store_false", - default=False, help="Upload the data to the production dashboard.") - args = parser.parse_args() - - result = UploadPerfData(args.master_name, args.perf_id, args.test_name, - args.builder_name, args.build_number, args.revision, - args.perf_data, args.point_id, args.dry_run, - args.testing_dashboard) - return 0 if result else 1 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/mojo/tools/mopy/print_process_error.py b/mojo/tools/mopy/print_process_error.py deleted file mode 100644 index ec565d14e40c0..0000000000000 --- a/mojo/tools/mopy/print_process_error.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2014 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. - -def print_process_error(command_line, error): - """Properly format an exception raised from a failed command execution.""" - - if command_line: - print 'Failed command: %r' % command_line - else: - print 'Failed command:' - print 72 * '-' - - if hasattr(error, 'returncode'): - print ' with exit code %d' % error.returncode - print 72 * '-' - - if hasattr(error, 'output'): - print error.output - else: - print error - print 72 * '-' diff --git a/mojo/tools/mopy/transitive_hash.py b/mojo/tools/mopy/transitive_hash.py deleted file mode 100644 index 740892b27c4b8..0000000000000 --- a/mojo/tools/mopy/transitive_hash.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright 2014 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. - -import logging -import platform -import subprocess -import sys - -# pylint: disable=E0611 -from hashlib import sha256 -# pylint: enable=E0611 -from os.path import basename, realpath - -from mopy.file_hash import file_hash -from mopy.memoize import memoize - -_logging = logging.getLogger() - -@memoize -def _get_dependencies(filename): - """Returns a list of filenames for files that the given file depends on.""" - if platform.system() == 'Windows': - # There's no ldd on Windows. We can try to bundle or require depends, but - # given that we're not supporting component build this seems low priority. - return [] - _logging.debug("Getting dependencies for %s ...", filename) - lines = subprocess.check_output(['ldd', filename]).splitlines() - rv = [] - for line in lines: - i = line.find('/') - if i < 0: - _logging.debug(" => no file found in line: %s", line) - continue - rv.append(line[i:].split(None, 1)[0]) - _logging.debug(" => %s", rv) - return rv - -def transitive_hash(filename): - """Returns a string that represents the "transitive" hash of the given - file. The transitive hash is a hash of the file and all the shared libraries - on which it depends (done in an order-independent way).""" - hashes = set() - to_hash = [filename] - while to_hash: - current_filename = realpath(to_hash.pop()) - current_hash = file_hash(current_filename) - if current_hash in hashes: - _logging.debug("Already seen %s (%s) ...", current_filename, current_hash) - continue - _logging.debug("Haven't seen %s (%s) ...", current_filename, current_hash) - hashes.add(current_hash) - to_hash.extend(_get_dependencies(current_filename)) - return sha256('|'.join(sorted(hashes))).hexdigest() - -def main(argv): - logging.basicConfig() - # Uncomment to debug: - # _logging.setLevel(logging.DEBUG) - - if len(argv) < 2: - print """\ -Usage: %s [file] ... - -Prints the \"transitive\" hash of each (executable) file. The transitive -hash is a hash of the file and all the shared libraries on which it -depends (done in an order-independent way).""" % basename(argv[0]) - return 0 - - rv = 0 - for filename in argv[1:]: - try: - print transitive_hash(filename), filename - except subprocess.CalledProcessError: - print "ERROR", filename - rv = 1 - return rv - -if __name__ == '__main__': - sys.exit(main(sys.argv)) diff --git a/mojo/tools/mopy/version.py b/mojo/tools/mopy/version.py deleted file mode 100644 index 8f8e1329fe73c..0000000000000 --- a/mojo/tools/mopy/version.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright 2014 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. - -import subprocess - -import mopy.paths - -class Version(object): - """Computes the version (git committish) of the mojo repo""" - - def __init__(self): - self.version = subprocess.check_output(["git", "rev-parse", "HEAD"], - cwd=mopy.paths.Paths().src_root).strip() diff --git a/mojo/tools/perf_test_runner.py b/mojo/tools/perf_test_runner.py deleted file mode 100755 index dff6b2d4596b9..0000000000000 --- a/mojo/tools/perf_test_runner.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python -# Copyright 2015 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. - -"""A tool that runs a perf test and uploads the resulting data to the -performance dashboard. -""" - -import argparse -from mopy import perf_data_uploader -from mopy.version import Version -import subprocess -import sys - - -def _GetCurrentCommitCount(): - return subprocess.check_output( - ["git", "rev-list", "HEAD", "--count"]).strip() - - -def main(): - parser = argparse.ArgumentParser( - description="A tool that runs a perf test and uploads the resulting data " - "to the performance dashboard.") - - parser.add_argument( - "--master-name", - help="Buildbot master name, used to construct link to buildbot log by " - "the dashboard, and also as the top-level category for the data.") - parser.add_argument( - "--perf-id", - help="Used as the second-level category for the data, usually the " - "platform type.") - parser.add_argument( - "--test-name", - help="Name of the test that the perf data was generated from.") - parser.add_argument( - "--builder-name", - help="Buildbot builder name, used to construct link to buildbot log by " - "the dashboard.") - parser.add_argument( - "--build-number", type=int, - help="Build number, used to construct link to buildbot log by the " - "dashboard.") - parser.add_argument( - "--perf-data-path", - help="The path to the perf data that the perf test generates.") - server_group = parser.add_mutually_exclusive_group() - server_group.add_argument( - "--testing-dashboard", action="store_true", default=True, - help="Upload the data to the testing dashboard (default).") - server_group.add_argument( - "--production-dashboard", dest="testing_dashboard", action="store_false", - default=False, help="Upload the data to the production dashboard.") - parser.add_argument("command", nargs=argparse.REMAINDER) - args = parser.parse_args() - - subprocess.check_call(args.command) - - if args.master_name is None or \ - args.perf_id is None or \ - args.test_name is None or \ - args.builder_name is None or \ - args.build_number is None or \ - args.perf_data_path is None: - print "Won't upload perf data to the dashboard because not all of the " \ - "following values are specified: master-name, perf-id, test-name, " \ - "builder-name, build-number, perf-data-path." - return 0 - - revision = Version().version - perf_data = open(args.perf_data_path, "r") - point_id = _GetCurrentCommitCount() - - result = perf_data_uploader.UploadPerfData( - args.master_name, args.perf_id, args.test_name, args.builder_name, - args.build_number, revision, perf_data, point_id, False, - args.testing_dashboard) - - return 0 if result else 1 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/mojo/tools/prepare_pub_packages.py b/mojo/tools/prepare_pub_packages.py deleted file mode 100755 index e53b0c9896fd2..0000000000000 --- a/mojo/tools/prepare_pub_packages.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python -# Copyright 2015 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. - -"""Prepares pub packages for upload.""" - -# NOTE: Requires the following build artifacts: -# *) out/Config/gen/dart-pkg -# *) out/Config/apks/ -# By default Config is 'android_Release' - -import argparse -import os -import shutil -import tempfile - - -def remove_empty_dirs(root_dir): - for root, dirs, _ in os.walk(root_dir): - for name in dirs: - fname = os.path.join(root, name) - if not os.listdir(fname): - os.removedirs(fname) - - -def copy_package(src_dir, dst_dir, ignore=None): - # Remove existing destination directory. - shutil.rmtree(dst_dir, True) - shutil.copytree(src_dir, dst_dir, symlinks=False, ignore=ignore) - - -def install_mojo_license_and_authors_files(src_root, dst_dir): - shutil.copy(os.path.join(src_root, 'LICENSE'), dst_dir) - shutil.copy(os.path.join(src_root, 'AUTHORS'), dst_dir) - - -def main(): - parser = argparse.ArgumentParser( - description='Prepare pub packages for upload') - parser.add_argument('--config', - type=str, - default='android_Release') - parser.add_argument('--src-root', - type=str, - default='.') - parser.add_argument('--packages', - default=['mojo', 'mojom', 'mojo_services']) - parser.add_argument('--out-dir', - default=None) - parser.add_argument('build_dir', - type=str) - args = parser.parse_args() - - rel_build_dir = os.path.join(args.build_dir, args.config) - build_dir = os.path.abspath(rel_build_dir) - sdk_dir = os.path.abspath(args.src_root) - print('Using SDK in %s' % sdk_dir) - print('Using build in %s' % build_dir) - - temp_dir = args.out_dir - if temp_dir: - try: - shutil.rmtree(temp_dir) - except OSError: - pass - os.makedirs(temp_dir) - else: - # Create a temporary directory to copy files into. - temp_dir = tempfile.mkdtemp(prefix='pub_packages-') - - print('Packages ready to be uploaded in %s' % temp_dir) - - # Copy packages - dart_pkg_dir = os.path.join(build_dir, 'gen', 'dart-pkg') - for package in args.packages: - print('Preparing package %s' % package) - src_dir = os.path.join(dart_pkg_dir, package) - dst_dir = os.path.join(temp_dir, package) - ignore = None - # Special case 'mojom' package to not copy generated mojom.dart files. - if package == 'mojom': - ignore = shutil.ignore_patterns('*.mojom.dart') - copy_package(src_dir, dst_dir, ignore) - # Special case 'mojom' package to remove empty directories. - if package == 'mojom': - remove_empty_dirs(dst_dir) - install_mojo_license_and_authors_files(sdk_dir, dst_dir) - - -if __name__ == '__main__': - main() diff --git a/mojo/tools/publish_pub_packages.py b/mojo/tools/publish_pub_packages.py deleted file mode 100755 index fcfbeea3ba06c..0000000000000 --- a/mojo/tools/publish_pub_packages.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python -# Copyright 2015 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. - -# See https://github.com/domokit/mojo/wiki/Release-process - -import argparse -import distutils.util -import os -import subprocess -import sys -import tempfile - -MOJO_TOOLS_DIR = os.path.dirname(os.path.abspath(__file__)) -SRC_ROOT = os.path.dirname(os.path.dirname(MOJO_TOOLS_DIR)) -DART_SDK = os.path.join(SRC_ROOT, 'third_party', 'dart-sdk', 'dart-sdk', 'bin') -PUB = os.path.join(DART_SDK, 'pub') - -PACKAGES = [ - 'mojo', - 'mojom', - 'mojo_services', -] - -CONFIRM = """This tool is destructive and will revert your current branch to -origin/master among other things. Are you sure you wish to continue?""" - - -def run(cwd, args): - print 'RUNNING:', ' '.join(args), 'IN:', cwd - subprocess.check_call(args, cwd=cwd) - - -def confirm(prompt): - user_input = raw_input("%s (y/N) " % prompt) - try: - return distutils.util.strtobool(user_input) == 1 - except ValueError: - return False - - -def main(): - parser = argparse.ArgumentParser(description='Deploy!') - parser.parse_args() - - if not confirm(CONFIRM): - print "Aborted." - return 1 - - run(SRC_ROOT, ['git', 'fetch', 'origin']) - run(SRC_ROOT, ['git', 'reset', 'origin/master', '--hard']) - run(SRC_ROOT, ['gclient', 'sync']) - - run(SRC_ROOT, ['mojo/tools/mojob.py', 'gn', '--android', '--release']) - run(SRC_ROOT, ['ninja', '-C', 'out/android_Release']) - - package_root = tempfile.mkdtemp(prefix='pub_packages-') - - run(SRC_ROOT, [ - 'mojo/tools/prepare_pub_packages.py', - '--out-dir', - package_root, - 'out', - ]) - - for package in PACKAGES: - package_dir = os.path.join(package_root, package) - print "PACKAGE", package_dir, "PUB", PUB - run(package_dir, [PUB, 'publish', '--force']) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/mojo/tools/remote_file_reader.cc b/mojo/tools/remote_file_reader.cc deleted file mode 100644 index c12132ae0d4f4..0000000000000 --- a/mojo/tools/remote_file_reader.cc +++ /dev/null @@ -1,325 +0,0 @@ -// Copyright 2015 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -// This utility allows to read a file from the local file system through a -// network protocol. The protocol is the following request response protocol: -// -// Opening a new file: -// Request: O path_to_file\n -// Success: O -// Error: E -// -// Seeking on the last opened file: -// Request: S offset whence\n -// Success: 0 -// Error: E -// -// Reading the last opened file at the current position: -// Request: R size\n -// Success: 0{size encoded on 4 bytes in network order}{content} -// Error: E - -namespace { - -// Display an error message and exit. -void error(const char* msg) { - perror(msg); - exit(1); -} - -// Keep track of an active connection with a client. -class Connection { - public: - // Takes ownership of the given fd which is an opened socket to the client. - explicit Connection(int fd) - : fd_(fd), file_fd_(-1), buffer_size_(0), buffer_(nullptr, free) {} - ~Connection() { Close(); } - - int fd() { return fd_; }; - - void Close() { - if (fd_ != -1) { - close(fd_); - fd_ = -1; - } - if (file_fd_ != -1) { - close(file_fd_); - file_fd_ = -1; - } - } - - // Returns whether this connection has some data to write to the client. - bool NeedsWriting() { return write_buffer_.size() > 0; } - - // Try to write buffered data to the client. This should only be called when - // the socket is writeable, otherwise this method may block. - bool Write() { - int nb_written = write(fd_, write_buffer_.data(), write_buffer_.size()); - if (nb_written <= 0) { - Close(); - return false; - } - write_buffer_ = std::string(write_buffer_, nb_written); - return true; - } - - // Read any data available from the client, and send any responses if a full - // request has been read. This should only be called when the socket is - // readable, otherwise this method may block. - bool Read() { - char buffer[4096]; - int nb_read = read(fd_, buffer, sizeof(buffer)); - if (nb_read <= 0) { - Close(); - return false; - } - read_buffer_ += std::string(buffer, nb_read); - Respond(); - return true; - } - - private: - // Success message. - const char kSuccess = 'O'; - // Error message. - const char kError = 'E'; - - // Read any available request in the read buffer and write the responses in - // the write buffer. - void Respond() { - std::string::size_type eol_position = read_buffer_.find('\n'); - while (eol_position != std::string::npos) { - std::string command(read_buffer_, 0, eol_position); - read_buffer_ = std::string(read_buffer_, eol_position + 1); - std::string argument(command, 2); - switch (command[0]) { - case 'O': - OpenCommand(argument); - break; - case 'S': - SeekCommand(argument); - break; - case 'R': - ReadCommand(argument); - break; - default: - write_buffer_ += kError; - } - eol_position = read_buffer_.find('\n'); - } - } - - // Handle the open command. - void OpenCommand(const std::string& file) { - if (file_fd_ != -1) { - close(file_fd_); - file_fd_ = -1; - } - file_fd_ = open(file.c_str(), O_RDONLY); - if (file_fd_ == -1) { - perror("Unable to open file"); - write_buffer_ += kError; - return; - } - write_buffer_ += kSuccess; - } - - // Handle the seek command. - void SeekCommand(const std::string& parameters) { - if (file_fd_ == -1) { - write_buffer_ += kError; - return; - } - int32_t offset; - int32_t whence; - if (sscanf(parameters.c_str(), "%" SCNd32 " %" SCNd32, &offset, &whence) != - 2) { - write_buffer_ += kError; - return; - } - if (lseek(file_fd_, offset, whence) == -1) { - perror("Unable to seek"); - write_buffer_ += kError; - return; - } - write_buffer_ += kSuccess; - } - - // Handle the read command. - void ReadCommand(const std::string& parameters) { - if (file_fd_ == -1) { - write_buffer_ += kError; - return; - } - int32_t size; - if (sscanf(parameters.c_str(), "%" SCNd32, &size) != 1) { - write_buffer_ += kError; - return; - } - if (size <= 0) { - write_buffer_ += kError; - return; - } - EnsureBufferCapacity(size); - int32_t result = read(file_fd_, buffer_.get(), size); - if (result < 0) { - perror("Unable to read"); - close(file_fd_); - file_fd_ = -1; - write_buffer_ += kError; - return; - } - write_buffer_ += kSuccess; - int32_t size_to_send = htonl(result); - static_assert(sizeof(size_to_send) == 4, "Must send size with 4 byte."); - write_buffer_ += std::string(reinterpret_cast(&size_to_send), 4); - write_buffer_ += std::string(buffer_.get(), result); - } - - // Ensure that |buffer_| has the capacity needed to read from the local file. - void EnsureBufferCapacity(size_t capacity) { - if (buffer_size_ >= capacity) { - return; - } - if (buffer_size_ == 0) { - buffer_.reset(static_cast(malloc(capacity))); - buffer_size_ = capacity; - return; - } - buffer_.reset(static_cast(realloc(buffer_.release(), capacity))); - buffer_size_ = capacity; - } - - // File descriptor of the socket connected to the client. - int fd_; - // File descriptor of the current read file. - int file_fd_; - size_t buffer_size_; - std::unique_ptr buffer_; - std::string write_buffer_; - std::string read_buffer_; -}; - -} // namespace - -int main(int argc, char** argv) { - // The port to bind to. - int port = 0; - if (argc > 1) { - port = atoi(argv[1]); - } - // Setup the server socket. - int server_socket, connected_socket; - struct sockaddr_in server_address, client_address; - server_socket = socket(AF_INET, SOCK_STREAM, 0); - if (server_socket < 0) { - error("Unable to open socket"); - } - bzero(&server_address, sizeof(server_address)); - server_address.sin_family = AF_INET; - server_address.sin_addr.s_addr = INADDR_ANY; - server_address.sin_port = port; - if (bind(server_socket, reinterpret_cast(&server_address), - sizeof(server_address)) < 0) { - error("Unable to bind socket"); - } - socklen_t socket_size = sizeof(server_address); - if (getsockname(server_socket, - reinterpret_cast(&server_address), - &socket_size) < 0) { - perror("Unable to retrieve socket information"); - } - // Print the port on the bound port on the standard output. - printf("%d\n", ntohs(server_address.sin_port)); - - // Start listening for client. - listen(server_socket, 5); - - // Wait for the first client to connect. - socket_size = sizeof(client_address); - connected_socket = - accept(server_socket, reinterpret_cast(&client_address), - &socket_size); - if (connected_socket < 0) { - error("Unable to accept the intiial client"); - } - - // Keep track of active connections. - std::vector> connections; - connections.push_back( - std::unique_ptr(new Connection(connected_socket))); - - // Stop when all clients have disconnected. - while (connections.size()) { - // Prepate data to wait for any I/O to be ready. - fd_set rset; - fd_set wset; - FD_ZERO(&rset); - FD_ZERO(&wset); - // Always wait for a new connection. - FD_SET(server_socket, &rset); - int max_fd = server_socket + 1; - for (auto& c : connections) { - // Always wait for a client sending data. - FD_SET(c->fd(), &rset); - // Wait for a client to be ready to receive data only if some data needs - // to be sent. - if (c->NeedsWriting()) { - FD_SET(c->fd(), &wset); - } - max_fd = std::max(max_fd, c->fd() + 1); - } - // Wait for any I/O to be ready. - select(max_fd, &rset, &wset, nullptr, nullptr); - - // Check if a client a connected. - if (FD_ISSET(server_socket, &rset)) { - int fd = accept(server_socket, - reinterpret_cast(&client_address), - &socket_size); - if (fd >= 0) { - connections.push_back(std::unique_ptr(new Connection(fd))); - } - } - - // Check each connection. - for (auto& c : connections) { - if (FD_ISSET(c->fd(), &rset)) { - if (!c->Read()) { - // If a fatal error happen, delete the connection. - c.reset(); - } - } - if (c && FD_ISSET(c->fd(), &wset)) { - if (!c->Write()) { - // If a fatal error happen, delete the connection. - c.reset(); - } - } - } - - // Remove any deleted connection from the list of active connections. - connections.erase( - std::remove_if(connections.begin(), connections.end(), - [](const std::unique_ptr& c) { return !c; }), - connections.end()); - } - return 0; -} diff --git a/mojo/tools/roll/android_build.patch b/mojo/tools/roll/android_build.patch deleted file mode 100644 index bd73b9e009c59..0000000000000 --- a/mojo/tools/roll/android_build.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/build/android/pylib/constants/__init__.py -+++ b/build/android/pylib/constants/__init__.py -@@ -184,7 +184,7 @@ class ANDROID_SDK_VERSION_CODES(object): - LOLLIPOP_MR1 = 22 - - ANDROID_SDK_VERSION = ANDROID_SDK_VERSION_CODES.LOLLIPOP_MR1 --ANDROID_SDK_BUILD_TOOLS_VERSION = '22.0.0' -+ANDROID_SDK_BUILD_TOOLS_VERSION = '22.0.1' - ANDROID_SDK_ROOT = os.path.join(DIR_SOURCE_ROOT, - 'third_party/android_tools/sdk') - ANDROID_SDK_TOOLS = os.path.join(ANDROID_SDK_ROOT, ---- a/build/common.gypi -+++ b/build/common.gypi -@@ -1682,7 +1682,7 @@ - 'android_host_arch%': '" - sys.exit(1) - -chromium_deps_path = sys.argv[1] -mojo_deps_path = os.path.join(utils.mojo_root_dir, "DEPS") - -chromium_deps = "" - -with open(chromium_deps_path) as chromium_deps_file: - chromium_deps = chromium_deps_file.read() - -found_mismatch = False - -with open(mojo_deps_path) as mojo_deps_file: - for line in mojo_deps_file: - m = re.search("[0-9a-f]{32}", line) - if m: - git_hash = m.group(0) - if not git_hash in chromium_deps: - print "%s in mojo DEPS but not in chromium DEPS" % git_hash - print "line %s" % line.strip() - found_mismatch = True - -if found_mismatch: - sys.exit(1) diff --git a/mojo/tools/roll/patch.py b/mojo/tools/roll/patch.py deleted file mode 100755 index 4147b24f51925..0000000000000 --- a/mojo/tools/roll/patch.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -import os -import subprocess -import utils - -def patch_and_filter(): - """Applies the *.patch files in the current dir and some hardcoded filters.""" - os.chdir(utils.mojo_root_dir) - - utils.filter_file("build/landmines.py", - lambda line: not "gyp_environment" in line) - utils.commit("filter gyp_environment out of build/landmines.py") - - utils.filter_file("gpu/BUILD.gn", lambda line: not "//gpu/ipc" in line) - utils.commit("filter //gpu/ipc out of gpu/BUILD.gn") - - utils.filter_file("cc/BUILD.gn", lambda line: not "//media" in line) - utils.commit("filter //media out of cc/BUILD.gn") - - patch() - - -def patch(relative_patches_dir=os.curdir): - """Applies the *.patch files in |relative_patches_dir|. - - Args: - relative_patches_dir: A directory path relative to the current directory. - Defaults to the directory of this file. - - Raises: - subprocess.CalledProcessError if the patch couldn't be applied. - """ - patches_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), - relative_patches_dir) - assert os.path.isdir(patches_dir) - - os.chdir(utils.mojo_root_dir) - for p in utils.find(["*.patch"], patches_dir): - print "applying patch %s" % os.path.basename(p) - try: - utils.system(["git", "apply", p]) - utils.commit("applied patch %s" % os.path.basename(p)) - except subprocess.CalledProcessError: - print "ERROR: patch %s failed to apply" % os.path.basename(p) - raise diff --git a/mojo/tools/roll/sanitizers_build.patch b/mojo/tools/roll/sanitizers_build.patch deleted file mode 100644 index 9f9e8b8334f2d..0000000000000 --- a/mojo/tools/roll/sanitizers_build.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn -index 8996951..023315f 100644 ---- a/build/config/sanitizers/BUILD.gn -+++ b/build/config/sanitizers/BUILD.gn -@@ -8,9 +8,12 @@ import("//build/config/sanitizers/sanitizers.gni") - # shared_libraries. Unconditionally depend upon this target as it is empty if - # |is_asan|, |is_lsan|, |is_tsan|, |is_msan| and |use_custom_libcxx| are false. - group("deps") { -- deps = [ -- "//third_party/instrumented_libraries:deps", -- ] -+ # TODO(vtl): Chromium has the following (but we don't have -+ # instrumented_libraries). -+ # deps = [ -+ # "//third_party/instrumented_libraries:deps", -+ # ] -+ deps = [] - if (is_asan || is_lsan || is_tsan || is_msan) { - public_configs = [ ":sanitizer_options_link_helper" ] - deps += [ ":options_sources" ] -diff --git a/build/config/sanitizers/sanitizers.gni b/build/config/sanitizers/sanitizers.gni -index a7b9658..0edc144 100644 ---- a/build/config/sanitizers/sanitizers.gni -+++ b/build/config/sanitizers/sanitizers.gni -@@ -6,7 +6,9 @@ declare_args() { - # Use libc++ (buildtools/third_party/libc++ and - # buildtools/third_party/libc++abi) instead of stdlibc++ as standard library. - # This is intended to be used for instrumented builds. -- use_custom_libcxx = (is_asan && is_linux) || is_tsan || is_msan -+ # TODO(vtl): We don't use this, since building fails, for some reason. -+ use_custom_libcxx = false -+ # use_custom_libcxx = (is_asan && is_linux) || is_tsan || is_msan - - # Track where uninitialized memory originates from. From fastest to slowest: - # 0 - no tracking, 1 - track only the initial allocation site, 2 - track the diff --git a/mojo/tools/roll/update_from_chromium.py b/mojo/tools/roll/update_from_chromium.py deleted file mode 100755 index d9ae68d57f8ce..0000000000000 --- a/mojo/tools/roll/update_from_chromium.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -import argparse -import json -import os -import subprocess -import sys -import urllib2 -from utils import commit -from utils import mojo_root_dir -from utils import system - -import patch - -# //base and its dependencies -base_deps = [ - "base", - "testing", - "third_party/ashmem", - "third_party/libevent", - "third_party/libxml", # via //base/test - "third_party/modp_b64", - "third_party/tcmalloc", -] - -# //build and its dependencies -build_deps = [ - "build", - "third_party/android_testrunner", - "third_party/binutils", - "third_party/pymock", - "tools/android", - "tools/clang", - "tools/generate_library_loader", - "tools/gritsettings", - "tools/relocation_packer", - "tools/valgrind", -] - -# //sandbox/linux and its dependencies -sandbox_deps = [ - "sandbox/linux", -] - -# things used from //mojo/public -mojo_sdk_deps = [ - "third_party/cython", -] - -# These directories are snapshotted from chromium without modifications. -dirs_to_snapshot = base_deps + build_deps + sandbox_deps + mojo_sdk_deps - -files_to_copy = [ "sandbox/sandbox_export.h" ] - -# The contents of these files before the roll will be preserved after the roll, -# even though they live in directories rolled in from Chromium. -files_not_to_roll = [ - "build/config/ui.gni", - "build/ls.py", - "build/module_args/mojo.gni", -] - -dirs = dirs_to_snapshot - -def chromium_rev_number(src_commit): - base_url = "https://cr-rev.appspot.com/_ah/api/crrev/v1/commit/" - commit_info = json.load(urllib2.urlopen(base_url + src_commit)) - return commit_info["numberings"][0]["number"] - -def rev(source_dir): - for d in dirs: - print "removing directory %s" % d - try: - system(["git", "rm", "-r", d], cwd=mojo_root_dir) - except subprocess.CalledProcessError: - print "Could not remove %s" % d - print "cloning directory %s" % d - files = system(["git", "ls-files", d], cwd=source_dir) - for f in files.splitlines(): - dest_path = os.path.join(mojo_root_dir, f) - system(["mkdir", "-p", os.path.dirname(dest_path)], cwd=source_dir) - system(["cp", os.path.join(source_dir, f), dest_path], cwd=source_dir) - system(["git", "add", d], cwd=mojo_root_dir) - - for f in files_to_copy: - system(["cp", os.path.join(source_dir, f), os.path.join(mojo_root_dir, f)]) - - system(["git", "add", "."], cwd=mojo_root_dir) - src_commit = system(["git", "rev-parse", "HEAD"], cwd=source_dir).strip() - src_rev = chromium_rev_number(src_commit) - commit("Update from https://crrev.com/" + src_rev, cwd=mojo_root_dir) - -def main(): - parser = argparse.ArgumentParser(description="Update the mojo repo's " + - "snapshot of things imported from chromium.") - parser.add_argument("chromium_dir", help="chromium source dir") - args = parser.parse_args() - pre_roll_commit = system( - ["git", "rev-parse", "HEAD"], cwd=mojo_root_dir).strip() - - rev(args.chromium_dir) - - try: - patch.patch_and_filter() - except subprocess.CalledProcessError: - print "ERROR: Roll failed due to a patch not applying" - print "Fix the patch to apply, commit the result, and re-run this script" - return 1 - - print "Restoring files whose contents don't track Chromium" - for f in files_not_to_roll: - system(["git", "checkout", pre_roll_commit, "--", f], cwd=mojo_root_dir) - if files_not_to_roll: - commit("Restored pre-roll versions of files that don't get rolled") - return 0 - -if __name__ == "__main__": - sys.exit(main()) diff --git a/mojo/tools/roll/utils.py b/mojo/tools/roll/utils.py deleted file mode 100755 index dcdfc3510e700..0000000000000 --- a/mojo/tools/roll/utils.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -import fnmatch -import os -import subprocess - -mojo_root_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), - os.pardir, os.pardir, os.pardir) - -def commit(message, cwd=None): - subprocess.call(['git', 'commit', '-a', '-m', message], cwd=cwd) - -def system(command, cwd=None): - return subprocess.check_output(command, cwd=cwd) - -def find(patterns, start='.'): - for path, dirs, files in os.walk(start): - for basename in files + dirs: - if any([fnmatch.fnmatch(basename, pattern) for pattern in patterns]): - filename = os.path.join(path, basename) - yield filename - -def filter_file(path, predicate): - with open(path, 'r+') as f: - lines = f.readlines() - new_lines = [line for line in lines if predicate(line)] - f.seek(0) - f.truncate() - f.write(''.join(new_lines)) diff --git a/mojo/tools/roll_services.py b/mojo/tools/roll_services.py deleted file mode 100755 index 5f9a94db7a93b..0000000000000 --- a/mojo/tools/roll_services.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python -# Copyright 2015 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. - -"""Roll services version in the cdn.""" - -import argparse -import os -import subprocess -import sys -import tempfile - -from mopy.config import Config -from mopy.paths import Paths - -def target(config): - target_name = config.target_os + "-" + config.target_cpu - if config.is_official_build: - target_name += "-official" - return target_name - - -def get_gsutil(): - paths = Paths() - sys.path.insert(0, os.path.join(paths.src_root, "tools")) - # pylint: disable=F0401 - import find_depot_tools - - depot_tools_path = find_depot_tools.add_depot_tools_to_path() - return os.path.join(depot_tools_path, "third_party", "gsutil", "gsutil") - - -def upload(gsutil_exe, source, dest): - subprocess.check_call([gsutil_exe, "cp", source, dest]) - - -def write_file_to_gs(gsutil_exe, file_contents, dest): - with tempfile.NamedTemporaryFile() as temp_version_file: - temp_version_file.write(file_contents) - temp_version_file.flush() - upload(gsutil_exe, temp_version_file.name, dest) - - -def roll_version(gsutil_exe, config, version): - service_dir = 'gs://mojo/services/%s/%s' % (target(config), version) - services = subprocess.check_output( - [gsutil_exe, 'ls', service_dir]).strip().split('\n') - for service in services: - service_binary_name = service.split('/')[-1] - service_location_file = ("gs://mojo/services/" + target(config) + "/" + - service_binary_name + "_location") - service_location_in_gs = service[len('gs://'):] - write_file_to_gs(gsutil_exe, service_location_in_gs, service_location_file) - - -def main(): - parser = argparse.ArgumentParser(description="Change the version of the mojo " - "services on the cdn.") - parser.add_argument("-v", "--verbose", help="Verbose mode", - action="store_true") - parser.add_argument("version", - help="New version of the mojo services.") - args = parser.parse_args() - - gsutil_exe = get_gsutil() - - for target_os in [Config.OS_LINUX, Config.OS_ANDROID]: - config = Config(target_os=target_os) - roll_version(gsutil_exe, config, args.version) - - return 0 - -if __name__ == "__main__": - sys.exit(main()) diff --git a/mojo/tools/run_command_through_symbolizer.py b/mojo/tools/run_command_through_symbolizer.py deleted file mode 100755 index 1110eeec8e10c..0000000000000 --- a/mojo/tools/run_command_through_symbolizer.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -# Simple script that executes the command supplied as arguments and pipes -# stderr/out through asan_symbolize.py. - -import os -import subprocess -import sys - -def main(): - p1 = subprocess.Popen(sys.argv[1:], stdout=subprocess.PIPE, - stderr=sys.stdout) - p2 = subprocess.Popen([os.path.join('tools', 'valgrind', 'asan', - 'asan_symbolize.py')], - stdin=p1.stdout) - p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits. - p1.wait() - p2.wait() - return p1.returncode - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/mojo/tools/run_mojo_python_bindings_tests.py b/mojo/tools/run_mojo_python_bindings_tests.py deleted file mode 100755 index d64f49cd1159f..0000000000000 --- a/mojo/tools/run_mojo_python_bindings_tests.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -import os -import sys - -from mopy.mojo_python_tests_runner import MojoPythonTestRunner - - -class PythonBindingsTestRunner(MojoPythonTestRunner): - def add_custom_commandline_options(self, parser): - parser.add_argument('--build-dir', action='store', - help='path to the build output directory') - - def apply_customization(self, args): - if args.build_dir: - python_build_dir = os.path.join(args.build_dir, 'python') - if python_build_dir not in sys.path: - sys.path.append(python_build_dir) - python_gen_dir = os.path.join( - args.build_dir, - 'gen', 'mojo', 'public', 'interfaces', 'bindings', 'tests') - if python_gen_dir not in sys.path: - sys.path.append(python_gen_dir) - - -def main(): - runner = PythonBindingsTestRunner(os.path.join('mojo', 'python', 'tests')) - sys.exit(runner.run()) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/mojo/tools/run_mojo_python_tests.py b/mojo/tools/run_mojo_python_tests.py deleted file mode 100755 index d18baf4f6efa4..0000000000000 --- a/mojo/tools/run_mojo_python_tests.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -import os -import sys - -from mopy.mojo_python_tests_runner import MojoPythonTestRunner - - -def main(): - test_dir_list = [ - # Tests of pylib bindings. - os.path.join('mojo', 'public', 'tools', 'bindings', 'pylib'), - # Tests of "mopy" python tools code. - os.path.join('mojo', 'tools', 'mopy'), - # Tests of python code in devtools. - os.path.join('mojo', 'devtools', 'common', 'devtoolslib') - ] - - for test_dir in test_dir_list: - runner = MojoPythonTestRunner(test_dir) - exit_code = runner.run() - if exit_code: - return exit_code - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/mojo/tools/test_runner.py b/mojo/tools/test_runner.py deleted file mode 100755 index fe564a9a57d0f..0000000000000 --- a/mojo/tools/test_runner.py +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -"""A "smart" test runner for gtest unit tests (that caches successes).""" - -import argparse -import logging -import os -import subprocess -import sys - -from mopy import gtest -from mopy.config import Config -from mopy.gn import ConfigForGNArgs, ParseGNConfig -from mopy.log import InitLogging -from mopy.paths import Paths -from mopy.transitive_hash import file_hash, transitive_hash - - -_logger = logging.getLogger() -_paths = Paths() - - -def main(): - parser = argparse.ArgumentParser( - description="A 'smart' test runner for gtest unit tests (that caches " - "successes).") - - parser.add_argument("--verbose", help="be verbose (multiple times for more)", - default=0, dest="verbose_count", action="count") - parser.add_argument("--successes-cache", - help="the file caching test results (empty to not cache)", - default="mojob_test_successes") - parser.add_argument("test_list_file", - help="the file containing the tests to run", type=file) - parser.add_argument("root_dir", help="the build directory") - args = parser.parse_args() - - InitLogging(args.verbose_count) - config = ConfigForGNArgs(ParseGNConfig(args.root_dir)) - - _logger.debug("Test list file: %s", args.test_list_file) - execution_globals = {"config": config} - exec args.test_list_file in execution_globals - test_list = execution_globals["tests"] - _logger.debug("Test list: %s" % test_list) - - print "Running tests in directory: %s" % args.root_dir - os.chdir(args.root_dir) - - if args.successes_cache: - print "Successes cache file: %s" % args.successes_cache - else: - print "No successes cache file (will run all tests unconditionally)" - - if args.successes_cache: - # This file simply contains a list of transitive hashes of tests that - # succeeded. - try: - _logger.debug("Trying to read successes cache file: %s", - args.successes_cache) - with open(args.successes_cache, 'rb') as f: - successes = set([x.strip() for x in f.readlines()]) - _logger.debug("Successes: %s", successes) - except IOError: - # Just assume that it didn't exist, or whatever. - print ("Failed to read successes cache file %s (will create)" % - args.successes_cache) - successes = set() - - gtest.set_color() - - exit_code = 0 - successes_cache_file = (open(args.successes_cache, "ab") - if args.successes_cache else None) - for test_dict in test_list: - test = test_dict["test"] - test_name = test_dict.get("name", test) - # TODO(vtl): Add type. - cacheable = test_dict.get("cacheable", True) - if not cacheable: - _logger.debug("%s is marked as non-cacheable" % test_name) - - gtest_file = test - if config.target_os == Config.OS_ANDROID: - gtest_file = test + "_apk/" + test + "-debug.apk" - - if successes_cache_file and cacheable: - _logger.debug("Getting transitive hash for %s ... " % test_name) - try: - if config.target_os == Config.OS_ANDROID: - gtest_hash = file_hash(gtest_file) - else: - gtest_hash = transitive_hash(gtest_file) - except subprocess.CalledProcessError: - print "Failed to get transitive hash for %s" % test_name - exit_code = 1 - continue - _logger.debug(" Transitive hash: %s" % gtest_hash) - - if gtest_hash in successes: - print "Skipping %s (previously succeeded)" % test_name - continue - - _logger.info("Will start: %s" % test_name) - print "Running %s...." % test_name, - sys.stdout.flush() - try: - if config.target_os == Config.OS_ANDROID: - command = [ - "python", - os.path.join(_paths.src_root, "build", "android", "test_runner.py"), - "gtest", - "--output-directory", - args.root_dir, - "-s", - test, - ] - else: - command = ["./" + test] - _logger.debug("Command: %s" % command) - subprocess.check_output(command, stderr=subprocess.STDOUT) - print "Succeeded" - # Record success. - if args.successes_cache and cacheable: - successes.add(gtest_hash) - successes_cache_file.write(gtest_hash + "\n") - successes_cache_file.flush() - except subprocess.CalledProcessError as e: - print "Failed with exit code %d and output:" % e.returncode - print 72 * "-" - print e.output - print 72 * "-" - exit_code = 1 - continue - except OSError as e: - print " Failed to start test" - exit_code = 1 - continue - _logger.info("Completed: %s" % test_name) - if exit_code == 0: - print "All tests succeeded" - if successes_cache_file: - successes_cache_file.close() - - return exit_code - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/mojo/tools/testing/mojom_fetcher/dependency_tests.py b/mojo/tools/testing/mojom_fetcher/dependency_tests.py deleted file mode 100644 index 68f0ed8e6d1cf..0000000000000 --- a/mojo/tools/testing/mojom_fetcher/dependency_tests.py +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright 2015 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. - -import unittest - -from fetcher.dependency import Dependency - -class FakeRepository(object): - def get_repo_root_directory(self): - return "/base/repo" - - def get_external_directory(self): - return "/base/repo/third_party/external" - -class TestDependency(unittest.TestCase): - def test_importer_imported(self): - dep = Dependency(FakeRepository(), - "/base/repo/services/foo/../bar/bar.mojom", - "mojo/public/./../public/baz.mojom") - - self.assertEqual("/base/repo/services/bar/bar.mojom", dep.get_importer()) - self.assertEqual("mojo/public/baz.mojom", dep.get_imported()) - - def test_is_sdk_dep(self): - # Not in SDK - dep = Dependency(FakeRepository(), - "/base/repo/services/bar/bar.mojom", - "mojo/public/../foo/baz.mojom") - self.assertFalse(dep.is_sdk_dep()) - - # In SDK - dep = Dependency(FakeRepository(), - "/base/repo/services/bar/bar.mojom", - "mojo/public/baz.mojom") - self.assertTrue(dep.is_sdk_dep()) - - def test_maybe_is_a_url(self): - # Not a URL - dep = Dependency(FakeRepository(), - "/base/repo/services/bar/bar.mojom", - "mojo/foo/baz.mojom") - self.assertFalse(dep.maybe_is_a_url()) - - # URL import from non-external mojom - dep = Dependency(FakeRepository(), - "/base/repo/services/bar/bar.mojom", - "foo.bar.com/foo/baz.mojom") - self.assertTrue(dep.maybe_is_a_url()) - - # URL import from an external mojom - dep = Dependency(FakeRepository(), - "/base/repo/third_party/external/" + - "services.bar.com/bar/bar.mojom", - "foo.bar.com/foo/baz.mojom") - self.assertTrue(dep.maybe_is_a_url()) - - # relative import from an external mojom - dep = Dependency( - FakeRepository(), - "/base/repo/third_party/external/services.bar.com/bar/bar.mojom", - "foo/baz.mojom") - self.assertTrue(dep.maybe_is_a_url()) - - # external mojom importing SDK dep - dep = Dependency( - FakeRepository(), - "/base/repo/third_party/external/services.bar.com/bar/bar.mojom", - "mojo/public/foo/baz.mojom") - self.assertFalse(dep.maybe_is_a_url()) - - def test_generate_candidate_urls_relative(self): - dep = Dependency( - FakeRepository(), - "/base/repo/third_party/external/" + - "services.bar.com/bar/interfaces/bar.mojom", - "foo/baz.mojom") - self.assertTrue(dep.maybe_is_a_url()) - candidate_urls = dep.generate_candidate_urls() - self.assertEqual(["services.bar.com/bar/interfaces/foo/baz.mojom", - "services.bar.com/bar/foo/baz.mojom", - "services.bar.com/foo/baz.mojom"], candidate_urls) - - def test_generate_candidate_urls_absolute(self): - dep = Dependency(FakeRepository(), - "/base/repo/services/bar/interfaces/bar.mojom", - "services.foo.com/foo/baz.mojom") - self.assertTrue(dep.maybe_is_a_url()) - candidate_urls = dep.generate_candidate_urls() - self.assertEqual(["services.foo.com/foo/baz.mojom"], candidate_urls) - - def test_get_search_path_for_dependency(self): - # Absolute - dep = Dependency(FakeRepository(), - "/base/repo/services/bar/interfaces/bar.mojom", - "services.foo.com/foo/baz.mojom") - self.assertEqual(set(["/base/repo/services/bar/interfaces", - "/base/repo", "/base/repo/third_party/external"]), - dep.get_search_path_for_dependency()) - - # Relative - dep = Dependency( - FakeRepository(), - "/base/repo/third_party/external/services.foo.com/bar/bar.mojom", - "baz/baz.mojom") - self.assertEqual(set([ - "/base/repo", "/base/repo/third_party/external", - "/base/repo/third_party/external/services.foo.com/bar", - "/base/repo/third_party/external/services.foo.com"]), - dep.get_search_path_for_dependency()) diff --git a/mojo/tools/testing/mojom_fetcher/fakes.py b/mojo/tools/testing/mojom_fetcher/fakes.py deleted file mode 100644 index 699d3063846a4..0000000000000 --- a/mojo/tools/testing/mojom_fetcher/fakes.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright 2015 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. - -import io -import os.path - -from fetcher.dependency import Dependency -from fetcher.mojom_file import MojomFile -from fetcher.repository import Repository - -class FakeRepository(Repository): - data1 = """module test; -import "bar/baz.mojom"; -interface Foo {};""" - data2 = """module test; -import "services.domokit.org/foo/fiz.mojom"; -interface Baz {};""" - data3 = """module test; -import "services.fiz.org/foo/bar.mojom"; -interface Fiz {};""" - data4 = """module test; -interface SomeInterface {};""" - - def __init__(self, *args, **kwargs): - self.files_opened = [] - self.directories_walked = [] - self.all_files_available = False - - Repository.__init__(self, *args, **kwargs) - - def get_walk_base(self, directory): - data_base = [ - (directory, ["foo", "third_party"], []), - (os.path.join(directory, "foo"), ["bar"], ["foo.mojom"]), - (os.path.join(directory, "foo/bar"), [], ["baz.mojom"]), - (os.path.join(directory, "third_party"), ["external"], []), - (os.path.join(directory, "third_party/external"), - ["services.domokit.org"], []), - (os.path.join(directory, - "third_party/external/services.domokit.org"), - ["foo"], []), - (os.path.join(directory, - "third_party/external/services.domokit.org/foo"), - [], ["fiz.mojom"])] - if self.all_files_available: - data_base.extend([ - (os.path.join(directory, - "third_party/external/services.fiz.org"), - ["foo"], []), - (os.path.join(directory, - "third_party/external/services.fiz.org/foo"), - [], ["bar.mojom"])]) - return data_base - - def get_walk_external(self, directory): - data_external = [ - (directory, ["services.domokit.org"], []), - (os.path.join(directory, "services.domokit.org"), - ["foo"], []), - (os.path.join(directory, "services.domokit.org/foo"), - [], ["fiz.mojom"])] - if self.all_files_available: - data_external.extend([ - (os.path.join(directory, "services.fiz.org"), - ["foo"], []), - (os.path.join(directory, "services.fiz.org/foo"), - [], ["bar.mojom"])]) - return data_external - - - def _open(self, f): - self.files_opened.append(f) - - if "foo.mojom" in f: - val = io.BytesIO(self.data1) - elif "baz.mojom" in f: - val = io.BytesIO(self.data2) - elif "fiz.mojom" in f: - val = io.BytesIO(self.data3) - else: - val = io.BytesIO(self.data4) - return val - - def _os_walk(self, directory): - self.directories_walked.append(directory) - if directory == self._root_dir: - return iter(self.get_walk_base(directory)) - else: - return iter(self.get_walk_external(directory)) - - -class FakeDependency(Dependency): - IN_FILESYSTEM = [ - "/base/repo/third_party/external/example.com/dir/example.mojom", - "/base/repo/third_party/external/example.com/dir/dir.mojom", - "/base/repo/third_party/external/domokit.org/bar/baz/buzz.mojom", - "/base/repo/third_party/external/domokit.org/bar/foo/bar.mojom", - ] - - def _os_path_exists(self, path): - if path in self.IN_FILESYSTEM: - return True - elif os.path.join("/base/repo", path) in self.IN_FILESYSTEM: - return True - else: - return False - - -class FakeMojomFile(MojomFile): - def add_dependency(self, dependency): - """Declare a new dependency of this mojom.""" - self.deps.append(FakeDependency(self._repository, self.name, dependency)) diff --git a/mojo/tools/testing/mojom_fetcher/mojom_directory_tests.py b/mojo/tools/testing/mojom_fetcher/mojom_directory_tests.py deleted file mode 100644 index 0b2f5dd12b6d5..0000000000000 --- a/mojo/tools/testing/mojom_fetcher/mojom_directory_tests.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2015 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. - -import os.path -import unittest - -from fakes import FakeMojomFile -from fetcher.dependency import Dependency -from fetcher.mojom_directory import MojomDirectory -from fetcher.mojom_file import MojomFile -from fetcher.repository import Repository - - -class TestMojomDirectory(unittest.TestCase): - def test_build_gn_path(self): - directory = MojomDirectory( - "/base/repo/third_party/external/domokit.org/bar/baz") - self.assertEquals( - "/base/repo/third_party/external/domokit.org/bar/baz/BUILD.gn", - directory.get_build_gn_path()) - - def test_jinja_parameters(self): - mojom = FakeMojomFile( - Repository("/base/repo", "third_party/external"), - "/base/repo/third_party/external/domokit.org/bar/baz/foo.mojom") - mojom.add_dependency("example.com/dir/example.mojom") - mojom.add_dependency("example.com/dir/dir.mojom") - mojom.add_dependency("buzz.mojom") - mojom.add_dependency("foo/bar.mojom") - mojom.add_dependency( - "mojo/public/interfaces/application/shell.mojom") - directory = MojomDirectory( - "/base/repo/third_party/external/domokit.org/bar/baz") - directory.add_mojom(mojom) - params = directory.get_jinja_parameters([]) - self.assertEquals( - {"group_name": "baz", - "mojoms": [{ - "target_name": "foo", - "filename": "foo.mojom", - "import_dirs": [".."], - "mojo_sdk_deps": ["mojo/public/interfaces/application"], - "deps": [ - '//third_party/external/example.com/dir:example', - '//third_party/external/example.com/dir:dir_mojom', - ':buzz', - '../foo:bar'] - }]}, params) - diff --git a/mojo/tools/testing/mojom_fetcher/mojom_fetcher_tests.py b/mojo/tools/testing/mojom_fetcher/mojom_fetcher_tests.py deleted file mode 100755 index 8781ffedb310a..0000000000000 --- a/mojo/tools/testing/mojom_fetcher/mojom_fetcher_tests.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python -# Copyright 2015 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. - -import io -import os -import sys -import unittest - -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), - "..", "..", "..", "public", "tools", - "mojom_fetcher")) -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), - "..", "..", "..", "public", "tools", - "mojom_fetcher", "pylib")) -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), - "..", "..", "..", "public", "tools", - "bindings", "pylib")) - -from mojom_fetcher import UrlRewriter, UrlRewriterException, MojomFetcher - -# Fake repository for testing -from fakes import FakeRepository - - -class TestUrlRewriter(unittest.TestCase): - def test_no_transitive(self): - rules = {"foo.com": "bar.com/foo", "bar.com": "baz.com"} - try: - UrlRewriter(rules) - self.fail() - except UrlRewriterException: - # This is expected - pass - - def test_rewrite(self): - rules = {"foo.com": "bar.com/foo", "baz.com": "bar.com/baz"} - rewriter = UrlRewriter(rules) - self.assertEquals("bar.com/foo/foo_file", - rewriter.rewrite("foo.com/foo_file")) - self.assertEquals("bar.com/baz/foo_file", - rewriter.rewrite("baz.com/foo_file")) - self.assertEquals("example.com/file", - rewriter.rewrite("example.com/file")) - - -class FakeRequest(object): - def __init__(self, content, ok): - self.content = content - self.ok = ok - - -class FakeMojomFetcher(MojomFetcher): - data = """module test; -interface Fiz {};""" - - def __init__(self, repository, rewriter): - self.count = 1 - self.opened_files = {} - self.downloaded_urls = [] - MojomFetcher.__init__(self, repository, rewriter) - - def _requests_get(self, url): - self.downloaded_urls.append(url) - return FakeRequest(self.data, True) - - def _os_makedirs(self, _): - return - - def _open(self, f, _): - fake_file = io.BytesIO() - self.opened_files[f] = fake_file - if "services.fiz.org/foo/bar.mojom" in f: - self._repository.all_files_available = True - return fake_file - - -class TestMojomFetcher(unittest.TestCase): - def setUp(self): - self.rules = {"foo.com": "bar.com/foo", "baz.com": "bar.com/baz"} - self.rewriter = UrlRewriter(self.rules) - self.repository = FakeRepository("/path/to/repo", "third_party/external") - self.fetcher = FakeMojomFetcher(self.repository, self.rewriter) - - def test_get(self): - self.fetcher.get("foo.com/bar.mojom") - self.assertEquals(["https://bar.com/foo/bar.mojom", - "https://services.fiz.org/foo/bar.mojom"], - self.fetcher.downloaded_urls) - - def test_update(self): - self.fetcher.update() - self.assertEquals(["https://services.domokit.org/foo/fiz.mojom", - "https://services.fiz.org/foo/bar.mojom"], - self.fetcher.downloaded_urls) - - def test_discover(self): - self.fetcher.update() - self.assertEquals(["https://services.domokit.org/foo/fiz.mojom", - "https://services.fiz.org/foo/bar.mojom"], - self.fetcher.downloaded_urls) - -if __name__ == '__main__': - loader = unittest.defaultTestLoader - runner = unittest.TextTestRunner() - directory = os.path.dirname(os.path.abspath(__file__)) - suite = loader.discover(directory, '*_tests.py') - runner.run(suite) diff --git a/mojo/tools/testing/mojom_fetcher/mojom_file_tests.py b/mojo/tools/testing/mojom_fetcher/mojom_file_tests.py deleted file mode 100644 index cb5558d299ea6..0000000000000 --- a/mojo/tools/testing/mojom_fetcher/mojom_file_tests.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2015 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. - -import os.path -import unittest - -from fetcher.mojom_file import MojomFile -from fetcher.dependency import Dependency -from fetcher.repository import Repository -from fakes import FakeDependency, FakeMojomFile - - -class TestMojomFile(unittest.TestCase): - def test_add_dependency(self): - mojom = MojomFile(Repository("/base/repo", "third_party/external"), - "mojom_name") - mojom.add_dependency("dependency_name") - self.assertEqual(1, len(mojom.deps)) - self.assertEqual("mojom_name", mojom.deps[0].get_importer()) - self.assertEqual("dependency_name", mojom.deps[0].get_imported()) - - def test_jinja_parameters(self): - mojom = FakeMojomFile( - Repository("/base/repo", "third_party/external"), - "/base/repo/third_party/external/domokit.org/bar/baz/foo.mojom") - mojom.add_dependency("example.com/dir/example.mojom") - mojom.add_dependency("example.com/dir/dir.mojom") - mojom.add_dependency("buzz.mojom") - mojom.add_dependency("foo/bar.mojom") - mojom.add_dependency( - "mojo/public/interfaces/application/shell.mojom") - params = mojom.get_jinja_parameters([]) - self.assertEquals({ - "target_name": "foo", - "filename": "foo.mojom", - "import_dirs": [".."], - "mojo_sdk_deps": ["mojo/public/interfaces/application"], - "deps": [ - '//third_party/external/example.com/dir:example', - '//third_party/external/example.com/dir:dir_mojom', - ':buzz', - '../foo:bar'] - }, params) diff --git a/mojo/tools/testing/mojom_fetcher/mojom_gn_tests.py b/mojo/tools/testing/mojom_fetcher/mojom_gn_tests.py deleted file mode 100644 index 11e61b3afb108..0000000000000 --- a/mojo/tools/testing/mojom_fetcher/mojom_gn_tests.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright 2015 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. - -import io -import os.path -import unittest - -from fakes import FakeMojomFile -from fetcher.mojom_directory import MojomDirectory -from fetcher.repository import Repository -from mojom_gn import BuildGNGenerator - -class FakeRepository(Repository): - def get_all_external_mojom_directories(self): - mojom = FakeMojomFile( - self, os.path.join(self.get_external_directory(), - "domokit.org/bar/baz/foo.mojom")) - mojom.add_dependency("example.com/dir/example.mojom") - mojom.add_dependency("example.com/dir/dir.mojom") - mojom.add_dependency("buzz.mojom") - mojom.add_dependency("foo/bar.mojom") - mojom.add_dependency( - "mojo/public/interfaces/application/shell.mojom") - directory = MojomDirectory( - os.path.join(self.get_external_directory(), - "domokit.org/bar/baz")) - directory.add_mojom(mojom) - return [directory] - - -class FakeBuildGNGenerator(BuildGNGenerator): - def __init__(self, *args, **kwargs): - self.opened_files = {} - BuildGNGenerator.__init__(self, *args, **kwargs) - - def _open(self, filepath, mode): - if mode != "w": - raise Exception("Invalid mode " + str(mode)) - self.opened_files[filepath] = io.StringIO() - return self.opened_files[filepath] - - -class TestBuildGNGenerator(unittest.TestCase): - BAZ_BUILD_GN = u"""import("//build/module_args/mojo.gni") -import("$mojo_sdk_root/mojo/public/tools/bindings/mojom.gni") - -mojom("baz") { - deps = [ - ":foo", - ] -} - -mojom("foo") { - sources = [ - "foo.mojom", - ] - import_dirs = [ - get_path_info("..", "abspath"), - ] - mojo_sdk_deps = [ - "mojo/public/interfaces/application", - ] - deps = [ - "//third_party/external/example.com/dir:example", - "//third_party/external/example.com/dir:dir_mojom", - ":buzz", - "../foo:bar", - ] -}""" - def test_generate(self): - self.maxDiff = None - repository = FakeRepository("/base/repo", "third_party/external") - gn_generator = FakeBuildGNGenerator(repository, os.path.abspath( - os.path.join(os.path.dirname(__file__), - "../../../public/tools/mojom_fetcher"))) - gn_generator.generate() - output_stream = gn_generator.opened_files[ - "/base/repo/third_party/external/domokit.org/bar/baz/BUILD.gn"] - self.assertEquals(prepare_string(self.BAZ_BUILD_GN), - prepare_string(output_stream.getvalue())) - -def prepare_string(value): - lines = value.split("\n") - lines = map(lambda l: l.strip().replace(" ", ""), lines) - lines = filter(lambda l: not l.startswith("#"), lines) - return ''.join(lines) - diff --git a/mojo/tools/testing/mojom_fetcher/repository_tests.py b/mojo/tools/testing/mojom_fetcher/repository_tests.py deleted file mode 100644 index 46724d1032e68..0000000000000 --- a/mojo/tools/testing/mojom_fetcher/repository_tests.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2015 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. - -import io -import os.path -import unittest - -from fetcher.dependency import Dependency - -# Fake repository for testing -from fakes import FakeRepository - - -class TestRepository(unittest.TestCase): - def test_init(self): - repository = FakeRepository("/path/to/repo", "third_party/external") - self.assertEqual("/path/to/repo", repository.get_repo_root_directory()) - self.assertEqual("/path/to/repo/third_party/external", - repository.get_external_directory()) - - def test_get_missing_dependencies(self): - repository = FakeRepository("/path/to/repo", "third_party/external") - missing_deps = repository.get_missing_dependencies() - self.assertEquals(["/path/to/repo"], repository.directories_walked) - # Order is not important - self.assertIn("/path/to/repo/foo/foo.mojom", repository.files_opened) - self.assertIn("/path/to/repo/foo/bar/baz.mojom", repository.files_opened) - self.assertIn( - "/path/to/repo/third_party/external/services.domokit.org/foo/fiz.mojom", - repository.files_opened) - self.assertEquals(3, len(repository.files_opened)) - - self.assertEquals([Dependency(repository, - "/path/to/repo/third_party/external/services.domokit.org/foo/fiz.mojom", - "services.fiz.org/foo/bar.mojom")], missing_deps) - - def test_get_external_urls(self): - repository = FakeRepository("/path/to/repo", "third_party/external") - urls = repository.get_external_urls() - self.assertEquals(["/path/to/repo/third_party/external"], - repository.directories_walked) - self.assertEquals(["services.domokit.org/foo/fiz.mojom"], urls) diff --git a/mojo/tools/upload_binaries.py b/mojo/tools/upload_binaries.py deleted file mode 100755 index d1c25cc9890bc..0000000000000 --- a/mojo/tools/upload_binaries.py +++ /dev/null @@ -1,234 +0,0 @@ -#!/usr/bin/env python -# Copyright 2015 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. - -"""Tool to roll Chromium into Mojo. See: -https://github.com/domokit/mojo/wiki/Rolling-code-between-chromium-and-mojo#chromium---mojo-updates -""" - -import argparse -import glob -import itertools -import os -import subprocess -import sys -import tempfile -import time -import zipfile - -import mopy.gn as gn -from mopy.config import Config -from mopy.paths import Paths -from mopy.version import Version - -sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, - "third_party", "pyelftools")) -import elftools.elf.elffile as elffile - -sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, - 'devtools', 'common')) -import android_gdb.signatures as signatures - - -BLACKLISTED_APPS = [ - # The network service apps are not produced out of the Mojo repo, but may - # be present in the build dir. - "network_service.mojo", - "network_service_apptests.mojo", -] - -ARCHITECTURE_INDEPENDENT_FILES = [ - # These are files other than *.mojo files which are part of our binary - # artifact scheme. These files must be architecture independent. - "obj/mojo/dart/apptest/apptest.dartzip", -] - - -def target(config): - target_name = config.target_os + "-" + config.target_cpu - if config.is_official_build: - target_name += "-official" - return target_name - -def find_apps_to_upload(build_dir): - apps = [] - for path in glob.glob(build_dir + "/*"): - if not os.path.isfile(path): - continue - _, ext = os.path.splitext(path) - if ext != '.mojo': - continue - if os.path.basename(path) in BLACKLISTED_APPS: - continue - apps.append(path) - return apps - - -def find_architecture_independent_files(build_dir): - existing_files = [] - for path in ARCHITECTURE_INDEPENDENT_FILES: - joined_path = os.path.join(build_dir, path) - if os.path.isfile(joined_path): - existing_files.append(joined_path) - return existing_files - - -def check_call(command_line, dry_run, **kwargs): - if dry_run: - print command_line - else: - subprocess.check_call(command_line, **kwargs) - - -def upload(config, source, dest, dry_run, gzip=False): - paths = Paths(config) - sys.path.insert(0, os.path.join(paths.src_root, "tools")) - # pylint: disable=F0401 - import find_depot_tools - - depot_tools_path = find_depot_tools.add_depot_tools_to_path() - gsutil_exe = os.path.join(depot_tools_path, "third_party", "gsutil", "gsutil") - - command_line = [gsutil_exe, "cp"] - if gzip and "." in source: - extension = source.split(".")[-1] - command_line.extend(["-z", extension]) - command_line.extend([source, dest]) - - check_call(command_line, dry_run) - - -def upload_symbols(config, build_dir, breakpad_upload_urls, dry_run): - dump_syms_exe = os.path.join(Paths().src_root, - "mojo", "tools", "linux64", "dump_syms") - symupload_exe = os.path.join(Paths().src_root, - "mojo", "tools", "linux64", "symupload") - dest_dir = "gs://mojo/symbols/" - symbols_dir = os.path.join(build_dir, "symbols") - with open(os.devnull, "w") as devnull: - for name in os.listdir(symbols_dir): - path = os.path.join(symbols_dir, name) - with open(path) as f: - signature = signatures.get_signature(f, elffile) - if signature is not None: - dest = dest_dir + signature - upload(config, path, dest, dry_run) - if breakpad_upload_urls: - with tempfile.NamedTemporaryFile() as temp: - check_call([dump_syms_exe, path], dry_run, - stdout=temp, stderr=devnull) - temp.flush() - for upload_url in breakpad_upload_urls: - check_call([symupload_exe, temp.name, upload_url], dry_run) - -def upload_shell(config, dry_run, verbose): - paths = Paths(config) - zipfile_name = target(config) - version = Version().version - - # Upload the binary. - # TODO(blundell): Change this to be in the same structure as the LATEST files, - # e.g., gs://mojo/shell/linux-x64//shell.zip. - dest = "gs://mojo/shell/" + version + "/" + zipfile_name + ".zip" - with tempfile.NamedTemporaryFile() as zip_file: - with zipfile.ZipFile(zip_file, 'w') as z: - shell_path = paths.target_mojo_shell_path - with open(shell_path) as shell_binary: - shell_filename = os.path.basename(shell_path) - zipinfo = zipfile.ZipInfo(shell_filename) - zipinfo.external_attr = 0777 << 16L - compress_type = zipfile.ZIP_DEFLATED - if config.target_os == Config.OS_ANDROID: - # The APK is already compressed. - compress_type = zipfile.ZIP_STORED - zipinfo.compress_type = compress_type - zipinfo.date_time = time.gmtime(os.path.getmtime(shell_path)) - if verbose: - print "zipping %s" % shell_path - z.writestr(zipinfo, shell_binary.read()) - upload(config, zip_file.name, dest, dry_run, gzip=False) - - # Update the LATEST file to contain the version of the new binary. - latest_file = "gs://mojo/shell/%s/LATEST" % target(config) - write_file_to_gs(version, latest_file, config, dry_run) - - -def upload_app(app_binary_path, config, dry_run): - app_binary_name = os.path.basename(app_binary_path) - version = Version().version - gsutil_app_location = ("gs://mojo/services/%s/%s/%s" % - (target(config), version, app_binary_name)) - - # Upload the new binary. - upload(config, app_binary_path, gsutil_app_location, dry_run) - - -def upload_file(file_path, config, dry_run): - file_binary_name = os.path.basename(file_path) - version = Version().version - gsutil_file_location = "gs://mojo/file/%s/%s" % (version, file_binary_name) - - # Upload the new binary. - upload(config, file_path, gsutil_file_location, dry_run) - - -def write_file_to_gs(file_contents, dest, config, dry_run): - with tempfile.NamedTemporaryFile() as temp_version_file: - temp_version_file.write(file_contents) - temp_version_file.flush() - upload(config, temp_version_file.name, dest, dry_run) - - -def main(): - parser = argparse.ArgumentParser(description="Upload binaries for apps and " - "the Mojo shell to google storage (by default on Linux, but this can be " - "changed via options).") - parser.add_argument("-n", "--dry_run", help="Dry run, do not actually "+ - "upload", action="store_true") - parser.add_argument("-v", "--verbose", help="Verbose mode", - action="store_true") - parser.add_argument("--android", - action="store_true", - help="Upload the shell and apps for Android") - parser.add_argument("--official", - action="store_true", - help="Upload the official build of the Android shell") - parser.add_argument("--symbols-upload-url", - action="append", default=[], - help="URL of the server to upload breakpad symbols to") - args = parser.parse_args() - - is_official_build = args.official - target_os = Config.OS_LINUX - if args.android: - target_os = Config.OS_ANDROID - elif is_official_build: - print "Uploading official builds is only supported for android." - return 1 - - config = Config(target_os=target_os, is_debug=False, - is_official_build=is_official_build) - - upload_shell(config, args.dry_run, args.verbose) - - if is_official_build: - print "Skipping uploading apps (official apk build)." - return 0 - - build_directory = gn.BuildDirectoryForConfig(config, Paths(config).src_root) - apps_to_upload = find_apps_to_upload(build_directory) - for app in apps_to_upload: - upload_app(app, config, args.dry_run) - - files_to_upload = find_architecture_independent_files(build_directory) - for file_to_upload in files_to_upload: - upload_file(file_to_upload, config, args.dry_run) - - upload_symbols(config, build_directory, - args.symbols_upload_url, args.dry_run) - - return 0 - -if __name__ == "__main__": - sys.exit(main()) diff --git a/services/asset_bundle/BUILD.gn b/services/asset_bundle/BUILD.gn index 8d988593080cd..7c38a3727461a 100644 --- a/services/asset_bundle/BUILD.gn +++ b/services/asset_bundle/BUILD.gn @@ -16,7 +16,7 @@ source_set("lib") { deps = [ "//base", - "//mojo/common", + "//mojo/data_pipe_utils", "//mojo/public/cpp/bindings:callback", "//mojo/public/cpp/system", "//mojo/services/asset_bundle/public/interfaces", @@ -32,7 +32,6 @@ mojo_native_application("asset_bundle") { deps = [ "//base", "//mojo/application", - "//mojo/common", "//mojo/public/cpp/application", "//mojo/public/cpp/bindings:callback", "//mojo/public/cpp/system", @@ -54,7 +53,7 @@ mojo_native_application("apptests") { "//base", "//mojo/application", "//mojo/application:test_support", - "//mojo/common", + "//mojo/data_pipe_utils", "//mojo/public/cpp/bindings", "//mojo/services/asset_bundle/public/interfaces", "//third_party/zlib:zip", diff --git a/services/asset_bundle/asset_bundle_apptest.cc b/services/asset_bundle/asset_bundle_apptest.cc index 4fd98491e3096..c449796a26a5a 100644 --- a/services/asset_bundle/asset_bundle_apptest.cc +++ b/services/asset_bundle/asset_bundle_apptest.cc @@ -7,8 +7,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/run_loop.h" -#include "mojo/common/common_type_converters.h" -#include "mojo/common/data_pipe_utils.h" +#include "mojo/data_pipe_utils/data_pipe_utils.h" #include "mojo/public/cpp/application/application_impl.h" #include "mojo/public/cpp/application/application_test_base.h" #include "mojo/services/asset_bundle/public/interfaces/asset_bundle.mojom.h" diff --git a/services/asset_bundle/asset_bundle_impl.cc b/services/asset_bundle/asset_bundle_impl.cc index 0c3bd343630cd..8776641f0afac 100644 --- a/services/asset_bundle/asset_bundle_impl.cc +++ b/services/asset_bundle/asset_bundle_impl.cc @@ -8,7 +8,7 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/logging.h" -#include "mojo/common/data_pipe_utils.h" +#include "mojo/data_pipe_utils/data_pipe_utils.h" namespace mojo { namespace asset_bundle { diff --git a/services/asset_bundle/asset_unpacker_job.h b/services/asset_bundle/asset_unpacker_job.h index 66c2b331e84d2..ed7cddc260c4e 100644 --- a/services/asset_bundle/asset_unpacker_job.h +++ b/services/asset_bundle/asset_unpacker_job.h @@ -9,7 +9,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/task_runner.h" -#include "mojo/common/data_pipe_utils.h" +#include "mojo/data_pipe_utils/data_pipe_utils.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/services/asset_bundle/public/interfaces/asset_bundle.mojom.h" diff --git a/services/sky/BUILD.gn b/services/sky/BUILD.gn index 90ee4610ec17e..4b15f980221e8 100644 --- a/services/sky/BUILD.gn +++ b/services/sky/BUILD.gn @@ -30,7 +30,6 @@ mojo_native_application("sky") { deps = [ "//mojo/application", - "//mojo/common", "//mojo/common:tracing_impl", "//mojo/converters/geometry", "//mojo/converters/input_events", diff --git a/sky/engine/bindings/BUILD.gn b/sky/engine/bindings/BUILD.gn index 03a429974c05d..509a207510294 100644 --- a/sky/engine/bindings/BUILD.gn +++ b/sky/engine/bindings/BUILD.gn @@ -376,7 +376,6 @@ source_set("generated_bindings") { "//dart/runtime:libdart", "//dart/runtime/vm:libdart_platform", "//mojo/application", - "//mojo/common", "//mojo/public/c/system", "//mojo/public/cpp/bindings", "//mojo/public/cpp/system", diff --git a/sky/engine/core/BUILD.gn b/sky/engine/core/BUILD.gn index e655074b911fd..45103f2efe3f3 100644 --- a/sky/engine/core/BUILD.gn +++ b/sky/engine/core/BUILD.gn @@ -14,7 +14,7 @@ source_set("libraries") { public_deps = [ "//base", "//mojo/application", - "//mojo/common", + "//mojo/data_pipe_utils", "//mojo/public/c/system", "//mojo/public/cpp/bindings", "//mojo/public/cpp/system", diff --git a/sky/engine/core/loader/CanvasImageDecoder.h b/sky/engine/core/loader/CanvasImageDecoder.h index 8d545dbbc6f8b..020a548c2dcaa 100644 --- a/sky/engine/core/loader/CanvasImageDecoder.h +++ b/sky/engine/core/loader/CanvasImageDecoder.h @@ -7,7 +7,7 @@ #define SKY_ENGINE_CORE_LOADER_CANVASIMAGELOADER_H_ #include "base/memory/weak_ptr.h" -#include "mojo/common/data_pipe_drainer.h" +#include "mojo/data_pipe_utils/data_pipe_drainer.h" #include "sky/engine/core/loader/ImageDecoderCallback.h" #include "sky/engine/platform/SharedBuffer.h" #include "sky/engine/tonic/dart_wrappable.h" diff --git a/sky/engine/core/script/dart_controller.cc b/sky/engine/core/script/dart_controller.cc index 8f9bb0a533480..eca1102111269 100644 --- a/sky/engine/core/script/dart_controller.cc +++ b/sky/engine/core/script/dart_controller.cc @@ -9,7 +9,7 @@ #include "base/single_thread_task_runner.h" #include "base/trace_event/trace_event.h" #include "dart/runtime/include/dart_tools_api.h" -#include "mojo/common/data_pipe_utils.h" +#include "mojo/data_pipe_utils/data_pipe_utils.h" #include "mojo/public/cpp/system/data_pipe.h" #include "sky/engine/bindings/builtin.h" #include "sky/engine/bindings/builtin_natives.h" diff --git a/sky/engine/platform/BUILD.gn b/sky/engine/platform/BUILD.gn index db9d9cba4cdfb..281a3f5e491a3 100644 --- a/sky/engine/platform/BUILD.gn +++ b/sky/engine/platform/BUILD.gn @@ -542,7 +542,6 @@ source_set("platform") { ":make_platform_generated", "//base:base", "//mojo/application", - "//mojo/common", "//mojo/environment:chromium", "//mojo/public/c/system", "//mojo/public/cpp/bindings", diff --git a/sky/engine/tonic/BUILD.gn b/sky/engine/tonic/BUILD.gn index 4f37841a6bbd2..cbcc08cf92308 100644 --- a/sky/engine/tonic/BUILD.gn +++ b/sky/engine/tonic/BUILD.gn @@ -57,7 +57,7 @@ source_set("tonic") { deps = [ "//base", - "//mojo/common", + "//mojo/data_pipe_utils", "//mojo/public/cpp/system", "//sky/engine/wtf", ] diff --git a/sky/engine/tonic/dart_library_loader.cc b/sky/engine/tonic/dart_library_loader.cc index 93c458787ba55..0b65fd6ea6e90 100644 --- a/sky/engine/tonic/dart_library_loader.cc +++ b/sky/engine/tonic/dart_library_loader.cc @@ -6,7 +6,7 @@ #include "base/callback.h" #include "base/trace_event/trace_event.h" -#include "mojo/common/data_pipe_drainer.h" +#include "mojo/data_pipe_utils/data_pipe_drainer.h" #include "sky/engine/tonic/dart_api_scope.h" #include "sky/engine/tonic/dart_converter.h" #include "sky/engine/tonic/dart_dependency_catcher.h" diff --git a/sky/engine/tonic/dart_snapshot_loader.h b/sky/engine/tonic/dart_snapshot_loader.h index 53edb0403a2ca..a1f7356ae0899 100644 --- a/sky/engine/tonic/dart_snapshot_loader.h +++ b/sky/engine/tonic/dart_snapshot_loader.h @@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "dart/runtime/include/dart_api.h" -#include "mojo/common/data_pipe_drainer.h" +#include "mojo/data_pipe_utils/data_pipe_drainer.h" namespace blink { class DartState; diff --git a/sky/engine/web/BUILD.gn b/sky/engine/web/BUILD.gn index 5d21211c60ffe..57185bea33292 100644 --- a/sky/engine/web/BUILD.gn +++ b/sky/engine/web/BUILD.gn @@ -2,10 +2,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -component("web") { - output_name = "sky_web" - +source_set("web") { deps = [ + "//mojo/message_pump", "//sky/engine/core", "//sky/engine/platform", ] diff --git a/sky/engine/web/Sky.cpp b/sky/engine/web/Sky.cpp index c06612b1176bf..4abd634fae12e 100644 --- a/sky/engine/web/Sky.cpp +++ b/sky/engine/web/Sky.cpp @@ -33,7 +33,7 @@ #include "base/message_loop/message_loop.h" #include "base/rand_util.h" #include "gen/sky/platform/RuntimeEnabledFeatures.h" -#include "mojo/common/message_pump_mojo.h" +#include "mojo/message_pump/message_pump_mojo.h" #include "sky/engine/core/dom/Microtask.h" #include "sky/engine/core/frame/Settings.h" #include "sky/engine/core/Init.h" diff --git a/sky/services/keyboard/BUILD.gn b/sky/services/keyboard/BUILD.gn index c7320c15cd4ee..7b6fd1a833cfa 100644 --- a/sky/services/keyboard/BUILD.gn +++ b/sky/services/keyboard/BUILD.gn @@ -10,7 +10,6 @@ if (is_ios) { ] deps = [ "//base:base", - "//mojo/common", "//mojo/public/cpp/application", "//mojo/services/keyboard/public/interfaces", ] diff --git a/sky/services/media/BUILD.gn b/sky/services/media/BUILD.gn index f149bc26ad5a5..af7ad39730667 100644 --- a/sky/services/media/BUILD.gn +++ b/sky/services/media/BUILD.gn @@ -50,7 +50,7 @@ if (is_android) { deps = [ ":interfaces", "//base:base", - "//mojo/common", + "//mojo/data_pipe_utils", "//mojo/public/cpp/application", ] } diff --git a/sky/services/media/ios/media_player_impl.mm b/sky/services/media/ios/media_player_impl.mm index 718dfa4a6b738..0250a93e4361e 100644 --- a/sky/services/media/ios/media_player_impl.mm +++ b/sky/services/media/ios/media_player_impl.mm @@ -4,7 +4,7 @@ #include "base/bind.h" #include "base/message_loop/message_loop.h" -#include "mojo/common/data_pipe_utils.h" +#include "mojo/data_pipe_utils/data_pipe_utils.h" #include "sky/services/media/ios/media_player_impl.h" #import diff --git a/sky/services/ns_net/BUILD.gn b/sky/services/ns_net/BUILD.gn index ab7a5eb82197f..690560416d826 100644 --- a/sky/services/ns_net/BUILD.gn +++ b/sky/services/ns_net/BUILD.gn @@ -12,7 +12,6 @@ source_set("ns_net") { deps = [ "//base:base", - "//mojo/common", "//mojo/public/cpp/application", "//mojo/services/network/public/interfaces", ] diff --git a/sky/shell/BUILD.gn b/sky/shell/BUILD.gn index 5939a85a30990..196b28d8788d4 100644 --- a/sky/shell/BUILD.gn +++ b/sky/shell/BUILD.gn @@ -7,8 +7,9 @@ common_deps = [ "//base:i18n", "//build/config/sanitizers:deps", "//dart/runtime:libdart", - "//mojo/common", + "//mojo/data_pipe_utils", "//mojo/edk/system", + "//mojo/message_pump", "//mojo/public/cpp/application", "//mojo/public/interfaces/application", "//mojo/services/asset_bundle/public/interfaces", @@ -244,6 +245,7 @@ if (is_android) { deps = common_deps + [ ":common", + "//mojo/common", "//sky/services/testing:interfaces", ] } diff --git a/sky/shell/dart/BUILD.gn b/sky/shell/dart/BUILD.gn index b4a1cf528a0e5..06d83f112a24e 100644 --- a/sky/shell/dart/BUILD.gn +++ b/sky/shell/dart/BUILD.gn @@ -14,7 +14,7 @@ source_set("dart") { "//base", "//build/config/sanitizers:deps", "//dart/runtime:libdart", - "//mojo/common", + "//mojo/data_pipe_utils", "//mojo/public/cpp/application", "//mojo/services/network/public/interfaces", "//sky/engine/tonic", diff --git a/sky/shell/dart/dart_library_provider_files.cc b/sky/shell/dart/dart_library_provider_files.cc index 948e083e7b36c..1b5e78c4d5947 100644 --- a/sky/shell/dart/dart_library_provider_files.cc +++ b/sky/shell/dart/dart_library_provider_files.cc @@ -8,7 +8,7 @@ #include "base/files/file_util.h" #include "base/strings/string_util.h" #include "base/threading/worker_pool.h" -#include "mojo/common/data_pipe_utils.h" +#include "mojo/data_pipe_utils/data_pipe_utils.h" #include "sky/engine/tonic/dart_converter.h" namespace sky { diff --git a/sky/shell/shell.cc b/sky/shell/shell.cc index 07658ad4d1e22..78e496074c567 100644 --- a/sky/shell/shell.cc +++ b/sky/shell/shell.cc @@ -10,7 +10,7 @@ #include "base/memory/discardable_memory.h" #include "base/memory/discardable_memory_allocator.h" #include "base/single_thread_task_runner.h" -#include "mojo/common/message_pump_mojo.h" +#include "mojo/message_pump/message_pump_mojo.h" #include "mojo/edk/embedder/embedder.h" #include "mojo/edk/embedder/simple_platform_support.h" #include "sky/shell/ui/engine.h" diff --git a/sky/shell/tracing_controller.h b/sky/shell/tracing_controller.h index 0c6a8bc242158..4514cc87f579b 100644 --- a/sky/shell/tracing_controller.h +++ b/sky/shell/tracing_controller.h @@ -8,7 +8,7 @@ #include "base/files/file.h" #include "base/macros.h" #include "base/memory/ref_counted_memory.h" -#include "mojo/common/data_pipe_drainer.h" +#include "mojo/data_pipe_utils/data_pipe_drainer.h" #include "mojo/public/cpp/system/data_pipe.h" #include "sky/shell/shell_view.h" diff --git a/sky/shell/ui/engine.cc b/sky/shell/ui/engine.cc index 058efdc989877..8c31caedddac4 100644 --- a/sky/shell/ui/engine.cc +++ b/sky/shell/ui/engine.cc @@ -9,7 +9,7 @@ #include "base/files/file_path.h" #include "base/threading/worker_pool.h" #include "base/trace_event/trace_event.h" -#include "mojo/common/data_pipe_utils.h" +#include "mojo/data_pipe_utils/data_pipe_utils.h" #include "mojo/public/cpp/application/connect.h" #include "services/asset_bundle/asset_unpacker_job.h" #include "sky/engine/public/platform/WebInputEvent.h" diff --git a/sky/tools/roll/patches/mojo/mojo_converters_input_events.patch b/sky/tools/roll/patches/mojo/mojo_converters_input_events.patch new file mode 100644 index 0000000000000..8434aca73621b --- /dev/null +++ b/sky/tools/roll/patches/mojo/mojo_converters_input_events.patch @@ -0,0 +1,20 @@ +diff --git b/mojo/converters/input_events/input_events_type_converters.cc a/mojo/converters/input_events/input_events_type_converters.cc +index a4f6e73..a7d6a97 100644 +--- b/mojo/converters/input_events/input_events_type_converters.cc ++++ a/mojo/converters/input_events/input_events_type_converters.cc +@@ -11,7 +11,6 @@ + #include + #endif + +-#include "base/time/time.h" + #include "mojo/converters/geometry/geometry_type_converters.h" + #include "mojo/converters/input_events/mojo_extended_key_event_data.h" + #include "mojo/services/input_events/public/interfaces/input_events.mojom.h" +@@ -278,7 +277,6 @@ scoped_ptr TypeConverter, EventPtr>::Convert( + // TODO: last flags isn't right. Need to send changed_flags. + scoped_ptr event(new ui::MouseEvent( + MojoMouseEventTypeToUIEvent(input), location, screen_location, +- base::TimeDelta::FromMilliseconds(input->time_stamp), + ui::EventFlags(input->flags), ui::EventFlags(input->flags))); + if (event->IsMouseWheelEvent()) { + // This conversion assumes we're using the mojo meaning of these diff --git a/sky/tools/roll/patches/mojo/services_keyboard.patch b/sky/tools/roll/patches/mojo/services_keyboard.patch new file mode 100644 index 0000000000000..d1180aab39137 --- /dev/null +++ b/sky/tools/roll/patches/mojo/services_keyboard.patch @@ -0,0 +1,30 @@ +diff --git a/services/keyboard/src/org/chromium/mojo/keyboard/InputConnectionAdaptor.java b/services/keyboard/src/org/chromium/mojo/keyboard/InputConnectionAdaptor.java +index 42bdd57..a3cdc61 100644 +--- a/services/keyboard/src/org/chromium/mojo/keyboard/InputConnectionAdaptor.java ++++ b/services/keyboard/src/org/chromium/mojo/keyboard/InputConnectionAdaptor.java +@@ -4,7 +4,10 @@ + + package org.chromium.mojo.keyboard; + ++import java.lang.StringBuilder; ++ + import android.view.View; ++import android.view.KeyEvent; + import android.view.inputmethod.BaseInputConnection; + import android.view.inputmethod.CompletionInfo; + import android.view.inputmethod.CorrectionInfo; +@@ -71,4 +74,14 @@ public class InputConnectionAdaptor extends BaseInputConnection { + mClient.setSelection(start, end); + return super.setSelection(start, end); + } ++ ++ // Number keys come through as key events instead of commitText!? ++ @Override ++ public boolean sendKeyEvent(KeyEvent event) { ++ if (event.getAction() == KeyEvent.ACTION_UP) { ++ // 1 appears to always be the value for newCursorPosition? ++ mClient.commitText(String.valueOf(event.getNumber()), 1); ++ } ++ return super.sendKeyEvent(event); ++ } + } diff --git a/sky/tools/roll/roll.py b/sky/tools/roll/roll.py index a066a7f7bb80b..c66fb7b868444 100755 --- a/sky/tools/roll/roll.py +++ b/sky/tools/roll/roll.py @@ -72,7 +72,21 @@ dirs_from_mojo = [ 'gpu', - 'mojo', + 'mojo/android', + 'mojo/application', + 'mojo/common', + 'mojo/converters', + 'mojo/dart', + 'mojo/data_pipe_utils', + 'mojo/edk', + 'mojo/environment', + 'mojo/gles2', + 'mojo/gpu', + 'mojo/icu', + 'mojo/java', + 'mojo/message_pump', + 'mojo/services', + 'mojo/skia', 'services/asset_bundle', 'services/keyboard', 'services/sensors',