Thursday, December 22, 2011

Разработка через тестирование. Организовываем Додзё



Сегодня в Luxoft UBS DC удалось организовать двухчасовую сессию посвященную TDD и coding dojo практикам.


Было минимум теории. Благодаря SmartBoard удалось достичь максимальной вовлеченности участников.


Всего было 8 человек, каждый успел побывать в роли pilot и copilot. 


Тренировались на кате Game Of Life


К сожалению мы не успели закончить полностью, закончили лишь на 80 - 90 % реализации.


Зато провели ретроспекцию, что очень важно в такого рода мероприятиях.


Среди недостатков отметили отсутвие дизайн сессии и работы у WiteBoard. Кроме того специфика Dojo привнесла некую сумбурность в процесс, потому как приходилось каждые 7 минут ротировать участников.


Однако, всем понравилось, и все изъявили желание продолжать проведения такого рода мероприятий, что скорее всего приведет к образованию KievGojo.


Для тех кому интересна эта тема предлагаю посмотреть пятиминутный ролик о том как организовать подобного рода мероприятие. А также добро пожаловать на сайт энтузиастов coding dojo.

В дальнейшем планируется провести ряд практических и теоретических сессий по методологиям, инструментам и подходам к написанию тестов.

Пока все.

Tuesday, December 20, 2011

Надоел Enterprise. Немного геометрии

Недавно наводил порядок в архивах и наткнулся на папку с диссертацией. покопался немного в исходниках матлаба и решил проверить рабочее ли все?

Взор у меня пал на скрипт Circles.m. Скажу честно код совершенно нечитабелен. И если бы его когдато написал не я то наверно я черти с два понял что там написано.

сценарий таков:

1. Есть изображение черно белое, какой то слитной фигуры, например самолета. Вот пример
2. Делаем над ним двумерное преобразование Гильберта. В результате мы получим точки в местах перегибов контура фигуры - назовем их характерными точками
3. А теперь геометрия. Задача найти центр масс слитной фигуры, в данном случае самолета, и провести концентрические окружности с центом в центре масс фигуры. Представить эти окружности как радар, и предположить что если характерная точка в пределах видимости радара, то засветить её. Должно получиться что то типа вот этого:
проблема в том что характерные точки вовсе не обязательно будут лежать на концентрических окружностях радар. Необходимо сделать допущение что если характерная точка в непосредственной близости от радара, то она засветится, как то вот так

черным цветом  обозначил светящиеся точки, не лучший вариант но тем не менее понятно вроде.

Теперь о реализации.

Писалось это очень давно и на скриптовом языке для научных вычислениях Matlab.

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


for r = 10 : 10 : 130
        %рассчет координат точек окружности радара - 100 точек с радиусом r и центром в xr,yr
        circlePoints = calcCirclePoints(xr, yr, r, 100, 0);
        hold on
        plot(circlePoints(1,:), circlePoints(2,:), 'r-')
        hold on
        for i = 1 : length(arClasterData)
            d = sqrt((arClasterData(i,1) - xr)^2 + (arClasterData(i,2) - yr)^2);
            if d >= (r-1)
%уравнение прямой ax+b рассчитаем коэффициенты a и b для прямой проходящей от центра до характерной точки
[a, b] = calcLineKoef(xr, yr, arClasterData(i,1), arClasterData(i,2));
%а теперь рассчитаем расстояние от характерной точки до окружности радара
d = pointToCircleDist(arClasterData(i,1), arClasterData(i,2), xr, yr, r, a, b);
%если расстояние меньше 1 то засветим точку
                if d <= 1
                    hold on
                    plot(arClasterData(i,1), arClasterData(i,2),'k*')
                end
            end
        end
    end

Самой интересной функцией тут является на мой взгляд расчет расстояния от точки до окружности. Как известно это можно сделать с помощью касательной к окружности, а именно нахождения координат точки соприкосновения касательной и окружности и расчета Евклидова расстояния от этой точки до характерной точки. Сделал я это так


function d = pointToCircleDist(xp, yp, xr, yr, r, a, b)

switch checkCircleSector(xr, yr, xp, yp)
    case 1
        y = yr + r * sin(abs(atan(a)));
        x = xr + r * cos(abs(atan(a)));
    case 2
        y = yr + r * sin(pi - abs(atan(a)));
        x = xr + r * cos(pi - abs(atan(a)));
    case 3
        y = yr + r * sin(pi + abs(atan(a)));
        x = xr + r * cos(pi + abs(atan(a)));
    case 4
        y = yr + r * sin(2*pi - abs(atan(a)));
        x = xr + r * cos(2*pi - abs(atan(a)));
end
d = sqrt((xp - x)^2 + (yp - y)^2);

В зависимости от того в каком квандранте находится характерная точка, координаты точки касания рассчитываются по разному


Как то так. На мой взгляд интересно.

Thursday, December 1, 2011

Software development values

