👾

AWS の Code Quality Workshop をやってみる

2023/12/04に公開

はじめに

今のチームでは Java を使っているのですがコードの品質向上が課題となっています。
そこで以下の記事で紹介されている Amazon CodeGuru について学んで日々の開発に活用できないか検討してみたいと思います。
Amazon CodeGuru Reviewer と Amazon CodeGuru Profiler に入門しよう!「Code Quality Workshop」を試した

まずは Workshop を実際にやってみます!
※このブログはワークショップをやりながら書いています。

Code Quality Workshop

ワークショップの目的としては

AWS Developer Toolsを使用してCI/CDパイプラインを構築し、コードレビュー、ユニットテスト、
ランタイムプロファイリングを実装してコード品質を向上させる方法を説明します。

となっています。

サンプルアプリケーションでは次のような構成を作成するようです。

作成する CI/CD パイプラインは次のようになるそうです。

どれも触ったことないサービスなので楽しみです!

では次から Warkshop を初めていきます。

紹介

introduction

ざっくり要約

コードリポジトリには、masterブランチとdevelopブランチの2つがあります。
masterブランチは本番環境または本番準備が整ったコード用、developブランチは開発環境用です。developブランチへのコミットは開発環境に、masterブランチへの変更は本番環境にデプロイされます。
これは、ビルド、テスト、デプロイメントの各ステージを自動的に行う2つのCodePipelineパイプラインを使用して実現されます。
コードレビューとユニットテストはコード品質を向上させるために重要です。
このラボでは、CodeBuildとCodeGuruを使用した自動化されたコードレビューとユニットテストを利用して、developブランチからmasterブランチへ安全に変更をマージする方法について説明します。
また、jacocoを使用して測定されたコードカバレッジを視覚化する方法も説明しています。

CI/CD on AWS

CI/CD の説明が書かれています。

Developer Tools on AWS

このワークショップで利用するツールが紹介されています。

CodeCommit : AWS CodeCommit は、Git ベースのリポジトリをホストする、セキュアで完全に管理されたソース管理サービスです。

CodeBuild : AWS CodeBuildは、ソースコードをコンパイルし、テストを実行し、デプロイ準備が整ったソフトウェアパッケージを生成する、完全に管理された継続的インテグレーションサービスです。

CodeDeploy : AWS CodeDeployは、Amazon EC2、AWS Fargate、AWS Lambda、オンプレミスのサーバーなど、さまざまなコンピュートサービスへのソフトウェアデプロイを自動化するフルマネージドのデプロイサービスです。

CodePipeline : AWS CodePipelineはフルマネージドな継続的デリバリーサービスで、リリースパイプラインを自動化し、アプリケーションとインフラの迅速かつ信頼性の高いアップデートを支援します。

Unit Testing

Unit Test の説明が書かれています。

このワークショップでは、JAVAでJunitを使ったユニットテストを紹介し、jacocoを使ってコード・カバレッジを測定するそうです。

テスト結果はXML形式で出力され、CodeBuildレポートを使用して視覚化できます。開発者は、テストの成功率と失敗率を簡単に確認することができます。また、jacoco を使用して、コードのどれだけがユニットテストに含まれているかを測定することもできます。

CodeGuru

CodeGuru の説明が書いてあります。

Amazon CodeGuruは、機械学習を利用した自動コードレビューとアプリケーションパフォーマンスの推奨を
提供するサービスです。アプリケーションの隠れた問題や、潜在的に問題を引き起こす可能性のあるコードの
ブロックを見つけるだけでなく、コードを修正または改善するための具体的な推奨事項を教えてくれます。
CodeGuruは、何百万ものコードレビュー、オープンソースプロジェクト、何千もの内部プロファイル化された
Amazonのアプリケーションに基づいています。

なんかすごそう・・・。

CodeGuru は2つのパートで構成されているらしい。

CodeGuru Reviewer

自動的にコードを分析し、修正提案を含む提案をおこなってくれるっぽい!

CodeGuru Reviewerは以下のカテゴリーでコードの問題を検出します。

AWSのベストプラクティス : CodeGuru Reviewerは、AWS APIが適切に使用されているかどうかを検出できます。
同時実行 : CodeGuru Reviewerは、マルチスレッドコードにおける同時実行の実装の問題を特定します(スレッドセーフティ)。
リソースリーク : CodeGuru Reviewerは、リソースリークが発生している可能性のあるコード行を探します。
機密情報のリーク : CodeGuru Reviewerは、ハードコードされたパスワード、データベース接続文字列、ユーザー名などを検索します。

CodeGuru Profiler

