44
55use OpenTelemetry \Tests \Contrib \Instrumentation \Laravel \Integration \TestCase ;
66use Illuminate \Support \Facades \DB ;
7+ use OpenTelemetry \Tests \Contrib \Instrumentation \Laravel \Fixtures \Models \TestModel ;
78
89/**
910 * Integration test for Eloquent\Model hooks
@@ -23,9 +24,11 @@ protected function getEnvironmentSetUp($app): void
2324
2425 public function setUp (): void
2526 {
27+ parent ::setUp ();
28+
2629 // Setup database table for fixture model
2730 DB ::statement ('CREATE TABLE IF NOT EXISTS test_models(
28- id BIGINTEGER ,
31+ id BIGINT ,
2932 name VARCHAR(255),
3033 created_at DATETIME,
3134 updated_at DATETIME
@@ -36,6 +39,157 @@ public function setUp(): void
3639 public function tearDown (): void
3740 {
3841 // Reset table
39- DB ::statement ('DROP IF EXISTS test_models ' );
42+ DB ::statement ('DROP TABLE IF EXISTS test_models ' );
43+
44+ parent ::tearDown ();
45+ }
46+
47+ /**
48+ * @return \OpenTelemetry\SDK\Trace\ImmutableSpan[]
49+ */
50+ private function filterOnlyEloquentSpans (): array
51+ {
52+ // SQL spans be mixed up in storage because \Illuminate\Support\Facades\DB called.
53+ // So, filtering only spans has attribute named 'laravel.eloquent.operation'.
54+ return array_values (
55+ array_filter (
56+ iterator_to_array ($ this ->storage ),
57+ fn ($ span ) =>
58+ $ span instanceof \OpenTelemetry \SDK \Trace \ImmutableSpan &&
59+ $ span ->getAttributes ()->has ('laravel.eloquent.operation ' )
60+ )
61+ );
62+ }
63+
64+ public function test_create (): void
65+ {
66+ TestModel::create (['id ' => 1 , 'name ' => 'test ' ]);
67+
68+ $ spans = $ this ->filterOnlyEloquentSpans ();
69+
70+ $ this ->assertCount (1 , $ spans );
71+
72+ $ span = $ spans [0 ];
73+ $ this ->assertSame ('OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel::create ' , $ span ->getName ());
74+ $ this ->assertSame ('OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel ' , $ span ->getAttributes ()->get ('laravel.eloquent.model ' ));
75+ $ this ->assertSame ('test_models ' , $ span ->getAttributes ()->get ('laravel.eloquent.table ' ));
76+ $ this ->assertSame ('create ' , $ span ->getAttributes ()->get ('laravel.eloquent.operation ' ));
77+ }
78+
79+ public function test_find_and_get_models (): void
80+ {
81+ TestModel::find (1 );
82+
83+ $ spans = $ this ->filterOnlyEloquentSpans ();
84+
85+ // spans contains 2 eloquent spans for 'find' and 'get', because it method internally calls 'getModels' method.
86+ $ this ->assertCount (2 , $ spans );
87+
88+ foreach ($ spans as $ span ) {
89+ $ this ->assertSame (
90+ 'OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel ' ,
91+ $ span ->getAttributes ()->get ('laravel.eloquent.model ' )
92+ );
93+ $ this ->assertSame ('test_models ' , $ span ->getAttributes ()->get ('laravel.eloquent.table ' ));
94+
95+ $ operation = $ span ->getAttributes ()->get ('laravel.eloquent.operation ' );
96+ $ this ->assertSame (
97+ match ($ operation ) {
98+ 'find ' => 'OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel::find ' ,
99+ 'get ' => 'OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel::get '
100+ },
101+ $ span ->getName (),
102+ );
103+ }
104+ }
105+
106+ public function test_perform_insert (): void
107+ {
108+ // Illuminate\Database\Eloquent\Model::performInsert is called from Illuminate\Database\Eloquent\Model::save.
109+ // Mark as exists = false required, because performUpdate called if exists = true.
110+ $ model = (new TestModel ())->newInstance (['id ' => 1 , 'name ' => 'test ' ], false );
111+ $ model ->save ();
112+
113+ $ spans = $ this ->filterOnlyEloquentSpans ();
114+ $ this ->assertCount (1 , $ spans );
115+
116+ $ span = $ spans [0 ];
117+ $ this ->assertSame ('OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel::create ' , $ span ->getName ());
118+ $ this ->assertSame ('OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel ' , $ span ->getAttributes ()->get ('laravel.eloquent.model ' ));
119+ $ this ->assertSame ('test_models ' , $ span ->getAttributes ()->get ('laravel.eloquent.table ' ));
120+ $ this ->assertSame ('create ' , $ span ->getAttributes ()->get ('laravel.eloquent.operation ' ));
121+ }
122+
123+ public function test_perform_update (): void
124+ {
125+ // Illuminate\Database\Eloquent\Model::performInsert is called from Illuminate\Database\Eloquent\Model::save.
126+ // Mark as exists = true required, because performInsert called if exists = false.
127+ $ model = (new TestModel ())->newInstance (['id ' => 1 , 'name ' => 'test ' ], true );
128+ $ model ->save ();
129+
130+ $ spans = $ this ->filterOnlyEloquentSpans ();
131+ $ this ->assertCount (1 , $ spans );
132+
133+ $ span = $ spans [0 ];
134+ $ this ->assertSame ('OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel::update ' , $ span ->getName ());
135+ $ this ->assertSame ('OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel ' , $ span ->getAttributes ()->get ('laravel.eloquent.model ' ));
136+ $ this ->assertSame ('test_models ' , $ span ->getAttributes ()->get ('laravel.eloquent.table ' ));
137+ $ this ->assertSame ('update ' , $ span ->getAttributes ()->get ('laravel.eloquent.operation ' ));
138+ }
139+
140+ public function test_get_models (): void
141+ {
142+ TestModel::get ();
143+
144+ $ spans = $ this ->filterOnlyEloquentSpans ();
145+ $ this ->assertCount (1 , $ spans );
146+
147+ $ span = $ spans [0 ];
148+ $ this ->assertSame ('OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel::get ' , $ span ->getName ());
149+ $ this ->assertSame ('OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel ' , $ span ->getAttributes ()->get ('laravel.eloquent.model ' ));
150+ $ this ->assertSame ('test_models ' , $ span ->getAttributes ()->get ('laravel.eloquent.table ' ));
151+ $ this ->assertSame ('get ' , $ span ->getAttributes ()->get ('laravel.eloquent.operation ' ));
152+ }
153+
154+ public function test_destory (): void
155+ {
156+ TestModel::destroy ([1 ]);
157+
158+ $ spans = $ this ->filterOnlyEloquentSpans ();
159+
160+ // spans contains 2 eloquent spans for 'destroy' and 'get', because it method internally calls 'getModels' method.
161+ $ this ->assertCount (2 , $ spans );
162+
163+ foreach ($ spans as $ span ) {
164+ $ this ->assertSame (
165+ 'OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel ' ,
166+ $ span ->getAttributes ()->get ('laravel.eloquent.model ' )
167+ );
168+ $ this ->assertSame ('test_models ' , $ span ->getAttributes ()->get ('laravel.eloquent.table ' ));
169+
170+ $ operation = $ span ->getAttributes ()->get ('laravel.eloquent.operation ' );
171+ $ this ->assertSame (
172+ match ($ operation ) {
173+ 'destroy ' => 'OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel::destroy ' ,
174+ 'get ' => 'OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel::get '
175+ },
176+ $ span ->getName (),
177+ );
178+ }
179+ }
180+
181+ public function test_refresh (): void
182+ {
183+ $ model = new TestModel ();
184+ $ model ->refresh (); // no effect
185+
186+ $ spans = $ this ->filterOnlyEloquentSpans ();
187+ $ this ->assertCount (1 , $ spans );
188+
189+ $ span = $ spans [0 ];
190+ $ this ->assertSame ('OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel::refresh ' , $ span ->getName ());
191+ $ this ->assertSame ('OpenTelemetry\Tests\Contrib\Instrumentation\Laravel\Fixtures\Models\TestModel ' , $ span ->getAttributes ()->get ('laravel.eloquent.model ' ));
192+ $ this ->assertSame ('test_models ' , $ span ->getAttributes ()->get ('laravel.eloquent.table ' ));
193+ $ this ->assertSame ('refresh ' , $ span ->getAttributes ()->get ('laravel.eloquent.operation ' ));
40194 }
41195}
0 commit comments