Давненько не писал в блог. Очень много работы в последнее время, зачастую нет времени банально пойти поесть или даже ... нет не будем об этом.
Перебирая почту нашел рассылку от InfoQ в которой была ссылка на книгу "Patterns of Agile Practice of Adoption The Technical Cluster". Решил поделиться мыслями о прочитанном.
Business Value.
В процессе жизненного цикла Delivery какой то функциональности, я уделяю много внимания деталям, я не хочу сказать что это плохо, наоборот, продумывая все возможные варианты и углубляясь в детали я делаю свой продукт лучше. Но, лучше для кого? для себя? потому что я разобрались с очередной нетривиальной задачей и потешили свое самолюбие, или для конечного пользователя?
Для меня, поле моего интереса заканчивается примерно тогда, когда я написал код, который по моему хорошо работает и решает описанную задачу. Есть мнение что для аналитика он заканчивается тогда, когда он провел анализ и разложил все по полочкам, так, чтобы это понятно было мне, как разработчику, а для специалиста по качеству, когда функциональность протестирована и все может идти в релиз. Я конечно сейчас говорю о людях которые получают кайф от своей работы, а не приходят туда для того чтобы отметится, потому что иначе не переведут на карточку ЗП, и вообще попросят написать заявление по собственному желанию. Потому что с такими нужно прощаться сразу так чтобы они не тянули команду вниз во всех смыслах этого слова.
Человек существо эгоистичное, но если поднять немного выше голову то можно найти еще источник удовлетворения своего самолюбия. И этим источником является конечный пользователь, кастомер, не знаю как вы его называете. Но, надеюсь мы все понимаем одно и тоже под этими словами.
Кастомер существо благодарное, и если говорить о материальной стороне, то если вы делаете качественный продукт, то с вами перезаключат контракт, если ваш продукт сэкономил кучу денег кастомеру то наверняка он с вами поделится и т.д. или вообще отбросим материальную сторону и представим, что вашей фичей стали пользоваться кучу народу и благодарны вам за её.
Мораль.
Доводите свой продукт общими усилиями, а не кидайте дело, когда оно выходит за пределы вашей специализации.
Собирайте отзывы от конечных пользователей, в конце концов, если не учитывать бабло которое вам платят, это самое главное, ибо в отзыве отражается качество анализа, технического решения и тестирования
Вырабатываете практики, которые вам позволят избавиться от рутинной работы во время Delivery.
Не бойтесь экспериментировать, пробуйте разные подходы и практики, выступайте в разных ролях в команде, это позволит лучше понять все стороны и этапы разработки анализа и тестирования.
Эволюционируете всей командой а не по частям, делитесь опытом.
Заражайте остальные команды которые вокруг вас своей производительностью.
В противном случае ~40 процентов жизни, которую вы проводите на работе превращается в угрюмое и унылое времяпрепровождение.

Wednesday, October 12, 2011

Git and Continuous Delivery


I wonder, how to establish development process with git or other distributed source control system and Continious Delivery pattern.
I've seen a presentation by Linus Torvalds, where he explained how are they use git for Linux development. So it's an hierarchical structure of commiters based on trust with Linus on the top. Linus trusts to some people and can pull code from them. These people have their own teams which they trust and pull changes and so on.
As a result Linus has fork of Linux source code which can be released. I know that Linux was migrated on GiHub. I suspect that only Linus can push changes there (or few people including Linus)
So GitHub remote repository can be treated as a mainline. Continuous Delivery pipelines use it for releases.
So i can see two ways to establish the process of commits.
1st as i described earlier with Linux
2nd - everybody can push to mainline (GitHub) and no hierarchy. I cannot see any benefits of distributed source control system in this case.

What do you think? What is best approach to build delivery process in this case? Or distributed source control systems are not the best choice for continuous delivery, and you'd better use centralized?

Wednesday, August 24, 2011

Functional testing Grails app with Geb. User story 1

User Story Description.
As a head of Sales department, i would like to see all orders from PreSellers and VanSellers.
I would like to see following info on the Orders Grid

  • Order Number
  • Seller
  • Customer
  • Sum
  • Customer Address
  • Status
  • Type
  • Order Date
  • Discount
  • Discount %
  • Payment type
  • Price
  • if Credit Limit Passed
  • is Stock Limit Passed
  • Shipped Date
  • Description
I also would like to be able to expand each row and see detailed description of each order, including Order Details

Architecture and Design
So, let's describe brief architecture of this solution. It's quite easy. 
We already have database solution of Orders data structure, which is on production. I prefer to provide read only access to Web Application using views.
We will use Grails Web framework as underlying technology for web application.
We will use GWT to implement views for Orders Enquiry (because i have Java background but not Java Script, unfortunately)

What about testing?
Ok. I prefer to be test driven as match as possible. But it's challenged task for UI tests. Unfortunately it's difficult to provide TDD for UI unless you have implemented it.
Imagine we will have simple grid, each row can be expanded and form appears. Form consists of 3 tabs:
  • Order Information
  • Customer Information
  • Order details with grid on it
Let's describe possible UI tests using mmm... Spock?

def "lets open order page and vlidate if 4 orders are seen"(){
when:
to OrdersPage
then:
assert ordersGrid.size == 4
}

More tests?


def "i would like to expand rows to see order info"(){
when:
to OrdersPage
and:
ordersGrid.expandRow(0).click()
then:
def now = new Date()
def df = new SimpleDateFormat('yyyy-MM-dd')
ordersGrid.expandedForm.orderInfoTab.nomNumber.value() == '000-00000-00'
ordersGrid.expandedForm.orderInfoTab.orderedDate.value() == df.format(now)
ordersGrid.expandedForm.orderInfoTab.shippedDate.value() == df.format(now)
ordersGrid.expandedForm.orderInfoTab.description.attr('value') == 'description'
ordersGrid.expandedForm.orderInfoTab.summ.value() == '10.30'
ordersGrid.expandedForm.orderInfoTab.seller.value() == 'PreSeller Ivanov'
}

def "i would like to expand rows to see customer info"(){
when:
to OrdersPage
and:
ordersGrid.expandRow(0).click()
then:
ordersGrid.expandedForm.customerInfoTab.customer.value() == 'Some test customer'
ordersGrid.expandedForm.customerInfoTab.salesOutlet.value() == 'Sales outlet'
ordersGrid.expandedForm.customerInfoTab.dept.value() == '0.00'
ordersGrid.expandedForm.customerInfoTab.creditLimit.value() == '1000.00'
}

