今まで、数回OpenStackにしょぼいパッチを出したことがあるが、たまに、自分のパッチとは関係のないところで、テストが失敗してしまい、マージされないことがある。
そんな時、いつもなら誰か「すごい人」が直してくれるだろうと思って、そのバックエンドのテストの仕組みを考えたことがなかった。
しかし、それでは少し気持ち悪いので、少しぐらい裏の仕組みを知っておこう。
そんな訳で、GerritのJenkinsのjobってどこで定義されているのだろうか。
OpenStack(Gerrit)にパッチを出すとこんなのが出るはず
まずは、そもそもどこの話をしているのかを、おさらい。
Gerrit(OpenStackのCodeReviewシステム)にパッチを出すと、右側にJenkins Checkというのが表示される。ここがどうなっているのか。
各jobの詳細はどこで見れるのか?
OpenStackのjenkinsサーバが7台いるっぽい。
- https://jenkins< 01-07 >.openstack.org/
 
各jobの画面は、 /job/< jobname > で見ることができる。
基本的に、jenkinsのjobのlogのlinkがgerritに貼られるので、直接jenkinsを見に行くことはないと思うけど一応存在は知っといた方がいいはず。
次の疑問、
- 各jobがどんなことをしているかよくわからない
 - プロジェクトとjobの関連づけがよくわからない
 
プロジェクトとjobの対応づけについて
何が言いたいのかとう言うと、例えばneutronのpatchをテストするときは、どのjobを当てて、novaのテストをするときは、どのjobを当ててというのをどこで管理しているのか?って話。
どうやら、 openstack-infra/project-config でjenkinsの設定が管理されているみたい
その中の zuul/layout.yaml で 各プロジェクトで実行するjobが定義されている。
省略
------
 - name: openstack/rally
    template:
      - name: merge-check
      - name: python-jobs
      - name: python26-jobs
      - name: python3-jobs
      - name: check-requirements
      - name: docs-on-rtfd
      - name: publish-to-pypi
    check:
      - rally-coverage
      - gate-rally-install-bare-centos6
      - gate-rally-install-bare-precise
      - gate-rally-dsvm-rally
      - gate-rally-dsvm-rally-cinder
      - gate-rally-dsvm-rally-heat
      - gate-rally-dsvm-rally-nova
      - gate-rally-dsvm-neutron-rally
      - gate-rally-dsvm-neutron-unstable
------
省略
これらの、詳細の設定は jenkins/jobs の中のファイルで定義されている。
んで、
1つのjobの処理内容について見ていく。
ここでは、独断と偏見で gate-rally-dsvm-rally-nova を見ていく。
これは jenkins/jobs/rally.yaml の中に定義がある
省略
---- 580L
- job-template:
    name: 'gate-rally-dsvm-rally-{service}'
    node: 'devstack-precise || devstack-trusty'
    wrappers:
      - build-timeout:
          timeout: 125
      - timestamps
    builders:
      - devstack-rally-gate:
          scenario: '{service}'
          ironic: '0'
          neutron: '{neutron}'
          zaqar: '0'
          large_ops: '0'
    publishers:
      - devstack-logs
      - console-log
      - rally-plot
---- 602L
省略
これの読み方は、雰囲気で分かると思う。
buildersが、テスト内容になっている。ここでは devstack-rally-gate を指定していて、具体的な処理内容は別のところに書いてある(まぁ関数みたいなもの)
それが同じファイルの45行目に定義されている
省略
---- 45L
- builder:
    name: devstack-rally-gate
    builders:
      - link-logs
      - devstack-checkout
      - shell: |
          #!/bin/bash -xe
          export PROJECTS="openstack/rally $PROJECTS"
          export PROJECTS="openstack/ceilometer $PROJECTS"
          export CEILOMETER_NOTIFICATION_TOPICS=notifications,profiler
          export DEVSTACK_GATE_NEUTRON={neutron}
          export DEVSTACK_GATE_IRONIC={ironic}
          export DEVSTACK_GATE_ZAQAR={zaqar}
          export DEVSTACK_GATE_TEMPEST_LARGE_OPS={large_ops}
          export DEVSTACK_GATE_EXERCISES=0
          export DEVSTACK_GATE_TIMEOUT=120
          export DEVSTACK_LOCAL_CONFIG="enable_plugin sahara git://git.openstack.org/openstack/sahara"
          export RALLY_SCENARIO={scenario}
          ENABLED_SERVICES=sahara,key,horizon,
          ENABLED_SERVICES+=cinder,c-api,c-vol,c-sch,c-bak
          ENABLED_SERVICES+=g-api,g-reg,
          ENABLED_SERVICES+=heat,h-api,h-api-cfn,h-api-cw,h-eng,
          ENABLED_SERVICES+=n-api,n-crt,n-obj,n-cpu,n-sch,n-cond,
          ENABLED_SERVICES+=s-proxy,s-account,s-container,s-object,
          ENABLED_SERVICES+=ceilometer-acompute,ceilometer-acentral,ceilometer-api,
          ENABLED_SERVICES+=ceilometer-anotification,ceilometer-collector,
          ENABLED_SERVICES+=ceilometer-alarm-evaluator,ceilometer-alarm-notifier,
          if [ $DEVSTACK_GATE_NEUTRON -ne 1 ]; then
              ENABLED_SERVICES+=n-net,n-api-meta,
          fi
          if [ $DEVSTACK_GATE_IRONIC -ne 0 ]; then
              ENABLED_SERVICES+=ironic,ir-api,ir-cond,
          fi
          export ENABLED_SERVICES
          # TODO(mrostecki): Remove this if statement after implementing
          # Devstack plugin in Rally.
          if [ -d $BASE/new/rally/devstack ]; then
              # New-style Devstack integration
              export DEVSTACK_LOCAL_CONFIG="enable_plugin rally git://git.openstack.org/openstack/rally"
          else
              # Old-style Devstack integration
              ENABLED_SERVICES+=rally,
              function pre_test_hook {{
                  # Install rally-devstack integration
                  cp -r $BASE/new/rally/contrib/devstack/* $BASE/new/devstack/
              }}
              export -f pre_test_hook
          fi
          function post_test_hook {{
              $BASE/new/rally/tests/ci/rally-gate.sh
          }}
          export -f post_test_hook
          cp devstack-gate/devstack-vm-gate-wrap.sh ./safe-devstack-vm-gate-wrap.sh
          ./safe-devstack-vm-gate-wrap.sh
----
省略
link-logs とか devstack-check とかここでも、また他のbuilderを参照している。
いろんなファイルから呼ばれることが想定されている、builderは、 jenkins/jobs/macros.yaml に定義されているので、そこを見ればよし。
頻繁に、コミットするプロジェクトとかは、一通りjobを見ておいた方がいいかも。
