<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Test environment API - TestEnv
The test environment is primarily defined by the target configuration (see conf below).
One can also pass the test configuration - definining which software setups are needed on the hardware target, and a location for the results of the experiments.
Parameters
Step1:  Test environment setup
Target configuration
Step2:  Test environment initialisation
Step3:  Attributes
The initialisation of the test environment pre-initialises some useful environment variables.
This is some of the information available via the TestEnv object
Step4:  Functions
Some methods are also exposed to test developers which could be used to ease the creation of tests.
These are some of the methods available
Step5:  Attributes
Step6:  Attributes
Step7:  Attribute
<ASSISTANT_TASK:>
Python Code:
# One initial cell for imports
import json
import time
import os
import logging
from conf import LisaLogging
LisaLogging.setup()
# For debug information use:
# LisaLogging.setup(level=logging.DEBUG)
Explanation: Test environment API - TestEnv
The test environment is primarily defined by the target configuration (see conf below).
One can also pass the test configuration - definining which software setups are needed on the hardware target, and a location for the results of the experiments.
Parameters:
 - target configuration
 - test configuration - more information on this can be found in examples/utils/executor_example.ipynb
 - wipe - if to clean up all previous content from the results folder
 - force new - if to create a new TestEnv object even if there is one available
End of explanation
# Setup a target configuration
conf = {
    # Platform
    "platform"    : "linux",
    # Board
    "board"       : "juno",
    # Login credentials
    "host"        : "192.168.0.1",
    "username"    : "root",
    # You can specify either a password or keyfile
    "password"    : "juno",
    # "keyfile"   : "/complete/path/of/your/keyfile",
    # Tools to deploy
    "tools" : [ "rt-app", "taskset" ],
    "tftp"  : {
        "folder"    : "/var/lib/tftpboot/",
        "kernel"    : "Image",
        "dtb"       : "juno.dtb"
    },
    #"ping_time" : "15",
    #"reboot_time" : "180",
    # RTApp calibration values (comment to let LISA do a calibration run)
    "rtapp-calib" :  {
        "0": 358, "1": 138, "2": 138, "3": 357, "4": 359, "5": 355
    },
    # FTrace configuration
    "ftrace" : {
         "events" : [
             "cpu_idle",
             "sched_switch",
         ],
         "buffsize" : 10240,
    },
    
    # Where results are collected
    "results_dir" : "TestEnvExample",
    #"__features__" : "no-kernel no-reboot"
}
Explanation: Test environment setup
Target configuration:
platform - the currently supported boards are:
        - linux - accessed via SSH connection
        - android - accessed via ADB connection
        - host - ran on local host
board - the currently supported boards are:
        - juno - target is a JUNO board
        - tc2 - target is a TC2 board
        - oak - target is MT8173 platform model
        - pixel - target is a Pixel device
        - hikey - target is a Hikey development platform
        - nexus5x - target is a Nexus 5X device
host - target IP or MAC address
device - target Android device ID
port - port for Android connection - default port is 5555
ANDROID_HOME - path to android-sdk-linux
username
password
keyfile - you can either specify a password or a keyfile
rtapp-calib - these values are not supposed to be specified at the first run on a target.
      After the first run, it's best to fill this array with values reported in the log messges for
      your specific target, for these not to be obtained again.
tftp - tftp server from where the target gets kernel/dtb images at each boot
modules - devlib modules to be enabled
exclude_modules - devlib modules to be disabled
tools - binary tools (available under ./tools/$ARCH/) to install by default
ping_time - wait time before trying to access the target after reboot
reboot_time - maximum time to wait after rebooting the target
features - list of test environment features to enable
        - no-kernel - do not deploy kernel/dtb images
        - no-reboot - do not force reboot the target at each configuration change
        - debug - enable debugging messages
