Commit ae9dd2d3 authored by 0Tyler's avatar 0Tyler

feat: k6 test

parent 72769b24
import {check, group, sleep} from 'k6';
import {Rate, Trend} from 'k6/metrics';
import http from 'k6/http';
export const options = {
vus: 1, // 1 user looping for 10 secend
scenarios: {
contacts: {
executor: 'constant-vus',
vus: 10,
duration: '1s',
},
},
// scenarios: {
// contacts: {
// executor: 'per-vu-iterations',
// vus: 2,
// iterations: 1,
// maxDuration: '30s',
// },
// },
thresholds: {
http_req_duration: ['p(99)<1500'], // 99% of requests must complete below 1.5s
},
};
const URL = 'http://localhost:7168/api';
const USERNAME = 'user1';
const PASSWORD = '1234';
const PRODUCTID = '70d2d54e-1030-4a17-94b4-348713bf9631';
const TAGLIST = ["tag2"];
export default function () {
let token;
const loginRes = http.post(http.url`${URL}/login`,
JSON.stringify({
"username": USERNAME,
"password": PASSWORD
}))
check(loginRes, {
'logged in successfully': (resp) => !!resp.body,
});
const authHeaders = {
headers: {
Authorization: `${loginRes.body}`,
'Content-Type': 'application/json'
},
};
const product = http.get(http.url`${URL}/product/${PRODUCTID}`, authHeaders).json();
check(product, {'retrieved product': (obj) => !!obj});
const productByTag = http.post(http.url`${URL}/product`, JSON.stringify(TAGLIST), authHeaders).json();
check(productByTag, {'retrieved productByTag': (obj) => !!obj});
const checkout = http.post(http.url`${URL}/checkout`, JSON.stringify({
"lineItems": [
{
"sku": PRODUCTID,
"quantity": 1
}
],
"email": "[email protected]",
"creditCard": "test_card"
}), authHeaders)
check(checkout, {'checkout order': (obj) => !!obj});
}
\ No newline at end of file
...@@ -33,12 +33,12 @@ public class DefaultDataBean implements ApplicationRunner { ...@@ -33,12 +33,12 @@ public class DefaultDataBean implements ApplicationRunner {
productService.create(Product.builder() productService.create(Product.builder()
.name("product1") .name("product1")
.tags(List.of("tag1", "tag2")) .tags(List.of("tag1", "tag2"))
.quantity(10) .quantity(1000)
.build()); .build());
productService.create(Product.builder() productService.create(Product.builder()
.name("product2") .name("product2")
.tags(List.of("tag2", "tag3")) .tags(List.of("tag2", "tag3"))
.quantity(20) .quantity(2000)
.build()); .build());
} }
} }
...@@ -55,7 +55,7 @@ public class SecurityConfig { ...@@ -55,7 +55,7 @@ public class SecurityConfig {
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and() .and()
.authorizeRequests() .authorizeRequests()
.antMatchers("/h2**").permitAll() .antMatchers("/h2-console/**").permitAll()
.and() .and()
.addFilterBefore(jwtAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(jwtAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilter(new JwtAuthorizationFilter(authenticationManager, jwtTokenProvider)) .addFilter(new JwtAuthorizationFilter(authenticationManager, jwtTokenProvider))
......
...@@ -9,6 +9,7 @@ import edu.prlab.ecsimple.repo.ItemRepo; ...@@ -9,6 +9,7 @@ import edu.prlab.ecsimple.repo.ItemRepo;
import edu.prlab.ecsimple.repo.OrderRepo; import edu.prlab.ecsimple.repo.OrderRepo;
import edu.prlab.ecsimple.repo.ProductRepo; import edu.prlab.ecsimple.repo.ProductRepo;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -17,6 +18,7 @@ import java.util.Collection; ...@@ -17,6 +18,7 @@ import java.util.Collection;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@Transactional @Transactional
...@@ -43,6 +45,7 @@ public class OrderServiceImpl implements OrderService { ...@@ -43,6 +45,7 @@ public class OrderServiceImpl implements OrderService {
throw new BusinessException("There is not enough stock with product: " + product.getSku()); throw new BusinessException("There is not enough stock with product: " + product.getSku());
} }
product.setQuantity(leftQty); product.setQuantity(leftQty);
log.info("save product sku: " + product.getSku() + "qty: " + product.getQuantity());
return itemRepo.save(lineItem); return itemRepo.save(lineItem);
}) })
.orElseThrow(() -> new EntityNotFoundException("Not found Product: " + it.getSku()))); .orElseThrow(() -> new EntityNotFoundException("Not found Product: " + it.getSku())));
...@@ -73,6 +76,7 @@ public class OrderServiceImpl implements OrderService { ...@@ -73,6 +76,7 @@ public class OrderServiceImpl implements OrderService {
.orElseThrow(() -> new BusinessException("Save lineItem error"))) .orElseThrow(() -> new BusinessException("Save lineItem error")))
.peek(it -> addItemToOrder(order.getIid(), it.getSku())) .peek(it -> addItemToOrder(order.getIid(), it.getSku()))
.collect(Collectors.toList()); .collect(Collectors.toList());
lineItems.forEach(it -> log.info("sku : " + it.getSku() + " : qty: " + it.getQuantity()));
order.setLineItems(lineItems); order.setLineItems(lineItems);
return order; return order;
}); });
......
...@@ -8,7 +8,6 @@ import java.util.Optional; ...@@ -8,7 +8,6 @@ import java.util.Optional;
public interface ProductService { public interface ProductService {
Optional<Product> create(Product product); Optional<Product> create(Product product);
Optional<Product> getProduct(String sku); Optional<Product> getProduct(String sku);
List<Product> getProductsByTags(List<String> tags); List<Product> getProductsByTags(List<String> tags);
List<Product> getProducts(); List<Product> getProducts();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment