-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrun-farcaster-test.ts
More file actions
312 lines (280 loc) · 10.7 KB
/
Copy pathrun-farcaster-test.ts
File metadata and controls
312 lines (280 loc) · 10.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
import { NestFactory } from '@nestjs/core';
import { AppModule } from './src/app.module';
import { FarcasterService } from './src/modules/social-media/services/farcaster.service';
import { SocialPostDto } from './src/modules/social-media/dto/social-post.dto';
async function testFarcasterService() {
console.log('🚀 Testing Farcaster Service');
console.log('═'.repeat(60));
let app;
try {
// Create NestJS application context
app = await NestFactory.createApplicationContext(AppModule);
const farcasterService = app.get(FarcasterService);
console.log('✅ NestJS application context created');
console.log('📱 FarcasterService initialized');
// --- Test Accounts ---
const testAccounts = [
{ username: 'dwr.eth', description: 'Warpcast founder' },
{ username: 'vitalik.eth', description: 'Vitalik Buterin' },
{ username: 'jessepollak', description: 'Jesse Pollak - Base' },
{ username: 'invalid-user-xyz123', description: 'Invalid user' },
];
console.log('\n📋 Famous Farcaster accounts to test:');
testAccounts.forEach(acc =>
console.log(` • ${acc.username} (${acc.description})`),
);
// --- Test 1: getRecentCasts for each account ---
console.log('\n\n--- Test 1: Fetching Recent Casts ---');
console.log('─'.repeat(40));
for (const account of testAccounts) {
console.log(`\n▶️ Testing getRecentCasts for: ${account.username}`);
const startTime = Date.now();
const posts: SocialPostDto[] = await farcasterService.getRecentCasts(
account.username,
);
const endTime = Date.now();
console.log(`⏱️ Request completed in ${endTime - startTime}ms`);
if (posts.length > 0) {
console.log(`✅ Found ${posts.length} posts.`);
console.log(' Sample posts:');
posts.slice(0, 3).forEach((post, index) => {
console.log(
` ${index + 1}. [${post.createdAt.toISOString().split('T')[0]}] ${post.text.substring(0, 70).replace(/\n/g, ' ')}...`,
);
console.log(` URL: ${post.url}`);
});
if (posts.length > 3) {
console.log(` ... and ${posts.length - 3} more.`);
}
} else {
console.log(
`ℹ️ No posts found for ${account.username}. This is expected for the invalid user.`,
);
}
}
// --- Test 2: Incremental Fetching ---
console.log('\n\n--- Test 2: Incremental Fetching ---');
console.log('─'.repeat(40));
const incrementalTestUser = 'dwr.eth';
console.log(`\n▶️ Testing incremental fetch for: ${incrementalTestUser}`);
// First, fetch all recent posts to get a timestamp
const initialPosts =
await farcasterService.getRecentCasts(incrementalTestUser);
if (initialPosts.length > 2) {
// Get a timestamp from the 3rd post to use as our "since" marker
const sinceTimestamp = initialPosts[2].createdAt;
console.log(
` Set 'since' timestamp to: ${sinceTimestamp.toISOString()} (from 3rd post)`,
);
console.log(
`\n Fetching posts newer than ${sinceTimestamp.toISOString()}...`,
);
const startTime = Date.now();
const incrementalPosts = await farcasterService.getRecentCastsIncremental(
incrementalTestUser,
sinceTimestamp,
);
const endTime = Date.now();
console.log(
`⏱️ Incremental request completed in ${endTime - startTime}ms`,
);
console.log(`✅ Found ${incrementalPosts.length} new posts.`);
console.log(
` (Expected to find 2, since we used the 3rd post's timestamp)`,
);
if (incrementalPosts.length > 0) {
console.log(' New posts:');
incrementalPosts.forEach((post, index) => {
console.log(
` ${index + 1}. [${post.createdAt.toISOString().split('T')[0]}] ${post.text.substring(0, 70).replace(/\n/g, ' ')}...`,
);
});
}
} else {
console.log(
`ℹ️ Not enough posts for ${incrementalTestUser} to run incremental test.`,
);
}
// --- Test 3: FID Lookup Caching ---
console.log('\n\n--- Test 3: FID Lookup Caching ---');
console.log('─'.repeat(40));
const cacheTestUser = 'vitalik.eth';
console.log(`\n▶️ Testing FID lookup caching for: ${cacheTestUser}`);
// First call - should be from API
console.log('\n First call (should be from API):');
let startTime = Date.now();
let fidResult = await farcasterService.getFidByUsername(cacheTestUser);
let endTime = Date.now();
console.log(
` FID: ${fidResult.fid}, Success: ${fidResult.success}, From Cache: ${fidResult.fromCache}`,
);
console.log(`⏱️ Completed in ${endTime - startTime}ms`);
// Second call - should be from cache
console.log('\n Second call (should be from cache):');
startTime = Date.now();
fidResult = await farcasterService.getFidByUsername(cacheTestUser);
endTime = Date.now();
console.log(
` FID: ${fidResult.fid}, Success: ${fidResult.success}, From Cache: ${fidResult.fromCache}`,
);
console.log(
`⏱️ Completed in ${endTime - startTime}ms (should be much faster)`,
);
// --- Test 4: Batch Operation Benchmarking ---
console.log('\n\n--- Test 4: Batch Operation Benchmarking ---');
console.log('─'.repeat(40));
const batchTestAccounts = ['dwr.eth', 'vitalik.eth', 'jessepollak'];
console.log(
`\n▶️ Testing batch operations for: ${batchTestAccounts.join(', ')}`,
);
// Sequential processing benchmark
console.log('\n 📊 Sequential Processing Benchmark:');
const sequentialStartTime = Date.now();
const sequentialResults: Array<{
username: string;
postCount: number;
duration: number;
}> = [];
for (const username of batchTestAccounts) {
const accountStartTime = Date.now();
const posts = await farcasterService.getRecentCasts(username);
const accountEndTime = Date.now();
sequentialResults.push({
username,
postCount: posts.length,
duration: accountEndTime - accountStartTime,
});
console.log(
` ${username}: ${posts.length} posts in ${accountEndTime - accountStartTime}ms`,
);
}
const sequentialTotalTime = Date.now() - sequentialStartTime;
console.log(` 📈 Sequential Total: ${sequentialTotalTime}ms`);
// Parallel processing benchmark
console.log('\n 🚀 Parallel Processing Benchmark:');
const parallelStartTime = Date.now();
const parallelPromises = batchTestAccounts.map(async username => {
const accountStartTime = Date.now();
const posts = await farcasterService.getRecentCasts(username);
const accountEndTime = Date.now();
return {
username,
postCount: posts.length,
duration: accountEndTime - accountStartTime,
};
});
const parallelResults = await Promise.all(parallelPromises);
const parallelTotalTime = Date.now() - parallelStartTime;
parallelResults.forEach(result => {
console.log(
` ${result.username}: ${result.postCount} posts in ${result.duration}ms`,
);
});
console.log(` 📈 Parallel Total: ${parallelTotalTime}ms`);
// Performance comparison
console.log('\n 📊 Performance Comparison:');
const timeReduction = sequentialTotalTime - parallelTotalTime;
const percentageImprovement = (
(timeReduction / sequentialTotalTime) *
100
).toFixed(1);
console.log(` Sequential: ${sequentialTotalTime}ms`);
console.log(` Parallel: ${parallelTotalTime}ms`);
console.log(
` Reduction: ${timeReduction}ms (${percentageImprovement}% faster)`,
);
// Batch FID lookup benchmark
console.log('\n 🔍 Batch FID Lookup Benchmark:');
const fidBenchmarkAccounts = [
'dwr.eth',
'vitalik.eth',
'jessepollak',
'balajis.eth',
];
// Sequential FID lookups
const fidSequentialStart = Date.now();
const fidSequentialResults: Array<{
username: string;
fid: any;
success: any;
fromCache: any;
duration: number;
}> = [];
for (const username of fidBenchmarkAccounts) {
const startTime = Date.now();
const fidResult = await farcasterService.getFidByUsername(username);
const endTime = Date.now();
fidSequentialResults.push({
username,
fid: fidResult.fid,
success: fidResult.success,
fromCache: fidResult.fromCache,
duration: endTime - startTime,
});
}
const fidSequentialTotal = Date.now() - fidSequentialStart;
// Parallel FID lookups
const fidParallelStart = Date.now();
const fidParallelPromises = fidBenchmarkAccounts.map(async username => {
const startTime = Date.now();
const fidResult = await farcasterService.getFidByUsername(username);
const endTime = Date.now();
return {
username,
fid: fidResult.fid,
success: fidResult.success,
fromCache: fidResult.fromCache,
duration: endTime - startTime,
};
});
const fidParallelResults = await Promise.all(fidParallelPromises);
const fidParallelTotal = Date.now() - fidParallelStart;
console.log(' Sequential FID Lookups:');
fidSequentialResults.forEach(result => {
console.log(
` ${result.username}: FID ${result.fid} in ${result.duration}ms (cache: ${result.fromCache})`,
);
});
console.log(` Sequential Total: ${fidSequentialTotal}ms`);
console.log(' Parallel FID Lookups:');
fidParallelResults.forEach(result => {
console.log(
` ${result.username}: FID ${result.fid} in ${result.duration}ms (cache: ${result.fromCache})`,
);
});
console.log(` Parallel Total: ${fidParallelTotal}ms`);
const fidTimeReduction = fidSequentialTotal - fidParallelTotal;
const fidPercentageImprovement = (
(fidTimeReduction / fidSequentialTotal) *
100
).toFixed(1);
console.log(
` FID Lookup Improvement: ${fidTimeReduction}ms (${fidPercentageImprovement}% faster)`,
);
} catch (error) {
console.error('\n❌ Test failed with an unexpected error:');
if (error instanceof Error) {
console.error('Error:', error.message);
console.error('Stack:', error.stack);
} else {
console.error('Caught an unknown error object:', error);
}
} finally {
if (app) {
await app.close();
console.log('\n✅ Test completed and application context closed.');
}
}
}
// Main execution
if (require.main === module) {
testFarcasterService()
.then(() => {
console.log('\n🎉 All done!');
process.exit(0);
})
.catch(error => {
console.error('\n💥 Unhandled error in test runner:', error);
process.exit(1);
});
}