def "i would like to expand rows to see order rows"(){
when:
to OrdersPage
and:
ordersGrid.expandRow(0).click()
then:
ordersGrid.expandedForm.orderDetailsTab.details.size() == '3'
}



What are to OrdersPage and ordersGrid.expandedForm.orderDetailsTab.details.size() == '3' you would ask. This is Geb and it's page objects.
I think that i should not explain what all these tests are doing. I think the main question is how are they doing their stuff.

Here are top level steps that you should do in order to lunch your UI tests using grails.
  • add geb grails plugin
  • add spock-groovy grails plugin
  • add build-test-data grails plugin in order to generate your data for tests
  • Place your tests in test/functional source directory
  • use grails command test-app -functional
What is grails test-app -functional
Actually this is command for triggering functional test against grails web application. The life-cycle of grails functional test is straightforward:
  • Build grails application
  • deploy it in servlet container instance (Tomcat is used)
  • start web application in tomcat
  • run functional test against running grails application
  • shutdown web application and tomcat instance
You can configure grails functional test in Continuous Integration system.

TDD
 So tests are written and it's time for coding. But it's not really true. We need to generate data for our test and do it automatically for each test run and clean previous tests results.

Test data generation
Lets create grails controller which will be responsible for data generation. And thus we will be available to trigger it from browser to generate test data.
All controllers are placed in grails-app/controllers source folder. Also there is naming convention about controllers. Their class names should have Controller tail. For instance TestController. This class will be treated as controller class. Grails has a spring MVC under the hood.
So here is our controller with two closures for generating and deleting test data for our tests

class TestController {

def generateOrders = {
OrdersBuilder.build{
orders '000-00000-00', '000-00000-01', '000-00000-02', '000-00000-03'

Date now = new Date()
order('000-00000-00').hasType('Local Storage').and().hasOrderDate(now)
order('000-00000-01').hasType('Main Stoarage ').and().hasOrderDate(DateGroovyMethods.previous(now))
order('000-00000-02').hasType('Direct Move').and().hasOrderDate(DateGroovyMethods.previous(DateGroovyMethods.previous(now)))
order('000-00000-03').hasType('indirrect Move').and().hasOrderDate(DateGroovyMethods.previous(DateGroovyMethods.previous(DateGroovyMethods.previous(now))))
}.each {
it.value.save(flush:true)
}

render 'orders generated succesfully'
}

def deleteOrders = {

Orders.findAll().each { it.delete()  }
render 'orders deleted succesfully'
}
}

And it's available through URLs
and

I've used DSL technique (which i'll describe in my future posts) for generation data in order to be more readable by user. As a result of this DSL execution we will have 4 Orders with 000-00000-00 01 02 03 order numbers. Now the only thing we should do is to visit these URLs from our test to delete previous data and generate a new one. I will explain it later

Grails application can be run against several configured environments.  Functional Tests are run against grails executed with test env. You can configure several things under environments, but one of the main things is db configuration. Test env uses embedded in-memory hsql db by default. So all generated data will not affect your production data and will live in scope of running grails server for testing propose.


Coding
Now let's implement out inquiry page using grails and GWT. I won't explain how to do it. Just provide screenshots















































Geb
Geb is Groovy based web testing framework. It uses JQuery syntax, Page Objects pattern and groovy under the hood. All these 3 elements makes Geb extremely powerful DSL for web testing and even scraping web scripts.