CodeGuru Profilerは、ライブ・アプリケーションからランタイム・パフォーマンス・データを収集し、アプリケーション・パフォーマンスを微調整するための推奨事項を提供します。
CodeGuru Profilerは、常にアプリケーション・パフォーマンスの最適化を探し、最もコストのかかるコード行を特定し、CPU使用率を下げ、計算コストを削減し、アプリケーション・パフォーマンスを向上させるための修正方法を推奨します。

これも相当便利なのでは?

セットアップ

このワークショップの環境は CloudFormation template を使うみたいですね。

Environment Setup

今回は個人の AWS アカウントでやるので Option2 で進めます。

Option 2: Use Your Own AWS Account

ワークショップの上記のページの「Launch Stack」をクリックしたら以下の画面が開きました。

「次へ」をクリックしてスタックの詳細を指定に移動します。

ワークショップでは KeyName に EC2 の Key pair をと書いてありましたが画面を見ると KeyName 自体なかったので無視して特に変更せずに「次へ」をクリックします。

ステップ4 にきました。画面下部のチェックボックスにチェックを入れて「送信」をクリックします。

しばらくすると成功していました!

Cloud9 Setup

次は Cloud9 のセットアップです。
「環境を作成」をクリックします。

ワークショップの内容に沿って入力してセットアップを行います。

Cloud9 が立ち上がりました。

CodeCommit

次は、GitHub からサンプルコードをダウンロードし、Cloud9 環境を使って CodeCommit にプッシュするようです。

Cloud9 のターミナルで以下を実行してサンプルアプリケーションを取得します。

git clone https://github.com/aws-samples/amazon-cicd-concurrency-sample-application.git

サンプルアプリケーションに移動して develop ブランチに切り替えます。

cd amazon-cicd-concurrency-sample-application
git checkout origin/develop -b develop

次に今落としてきたサンプルアプリケーションを CodeCommit のリポジトリに push するために Cloudformation で作成した RepositoryURL を調べておきます。

CodeQuality-Workshop スタックの出力のタブに RepositoryURL の値として出力されているのでこの値をコピーしておきます。

Cloud9 に戻って現在の origin リポジトリが何か確認します。

git remote show origin

remote origin が github の URL になっているので origin を CodeCommit のリポジトリに変更します。

git remote set-url origin <YOUR-REPOSITORY-URL>

もう一度 origin を確認すると origin が変わっていることが確認できると思います。

では master, develop ともに push していきます。

git checkout master
git push
git checkout develop
git push

CodeCommit に push できていることが確認できました!

CodeGuru Reviewer

このセクションでは、CodeCommit リポジトリのCodeGuru Reviewer コード解析を有効にするようです。

CodeGuru のコンソールでリポジトリをクリックします。

「リポジトリを関連付けて分析を実行」をクリックします。

ソースプロバイダーを AWS CodeCommit にしてリポジトリの場所で「concurencysample」を選択します。
ソースブランチは「master」を選択して「リポジトリを関連付けて分析を実行」をクリックします。

すると、CodeGuru ダッシュボードに、新しく関連付けられた concurrencysample リポジトリが表示されます。
※2回くらいエラーがでましたが、「再試行」をしたらリポジトリに表示されるようになりました。

CodeGuru Profiler

ここでは CodeGuru Profiler をセットアップしていくみたいです。
こんな説明がありました。

Amazon CodeGuru Profilerは、ライブ・アプリケーションからエージェントを使用して
ランタイム・パフォーマンス・データを収集し、アプリケーション・パフォーマンスの微調整に
役立つ推奨事項を提供します。

「Profiling groups」 をクリックします。

「プロファイリンググループを作成」をクリックします。

指示通り入力して「作成」をクリックします。

次の画面の「設定手順」で「JVM」のタブを選択して「ユーザーとロールにアクセス許可を付与する」をクリックします。

Web と入力すると、CloudFormation スタックを使用して以前に作成した EC2 インスタンスロールが表示されます。左側のロールの横にあるチェックボックスを選択し、「保存」をクリックします。

CodeBuild Report

こんな感じの説明がありました。

CodeBuild レポートの作成
CodeBuild では、ビルド中に実行されるテストの詳細を含むレポートを作成できます。
ユニットテスト、構成テスト、機能テストなどのテストを作成できます。

このワークショップで使用するコードは、 Junit を使用してユニットテストを実行します。
ユニットテストの結果は XML 形式で公開されます。
このセクションでは、 CodeBuild のユニットテストとコードカバレッジレポートを設定します。

CodeBuild のコンソールに移動します。
レポートグループをクリックします

「レポートグループを作成」をクリックします。

指定されたようにレポートグループ名を入力し、S3 へのエクスポートのチェックは外して「レポートグループの作成」をクリックします。

作成できたらレポートグループの ARN をコピーしておきます。

