mirror of
https://github.com/ProjectSWGCore/Holocore.git
synced 2026-09-11 21:45:26 -04:00
Merge pull request #495 from madsboddum/buildscript_fixes
Buildscript fixes
This commit is contained in:
@@ -1,6 +1,3 @@
|
||||
[submodule "pswgcommon"]
|
||||
path = pswgcommon
|
||||
url = https://github.com/ProjectSWGCore/pswgcommon.git
|
||||
[submodule "client-holocore"]
|
||||
path = client-holocore
|
||||
url = https://github.com/ProjectSWGCore/client-holocore.git
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
pipelines:
|
||||
default:
|
||||
- step:
|
||||
name: fetch code
|
||||
image: alpine/git
|
||||
script:
|
||||
- git submodule update --init
|
||||
artifacts:
|
||||
- pswgcommon/**
|
||||
- client-holocore/**
|
||||
- step:
|
||||
name: test, build, and deploy
|
||||
image: openjdk:12
|
||||
caches:
|
||||
- docker
|
||||
- gradle
|
||||
- gradlewrapper
|
||||
script:
|
||||
- ./gradlew test
|
||||
- ./gradlew jlink
|
||||
- docker login -u $DOCKER_HUB_USER -p $DOCKER_HUB_PASSWORD
|
||||
- docker build -t $DOCKER_HUB_REPO/holocore:$BITBUCKET_BRANCH .
|
||||
- docker push $DOCKER_HUB_REPO/holocore:$BITBUCKET_BRANCH
|
||||
artifacts:
|
||||
- pswgcommon/**
|
||||
- client-holocore/**
|
||||
- .gradle/**
|
||||
- build/**
|
||||
services:
|
||||
- docker
|
||||
|
||||
definitions:
|
||||
caches:
|
||||
gradlewrapper: ~/.gradle/wrapper
|
||||
+5
-16
@@ -44,21 +44,7 @@ sourceSets {
|
||||
implementation(group="org.mockito", name="mockito-core", version="3.8.0")
|
||||
}
|
||||
}
|
||||
create("display") {
|
||||
dependencies {
|
||||
implementation(project(":pswgcommon"))
|
||||
}
|
||||
}
|
||||
create("utility")
|
||||
create("integration") {
|
||||
dependencies {
|
||||
implementation(project(":pswgcommon"))
|
||||
implementation(project(":client-holocore"))
|
||||
implementation(group="org.xerial", name="sqlite-jdbc", version="3.23.1")
|
||||
implementation(group="org.mongodb", name="mongodb-driver-sync", version="3.12.2")
|
||||
implementation(group="junit", name="junit", version="4.12")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val utilityImplementation by configurations.getting {
|
||||
@@ -66,8 +52,11 @@ val utilityImplementation by configurations.getting {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
utilityImplementation(project(":")) // Root project, which would be holocore itself
|
||||
utilityImplementation(project(":pswgcommon"))
|
||||
val holocoreProject = project(":")
|
||||
val pswgcommonProject = project(":pswgcommon")
|
||||
|
||||
utilityImplementation(holocoreProject)
|
||||
utilityImplementation(pswgcommonProject)
|
||||
utilityImplementation(group="org.jetbrains.kotlin", name="kotlin-stdlib", version="1.3.50")
|
||||
utilityImplementation(group="org.xerial", name="sqlite-jdbc", version="3.23.1")
|
||||
utilityImplementation(group="org.mongodb", name="mongodb-driver-sync", version="3.12.2")
|
||||
|
||||
Submodule client-holocore deleted from 38abddab1a
@@ -1,3 +1,2 @@
|
||||
rootProject.name = 'holocore'
|
||||
include ':pswgcommon'
|
||||
include ':client-holocore'
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
package com.projectswg.holocore;
|
||||
|
||||
import com.projectswg.common.network.packets.swg.holo.HoloConnectionStopped.ConnectionStoppedReason;
|
||||
import com.projectswg.holocore.client.HolocoreSocket;
|
||||
import me.joshlarson.jlcommon.concurrency.BasicThread;
|
||||
import me.joshlarson.jlcommon.concurrency.Delay;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
public class ProjectSWGRunner {
|
||||
|
||||
private final BasicThread runner;
|
||||
|
||||
public ProjectSWGRunner() {
|
||||
this.runner = new BasicThread("holocore", () -> ProjectSWG.run(new String[0]));
|
||||
}
|
||||
|
||||
public void start() {
|
||||
runner.start();
|
||||
{
|
||||
try (HolocoreSocket socket = new HolocoreSocket(InetAddress.getLoopbackAddress(), 44463)) {
|
||||
long start = System.nanoTime();
|
||||
boolean connected = false;
|
||||
while (System.nanoTime() - start <= 60E9) { // 60s max wait
|
||||
connected = socket.getServerStatus().equals("UP");
|
||||
if (connected)
|
||||
break;
|
||||
Delay.sleepSeconds(1);
|
||||
}
|
||||
if (connected) {
|
||||
start = System.nanoTime();
|
||||
while (System.nanoTime() - start <= 60E9) { // 60s max wait
|
||||
if (socket.connect(1000)) {
|
||||
socket.disconnect(ConnectionStoppedReason.NETWORK);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
runner.stop(true);
|
||||
runner.awaitTermination(5000);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.projectswg.holocore.integration.resources;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class ClientRunner {
|
||||
|
||||
protected HolocoreClient client;
|
||||
|
||||
@Before
|
||||
public void initializeClient() {
|
||||
client = new HolocoreClient();
|
||||
Assert.assertTrue(client.login("Obique", "pass"));
|
||||
}
|
||||
|
||||
@After
|
||||
public void terminateClient() {
|
||||
client.disconnect();
|
||||
}
|
||||
|
||||
}
|
||||
-89
@@ -1,89 +0,0 @@
|
||||
package com.projectswg.holocore.integration.resources;
|
||||
|
||||
import com.projectswg.common.data.customization.CustomizationString;
|
||||
import com.projectswg.common.network.packets.swg.login.creation.*;
|
||||
import org.junit.Assert;
|
||||
|
||||
public class ClientUtilities {
|
||||
|
||||
private ClientUtilities() {
|
||||
|
||||
}
|
||||
|
||||
public static void createCharacter(HolocoreClient client) {
|
||||
client.send(new RandomNameRequest());
|
||||
RandomNameResponse randomNameResponse = (RandomNameResponse) client.receive();
|
||||
Assert.assertNotNull(randomNameResponse);
|
||||
|
||||
client.send(new ClientVerifyAndLockNameRequest(randomNameResponse.getRace(), randomNameResponse.getRandomName()));
|
||||
ClientVerifyAndLockNameResponse verifiedResponse = (ClientVerifyAndLockNameResponse) client.receive();
|
||||
Assert.assertNotNull(verifiedResponse);
|
||||
|
||||
ClientCreateCharacter create = new ClientCreateCharacter();
|
||||
create.setCharCustomization(createCharacterCustomization());
|
||||
create.setName(randomNameResponse.getRandomName());
|
||||
create.setRace(randomNameResponse.getRace());
|
||||
create.setStart("mos_eisley");
|
||||
create.setHair("object/tangible/hair/human/hair_human_male_s02.iff");
|
||||
create.setHairCustomization(createHairCustomization());
|
||||
create.setClothes("combat_brawler");
|
||||
create.setHeight(0.9648422f);
|
||||
create.setTutorial(false);
|
||||
create.setProfession("smuggler_1a");
|
||||
create.setStartingPhase("class_smuggler_phase1_novice");
|
||||
client.send(create);
|
||||
|
||||
CreateCharacterSuccess success = (CreateCharacterSuccess) client.receive();
|
||||
Assert.assertNotNull(success);
|
||||
client.addCharacter(success.getId(), create.getName());
|
||||
client.zoneIn(success.getId());
|
||||
}
|
||||
|
||||
private static CustomizationString createCharacterCustomization() {
|
||||
CustomizationString str = new CustomizationString();
|
||||
str.put("/shared_owner/blend_lipfullness_0", 33);
|
||||
str.put("/shared_owner/blend_lipfullness_1", 0);
|
||||
str.put("/shared_owner/blend_chinsize_0", 208);
|
||||
str.put("/shared_owner/blend_chinsize_1", 0);
|
||||
str.put("/shared_owner/blend_fat", 0);
|
||||
str.put("/shared_owner/blend_ears_1", 0);
|
||||
str.put("/shared_owner/blend_ears_0", 191);
|
||||
str.put("/shared_owner/blend_noselength_0", 0);
|
||||
str.put("/shared_owner/blend_noselength_1", 40);
|
||||
str.put("/shared_owner/blend_jaw_1", 0);
|
||||
str.put("/shared_owner/blend_jaw_0", 156);
|
||||
str.put("/shared_owner/blend_eyeshape_1", 32);
|
||||
str.put("/shared_owner/blend_nosewidth_1", 0);
|
||||
str.put("/shared_owner/blend_eyeshape_0", 0);
|
||||
str.put("/shared_owner/blend_nosewidth_0", 35);
|
||||
str.put("/shared_owner/index_color_skin", 35);
|
||||
str.put("/shared_owner/blend_cheeks_1", 5);
|
||||
str.put("/shared_owner/blend_eyedirection_1", 16);
|
||||
str.put("/shared_owner/blend_skinny", 26);
|
||||
str.put("/shared_owner/blend_cheeks_0", 0);
|
||||
str.put("/shared_owner/blend_eyedirection_0", 0);
|
||||
str.put("/shared_owner/blend_nosedepth_1", 0);
|
||||
str.put("/shared_owner/blend_nosedepth_0", 107);
|
||||
str.put("/shared_owner/blend_lipwidth_0", 23);
|
||||
str.put("/shared_owner/blend_lipwidth_1", 0);
|
||||
str.put("/shared_owner/blend_muscle", 144);
|
||||
str.put("/shared_owner/blend_eyesize_0", 117);
|
||||
str.put("/shared_owner/blend_eyesize_1", 0);
|
||||
str.put("/private/index_style_beard", 0);
|
||||
str.put("/private/index_style_freckles", 0);
|
||||
str.put("/private/index_age", 0);
|
||||
str.put("/private/index_color_skin", 0);
|
||||
str.put("/private/index_color_2", 1);
|
||||
str.put("/private/index_color_3", 0);
|
||||
str.put("/private/index_color_facial_hair", 1);
|
||||
str.put("/private/index_style_eyebrow", 0);
|
||||
return str;
|
||||
}
|
||||
|
||||
private static CustomizationString createHairCustomization() {
|
||||
CustomizationString str = new CustomizationString();
|
||||
str.put("/private/index_color_1", 1);
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
-194
@@ -1,194 +0,0 @@
|
||||
package com.projectswg.holocore.integration.resources;
|
||||
|
||||
import com.projectswg.common.data.CRC;
|
||||
import com.projectswg.common.data.location.Location;
|
||||
import com.projectswg.common.data.location.Terrain;
|
||||
import com.projectswg.common.network.NetBuffer;
|
||||
import com.projectswg.common.network.packets.PacketType;
|
||||
import com.projectswg.common.network.packets.SWGPacket;
|
||||
import com.projectswg.common.network.packets.swg.holo.HoloConnectionStopped.ConnectionStoppedReason;
|
||||
import com.projectswg.common.network.packets.swg.holo.login.HoloLoginRequestPacket;
|
||||
import com.projectswg.common.network.packets.swg.holo.login.HoloLoginResponsePacket;
|
||||
import com.projectswg.common.network.packets.swg.login.EnumerateCharacterId.SWGCharacter;
|
||||
import com.projectswg.common.network.packets.swg.zone.CmdSceneReady;
|
||||
import com.projectswg.common.network.packets.swg.zone.SceneCreateObjectByCrc;
|
||||
import com.projectswg.common.network.packets.swg.zone.SceneEndBaselines;
|
||||
import com.projectswg.common.network.packets.swg.zone.baselines.Baseline;
|
||||
import com.projectswg.common.network.packets.swg.zone.insertion.CmdStartScene;
|
||||
import com.projectswg.common.network.packets.swg.zone.insertion.SelectCharacter;
|
||||
import com.projectswg.holocore.client.HolocoreSocket;
|
||||
import com.projectswg.holocore.client.RawPacket;
|
||||
import com.projectswg.holocore.resources.support.objects.ObjectCreator;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import me.joshlarson.jlcommon.concurrency.BasicThread;
|
||||
import me.joshlarson.jlcommon.concurrency.Delay;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class HolocoreClient {
|
||||
|
||||
private final HolocoreSocket socket;
|
||||
private final BasicThread listenThread;
|
||||
private final AtomicReference<Location> location;
|
||||
private final AtomicReference<Terrain> terrain;
|
||||
private final Map<Long, SWGObject> objectsAware;
|
||||
private final Map<Long, SWGObject> objectsInProgress;
|
||||
private final Map<Long, String> characters;
|
||||
private final BlockingQueue<SWGPacket> packets;
|
||||
private final AtomicLong characterId;
|
||||
private final AtomicBoolean zonedIn;
|
||||
|
||||
public HolocoreClient() {
|
||||
this(new InetSocketAddress("localhost", 44463));
|
||||
}
|
||||
|
||||
public HolocoreClient(InetSocketAddress address) {
|
||||
this.socket = new HolocoreSocket(address.getAddress(), address.getPort());
|
||||
this.listenThread = new BasicThread("holocore-client-listen", this::listen);
|
||||
this.location = new AtomicReference<>(null);
|
||||
this.terrain = new AtomicReference<>(null);
|
||||
this.objectsAware = new ConcurrentHashMap<>();
|
||||
this.objectsInProgress = new ConcurrentHashMap<>();
|
||||
this.characters = new ConcurrentHashMap<>();
|
||||
this.packets = new LinkedBlockingQueue<>();
|
||||
this.characterId = new AtomicLong(0);
|
||||
this.zonedIn = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
public long getCharacterId() {
|
||||
return characterId.get();
|
||||
}
|
||||
|
||||
public String getCharacterName() {
|
||||
return characters.get(getCharacterId());
|
||||
}
|
||||
|
||||
public void addCharacter(long id, String name) {
|
||||
this.characters.put(id, name);
|
||||
}
|
||||
|
||||
public long getRandomCharacter() {
|
||||
return characters.keySet().iterator().next();
|
||||
}
|
||||
|
||||
public boolean login(String username, String password) {
|
||||
Assert.assertTrue(socket.connect(5000));
|
||||
listenThread.start();
|
||||
send(new HoloLoginRequestPacket(username, password));
|
||||
HoloLoginResponsePacket response = receiveNext(PacketType.HOLO_LOGIN_RESPONSE);
|
||||
return response.isSuccess();
|
||||
}
|
||||
|
||||
public void zoneIn(long characterId) {
|
||||
this.characterId.set(characterId);
|
||||
send(new SelectCharacter(characterId));
|
||||
}
|
||||
|
||||
public void waitForZoneIn() {
|
||||
long start = System.nanoTime();
|
||||
while ((!zonedIn.get() || !objectsAware.containsKey(getCharacterId())) && System.nanoTime() - start < 10E9) {
|
||||
Delay.sleepMilli(100);
|
||||
}
|
||||
Assert.assertTrue(zonedIn.get());
|
||||
Assert.assertTrue(objectsAware.containsKey(getCharacterId()));
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
listenThread.stop(false);
|
||||
socket.disconnect(ConnectionStoppedReason.APPLICATION);
|
||||
socket.close();
|
||||
listenThread.awaitTermination(1000);
|
||||
}
|
||||
|
||||
public void send(SWGPacket packet) {
|
||||
socket.send(packet.encode().array());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends SWGPacket> T receiveNext(PacketType type) {
|
||||
SWGPacket packet;
|
||||
while ((packet = receive()) != null) {
|
||||
if (packet.getPacketType() == type) {
|
||||
return (T) packet;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public SWGPacket receive() {
|
||||
try {
|
||||
return packets.poll(5, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void listen() {
|
||||
RawPacket received;
|
||||
while ((received = socket.receive()) != null) {
|
||||
SWGPacket packet = PacketType.getForCrc(received.getCrc());
|
||||
Assert.assertNotNull(packet);
|
||||
packet.decode(NetBuffer.wrap(received.getData()));
|
||||
process(packet);
|
||||
this.packets.add(packet);
|
||||
}
|
||||
}
|
||||
|
||||
private void process(SWGPacket packet) {
|
||||
switch (packet.getPacketType()) {
|
||||
case HOLO_LOGIN_RESPONSE:
|
||||
processLoginResponse((HoloLoginResponsePacket) packet);
|
||||
break;
|
||||
case CMD_START_SCENE:
|
||||
zonedIn.set(true);
|
||||
location.set(((CmdStartScene) packet).getLocation());
|
||||
terrain.set(((CmdStartScene) packet).getLocation().getTerrain());
|
||||
send(new CmdSceneReady());
|
||||
break;
|
||||
case SCENE_CREATE_OBJECT_BY_CRC:
|
||||
processSceneCreateObject((SceneCreateObjectByCrc) packet);
|
||||
break;
|
||||
case BASELINE:
|
||||
processBaseline((Baseline) packet);
|
||||
break;
|
||||
case SCENE_END_BASELINES:
|
||||
processEndBaselines((SceneEndBaselines) packet);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void processLoginResponse(HoloLoginResponsePacket login) {
|
||||
for (SWGCharacter character : login.getCharacters()) {
|
||||
characters.put(character.getId(), character.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private void processSceneCreateObject(SceneCreateObjectByCrc create) {
|
||||
SWGObject obj = ObjectCreator.createObjectFromTemplate(CRC.getString(create.getObjectCrc()));
|
||||
obj.setLocation(Location.builder(create.getLocation()).setTerrain(terrain.get()).build());
|
||||
objectsInProgress.put(create.getObjectId(), obj);
|
||||
}
|
||||
|
||||
private void processBaseline(Baseline base) {
|
||||
SWGObject obj = objectsInProgress.get(base.getObjectId());
|
||||
Objects.requireNonNull(obj);
|
||||
obj.parseBaseline(base);
|
||||
}
|
||||
|
||||
private void processEndBaselines(SceneEndBaselines end) {
|
||||
SWGObject obj = objectsInProgress.get(end.getObjectId());
|
||||
Objects.requireNonNull(obj);
|
||||
objectsAware.put(end.getObjectId(), obj);
|
||||
}
|
||||
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
package com.projectswg.holocore.integration.resources;
|
||||
|
||||
import com.projectswg.common.network.packets.swg.login.creation.DeleteCharacterRequest;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class MultipleClientRunner {
|
||||
|
||||
private final HolocoreClient [] clients;
|
||||
private final boolean deleteCharacters;
|
||||
|
||||
public MultipleClientRunner(int clientCount, boolean deleteCharacters) {
|
||||
this.clients = new HolocoreClient[clientCount];
|
||||
this.deleteCharacters = deleteCharacters;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void initializeClient() {
|
||||
for (int i = 0; i < clients.length; i++) {
|
||||
clients[i] = new HolocoreClient();
|
||||
Assert.assertTrue(clients[i].login("Obique", "pass"));
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void terminateClient() {
|
||||
for (HolocoreClient client : clients) {
|
||||
if (deleteCharacters)
|
||||
client.send(new DeleteCharacterRequest(0, client.getCharacterId()));
|
||||
client.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
protected HolocoreClient client(int index) {
|
||||
return clients[index];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.projectswg.holocore.integration.test;
|
||||
|
||||
import com.projectswg.holocore.ProjectSWGRunner;
|
||||
import com.projectswg.holocore.integration.test.login.TestLogin;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses(value = {
|
||||
TestLogin.class
|
||||
})
|
||||
public class TestIntegration {
|
||||
|
||||
private static final ProjectSWGRunner HOLOCORE = new ProjectSWGRunner();
|
||||
|
||||
@BeforeClass
|
||||
public static void startHolocore() {
|
||||
HOLOCORE.start();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopHolocore() {
|
||||
HOLOCORE.stop();
|
||||
}
|
||||
|
||||
}
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
package com.projectswg.holocore.integration.test.login;
|
||||
|
||||
import com.projectswg.common.network.packets.swg.login.creation.DeleteCharacterRequest;
|
||||
import com.projectswg.holocore.integration.resources.ClientRunner;
|
||||
import com.projectswg.holocore.integration.resources.ClientUtilities;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestCharacterCreation extends ClientRunner {
|
||||
|
||||
@Test
|
||||
public void testCreateCharacter() {
|
||||
try {
|
||||
ClientUtilities.createCharacter(client);
|
||||
client.waitForZoneIn();
|
||||
} finally {
|
||||
client.send(new DeleteCharacterRequest(0, client.getCharacterId()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
package com.projectswg.holocore.integration.test.login;
|
||||
|
||||
import com.projectswg.holocore.integration.resources.ClientRunner;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestExistingLogin extends ClientRunner {
|
||||
|
||||
@Test
|
||||
public void testLoginExisting() {
|
||||
client.zoneIn(client.getRandomCharacter());
|
||||
client.waitForZoneIn();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.projectswg.holocore.integration.test.login;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses(value = {
|
||||
TestCharacterCreation.class,
|
||||
TestExistingLogin.class
|
||||
})
|
||||
public class TestLogin {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user