16 сентября 2016 г.

Ведение списка работ на проекте НТ

При составлении плана проекта список задач прошел этапы:
  1. Таблица Excel с этапами, участниками и длительностью, а также подсчётом суммарной длительности проекта. Таблица согласовывалась с заказчиком.
  2. Файл Microsoft Project, который составил менеджер проекта после согласования. Основной плюс тут - выставление зависимостей этапов, указание параллельных этапов и учёт выходных.
  3. Одновременно с файлом Microsoft Project создал список Issues для себя команды в проекте на GitLab, расставил там на глаз даты и теги. Удобство в том, что есть теги. И проект по написанию кода можно привязывать к созданным Issues,
  4. Trello, где была создана команда, командные доски и туда были скопированы все Issues с такими же метками как в GitLab. Причина - у Trello доступность выше, чем у GitLab, и можно добавить в команду представителей сторонних компаний.
  5. Продублировал такой же список меток для Outlook и разделил входящие и исходящие письма по ним. Письма, задачи Outlook, календарь - без них никак и их много, надо их группировать, и гибко, без папок и подпапок - метками.
Теперь в GitLab, Trello и Outlook общий набор меток, с почти одинаковыми цветами. Список меток расшириться, пока для Trello сделал метрку "Не по плану", чтобы отделить те задачи, которые не закладывались в плане Excel и Microsoft Project, а которые добавились в ходе работы и, очевидно, увеличат длительность проекта.

Пока план такой - вести задачи одновременно в Trello и в GitLab. В Trello удобно вести все организационные задачи, непривязанные к коду. А когда настанет долгожданный этап разработки, на первое место выйдет GitLab и его Issues и Milestone.
Метки в Trello

Считаю, что метки выбрал удачно.

А разделять почту и задачи Outlook по меткам - пока эксперимент. Метки для писем позволят быстрее отыскать нужное письмо. Раскрасить календарь и список задач.

Также. Чтобы не потеряться в почте Outlook перестал использовать режим представления "Беседа", смотрю на почту, как на отдельные письма. Это позволяет относиться к каждому письму, как в первому и главному. И не пропустить момент, когда в переписке кто-то ждёт от меня решения и ответа. И нет психологического барьера на то, чтобы вдруг послать ответ, когда активная переписка продолжается и уже ушла дальше. Это выглядит, как новая ветка в дереве коммитов. И как известно, не нужно бояться создавать ветки. А в режиме "Беседы" Outlook боишься создать ветку от беседы и затереть обсуждения других.

Менеджер проекта будет вести файл Microsoft Project самостоятельно. Только у него есть программное обеспечение Microsoft Project. Я буду пользоваться GitLab-ом, Trello, почтой, скайпом и телефоном.

16 января 2016 г.

Code Review: JMeter + GitLab

Входные параметры:
  • маленькие короткие проекты разработки нагрузочных тестов;
  • для разработки нагрузочных тестов используется JMeter;
  • уже успешно используется GitLab для хранения кода;
  • команда проекта два человека: опытный и ученик.
Нужно было придумать способ рецензирования кода JMeter-скриптов.

Был опыт работы с TFS, где рецензирование сделано отлично:
  • делаешь commit;
  • указываешь список рецензентов;
  • рецензенты проверяют файлы, затронутые в commit-е;
  • оставленные рецензентами примечания приходят почтой и отображаются в TFS.
В GitLab оставлять комментарии к файлам, затронутым в commit-е нельзя, но можно оставлять примечания к блокам изменений (частям файлов) и ко всему набору изменений (commit-у), возможно, так даже удобнее.

