def setUp(self): self._full_record = RFC822Record({ 'plugin': 'plugin', 'id': 'id', 'summary': 'summary-value', 'requires': 'requires', 'command': 'command', 'description': 'description-value' }, Origin(FileTextSource('file.txt'), 1, 5)) self._full_gettext_record = RFC822Record({ '_plugin': 'plugin', '_id': 'id', '_summary': 'summary-value', '_requires': 'requires', '_command': 'command', '_description': 'description-value', '_siblings': '[{"id": "foo", "depends": "bar"}]' }, Origin(FileTextSource('file.txt.in'), 1, 5)) self._min_record = RFC822Record({ 'plugin': 'plugin', 'id': 'id', }, Origin(FileTextSource('file.txt'), 1, 2)) self._split_description_record = RFC822Record({ 'id': 'id', 'purpose': 'purpose-value', 'steps': 'steps-value', 'verification': 'verification-value' }, Origin(FileTextSource('file.txt'), 1, 1))
def test_eq(self): """ verify instances of Origin are all equal to other instances with the same instance attributes but not equal to instances with different attributes """ origin1 = Origin( self.origin.source, self.origin.line_start, self.origin.line_end) origin2 = Origin( self.origin.source, self.origin.line_start, self.origin.line_end) self.assertTrue(origin1 == origin2) origin_other1 = Origin( self.origin.source, self.origin.line_start + 1, self.origin.line_end) self.assertTrue(origin1 != origin_other1) self.assertFalse(origin1 == origin_other1) origin_other2 = Origin( self.origin.source, self.origin.line_start, self.origin.line_end + 1) self.assertTrue(origin1 != origin_other2) self.assertFalse(origin1 == origin_other2) origin_other3 = Origin( FileTextSource("unrelated"), self.origin.line_start, self.origin.line_end) self.assertTrue(origin1 != origin_other3) self.assertFalse(origin1 == origin_other3)
def select_qualifier_list(self): # Add whitelists if 'whitelist' in self.ns and self.ns.whitelist: for whitelist_file in self.ns.whitelist: qualifier = self.get_whitelist_from_file( whitelist_file.name, whitelist_file) if qualifier is not None: self._qualifier_list.append(qualifier) # Add all the --include jobs for pattern in self.ns.include_pattern_list: origin = Origin(CommandLineTextSource('-i', pattern), None, None) try: qualifier = RegExpJobQualifier('^{}$'.format(pattern), origin, inclusive=True) except Exception as exc: logger.warning(_("Incorrect pattern %r: %s"), pattern, exc) else: self._qualifier_list.append(qualifier) # Add all the --exclude jobs for pattern in self.ns.exclude_pattern_list: origin = Origin(CommandLineTextSource('-x', pattern), None, None) try: qualifier = RegExpJobQualifier('^{}$'.format(pattern), origin, inclusive=False) except Exception as exc: logger.warning(_("Incorrect pattern %r: %s"), pattern, exc) else: self._qualifier_list.append(qualifier) if self.config.whitelist is not Unset: self._qualifier_list.append( self.get_whitelist_from_file(self.config.whitelist))
def setUp(self): self._record = RFC822Record({ 'id': 'id', 'name': 'name', }, Origin(FileTextSource('file.txt'), 1, 2)) self._gettext_record = RFC822Record({ '_id': 'id', '_name': 'name' }, Origin(FileTextSource('file.txt.in'), 1, 2)) warnings.filterwarnings('ignore', 'validate is deprecated since version 0.11')
def test_relative_to(self): """ verify how Origin.relative_to() works in various situations """ # if the source does not have relative_to method, nothing is changed origin = Origin(UnknownTextSource(), 1, 2) self.assertIs(origin.relative_to("/some/path"), origin) # otherwise the source is replaced and a new origin is returned self.assertEqual( Origin( FileTextSource("/some/path/file.txt"), 1, 2 ).relative_to("/some/path"), Origin(FileTextSource("file.txt"), 1, 2))
def test_str__whole_file(self): """ verify that Origin.__str__() behaves differently when the range is empty """ expected = "file.txt" observed = str(Origin(FileTextSource("file.txt"))) self.assertEqual(expected, observed)
def test_str__single_line(self): """ verify that Origin.__str__() behaves differently when the range describes a single line """ expected = "file.txt:15" observed = str(Origin(FileTextSource("file.txt"), 15, 15)) self.assertEqual(expected, observed)
def _get_matching_job_list(self, ns, job_list): logger.debug("_get_matching_job_list(%r, %r)", ns, job_list) qualifier_list = [] # Add the test plan if ns.test_plan is not None: # Uh, dodgy, recreate a list of providers from the list of jobs we # know about here. This code needs to be re-factored to use the # upcoming provider store class. for provider in {job.provider for job in job_list}: for unit in provider.id_map[ns.test_plan]: if unit.Meta.name == 'test plan': qualifier_list.append(unit.get_qualifier()) break else: logger.debug(_("There is no test plan: %s"), ns.test_plan) # Add whitelists for whitelist_file in ns.whitelist: qualifier = self.get_whitelist_from_file(whitelist_file.name, whitelist_file) if qualifier is not None: qualifier_list.append(qualifier) # Add all the --include jobs for pattern in ns.include_pattern_list: origin = Origin(CommandLineTextSource('-i', pattern), None, None) try: qualifier = RegExpJobQualifier('^{}$'.format(pattern), origin, inclusive=True) except Exception as exc: logger.warning(_("Incorrect pattern %r: %s"), pattern, exc) else: qualifier_list.append(qualifier) # Add all the --exclude jobs for pattern in ns.exclude_pattern_list: origin = Origin(CommandLineTextSource('-x', pattern), None, None) try: qualifier = RegExpJobQualifier('^{}$'.format(pattern), origin, inclusive=False) except Exception as exc: logger.warning(_("Incorrect pattern %r: %s"), pattern, exc) else: qualifier_list.append(qualifier) logger.debug("select_jobs(%r, %r)", job_list, qualifier_list) return select_jobs(job_list, qualifier_list)
def from_string(cls, text, *, filename=None, name=None, origin=None, implicit_namespace=None): """ Load and initialize the WhiteList object from the specified string. :param text: full text of the whitelist :param filename: (optional, keyword-only) filename from which text was read from. This simulates a call to :meth:`from_file()` which properly computes the name and origin of the whitelist. :param name: (optional) name of the whitelist, only used if filename is not specified. :param origin: (optional) origin of the whitelist, only used if a filename is not specified. If omitted a default origin value will be constructed out of UnknownTextSource instance :param implicit_namespace: (optional) implicit namespace for jobs that are using partial identifiers (all jobs) :returns: a fresh WhiteList object The optional filename or a pair of name and origin arguments may be provided in order to have additional meta-data. This is typically needed when the :meth:`from_file()` method cannot be used as the caller already has the full text of the intended file available. """ _logger.debug("Loaded whitelist from %r", filename) pattern_list, max_lineno = cls._parse_patterns(text) # generate name and origin if filename is provided if filename is not None: name = WhiteList.name_from_filename(filename) origin = Origin(FileTextSource(filename), 1, max_lineno) else: # otherwise generate origin if it's not specified if origin is None: origin = Origin(UnknownTextSource(), 1, max_lineno) return cls(pattern_list, name, origin, implicit_namespace)
def setUp(self): self._record = RFC822Record( { 'id': 'id', 'unit': 'exporter', '_summary': 'summary', 'entry_point': 'text', 'file_extension': 'file_extension', }, Origin(FileTextSource('file.txt'), 1, 2))
def test_just_file(self): """ verify how Origin.just_file() works as expected """ origin1 = Origin(UnknownTextSource(), 1, 2) origin2 = origin1.just_file() self.assertEqual(origin2.line_start, None) self.assertEqual(origin2.line_end, None) self.assertIs(origin2.source, origin1.source)
def test_with_offset(self): """ verify how Origin.with_offset() works as expected """ origin1 = Origin(UnknownTextSource(), 1, 2) origin2 = origin1.with_offset(10) self.assertEqual(origin2.line_start, 11) self.assertEqual(origin2.line_end, 12) self.assertIs(origin2.source, origin1.source)
def test_parse_typical(self): """ verify typical operation without any parsing errors """ # Setup a mock job and result, give some io log to the result job = mock.Mock(spec=JobDefinition) result = mock.Mock(spec=IJobResult) result.get_io_log.return_value = [(0, 'stdout', b'attr: value1\n'), (0, 'stdout', b'\n'), (0, 'stdout', b'attr: value2\n')] # Parse the IO log records records = list(gen_rfc822_records_from_io_log(job, result)) # Ensure that we saw both records self.assertEqual(records, [ RFC822Record({'attr': 'value1'}, Origin(JobOutputTextSource(job), 1, 1)), RFC822Record({'attr': 'value2'}, Origin(JobOutputTextSource(job), 3, 3)), ])
def test_from_string__with_name_and_origin(self): """ verify that WhiteList.from_string() works when passing name and origin """ # construct a whitelist with some dummy data, the names, pathnames and # line ranges are arbitrary whitelist = WhiteList.from_string("\n".join(self._content), name="somefile", origin=Origin( FileTextSource("somefile.txt"), 1, 3)) # verify that the patterns are okay self.assertEqual(repr(whitelist.qualifier_list[0]), "RegExpJobQualifier('^foo$', inclusive=True)") # verify that whitelist name is copied self.assertEqual(whitelist.name, "somefile") # verify that the origin is copied self.assertEqual(whitelist.origin, Origin(FileTextSource("somefile.txt"), 1, 3))
def test_get_qualifier__full(self): # Let's pretend the unit looks like this: # +0 unit: test-plan # +1 name: An example test plan # +2 include: # +3 foo # +4 # nothing # +5 b.* # +6 exclude: bar # Let's also assume that it is at a +10 offset in the file it comes # from so that the first line +0 is actually the 10th Line src = mock.Mock(name='source', spec_set=ITextSource) origin = Origin(src, 10, 16) field_offset_map = {'unit': 0, 'name': 1, 'include': 3, 'exclude': 6} unit = TestPlanUnit( { 'unit': 'test-plan', 'name': 'An example test plan', 'include': ('foo\n' '# nothing\n' 'b.*\n'), 'exclude': 'bar\n' }, provider=self.provider, origin=origin, field_offset_map=field_offset_map) qual_list = unit.get_qualifier().get_primitive_qualifiers() self.assertEqual(qual_list[0].field, 'id') self.assertIsInstance(qual_list[0].matcher, OperatorMatcher) self.assertEqual(qual_list[0].matcher.value, 'ns::foo') self.assertEqual(qual_list[0].origin, Origin(src, 13, 13)) self.assertEqual(qual_list[0].inclusive, True) self.assertEqual(qual_list[1].field, 'id') self.assertIsInstance(qual_list[1].matcher, PatternMatcher) self.assertEqual(qual_list[1].matcher.pattern_text, '^ns::b.*$') self.assertEqual(qual_list[1].origin, Origin(src, 15, 15)) self.assertEqual(qual_list[1].inclusive, True) self.assertEqual(qual_list[2].field, 'id') self.assertIsInstance(qual_list[2].matcher, OperatorMatcher) self.assertEqual(qual_list[2].matcher.value, 'ns::bar') self.assertEqual(qual_list[2].origin, Origin(src, 16, 16)) self.assertEqual(qual_list[2].inclusive, False)
def test_origin_from_filename_is_filename(self): # If the test's origin has a filename, we need a valid origin # with proper data. # We're faking the name by using a StringIO subclass with a # name property, which is how rfc822 gets that data. expected_origin = Origin(FileTextSource("file.txt"), 1, 1) with NamedStringIO("key:value", fake_filename="file.txt") as stream: records = type(self).loader(stream) self.assertEqual(len(records), 1) self.assertEqual(records[0].data, {'key': 'value'}) self.assertEqual(records[0].origin, expected_origin)
def setUp(self): self._record = RFC822Record( { 'id': 'id', 'unit': 'exporter', '_summary': 'summary', 'entry_point': 'text', 'file_extension': 'file_extension', }, Origin(FileTextSource('file.txt'), 1, 2)) warnings.filterwarnings('ignore', 'validate is deprecated since version 0.11')
def test_gt(self): """ verify that Origin instances are ordered by their constituting components """ self.assertTrue( Origin(FileTextSource('file.txt'), 1, 1) < Origin(FileTextSource('file.txt'), 1, 2) < Origin(FileTextSource('file.txt'), 1, 3)) self.assertTrue( Origin(FileTextSource('file.txt'), 1, 10) < Origin(FileTextSource('file.txt'), 2, 10) < Origin(FileTextSource('file.txt'), 3, 10)) self.assertTrue( Origin(FileTextSource('file1.txt'), 1, 10) < Origin(FileTextSource('file2.txt'), 1, 10) < Origin(FileTextSource('file3.txt'), 1, 10))
def test_origin_from_stream_is_Unknown(self): """ verify that gen_rfc822_records() uses origin instances with source equal to UnknownTextSource, when no explicit source is provided and the stream has no name to infer a FileTextSource() from. """ expected_origin = Origin(UnknownTextSource(), 1, 1) with StringIO("key:value") as stream: records = type(self).loader(stream) self.assertEqual(len(records), 1) self.assertEqual(records[0].data, {'key': 'value'}) self.assertEqual(records[0].origin, expected_origin)
def test_from_string(self): """ verify that WhiteList.from_string() works """ whitelist = WhiteList.from_string("\n".join(self._content)) # verify that the patterns are okay self.assertEqual(repr(whitelist.qualifier_list[0]), "RegExpJobQualifier('^foo$', inclusive=True)") # verify that whitelist name is the empty default self.assertEqual(whitelist.name, None) # verify that the origin got set to the default constructed value self.assertEqual(whitelist.origin, Origin(UnknownTextSource(), 1, 3))
def test_from_file(self): """ verify that WhiteList.from_file() works """ with self.mocked_file(self._name, self._content): whitelist = WhiteList.from_file(self._name) # verify that the patterns are okay self.assertEqual(repr(whitelist.qualifier_list[0]), "RegExpJobQualifier('^foo$', inclusive=True)") # verify that whitelist name got set self.assertEqual(whitelist.name, "whitelist") # verify that the origin got set self.assertEqual(whitelist.origin, Origin(FileTextSource("whitelist.txt"), 1, 3))
def _new_record(): """ Reset local state to track new record """ nonlocal key nonlocal value_list nonlocal record nonlocal origin nonlocal field_offset_map key = None value_list = None if source is not None: origin = Origin(source, None, None) field_offset_map = {} record = RFC822Record(data_cls(), origin, data_cls(), field_offset_map)
def from_file(cls, pathname, implicit_namespace=None): """ Load and initialize the WhiteList object from the specified file. :param pathname: file to load :param implicit_namespace: (optional) implicit namespace for jobs that are using partial identifiers (all jobs) :returns: a fresh WhiteList object """ pattern_list, max_lineno = cls._load_patterns(pathname) name = os.path.splitext(os.path.basename(pathname))[0] origin = Origin(FileTextSource(pathname), 1, max_lineno) return cls(pattern_list, name, origin, implicit_namespace)
def test_parse_error(self, mock_logger): # Setup a mock job and result, give some io log to the result job = mock.Mock(spec=JobDefinition) result = mock.Mock(spec=IJobResult) result.get_io_log.return_value = [(0, 'stdout', b'attr: value1\n'), (0, 'stdout', b'\n'), (0, 'stdout', b'error\n'), (0, 'stdout', b'\n'), (0, 'stdout', b'attr: value2\n')] # Parse the IO log records records = list(gen_rfc822_records_from_io_log(job, result)) # Ensure that only the first record was generated self.assertEqual(records, [ RFC822Record({'attr': 'value1'}, Origin(JobOutputTextSource(job), 1, 1)), ]) # Ensure that a warning was logged mock_logger.warning.assert_called_once_with( "local script %s returned invalid RFC822 data: %s", job.id, RFC822SyntaxError(None, 3, "Unexpected non-empty line: 'error\\n'"))
def setUp(self): self.raw_data = {'key': ' value'} self.data = {'key': 'value'} self.origin = Origin(FileTextSource('file.txt'), 1, 1) self.record = RFC822Record(self.data, self.origin, self.raw_data)
def setUp(self): self.origin = Origin(FileTextSource("file.txt"), 10, 12)