Pull to refresh
25
0
Send message
часто (не менее 1 раза в день) «заливать» свой код в репозиторий
Регулярный апдейт репозитория позволяет быстро узнавать когда и кто сломал билд
Т.е. как я себе это вижу — постоянное заливание кода в удаленный репозиторий позволяет вовремя среагировать на ошибки, плюс очень дисциплинирует.
Я согласен с тем, что после того, как разработчик полностью закончил работу над задачей («заимплементил фичу», «пофиксил багу» и т.п.), то эти изменения должны быть в кротчайшие сроки добавлены в репозиторий. Но дело в том, что работа над задачей может длиться более чем один день, с одной стороны, а с другой, может содержать не один, а несколько коммитов (некоторые из которых могут содержать нерабочий код, но о котором знает разработчик). Резюмирую: однозначно поддерживаю слово «регулярно», но остаюсь при своем мнении и считаю, что говорить «не менее 1 раза в день» не корректно.

У нас в компании есть следующий подход. Как Вы и описали, можно развернуть часть инструментария CI (продукт состоит из многих модулей, следовательно — разные технологии и т.п.) локально, а можно «постучаться» к билд серверу, на котором уже есть все, кроме того модуля, над которым в данный момент работает разработчик.
Я хотел обратить внимание, что возмножы ситуации, когда разработчик не сможет обнаружить проблему локально и «зальет» неработающий код. И на мой взгляд это очень сложно обеспечить выполнение требования: не «заливать» неработающий код.

У CI есть одно положение «билд падает быстро».
Возможно речь идет о smoke тестах?

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

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

От прочтения данной статьи возникло море вопрсов.

Идеологически CI базируется на следующих соглашениях:
часто (не менее 1 раза в день) «заливать» свой код в репозиторий
Зачем? Т.е. если я сегодня не залил изменения на сервер, то я поломал CI на предприятии? На мой взгляд важно не регулярно заливать, а регулярно производить сборку.
запускать private builds(процесс сборки, который выполняется с использованием исходного кода, в данный момент находящегося в
локальном репозитории разработчика)
не «заливать» неработающий код
Это возможно если весь инструментарий CI развернут на машине разработчика, иногда это неудобно — у разработчиков могут быть различные версии ПО (ОС) и т.п. Возможно более удобным решением может оказаться pre-tested commit.
следить за тем, чтобы все тесты и проверки проходили
Следить и что?
не выкачивать из репозитория сломанный код
Как? Как я узнаю, что среди изменений, которые были залиты другими разработчиками есть сломаных код? И если даже я это и узнаю, то как технически я уговорю свою систему контроля версий это сделать?

Скрипт сборки — это набор комманд, которые будут выполнены при запуске процесса интеграции. Чаще всего он выглядит как следующий набор шагов:
Компиляция (или статический анализ кода для интерпретируемых языков)
Для компилируемых языков статический анилиз тоже может быть успешно использован.
Разворачивание программного обеспечения
Могу ошибаться но это уже Continuous Deployment (если речь не идет о разворачивании приложения в Staging Environment для его тестирования).

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

На сколько надежна система
Не понял к чему этот раздел.

Решения:
доклады по CI и модульному тестированию
просветительская работа с каждым разработчиком
сотрудничество с QA департаментом
Не благоданое это дело…
изменение в процессе разработки, предполагающее обязательное написание тестов
Как именно вам этого удалось добиться?

Планы:
наладить процесс написания модульных тестов перед кодом, фактически переход на TDD
Ню-ню ;)…

Желаю удачи в дальнейшем внедрении и использовании!
> Эээ я же не предлагаю заменть то что есть, дополнить.
Т.е. использовать CPU в качестве источника энтропии?
> в Куде есть операция типа A=B*C+D
> не имеющая эквивалента на CPU

FMA4?
Большое спасибо за развернутый ответ!

> -ax, доступной в компиляторе Intel
А для gcc, я так понимаю для таких целей прийдется вручную писать разные реализации и использовать Function Multiversioning. Или в gcc тоже есть такая волшебная опция компиляции?
> Есть же специально предназначенные для этого типы данных.
Подскажите пожалуйста, что это за типы? Речь идет о целых типах и вычислениях с фиксированной точкой?
Ошибся веткой… Вопрос адресован eugenius_nsk
> но я думаю ответ очевиден.
Спешу вас удивить, что не для всех :).