Процесс рецензирования:
  1. Зайти в список Commits (https://gitlab-url.ru/userName/projectName/commits/branchName).
  2. Открыть ссылку на рецензируемый commit, ссылки справа вверху, выглядят например так - 6af0b83c (https://gitlab-url.ru/userName/projectName/commit/6af0b83cCommitID7c0e04).
  3. Просмотреть код JMeter-скрипта глазами, тут нужно привыкнуть, удобно иметь два монитора и слева запускать JMeter а справа запускать браузер и смотреть содержимое commit-а с исходником скрипта.
  4. Оставить комментарии к коду, используется Markdown форматирование, можно цитировать код, прикладывать файлы - широкие возможности, шире, чем при рецензировании кода через Visual Studio в TFS.
  5. Автору commit-а придёт почтовое уведомление со ссылкой на оставленный комментарий.
Пример добавления комментария к строке текста
Пример письма с уведомлением о примечании к набору изменений. В тексте письма есть ссылка на комментарий в GitLab

А если объём изменения небольшой или наоборот очень большой и в нём сложно ориентироваться. То комментарии можно оставлять к самому commit-у, форма для добавления комментария к commit-у находится в самом низу.
Пример добавления комментария ко всему набору изменений


Под коммитом также можно писать:
  • Хороший commit, всё сделано правильно, молодец. 
Автор набора изменений получит этот отклик и будет знать, что рецензирование кода было выполнено.

Для JMeter нет такой среды разработки, которая бы поддерживала интеграцию с системами контроля версий и рецензирование кода. Но для задачи хранения и рецензирования кода можно использовать:
  • GitLab для рецензирования;
  • WinMerge для сравнения наборов изменений;
  • SourceTree для удобной работы с репозиторием;
  • Почтовый клиент для просмотра результатов рецензирования.
 Эти инструменты доступны, с их помощью можно организовать работу команды.

14 января 2016 г.

JMeter + GitLab => SourceTree + WinMerge или организация разработки нагрузочных тестов

В Apache JMeter результатом разработки является файл jmx. Это XML-файл.
Для организации процесса разработки удобно использовать систему контроля версий.

Наиболее удачными инструментами для сохранения результатов разработки JMeter в git считаю:
WinMerge позволяет задать такие настройки, при которых отображение отличий в XML-документах выглядит наиболее органичным и минималистичным.

Максимально гибкие настройки сравнения в WinMerge


А в SourceTree есть возможность легко подключить WinMerge в качестве инструмента сравнения.
Интеграция SourceTree и WinMerge

 Теперь если в SourceTree выделить изменённый файл со скриптом Apache.JMeter и нажать Ctrl+D, то откроется WinMerge и покажет изменения в скрипте. Которые легко отразить в комментарии.
SourceTree
WinMerge
В SourceTree и GitLab есть встроенное средство сравнения - diff. Из-за того, что утилита diff для сравнения XML не приспособлена, при отображении измеенений для XML-файла она показыает слишком много отличий. Особенно если изменений накопилось много.

Поэтому фиксировать изменения нужно часто:
  • каждое изменение фиксировать, не накапливать большие изменения;
  • под каждую задачу создавать ветку.
Иначе будет так, что WinMerge показывает что изменены три строки, а diff будет показывать, что было удалено 1000 строк и добавлено 1003 строки - набор изменений будет огромным.

BSOD при запуске VirtualBox 5 если есть КриптоПро CSP 3.6 R4 или USB 3.0 VGA Adapter

День первый

На Windows 7 x64 были совместно установлены Virtual Box (версии 4 и 5) с расширением Extension Pack и CryptoPro CSP (КриптоПро CSP 3.6 R4 для Windows).

При запуске виртуальной машины через Virtual Box система падала в синий экран. Причина в невозможности совместной работы КриптоПро CSP и Virtual Box.

Чтобы не было синего экрана при запуске виртуальной машины VirtualBox удалил КриптоПро CSP и перезагрузил компьютер. Решение временное, не сумел разобраться как подружить два продукта, а VirtualBox был нужнее, чем КриптоПро.

Помогло выйти на связь VirtualBox + КриптоПро == BSOD сообщение на форуме:
На форуме Крипто Про также есть обсуждение:
Отчёты из программы blueScreenView:

Bug Check String SYSTEM_SERVICE_EXCEPTION
Bug Check Code 0x0000003b
Parameter 1 00000000`c0000005
Parameter 2 fffff800`032735af
Parameter 3 fffff880`0412eb90
Parameter 4 00000000`00000000
Caused By Driver ntoskrnl.exe
Caused By Address ntoskrnl.exe+73c40
File Description NT Kernel & System
File Version 6.1.7601.19110 (win7sp1_gdr.151230-0600)
Major Version 15
Minor Version 7601
A problem has been detected and Windows has been shut down to prevent damage
to your computer.

The problem seems to be caused by the following file: ntoskrnl.exe

SYSTEM_SERVICE_EXCEPTION

Technical Information:

*** STOP: 0x0000003b (0x00000000c0000005, 0xfffff800032735af, 0xfffff8800412eb90, 
0x0000000000000000)

*** ntoskrnl.exe - Address 0xfffff80003292c40 base at 0xfffff8000321f000 DateStamp 
0x5625815c

Вывод - Virtual Box (версии 4 и 5) и CryptoPro CSP (КриптоПро CSP 3.6 R4 для Windows) пока несовместимы на Windows 7 x64 SP1.

================

День второй

Подключил к первому монитору второй монитор, используя USB 3.0 VGA Adapter. Модель устройства - Fresco Logic FL200 USB Display Adapter. Если подключить адаптер до включения виртуальной машины, то порядок. А если подключать адаптер во время работы виртуальной машины Virtual Box, то будет снова синий экран.


Bug Check StringIRQL_NOT_LESS_OR_EQUAL
Bug Check Code0x0000000a
Parameter 100000000`00000088
Parameter 200000000`00000002
Parameter 300000000`00000001
Parameter 4fffff800`032579e6
Caused By Driverntoskrnl.exe
Caused By Addressntoskrnl.exe+73c00
File DescriptionNT Kernel & System
File Version6.1.7601.19110 (win7sp1_gdr.151230-0600)
Major Version15
Minor Version7601

A problem has been detected and Windows has been shut down to prevent damage
to your computer.

The problem seems to be caused by the following file: ntoskrnl.exe

IRQL_NOT_LESS_OR_EQUAL

Technical Information:

*** STOP: 0x0000000a (0x0000000000000088, 0x0000000000000002, 0x0000000000000001, 
0xfffff800032579e6)

*** ntoskrnl.exe - Address 0xfffff80003276c00 base at 0xfffff80003203000 DateStamp 
0x5684191c

Из того, что видно перед ошибкой - диспетчер устройств (HAL) сообщает, что подключено новое USB 2.0 устройство, а затем система падает. Диспетчер устройств не прав, так как подключается USB 3.0 устройство в USB 3.0 порт.

Возможно, просто совпадение, два BSOD-а подряд. И причина BSOD в реализации драйверов для Fresco Logic FL200 USB Display Adapter.

Но есть предположение, что причина ошибок в реализации поддержки USB 2.0 / USB 3.0 в VirtualBox. А особые возможности поддержки USB появляются при установке Oracle VM VirtualBox Extension Pack.

Удалить VirtualBox не хотелось бы, иногда бывает нужен. А удалить Extension Pack могу запросто. Надеюсь, что после удаления VirtualBox Extension Pack синих экранов больше не будет. И можно будет повторно установить КриптоПро CSP 3.6 R4 для Windows и пользоваться двумя мониторами.


12 января 2016 г.

log4j (v.1) пример настройки трассировки (TRACE) нужного модуля

Настройка логирования для log4j версии 1
Пусть есть приложение, которое использует библиотеку log4j-1.2.17.jar

Параметры для log4j удобно передавать через внешний файл. Внешний файл удобно редактировать.

Запуск приложения с указанием конфига логов

Можно создать командный файл start.SampleConsoleServer.bat с текстом:
java -jar ^
    -Dlog4j.configuration=file:log4j.properties ^
    Server.jar ^
    com.blogger.server.SampleConsoleServer

Предполагается, что в одном каталоге находится три файла:
  • Server.jar - java-приложение, реализуещее класс com.blogger.server.SampleConsoleServer;
  • log4j.properties - файл настроек логирования для log4j версии 1;
  • start.SampleConsoleServer.bat - командный файл для запуска Server.jar.
Если бы файл log4j.properties находится не в текущем каталоге, а в каталоге на уровень выше, то надо бы было написать:
java -jar ^
    -Dlog4j.configuration=file:../log4j.properties ^
    Server.jar ^
    com.blogger.server.SampleConsoleServer

Пример содержимого файла log4j.properties

# Default logging level, log on console only (add ',file' to log on file as well)
#log4j.rootLogger=TRACE, stdout, fileTrace

log4j.logger.com.blogger.server.SampleConsoleServer=TRACE, stdout, fileTraceServer
log4j.logger.com.blogger.client=TRACE, stdout, fileTraceClient 

#Общий вывод в консоль
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %p %c{1}:%L - %m%n#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}\t%p\t%c{1}:%L\t-\t%C\t-\t%l\t-\t%M\t-\t%m%n
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}\t%p\t-\t%l\t-\t%m%n

#Лог сервера
log4j.appender.fileTraceServer=org.apache.log4j.RollingFileAppender
log4j.appender.fileTraceServer.maxFileSize=100MB
log4j.appender.fileTraceServer.maxBackupIndex=50
log4j.appender.fileTraceServer.file=trace.file.server.log
log4j.appender.fileTraceServer.layout=org.apache.log4j.PatternLayout
#log4j.appender.fileTraceServer.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}\t%p\t%c{1}:%L\t-\t%C\t-\t%l\t-\t%M\t-\t%m%n
log4j.appender.fileTraceServer.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}\t%p\t-\t%l\t-\t%m%n 

#Лог клиента
log4j.appender.fileTraceClient=org.apache.log4j.RollingFileAppender
log4j.appender.fileTraceClient.maxFileSize=100MB
log4j.appender.fileTraceClient.maxBackupIndex=50 
log4j.appender.fileTraceClient.file=trace.file.client.log 
log4j.appender.fileTraceClient.layout=org.apache.log4j.PatternLayout 
#log4j.appender.fileTraceClient.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}\t%p\t%c{1}:%L\t-\t%C\t-\t%l\t-\t%M\t-\t%m%n 
log4j.appender.fileTraceClient.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}\t%p\t-\t%l\t-\t%m%n

Описание конфигурационного файла log4j.properties


1. Указываются настройки для логгеров с разными именами

# Default logging level, log on console only (add ',file' to log on file as well)
#log4j.rootLogger=TRACE, stdout, fileTrace

log4j.logger.com.blogger.server.SampleConsoleServer=TRACE, stdout, fileTraceServer
log4j.logger.com.blogger.client=TRACE, stdout, fileTraceClient

Настройки логирования для всех логгеров

Можно настроить логирование которое будет применяться логгерам log4j с любым именем. Ключевым словом тут является rootLogger. Далее указываются Уровень логирования и куда записывать логи. В примере выше такая настройка закомментивана.
# Default logging level, log on console only (add ',file' to log on file as well)
log4j.rootLogger=TRACE, stdout, fileTrace