次に Cloud9 にもどって指示の通りに buildspec.yml を編集します。
編集の指示の途中で別のレポートグループの作成も指示されるので行います。

こんな感じになりました。

ちゃんと保存すること!

これを push していきます。

cd amazon-cicd-concurrency-sample-application
git add .
git commit -m "change Buildspec.yml"
git push

ビルドが走りましたが失敗しました。

これはどうも想定通りらしく、詳細をみてみると以下のようになっていました。
ビルド・ログを見ると、ビルドは成功しているが、ユニット・テストは失敗している状態のようです。

先ほど指示されて作ったレポートグループの Concurrency-Unittest-Report で単体テストの詳細をグラフや表で見ることができ、結果の分析がより簡単になります。

レポートグループの Concurrency-Coverage-Report ではコード・カバレッジをコード行数やブランチ数でパーセント表示することができます。
回数が少ないので点になってます。

現在、build.gradleでコード・カバレッジが20%未満の場合、ビルドは失敗するように設定されているようです。
この辺かな?

プログラムコード

テストが失敗した理由が説明されています。
HashMap が スレッドセーフじゃないことが問題のようです。

Solution

失敗したユニットテストを修正していきます。
修正方針としては HashMap を ConcurrentHashMap に置き換えて解決するようです。

SingletonRepo.java を開いて指示通りに修正していきます。

修正したら push します。

git add .
git commit -m "fix singletonrepo.java"
git push

CodeBuild を覗いて見ると成功しました!

ユニットテストのレポートの Concurrency-Unittest-Report を見てみるとすべてのテストが成功していることがわかります!

CodePipeline のコンソールで見ても concurrencysample-develop が成功しています。

すべてのテストに合格した後、パイプラインのステップに従ってコードが開発環境に自動的にデプロイされました。CodeBuild レポートは ユニットテストの 問題を可視化し、特定し、対処するのに便利ですね。

CodePipeline はビルド、テスト、デプロイのプロセスを自動化して、 DevOps のサイクルを加速し、手作業によるミスを減らしてくれる!

次は本番にデプロイするためのプルリクエストを作成するみたいです。

CodeGuru Reviewer

本番にデプロイするために CodeCommit のコンソールからプルリクエストを作成するみたいです。

指示に従って入力してプルリクエストを作成します。

CodeGuru Reviewer

このセクションでは、CodeGuru Reviewerによる推奨事項を確認するそうです。
分析には約5分かかります。
CodeCommit コンソールでリポジトリを選択してプルリクエストをみます。

プルリクエストの中のアクティビティを見るとステータスが完了済みになって分析が完了しました。

いくつか新しい指摘をしてくれています!

最後の指摘は普通のユニットテストでは見つけられない推奨セキュリティと AWS SDK の適切な使用についても指摘してくれています!

CodeGuru Concurrency

他にもいろいろ推奨事項が書いてあります。
修正内容の提案に沿って変更して push してみます。

git add .
git commit -m "fix put(), containsKey()-> putifAbsent()"
git push

次はマージをしてみます。

Pipeline で master の進捗がわかります。

成功しました。

ユニットテストとコードレビューは、コード品質を向上させる最良の方法の一つです。
CodeBuild Reports と CodeGuru Reviewer を他の AWS Developer Tools と
一緒に活用することで、開発者の生産性を向上させ、製品の不具合を減らすことができます。

確かに CodeGuru Reviewer 入れたら品質上がりそう!

次は、開発環境で実行したコードのプロファイリング結果を確認するみたいです。

CodeGuru Profiler

このセクションでは、CodeGuru Profiler を使用してコード実行中に得られた推奨事項を確認するみたいです。

一旦指示に従ってコードを置き換えて push します。

git add .
git commit -m "Repeat DynamoDB init"
git push

CPU を 視覚化

レイテンシーを視覚化

ヒープを視覚化

データや表示内容を切り替えることでいろいろなデータが確認できます。
CPU, レイテンシー, ヒープの情報が詳細に見れて便利だなと思います。
1日以上経っていないので出ていませんが、 Recommendations Report というものも出るようになるみたいです。

CodeGuru Profiler で生成される様々な情報をもとに、AWS SDK を効率的に利用することで、ソフトウェアを最適化することができるそうなので結構良さそうですね。

Clean Up

最後は作ったリソースのお掃除です。
指示の通りに消していきます。

さいごに

今回は Code Quality Workshop をやってみました。
実際に手を動かしながらやったので各サービスの関連がよくわかりました。
現在のチームでは GitHub Actions でデプロイしているので CodeGuru を絡めてコードの品質向上に繋げられないか実際に試していこうと思いました。

レスキューナウテックブログ

Discussion