Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,79 @@ is used in the EvoMaster Core (eg, when making HTTP calls) and
*/
public class EMTestUtils {

/**
* Loaded only once at class loading.
* Seed is still going to incremented with ++ at each use.
* The idea is to force each value unique during a session, even when generating hundreds of thousands of tests.
* However, when running again in generated test suite, a new starting seed might reduce chances of clashes,
* albeit cannot guarantee removal of them
*/
private static long seed = System.currentTimeMillis();

/**
*
* @param minLength Optional minimum length of the generated string
* @param maxLength Optional maximum length of the generated string
* @param prefix Optional fixed prefix shared by all generated strings
* @param postfix Optional fixed postfix shared by all generated strings
* @return
*/
public static String createString(Integer minLength, Integer maxLength, String prefix, String postfix){

if(minLength != null && minLength < 0){
throw new IllegalArgumentException("Negative minimum length: " + minLength);
}
if(maxLength != null && maxLength < 0){
throw new IllegalArgumentException("Negative maximum length: " + maxLength);
}

int min = 0;
if(minLength != null){
min = minLength;
}
int len = 0;
if(prefix != null){
len += prefix.length();
}
if(postfix != null){
len += postfix.length();
}
min = Math.max(min, len);

//actual check on inputs
if(maxLength != null && maxLength < len){
throw new IllegalArgumentException("Maximum length " + maxLength + " does not cover minimum prefix+postfix length: "+prefix+postfix);
}

//recompute with default values if not specified
if(prefix == null){
prefix = "u";
}
if(postfix == null){
postfix = "";
}
len = prefix.length() + postfix.length();

int maxDigits = 6; // 999 999 values
if(maxDigits + len < min){
maxDigits = min - len;
}
if(maxLength != null && maxDigits + len > maxLength ){
maxDigits = maxLength - len;
}

int mask = 1;
for(int i = 0; i < maxDigits; i++){
mask = mask * 10;
}

long value = seed % mask;
seed++;

return prefix + value + postfix;
}


/**
*
* @param locationHeader a URI-reference, coming from a "location" header. See RFC 7231.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,35 @@
package org.evomaster.test.utils;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class EMTestUtilsTest {

@Test
public void testCreateString(){

String prefix = "foo";
String postfix = "bar";
int min = 5;
int max = 10;

String first = EMTestUtils.createString(min, max, prefix, postfix);
assertTrue(first.startsWith(prefix));
assertTrue(first.endsWith(postfix));
assertTrue(first.length() >= min);
assertTrue(first.length() <= max);

String second = EMTestUtils.createString(min, max, prefix, postfix);
assertTrue(second.startsWith(prefix));
assertTrue(second.endsWith(postfix));
assertTrue(second.length() >= min);
assertTrue(second.length() <= max);

assertNotEquals(first, second);
}


@Test
public void testEmptyPath(){

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.foo.rest.examples.bb.authcreateusers

class AuthDto(
var email : String? = null,
var token: TokenDto? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.foo.rest.examples.bb.authcreateusers

import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration


@SpringBootApplication(exclude = [SecurityAutoConfiguration::class])
open class BBAuthCreateUsersApplication {

companion object {
@JvmStatic
fun main(args: Array<String>) {
SpringApplication.run(BBAuthCreateUsersApplication::class.java, *args)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.foo.rest.examples.bb.authcreateusers

import org.evomaster.e2etests.utils.CoveredTargets
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping(path = ["/api/authcreateusers"])
class BBAuthCreateUsersRest {

private val SECRET = "a complex secret - "

private val users = mutableMapOf<String, CreateUserDto>()

private val tokens = mutableMapOf<String, String>()


@PostMapping("/users")
fun createUser(@RequestBody user: CreateUserDto): ResponseEntity<Unit> {

if(user.email == null || user.username == null || user.password == null) {
return ResponseEntity.status(400).build()
}

if(!user.email!!.contains("@") || !user.email!!.contains(".")) {
return ResponseEntity.status(400).build()
}

if(user.password != user.repeatPassword) {
return ResponseEntity.status(400).build()
}

if(users.containsKey(user.email)){
return ResponseEntity.status(403).build()
}

users[user.email!!] = user
return ResponseEntity.status(201).build()
}


@PostMapping(path = ["/users/login"], consumes = [MediaType.APPLICATION_JSON_VALUE])
fun login(@RequestBody login : LoginDto) : ResponseEntity<AuthDto>{

val user = users[login.email!!]
?: return ResponseEntity.status(404).build()

if(login.password != user.password){
return ResponseEntity.status(400).build()
}

val secret = "$SECRET${System.currentTimeMillis()}"

tokens[secret] = user.email!!

return ResponseEntity.ok(AuthDto(user.email, TokenDto(secret)))
}

@GetMapping(path = ["/check"])
fun check(@RequestHeader("Authorization") authorization: String?) : ResponseEntity<String>{

val secret = authorization!!.substring("Bearer ".length)

if(tokens.containsKey(secret)){
CoveredTargets.cover("CHECK")
return ResponseEntity.ok("OK")
}

return ResponseEntity.status(401).build()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.foo.rest.examples.bb.authcreateusers

class CreateUserDto(
var email: String? = null,
var password: String? = null,
var repeatPassword: String? = null,
var username: String? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.foo.rest.examples.bb.authcreateusers

class LoginDto(
var email: String? = null,
var password: String? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.foo.rest.examples.bb.authcreateusers

class TokenDto(
var authToken : String? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.foo.rest.examples.bb.authcreateusers

import com.foo.rest.examples.bb.SpringController
import com.foo.rest.examples.bb.authcookie.CookieLoginApplication
import org.evomaster.client.java.controller.problem.ProblemInfo
import org.evomaster.client.java.controller.problem.RestProblem

class AuthCreateUsersController : SpringController(BBAuthCreateUsersApplication::class.java)
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.evomaster.e2etests.spring.rest.bb.authcreateusers

import com.foo.rest.examples.bb.authcookie.CookieLoginController
import com.foo.rest.examples.bb.authcreateusers.AuthCreateUsersController
import org.evomaster.core.output.OutputFormat
import org.evomaster.core.problem.rest.data.HttpVerb
import org.evomaster.e2etests.spring.rest.bb.SpringTestBase
import org.evomaster.e2etests.utils.EnterpriseTestBase
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.EnumSource

class BBAuthCreateUsersEMTest : SpringTestBase() {

companion object {
init {
shouldApplyInstrumentation = false
}

@BeforeAll
@JvmStatic
fun init() {
initClass(AuthCreateUsersController())
}
}

@ParameterizedTest
@EnumSource
fun testBlackBoxOutput(outputFormat: OutputFormat) {

executeAndEvaluateBBTest(
outputFormat,
"authcreateusers",
50,
3,
"CHECK"
){ args: MutableList<String> ->

setOption(args, "configPath", "src/test/resources/config/authcreateusers.yaml")

val solution = initAndRun(args)

assertTrue(solution.individuals.size >= 1)
assertHasAtLeastOne(solution, HttpVerb.GET, 200, "/api/authcreateusers/check", "OK")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
auth:
- name: "CreatedUser"
createUsers:
endpoint: "/api/authcreateusers/users"
contentType: "application/json"
verb: "POST"
payloadRaw: '{"email": "{$username}@example.com", "password": "123456", "repeatPassword": "123456", "username": "{$username}"}'
generators:
- placeHolder: "{$username}"
minLength: 8
maxLength: 30
prefix: "user_"
postfix: ""
loginEndpointAuth:
endpoint: "/api/authcreateusers/users/login"
verb: "POST"
contentType: "application/json"
payloadRaw: '{"email": "{$username}@example.com", "password": "123456"}'
token:
extractFrom: "body"
extractSelector: "/token/authToken"
sendIn: "header"
sendName: "Authorization"
sendTemplate: "Bearer {token}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.evomaster.core.output.auth

import org.evomaster.core.problem.httpws.HttpWsAction
import org.evomaster.core.search.Individual

object CreateUsersWriter {

fun getCreateUsersAuth(ind: Individual) = ind.seeAllActions()
.filterIsInstance<HttpWsAction>()
.filter { it.auth.createUsers != null }
.distinctBy { it.auth.name }
.map { it.auth.createUsers!! }
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ open class GraphQLFitness : HttpWsFitness<GraphQLIndividual>() {

goingToStartExecutingNewTest()

val cookies = AuthUtils.getCookies(client, getBaseUrl(), individual)
val tokens = AuthUtils.getTokens(client, getBaseUrl(), individual)
val placeholders = AuthUtils.createUsers(client, getBaseUrl(), individual)
val cookies = AuthUtils.getCookies(client, getBaseUrl(), individual, placeholders)
val tokens = AuthUtils.getTokens(client, getBaseUrl(), individual, placeholders)

val actionResults: MutableList<ActionResult> = mutableListOf()

Expand Down
Loading
Loading