Spock
Spock is groovy based highly expressive specification language. It allows you describe specifications by example very quickly using given when then (and it's modifications such as expect - where) notation.


Geb Spock Grails functional tests examples



Specification provided above will open page which is represented by OrdersPage Page Object. Static variable url in OrdersPage class is used for to method in specification. As a result orders page will be opened in configured browser.
The contents of the page is described with static content closure property. The notation of defining content is following:
"name" {"defenition"}
name is a reference to the content definition which can be used in specification.
If your pages are too complicated you should use Modules. So i decided to isolate Grid object in separate ExpandableGrid Module.
As a result we will have:

when:
to OrdersPage - opens http://localhost:8080/mcell-gui/ordersControl/orders url in configured browser
then:
assert ordersGrid.size == 4 Refers to ordersGrid content definition of OrdersPage and then to size definition of ExpandableGrid Module

As you can see from ExpandableGrid i defined all needed content for my tests using css selectors. Actually Geb uses css selectors for retrieving data from the DOM tree of the page.

Also you can inherit Modules and Pages. For example i have ExpandableGrid which contains simple Grid definitions plus expandable rows functionality. Let's refactor it:


class Grid extends Module{
def debugId
static content = {
grid {
$('div', id: "gwt-debug-${debugId}").find('.x-grid3-body')
}
rows{ grid.find('table[class*=row-table]') }
size{ rows.size() }
row{row-> rows[row] }
}
}


and 


class ExpandableGrid extends Grid{
static content = {
expandRow { row ->
grid.find('.x-grid3-row-expander')[row]
}
expandedForm{ module OrderForm}
}
}

Content information will be merged with Grid Module for ExpandableGrid


One more test description




I've added more Modules to represent Order Form and all tabs on it. Now i can straightforward DSL for my specifications


Driver configuration
More detailed driver configuration you can find on geb site. I've chosen ConfigSlurper mechanism:

waiting = { timeout = 2 }
driver = {
def driver = new FirefoxDriver()
}


Now my geb scenarios will work with firefox WebDrivers


That's all so far. i think it's time to deploy may app.







Thursday, August 11, 2011

Почему feature branches плохо.

читаю статью на http://habrahabr.ru/blogs/android/126082/ , вот выдержка

В прошлом году Google столкнулся с серьезной проблемой. Они хотели выпустить планшетную версию Android как можно быстрее, чтобы соревноваться с iPad от Apple, поэтому и разделили разработчиков на две группы. Одна часть занималась разработкой Gingerbread для смартфонов, а вторая разрабатывала Honeycomb для планшетов.

«Для того, чтобы успеть вовремя, мы пошли на компромиссы» — сказал Энди Рубин. «Мы даже не хотели задумываться, как запусть ту же самую версию (Honeycomb) на смартфонах. Это потребовало бы дополнительных ресурсов и задержало срок сверх разумного».

Поэтому Google и продолжил в том же стиле — дебютировал с Gingerbread на Nexus S в декабре, а версия Honeycomb появилась на Motorola Xoom в феврале. И с тех пор команда разработчиков Android прикладывает все возможные усилия для того, чтобы объединить эти ветви обратно в единое целое.
Goole пошел на компромиссы, я понимаю компромиссом тут является создание отдельной ветки для планшетов и все что из этого вытекает. Теперь нужно потратить много усилий чтобы все это смержить.  

Рассуждение о релизных циклах и методологиях ведения проектов


Если вы хотите быстро получить информацию о том какая методология используется в той или иной компании для ведения проектов спросите, "сколько у вас длиться релизный цикл?" ответом на этот вопрос может быть фраза от "1 день или неделя" до "1 год".
Так вот если ответом был первый то это скорее Agile методология, если второй то скорее всего традиционный подход.
Теперь подумаем что плохого в той или иной продолжительности циклов и стоит ли сразу переходить от одного к другому.
Сначала я встану на защиту традиционного подхода, хотя сразу оговорюсь - я не являюсь его поклонником. Итак релизный цикл 6 - 12 месяцев. Скорее всего процессы компании настроены таким образом, что требования подготавливаются перед началом цикла и заказчик ожидает получить новые фичи к концу. Заказчик готов к тому, что у него раз в год или полгода происходит обновления программного обеспечения и это его полностью удовлетворяет. Учитывая что релиз достаточно болезненное мероприятие как для компании разработчика так и для заказчика то, чем меньше их тем лучше для обоих :) поэтому некоторые стараются увеличить релизные циклы, однако с увеличением они становятся все сложнее и болезненней. Сокращение же релизного цикла приведет ко многим изменениям организации процессов начиная от IT департаментов заканчивая Sales и к этому нужно быть готовым. Кроме того Agile методология с её короткими релизными циклами лучше всего подходит к Software as a Service (SaaS), когда заказчик даже не подозревает, что на продакшен серверах происходит обновление программного обеспечения. Хотя вам ничего не мешает делать Private Releases.
Теперь поговорим о всем том плохом, что сопровождает длинные релизные циклы. Как правило при таком подходе 2/3 времени занимает разработка фичи, а остальное на её тестирование. Итак представьте что вы взяли в очередное релиз цикл 20 фич, при этом цикл у вас занимает 6 месяцев. 4 месяца разработка и 2 тестирование (автоматизированное, UAT и т.д.) Итак посчитаем сколько времени необходимо потратить чтобы фича прошла все стадии и была готова к релизу. 6 мес (24 недели) / 20 = 1.2 недели. округлим в большую сторону и получим 2 недели на одну фичу (это разработка и тестирование и выпуск её в релиз). Вместо этого заказчик её увидит через 6 месяцев эффективность можно посчитать 2/24 = 0.08 что составляет примерно 8 процентов.
Итак возникает вопрос, а стоит ли увеличивать релизные циклы и вечно бегать от страшного наказания под названием "релиз"? Что если наоборот уменьшать их? от полугодового перейти к поквартальному. От поквартального к ежемесячному и наконец к еженедельному и ежедневному, когда фичи поставляются как пирожки на конвейере. Да вам скорее придется обратиться в веру Agile, но подумайте над этим, стоит ли противиться этой новой вере?

Tuesday, July 26, 2011

Возрождение старого проекта

Давно я не писал.

Есть мнение, что пора поменять стиль отдыха по вечерам и вместо попивания пива в промышленных масштабах за сериалом Декстер, лучше заняться делом.

И вот что пришло в мою светлую голову. Был когда то у меня проект на котором я собственно учился Java. Сейчас он даже в продакшене в конторе в которой я работал когда то. Я до сих пор с умилением и теплотой вспоминаю о том времени когда я над ним работал. И вот что собственно пришло мне в голову. А не восстановить ли в памяти все бизнес требования и переписать его под современный стэк технологий. В чем поинт спросят меня критики. Ну поинт первый - перестать сетям Мегамаркет делать кассу на бердичевском пиве, хоть оно и офигенно вкусное. Поинт второй - хоть проект на котором я работаю сейчас интересен с технологической точки зрения, но все как то дают нам задачи доделать, что то за ребятами из Лондона, а хочется с нуля, чтобы прочувствовать всю глубину глубин. Ну и наконец последнее хочется выкатить, что то свое и Open Source.

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

Теперь по стэку технологий
сейчас там используется J2SE 1.3, Swing, SWT (на клиентской части), hibernate, MS SQL, Maven

Хотелось бы
UI: GWT (JQuery) или какой то другой JS framework
Web framework: Grails и весь список фрэймворков под капотом
Server Side. Тут хочется использовать SOA архитектуру которая окутана чем то типа ServiceMix
DB layer: тут я уступаю достаточно в познаниях но я так понимаю, что или My SQL, или PostgreSQL, а может для производительности и NoSQL решение. Кроме того наверно какой нить распределенный кэшь хмм, может cassandra? пока незнаю

