File: context.py

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (138 lines) | stat: -rw-r--r-- 3,625 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# Copyright 2022 the V8 project 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 signal
import subprocess
import sys

from contextlib import contextmanager

from ..local.android import Driver
from .command import (
    AndroidCommand,
    IOSCommand,
    PosixCommand,
    WindowsCommand,
    terminate_process_windows)
from .pool import DefaultExecutionPool
from .process_utils import EMPTY_PROCESS_LOGGER, PROCESS_LOGGER
from ..testproc.util import list_processes_linux


class DefaultOSContext:

  def __init__(self, command, pool=None):
    self.command = command
    self.pool = pool or DefaultExecutionPool(self)

  @contextmanager
  def handle_context(self, options):
    yield

  def list_processes(self):
    return []

  def terminate_process(self, process):
    pass

  def platform_shell(self, shell, args, outdir):
    return outdir.resolve() / shell

  @property
  def device_type(self):
    return None


class DesktopContext(DefaultOSContext):

  @contextmanager
  def handle_context(self, options):
    log_path = options.log_system_memory
    logger = PROCESS_LOGGER if log_path else EMPTY_PROCESS_LOGGER
    with logger.log_system_memory(log_path):
      yield


class PosixContext(DesktopContext):

  def __init__(self):
    super().__init__(PosixCommand)

  def list_processes(self):
    return list_processes_linux()

  def terminate_process(self, process):
    os.kill(process.pid, signal.SIGTERM)


class WindowsContext(DesktopContext):

  def __init__(self):
    super().__init__(WindowsCommand)

  def terminate_process(self, process):
    terminate_process_windows(process)

  def platform_shell(self, shell, args, outdir):
    return outdir.resolve() / f'{shell}.exe'


class AndroidOSContext(DefaultOSContext):

  def __init__(self):
    super().__init__(AndroidCommand)

  @contextmanager
  def handle_context(self, options):
    try:
      AndroidCommand.driver = Driver.instance(options.device)
      yield
    finally:
      AndroidCommand.driver.tear_down()

  @property
  def device_type(self):
    return AndroidCommand.driver.device_type


class IOSContext(DefaultOSContext):

  def __init__(self):
    super().__init__(IOSCommand)

  def terminate_process(self, process):
    os.kill(process.pid, signal.SIGTERM)

  def platform_shell(self, shell, appargs, outdir):
    # Rather than having to use a physical device (iPhone, iPad, etc), we use
    # the iOS Simulator for the test runners in order to ease the job of
    # builders and testers.
    # At the moment Chromium's iossim tool is being used, which is a wrapper
    # around 'simctl' macOS command utility.
    iossim = outdir.resolve() / "iossim -d 'iPhone X' "

    if isinstance(appargs, list):
      appargs = ' '.join(map(str, appargs))
    if appargs != "":
      iossim = f'{iossim}-c '
      appargs = '\"' + appargs + '\"'
    app = outdir.resolve() / f'{shell}.app'
    return f'{iossim}{appargs} {app}'

# TODO(liviurau): Add documentation with diagrams to describe how context and
# its components gets initialized and eventually teared down and how does it
# interact with both tests and underlying platform specific concerns.
def find_os_context_factory(target_os):
  registry = dict(
      android=AndroidOSContext, ios=IOSContext, windows=WindowsContext)
  return registry.get(target_os, PosixContext)


@contextmanager
def os_context(target_os, options):
  factory = find_os_context_factory(target_os)
  context_instance = factory()
  with context_instance.handle_context(options):
    yield context_instance