自由課題

学んだり、考えたり、試したりしたこと。

C++における単体テストのための依存性注入方法まとめ

はじめに

あるモジュールを作成した時、当然ながら(ですよね?)このモジュール(以降テスト対象モジュールと呼びます)を何らかの方法でテストする必要があります。テスト対象モジュールが別のモジュール(以降依存モジュールと呼びます)に依存している場合、

  1. テスト対象モジュールと依存モジュールを一緒にテストする
  2. 何とかして依存モジュールをテスト対象モジュールと切り離し、テスト対象モジュールを単独でテストする。

一般的に、1は結合テスト、2は単体テストと呼ばれます。
この記事では、単体テストで何とかして依存モジュールを切り離す、言い換えるとテストのために別の依存モジュール(依存性)を注入する方法を紹介します。
一応記事タイトルをC++としていますが、いくつかは別の言語でも使えるはずです。

続きを読む

node.jsを支えるlibuvのチュートリアル"uvbook" :ユーティリティ

この文書はuvbookの日本語翻訳の一部となります。文書そのものの説明その他については目次をご覧ください。

続きを読む

node.jsを支えるlibuvのチュートリアル"uvbook" :イベントループ

この文書はuvbookの日本語翻訳の一部となります。文書そのものの説明その他については目次をご覧ください。

より進んだイベントループ

libuvはイベントループに対して相当な制御機構を提供しており、複数のイベントループで曲芸を行うことにより興味深い結果を得ることができます。また、libuvのイベントループを別のイベントループライブラリに組み込むことができます - Qt ベースのUIを考えてみてください。Qtのイベントループが集中的なシステムレベルのタスクを行うlibuvのバックエンドを駆動します。

続きを読む

node.jsを支えるlibuvのチュートリアル"uvbook" :プロセス

この文書はuvbookの日本語翻訳の一部となります。文書そのものの説明その他については目次をご覧ください。

プロセス

libuvはかなりの量の子プロセス管理機能を提供しており、プラットフォーム間の差異を抽象化し、ストリームや名前付きパイプを用いて子プロセスと通信することを可能にしています。

Unixにおける共通のイディオムは全てのプロセスが一つのことを良好に行えることです。このようなケースでは、プロセスはタスクを完遂するために複数の子プロセスを使用します(シェルがパイプを用いるように)。メッセージを用いるマルチプロセスモデルはスレッドと共有メモリを用いるモデルに比較して簡単になるでしょう。

イベントベースのプログラムに対する共通のマイナス要因は現代のコンピュータにおいて複数のコアを持つ利点を活用しきれない点です。マルチスレッドプログラムではカーネルはスケジューリングを行い、異なるスレッドに異なるコアを割り当てることができます。しかし、イベントループは単一のスレッドです。これに対する回避策は代わりに複数のプロセスを起動することであり、各プロセスはイベントループを処理し、各プロセスは別々のコアを割り当てられます。

続きを読む

node.jsを支えるlibuvのチュートリアル"uvbook" :スレッド

この文書はuvbookの日本語翻訳の一部となります。文書そのものの説明その他については目次をご覧ください。

スレッド

ちょっと待って下さい? なぜスレッドの話をするのですか? イベントループは web-scaleプログラミング を行うための 手段 だったのではないのですか? いいえ、違います。スレッドはまだプロセッサが処理を行う際の手段であり、同期プリミティブを苦労して使う必要があるとしても、スレッドは時々かなり有用です。

スレッドは全てのシステムコールを非同期の性質を持つかのように装わせるために内部的に用いられています。libuvはまた、スレッドを起動してタスクが終了した時に結果を収集することにより、実際はブロックするタスクを非同期的に実行するためにスレッドを用いています。

現在、2つの有力なスレッドライブラリが存在します。Windowsのスレッド実装とpthreadsです。libuvのスレッドAPIはpthread APIによく似ており、しばしば同様の部分があります。

libuvのスレッド機能の特筆すべき点は、これがlibuvそのものに含まれている(self contained)点です。他の機能がイベントループやコールバックと密接に関係しているのに対して、スレッドは完全に隠蔽されており、戻り値を直接経由したシグナルエラーを必要に応じてブロックし、最初の例で見るようにイベントループを実行する必要すらありません。

libuvのスレッドAPIはスレッドの意味や文法がプラットフォームごとに全て異なり、完全さの店でもレベルが異なるのでとても制限されています。

この章では以下の仮定を行います: 一つのイベントループだけが存在し、単一(メイン)のスレッド上で動作するuv_async_send を用いた場合を除き)イベントループは他のスレッドと関連することはありません。 :doc:multiple は異なる複数のスレッドでイベントループを実行し、これらを管理します。

続きを読む

node.jsを支えるlibuvのチュートリアル"uvbook" :ネットワーク処理

この文書はuvbookの日本語翻訳の一部となります。文書そのものの説明その他については目次をご覧ください。

ネットワーク処理

libuvにおけるネットワーク処理は直接BSDソケットを用いた場合のそう変わりませんが、いくつかのことは簡単になっており、全てはノンブロッキングであり、コンセプトは同じです。加えてlibuvはBSDソケットを用いたソケットの準備、DNSルックアップ、色々なソケットパラメータの調整のようなやっかいで何度も必要となる低レベルの処理を抽象化するためのユーティリティ関数を提供します。

uv_tcp_tuv_udp_t 構造体はネットワークI/Oのために用いられます。

続きを読む

node.jsを支えるlibuvのチュートリアル"uvbook" :ファイルシステム

この文書はuvbookの日本語翻訳の一部となります。文書そのものの説明その他については目次をご覧ください。

ファイルシステム

単純なファイルシステムの読み取り/書き込みには uv_fs_* 関数群と uv_fs_t 構造体を用います。

Note
libuvのファイル操作はソケット操作とは異なります。ソケット操作はOSから提供されたノンブロッキング操作を用いています。ファイルシステム操作は内部的にはブロッキング関数を用いていますが、これらの関数はスレッドプールの内部で呼び出され、アプリケーションとのやりとりが必要になるときにイベントループに登録されたウォッチャに通知されます。

全てのファイルシステムは2つの形態を持ちます - 同期的非同期的 です。

同期的 な形態はコールバックが指定されない場合に自動的に呼び出され(、そして ブロック され)ます。関数の戻り値はUnixの戻り値と同様です(通常は成功時に0、エラー時に-1)。

非同期 な形態はコールパックが渡された時に呼び出され、戻り値は0となります。

続きを読む