понедельник, 26 марта 2012 г.

WebSphere Application Server 6. Диагностика зависших потоков.

Иногда в логе WebSphere Application Server можно наблюдать следующие строки WSVR0605W: Thread <threadname> has been active for <time> and may be hung.  There are <totalthreads> in total in the server that may be hung.

Что делать в этом случае? Как понять, в чём проблема? Ответ на этот вопрос состоит в том, чтобы сгенерировать javacore и изучать его содержимое. В апп сервер встроена диагностика зависших потоков. 

Для этого необходимо сделать следующее:
  1. Из консоли администрирования выбрать Servers > Application Servers > server_name.

  2. Далее в разделе Server Infrastructure выбрать Administration > Custom Properties.

  3. Нажать New.

  4. Добавить следующее свойство:

    Name: com.ibm.websphere.threadmonitor.dump.java
    Value: true

  5. Нажать Apply.

  6. Нажать OK и сохранить изменения.

  7. Рестартовать Application Server.
Теперь в случае если, WAS увидет, что поток подвис, то он автоматически создаст javacore, который можно в дальнейшем изучать.
 

DB2 8.2. Оптимизация

Добрый вечер,
Сегодня расскажу пару слов об оптимизации СУБД DB2 8.2.

Итак, для начала необходимо проводить следующие процедуры для поддержания СУБД в рабочем состоянии:
1) сбор статистики,
2) реорганизация таблиц и индексов,
3) обновление статистики,
4) ребиндинг хранимых процедур.

Что касается обновления статистики, то в сети можно найти скрипты по сбору статистики в DB2.
То же самое касается и реорганизации данных. 

Ребиндинг можно делать с помощью команды db2rbind <имя бд> -l <лог файл> all.
Правда названная выше команда может корректно выполнится если никто не использует хранимые процедуры в настоящий момент, поэтому эту команду необходимо выполнять в оффлайн режиме.

Также, если у нас DB2 стоит на линуксе с ядром серии 2.6, то можно выставить следующие параметры:
db2set DB2LINUXAIO=true
db2set DB2_SCATTERED_IO=ON
db2set DB2_DIRECT_IO=YES
 
После выставления параметров необходимо перезапустить db2.
Начиная с версии 9 параметр DB2_DIRECT_IO использовать не рекомендуется.
 
Также отключить кеширование можно на уровне табличного пространства. Это делается с 
помощью команды 
ALTER TABLESPACE <имя табличного пространства> NO FILE SYSTEM CACHING; 
 
После выполнения команды ALTER TABLESPACe существующие соединения с БД необходимо закрыть,
чтобы новые правила кеширования вступили в силу. 

 
Однако в боевой системе это делать стрёмно - куда проще поменять параметр среды и 
рестартовать СУБД.
 
Это хороший старт для дальнейшей оптимизации БД.

вторник, 20 марта 2012 г.

JQuery ajax post on Safari windows and Apache2

Добрый вечер,
Недавно я словил удивительный баг: иногда при попытке отправить post запрос через jQuery в Safari под Windows на Apache HTTP Server 2 происходило следующее. Запрос отправлялся, однако на сервере я не мог получить ни одного параметра http запроса. Более того, подобная ситуация не имела какого-либо сценария воспроизведения.

Решение:
Проблема решилась с помощью редактирования файла httpd.conf и выставлении опции KeepAlive Off.

Подобные ситуации возникают, и они описаны в сети. Достаточно ввести поиск по словам "jquery ajax tcp post".

понедельник, 12 марта 2012 г.

Русификация консоли NetBSD

Удалось настроить русификацию в консоли.
Но выяснилось следующее - если переключиться из консоли в иксы, а потом выйти из иксов в текстовый режим, то на экране получаем мусор и неработающую консоль. Разбираться с этим дальше нет времени и желания.

Конечно, можно пользоваться и иксами, но это уже не так интересно. В общем, на desktope NetBSD не жилец.

Да, наверное со всем остальным в этой системе обстоят дела лучше, но текстовая консоль является основополагающим инструментом.

Всем спасибо, кто помогал.

среда, 7 марта 2012 г.

NetBSD и X

Мораль сей басни такова - внимательно читайте man xorg.conf!

Русификация NetBSD 5.1.2 в X

1. установил usr/pkgsrc/fonts/dejavu-ttf и mlterm.
В ~/.xinitrc прописать
export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'

2. Указываем на них фонтконфигу. Fontconfig -- это поделие Кейта
Пакарда для настройки и доступа к шрифтам на уровне системы. В файле
/etc/fonts/fonts.conf ищем записи вида <dir>...</dir> (они расположены
на самом верхнем уровне вложенности документа, после большого
коммента) и добавляем туда:

     <dir>/usr/pkg/lib/X11/fonts/TTF</dir>

3. Обновляем кэш фонтконфига:

     # fc-cache -fv
4. В файле /etc/X11/xorg.conf в разделе InputDevice
прописываем следующую строку: Option "XkbOptions" "grp:alt_shift_toggle".

Переключение раскладки клавиатуры будет осуществлено по нажатию alt+shift.

понедельник, 5 марта 2012 г.

OpenJDK 1.7.0 на NetBSD

В этой небольшой заметке я расскажу как установить jdk 1.7 на NetBSD 5.1.2.

Войдём как root.
Далее cd /usr/pkgsrc/lang/openjd7.
make install && clean && clean-depends.

Java установится по пути /usr/pkg/java/openjdk7.

Полёт нормальный.

суббота, 3 марта 2012 г.

Trac + Fedora 12 + MySQL

Версии компонентов:
Trac 0.12.3
MySQL 5.1.47-2
Russian Fedora 12

При попытке создать проект Trac, который будет хранить данные в MySQL вываливается вот такая ошибка:
unsupported operand type(s) for /: 'int' and 'NoneType'
Traceback (most recent call last):
File "build/bdist.linux-i686/egg/trac/admin/console.py", line 437, in do_initenv
  options=options)
File "build/bdist.linux-i686/egg/trac/env.py", line 214, in __init__
  self.create(options)
File "build/bdist.linux-i686/egg/trac/env.py", line 402, in create
  DatabaseManager(self).init_db()
File "build/bdist.linux-i686/egg/trac/db/api.py", line 146, in init_db
  connector.init_db(**args)
File "build/bdist.linux-i686/egg/trac/db/mysql_backend.py", line 106, in init_db
  for stmt in self.to_sql(table, utf8_size=utf8_size):
File "build/bdist.linux-i686/egg/trac/db/mysql_backend.py", line 155, in to_sql
  utf8_size=utf8_size))
File "build/bdist.linux-i686/egg/trac/db/mysql_backend.py", line 119, in _collist
  limit_col = 767 / utf8_size
TypeError: unsupported operand type(s) for /: 'int' and 'NoneType'

В общем, не удалось подружить Trac и MySQL.
Необходимо  проверить как поведёт себя Trac и PosgreSQL.

Безбраузерное тестирование javascript кода


Безбраузерное тестирование
Автоматизированное тестирование javascript
Автоматизированное тестирование с помощью Rhino + QUnit
Работа с отладчиком Rhino
Автоматизированное тестирование с помощью Rhino + Jasmine
Тестирование AJAX вызовов в безбраузерной среде с помощью Jasmine



Безбраузерное тестирование

Бурное развитие создания приложений для браузера с помощью javascript привело к тому, что методы выполнения unit тестов для серверных приложений необходимо адаптировать для клиентских приложений, выполняющихся в браузере.

До тех пора, пока приложение является небольшим, тестирование автоматизированное или ручное в браузере является терпимым. Однако более практичным представляется атоматизированное безбраузерное тестирование.  Разумеется недостатком такого подхода является то, что мы не можем проследить как ведёт себя код в разных браузерах, но это может стать подспорьем при разработке приложения. Для ручного тестирования в различных браузерах рекомендуется использовать либо отдельные виртуальные машины для каждого браузера либо использовать набор IE Collection (http://utilu.com/IECollection/).

Для безбраузерного тестирования нам понадобится javascript движок. На февраль 2012 года известны следующие движки javascript:
Rhino: Mozilla’s Java JavaScript implementation.
SpiderMonkey: Mozilla’s C implementation of JavaScript.
V8: Google’s JavaScript virtual machine for Chrome.

Автоматизированное тестирование javascript



Мне пока известны следующие подходы к тестированию:

1) на базе Node.js
2) на базе движка Rhino от Mozilla

Рассмотрим второй подход.

Для этого можно использовать:  
  1. Rhino - реализация javascript на java.
  2. Envjs - реализация DOM API для Rhino. Эту библиотеку разработал разработчик jQuery.
  3. Jasmine - библиотека для тестирования.
  4. Jquery-jasmine - упрощение тестирования jasmine и DOM.
  5. QUnit - ещё одна библиотека для тестирования.

Автоматизированное тестирование с помощью Rhino + QUnit


Попробуем поставить Rhino и заставить работать Envjs.
1) Скачиваем Rhino rhino1_7R2 с сайта  Mozilla ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_7R2.zip.
Распаковываем архив. В этом архиве нам потребуется файл js.jar.
Теперь проверим, что Rhino действительно работает.
Для этого запустим команду
java -cp js.jar org.mozilla.javascript.tools.shell.Main -opt -1

Затем введём команду print("Hello world");
quit();

Далее необходимо установить Envjs.
Установим пропатченную версию Envjs.
Для этого скачаем её по ссылке https://github.com/ryan-roemer/envjs-1.2.

Скачаем также QUnit - система для создания тестов.
https://github.com/jquery/qunit/blob/a46610796b457fab05587945e743d4e857f580b5/qunit/qunit.css
https://github.com/jquery/qunit/blob/a46610796b457fab05587945e743d4e857f580b5/qunit/qunit.js


Теперь нам надо будет создать ещё два файла:
setup.js - для интеграции Envjs с QUnit.
run-tests.js - скрипт для запуска тестов.

Создадим файл my-lib.js с тестируемой функцией:
function addTwo(x, y) {
   return x + y;
}

Создадим файл my-tests.js с QUnit тестом.
module("My Module");

test("addTwo", function () {
   equals(addTwo(0, 0), 0, "Add nothing.");
   equals(addTwo(1, 2), 3, "Add numbers.");
   equals(addTwo(-1, -2), -3, "Add negatives.");
});

Теперь создадим страницу test.html:
<html>
 <head>
   <title>QUnit</title>
   <link rel="stylesheet" href="qunit.css" type="text/css" />
   <script type="text/javascript" src="qunit.js"></script>
   <script type="text/javascript" src="my-lib.js"></script>
   <script type="text/javascript" src="my-tests.js"></script>
 </head>
 <body>
   <h1 id="qunit-header">QUnit Test Suite</h1>
   <h2 id="qunit-banner"></h2>
   <div id="qunit-testrunner-toolbar"></div>
   <h2 id="qunit-userAgent"></h2>
   <ol id="qunit-tests"></ol>
   <div id="qunit-fixture"></div>
 </body>
</html>

После того, как мы убедились, что в браузере файл test.html выполняется, можно настроить
Envjs и Qunit.

Создадим файл setup.js со следующим содержимым:
load('env.rhino.1.2.js');
load('qunit.js');

var starttime = new Date().getTime();

// Envjs/QUnit Bridge.
Envjs({
   // Straight from the Envjs guide.
   scriptTypes: {
       "": true,
       "text/javascript": true
   },
   // Straight from the Envjs guide.
   beforeScriptLoad: {
       'sharethis': function (script) {
           script.src = '';
           return false;
       }
   },

   // Hook QUnit logging to console.
   afterScriptLoad: {
       'qunit': function () {
           var count = 0, testName;

           console.log("* QUnit test runner loaded.");

           // Grab current test name.
           QUnit.testStart = function(name, testEnvironment) {
               testName = name;
           };
           // Override log to display to stdout.
           QUnit.log = function (result, message) {
               // Strip out HTML in results messages.
               message = message.replace(/<\/?.*?>/g, '');
               console.log("  * {%s}(%s)[%s] %s",
                   testName, count++,
                   result ? 'PASS' : 'FAIL', message);
           };
           QUnit.done = function (fail, total){
               var endtime = new Date().getTime();
               var pass = total - fail;
               console.log("\n" +
                   "*****************\n" +
                   "* QUnit Results *\n" +
                   "*****************\n" +
                   "* PASSED: %s\n" +
                   "* FAILED: %s\n" +
                   "* Completed %s tests total in %s seconds.\n",
                   pass, fail, total,
                   parseFloat(endtime-starttime) / 1000.0);
          };
       },

       // Straight from the Envjs guide.
       '.': function (script) {
           script.type = 'text/envjs';
       }
   }
});

Создадим теперь скрипт для запуска тестов run-tests.js:
load('setup.js');

console.log("Starting QUnit tests...");
window.location = "test.html";

Теперь проверим как всё это работает.
Выполним команду
java -cp ~/rhino1_7R2/js.jar org.mozilla.javascript.tools.shell.Main -opt -1 run-tests.js

[duglas@vmstation js]$ java -cp ~/projects/Rhino/rhino1_7R2/js.jar org.mozilla.javascript.tools.shell.Main -opt -1 run-tests.js
[  Envjs/1.6 (Rhino; U; Linux i386 2.6.32.11-99.fc12.i686; en-US; rv:1.7.0.rc2) Resig/20070309 PilotFish/1.2.13  ]
Starting QUnit tests...
* QUnit test runner loaded.
 * { addTwo }( 0 )[ PASS ]  Add nothing.
 * { addTwo }( 1 )[ PASS ]  Add numbers.
 * { addTwo }( 2 )[ PASS ]  Add negatives.

*****************
* QUnit Results *
*****************
* PASSED:  3
* FAILED:  0
* Completed  3  tests total in  3.233  seconds.

[duglas@vmstation js]$ java -cp ~/projects/Rhino/rhino1_7R2/js.jar org.mozilla.javascript.tools.shell.Main -opt -1 run-tests.js
[  Envjs/1.6 (Rhino; U; Linux i386 2.6.32.11-99.fc12.i686; en-US; rv:1.7.0.rc2) Resig/20070309 PilotFish/1.2.13  ]
Starting QUnit tests...
* QUnit test runner loaded.
 * { addTwo }( 0 )[ PASS ]  Add nothing.
 * { addTwo }( 1 )[ PASS ]  Add numbers.
 * { addTwo }( 2 )[ PASS ]  Add negatives.

*****************
* QUnit Results *
*****************
* PASSED:  3
* FAILED:  0
* Completed  3  tests total in  3.466  seconds.

Ура!
Заработали наши тесты.

Работа с отладчиком Rhino

Чтобы вызвать отладчик Rhino необходимо выполнить команду:
java -cp js.jar org.mozilla.javascript.tools.debugger.Main


Автоматизированное тестирование с помощью Rhino + Jasmine


Скачаем Jasmine по ссылке https://github.com/downloads/pivotal/jasmine/jasmine-0.10.0.zip.
Скачаем Jasmie-reporters по ссылке https://github.com/larrymyers/jasmine-reporters.  Этот проект представляет собой набор из подключаемых адаптеров для форматирования результатов теста.

По умолчанию Jasmine использует TrivialReporter для отображения результатов тестов в браузере. Jasmie-reporters содержит ConsoleReporter для вывода результатов в консоль и JUnitXmlReporter - для формирования отчёта в формате JUnit.

Создадим пример теста Jasmine и ConsoleReporter.


Создадим модель Калькулятора.
Для этого создадим файл calc.js со следующим содержимым:

/*
   Класс калькулятора
*/

var Calculator = function(){
return {
    add: function(a,b){
       return a+b;
    },
    sub: function(a,b){
       return a-b;
    },
    div: function(a,b){
       return a/b;
    },
    mul: function(a,b){
       return a*b;
    },
    writeTofile: function(filename, text){
       try {
               var out = new java.io.BufferedWriter(new java.io.FileWriter(filename));
               out.write(text);
               out.close();
               return;
           } catch (e) {}
    }
}
};

Создадим файл calc-test.js с нашими тестами:

           describe('калькулятор',function(){
               var calc = Calculator();
               it('Складываем 1 и 2',function(){
                   var result = calc.add(1,2);
                   expect(result).toEqual(3);
               });
               
               it('Вычитаем 1 и 2',function(){
                   var result = calc.sub(1,2);
                   expect(result).toEqual(-1);
               });
               
           });

Мы написали 1 модуль с 2 тестами. Один тест на сложение двух чисел, а второй тест на вычитание двух чисел. Нам также понадобятся следующие файлы:
env.rhino.1.2.js
jasmine.console_reporter.js
jasmine.css
jasmine.js
jasmine-html.js
jquery-1.6.2.min.js

Создадим файл setup.js, который будет загружать DOM модель в Rhino:
load('env.rhino.1.2.js');
Envjs.scriptTypes['text/javascript'] = true;  

Создадим файл index.html, представляющий собой нашу страницу:
<html>
<head>
<link rel="stylesheet" type="text/css" href="jasmine.css">
 <script type="text/javascript" src="jasmine.js"></script>
 <script type="text/javascript" src="jasmine-html.js"></script>
<script type="text/javascript" src="jquery-1.6.2.min.js"></script>
 <script type="text/javascript" src="jasmine.console_reporter.js"></script>
 <script type="text/javascript" src="calc.js"></script>
 <script type="text/javascript" src="calc-test.js"></script>
</head>
<body>

<script type="text/javascript">
   (function($){
       $(document).ready(function(){
           var jasmineEnv = jasmine.getEnv();
       
         var trivialReporter = new jasmine.TrivialReporter();

         jasmineEnv.addReporter(trivialReporter);
                 jasmineEnv.addReporter(new jasmine.ConsoleReporter());
         
       
           jasmineEnv.execute();
           
           var calc = Calculator();
           //calc.writeTofile('./test.txt','мой простой текст');
       })    
   })(jQuery);
   
   
</script>
   <div  >
   <p>
       http://net.tutsplus.com/tutorials/javascript-ajax/testing-your-javascript-with-jasmine/ - интересная страница по jasmine
       http://www.build-doctor.com/2010/12/08/javascript-bdd-jasmine
       https://github.com/velesin/jasmine-jquery
       http://stanislavvitvitskiy.blogspot.com/2009/04/calling-java-from-xul-applications.html
$ java -cp ~/rhino1_7R2/js.jar org.mozilla.javascript.tools.shell.Main -opt -1 run-tests.js

   </p>    
   </div>
</body>
</html>

Теперь нам нужен файл для запуска непосредственно процесса тестирования. Содержимое файла run-tests.js:
load('setup.js');

console.log("Starting Jasmine tests...");
window.location = "index.html";

Запустим тесты с помощью следующей команды :
[duglas@vmstation jasminetest]$ java -cp ~/projects/Rhino/rhino1_7R2/js.jar org.mozilla.javascript.tools.shell.Main -opt -1 run-tests.js
[  Envjs/1.6 (Rhino; U; Linux i386 2.6.32.11-99.fc12.i686; en-US; rv:1.7.0.rc2) Resig/20070309 PilotFish/1.2.13  ]
Starting Jasmine tests...
Runner Started.
калькулятор : Складываем 1 и 2 ...
Passed.
калькулятор : Вычитаем 1 и 2 ...
Passed.
калькулятор: 2 of 2 passed.
Runner Finished.
2 specs, 0 failures in 0.087s.

Таким образом мы смогли выполнить jasmine тесты, а результат своей работы вывели в консоль.

Очень легко подключить JUnitXmlReporter. Для этого необходимо вставить строчку <script type="text/javascript" src="jasmine.junit_reporter.js"></script>
в раздел подключаемых скриптов и подключить новый адаптер в коде jasmineEnv.addReporter(new jasmine.JUnitXmlReporter());

После прогона тестов будет создан xml файл вида TEST-<имя спецификации>.xml, который можно обрабатывать в JUnit.



Тестирование AJAX вызовов в безбраузерной среде с помощью Jasmine

Пока не очень понятно, что можно написать.
В данном случае возможны следующие виды тестирования:
  1. Unit тесты, которые подменяют AJAX запросы и позволяют выполнять код до вызова AJAX запроса и сразу после него. Также можно подменять ответ от сервера.
  2. Интеграционные тесты, которые выполняют настоящие AJAX запросы.


Jasmine имеет поддержку и тех и других видов тестов.

Также написан плагин jasmine-ajax. Найти его можно по ссылке https://github.com/pivotal/jasmine-ajax. Этот плагин совместим с jQuery и Prototype.  Плагин подменяет AJAX вызовы и таким образом не один запрос не уйдёт на сервер.