def test_constraints(self, ports): a, b = ports self.expectThat(a, GreaterThan(0)) self.expectThat(a, LessThan(65536)) self.expectThat(b, GreaterThan(0)) self.expectThat(b, LessThan(65536)) self.expectThat(a, Not(Equals(b)))
def test_sample_binary_packages__constant_number_sql_queries(self): # Retrieving # DistributionSourcePackageRelease.sample_binary_packages and # accessing the property "summary" of its items requires a # constant number of SQL queries, regardless of the number # of existing binary package releases. self.makeBinaryPackageRelease() self.updateDistroSeriesPackageCache() with StormStatementRecorder() as recorder: for ds_package in self.dsp_release.sample_binary_packages: ds_package.summary self.assertThat(recorder, HasQueryCount(LessThan(5))) self.assertEqual(1, self.dsp_release.sample_binary_packages.count()) for iteration in range(5): self.makeBinaryPackageRelease() self.updateDistroSeriesPackageCache() with StormStatementRecorder() as recorder: for ds_package in self.dsp_release.sample_binary_packages: ds_package.summary self.assertThat(recorder, HasQueryCount(LessThan(5))) self.assertEqual(6, self.dsp_release.sample_binary_packages.count()) # Even if the cache is not updated for binary packages, # DistributionSourcePackageRelease objects do not try to # retrieve DistroSeriesPackageCache records if they know # that such records do not exist. for iteration in range(5): self.makeBinaryPackageRelease() with StormStatementRecorder() as recorder: for ds_package in self.dsp_release.sample_binary_packages: ds_package.summary self.assertThat(recorder, HasQueryCount(LessThan(5))) self.assertEqual(11, self.dsp_release.sample_binary_packages.count())
def test_rough_length_decorated_result_set(self): # StormRangeFactory.rough_length can handle DecoratedResultSets. resultset = self.makeDecoratedStormResultSet() range_factory = StormRangeFactory(resultset) estimated_length = range_factory.rough_length self.assertThat(estimated_length, LessThan(10)) self.assertThat(estimated_length, Not(LessThan(1)))
def test_getPrecachedPersonsFromIDs(self): # The getPrecachedPersonsFromIDs() method should only make one # query to load all the extraneous data. Accessing the # attributes should then cause zero queries. person_ids = [self.factory.makePerson().id for i in range(3)] with StormStatementRecorder() as recorder: persons = list( self.person_set.getPrecachedPersonsFromIDs( person_ids, need_karma=True, need_ubuntu_coc=True, need_location=True, need_archive=True, need_preferred_email=True, need_validity=True)) self.assertThat(recorder, HasQueryCount(LessThan(2))) with StormStatementRecorder() as recorder: for person in persons: person.is_valid_person person.karma person.is_ubuntu_coc_signer person.location, person.archive person.preferredemail self.assertThat(recorder, HasQueryCount(LessThan(1)))
def test_mismatch(self): matcher = HasQueryCount(LessThan(2)) collector = RequestTimelineCollector() collector.count = 2 collector.queries = [ (0, 1, "SQL-main-slave", "SELECT 1 FROM Person", None), (2, 3, "SQL-main-slave", "SELECT 1 FROM Product", None), ] mismatch = matcher.match(collector) self.assertThat(mismatch, Not(Is(None))) details = mismatch.get_details() lines = [] for name, content in details.items(): self.assertEqual("queries", name) self.assertEqual("text", content.content_type.type) lines.append(''.join(content.iter_text())) separator = "-" * 70 expected_lines = [ "0-1@SQL-main-slave SELECT 1 FROM Person\n" + separator + "\n" + "2-3@SQL-main-slave SELECT 1 FROM Product\n" + separator, ] self.assertEqual(expected_lines, lines) self.assertEqual( "queries do not match: %s" % (LessThan(2).match(2).describe(),), mismatch.describe())
def test_run_environment(self, run_mock): plugin = colcon.ColconPlugin("test-part", self.properties, self.project) with mock.patch.object(plugin, "_source_setup_sh", wraps=plugin._source_setup_sh) as sh_mock: # Joining and re-splitting to get hacked script in there as well environment = "\n".join(plugin.env(plugin.installdir)).split("\n") sh_mock.assert_called_with(plugin.installdir) underlay_setup = os.path.join(plugin.options.colcon_rosdistro, "setup.sh") overlay_setup = os.path.join("snap", "setup.sh") # Verify that LD_LIBRARY_PATH was set before any setup.sh is sourced. Also # verify that the underlay setup is sourced before the overlay. ld_library_path_index = [ i for i, line in enumerate(environment) if "LD_LIBRARY_PATH" in line ][0] underlay_source_setup_index = [ i for i, line in enumerate(environment) if underlay_setup in line ][0] overlay_source_setup_index = [ i for i, line in enumerate(environment) if overlay_setup in line ][0] self.assertThat(ld_library_path_index, LessThan(underlay_source_setup_index)) self.assertThat(underlay_source_setup_index, LessThan(overlay_source_setup_index))
def test_set_diffing_smart(self): """ Small modifications to sets have diffs that are small. Their reverse is also small. """ # Any Application with a large set of ports will do, just use # hypothesis for convenience of generating a large number of ports on # an application. application = application_strategy(min_number_of_ports=1000).example() new_ports = list( Port(internal_port=i, external_port=i) for i in xrange(4)) a = reduce(lambda x, y: x.transform(['ports'], lambda x: x.add(y)), new_ports, application) encoded_application = wire_encode(application) diff = create_diff(application, a) encoded_diff = wire_encode(diff) self.assertThat(len(encoded_diff), LessThan(len(encoded_application) / 2)) self.assertThat( wire_decode(encoded_diff).apply(application), Equals(a)) removal_diff = create_diff(a, application) encoded_removal_diff = wire_encode(removal_diff) self.assertThat(len(encoded_removal_diff), LessThan(len(encoded_application) / 2)) self.assertThat( wire_decode(encoded_removal_diff).apply(a), Equals(application))
def test_deployment_diffing_smart(self): """ Small modifications to a deployment have diffs that are small. Their reverse is also small. """ # Any large deployment will do, just use hypothesis for convenience of # generating a large deployment. deployment = deployment_strategy(min_number_of_nodes=90).example() new_nodes = list(Node(uuid=uuid4()) for _ in xrange(4)) d = reduce(lambda x, y: x.update_node(y), new_nodes, deployment) encoded_deployment = wire_encode(deployment) diff = create_diff(deployment, d) encoded_diff = wire_encode(diff) self.assertThat(len(encoded_diff), LessThan(len(encoded_deployment) / 2)) self.assertThat(wire_decode(encoded_diff).apply(deployment), Equals(d)) removal_diff = create_diff(d, deployment) encoded_removal_diff = wire_encode(removal_diff) self.assertThat(len(encoded_removal_diff), LessThan(len(encoded_deployment) / 2)) self.assertThat( wire_decode(encoded_removal_diff).apply(d), Equals(deployment))
class TestAllMatch(TestCase, TestMatchersInterface): matches_matcher = AllMatch(LessThan(10)) matches_matches = [ [9, 9, 9], (9, 9), iter([9, 9, 9, 9, 9]), ] matches_mismatches = [ [11, 9, 9], iter([9, 12, 9, 11]), ] str_examples = [ ("AllMatch(LessThan(12))", AllMatch(LessThan(12))), ] describe_examples = [ ('Differences: [\n' '10 is not > 11\n' '10 is not > 10\n' ']', [11, 9, 10], AllMatch(LessThan(10))), ]
def test_with_backtrace(self): matcher = HasQueryCount(LessThan(2)) collector = RequestTimelineCollector() collector.count = 2 collector.queries = [ (0, 1, "SQL-main-slave", "SELECT 1 FROM Person", ' File "example", line 2, in <module>\n' ' Store.of(Person).one()\n'), (2, 3, "SQL-main-slave", "SELECT 1 FROM Product", ' File "example", line 3, in <module>\n' ' Store.of(Product).one()\n'), ] mismatch = matcher.match(collector) self.assertThat(mismatch, Not(Is(None))) details = mismatch.get_details() lines = [] for name, content in details.items(): self.assertEqual("queries", name) self.assertEqual("text", content.content_type.type) lines.append(''.join(content.iter_text())) separator = "-" * 70 backtrace_separator = "." * 70 expected_lines = [ '0-1@SQL-main-slave SELECT 1 FROM Person\n' + separator + '\n' + ' File "example", line 2, in <module>\n' + ' Store.of(Person).one()\n' + backtrace_separator + '\n' + '2-3@SQL-main-slave SELECT 1 FROM Product\n' + separator + '\n' + ' File "example", line 3, in <module>\n' + ' Store.of(Product).one()\n' + backtrace_separator, ] self.assertEqual(expected_lines, lines) self.assertEqual( "queries do not match: %s" % (LessThan(2).match(2).describe(),), mismatch.describe())
def test_rough_length_distinct_query(self): # StormRangeFactory.rough_length with SELECT DISTINCT queries. resultset = self.makeStormResultSet() resultset.config(distinct=True) resultset.order_by(Person.name, Person.id) range_factory = StormRangeFactory(resultset) estimated_length = range_factory.rough_length self.assertThat(estimated_length, LessThan(10)) self.assertThat(estimated_length, Not(LessThan(1)))
def test_rough_length_first_sort_column_desc(self): # StormRangeFactory.rough_length can handle result sets where # the first sort column has descendig order. resultset = self.makeStormResultSet() resultset.order_by(Desc(Person.id)) range_factory = StormRangeFactory(resultset) estimated_length = range_factory.rough_length self.assertThat(estimated_length, LessThan(10)) self.assertThat(estimated_length, Not(LessThan(1)))
def test_rough_length(self): # StormRangeFactory.rough_length returns an estimate of the # length of the result set. resultset = self.makeStormResultSet() resultset.order_by(Person.id) range_factory = StormRangeFactory(resultset) estimated_length = range_factory.rough_length self.assertThat(estimated_length, LessThan(10)) self.assertThat(estimated_length, Not(LessThan(1)))
def assertRaisesFailure(self, failure, function, *args, **kwargs): try: function(*args, **kwargs) except Failure as raised_failure: self.assertThat(sys.version_info, LessThan((3, 0))) self.assertEqual(failure, raised_failure) except Exception as raised_exception: self.assertThat(sys.version_info, Not(LessThan((3, 0)))) self.assertEqual(failure.value, raised_exception)
class TestLessThanInterface(TestCase, TestMatchersInterface): matches_matcher = LessThan(4) matches_matches = [-5, 3] matches_mismatches = [4, 5, 5000] str_examples = [ ("LessThan(12)", LessThan(12)), ] describe_examples = [('4 is >= 4', 4, LessThan(4))]
def test_window_geometry(self): """Window.geometry property Check that all Window geometry properties work and have a plausible range. """ # ensure we have at least one open app window self.start_mock_app(EmulatorBase) display = Display.create() top = left = right = bottom = None # for multi-monitor setups, make sure we examine the full desktop # space: for monitor in range(display.get_num_screens()): sx, sy, swidth, sheight = Display.create().get_screen_geometry( monitor ) logger.info( "Monitor %d geometry is (%d, %d, %d, %d)", monitor, sx, sy, swidth, sheight, ) if left is None or sx < left: left = sx if top is None or sy < top: top = sy if right is None or sx + swidth >= right: right = sx + swidth if bottom is None or sy + sheight >= bottom: bottom = sy + sheight logger.info( "Total desktop geometry is (%d, %d), (%d, %d)", left, top, right, bottom, ) for win in self.process_manager.get_open_windows(): logger.info("Win '%r' geometry is %r", win, win.geometry) geom = win.geometry self.assertThat(len(geom), Equals(4)) self.assertThat(geom[0], GreaterThan(left - 1)) # no GreaterEquals self.assertThat(geom[1], GreaterThan(top - 1)) self.assertThat(geom[2], LessThan(right)) self.assertThat(geom[3], LessThan(bottom))
def test_getEnvironment(self): bc = BaseConfiguration() self.assertEqual(10, bc.getEnvironment(10)) self.assertEqual(20, bc.getEnvironment(20)) self.assertEqual(30, bc.getEnvironment(30)) self.assertEqual(10, bc.getEnvironment("production")) self.assertEqual(20, bc.getEnvironment("staging")) self.assertEqual(30, bc.getEnvironment("development")) self.assertThat(bc.getEnvironment("production"), LessThan(bc.getEnvironment("staging"))) self.assertThat(bc.getEnvironment("staging"), LessThan(bc.getEnvironment("development")))
def test_messages_query_counts_constant(self): # XXX Robert Collins 2010-09-15 bug=619017 # This test may be thrown off by the reference bug. To get around the # problem, flush and reset are called on the bug storm cache before # each call to the webservice. When lp's storm is updated to release # the committed fix for this bug, please see about updating this test. login(USER_EMAIL) bug = self.factory.makeBug() store = Store.of(bug) self.factory.makeBugComment(bug) self.factory.makeBugComment(bug) self.factory.makeBugComment(bug) webservice = LaunchpadWebServiceCaller('launchpad-library', 'salgado-change-anything') collector = QueryCollector() collector.register() self.addCleanup(collector.unregister) url = '/bugs/%d/messages?ws.size=75' % bug.id # First request. store.flush() store.reset() response = webservice.get(url) self.assertThat(collector, HasQueryCount(LessThan(24))) with_2_count = collector.count self.failUnlessEqual(response.status, 200) login(USER_EMAIL) for i in range(50): self.factory.makeBugComment(bug) self.factory.makeBugAttachment(bug) logout() # Second request. store.flush() store.reset() response = webservice.get(url) self.assertThat(collector, HasQueryCount(Equals(with_2_count)))
def test_landing_targets_constant_queries(self): project = self.factory.makeProduct() with person_logged_in(project.owner): source = self.factory.makeBranch(target=project) source_url = api_url(source) webservice = webservice_for_person( project.owner, permission=OAuthPermission.WRITE_PRIVATE) def create_mp(): with admin_logged_in(): branch = self.factory.makeBranch( target=project, stacked_on=self.factory.makeBranch( target=project, information_type=InformationType.PRIVATESECURITY), information_type=InformationType.PRIVATESECURITY) self.factory.makeBranchMergeProposal(source_branch=source, target_branch=branch) def list_mps(): webservice.get(source_url + '/landing_targets') list_mps() recorder1, recorder2 = record_two_runs(list_mps, create_mp, 2) self.assertThat(recorder1, HasQueryCount(LessThan(30))) self.assertThat(recorder2, HasQueryCount.byEquality(recorder1))
def test_commits_after_each_item(self): # Test that the script commits after each item, not just at the end. uploads = [ self.createWaitingAcceptancePackage( distroseries=self.factory.makeDistroSeries( distribution=self.distro), sourcename='source%d' % i) for i in range(3) ] class UploadCheckingSynchronizer: commit_count = 0 def beforeCompletion(inner_self, txn): pass def afterCompletion(inner_self, txn): if txn.status != 'Committed': return inner_self.commit_count += 1 done_count = len([ upload for upload in uploads if upload.package_upload.status == PackageUploadStatus.DONE ]) self.assertEqual(min(len(uploads), inner_self.commit_count), done_count) script = self.getScript([]) switch_dbuser(self.dbuser) synch = UploadCheckingSynchronizer() transaction.manager.registerSynch(synch) script.main() self.assertThat(len(uploads), LessThan(synch.commit_count))
def assert_window_fullscreen(self, fullscreen): if fullscreen: self.assertThat(self.main_window.get_window().visibility, Eventually(Equals(self.QWINDOW_FULLSCREEN))) else: self.assertThat(self.main_window.get_window().visibility, Eventually(LessThan(self.QWINDOW_FULLSCREEN)))
def test_binary_query_counts(self): query_baseline = 40 # Assess the baseline. collector = RequestTimelineCollector() collector.register() self.addCleanup(collector.unregister) ppa = self.factory.makeArchive() viewer = self.factory.makePerson() browser = self.getUserBrowser(user=viewer) with person_logged_in(viewer): # The baseline has one package, because otherwise the # short-circuit prevents the packages iteration happening at # all and we're not actually measuring scaling # appropriately. pkg = self.factory.makeBinaryPackagePublishingHistory(archive=ppa) url = canonical_url(ppa) + "/+packages" browser.open(url) self.assertThat(collector, HasQueryCount(LessThan(query_baseline))) expected_count = collector.count # Use all new objects - avoids caching issues invalidating the # gathered metrics. login(ADMIN_EMAIL) ppa = self.factory.makeArchive() viewer = self.factory.makePerson() browser = self.getUserBrowser(user=viewer) with person_logged_in(viewer): for i in range(3): pkg = self.factory.makeBinaryPackagePublishingHistory( archive=ppa, distroarchseries=pkg.distroarchseries) url = canonical_url(ppa) + "/+packages" browser.open(url) self.assertThat(collector, HasQueryCount(Equals(expected_count)))
def matches_time_or_just_before(time, tolerance=timedelta(seconds=10)): """ Match a time to be equal to a certain time or just before it. Useful when checking for a time that is now +/- some amount of time. """ return MatchesAll(GreaterThan(time - tolerance), MatchesAny(LessThan(time), Equals(time)))
def test_autoscrolling_from_top(self): """Test the autoscrolling from the top of the Launcher""" self.open_apps_in_launcher() # Set the autoscroll_offset to 10 (this is arbitrary for this test). autoscroll_offset = 10 launcher_instance = self.get_launcher() (x, y, w, h) = launcher_instance.geometry icons = self.unity.launcher.model.get_launcher_icons_for_monitor( self.launcher_monitor) num_icons = self.unity.launcher.model.num_launcher_icons() first_icon = icons[0] last_icon = icons[num_icons - 1] launcher_instance.move_mouse_over_launcher() # Move to the last icon in order to expand the top of the Launcher launcher_instance.move_mouse_to_icon(last_icon) # Make sure the first icon is off the screen or else there is no # scrolling. self.assertThat(first_icon.center.y, LessThan(y)) # Autoscroll to the first icon launcher_instance.move_mouse_to_icon(first_icon, autoscroll_offset) (x_fin, y_fin) = self.mouse.position() # Make sure we ended up in the center of the first icon self.assertThat(x_fin, Equals(first_icon.center.x)) self.assertThat(y_fin, Equals(first_icon.center.y))
def test_mocked_sleep_methods(self): with ElapsedTimeCounter() as time_counter: sleep.enable_mock() self.addCleanup(sleep.disable_mock) sleep(10) self.assertThat(time_counter.elapsed_time, LessThan(2))
def test_creating_proxy_for_segfaulted_app_fails_quicker(self): """Searching for a process that has died since launching, the search must fail before the 10 second timeout. """ path = self.write_script( dedent("""\ #!%s from time import sleep import sys sleep(1) sys.exit(1) """ % sys.executable)) start = datetime.datetime.now() try: self.launch_test_application(path, app_type='qt') except ProcessSearchError: end = datetime.datetime.now() else: self.fail( "launch_test_application didn't raise expected exception") difference = end - start self.assertThat(difference.total_seconds(), LessThan(5))
def test_date_created(self): result = self.factory.makeCodeImportResult() # date_created is "now", but there will have been a transaction # commit, so it won't be the same as UTC_NOW. self.assertThat(result.date_created, LessThan(datetime.utcnow().replace(tzinfo=UTC))) self.assertEqual(result.date_created, result.date_job_finished)
def test_wait_select_single_succeeds_quickly(self): app = self.start_fully_featured_app() start_time = default_timer() main_window = app.wait_select_single('QMainWindow') end_time = default_timer() self.assertThat(main_window, NotEquals(None)) self.assertThat(abs(end_time - start_time), LessThan(1))
def test_multiple_hud_reveal_does_not_break_launcher(self): """Multiple Hud reveals must not cause the launcher to set multiple apps as active. """ launcher = self.unity.launcher.get_launcher_for_monitor(self.hud_monitor) # We need an app to switch to: self.process_manager.start_app('Character Map') # We need an application to play with - I'll use the calculator. self.process_manager.start_app('Calculator') sleep(1) # before we start, make sure there's zero or one active icon: num_active = self.get_num_active_launcher_icons() self.assertThat(num_active, LessThan(2), "Invalid number of launcher icons active before test has run!") # reveal and hide hud several times over: for i in range(3): self.unity.hud.ensure_visible() self.unity.hud.ensure_hidden() # click application icons for running apps in the launcher: icon = self.unity.launcher.model.get_icon(desktop_id="gucharmap.desktop") launcher.click_launcher_icon(icon) # see how many apps are marked as being active: num_active = self.get_num_active_launcher_icons() self.assertLessEqual(num_active, 1, "More than one launcher icon active after test has run!")
def test__returns_at_most_60kiB_of_JSON(self): # Configure the rack controller subnet to be very large so it # can hold that many BMC connected to the interface for the rack # controller. rack = factory.make_RackController(power_type='') rack_interface = rack.get_boot_interface() subnet = factory.make_Subnet( cidr=str(factory.make_ipv6_network(slash=8))) factory.make_StaticIPAddress(ip=factory.pick_ip_in_Subnet(subnet), subnet=subnet, interface=rack_interface) # Ensure that there are at least 64kiB of power parameters (when # converted to JSON) in the database. example_parameters = {"key%d" % i: "value%d" % i for i in range(250)} remaining = 2**16 while remaining > 0: node = self.make_Node(bmc_connected_to=rack, power_parameters=example_parameters) remaining -= len(json.dumps(node.get_effective_power_parameters())) nodes = list_cluster_nodes_power_parameters( rack.system_id, limit=None) # Remove numeric limit. # The total size of the JSON is less than 60kiB, but only a bit. nodes_json = map(json.dumps, nodes) nodes_json_lengths = map(len, nodes_json) nodes_json_length = sum(nodes_json_lengths) expected_maximum = 60 * (2**10) # 60kiB self.expectThat(nodes_json_length, LessThan(expected_maximum + 1)) expected_minimum = 50 * (2**10) # 50kiB self.expectThat(nodes_json_length, GreaterThan(expected_minimum - 1))