пятница, 29 августа 2014 г.

Load testing with Amazon

Использование EC2 Amazon для нагрузочного тестирования

Думаю, что тут все просто.Не всегда нам хватает своих машин или своей ширины канала для нагрузочного тестирования.
А быстро нам все это предоставить не всегда возможно,но есть выход что с этим делать.
Можно воспользоваться EC2 Amazon.
Сервис который предоставит нам до 10 микро инстансов,на удобной нам системе и бесплатно(правда только первый год,но нам этого хватит)

В общем то все это сделать можно достаточно просто,но не совсем,постараюсь рассказать.
1.Создаем нужный нам instance машины.
2.Начинаем предварительную настройку машины.

Важно!-Не нужно заходить на машину и настраивать iptables,как делал сначала я.Все это настраиваться в UI Instance в категории Security Groups.

3.Настраиваем доступы следующим образом


4.После этого мы уже почти закончили)
Сетапим Jmeter и запускаем на машинах jmeter-server
Запускаем примерно вот так

jmeter-server -Dserver.rmi.localport=2048 -Djava.rmi.server.hostname=`curl -s http://169.254.169.254/latest/meta-data/public-ipv4`

На всякий случай объясню,что мы тут делаем.
Мы биндим RMI на 2048 порт и запускаем сервер с публичным IP который нам предоставил EC2

5.Нам понадобится ssh туннели,кто не в курсе как это и что это лезем сюда.

ssh -R11099:localhost:11099 ...(user@ip)

ssh -i yourkey.pem -R 11099:localhost:11099 ec2-user@54.213.155.162

6.На основной машине запускаем Jmeter следующим образом

jmeter -Dclient.rmi.localport=11099 -Djava.rmi.server.hostname=localhost 

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

Кстати скопировать на инстанс проще всего как то так 

rsync -azvv --progress -e "ssh -i pathtopem.pem" target_folder ec2-user@52.88.37.176:destination_folder

Вот собственно и все.
Всем спасибо.







пятница, 27 июня 2014 г.

JDK Linux

JDK Linux

Вот уж точно статья только для себя,потому что постоянно с этим что то не так,но мб и еще кому пригодится.
Собственно. Если кто не в курсе, то в какой-то момент компаниякоторуюнельзяназывать изменила лицензионное соглашение для JDK так, что её стало невозможно распространять через линуксячьи репозитории.
OpenJDK, который остался в репозиториях — полный шлак и не умеет даже запускать KVM-ные апплеты. Очень многие.
Тем временем jdk делает огромные шаги, вышла уже 8я версия (шустрее, выше, сильнее, а главное, что нет проблем с доступом к ipmi/ip-kvm вообще никаких).
Вот только процесс установки теперь для убунтоводов несколько нетривиален.

По-хорошему нужно пойти сюда, и ткнуть «download» под нужной версией. 
Когда мы получим файл — можно наконец-то распрощаться с оракловым говносайтом и спокойно идти в консольку.
У меня получился файл jdk-7u4-linux-x64.tar.gz
user@host:~$ tar -xvf jdk-7u4-linux-x64.tar.gz
Положим это отродие в правильное с его точки зрения место:
root@host:~# mv jdk1.7.0_04 /usr/lib/jvm/
Создадим переменную, чтобы мануал остался универсальным для любых версий (потом всё следует делать в том же терминале):
root@host:~# jdir=jdk1.7.0_04
# здесь после равно нужно указать название каталога, которому мы делали mv
Теперь создадим правильные симлинки внутри системы:
root@host:~# update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/$jdir/bin/javac 1
root@host:~# update-alternatives --install /usr/bin/java java /usr/lib/jvm/$jdir/bin/java 1
root@host:~# update-alternatives --install /usr/bin/javaws javaws /usr/lib/jvm/$jdir/bin/javaws 1
root@host:~# update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/$jdir/bin/jar 1
Теперь самое время убедить нашу убунту в том, что следует использовать именно 7ю jdk, которую мы только что «установили». Если других версий jdk вы не ставили — то вам просто для успокоения совести следует ввести следующие 3 команды. Если ставили — то нам зададут всякие глупые вопросы. На них придется ответить:
root@host:~# update-alternatives --config javac
There are 2 choices for the alternative javac (providing /usr/bin/javac).

Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/lib/jvm/java-7-openjdk-amd64/bin/javac 1051 auto mode
1 /usr/lib/jvm/java-7-openjdk-amd64/bin/javac 1051 manual mode
2 /usr/lib/jvm/jdk1.7.0_04/bin/javac 1 manual mode