Tools
Git + GitHub
Maven, Ivy(для grails)
TeamCity а лучше Jenkins он open source
Sonar

Куда деплоиться? думаю на какой нить AWS или на какой нить кастомный сервачек.

Ну и наконец методологии буду(ем) если кто то присоединиться, придерживаться гибкой, это означает, что сейчас не будем делать архитектуру и дизайн, а потом как то перейдем к реализации. We will not build software we will grow it.

Ну вот как то так.

Monday, June 27, 2011

InfoQ: Collaboration Over Contracts in Agile “Offshore” Outsourced Development

Посмотрел давеча презентацию Craig Larman.
InfoQ: Collaboration Over Contracts in Agile “Offshore” Outsourced Development

Первое, что понравилось, что он сумел в полтора часа вложить столько аспектов взаимодействия с offshore командами.

Сюда вошли и общие принципы agile и сугубо технические вопросы и даже типы payment.
Передаю горячий привет своему Project Manager. Андрей судя по всему твоя роль весьма сомнительная. И даже страдает Transparency. Дело вот в чем, исходя из того что Feadback мы слышим от Customer не так часто, а если и слышим то в основном положительные отзывы, то у нас или все хорошо или не совсем так, но в это верится с трудом, потому что РМ иногда приходит и говорит, а что нужно сделать чтобы вы работали в 2 раза лучше :) Craig говорит, что РМа не должно быть как такового и налаживать отношение должен Product Owner (PO) непосредственно с командой.

Где то на 44 ой минуте Craig говорил о тестировании и Acceptance Tests. Тут мне вспомнилась полемика с моим предыдущим тимлидом. Он говорил о том, что acceptance tests слишком долгие и их тяжело поддерживать. Одним из аргументов было то, что они неправильно написаны, но как мне кажется все зависит от сложности flow и проекта в целом. Единственное в чем я твердо уверен, так это то, что они должны делаться и максимальное количество из них если не все должны быть автоматизированы. Spec by Example вам в помощь. В конце концов это подтверждение того что вы имплементировали именно то, что от вас хотел заказчик.

Хорошо что Craig затронул тему о передаче знаний (Knowlage transfer). Это очень важно для offshore teams. Следует взять на заметку Domain and Vision Workshops. Потому как офшорные команды должны разбираться в доменной области и видеть big picture, иначе они превращаются обезьянок за клавиатурой.

Очень понравилась рекомендация не навязывать дизайн и архитектуру со стороны onshore. Давать возможность офшорным командам самим принимать решения в этих вопросах, иначе это очень разочаровывает. Ведь на самом деле предотвратить проблемный дизайн можно всегда с помощью Code Review и Design Workshop.

Напоследок, хочу отметить что Craig Larman удивительно всесторонне развитый и терпеливый человек и действительно имеет право давать такого рода рекомендации и мастер классы. У него богатый опыт как в управлении процессами, так и в непосредственной разработке программного обеспечения. Я это могу утверждать на основании того, что сам с ним 2 дня сидел вместе в паре и TDDировал :)


Saturday, June 25, 2011

Ubuntu Natty Narwhal upgrade или как я провел сутки

Сейчас оглядываясь назад я себя чувствую уставшим. Я и подумать не мог, что затеяв upgrade на нетбуке своей жены я обреку себя на почти 24 часа пляски с бубном и googление.

Так вот, как видно из темы я решил заапгрейдится на более новую версию опреационки на Lenovo S12.

Сразу скажу, что у меня знаний в Linux администрировании на уровне пятиклассника.

Все шло хорошо, как по маслу пока не пришла пора перегружаться. Как оказалось после перезагрузки максимум что я увижу пустые обои на девственно чистом рабочем столе. Максимум что я мог делать это бездумно двигать курсором мыши елозя тачпад, менять рабочие зоны через Ctrl+Alt+PgDn|Up|Left|Right и наконец нажать на power увидеть чудо - диалог завершения работы ну собственно завершить работу или перегрузить это чудо.

Немного погуглив я напоролся на что то типа вот таких постов разочарованных пользователей :) Очень информативно. К сожалению дело уже было поздно вечером и я не мог четко сформировать запрос googлу, поэтому поиск затянулся, пока я не нашел вот этот пост. Это реально был кладезь информации по проблеме. В итоге я почти все перепробовал что предложил товарисч MAFoElffen.


Первое что меня обнадежило и не дало поднять белый флаг, это то что загрузка с LiveCD, происходит без потерь, кроме того мне удалось запуститься в recovery mode и увидеть Gnome Desktop (вместо Unity, которое в Ubuntu 11.04 по умолчанию).


Почитав дальше я понял что проблема с grub2 конфигурацией, и вообще с загрузчиком. Дело в том что когда-то давно когда я купил этот нетбук я поставил на него 3 операционки Ubuntu, Win7 и еще раз Ubuntu потому как не знал как вернуть загрузчик после того как его стерла Win7 :) (стыдно)


Загрузчик у меня был grub а не grub2, это я понял после того как начал применять инструкцию по восстановлению grub2 для своего grub. В итоге было решено сделать upgrade и загрузчику :) слава богу он прошел более не менее гладко благодаря вот этой статье, воспользовался я Boot-Repair тулзовиной.


Вернувшись к изначальной проблеме я начал пробовать разные варианты загрузки, манипулируя с linux boot line я пришел к выводу, работают 2 варианта
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash nomodeset"
и
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash i915.modeset=0 xforcevesa"
Прописав один из вариантов в /etc/default/grub, выполнив sudo grub-update, и перегрузившись я наконец увидел Gnome