Но если бы она не была закомментирована, то сообщения с уровнем TRACE и выше для любого логгера записывались бы в лог согласно настройкам
log4j.appender.stdout
и
log4j.appender.fileTrace

Настройки логирования для конкретного класса и его подклассов

Обычно, логгеры создаются с именем, соответствующим имени класса. Пример java-кода ниже.
package com.blogger.server;

import org.apache.log4j.Logger;

public class SampleConsoleServer {
    protected static final Logger LOG = Logger.getLogger(SampleConsoleServer.class);

    public void processRequest(String request) {
        if (LOG.isTraceEnabled()) LOG.trace("processRequest(String request)");
        //...
        if (request == null) {
            LOG.fatal("Request is null");
            throw new NullPointerException();
        }
        //...
    }
}

Если логгер создавался по описанию класса, то имя логгера соотвествует полному имени класса: com.blogger.server.SampleConsoleServer.
В файле log4j.properties настройки для такого именованного логгера задаются после указания имени логгера:

log4j.logger.{Имя логгера}={Уровень}, {Обработчик 1}, {Обработчик 2}, ...
В имени логгера могут быть точки. Наличие точек в имени логгера и создаёт особую магию, позволяя задать настройки для конкретного класса или для логгеров всех классов из пакета, но об этом позже.