Press enter to keep the current choice[*], or type selection number: 2
root@host:~# update-alternatives --config java
There are 2 choices for the alternative java (providing /usr/bin/java).

Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java 1051 auto mode
1 /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java 1051 manual mode
2 /usr/lib/jvm/jdk1.7.0_04/bin/java 1 manual mode

Press enter to keep the current choice[*], or type selection number: 2
root@host:~# update-alternatives --config javaws
There is only one alternative in link group javaws: /usr/lib/jvm/jdk1.7.0_04/bin/javaws
Nothing to configure.
root@host:~# update-alternatives --config jar
...
Теперь проверим, что мы всё настроили верно:
user@host:~$ ls -la /etc/alternatives/{java,javac,javaws,jar}
lrwxrwxrwx 1 root root 33 May 23 01:40 /etc/alternatives/java -> /usr/lib/jvm/jdk1.7.0_04/bin/java
lrwxrwxrwx 1 root root 34 May 23 01:39 /etc/alternatives/javac -> /usr/lib/jvm/jdk1.7.0_04/bin/javac
lrwxrwxrwx 1 root root 35 May 23 00:29 /etc/alternatives/javaws -> /usr/lib/jvm/jdk1.7.0_04/bin/javaws
...
user@host:~$ java -version
java version "1.7.0_04"
Java(TM) SE Runtime Environment (build 1.7.0_04-b20)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)
Ну и осталась мелочь — рассказать нашим браузерам, что у нас есть java-плагин к ним (это актуально почти для всех браузеров, для FF и Chrome/Iron/Chromium — точно):
root@host:~# username=set_your_username_here; su ${username} -c "mkdir ~${username}/.mozilla/plugins"; rm /home/${username}/.mozilla/plugins/libnpjp2.so; su ${username} -c "ln -s /usr/lib/jvm/$jdir/jre/lib/amd64/libnpjp2.so ~${username}/.mozilla/plugins/"
Проверить, что оно заработало можно здесь.

Вот и все.

Java Simple WebService

Java Simple WebService

Решил для себя описать(чтобы не забыть и все такое) создание простейшего вебсервиса на Java.
С использованием технологии JAX-WS.Будет 2 примера,каждый мне в чем то нравится.

Для начала,что такое JAX-WS?
JAX-WS - это технология, разработанная для упрощения создания Web-сервисов и клиентов Web-сервисов на языке Java. Она предоставляет полный стек Web-сервисов, облегчающий разработку и развертывание Web-сервисов. JAX-WS поддерживает WS-I Basic Profile 1.1. Это гарантирует, что Web-сервисы, разработанные с использованием стека JAX-WS, могут потребляться любыми клиентами, разработанными на любом языке программирования и удовлетворяющими стандарту WS-I Basic Profile. 
Более того, JAX-WS ускоряет разработку Web-сервисов, предоставляя библиотеку аннотаций для преобразования POJO-классов (plain old Java object – традиционные Java-объекты) в Web-сервисы. Она также определяет детализированное отображение сервисов, определенных на языке WSDL (Web Services Description Language), в Java-классы, реализующие эти сервисы. Все сложные типы, определенные в WSDL, отображаются в Java-классы согласно отображению, определенному спецификацией JAXB. JAX-WS ранее поставлялась с платформой Java Platform, Enterprise Edition (Java EE) 5. Спецификация JAX-WS 2.0 разрабатывается под эгидой JSR 224 Java Community Process (JCP).
Для начала у нас будет просто WebService(как в большинстве примерах)


 
@WebService
public class HelloService {
    private String message = "Hello, ";