Вот немного теории которую я вытянул по nomodeset из этого ресурса. Последние ядра взяли на себя ответственность за конфигурацию video, вместо того чтобы это делал драйвер X Server. Одной из причин по видимому является появившаяся возможность заранее инициировать видиокарту и тем самым обеспечить более представительный процесс загрузки.


Итак проблема пустого десктопа была решена и я уже было вздохнул с облегчением как обнаружил новую (_|_). Пропал Wireless. И снова google нам помог, правда не сразу. Материала по поводу проблем с wlan в Ubuntu Natty навалом, и опять же не все было применимо для моей конфигурации железа.


Вот ресурс и ресурс которые мне в итоге помогли.

Первое что нужно, так это избавиться от загрузки модуля acer_wmi. Для этого
sudo rmmod -f acer-wmi
sudo rfkill unblock all 
rfkill list all
при этом wireless LAN должен быть

Soft blocked: no
Hard blocked: no


к сожалению у меня этого не произошло. Я обнаружил что у меня загружено 2 Wireless модуля: первый ideapad-laptop, а второй собственно тот который нужен brcmwl. Дело в том что я этот драйвер предварительно установил из предложенных проприетарных драйверов от Broadcom. Грохаем ideapad-laptop
sudo rmmod -f ideapad-laptop
sudo rfkill unblock all 
rfkill list all 


после этого Network Manager магически ожил.

Теперь для того чтобы эти манипуляции не делать при каждой загрузке системы кладем все ненужные модули в blacklist
echo 'blacklist ideapad-laptop'  >> /etc/modprobe.d/blacklist.conf
echo 'blacklist acer-wmi'  >> /etc/modprobe.d/blacklist.conf

также добавим

rfkill unblock all в /etc/rc.conf перед exit 0

Если вы игрались с opensource драйверами то нужно их также выгрузить

sudo modprobe -r b43 ssb wl
sudo modprobe wl 

и убедиться что они в blacklist

вроде все.

Friday, June 17, 2011

Как себя правильно разбудить

У меня большая проблема, думаю что у многих она есть. Я говорю об утреннем подъеме на работу. Хочу поделиться как я её для себя решил.

Начну с того, что я ярый поклонник RadioRoks и творчества их ведущих. У них есть возможность слушать музыку прямо на сайте, можно также скачать m3u файло и слушать с любимого проигрывателя.

Так вот, а что есть просыпаться под хороший рок, подумал я.

У меня ноутбук с которого я в свое время снес нафиг Win Vista  и поставил старый добрый WinXP, а потом и вовсе перешел на Ubuntu.

создаем простенький скриптик


#!/bin/bash
export DISPLAY=:0 && vlc -f ~/Downloads/RadioROKS_256.m3u

Тут ключевой момент в переменной DISPLAY. Дело в том, что если не задать её vlc не понимает на каком X терминале запускаться. Таким образом мы указываем что мы запускаемся на локальном хосте в текущей сессии.


Берем scheduller заданий cron.

crontab -e

и настраиваем scheduller


# m h  dom mon dow   command
0 7 * * 1-5 bash ~/wake_up.sh # JOB_ID_1


сохраняем конфигурацию и просыпаемся каждый будний день в семь утра под RadioRoks.

А как вы просыпаетесь?

Thursday, June 16, 2011

Об архитектуре и DAO в частности

Я тут вот о чем подумал.

Я позапрошлом и прошлом моем проектах использовались ORM (Object Relational Mapping). И почему-то архитекторы приравнивали их к DAO. Тоесть слой сервисов напрямую дергали ORM слой, составляли критерии или HQL в случае hibernate. Таким образом осуществлялось взаимодействие с базой.

Полное дерьмо.

И вот почему. Что проще, замокать DAO или Hibernate? я про тестирование сервисов в изоляции.

Что проще, один класс DAO за другим переписать (смотри паттен branch by abstraction) под iBatis или еще проще под pure jdbc и наоборот или сидеть и искать все вызовы вашего текущего ORM слоя. И тем самым задерживать релиз из-за какой то внутренней переделки, на которую заказчику глубоко посрать, ведь ему реально посрать на то, что ты используешь для доступа к базе (CRUD).

И наконец, лучше содержать свой код так, как того требует базовые SOLID паттерны. Использование DAO слоя в данном случае подходит под практически все SOLID паттерны.

Мысль на закуcку. В чем разница между DAO и Repository паттернами? IMHO в том что к Repostory Эрик Эванс добавил ряд требований, таких как Repository может быть применен
к Root Donain Object, и все модификации с Childs могут происходит через Repository.

Wednesday, June 8, 2011

Об эффективности оффшорных комманд

В наше время у буржуев с запада и Европы очень популярным стало скидывать работу в страны восточной Европы а также в страны Азии. Я сейчас говорю об IT бизнесе. Казалось бы чего грустить? Если работы валом, причем работы по меркам Украинских зарплат высокооплачиваемой, то о каких проблемах может идти речь? К сожалению проблемы есть и вот какие.

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

Митинги
Митинги должны быть короткими (до часа), на них желательно не опаздывать. Совместные митинги с заказчикам должны сопровождаться высоким качеством канала связи, иначе хана, отстающее видео от звука, или вместо спецификации транслируется пошаговая стратегия обновления экрана, накладывается на проблему языка и до ofshore команды доходят лишь крупицы информации.
Бороться с этим можно многими способами.
На митингах нельзя говорить одновременно нескольким людям из за того что на другой стороне это зачастую походит на Одесский Привоз в разгар торговли. Говорящий должен к себе направить камеру и говорить в микрофон.
Как то к нам приезжал Крэйг Ларман Craig page, и на одном из PBR предложил onshore стороне делать контрольные точки, ставя вопросы по теме к нам в offshore. Тем самым добиваясь полного понимания вопроса обсуждения. Это может затянуть митинг, но гарантирует понимание всех сторон.

Бюрократия и секюрити
В некоторых организациях эти моменты доходят до абсурда, по крайней мере так нам кажется со стороны ofshore. Нас менеджмент "удивляет" вопросами типа как бы нам повысить в 2 раза эффективность, и при этом загоняет нас в рамки виртуальных машин и паршивого канала связи с серверами onshore. Как следствие половину времени тратиться на поднятие енвайрмента, осознавания факта, что тебе уже некуда делать check out из svn, потому что больше 30 гигов на виртуалке не положено и кучи других неприятных активностей которые приносят скорее раздражительность чем удовлетворение от работы.

пока все. а как у вас обстоят дела?

Tuesday, June 7, 2011

Continuous delivery

Surfing in internet, i've found some interesting interview with Martin Fowler and Jez Humble, here is a link. Also there are guys who doubts about Continuous Delivery and Continuous Deployment practices, here is a link. Taking into account that i'm working in agile environment and we also have these painful release activities i decided to provide some comparison of what are these guys talking about and what we actually have in my project.

I can say that we haven't built a communism in this sphere. First of all we are not ready to release on demand, and this is the one of the main point of Continuous Delivery pattern. We still have problems in our culture such as keep all tests green, i will talk about it later. Because of business specific, constraints, security and finally complexity of the product we cannot automate everything. I think we have too bureaucratic process of several approves before release. The fact that we're offshore is also impose the fact that we cannot take part in release activity and also production health. And from technical point of view the architecture of the product is very complicated, there are a lot of external dependencies which we cannot automatically test, but only front to back manual testing.

Tests.
I really like the article testing-pyramid, especially the phrase "Where we also value that the information provided from the right matters to our customer and is rich in information, and the information from the left matters to our developers and their ability to be efficient." I've been a witness and also opponent in production issue judgement, when some guy asks, please point me some test that you have done for this User Story. So i just want to highlight that all test are valuable and you should automate them as march as possible.
The other issue that might cause you avoid acceptance tests and other complicated test is actually complexity of these tests. In compare to unit tests, they require more reliable interface, the should be understandable for other guys then IT, i mean BA and QA, and finally they should be produced by other guys other than IT.
So, while your software is evolved , your testing framework is also should evolve.
And final issue about acceptance test is actually maintenance. No doubt that it's rather harder to maintain acceptance test then unit test. First of all, you should wait much more time the result of these tests in you continuous integration system, because of the nature of these test. The second point is that the reason of the failure of such tests may be hidden under complexity of the flows under these tests.   And this is the main problem of resistance of developers to keep them green


Ready to production code.
One guy reproached me, that using brunches is more efficient way to produce features in your software. But i would like to remind you what branches causes:

  • Merging process. This process may be too long and painful
  • You cannot guarantee the coexisting of several features in mainline on demand
  • you cannot build continuous delivery pattern upon multiple brunches   
Deployment pipeline
Well, this is an implementation of Continuous Delivery pattern. And IMHO it's strongly coupled with specific and architecture of the software. So any implementation of Deployment Pipeline should be flexible. May be it should have a pluggable architecture.

So thats all so far. I believe that it was interesting for you. 

Friday, May 27, 2011

Болезнь отошла

Вот и окончилось мое домашнее заключение на киевской квартире. Дело в том, что сев в поезд в Одессе в воскресенье вечером, я уже заподозрил что со мной, что то неладное, в глазах как будто песка сыпанули, по телу мурашки и сильная слабость.

Поворачивать назад было поздно и я решил что к утру все пройдет. Но не тут то было. Ночью по видимому поднялась температура, померить я конечно не мог, просто потому что с собой термометр не вожу, и сбить её тоже не чем было. 

Ко всей драматичности ситуации добавился еблан который подсел в купе на станции "Раздельная". Почему еблан? Потому что храпел как еблан.

Утром выйдя из поезда я позвонил в страховую и вызвал доктора. Диагноз ОРВИ, мне кажется все доктора ставят одинаковый диагноз, их нужно вызывать для того чтобы лекарства привозили, забирать их на пороге и говорить "пока доктор", своеобразные драгдиллеры делающие кассу определенным аптекам, ну а мне то что, страховая платит.

Так вот температура поднималась с регулярностью 2 раза в сутки. Выпил жаропонижающее, подождал полчаса и пошел эффект, успевай футболки менять, один раз ночью я проснулся от ощущения, что я в аквариуме и вот вот меня какая нить рыба за жопу укусит. Жаропонижающее , это самое коварное лекарство. Ты его выпиваешь, становится лучше, в моем случае вообще отлично, словно и не болеешь совсем, потому что насморка нет и горло не болит, и тебе кажется что ты здоров и можешь жить полноценной жизнью, но эффект его проходит, и ближе к вечеру болезнь дает о себе знать. вот в таком состоянии я провалялся с понедельника по среду включительно.

Среда.
Среда была переломным днем, во первых это был третий день болезни и как правило если это действительно банальная ОРВИ то тебя на следующий день отпускает, и во-вторых я уже так смердел, что терпеть было не возможно, и нужно было срочно в душ.

О душе.
Мать его, ну почему когда тебе что то позарез нужно, его как правило нет. Так и в этот раз произошло, в понедельник зайдя в подъезд, на дверях было русским по белому написано, что горячую воду в районе отключили в связи с каким то тестированием системы. Так вот мыться пришлось после того как закинулся очередной дозой жаропонижающего и очень быстро, потому что вода уже не ледяная но и не теплая.