ftrace - ftrace configuration
events
functions
buffsize
results_dir - location of results of the experiments
End of explanation
from env import TestEnv
# Initialize a test environment using the provided configuration
te = TestEnv(conf)
Explanation: Test environment initialisation
End of explanation
# The complete configuration of the target we have configured
print json.dumps(te.conf, indent=4)
# Last configured kernel and DTB image
print te.kernel
print te.dtb
# The IP and MAC address of the target
print te.ip
print te.mac
# A full platform descriptor
print json.dumps(te.platform, indent=4)
# This is a pre-created folder to host the tests results generated using this
# test environment. Notice that the suite could add additional information
# in this folder, like for example a copy of the target configuration
# and other target specific collected information.
te.res_dir
# The working directory on the target
te.workdir
# The target topology, which can be used to build BART assertions
te.topology
Explanation: Attributes
The initialisation of the test environment pre-initialises some useful environment variables.
This is some of the information available via the TestEnv object:
End of explanation
# Calibrate RT-App (if required) and get the most updated calibration value
te.calibration()
# Generate a JSON file with the complete platform description
te.platform_dump(dest_dir='/tmp')
# Force a reboot of the target (and wait specified [s] before reconnect)
# Keep in mind that a reboot can be disabled from __features__ in the target configuration
te.reboot(reboot_time=360, ping_time=15)
# Resolve a MAC address into an IP address
te.resolv_host(host='00:02:F7:00:5A:5B')
# Copy the specified file into the TFTP server folder defined by configuration
te.tftp_deploy('/etc/group')
Explanation: Functions
Some methods are also exposed to test developers which could be used to ease the creation of tests.
These are some of the methods available:
End of explanation
# Run a command on the target
te.target.execute("echo -n 'Hello Test Environment'", as_root=False)
# Spawn a command in background on the target
te.target.kick_off("sleep 10", as_root=True)
# Acces to many target specific information
print "ABI                 : ", te.target.abi
print "big Core Family     : ", te.target.big_core
print "LITTLE Core Family  : ", te.target.little_core
print "CPU's Clusters IDs  : ", te.target.core_clusters
print "CPUs type           : ", te.target.core_names
# Access to big.LITTLE specific information
print "big CPUs IDs        : ", te.target.bl.bigs
print "LITTLE CPUs IDs     : ", te.target.bl.littles
print "big CPUs freqs      : {}".format(te.target.bl.get_bigs_frequency())
print "big CPUs governor   : {}".format(te.target.bl.get_bigs_governor())
Explanation: Attributes: target
Access to the devlib API
A special attribute of TestEnv is target, which represents a devlib instance. Using the target attribute we have access to the full set of devlib provided functionalities. A small set of these are exemplified below. For a more extensive set check the examples/devlib notebooks.
End of explanation
# Reset and sample energy counters
te.emeter.reset()
nrg = te.emeter.sample()
nrg = json.dumps(te.emeter.sample(), indent=4)
print "First read: ", nrg
time.sleep(2)
nrg = te.emeter.sample()
nrg = json.dumps(te.emeter.sample(), indent=4)
print "Second read: ", nrg
Explanation: Attributes: emeter (energy meter)
In order to sample energy from the target:
End of explanation
# Configure a specific set of events to trace
te.ftrace_conf(
    {                                                                                                                                             
         "events" : [                                                                                                                                            
             "cpu_idle",                                                                                                                                         
             "cpu_capacity",
             "cpu_frequency",
             "sched_switch",
         ],                                                                                                                                                      
         "buffsize" : 10240                                                                                                                                      
    }
)
# Start/Stop a FTrace session
te.ftrace.start()
te.target.execute("uname -a")
te.ftrace.stop()
# Collect and visualize the trace
trace_file = os.path.join(te.res_dir, 'trace.dat')
te.ftrace.get_trace(trace_file)
# There might be a different display value on your machine
# Check by issuing "echo $DISPLAY" in the LISA VM
output = os.popen("DISPLAY=:10.0 kernelshark {}".format(trace_file))
Explanation: Attribute: ftrace
You can configure FTrace for a specific experiment using the following:
End of explanation
<END_TASK>