    @WebMethod//единственный вебметод нашего сервиса
    public String sayHello(String name) {
        return message + name + ".";
    }

    public static void main(String[] args) {
        Endpoint.publish("http://localhost:8080/WS/Greeting",new HelloService()); //паблишим сервис по указанному урлу
    }
}
Запусаем main и наш сервис запаблишится на том урле,который мы указали.
Можно перейти на http://localhost:8080/WS/Greeting?wsdl ,чтобы проверить его доступность.
Дальше нам нужен клиент для работы с сервисом и отладки.

1й способ.

Выполнить из папки проекта команду
wsimport -keep -p com.client  http://localhost:8080/WS/Greeting?wsdl
Параметр -keep указывает, что сгенерированные файлы сохраняются, а параметр -p указывает название пакета, в который должны генерироваться артефакты.  http://localhost:8080/WS/Greeting?wsdl указывает месторасположение WSDL-файла. 

wsimport поставляется вместе с jdk,так что переживать по её поводу не нужно.

После этого у нас будет несколько сгенеренных классов для работы с сервисом и клиент будет выглядеть примерно так:

 
public class Client {
    @WebServiceRef(wsdlLocation = "http://localhost:8080/WS/Greeting?wsdl")
    HelloServiceService service=new HelloServiceService();

    public static void main(String[] args) {
        try {
            String response = service.getHelloServicePort().sayHello("Robert");
            System.out.println(response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
В ответ вы должны получить "Hello Robert."

Способ 2

2й способ без генерации вспомогаемых классов утилитой wsimport.
Нам понадобится интерфейс нашего веб сервиса.

 
@WebService
public interface IService {
   @WebMethod
   public String sayHello(String name);
}
Наш сервис должен реализовывать этот интерфейс,как вы догадались

 
@WebService(endpointInterface = "com.main.IService")
public class HelloService implements IService{
    
    private String message = "Hello, ";
    @WebMethod
    public String sayHello(String name) {
        return message + name + ".";
    }

    public static void main(String[] args) {
        Endpoint.publish("http://localhost:8080/ws/Greeting",new HelloService());
    }
}

И пишем сам клиент.

 
public class Client {
    public static void main(String[] args) throws MalformedURLException {
        URL url = new URL("http://localhost:8080/ws/Greeting?wsdl");
        QName qname = new QName("http://main.com/", "HelloServiceService");
        Service service = Service.create(url, qname);
        IService hello = service.getPort(IService.class);
        System.out.println(hello.sayHello("Cool guy"));
    }
}

Ответ должен быть "Hello,Cool guy".

Вот и все,всем спасибо.

суббота, 17 мая 2014 г.

Выбор паттерна для WD тестов(мнение)

Выбор паттерна для WD тестов(мнение)

Собственно некоторое наблюдение по паттернам для WD тестов.
Изначально,для написания UI тестов, предлагается использовать либо Page Objects, либо Page Factory. (сделал их ссылками,вдруг кто не знает)
У каждого из подходов есть свои плюсы,но я в основном всегда использовал Page Object при работе с UI.
И могу объяснить почему:
Конечно я пробовал использовать Page Factory и вот те минусы что не дали мне с ним смириться:

  1. Нельзя проверить отсутствие нужного тебе элемента, не обернув это все в блок try/catch
    Вроде пункт не сложный,но меня напрягает.
  2. Нельзя искать элемент в элементе используя WebElement c Page Factory.
    Пропадает возможность вложенного поиска,который бывает очень удобен.
    Можно создавать коллекции элементов,подходящими под описание локатора,но это немного   другое.
  3. Большинство ExpectedConditions у WebDriverWait работают с объектом By,а не WebElement.
    Тоже решается созданием или перегрузкой имеющихся,но зачем,если есть готовые.
Ну в общем то и проксирование между объектом WebElement сразу к объекту на странице намного чаще даст шанс поймать Stale Element Exception.(Да, я знаю про lazy инициализацию,но ничего не могу поделать с тем,что мне так кажется)

Это было всего лишь мое мнение.Всем Спасибо.

воскресенье, 23 марта 2014 г.

Немного необходимого в Java.

Немного необходимого в Java.

Решил написать несколько теоретический пост,про основные понятия в Java,которые нужно знать каждому(по моему мнению).
Есть много вроде простых вопросов,на которые очень мало кто может ответить, еще их достаточно часто могут спросить и на собеседованиях)
В общем не будет лишним заметка.
Поехали:
Самый популярный вопрос:
Что такое Hashmap и как он работает?
Да все просто на самом деле.

Map - интерфейс, описывающий  классы, предназначенные для хранения пар объектов. Один из объектов пары должен быть уникальным  - называется "ключом" (key), второй объект, необязательно уникальный, называется "значением" (value). Всю пару называют "записью" (entry).

Уникальный - значит не равный другим ключам. Как определить "равность"? Достаточно знать, что ключи в Map сравниваются по методу equals(), и при попытке добавить в Map запись с не уникальным ключом предыдущая запись будет затерта новой.

Как HashMap устроен внутри?

Внутри HashMap - это массив. Элементы массива в документации называются бакетами (buckets).  В бакете хранится первый элемент связанного списка.Таким образом, HashMap внутри - массив связанных списков. Элемент связанного списка - объект класса Entry, содержит ключ, значение и ссылку на следующий Entry.

Что происходит при добавлении записи?

На следующем шаге, рассчитывается хеш-значение используя хеш-код ключа, получаемый вызовом метода hashCode(). Это хеш-значение используется для вычисления позиции в массиве, куда будет помещен объектEntry. Дизайнеры JDK предполагали, что плохо написанная функция hashCode() может вернуть слишком высокое или слишком низкое значение хеш-кода. Для решения этой проблемы, они ввели другую hash() функцию, и передали в нее значение хеш-кода объекта, чтобы привести хеш-значение в соответствие с размером массива.Теперь вызывается функция indexFor(hash, table.length), для вычисления точной позиции, куда будет помещен объект Entry
Далее, найдя нужный бакет, запись помещается в соответствующий связанный список.


А как искать элемент?

Поиск производится по ключу (ключ для поиска). Опять же по hashcode() ключа находим нужный бакет. Нашли бакет - значит нашли нужный нам связанный список. Далее проходим по списку и сравниваем ключи элементов списка с нашим ключом для поиска. Сравнение производим по функции equals(). Вернула функция true - значит нашли. 

И для чего все это нужно?
Для ускорения работы. В первую очередь ускорение поиска. Напомню, соответствие между hashcode ключа и бакетом не хранится, а вычисляется. Математические вычисления - это быстро. Далее, сравнивать объекты по equals() все же придется, но количество этих объектов ограничено.

Есть такие понятия как loadfactor и capacity-но они простые,даже писать не буду)
Как то много получилось про HashMap сейчас попробую короче укладываться.


В чем отличие между static synchronized и просто synchronized?

Использование слова synchronize на static-методе помечает весь класс как synchronize, т.е. такая запись: 
?
1
2
3
synchronized static void foo() {
    ...
}
равнозначна такой: 
?
1
2
3
4
5
static void foo() {
    synchronized(SomeClass.class) {
        ...
    }
}
А такая: 
?
1
2
3
synchronized void foo() {
    ...
}
такой: 
?
1
2
3
4
5
void foo() {
    synchronized(this) {
        ...
    }
}
Что значит synchronized(this)?

Семантически этот код: 
?
1
2
3
4
5
public void blah() {
  synchronized (this) {
    // do stuff
  }
}
эквивалентен этому: 
?
1
2
3
public synchronized void blah() {
  // do stuff
}
Однако synchronized(this) использовать не рекомендуется. Почему? Об этом можно почитать тут .



Что означают ключевые слова volatile и transient.

Определение переменной с ключевым словом volatile(«изменчивый») означает, что значение переменной будет изменяться несколькими потоками.

Переменная помеченая словом transient не будет сериализоваться и соответственно при десериализации её значение будет установлено значением по умолчанию.

Условия сериализации объектов?

Свойства класса должны быть сериализуемы и класс должен реализовывать маркирующий интерфейс Serializable. Не лишним будет вспомнить про serialVersionUID и его значение по умолчанию.

Можно ли передать объект в synchronized?

Да. Например очень популярна вот такая несложная конструкция: 
?
1
2
3
4
5
6
7
8
9
private final Object _SyncObject = new Object();
...
public void run() {
...
  synchronized(_SyncLock) {
    ...
  }
...
}
Работа со ссылками (weak и strong reference).

Об этом можно почитать тут.

Как сделать ArrayList синхронизированым в одну строку?
?
1
List<Record> s_list = Collections.synchronizedList(list);
Контракт между equals и hashCode.

Если equals возвращает true, то hashCode должен вернуть одно и то же значение. Обратное не верно.

Collections
Контейнеры бывают двух видов:
  1. Коллекции (List, Set, Queue)
  2. Ассоциативный массив (Map)
К популярным реализациям контейнеров стоит отнести: ArrayList, LinkedList, HashSet, TreeSet, LinkedHashSet, HashMap, TreeMap, LinkedHashMap.

В ArrayList и LinkedList элементы хранятся в порядке вставки. Различаются скоростью выполнения и количеством тех или иных операций: ArrayList имеет оптимизированый доступ к элементам списка, но обладает низкой производительностью при добавлении/удалении элементов в середину списка. LinkedList - наоборот.
HashSet обеспечивает наибольшую производительность при выборке элементов. TreeSet хранит элементы отсортированными по возрастанию в порядке сравнения. LinkedHashSet хранит элменты в порядке добавления.
HashMap обеспечивает наибольшую производительность. TreeMap хранит ключи отсортированными. LinkedHashMap хранит ключи в порядке вставки, но обеспечивает скорость HashMap.

Inner classes
Внутренний класс - класс, который объявлен внутри другого класса, например: 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Outer.java
public class Outer {
    Outer() {
        Inner i = new Inner();
        i.innerMethod();
    }
    // Inner class
    private class Inner {
        Inner() {}
        public void innerMethod() {
            // Do something.
        }
    }
}
Анонимный внутренний класс - это класс, который определен в методе другого класса и может быть использован только один раз - там, где он определен. Примером анонимного внутреннего класса часто является реализация обработчика какого-либо события.

Serialization
Сериализация это процесс сохранения состояния объекта в последовательность байт;десериализация это процесс восстановления объекта, из этих байт. Java Serialization API предоставляет стандартный механизм для создания сериализуемых объектов.
Сохранение объекта: 
?
1
2
3
4
5
6
7
8
9
FileOutputStream fos = new FileOutputStream("temp.out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
TestSerial ts = new TestSerial();
oos.writeObject(ts);
oos.flush();
oos.close();
Восстановление объекта: 
?
1
2
3
FileInputStream fis = new FileInputStream("temp.out");
ObjectInputStream oin = new ObjectInputStream(fis);
TestSerial ts = (TestSerial) oin.readObject();

В общем как то так,что то писал сам,что то дергал с других ресурсов.
Получилась не слишком длинная,но вполне возможно, что полезная шпаргалка.