Виски.
Как отогреваться после купания под холодным душем, мне пришло в голову прямо в душе, потому что когда ты пиздец как замерз, и если ты при этом музчина, то первое что тебе на ум приходит так это грелка во весь рост  (не мой случай, потому что жена осталась в Одессе) а второе это стаканчик качественного виски. К счастью у меня как раз остался в кульке, который я забрал домой с отдыха на природе в пятницу со своими ребятами с работы. Так что смывая мыло с себя я уже мысленно пригубил глоток.

Так вот в медицину я верю меньше чем в качественное зелье с Шотландии, и поэтому я с уверенностью могу сказать, что в четверг я пошел на поправку именно благодаря мастеру злачного дела, господину Дэвиду Стюарту из Balvenie и несомненно своей команде, которая мне звонила каждый день и справлялась о моем здоровье, особенно Юрочка, который даже фрукты привез :) За что им все огромное спасибо.

В заключении хочу сказать, что за время болезни было просмотрено более десятка фильмов, особенно повеселили "Мачете" и "Одноклассники".

Вроде все
 

Thursday, May 26, 2011

Investigation through the testing

Я заранее прошу прошение у читателя за обилия терминологии на английском, просто иногда трудно перевести на русский, да и стоит ли переводить?

Я уже полтора года работаю в условиях Agile а именно по Scrum методологии. причем мы проповедуем Large Scale Distributed Scrum. У нас порядка 8 команд распределенных по всему земному шару, которые работают над одним продуктом и в одном codebase.

Пару спринтов назад к нам поступила в работу User Story которая требовала дополнительного технического исследования перед планированием и оцениванием трудозатрат для реализации. К сожалению сценариев еще не было готово поэтому Specification by Example, которые потом практически безболезненно ложатся на интеграционные или функциональные тесты, мы сочиняли параллельно исследованию. Решено было попробовать описать сценарий интеграционным тестом который бы покрывал один из пунктов Spec by Example.

Интеграционные тесты в нашем продукте  по сравнению с функциональными достаточно легковесные и не требуют запуска всей инфраструктуры а лишь маленькой её части, поэтому писать такие тесты быстрее и результат их можно увидеть также гораздо быстрее, а также итерации TDD заметно короче чем если писать функциональный тест.

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

Конечно идеально распланировать задачи в условиях высокой степени неопределенности практически не возможно, но если на ранней стадии спринта понять, что именно необходимо делать, то можно вовремя скорректировать план и количество задач на спринт, и тем самым повысить вероятность своевременной сдачи готового продута.

Tuesday, May 24, 2011

О популярности языков программирования

Сегодня читал очередной блог своего знакомого, и наткнулся на тему которая не доминировала в его блоге, но которая повлияла на написание этой записи. Кроме того ограничение на вложенность комментов в disqus также сыграла свою роль.
Вот ссылка на блог моего знакомого blog-in binary.
Если лень читать, то на мой комент о том что не смотря на то что Java выглядит несомненно скудноватой по сравнению с C# по ряду причин, компенсируется это наличием языков программирования на основе JVM такими как Scala и Groovy, которые поддерживают ряд вещей которых нет в Java (замыкания, динамическое программирование и т.д.) автор блога ответил что смысла в них нет ибо по рейтинку tiobe они занимают не больше 0.1% по популярности.
Заглянув на ресурс tiobe я обнаружил, что и впрямь Scala и Groovy являются аутсайдерами рейтинга.
капнув глубже выяснилось, что, скажем, баш также вылетел из top списка и почему-то bash и bourne shell у них не одно и тоже?
И как это D, R и Q языки программирования (это что вообще за хрень такая?) на 23, 30 и 31 а bash, которым мы все любим пользоваться для скриптования непонятно в какой заднице?
Кроме того у меня закрадываются сомнения по поводу того что PL/SQL стоит ниже по рейтингу чем T-SQL, аргументирую это тем, что во-первых из моего опыта rонторы в которые я устраивался требовали знания именно Oracle а не MS SQL, во-вторых именно база Oracle признана de facto стандартным продуктом для использования в Enterprize, ну и в-третьих не забываем о PostgreSQL, пусть не такой популярной как MySQL но добавляющей к PL/SQL рейтинг (не смотря на то что в PostgreSQL используется PL/pgSQL)

Как говориться почувствуйте разницу, 0.8 % это не только IT вакансии

PL/SQL Job Trends graph


T-SQL Job Trends graph



А вот еще сравнение


похоже bash и groovy делает pascal (кто бы сомневался), тогда как по рейтингу tiobe паскаль на 17 месте и рейтинг у него 0.709%

Ниже цитата с сайта tiobe
The ratings are calculated by counting hits of the most popular search engines. The search query that is used is
+" programming"
This search query is executed for the top 6 websites of Alexa that meet the following conditions:

  • The entry page of the site contains a search facility
  • The result of querying the site contains an indication of the number of page hits

Based on these criteria currently Google (32%), YouTube (10%), Yahoo! (3%), Bing (3%), Wikipedia (16%), Blogger (32%) and Baidu (3%) are used as search engines.

Я вот не пойму с каких пор на YouTube можно достать адекватную инфу про язык программирования. На момент написания этого блога Wikipedia вылетела из TOP 6 сайтов алексы и заменил её поисковик life.com. Ну да ладна по большому счету все языки программирования в одинаковых условиях, а статистика это наука и спорить с ней сложно.
Поэтому я смирился, что Scala, groovy и, наконец bash аутсайдеры по рейтингу tiobe, но на мой взгляд это противоречивые данные.
Нельзя судить о популярности языка программирования по количеству найденных ссылок в поисковиках по +"language programming". Язык популярен тогда когда он реально востребован на рынке труда