Пример настроек логирования для конкретного класса в примере выше это строка:
log4j.logger.com.blogger.server.SampleConsoleServer=TRACE, stdout, fileTraceServer

Тут говорится для логгера с именем com.blogger.server.SampleConsoleServer нужно все сообщения с уровнем TRACE и выше записывать в лог согласно настройкам с именами stdout и fileTraceServer.

Если бы в классе  SampleConsoleServer был подкласс ServerSettings с логгером имя которого com.blogger.server.SampleConsoleServer.ServerSetting, то также бы использовались настройки логирования:
log4j.logger.com.blogger.server.SampleConsoleServer=TRACE, stdout, fileTraceServer

Так как они соответствуют имени логгера.

Настройки логирования для всех классов из указанного пакета

Также в примере есть настройка для логгера com.blogger.client.
log4j.logger.com.blogger.client=TRACE, stdout, fileTraceClient 

Тут предполагается, что com.blogger.client - пакет, а не название класса. Что в этом пакете есть классы:
  • com.blogger.client.Client1,
  • com.blogger.client.Client1.Settings,
  • com.blogger.client.DefaultClient,
  • com.blogger.client.AbstractClient.
Что для этих классов созданы логгеры с соотвествующими именами. И все эти логгеры будут использовать настройки логирования com.blogger.client.

2. Задаются настройки обработчиков логов

#Общий вывод в консоль
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %p %c{1}:%L - %m%n#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}\t%p\t%c{1}:%L\t-\t%C\t-\t%l\t-\t%M\t-\t%m%n
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}\t%p\t-\t%l\t-\t%m%n

#Лог сервера
log4j.appender.fileTraceServer=org.apache.log4j.RollingFileAppender
log4j.appender.fileTraceServer.maxFileSize=100MB
log4j.appender.fileTraceServer.maxBackupIndex=50
log4j.appender.fileTraceServer.file=trace.file.server.log
log4j.appender.fileTraceServer.layout=org.apache.log4j.PatternLayout
#log4j.appender.fileTraceServer.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}\t%p\t%c{1}:%L\t-\t%C\t-\t%l\t-\t%M\t-\t%m%n
log4j.appender.fileTraceServer.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}\t%p\t-\t%l\t-\t%m%n 

#Лог клиента
log4j.appender.fileTraceClient=org.apache.log4j.RollingFileAppender
log4j.appender.fileTraceClient.maxFileSize=100MB
log4j.appender.fileTraceClient.maxBackupIndex=50 
log4j.appender.fileTraceClient.file=trace.file.client.log 
log4j.appender.fileTraceClient.layout=org.apache.log4j.PatternLayout 
#log4j.appender.fileTraceClient.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}\t%p\t%c{1}:%L\t-\t%C\t-\t%l\t-\t%M\t-\t%m%n 
log4j.appender.fileTraceClient.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}\t%p\t-\t%l\t-\t%m%n

Имена обработчиков логов

У обработчиков логов есть имена. В примере выше это:
  • stdout;
  • fileTraceServer;
  • fileTraceClient.

Тип  обработчика логов

Для лога указывается тип. Самые ходовые типы в моей практике:
  • org.apache.log4j.ConsoleAppender - вывод на консоль;
  • org.apache.log4j.RollingFileAppender - вывод в файл.

Формат лога

Для большинства ситуаций отладочного лога достаточно короткого формата:
%d{yyyy-MM-dd HH:mm:ss}\t%p\t-\t%l\t-\t%m%n

В лог запишутся:
  • %d дата в формате yyyy-MM-dd HH:mm:ss;
  • %p уровень события;
  • %l строка кода с указанием класса, метода, имени исходного файла и номера строки;
  • %m добавляемое в лог сообщение;
  • %n перевод строки;
  • \t символы табуляции;
  • - разделители.