> почему один и тот же бинарник выполнился на одной машине с набором инструкций SSE, а на другой — с AVX
Я так думаю, что если бы CPU без поддержки AVX увидел бы регистр по имени ymm (или же AVX-инструкцию), то выдал бы что то вроде Illegal instruction. Поэтому очевидно (мне), что приложение скомпилировано с опцией -msseX (например для gcc). А в AVX-регистр SSE-код попал, так как xmm является младшей (младшими 128 битами) частью ymm. Я думаю так… Но как это могло повлиять на результат мне непонятно. Ведь в обоих случаях разрядность регистра в котором происходит вычисление одинакова и равна 128 битам.
> Почему же в примере на системах с разными Xeon'ами, мы получали разные результаты?
> в циклах, которые векторизованы, разное количество итераций будут распознаны как пролог, ядро цикла и эпилог, а, соответственно, и порядок вычислений будет изменён

Разная разрядность SIMD векторов (SSE vs AVX)?
Сейчас Вы мне ответите:
— IA-32.
А я тогда:
— Отлично, т.е. IA-64 несовместим с IA-64?!
А Вы мне:
— Да нет же! 64-битный вариант IA-32 не IA-64 (как может показаться на первый взгляд), а Intel 64!

Как тот так, да?
> Используется для обозначения 64-битной архитектуры, несовместимой ни с IA-32, ни с 64-битным её вариантом ни по набору команд, ни по принципам работы.

«Её» — кого? IA-32 или IA-64?
Жаль, что сайт более не доступен…
Это значит, что первый раз найти одного сотрудника будет стоить 25 тысяч долларов, а в последующие — бесплатно по актуальным контактам и результатам тестового задания.
Юнит. Что это такое?
Для меня это всегда функция (или функция-член).
Кстати здесь:
Связь результата со входными параметрами и есть суть функции.
И вы тоже проговорились, что юнит — это функция. Или описались.
Явность юнита
И тогда Subject — это имя функции.

Предикативность теста
Именно поэтому в качестве сказуемого предиката строго настрого запрещены такие паразитные слова как «correctly», «good», «fine», «well»...
Хм… Я добавляю суффиксы Success, Fail, Throw, которые отражают ожидаемый результат. Т.е. иногда я пишу тесты на положительный результат, а иногда и на отрицательный. Для арифметических операций смысла в этом мало, но при написании тестов на нетривиальную бизнес-логику или на парсер (мой случай) это может быть полезно.

Состояние и юниты
Не осилил.
Когда мне нужно выполнить нечто подобное, то я делаю вот так.

Не говорю, что я делаю правильно, даже скорее хочу услышать критику.

Статья интересная, спасибо.
> Правда собирается только в clang и мне малость некогда разбираться как это собрать в gcc.

На gcc 4.7.3, собралось без единого изменения по команде:
g++ -std=c++0x main.cpp
> Сюрприз
Мда… Действительно сюрприз…
Лямбда в будет удобнее тем, что она может быть определена там, где непосредственно используется, а в случае с функциональным объектом его придется определять в некотором другом месте:

#include <iostream>
#include <thread>

int main (int argc, char * argv [])
{
    std::thread work {[] {std::cout << "Hard work!" << std::endl;} };

    return 0;
}


#include <iostream>
#include <thread>


struct FunctionalObject
{
    public:
        void operator ()() {std::cout << "Hard work!" << std::endl;}
}

//
// Lot of code...
//

int main (int argc, char * argv [])
{
    std::thread work {FunctionalObject ()};

    return 0;
}
В принципе статью уже много пользователей прочитало и, судя по всему, вопросов ни у кого не возникло, но в любом случае спрошу:

1. > Атомные (atomic) объекты предоставляют atomic_exchange функцию…
Возможно Атомарные будет более уместно?

2. > std::cout << "She said \"Hi!\"; // вывод: She said "Hi!"
Тут не нужна еще одна кавычка?

Information

Rating
Does not participate
Location
Феодосия, Республика Крым, Россия
Date of birth
Registered
Activity