From 4e249fb3fbf75f0359758760d88e22aa5b14533c Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 27 Nov 2010 01:02:21 +0200 Subject: Initial files --- src/test.cpp | 920 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 920 insertions(+) create mode 100644 src/test.cpp (limited to 'src/test.cpp') diff --git a/src/test.cpp b/src/test.cpp new file mode 100644 index 000000000..8cdd84426 --- /dev/null +++ b/src/test.cpp @@ -0,0 +1,920 @@ +#include "test.h" +#include "common_irrlicht.h" + +#include "debug.h" +#include "map.h" +#include "player.h" +#include "main.h" +#include "heightmap.h" +#include "socket.h" +#include "connection.h" +#include "utility.h" +#include "serialization.h" +#include + +#ifdef _WIN32 + #include + #define sleep_ms(x) Sleep(x) +#else + #include + #define sleep_ms(x) usleep(x*1000) +#endif + +/* + Asserts that the exception occurs +*/ +#define EXCEPTION_CHECK(EType, code)\ +{\ + bool exception_thrown = false;\ + try{ code; }\ + catch(EType &e) { exception_thrown = true; }\ + assert(exception_thrown);\ +} + +struct TestUtilities +{ + void Run() + { + /*dstream<<"wrapDegrees(100.0) = "< fromdata(4); + fromdata[0]=1; + fromdata[1]=5; + fromdata[2]=5; + fromdata[3]=1; + + std::ostringstream os(std::ios_base::binary); + compress(fromdata, os, 0); + + std::string str_out = os.str(); + + dstream<<"str_out.size()="< "; + for(u32 i=0; i validity_exceptions; + + TC() + { + position_valid = true; + } + + virtual bool isValidPosition(v3s16 p) + { + //return position_valid ^ (p==position_valid_exception); + bool exception = false; + for(core::list::Iterator i=validity_exceptions.begin(); + i != validity_exceptions.end(); i++) + { + if(p == *i) + { + exception = true; + break; + } + } + return exception ? !position_valid : position_valid; + } + + virtual MapNode getNode(v3s16 p) + { + if(isValidPosition(p) == false) + throw InvalidPositionException(); + return node; + } + + virtual void setNode(v3s16 p, MapNode & n) + { + if(isValidPosition(p) == false) + throw InvalidPositionException(); + }; + + virtual u16 nodeContainerId() const + { + return 666; + } + }; + + void Run() + { + TC parent; + + MapBlock b(&parent, v3s16(1,1,1)); + v3s16 relpos(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE); + + assert(b.getPosRelative() == relpos); + + assert(b.getBox().MinEdge.X == MAP_BLOCKSIZE); + assert(b.getBox().MaxEdge.X == MAP_BLOCKSIZE*2-1); + assert(b.getBox().MinEdge.Y == MAP_BLOCKSIZE); + assert(b.getBox().MaxEdge.Y == MAP_BLOCKSIZE*2-1); + assert(b.getBox().MinEdge.Z == MAP_BLOCKSIZE); + assert(b.getBox().MaxEdge.Z == MAP_BLOCKSIZE*2-1); + + assert(b.isValidPosition(v3s16(0,0,0)) == true); + assert(b.isValidPosition(v3s16(-1,0,0)) == false); + assert(b.isValidPosition(v3s16(-1,-142,-2341)) == false); + assert(b.isValidPosition(v3s16(-124,142,2341)) == false); + assert(b.isValidPosition(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1)) == true); + assert(b.isValidPosition(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE,MAP_BLOCKSIZE-1)) == false); + + /* + TODO: this method should probably be removed + if the block size isn't going to be set variable + */ + /*assert(b.getSizeNodes() == v3s16(MAP_BLOCKSIZE, + MAP_BLOCKSIZE, MAP_BLOCKSIZE));*/ + + // Changed flag should be initially set + assert(b.getChangedFlag() == true); + b.resetChangedFlag(); + assert(b.getChangedFlag() == false); + + // All nodes should have been set to + // .d=MATERIAL_AIR and .getLight() = 0 + for(u16 z=0; z light_sources; + // The bottom block is invalid, because we have a shadowing node + assert(b.propagateSunlight(light_sources) == false); + assert(b.getNode(v3s16(1,4,0)).getLight() == LIGHT_SUN); + assert(b.getNode(v3s16(1,3,0)).getLight() == LIGHT_SUN); + assert(b.getNode(v3s16(1,2,0)).getLight() == 0); + assert(b.getNode(v3s16(1,1,0)).getLight() == 0); + assert(b.getNode(v3s16(1,0,0)).getLight() == 0); + assert(b.getNode(v3s16(1,2,3)).getLight() == LIGHT_SUN); + assert(b.getFaceLight(p, v3s16(0,1,0)) == LIGHT_SUN); + assert(b.getFaceLight(p, v3s16(0,-1,0)) == 0); + // According to MapBlock::getFaceLight, + // The face on the z+ side should have double-diminished light + assert(b.getFaceLight(p, v3s16(0,0,1)) == diminish_light(diminish_light(LIGHT_MAX))); + } + /* + Check how the block handles being in between blocks with some non-sunlight + while being underground + */ + { + // Make neighbours to exist and set some non-sunlight to them + parent.position_valid = true; + b.setIsUnderground(true); + parent.node.setLight(LIGHT_MAX/2); + core::map light_sources; + // The block below should be valid because there shouldn't be + // sunlight in there either + assert(b.propagateSunlight(light_sources) == true); + // Should not touch nodes that are not affected (that is, all of them) + //assert(b.getNode(v3s16(1,2,3)).getLight() == LIGHT_SUN); + // Should set light of non-sunlighted blocks to 0. + assert(b.getNode(v3s16(1,2,3)).getLight() == 0); + } + /* + Set up a situation where: + - There is only air in this block + - There is a valid non-sunlighted block at the bottom, and + - Invalid blocks elsewhere. + - the block is not underground. + + This should result in bottom block invalidity + */ + { + b.setIsUnderground(false); + // Clear block + for(u16 z=0; z light_sources; + // Bottom block is not valid + assert(b.propagateSunlight(light_sources) == false); + } + } +}; + +struct TestMapSector +{ + class TC : public NodeContainer + { + public: + + MapNode node; + bool position_valid; + + TC() + { + position_valid = true; + } + + virtual bool isValidPosition(v3s16 p) + { + return position_valid; + } + + virtual MapNode getNode(v3s16 p) + { + if(position_valid == false) + throw InvalidPositionException(); + return node; + } + + virtual void setNode(v3s16 p, MapNode & n) + { + if(position_valid == false) + throw InvalidPositionException(); + }; + + virtual u16 nodeContainerId() const + { + return 666; + } + }; + + void Run() + { + TC parent; + parent.position_valid = false; + + // Create one with no heightmaps + ServerMapSector sector(&parent, v2s16(1,1), 0); + //ConstantGenerator *dummyheightmap = new ConstantGenerator(); + //sector->setHeightmap(dummyheightmap); + + EXCEPTION_CHECK(InvalidPositionException, sector.getBlockNoCreate(0)); + EXCEPTION_CHECK(InvalidPositionException, sector.getBlockNoCreate(1)); + + MapBlock * bref = sector.createBlankBlock(-2); + + EXCEPTION_CHECK(InvalidPositionException, sector.getBlockNoCreate(0)); + assert(sector.getBlockNoCreate(-2) == bref); + + //TODO: Check for AlreadyExistsException + + /*bool exception_thrown = false; + try{ + sector.getBlock(0); + } + catch(InvalidPositionException &e){ + exception_thrown = true; + } + assert(exception_thrown);*/ + + } +}; + +struct TestHeightmap +{ + void TestSingleFixed() + { + const s16 BS1 = 4; + OneChildHeightmap hm1(BS1); + + // Test that it is filled with < GROUNDHEIGHT_VALID_MINVALUE + for(s16 y=0; y<=BS1; y++){ + for(s16 x=0; x<=BS1; x++){ + v2s16 p(x,y); + assert(hm1.m_child.getGroundHeight(p) + < GROUNDHEIGHT_VALID_MINVALUE); + } + } + + hm1.m_child.setGroundHeight(v2s16(1,0), 2.0); + //hm1.m_child.print(); + assert(fabs(hm1.getGroundHeight(v2s16(1,0))-2.0)<0.001); + hm1.setGroundHeight(v2s16(0,1), 3.0); + assert(fabs(hm1.m_child.getGroundHeight(v2s16(0,1))-3.0)<0.001); + + // Fill with -1.0 + for(s16 y=0; y<=BS1; y++){ + for(s16 x=0; x<=BS1; x++){ + v2s16 p(x,y); + hm1.m_child.setGroundHeight(p, -1.0); + } + } + + f32 corners[] = {0.0, 0.0, 1.0, 1.0}; + hm1.m_child.generateContinued(0.0, 0.0, corners); + + hm1.m_child.print(); + assert(fabs(hm1.m_child.getGroundHeight(v2s16(1,0))-0.2)<0.05); + assert(fabs(hm1.m_child.getGroundHeight(v2s16(4,3))-0.7)<0.05); + assert(fabs(hm1.m_child.getGroundHeight(v2s16(4,4))-1.0)<0.05); + } + + void TestUnlimited() + { + //g_heightmap_debugprint = true; + const s16 BS1 = 4; + UnlimitedHeightmap hm1(BS1, + new ConstantGenerator(0.0), + new ConstantGenerator(0.0), + new ConstantGenerator(5.0)); + // Go through it so it generates itself + for(s16 y=0; y<=BS1; y++){ + for(s16 x=0; x<=BS1; x++){ + v2s16 p(x,y); + hm1.getGroundHeight(p); + } + } + // Print it + dstream<<"UnlimitedHeightmap hm1:"<setGroundHeight(p1, v1); + // Read from UnlimitedHeightmap + assert(fabs(hm1.getGroundHeight(p1)-v1)<0.001); + } + + void Random() + { + dstream<<"Running random code (get a human to check this)"<generateContinued(0.0, 0.0, corners); + hm1.print();*/ + + //assert(0); + } + + void Run() + { + //srand(7); // Get constant random + srand(time(0)); // Get better random + + TestSingleFixed(); + TestUnlimited(); + Random(); + } +}; + +struct TestSocket +{ + void Run() + { + const int port = 30003; + UDPSocket socket; + socket.Bind(port); + + const char sendbuffer[] = "hello world!"; + socket.Send(Address(127,0,0,1,port), sendbuffer, sizeof(sendbuffer)); + + sleep_ms(50); + + char rcvbuffer[256]; + memset(rcvbuffer, 0, sizeof(rcvbuffer)); + Address sender; + for(;;) + { + int bytes_read = socket.Receive(sender, rcvbuffer, sizeof(rcvbuffer)); + if(bytes_read < 0) + break; + } + //FIXME: This fails on some systems + assert(strncmp(sendbuffer, rcvbuffer, sizeof(sendbuffer))==0); + assert(sender.getAddress() == Address(127,0,0,1, 0).getAddress()); + } +}; + +struct TestConnection +{ + void TestHelpers() + { + /* + Test helper functions + */ + + // Some constants for testing + u32 proto_id = 0x12345678; + u16 peer_id = 123; + u8 channel = 2; + SharedBuffer data1(1); + data1[0] = 100; + Address a(127,0,0,1, 10); + u16 seqnum = 34352; + + con::BufferedPacket p1 = con::makePacket(a, data1, + proto_id, peer_id, channel); + /* + We should now have a packet with this data: + Header: + [0] u32 protocol_id + [4] u16 sender_peer_id + [6] u8 channel + Data: + [7] u8 data1[0] + */ + assert(readU32(&p1.data[0]) == proto_id); + assert(readU16(&p1.data[4]) == peer_id); + assert(readU8(&p1.data[6]) == channel); + assert(readU8(&p1.data[7]) == data1[0]); + + //dstream<<"initial data1[0]="<<((u32)data1[0]&0xff)< p2 = con::makeReliablePacket(data1, seqnum); + + /*dstream<<"p2.getSize()="< data = SharedBufferFromString("Hello World!"); + + dstream<<"** running client.Send()"< data1 = SharedBufferFromString("hello1"); + SharedBuffer data2 = SharedBufferFromString("Hello2"); + + Address client_address = + server.GetPeer(peer_id_client)->address; + + dstream<<"*** Sending packets in wrong order (2,1,2)" + <channels[chn]; + u16 sn = ch->next_outgoing_seqnum; + ch->next_outgoing_seqnum = sn+1; + server.Send(peer_id_client, chn, data2, true); + ch->next_outgoing_seqnum = sn; + server.Send(peer_id_client, chn, data1, true); + ch->next_outgoing_seqnum = sn+1; + server.Send(peer_id_client, chn, data2, true); + + sleep_ms(50); + + dstream<<"*** Receiving the packets"< data1(1100); + for(u16 i=0; i<1100; i++){ + data1[i] = i/4; + } + + dstream<<"Sending data (size="<<1100<<"):"; + for(int i=0; i<1100 && i<20; i++){ + if(i%2==0) printf(" "); + printf("%.2X", ((int)((const char*)*data1)[i])&0xff); + } + if(1100>20) + dstream<<"..."; + dstream<20) + dstream<<"..."; + dstream<