Last active
          July 19, 2025 20:42 
        
      - 
      
- 
        Save orenaksakal/72381b8c195ebf7e5f2b965cd6195b53 to your computer and use it in GitHub Desktop. 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | http.route({ | |
| path: "/api/posts", | |
| method: "POST", | |
| handler: httpAction(async (ctx, request) => { | |
| const { title, content } = await request.json(); | |
| if (!title || !content) { | |
| return new Response("Title and content are required", { | |
| status: 400, | |
| }); | |
| } | |
| const post = await ctx.runMutation(internal.posts.create, { | |
| title, | |
| content, | |
| }); | |
| return new Response(JSON.stringify({ post }), { | |
| status: 200, | |
| }); | |
| }), | |
| }); | |
| http.route({ | |
| path: "/api/posts", | |
| method: "PATCH", | |
| handler: httpAction(async (ctx, request) => { | |
| const { id, content } = await request.json(); | |
| if (!id) { | |
| return new Response("Post ID is required", { | |
| status: 400, | |
| }); | |
| } | |
| await ctx.runMutation(internal.posts.update, { | |
| id, | |
| content, | |
| }); | |
| return new Response(JSON.stringify({ post: id }), { | |
| status: 200, | |
| }); | |
| }), | |
| }); | |
| http.route({ | |
| path: "/api/posts", | |
| method: "GET", | |
| handler: httpAction(async (ctx, request) => { | |
| const id = new URL(request.url).searchParams.get("id"); | |
| console.log("Retrieving post with ID:", { id, url: request.url }); | |
| if (!id) { | |
| return new Response("Post ID is required", { | |
| status: 400, | |
| }); | |
| } | |
| const post = await ctx.runMutation(internal.posts.get, { id }); | |
| const returnpost = post[0]; | |
| return new Response(JSON.stringify({ postId: returnpost._id }), { | |
| status: 200, | |
| }); | |
| }), | |
| }); | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | // load-test.js | |
| import http from 'k6/http'; | |
| import { check, sleep } from 'k6'; | |
| // --- TEST CONFIGURATION --- | |
| // Tweak these values to increase or decrease the load. | |
| export const options = { | |
| // vus: Number of virtual users to simulate. | |
| // duration: The total duration of the test. | |
| vus: 5000, // Simulate 10 concurrent users | |
| duration: '60s', // Run the test for 30 seconds | |
| // Thresholds are pass/fail criteria for the test. | |
| thresholds: { | |
| 'http_req_duration': ['p(95)<500'], // 95% of requests must complete below 500ms | |
| 'http_req_failed': ['rate<0.01'], // Request failure rate must be less than 1% | |
| 'checks': ['rate>0.99'], // Success rate of our checks must be > 99% | |
| }, | |
| }; | |
| // --- TEST CONSTANTS --- | |
| // Make sure to change these to match your PocketBase instance. | |
| const PB_URL = ''; // Your PocketBase URL | |
| const USER_EMAIL = ''; // A valid user email | |
| const USER_PASSWORD = ''; // The password for that user | |
| // The 'setup' function runs once before the test starts. | |
| // We'll use it to authenticate and get a token that all virtual users can share. | |
| export function setup() { | |
| // console.log('Authenticating user...'); | |
| // const authRes = http.post( | |
| // `${PB_URL}/api/collections/users/auth-with-password`, | |
| // JSON.stringify({ | |
| // identity: USER_EMAIL, | |
| // password: USER_PASSWORD, | |
| // }), | |
| // { headers: { 'Content-Type': 'application/json' } } | |
| // ); | |
| // check(authRes, { 'authentication successful': (res) => res.status === 200 }); | |
| // const authData = authRes.json(); | |
| // const authToken = authData.token; | |
| // const userId = authData.record.id; | |
| // console.log('Authentication successful. Starting test...'); | |
| // return { authToken, userId }; // Pass the token and user ID to the main test function | |
| console.log('Setup complete. Starting test...'); | |
| } | |
| // --- MAIN TEST FUNCTION --- | |
| // This is the code that each virtual user will execute in a loop. | |
| // The 'data' parameter receives the return value from the setup function. | |
| export default function (data) { | |
| // const { authToken, userId } = data; | |
| // // Set the authorization header for all subsequent requests | |
| // const params = { | |
| // headers: { | |
| // 'Authorization': `Bearer ${authToken}`, | |
| // 'Content-Type': 'application/json', | |
| // }, | |
| // }; | |
| // 1. CREATE a new post | |
| const createPayload = JSON.stringify({ | |
| title: `My Test Post - VU ${__VU} ITER ${__ITER}`, // Use k6 vars for unique data | |
| content: 'This is the content of the post.', | |
| }); | |
| const createRes = http.post(`${PB_URL}/api/posts`, createPayload); | |
| check(createRes, { 'post created successfully': (res) => res.status === 200 }); // PocketBase returns 200 on create via SDK-like calls | |
| // We need the ID of the new post for the next steps | |
| const postId = createRes.json().post; | |
| // Think time: simulate a user pausing for a second after creating a post | |
| sleep(1); | |
| // 2. READ the created post | |
| const readRes = http.get(`${PB_URL}/api/posts?id=${postId}`); | |
| check(readRes, { 'post read successfully': (res) => res.status === 200 }); | |
| sleep(1); | |
| // 3. UPDATE the post | |
| const updatePayload = JSON.stringify({ | |
| id: postId, | |
| content: 'This is the updated content.', | |
| }); | |
| const updateRes = http.patch(`${PB_URL}/api/posts`, updatePayload); | |
| check(updateRes, { 'post updated successfully': (res) => res.status === 200 }); | |
| // sleep(1); | |
| // // 4. DELETE the post (cleanup) | |
| // const deleteRes = http.del(`${PB_URL}/api/posts/${postId}`, null); | |
| // check(deleteRes, { 'post deleted successfully': (res) => res.status === 204 }); | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | app.post("/api/posts", async (context) => { | |
| const { title, content } = await context.req.json(); | |
| const post = await db.insert(posts).values({ | |
| title: title || "Default Title", | |
| content: content || "Default Content", | |
| }).returning(); | |
| console.log("Created post:", post); | |
| return context.json(post); | |
| }); | |
| app.get("/api/posts/:id", async (context) => { | |
| const id = context.req.param("id"); | |
| const post = await db.query.posts.findFirst({ | |
| where: eq(posts.id, id), | |
| }); | |
| console.log("Updated post:", post); | |
| return context.json(post || { error: "Post not found" }); | |
| }); | |
| app.patch("/api/posts/:id", async (context) => { | |
| const id = context.req.param("id"); | |
| const { content } = await context.req.json(); | |
| console.log("Updating post with ID:", id, "Content:", content); | |
| try { | |
| await db.update(posts).set({ content }).where(eq(posts.id, id)); | |
| } catch (error) { | |
| console.error("Error updating post:", error); | |
| return context.json({ error: "Failed to update post" }, 500); | |
| } | |
| console.log("Updated post:"); | |
| return context.json({ message: "Post updated successfully" }); | |
| }); | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | // load-test.js | |
| import http from 'k6/http'; | |
| import { check, sleep } from 'k6'; | |
| // --- TEST CONFIGURATION --- | |
| // Tweak these values to increase or decrease the load. | |
| export const options = { | |
| // vus: Number of virtual users to simulate. | |
| // duration: The total duration of the test. | |
| vus: 5000, // Simulate 10 concurrent users | |
| duration: '60s', // Run the test for 30 seconds | |
| // Thresholds are pass/fail criteria for the test. | |
| thresholds: { | |
| 'http_req_duration': ['p(95)<500'], // 95% of requests must complete below 500ms | |
| 'http_req_failed': ['rate<0.01'], // Request failure rate must be less than 1% | |
| 'checks': ['rate>0.99'], // Success rate of our checks must be > 99% | |
| }, | |
| }; | |
| // --- TEST CONSTANTS --- | |
| // Make sure to change these to match your PocketBase instance. | |
| const PB_URL = ''; // Your PocketBase URL | |
| const USER_EMAIL = ''; // A valid user email | |
| const USER_PASSWORD = ''; // The password for that user | |
| // The 'setup' function runs once before the test starts. | |
| // We'll use it to authenticate and get a token that all virtual users can share. | |
| export function setup() { | |
| // console.log('Authenticating user...'); | |
| // const authRes = http.post( | |
| // `${PB_URL}/api/collections/users/auth-with-password`, | |
| // JSON.stringify({ | |
| // identity: USER_EMAIL, | |
| // password: USER_PASSWORD, | |
| // }), | |
| // { headers: { 'Content-Type': 'application/json' } } | |
| // ); | |
| // check(authRes, { 'authentication successful': (res) => res.status === 200 }); | |
| // const authData = authRes.json(); | |
| // const authToken = authData.token; | |
| // const userId = authData.record.id; | |
| // console.log('Authentication successful. Starting test...'); | |
| // return { authToken, userId }; // Pass the token and user ID to the main test function | |
| console.log('Setup complete. Starting test...'); | |
| } | |
| // --- MAIN TEST FUNCTION --- | |
| // This is the code that each virtual user will execute in a loop. | |
| // The 'data' parameter receives the return value from the setup function. | |
| export default function (data) { | |
| // const { authToken, userId } = data; | |
| // // Set the authorization header for all subsequent requests | |
| // const params = { | |
| // headers: { | |
| // 'Authorization': `Bearer ${authToken}`, | |
| // 'Content-Type': 'application/json', | |
| // }, | |
| // }; | |
| // 1. CREATE a new post | |
| const createPayload = JSON.stringify({ | |
| title: `My Test Post - VU ${__VU} ITER ${__ITER}`, // Use k6 vars for unique data | |
| content: 'This is the content of the post.', | |
| }); | |
| const createRes = http.post(`${PB_URL}/api/posts`, createPayload); | |
| check(createRes, { 'post created successfully': (res) => res.status === 200 }); // PocketBase returns 200 on create via SDK-like calls | |
| // We need the ID of the new post for the next steps | |
| const postId = createRes.json()[0].id; | |
| // Think time: simulate a user pausing for a second after creating a post | |
| sleep(1); | |
| // 2. READ the created post | |
| const readRes = http.get(`${PB_URL}/api/posts/${postId}`); | |
| check(readRes, { 'post read successfully': (res) => res.status === 200 }); | |
| sleep(1); | |
| // 3. UPDATE the post | |
| const updatePayload = JSON.stringify({ | |
| content: 'This is the updated content.', | |
| }); | |
| const updateRes = http.patch(`${PB_URL}/api/posts/${postId}`, updatePayload); | |
| check(updateRes, { 'post updated successfully': (res) => res.status === 200 }); | |
| // sleep(1); | |
| // // 4. DELETE the post (cleanup) | |
| // const deleteRes = http.del(`${PB_URL}/api/posts/${postId}`, null); | |
| // check(deleteRes, { 'post deleted successfully': (res) => res.status === 204 }); | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | // load-test.js | |
| import http from 'k6/http'; | |
| import { check, sleep } from 'k6'; | |
| // --- TEST CONFIGURATION --- | |
| // Tweak these values to increase or decrease the load. | |
| export const options = { | |
| // vus: Number of virtual users to simulate. | |
| // duration: The total duration of the test. | |
| vus: 5000, // Simulate 10 concurrent users | |
| duration: '60s', // Run the test for 30 seconds | |
| // Thresholds are pass/fail criteria for the test. | |
| thresholds: { | |
| 'http_req_duration': ['p(95)<500'], // 95% of requests must complete below 500ms | |
| 'http_req_failed': ['rate<0.01'], // Request failure rate must be less than 1% | |
| 'checks': ['rate>0.99'], // Success rate of our checks must be > 99% | |
| }, | |
| }; | |
| // --- TEST CONSTANTS --- | |
| // Make sure to change these to match your PocketBase instance. | |
| const PB_URL = ''; // Your PocketBase URL | |
| const USER_EMAIL = ''; // A valid user email | |
| const USER_PASSWORD = ''; // The password for that user | |
| // The 'setup' function runs once before the test starts. | |
| // We'll use it to authenticate and get a token that all virtual users can share. | |
| export function setup() { | |
| console.log('Authenticating user...'); | |
| const authRes = http.post( | |
| `${PB_URL}/api/collections/users/auth-with-password`, | |
| JSON.stringify({ | |
| identity: USER_EMAIL, | |
| password: USER_PASSWORD, | |
| }), | |
| { headers: { 'Content-Type': 'application/json' } } | |
| ); | |
| check(authRes, { 'authentication successful': (res) => res.status === 200 }); | |
| const authData = authRes.json(); | |
| const authToken = authData.token; | |
| const userId = authData.record.id; | |
| console.log('Authentication successful. Starting test...'); | |
| return { authToken, userId }; // Pass the token and user ID to the main test function | |
| } | |
| // --- MAIN TEST FUNCTION --- | |
| // This is the code that each virtual user will execute in a loop. | |
| // The 'data' parameter receives the return value from the setup function. | |
| export default function (data) { | |
| const { authToken, userId } = data; | |
| // Set the authorization header for all subsequent requests | |
| const params = { | |
| headers: { | |
| 'Authorization': `Bearer ${authToken}`, | |
| 'Content-Type': 'application/json', | |
| }, | |
| }; | |
| // 1. CREATE a new post | |
| const createPayload = JSON.stringify({ | |
| title: `My Test Post - VU ${__VU} ITER ${__ITER}`, // Use k6 vars for unique data | |
| content: 'This is the content of the post.', | |
| author: userId, // Associate the post with the authenticated user | |
| }); | |
| const createRes = http.post(`${PB_URL}/api/collections/posts/records`, createPayload, params); | |
| check(createRes, { 'post created successfully': (res) => res.status === 200 }); // PocketBase returns 200 on create via SDK-like calls | |
| // We need the ID of the new post for the next steps | |
| const postId = createRes.json('id'); | |
| // Think time: simulate a user pausing for a second after creating a post | |
| sleep(1); | |
| // 2. READ the created post | |
| const readRes = http.get(`${PB_URL}/api/collections/posts/records/${postId}`, params); | |
| check(readRes, { 'post read successfully': (res) => res.status === 200 }); | |
| sleep(1); | |
| // 3. UPDATE the post | |
| const updatePayload = JSON.stringify({ | |
| content: 'This is the updated content.', | |
| }); | |
| const updateRes = http.patch(`${PB_URL}/api/collections/posts/records/${postId}`, updatePayload, params); | |
| check(updateRes, { 'post updated successfully': (res) => res.status === 200 }); | |
| sleep(1); | |
| // // 4. DELETE the post (cleanup) | |
| // const deleteRes = http.del(`${PB_URL}/api/collections/posts/records/${postId}`, null, params); | |
| // check(deleteRes, { 'post deleted successfully': (res) => res.status === 204 }); | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment