Re: [Freeipa-devel] [PATCH 68] text unit test should validate using installed mo file

2012-04-11 Thread Rob Crittenden

Petr Viktorin wrote:

On 04/09/2012 05:24 PM, John Dennis wrote:

On 03/30/2012 08:57 AM, Petr Viktorin wrote:

On 03/30/2012 02:41 AM, John Dennis wrote:

On 03/28/2012 04:40 AM, Petr Viktorin wrote:

Can install/po/Makefile just call test_i18n.py from the tests/
tree? It
doesn't import any IPA code so there's no need to set sys.path in this
case (though there'd have to be a comment saying we depend on this).
In the other case, unit tests, the path is already set by Nose.
Also the file would have to be renamed so nose doesn't pick it up as a
test module.


Good idea. I moved test_i18n.py to tests/i18n.py. I was reluctant about
moving the file, but that was without merit, it works better this way.


The downside is that the file now looks like a test utility module. It
could use a comment near the imports saying that it's also called as a
script, and that it shouldn't import IPA code (this could silently use
the system-installed version of IPA, or crash if it's not there).
Alternatively, set PYTHONPATH in the Makefile.


I also removed the superfluous comment in Makefile.in you pointed out.

When I was exercising the code I noticed the validation code was not
treating msgid's from C code correctly (we do have some C code in the
client area). That required a much more nuanced parsing the format
conversion specifiers to correctly identify what was a positional
format
specifier vs. an indexed format specifier. The new version of the
i18n.py includes the function parse_printf_fmt() and
get_prog_langs() to
identify the source programming language.


More non-trivial code without tests. This makes me worry. But, tests for
this can be added later I guess.


Two more patches will follow shortly, one which adds validation when
make lint is run and a patch to correct the problems it found in
the C
code strings which did not used indexed format specifiers.


revised patch with comment about imports attached.




ACK



pushed to master and ipa-2-2

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel


Re: [Freeipa-devel] [PATCH 68] text unit test should validate using installed mo file

2012-04-10 Thread Petr Viktorin

On 04/09/2012 05:24 PM, John Dennis wrote:

On 03/30/2012 08:57 AM, Petr Viktorin wrote:

On 03/30/2012 02:41 AM, John Dennis wrote:

On 03/28/2012 04:40 AM, Petr Viktorin wrote:

Can install/po/Makefile just call test_i18n.py from the tests/ tree? It
doesn't import any IPA code so there's no need to set sys.path in this
case (though there'd have to be a comment saying we depend on this).
In the other case, unit tests, the path is already set by Nose.
Also the file would have to be renamed so nose doesn't pick it up as a
test module.


Good idea. I moved test_i18n.py to tests/i18n.py. I was reluctant about
moving the file, but that was without merit, it works better this way.


The downside is that the file now looks like a test utility module. It
could use a comment near the imports saying that it's also called as a
script, and that it shouldn't import IPA code (this could silently use
the system-installed version of IPA, or crash if it's not there).
Alternatively, set PYTHONPATH in the Makefile.


I also removed the superfluous comment in Makefile.in you pointed out.

When I was exercising the code I noticed the validation code was not
treating msgid's from C code correctly (we do have some C code in the
client area). That required a much more nuanced parsing the format
conversion specifiers to correctly identify what was a positional format
specifier vs. an indexed format specifier. The new version of the
i18n.py includes the function parse_printf_fmt() and get_prog_langs() to
identify the source programming language.


More non-trivial code without tests. This makes me worry. But, tests for
this can be added later I guess.


Two more patches will follow shortly, one which adds validation when
make lint is run and a patch to correct the problems it found in the C
code strings which did not used indexed format specifiers.


revised patch with comment about imports attached.




ACK

--
Petr³

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Re: [Freeipa-devel] [PATCH 68] text unit test should validate using installed mo file

2012-03-30 Thread Petr Viktorin

On 03/30/2012 02:41 AM, John Dennis wrote:

On 03/28/2012 04:40 AM, Petr Viktorin wrote:

Can install/po/Makefile just call test_i18n.py from the tests/ tree? It
doesn't import any IPA code so there's no need to set sys.path in this
case (though there'd have to be a comment saying we depend on this).
In the other case, unit tests, the path is already set by Nose.
Also the file would have to be renamed so nose doesn't pick it up as a
test module.


Good idea. I moved test_i18n.py to tests/i18n.py. I was reluctant about
moving the file, but that was without merit, it works better this way.


The downside is that the file now looks like a test utility module. It 
could use a comment near the imports saying that it's also called as a 
script, and that it shouldn't import IPA code (this could silently use 
the system-installed version of IPA, or crash if it's not there).

Alternatively, set PYTHONPATH in the Makefile.


I also removed the superfluous comment in Makefile.in you pointed out.

When I was exercising the code I noticed the validation code was not
treating msgid's from C code correctly (we do have some C code in the
client area). That required a much more nuanced parsing the format
conversion specifiers to correctly identify what was a positional format
specifier vs. an indexed format specifier. The new version of the
i18n.py includes the function parse_printf_fmt() and get_prog_langs() to
identify the source programming language.


More non-trivial code without tests. This makes me worry. But, tests for 
this can be added later I guess.



Two more patches will follow shortly, one which adds validation when
make lint is run and a patch to correct the problems it found in the C
code strings which did not used indexed format specifiers.




--
Petr³

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Re: [Freeipa-devel] [PATCH 68] text unit test should validate using installed mo file

2012-03-28 Thread Petr Viktorin

On 03/27/2012 10:31 PM, John Dennis wrote:

On 03/27/2012 01:57 PM, Petr Viktorin wrote:

Seeing this, I definitely recommend putting po_file_iterate in an
importable package.


Of course I considered that. Clearly not any existing top level
directory in the tree, those are reserved for what we install and what
is import visible after installation.

Test utility code should not be installed with our normal modules and
packages.

It has to be importable from both the install/po area and the test area.

It can't depend on nosetests setting the import path prior to execution
(because only the unit tests are run via nose).

So we could create a directory tests/util which hosts utilities used for
test code and locate it there. I did consider that, it would be
(somewhat) cleaner.

But unless I'm missing something someone is going to have to modify the
include path prior to importing any test utility code. It just becomes a
question of where the file is located. I'd be happy to move the bulk of
the logic into tests/util/i18n.py, but to import it the importing code
is going to have to add tests/util to the import path, which puts you
pretty much back into the original situation, just with a different path
(albeit perhaps a more logical cleaner path).


