Session Assistant.

plainbox.impl.session.assistant – session assistant

class plainbox.impl.session.assistant.SessionAssistant(app_id, app_version=None, api_version='0.99', api_flags=())[source]

Bases: object

Assisting class to simplify common testing scenarios.

The assistant acts as a middle-man between the session manager and the application. It handles all currently known stages of the testing work-flow.

Note

The assistant class assumes single-threaded applications. Classic event loop or threaded applications can be developed with a little bit of care. The main problem is that plainbox doesn’t support event loops yet. Certain blocking operations (running jobs mostly) need to be done from another thread. It is recommended to run all of plainbox in a thread (either python or native thread embedding python runtime)

A typical application flow will look like this:

  • The application calls __init__() to create a new session assistant object with its own identifier as the only argument. This lets multiple programs that use the plainbox APIs co-exists without clashes.
  • (optionally) The application can call use_alternate_repository() to change the location of the session storage repository. This is where various files are created so if you don’t want to use the default location for any reason this is the only chance you have.
  • The application selects a set of providers to load using select_providers(). Typically applications will work with a well-defined set of providers, either maintained by the same set of developers or (sometimes) by reusing some third party test providers. A small set of wild-cards are supported so that applications can load all providers from a given name-space or even all available providers.
bootstrap()[source]

Perform session bootstrap process to discover all content.

Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

The session assistant offers two mechanism for generating additional content (primarily jobs). Understanding this mechanism is important for applications that wish to display a list of jobs before the test operator finally commits to running a subset of them.

During the bootstrap phase resource jobs that are associated with job templates may generate new jobs according to the information specified in the template. In addition, local jobs can generate arbitrary (unrestricted) units. Both of those mechanism are subject to the validation system (invalid units are discarded).

When this method returns (which can take a while) the session is now ready for running any jobs.

clear_cache() → None[source]
configure_application_restart()[source]

Configure automatic restart capability.

Parameters:

cmd_callback – A callable (function or lambda) that when called with a single string argument, session_id, returns a list of strings describing how to execute the tool in order to restart a particular session.

Raises:
  • UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.
  • LookupError – If no restart strategy was explicitly configured and no strategy was found with the auto-detection process.

This method configures session assistant for automatic application restart. When a job is expected to reboot or shut down the machine but the intent is to somehow resume testing automatically after that event, test designers can use the ‘noreturn’ and ‘restartable’ flags together to indicate that the testing process is should be automatically resumed when the machine is turned on again.

The means of re-starting the testing process are unique to each operating system environment. Plainbox knows about some restart strategies internally. Applications can create additional strategies using the use_alternate_restart_strategy() method.

delete_sessions()[source]

Delete session storages.

Parameters:session_ids – A list of session ids which storages should be removed.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

Note

If the session is not found in the currently selected session repository, it is silently ignored.

export_to_file()[source]

Export the session to file using given exporter ID.

Parameters:
  • exporter_id – The identifier of the exporter unit to use. This must have been loaded into the session from an existing provider. Many users will want to load the com.canonical.palainbox:exporter provider (via load_providers().
  • option_list – List of options customary to the exporter that is being created.
  • dir_path – Path to the directory where session file should be written to. Note that the file name is automatically generated, based on creation time and type of exporter.
Returns:

Path to the written file.

Raises:
  • KeyError – When the exporter unit cannot be found.
  • OSError – When there is a problem when writing the output.
export_to_stream()[source]

Export the session to file using given exporter ID.

Parameters:
  • exporter_id – The identifier of the exporter unit to use. This must have been loaded into the session from an existing provider. Many users will want to load the com.canonical.palainbox:exporter provider (via load_providers().
  • option_list – List of options customary to the exporter that is being created.
  • stream – Stream to write the report to.
Returns:

Path to the written file.

Raises:
  • KeyError – When the exporter unit cannot be found.
  • OSError – When there is a problem when writing the output.
export_to_transport()[source]

Export the session using given exporter ID and transport object.

Parameters:
  • exporter_id – The identifier of the exporter unit to use. This must have been loaded into the session from an existing provider. Many users will want to load the com.canonical.palainbox:exporter provider (via load_providers().
  • transport – A pre-created transport object such as the CertificationTransport that is useful for sending data to the Canonical Certification Website and HEXR. This can also be any object conforming to the appropriate API.
  • options – (optional) List of options customary to the exporter that is being created.
Returns:

pass

Raises:
  • KeyError – When the exporter unit cannot be found.
  • TransportError – If the transport fails in any way:
  • UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.
filter_jobs_by_categories()[source]

Filter out jobs with categories that don’t match given ones.

Parameters:categories – A sequence of category identifiers of jobs that should stay in the todo list.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This method can be called at any time to unselect jobs that belong to a category not present in categories.

Note

Calling this method will alter the result of get_static_todo_list() and get_dynamic_todo_list().

finalize_session() → None[source]

Finish the execution of the current session.

Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

Mark the session as complete, which prohibits running (or rerunning) any job. finalize_session will be ignored if session has already been finalized; this frees applications from keeping state information in them.

finish_bootstrap()[source]

Prepare the final list of jobs to be run

Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

If the application controls individual bootstrapping jobs’ execution then it should call this method after all bootstrapping is done. XXX: this could be automated by adding some state information to SessionAssistant class, but if the app wants fine control, ilet’s let it have it.

get_bootstrap_todo_list()[source]

Get a list of ids that should be run in while bootstrapping)

Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This method, together with run_job(), can be used instead of boostrap() to have control over when bootstrapping jobs are run. E.g. to inform the user about the progress

get_canonical_certification_transport()[source]

Get a transport for the Canonical Certification website.

Parameters:
  • secure_id – The secure identifier of the machine. This is an identifier issued by Canonical. It is only applicable to machines that are tested by the Hardware Certification team.
  • staging – Flag indicating if the staging server should be used.
Returns:

A ISessionStateTransport instance with appropriate configuration. In practice the transport object should be passed to export_to_transport() and not handled in any other way.

Raises:
  • ValueError – if the secure_id is malformed.
  • UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This transport, same as the hexr transport, expects the data created by the "hexr" exporter.

get_canonical_hexr_transport()[source]

Get a transport for the Canonical HEXR website.

Parameters:staging – Flag indicating if the staging server should be used.
Returns:A ISessionStateTransport instance with appropriate configuration. In practice the transport object should be passed to export_to_transport() and not handled in any other way.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This transport, same as the certification transport, expects the data created by the "hexr" exporter.

get_category()[source]

Get the category with the given identifier.

Returns:

The Category Unit object that corresponds to the given identifier.

Raises:
  • KeyError – If no such category exists.
  • UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

Note

The returned object contains parts that may not be covered by the public api stability promise. Refer to the documentation of the CategoryUnit class for details.

get_dynamic_todo_list()[source]

Get the (dynamic) list of jobs to run.

Returns:A list of identifiers of jobs to run.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This methods can be used to obtain the sequence of jobs that are yet to be executed. The result is affected by use_alternate_selection() as well as run_job().

Jobs that cannot be started (due to failed dependencies or unsatisfied requirements) are also returned here. Any attempts to run them via run_job() will produce a correct result object with appropriate information.

Please note that returned identifiers may refer to jobs that were automatically selected via some mechanism, not necessarily a job explicitly requested by the user. Examples of such mechanisms include job dependencies, resource dependencies or mandatory jobs.

Note

It is correct and safe if applications only execute this method once and iterate over the result from start to finish, calling run_job() and use_job_result(). All dynamics of generating jobs is hidden and handled by the boostrap() method.

get_job(job_id)[source]

Get the definition of the job with the given identifier.

Returns:

The JobDefinition object that corresponds to the given identifier.

Raises:
  • KeyError – If no such job exists
  • UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

Note

The returned object contains parts that may not be covered by the public api stability promise. Refer to the documentation of the JobDefinition class for details.

get_job_state()[source]

Get the mutable state of the job with the given identifier.

Returns:

The JobState object that corresponds to the given identifier.

Raises:
  • KeyError – If no such job exists
  • UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

Note

The returned object contains parts that may not be covered by the public api stability promise. Refer to the documentation of the JobState class for details.

get_mandatory_jobs()[source]

Get the list of ids of mandatory jobs.

Returns:A list of identifiers of mandatory jobs scheduled to run.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.
get_old_sessions()[source]

Get the list of previously run sessions.

Parameters:
  • flags – Set of flags from which at least one flag must be present in the metadata of the processed session storage in order for that storage to be returned.
  • allow_not_flagged – Also return sessions that have no flags attached.
Returns:

A list of tuples containing session id and flags that were attached to that session.

Raises:

UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

get_participating_categories()[source]

Get a set of category identifiers associated with current test plan.

Returns:A list of category identifiers.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This method computes the set of category identifiers that contains each category for which at least test might be executed in this session. This set does not include boostrap jobs as they must be executed prior to actually allowing the user to know what jobs are available.

get_resumable_sessions()[source]

Check repository for sessions that could be resumed.

Returns:A generator that yields namedtuples with (id, metadata) of subsequent resumable sessions, starting from the youngest one.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This method iterates through incomplete sessions saved in the storage repository and looks for the ones that were created using the same app_id as the one currently used.

Applications can use sessions’ metadata (and the app_blob contained in them) to decide which session is the best one to propose resuming.

get_session_dir()[source]

Get the pathname of the session directory.

Returns:The string that represents the absolute pathname of the session directory. All of the files and directories inside that directory constitute session state.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

Note

The layout of the session is documented but is considered volatile at this stage. The only thing that can be done reliably is a complete archive (backup) of the directory. This is guaranteed to work.

get_session_id()[source]

Get the identifier of the session.

Returns:The string that identifies the session in the repository being used. The identifier is a short, random directory name (without the full path), relative to the session storage repository.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

Applications can use this method and some side-channel to remember the session that was executed most recently. This can be useful in resuming that session without the need to search and analyze all of the sessions in the repository.

get_static_todo_list()[source]

Get the (static) list of jobs to run.

Returns:A list of identifiers of jobs to run.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This method can be used to obtain the full sequence of jobs that are described by the test plan. The result is only influenced by use_alternate_selection(). It never grows or shrinks during execution of subsequent jobs.

Please note that returned identifiers may refer to jobs that were automatically selected via some mechanism, not necessarily a job explicitly requested by the user. Examples of such mechanisms include job dependencies, resource dependencies or mandatory jobs.

get_summary()[source]

Get a grand total statistic for the jobs that ran.

Returns:A defaultdict mapping the number of jobs that have a given outcome to the kind of outcome. E.g. {IJobResult.OUTCOME_PASS: 6, (...)}.
get_test_plan()[source]

Get the test plan with the given identifier.

Returns:

The TestPlanUnit object that corresponds to the given identifier.

Raises:
  • KeyError – If no such test plan exists
  • UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

Note

The returned object contains parts that may not be covered by the public api stability promise. Refer to the documentation of the TestPlanUnit class for details.

get_test_plans()[source]

Get a set of test plan identifiers.

Returns:A list of test plan identifiers.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This method computes the set of category identifiers that contains each category for which at least test might be executed in this session. This set does not include bootstrap jobs as they must be executed prior to actually allowing the user to know what jobs are available.

get_ubuntu_sso_oauth_transport()[source]

Get a transport for OAuth.

Parameters:

transport_details – Dictionary containing necessray transport configuration.

Raises:
  • KeyError – When transport_details is missing vital information.
  • UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.
hand_pick_jobs()[source]

Select jobs to run. Don’t use test plans.

Parameters:id_patterns – List of regex patterns that jobs’ id must match in order to be selected.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

Use this method if you want to run particular jobs from all of the loaded providers. They don’t have to be included in any test plan. There is no bootstrapping done, so templates are not intantiated, thus selection is done only among explicit jobs.

provider_selected

Basic signal that supports arbitrary listeners.

While this class can be used directly it is best used with the helper decorator Signal.define on a function or method. See the documentation for the plainbox.vendor.morris module for details.

Attr _name:Name of the signal, typically accessed via name().
Attr _listeners:
 List of signal listeners. Each item is a tuple (listener, pass_signal) that encodes how to call the listener.
remove_all_filters()[source]

Bring back original job list.

Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This method can be called to remove all filters applied from currently reigning job selection.

resume_session()[source]

Resume a session.

Parameters:

session_id – The identifier of the session to resume.

Returns:

Resumed session metadata.

Raises:
  • KeyError – If the session with a given session_id cannot be found.
  • UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This method restores internal state of the plainbox runtime as it was the last time session assistant did a checkpoint, i.e. session assistant’s clients commited any information (e.g. saves job result, runs bootstrapping, updates app blob, etc.)

run_job()[source]

Run a job with the specific identifier.

Parameters:
  • job_id – Identifier of the job to run.
  • ui – The user interface delegate to use. As a special case it can be a well-known name of a stock user interface. Currently only the ‘silent’ user interface is available.
  • native – Flag indicating that the job will be run natively by the application. Normal runner won’t be used to execute the job
Raises:
  • KeyError – If no such job exists
  • ValueError – If the well known UI name is not recognized.
  • TypeError – If the UI is not a IJobRunnerUI subclass.
  • UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.
Returns:

JobResultBuilder instance.

This method can be used to run any job available in the session (not only those jobs that are selected, or on the todo list). The result is a ResultBuilder object which can be modified if necessary. The result builder object can be also converted to a result object and fed back to the session via the use_job_result() method.

It is expected that the caller will follow this protocol for each executed job. This API complexity is required to let users interact with interactive jobs and let the application do anything it needs to to accomplish that.

select_providers()[source]

Load plainbox providers.

Parameters:
  • patterns

    The list of patterns (or just names) of providers to load.

    Note that some special provides are always loaded, regardless of if the application wants that or not. Those providers are a part of plainbox itself and are required for normal operation of the framework.

    The names may include the * character (asterisk) to indicate “any”. This includes both the namespace part and the provider name part, e.g. com.canonical.certification::* will load all of providers made by the Canonical certification team. To load everything just pass *.

  • additional_providers – A list of providers that were loaded by other means (usually in some app-custom way).
Returns:

The list of loaded providers (including plainbox providers)

Raises:
  • ValueError – If any of the patterns didn’t match any provider.
  • UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

Providers are loaded into a temporary area so that they are ready for a session that you can either create from scratch or resume one you may have created earlier. In either case, this is the first method you should call.

A provider is used to supply tests (or in general, jobs) to execute. Typically applications will have an associated, well-known provider that they wish to load.

Providers can be broken and can, in fact, load in a partially or entirely damaged state. Applications should inspect the problem list of each loaded provider to see if they wish to abort.

select_test_plan(test_plan_id)[source]

Select a test plan for execution.

Parameters:

test_plan_id – The identifier of the test plan to execute.

Raises:
  • KeyError – If the test plan with that identifier cannot be found.
  • UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

Test plans describe all of the essential details needed to execute a set of tests. Like other plainbox components each test plan has an unique identifier.

Upon making the selection the application can inspect the execution plan which is expressed as a list of jobs to execute.

session_available

Basic signal that supports arbitrary listeners.

While this class can be used directly it is best used with the helper decorator Signal.define on a function or method. See the documentation for the plainbox.vendor.morris module for details.

Attr _name:Name of the signal, typically accessed via name().
Attr _listeners:
 List of signal listeners. Each item is a tuple (listener, pass_signal) that encodes how to call the listener.
start_new_session(title: str)[source]

Create a new testing session.

Parameters:title – Title of the session.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This method can be used to create a new session. This will create some filesystem entries related to the session.

The session title should be a human-readable string, as much as the application can create one, that describes the goal of the session. Some user interfaces will display this information.

Using this method always creates a _new_ session. If the application intends to use session resuming functionality it should use other methods to see if session should be resumed instead.

update_app_blob(app_blob: bytes) → None[source]

Update custom app data and save the session in the session storage.

Parameters:app_blob – Bytes sequence containing JSON-ised app_blob object.
use_alternate_configuration(config)[source]

Use alternate configuration object.

Parameters:config – A configuration object that implements a superset of the plainbox configuration.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

Note

Please check the source code to understand which values to pass here. This method is currently experimental.

use_alternate_execution_controllers()[source]

Use alternate execution controllers.

Parameters:ctrl_setup_list – An iterable with tuples, where each tuple represents a class of controller to instantiate, together with *args and **kwargs to use when calling its __init__.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This method can be used to use any custom execution controllers to execute jobs. Normally those should be offered by the SessionDeviceContext (which is a part of the implementation) and they should be good for any use but as we learned some applications needed to offer alternate controllers.

Note

Please check the source code to understand which values to pass here. This method is currently experimental.

use_alternate_repository(pathname: str) → None[source]

Setup an alternate location for the session storage repository.

Parameters:pathname – Directory name (that is created on demand) where sessions are supposed to be stored.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This method can be used to use a non-standard repository location. This is useful for testing, where it is good to separate test sessions from any real data that the user may be using.

On some platforms, this can be also used to use a better default location. If you have to call this in your application then please open a bug. Plainbox should integrate with all the platforms correctly out of the box.

use_alternate_restart_strategy(strategy: plainbox.impl.session.restart.IRestartStrategy) → None[source]

Setup an alternate restart strategy object.

Parameters:restart_strategy – An object implementing the restart strategy interface. This object is used to prepare the system for application restart.
Raises:UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

When this method is called all automatic environment auto-detection is disabled and application restart is solely under the control of the application.

The restart interface is very simple, it is comprised of a pair of methods, IRestartStrategy.prime_application_restart() and IRestartStrategy.diffuse_application_restart(). When the application is in a state where it will soon terminate, plainbox will call the former of the two methods to _prime_ the system so that application will be re-started when the machine is started (or rebooted). When the application successfully starts, the _diffuse_ method will undo what prime did so that the application restart is a one-off action.

The primary use of this method is to let applications support environments that are not automatically handled correctly by plainbox.

use_alternate_selection()[source]

Setup an alternate set of jobs to run.

Parameters:

selection – A sequence of identifiers of jobs that the user would like to run.

Raises:
  • KeyError – If the selection refers to unknown jobs.
  • UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This method can be called at any time to change the _selection_ of jobs that the user wishes to run. Any job present in the session can be used.

By default, after selecting a test plan, the job selection includes all of the jobs described by that test plan.

Note

Calling this method will alter the result of get_static_todo_list() and get_dynamic_todo_list().

use_job_result()[source]

Feed job result back to the session.

Parameters:
  • job_id – Identifier of the job the result is for
  • result – The result object that contains all the information about running that job. You can obtain one from a result builder by calling the builder.get_result() method.
Raises:

UnexpectedMethodCall – If the call is made at an unexpected time. Do not catch this error. It is a bug in your program. The error message will indicate what is the likely cause.

This method is meant to complement run_job(). They are split so that the application can freely modify the result object in a single _atomic_ operation.

Note that running a single job and presenting the result back to the session may unlock or lock other jobs. For example, running a resource job may allow or disallow another job to run (via requirement programs). Similar system exists for job dependencies. A job that depends on another job will not be able to run if any of its dependencies did not complete successfully.

plainbox.impl.session.assistant.get_all_sa_flags()[source]
comments powered by Disqus