Пример строк лога, соотвествующих указанному формату:
2015-12-14 18:53:15 TRACE - com.blogger.client.Handler.read(Handler.java:330) - 
2015-12-14 18:53:15 TRACE - com.blogger.client.Handler.read(Handler.java:346) - Read token duration: 185048 ms
2015-12-14 18:53:15 ERROR - com.blogger.client.Handler.read(Handler.java:360) - ProxyServer closed channel
2015-12-14 18:53:15 FATAL - com.blogger.client.Client2.run(Client2.java:164) - ProxyServer closed read channelData
com.blogger.exception.ReadControlChannelException: ProxyServer closed read channelData
 at com.blogger.client.Handler.read(Handler.java:361)
 at com.blogger.client.Handler.process(Handler.java:219)
 at com.blogger.client.Client2.run(Client2.java:151)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 at java.lang.Thread.run(Thread.java:745)
2015-12-14 18:53:15 TRACE - com.blogger.client.Client2.run(Client2.java:170) - Close all
2015-12-14 18:53:15 TRACE - com.blogger.client.Client2.tryClose(Client2.java:183) - Close channel java.nio.channels.SocketChannel[connected local=/192.168.150.58:55851 remote=/77.88.99.00:1234]

или без подсветки смысловых частей:
2015-12-14 18:53:15 TRACE - com.blogger.client.Handler.read(Handler.java:330) - 
2015-12-14 18:53:15 TRACE - com.blogger.client.Handler.read(Handler.java:346) - Read token duration: 185048 ms
2015-12-14 18:53:15 ERROR - com.blogger.client.Handler.read(Handler.java:360) - ProxyServer closed channel
2015-12-14 18:53:15 FATAL - com.blogger.client.Client2.run(Client2.java:164) - ProxyServer closed read channelData
com.blogger.exception.ReadControlChannelException: ProxyServer closed read channelData
 at com.blogger.client.Handler.read(Handler.java:361)
 at com.blogger.client.Handler.process(Handler.java:219)
 at com.blogger.client.Client2.run(Client2.java:151)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 at java.lang.Thread.run(Thread.java:745)
2015-12-14 18:53:15 TRACE - com.blogger.client.Client2.run(Client2.java:170) - Close all
2015-12-14 18:53:15 TRACE - com.blogger.client.Client2.tryClose(Client2.java:183) - Close channel java.nio.channels.SocketChannel[connected local=/192.168.150.58:55851 remote=/77.88.99.00:1234]

По такому логу можно увидеть трассировку выполнения всех методов. Ошибки. Номера строк, в которых произошли логируемые события. Удобно, понятно.

1 февраля 2015 г.

Добавление подсветки синтаксиса highlightjs.org

Добавление подсветки синтаксиса highlightjs.org в blogger.com.

Подготовка

using Мозг;
using Интернет;
public class Blog : Blogger
{
var help1 = Интернет.Загрузить(
    @"https://highlightjs.org/");
var help2 = Интернет.Загрузить(
    @"http://stackoverflow.com/questions/10936854/highlight-syntax-in-pre-tags-with-highlight-js");

var jsLibrary = Интернет.Загрузить(
    @"//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/highlight.min.js");
var cssFile = Интернет.Загрузить(
    @"https://highlightjs.org/static/demo/styles/github.css");
}
Прочитал на сайте проекта, что js-библиотеку можно грузить с cloudflare.

Выбор стиля подсветки на https://highlightjs.org/static/demo/

Также выбрал в качестве стиля стиль github. Ссылку на github.css свзял также с сайта проекта.

Правка шаблона

В начало шаблона добавить ссылки на библиотеку и стиль

После секции с базовыми стилями шаблона:

<b:template-skin>
    ...
</b:template-skin>
добавил ссылки на highlight.min.js и github.css.
<link href='https://highlightjs.org/static/demo/styles/github.css' rel='stylesheet'/>
<script src='//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/highlight.min.js'/>
Добавление ссылок в шаблон после секции template-skin

Сохранил шаблон.

Код запуска подсветки

Добавил в шаблон виджет "HTML/JavaScript". Открыл форму редактирования виджета, и написал код запуска подсветки синтаксиса:
<script type='text/javascript'>
//<![CDATA[
    var aCodes = document.getElementsByTagName('pre');
    for (var i=0; i < aCodes.length; i++) {
        hljs.highlightBlock(aCodes[i]);
    }
//]]>
</script>

Виджет "HTML/JavaScript", разместил внизу страницы.

Размещение виджета "HTML/JavaScript" внизу макета

14 января 2015 г.

Списки слов для генерации тестовых данных

Списки слов из ru.wikipedia.org, открытые в Sublime Text 2
Списки слов из ru.wikipedia.org, открытые в Sublime Text 2

Для нагрузочного тестирования готовлю 10 000 уникальных организаций и 50 000 уникальных пользователей. Для организаций и имён нужны подходящие словари. И их удобно достать на общедоступных сайтах, которые разрешают использование своего содержимого. Подготовил такие словари, убрав лишнее, сделав их лучше.

Когда-то брал такие данные из других информационных систем (грабил караваны). Создание своих наборов тестовых данных, более надёжное и более весёлое занятие.

Надёжность использования в полном контроле над данными, удобстве отладки и предсказуемости. Что важно при проектировании тестов.

Весело же бывает, когда пользователь или заказчик, решит поработать в системе, находящейся под нагрузкой. И получит входящее сообщение от Барабашкиной Ираиды Анатольевны, сотрудницы компании ООО "Большие погремушки". А содержимое текста сообщения, при использовании рандомизации и не использовании lorem ipsum (рыбы) может быть шедевральным.
В словаре OpenOffice есть много литературных слов, комбинация которых повеселит заказчика


Использовал как-то словарь проверки орфографии OpenOffice, для генерации данных в тестовой системе, не учёл, что там есть слова всех тематик, есть и ругательства. Потом руками вычищал словарь от всего, что может не понравится.

Словари:
  1. Существительные среднего рода.10854.
  2. Мужские фамилии.13529.
  3. Мужские имена. 312.
  4. Мужские отчества.140.
  5. Женские имена. 439.
  6. Прилагательные.1002.

Допустим, создаётся 10 000 организаций. Для этого генерируется 10 000 уникальных наименований организаций. Пригодится список существительных среднего рода.

Существительные:
  • наполнение;
  • напоминание;
  • направление;
  • ...

Соответствующие названия организаций, которые можно создать из списка слов:

  • ООО "Наполнение";
  • ООО "Напоминание";
  • ООО "Направление";
  • ...
Если предприятия делятся на классы (малое, среднее, большое), то название класса также можно отразить в наименовании:
  • ООО "Малое напряжение";
  • ООО "Среднее напудривание";
  • ООО "Большое напускание";
  • ...
Использование списков фамилий, имён и отчеств очевидно для формирования ФИО тестовых пользователей. Наличие тринадцати тысяч мужских фамилий позволяет создать столько групп пользователей-однофамильцев, которые будут работать в одинаковых организациях (более десяти тысяч).


Источники данных:

Windows Command Line Cheat Sheet

3 января 2015 г.

Xfce4, решение проблемы с восстановлением сеанса

Использую xfce4 как окружение по умолчанию. В xfce4 есть возможность сохранения сеанса при выходе. Сохранение сеанса — аналог настройки автозагрузки в Windows.
С сохранением сеанса всё хорошо. А вот с восстановлением могут быть проблемы.
xfse4 session save
Сохранение сеанса при выходе


12 сентября 2014 г.

Онтологии. OWL 2.0

Рассказывал про применение онтологий, OWL 2.0 и сравнение возможностей OWL с KG (Knowledge Guide, разработка ИжГТУ). Дело было в 2012 году. Составил схему лекции.

Схема лекции по OWL 2.0 (узлы с примерами свёрнуты)


7 сентября 2014 г.

Поделить текстовый файл на части

Поделить текстовый файл на части

Назначение

Если нужно открыть большой Log-файл в Windows, но ни один из установленных инструментов не позволяет открыть файл такого объёма (100-2000 МБайт). То можно поделить файл на меньшие части, используя командный сценарий (bat-ник). Возможность выполнить bat-файл всегда есть в Windows. Расход оперативной памяти при выполнении разделения будет приемлемым - двойной размер файла (600 МБайт ОЗУ для файла в 300 МБайт).

Текст сценария SplitBigTextFile.bat

echo off
setlocal enabledelayedexpansion

set fileName=%1
set partSize=%2
set partExt=%3

set index=0
set partNumber=0

for /F "tokens=*" %%i in (!fileName!) do (
set /a index+=1
if !index! GTR !partSize! (
set /a partNumber+=1
set index=0
)
@echo %%i >> !fileName!.!partNumber!.!partExt!
)

Параметры

Параметры выполнения скрипта, должны быть переданы при вызове:
  1. Путь к текстовому файлу, на основе которого надо создать несколько маленьких файлов.
  2. Максимальное количество строк, в маленьком файле.
  3. Расширение для создаваемых маленьких файлов.

Пример

Пример вызова:
SplitBigTextFile.bat D:\BigLog.log 10000 log

В результате работы сценария рядом с файлом D:\BigLog.log будут созданы файлы:
  1. D:\BigLog.log.1.log
  2. D:\BigLog.log.2.log
  3. D:\BigLog.log.3.log
  4. ...
В каждом из которых будет только по 10000 строк текста. В последнем файле, может быть менее 10000 строк.

А такие небольшие файлы, уже можно будет просмотреть в имеющемся в данный момент текстовом редакторе.

update 11 марта 2015. При работе потребуется ОЗУ в два раза больше размера файла. Для начала работы объём свободной оперативной памяти должен быть больше объёма файла. Так если файл размером 2 ГБайт, то при свободных 2,3 ГБайт процесс запустится и будет работать. Файлы более 2 ГБайт не разделял таким способом — памяти не хватает. Обработка некоторых текстовых файлов с кодировкой UCS-2 Little Endian не работает изначально (так выгружаютя файлы реестра *.reg). Чтобы заработала можно с помощью команды type перенести содержимое сбойного файла в новый файл командой:

type сбойныйФайл.txt > новыйФайл.txt
теоретически, могут потеряться данные, так как кодировка файла сменится на ANSI, но на практике данные не теряются — большая часть символов латинские.

Выбрать случайную запись из таблицы

Выбрать случайную запись из таблицы

Назначение

При подготовке к объёмному тестированию нужно наполнить базу данных связанными тестовыми данными. Если в тестируемой системе нет сложных прав доступа и фильтраторов, то для ускорения процесса заполнения базы данных данными можно использовать SQL-запросы. Нагенерировать связанных данных, работая с базой напрямую. При этом нужно выбирать случайные записи из связанных таблиц.

Теория

Для выборки случайной записи используется сортировка по случайному значению.
Из отсортированной выборки выбирается первая запись.

Для получения случайного значения подойдут функции:
  • RAND();
  • NEWID().

Выбор первой записи задаётся инструкцией TOP(1).

Примеры

Пример результирующего SQL-запроса:
SELECT TOP(1) "ID", "Text"
FROM "DataTable"
ORDER BY NEWID()

Боле быстрый код:
SELECT TOP(1) "ID", "Text"
FROM "DataTable"
ORDER BY RAND()

Если нужно наложить фильтр на данные из таблицы, используется инструкция WHERE.
SELECT TOP(1) "ID", "Text"
FROM "DataTable"
WHERE "ID" >= 100 AND "ID" <= 1000
ORDER BY RAND()

Примечание

Если надо будет SQL-запросами создать миллионы связанных записей. То от идеи случайной выборки лучше отказаться.
Сценарий заполнения базы данных зависнет. В случае огромного количества записей, надо использовать вычисления. Это возможно, если в качестве идентификаторов используются последовательные целые числа.

Например, в таблице "Links" в поле "FolderID" нужно вставить случайное значение из поля "ID" таблицы "Folders", где "ID" - целочисленный счётчик.
Заранее создаётся необходимое тестовое количество записей в "Folders" с подряд идущими значениями 5678...105678.
И при вставке не сканируем таблицу "Folders", а сразу вычисляем случайное значение "ID" из интервала 5678...105678, с помощью RAND() и ROUND().

SELECT @ID = @НачалоИнтервала + ROUND(RAND() * (@КонецИнтервала - @НачалоИнтервала), 0)

Пример с интервалом 5678...105678:
SELECT @ID = 5678 + ROUND(RAND() * (105678 - 5678), 0)