Can install/po/Makefile just call test_i18n.py from the tests/ tree? It 
doesn't import any IPA code so there's no need to set sys.path in this 
case (though there'd have to be a comment saying we depend on this).

In the other case, unit tests, the path is already set by Nose.
Also the file would have to be renamed so nose doesn't pick it up as a 
test module.



--
Petr³

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

[Freeipa-devel] [PATCH 68] text unit test should validate using installed mo file

2012-03-27 Thread John Dennis

This patch addresses ticket 2582, see comments in commit message.
--
John Dennis jden...@redhat.com

Looking to carve out IT costs?
www.redhat.com/carveoutcosts/
From fff7d0a42f7643039987d49c4de69b248f9baa9f Mon Sep 17 00:00:00 2001
From: John Dennis jden...@redhat.com
Date: Tue, 27 Mar 2012 10:18:24 -0400
Subject: [PATCH 68] text unit test should validate using installed mo file
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

We use custom gettext classes (e.g. GettextFactory 
NGettextFactory). We should exercise those classes with an installed
binary mo file to demonstrate we are actually returning the expected
translated strings for all strings defined as being translatable.

The test logic in install/po/test_i18n.py was recently enhanced to
make this type of testing easier and more complete.
tests/test_ipalib/test_text.py should import the new i18n test support
and run it.

Previously tests/test_ipalib/test_text.py made a feeble but incomplete
attempt to do the above but even that was often not run because the
test would skip because the necessary test files were not available
unless they had been manually created in the install/po subdir. It is
now possible to correct those deficiencies in the test.

This patch does the following:

* Imports test_i18n.py from the install/po directory in the tree

* Creates a tmp directory for the test localedir

* Parses the current ipa.pot file in install/po and generates
  a test po and mo file with special unicode markers. It installs
  the test mo file in the tmp localedir. This is accomplished by
  calling create_po() from the test_i18n.py file.

* If any of the above does not work it raises nose.SkipTest with
  the reason, and skips the test.

* It sets up functions to get a translation and a plural translation
  via our text.GettextFactory class and text.NGettextFactory class
  respectively. This are the functions we use intenally to get
  translations. It set the localdir and lang which are used by those
  classes to match our test configuration. It then runs a validation
  test on every translation and it's plural found in the test.po file
  by calling po_file_iterate and passed it the function pointers to
  our internal routines.

* At the conclusion of the test it cleans up after itself.

Note: extraneous files are not created in the tree, only a tmp
directory is utilized.
---
 tests/test_ipalib/test_text.py |  103 +---
 1 files changed, 64 insertions(+), 39 deletions(-)

diff --git a/tests/test_ipalib/test_text.py b/tests/test_ipalib/test_text.py
index f46b78e..45a6ca5 100644
--- a/tests/test_ipalib/test_text.py
+++ b/tests/test_ipalib/test_text.py
@@ -23,6 +23,8 @@ Test the `ipalib.text` module.
 
 import os
 import sys
+import shutil
+import tempfile
 import re
 import nose
 import locale
@@ -45,58 +47,81 @@ def test_create_translation():
 
 class test_TestLang(object):
 def setUp(self):
+self.tmp_dir = None
+self.saved_lang  = None
+
 self.lang = 'xh_ZA'
 self.domain = 'ipa'
 
-self.po_dir = os.path.join(os.path.dirname(__file__), '../../install/po')
-self.locale_dir = os.path.join(self.po_dir, 'test_locale')
+self.ipa_i18n_dir = os.path.join(os.path.dirname(__file__), '../../install/po')
+sys.path.insert(0, self.ipa_i18n_dir)
+try:
+import test_i18n
+except ImportError, e:
+raise nose.SkipTest('cannot import test_i18n: %s')
+
+self.pot_basename = '%s.pot' % self.domain
+self.po_basename = '%s.po' % self.lang
+self.mo_basename = '%s.mo' % self.domain
+
+self.tmp_dir = tempfile.mkdtemp()
+self.saved_lang  = os.environ['LANG']
+
+self.locale_dir = os.path.join(self.tmp_dir, 'test_locale')
+self.msg_dir = os.path.join(self.locale_dir, self.lang, 'LC_MESSAGES')
+
+if not os.path.exists(self.msg_dir):
+os.makedirs(self.msg_dir)
 
+self.pot_file = os.path.join(self.ipa_i18n_dir, self.pot_basename)
+self.mo_file = os.path.join(self.msg_dir, self.mo_basename)
+self.po_file = os.path.join(self.tmp_dir, self.po_basename)
+
+result = test_i18n.create_po(self.pot_file, self.po_file, self.mo_file)
+if result:
+raise nose.SkipTest('Unable to create po file %s  mo file %s from pot file %s' %
+(self.po_file, self.mo_file, self.pot_file))
 
-self.po_file = os.path.join(self.po_dir, 'test.po')
 if not file_exists(self.po_file):
 raise nose.SkipTest('Test po file unavailable, run make test in install/po')
 
-mo_file = os.path.join(self.locale_dir, self.lang, 'LC_MESSAGES', '%s.mo' % self.domain)
-if not file_exists(mo_file):
+if not file_exists(self.mo_file):
 raise nose.SkipTest('Test mo file unavailable, run make test in install/po')
 
-sys.path.insert(0, self.po_dir)
-  

Re: [Freeipa-devel] [PATCH 68] text unit test should validate using installed mo file

2012-03-27 Thread John Dennis

On 03/27/2012 10:34 AM, John Dennis wrote:

This patch addresses ticket 2582, see comments in commit message.


Sorry, the patch I originally posted was incorrect, the work had been 
done in several commits but I forgot to squash them into one commit 
and patch before posting it. This new patch fixes that mistake.



--
John Dennis jden...@redhat.com

Looking to carve out IT costs?
www.redhat.com/carveoutcosts/
From 03ffa8e2b1419de80c4769d8391ca56ffb4e2695 Mon Sep 17 00:00:00 2001
From: John Dennis jden...@redhat.com
Date: Mon, 26 Mar 2012 22:26:35 -0400
Subject: [PATCH 68-1] text unit test should validate using installed mo file
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

We use custom gettext classes (e.g. GettextFactory 
NGettextFactory). We should exercise those classes with an installed
binary mo file to demonstrate we are actually returning the expected
translated strings for all strings defined as being translatable.

The test logic in install/po/test_i18n.py was recently enhanced to
make this type of testing easier and more complete.
tests/test_ipalib/test_text.py should import the new i18n test support
and run it.

Previously tests/test_ipalib/test_text.py made a feeble but incomplete
attempt to do the above but even that was often not run because the
test would skip because the necessary test files were not available
unless they had been manually created in the install/po subdir. It is
now possible to correct those deficiencies in the test.

This patch does the following:

* Modfies test function in test_i18n.py to accept function pointers
  for retreiving a translation.

* Imports test_i18n.py from the install/po directory in the tree

* Creates a tmp directory for the test localedir

* Parses the current ipa.pot file in install/po and generates
  a test po and mo file with special unicode markers. It installs
  the test mo file in the tmp localedir. This is accomplished by
  calling create_po() from the test_i18n.py file.

* If any of the above does not work it raises nose.SkipTest with
  the reason, and skips the test.

* It sets up functions to get a translation and a plural translation
  via our text.GettextFactory class and text.NGettextFactory class
  respectively. This are the functions we use intenally to get
  translations. It set the localdir and lang which are used by those
  classes to match our test configuration. It then runs a validation
  test on every translation and it's plural found in the test.po file
  by calling po_file_iterate and passed it the function pointers to
  our internal routines.

* At the conclusion of the test it cleans up after itself.

Note: extraneous files are not created in the tree, only a tmp
directory is utilized.
---
 install/po/test_i18n.py|   35 +
 tests/test_ipalib/test_text.py |  168 +++-
 2 files changed, 101 insertions(+), 102 deletions(-)

diff --git a/install/po/test_i18n.py b/install/po/test_i18n.py
index beb43cc..c97874f 100755
--- a/install/po/test_i18n.py
+++ b/install/po/test_i18n.py
@@ -387,23 +387,28 @@ def validate_unicode_edit(msgid, msgstr):
 
 
 def test_translations(po_file, lang, domain, locale_dir):
-try:
+# The test installs the test message catalog under the xh_ZA
+# (e.g. Zambia Xhosa) language by default. It would be nice to
+# use a dummy language not associated with any real language,
+# but the setlocale function demands the locale be a valid
+# known locale, Zambia Xhosa is a reasonable choice :)
 
-# The test installs the test message catalog under the xh_ZA
-# (e.g. Zambia Xhosa) language by default. It would be nice to
-# use a dummy language not associated with any real language,
-# but the setlocale function demands the locale be a valid
-# known locale, Zambia Xhosa is a reasonable choice :)
+os.environ['LANG'] = lang
 
-os.environ['LANG'] = lang
+# Create a gettext translation object specifying our domain as
+# 'ipa' and the locale_dir as 'test_locale' (i.e. where to
+# look for the message catalog). Then use that translation
+# object to obtain the translation functions.
 
-# Create a gettext translation object specifying our domain as
-# 'ipa' and the locale_dir as 'test_locale' (i.e. where to
-# look for the message catalog). Then use that translation
-# object to obtain the translation functions.
+t = gettext.translation(domain, locale_dir)
+
+get_msgstr = t.ugettext
+get_msgstr_plural = t.ungettext
 
-t = gettext.translation(domain, locale_dir)
+return po_file_iterate(po_file, get_msgstr, get_msgstr_plural)
 
+def po_file_iterate(po_file, get_msgstr, get_msgstr_plural):
+try:
 # Iterate over the msgid's
 if not os.path.isfile(po_file):
 print sys.stderr, 'file does not exist %s' % (po_file)
@@ -422,8 +427,8 @@ def test_translations(po_file, lang, 

Re: [Freeipa-devel] [PATCH 68] text unit test should validate using installed mo file

2012-03-27 Thread Petr Viktorin


On 03/27/2012 04:58 PM, John Dennis wrote:
[...]


  def test_create_translation():
  f = text.create_translation
  key = ('foo', None)
@@ -129,6 +45,84 @@ def test_create_translation():
  assert context.__dict__[key] is t


+class test_TestLang(object):
+def setUp(self):
+self.tmp_dir = None
+self.saved_lang  = None
+
+self.lang = 'xh_ZA'
+self.domain = 'ipa'
+
+self.ipa_i18n_dir = os.path.join(os.path.dirname(__file__), 
'../../install/po')
+sys.path.insert(0, self.ipa_i18n_dir)


To keep the test isolated, I would save sys.path before modifying it, 
wrap the insert and import in a try block, and restore the path in finally.
Or even better, put the common code in an importable package: (most of) 
test_i18n.py could very well live under tests/.



+try:
+import test_i18n
+except ImportError, e:
+raise nose.SkipTest('cannot import test_i18n: %s')


Why would test_i18n not be importable?


+self.pot_basename = '%s.pot' % self.domain
+self.po_basename = '%s.po' % self.lang
+self.mo_basename = '%s.mo' % self.domain
+

[...]

+
+result = test_i18n.create_po(self.pot_file, self.po_file, self.mo_file)
+if result:
+raise nose.SkipTest('Unable to create po file %s  mo file %s from pot 
file %s' %
+(self.po_file, self.mo_file, self.pot_file))
+
+if not file_exists(self.po_file):
+raise nose.SkipTest('Test po file unavailable, run make test in 
install/po')
+
+if not file_exists(self.mo_file):
+raise nose.SkipTest('Test mo file unavailable, run make test in 
install/po')


Maybe it would be better to skip only if the pot file doesn't exist?
Is there a reason the PO generation should fail?


+self.po_file_iterate = test_i18n.po_file_iterate


Seeing this, I definitely recommend putting po_file_iterate in an 
importable package.



+def tearDown(self):
+if self.saved_lang is not None:
+os.environ['LANG'] = self.saved_lang
+
+if self.tmp_dir is not None:
+shutil.rmtree(self.tmp_dir)
+

[...]

One thing I missed in the previous patch: Makefile.in has a big comment 
near the end that's obsolete now.


--
Petr³

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel


Re: [Freeipa-devel] [PATCH 68] text unit test should validate using installed mo file

2012-03-27 Thread John Dennis

On 03/27/2012 01:57 PM, Petr Viktorin wrote:

Seeing this, I definitely recommend putting po_file_iterate in an
importable package.


Of course I considered that. Clearly not any existing top level 
directory in the tree, those are reserved for what we install and what 
is import visible after installation.


Test utility code should not be installed with our normal modules and 
packages.


It has to be importable from both the install/po area and the test area.

It can't depend on nosetests setting the import path prior to execution 
(because only the unit tests are run via nose).


So we could create a directory tests/util which hosts utilities used for 
test code and locate it there. I did consider that, it would be 
(somewhat) cleaner.


But unless I'm missing something someone is going to have to modify the 
include path prior to importing any test utility code. It just becomes a 
question of where the file is located. I'd be happy to move the bulk of 
the logic into tests/util/i18n.py, but to import it the importing code 
is going to have to add tests/util to the import path, which puts you 
pretty much back into the original situation, just with a different path 
(albeit perhaps a more logical cleaner path).



--
John Dennis jden...@redhat.com

Looking to carve out IT costs?
www.redhat.com/carveoutcosts/

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel