def test_log_during_teardown(self): message = 'hello' def teardown_log(test): test.logger.info(message) group = phase_group.PhaseGroup(main=[blank_phase], teardown=[teardown_log]) test = openhtf.Test(group) test.configure(default_dut_id='dut', ) executor = test_executor.TestExecutor(test.descriptor, 'uid', start_phase, test._test_options) executor.start() executor.wait() record = executor.test_state.test_record self.assertEqual(record.outcome, Outcome.PASS) log_records = [ log_record for log_record in record.log_records if log_record.message == message ] self.assertTrue(log_records) executor.close()
def test_all_fail_subtest__not_in_subtest(self): test_rec = yield htf.Test( fail_phase, phase_branches.PhaseFailureCheckpoint.all_previous( 'all_subtest', action=htf.PhaseResult.FAIL_SUBTEST), error_phase) self.assertTestError(test_rec) self.assertTestOutcomeCode(test_rec, 'InvalidPhaseResultError') self.assertPhasesOutcomeByName(test_record.PhaseOutcome.FAIL, test_rec, 'fail_phase') self.assertEqual([ test_record.CheckpointRecord( name='all_subtest', action=htf.PhaseResult.FAIL_SUBTEST, conditional=phase_branches.PreviousPhases.ALL, subtest_name=None, result=phase_executor.PhaseExecutionOutcome( phase_executor.ExceptionInfo( phase_executor.InvalidPhaseResultError, mock.ANY, mock.ANY)), evaluated_millis=htf_test.VALID_TIMESTAMP), ], test_rec.checkpoints)
def test_pass(self): test_rec = yield htf.Test( phase0, phase_branches.DiagnosisCheckpoint( 'diag_pass', phase_branches.DiagnosisCondition.on_all( BranchDiagResult.NOT_SET)), phase1) self.assertTestPass(test_rec) self.assertPhasesOutcomeByName(test_record.PhaseOutcome.PASS, test_rec, 'phase0', 'phase1') self.assertEqual([ test_record.CheckpointRecord( name='diag_pass', action=htf.PhaseResult.STOP, conditional=phase_branches.DiagnosisCondition( phase_branches.ConditionOn.ALL, (BranchDiagResult.NOT_SET, )), subtest_name=None, result=phase_executor.PhaseExecutionOutcome( htf.PhaseResult.CONTINUE), evaluated_millis=htf_test.VALID_TIMESTAMP), ], test_rec.checkpoints)
def test_cancel_phase(self): @openhtf.PhaseOptions() def cancel_phase(): # See above cancel_phase for explanations. _abort_executor_in_thread(executor.abort) ev = threading.Event() group = phase_group.PhaseGroup(main=[cancel_phase], teardown=[lambda: ev.set()]) # pylint: disable=unnecessary-lambda test = openhtf.Test(group) test.configure(default_dut_id='dut', ) executor = test_executor.TestExecutor(test.descriptor, 'uid', start_phase, test._test_options) executor.start() executor.wait() record = executor.test_state.test_record self.assertEqual(record.phases[0].name, start_phase.name) self.assertLessEqual(record.start_time_millis, util.time_millis()) self.assertLessEqual(record.start_time_millis, record.end_time_millis) self.assertLessEqual(record.end_time_millis, util.time_millis()) # Teardown function should be executed. self.assertTrue(ev.wait(1)) executor.close()
def test_failure_during_start_phase_plug_init(self): def never_gonna_run_phase(): ev2.set() ev = threading.Event() ev2 = threading.Event() test = openhtf.Test(never_gonna_run_phase) executor = core.TestExecutor(test.descriptor, 'uid', fail_plug_phase, 'dut', teardown_function=lambda: ev.set()) # pylint: disable=unnecessary-lambda executor.start() executor.wait() record = executor.test_state.test_record self.assertEqual(record.outcome, Outcome.ERROR) self.assertEqual(record.outcome_details[0].code, FailedPlugError.__name__) self.assertEqual(record.outcome_details[0].description, FAIL_PLUG_MESSAGE) # Teardown function should *NOT* be executed. self.assertFalse(ev.is_set()) self.assertFalse(ev2.is_set())
def test_ping(test, pinger, count): """This tests that we can ping a host. The plug, pinger, is expected to be replaced at test creation time, so the placeholder property was used instead of the class directly. """ start = time.time() retcode = pinger.run(count) elapsed = time.time() - start test.measurements['total_time_%s_%s' % (pinger.host, count)] = elapsed test.measurements.retcode = retcode if __name__ == '__main__': # We instantiate our OpenHTF test with the phases we want to run as args. # We're going to use these these plugs to create all our phases using only 1 # written phase. ping_plugs = [ PingGoogle, PingDnsA, PingDnsB, ] test = htf.Test(*(test_ping.with_plugs(pinger=plug).with_args(count=2) for plug in ping_plugs)) # Unlike hello_world.py, where we prompt for a DUT ID, here we'll just # use an arbitrary one. test.execute(test_start=lambda: 'MyDutId')
def main(): test = htf.Test(HelloWorldPhase) test.configure(default_dut_id=DEFAULT_DUT_ID) test.add_output_callbacks( CustomOutputToJSON('./{dut_id}.hello_world.json', indent=2)) test.execute(test_start=user_input.prompt_for_test_start())
# is the recommended way to do any logging within test phases (this is also # how to get logs to show up in the frontend). test.logger.info('Hello World!') # As described above, this is how measurements are set. The value that has # been set can also be accessed, but should only be set once (this will be # enforced in the future, for now it's best-practice). test.measurements.hello_world_measurement = 'Hello Again!' if __name__ == '__main__': # We instantiate our OpenHTF test with the phases we want to run as args. # Multiple phases would be passed as additional args, and additional # keyword arguments may be passed as well. See other examples for more # complex uses. test = htf.Test(hello_world) # In order to view the result of the test, we have to output it somewhere, # and a local JSON file is a convenient way to do this. Custom output # mechanisms can be implemented, but for now we'll just keep it simple. # This will always output to the same ./hello_world.json file, formatted # slightly for human readability. test.add_output_callbacks( json_factory.OutputToJSON('./{dut_id}.hello_world.json', indent=2)) # prompt_for_test_start prompts the operator for a DUT ID, a unique identifier # for the DUT (Device Under Test). OpenHTF requires that a DUT ID is set # each time a test is executed. It may be set programmatically, but the # simplest way to get one is to prompt the user for it. If test_start is # not provided, the test will start immediately and assume the DUT ID will # be set later (OpenHTF will raise an exception when the test completes if
def testStringFromTestRecord_SuccessfullyConvertsTestFailurePhaseColored( self): record = self.execute_phase_or_test(openhtf.Test(PhaseWithFailure)) self.assertEqual( text.StringFromTestRecord(record, colorize_text=True).count(_RED), 5)
def test_plug_map(self): test = openhtf.Test(phase_one, phase_two) self.assertIn(self.test_plug_type, test.descriptor.plug_types)
def testNotCaptured(self): htf.conf.load(capture_source=False) test = htf.Test(phase) phase_descriptor = test.descriptor.phases[0] self.assertEquals(phase_descriptor.code_info.name, '')
test.measurements.dimensions[dim] = 1 << dim for x, y, z in zip(range(1, 5), range(21, 25), range(101, 105)): test.measurements.lots_of_dims[x, y, z] = x + y + z def attachments(test): test.Attach('test_attachment', 'This is test attachment data.') test.AttachFromFile('example_attachment.txt') if __name__ == '__main__': test = openhtf.Test( hello_world, set_measurements, dimensions, attachments, # Some metadata fields, these in particular are used by mfg-inspector, # but you can include any metadata fields. test_name='MyTest', test_description='OpenHTF Example Test', test_version='1.0.0') test.AddOutputCallbacks( json_factory.OutputToJSON('./%(dut_id)s.%(start_time_millis)s.json', indent=4)) #test.AddOutputCallbacks(mfg_inspector.OutputToTestRunProto( # './%(dut_id)s.%(start_time_millis)s.pb')) # Example of how to upload to mfg-inspector. Replace filename with your # JSON-formatted private key downloaded from Google Developers Console # when you created the Service Account you intend to use, or name it # 'my_private_key.json'. #if os.path.isfile('my_private_key.json'): # with open('my_private_key.json', 'r') as json_file:
def get_test(): return htf.Test(hello_world, inline_phase, lots_of_measurements)
def testNotCaptured(self): htf.conf.load(capture_source=False) test = htf.Test(phase) phase_descriptor = typing.cast(htf.PhaseDescriptor, test.descriptor.phase_sequence.nodes[0]) self.assertEqual(phase_descriptor.code_info.name, '')
test.logger.info('test ATSC chip presence') ## ATSC chip test cmd = [joker_tv_path, '-d 11 -f 150000000'] p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) time.sleep(5) os.system('killall joker-tv') out, err = p.communicate() counter = 0 for line in out.splitlines(): if line.startswith('INFO: status=11 (NOLOCK) ucblocks=255'): counter += 1 test.logger.info('ATSC: counter %d' % counter) if counter < 5: test.logger.info('ATSC: counter out of range. ATSC chip error !') raise test.measurements.jokertv_atsc_measurement = 'Done' if __name__ == '__main__': conf.load(station_server_port='4444') with station_server.StationServer() as server: web_launcher.launch('http://localhost:4444') while 1: test = htf.Test(jokertv_fpga, jokertv_cam, jokertv_sat, jokertv_ter, jokertv_dtmb, jokertv_atsc) test.add_output_callbacks(server.publish_final_state) test.execute(test_start=user_input.prompt_for_test_start())
time.sleep(1) test.measurements.level_some = 8 time.sleep(1) test.measurements.level_all = 9 time.sleep(1) @measures( Measurement('dimensions').WithDimensions(UOM['HERTZ']), Measurement('lots_of_dims').WithDimensions( UOM['HERTZ'], UOM['BYTE'], UOM['RADIAN'])) def dimensions(test): for dim in range(5): test.measurements.dimensions[dim] = 1 << dim for x, y, z in zip(range(1, 5), range(21, 25), range (101, 105)): test.measurements.lots_of_dims[x, y, z] = x + y + z def attachments(test): test.Attach('test_attachment', 'This is test attachment data.') with tempfile.NamedTemporaryFile() as f: f.write('This is a file attachment') f.flush() test.AttachFromFile(f.name) if __name__ == '__main__': test = openhtf.Test(hello_world, set_measurements, dimensions, attachments) test.AddOutputCallback(OutputToJSON( './%(dut_id)s.%(start_time_millis)s', indent=4)) test.Execute(test_start=triggers.PromptForTestStart())
# total of three times: two fails followed by a success @plugs.plug(test_plug=FailTwicePlug) def phase_repeat(test, test_plug): try: test_plug.run() except: print "Error in phase_repeat, will retry" return openhtf.PhaseResult.REPEAT print "Completed phase_repeat" # This phase demonstrates repeating a phase based upon a result returned from a # plug. In this case the plug always returns an invalid result so we re-run # the phase. To prevent retrying in an infinite loop, we use repeat_limit to # limit the number of retries. @openhtf.PhaseOptions(repeat_limit=5) @plugs.plug(test_plug=FailAlwaysPlug) def phase_repeat_with_limit(test, test_plug): result = test_plug.run() if not result: print "Invalid result in phase_repeat_with_limit, will retry" return openhtf.PhaseResult.REPEAT if __name__ == '__main__': test = openhtf.Test(phase_repeat, phase_repeat_with_limit) test.execute(test_start=lambda: 'RepeatDutID')
def testCaptured(self): htf.conf.load(capture_source=True) test = htf.Test(phase) phase_descriptor = test.descriptor.phases[0] self.assertEqual(phase_descriptor.code_info.name, phase.__name__)
test.logger.info('This is what a dataframe looks like:\n%s', power_df) test.measurements['average_voltage'] = power_df['V'].mean() # We can convert the dataframe to a numpy array as well power_array = power_df.as_matrix() test.logger.info('This is the same data in a numpy array:\n%s', power_array) test.measurements['average_current'] = power_array.mean(axis=0)[2] # Finally, let's estimate the resistance test.measurements['resistance'] = (test.measurements['average_voltage'] / test.measurements['average_current']) if __name__ == '__main__': # We instantiate our OpenHTF test with the phases we want to run as args. test = htf.Test(hello_phase, again_phase, lots_of_measurements, measure_seconds, inline_phase, multdim_measurements) # In order to view the result of the test, we have to output it somewhere, # and a local JSON file is a convenient way to do this. Custom output # mechanisms can be implemented, but for now we'll just keep it simple. # This will always output to the same ./measurements.json file, formatted # slightly for human readability. test.add_output_callbacks( json_factory.OutputToJSON('./measurements.json', indent=2)) # Unlike hello_world.py, where we prompt for a DUT ID, here we'll just # use an arbitrary one. test.execute(test_start=lambda: 'MyDutId')
def test_passing_test(self): test_record = yield openhtf.Test(phase_retval(None)) self.assertTestPass(test_record)
del expected_retcode # Not used in the phase, only used by a measurement start = time.time() retcode = pinger.run(count) elapsed = time.time() - start test.measurements['total_time_%s_%s' % (pinger.host, count)] = elapsed test.measurements.retcode = retcode if __name__ == '__main__': # We instantiate our OpenHTF test with the phases we want to run as args. # We're going to use these these plugs to create all our phases using only 1 # written phase. ping_plugs = [ PingGoogle, PingDnsA, PingDnsB, ] phases = [ test_ping.with_plugs(pinger=plug).with_args(count=2, expected_retcode=0) for plug in ping_plugs ] test = htf.Test(*phases) # Unlike hello_world.py, where we prompt for a DUT ID, here we'll just # use an arbitrary one. test.execute(test_start=lambda: 'MyDutId')
def long_running_phase(test): # A long running phase could be something like a hardware burn-in. This # phase should not run if previous phases have failed, so we make sure # checkpoint phase is run right before this phase. for i in range(10): test.logger.info('Still running....') time.sleep(10) test.logger.info('Done with long_running_phase') if __name__ == '__main__': # We instantiate our OpenHTF test with the phases we want to run as args. test = htf.Test( measurements_example.hello_phase, measurements_example.again_phase, failing_phase, measurements_example.lots_of_measurements, checkpoints.checkpoint(), long_running_phase, ) # In order to view the result of the test, we have to output it somewhere, # outputting to console is an easy way to do this. test.add_output_callbacks(console_summary.ConsoleSummary()) # The complete summary is viable in json, including the measurements # included in measurements_example.lots_of_measurements. test.add_output_callbacks( json_factory.OutputToJSON('./checkpoints.json', indent=2)) # Unlike hello_world.py, where we prompt for a DUT ID, here we'll just # use an arbitrary one.
def test_wrong_measured_value(self): test_rec = yield openhtf.Test(phase_retval(None)) self.assertMeasured(test_rec, 'test_measurement', 0xBAD)
def test_call_skips_phase_result_override(self): phase = openhtf.PhaseOptions( stop_on_measurement_fail=False)(partially_passing_phase) record = self.execute_phase_or_test(openhtf.Test(phase, passing_phase)) self.assertEqual(record.outcome, test_record.Outcome.FAIL) self.assertEqual(record.phases[-1].name, passing_phase.name)
def test_errors(self): phase_record = yield raising_phase self.assertPhaseError(phase_record, DummyError) test_record = yield openhtf.Test(raising_phase) self.assertTestError(test_record, DummyError)
def test_execute_phase_or_test_test_with_no_patched_plugs(self): test_record = self.execute_phase_or_test( openhtf.Test(test_phase_with_shameless_plug)) self.assertTestPass(test_record)
def test_plug_type_map(self): test = openhtf.Test(phase_one, phase_two) self.assertIn(type(self.test_plug), test.plug_type_map.itervalues())
def test_patch_plugs_test(self, mock_plug): mock_plug.do_stuff.return_value = _DO_STUFF_RETVAL test_record = yield openhtf.Test(phase_retval(None), test_phase) self._run_my_phase_in_test_asserts(mock_plug, test_record)
@htf.TestPhase(run_if=lambda: False) def skip_phase(test): """Don't run this phase.""" def teardown(test): test.logger.info('Running teardown') if __name__ == '__main__': test = htf.Test( hello_world, set_measurements, dimensions, attachments, skip_phase, measures_with_args.with_args(min=2, max=4), # Some metadata fields, these in particular are used by mfg-inspector, # but you can include any metadata fields. test_name='MyTest', test_description='OpenHTF Example Test', test_version='1.0.0') test.add_output_callbacks( callbacks.OutputToFile( './{dut_id}.{metadata[test_name]}.{start_time_millis}.pickle')) test.add_output_callbacks( json_factory.OutputToJSON( './{dut_id}.{metadata[test_name]}.{start_time_millis}.json', indent=4)) # Example of how to output to testrun protobuf format. #test.add_output_callbacks(
# @htf.plug(tester=TestPlug) # def test_plug(test, tester): # messages = ["hola", "hi", "you're welcome"] # to_person = ['name_' + str(val) for val in range(3)] # Generate names # for msg, to_ in zip(messages, to_person): # rsp_t = tester.sayHello(to_) # tester.sendMessage(msg) # This one since the plug is directly where I'm running # the test if can be imported without any paths issues. # I sugges creating plugs in the same location # Test in the same location and after # we moved them to the plugs for openHTF @htf.plug(chamber=ChamberTe1007c) def test_vdivider(test, chamber): messages = ["hola", "hi", "you're welcome"] to_person = ['name_' + str(val) for val in range(3)] # Generate names for msg, to_ in zip(messages, to_person): rsp_t = chamber.setTemperature(to_) chamber.setHumidity(msg) if __name__ == '__main__': # We instantiate our OpenHTF test with the phases we want to run as args. # Multiple phases would be passed as additional args, and additional # keyword arguments may be passed as well. See other examples for more # complex uses. test = htf.Test(test_vdivider) # Names of the tests that I want to test.execute(test_start=user_input.prompt_for_test_start())