You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-10-30 07:25:34 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			266 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			266 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* Copyright (C) 2014 InfiniDB, Inc.
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or
 | |
|    modify it under the terms of the GNU General Public License
 | |
|    as published by the Free Software Foundation; version 2 of
 | |
|    the License.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 | |
|    MA 02110-1301, USA. */
 | |
| 
 | |
| #include <sys/types.h>
 | |
| #include <sys/socket.h>
 | |
| #include <sys/un.h>
 | |
| #include <sys/stat.h>
 | |
| #include <fcntl.h>
 | |
| #include <boost/thread.hpp>
 | |
| #include <unistd.h>
 | |
| #include <list>
 | |
| #include <string>
 | |
| 
 | |
| #include "SMFileSystem.h"
 | |
| #include "SMDataFile.h"
 | |
| #include "SMFileFactory.h"
 | |
| #include "sm_exceptions.h"
 | |
| #include "messageFormat.h"
 | |
| 
 | |
| /* The purpose of this is to test the idbdatafile cloud classes using a dummy
 | |
| SessionManager defined in this file. */
 | |
| 
 | |
| #undef NDEBUG
 | |
| #include <assert.h>
 | |
| 
 | |
| using namespace idbdatafile;
 | |
| using namespace std;
 | |
| 
 | |
| volatile bool die = false;
 | |
| int errCode = 0;
 | |
| 
 | |
| /* Right now this will just accept one connection & send a fixed error response */
 | |
| void error_server_thread()
 | |
| {
 | |
|   struct sockaddr_un addr;
 | |
|   memset(&addr, 0, sizeof(addr));
 | |
|   addr.sun_family = AF_UNIX;
 | |
|   strcpy(&addr.sun_path[1], &storagemanager::socket_name[1]);
 | |
| 
 | |
|   int server_socket = ::socket(AF_UNIX, SOCK_STREAM, 0);
 | |
|   assert(server_socket >= 0);
 | |
| 
 | |
|   int err = ::bind(server_socket, (struct sockaddr*)&addr, sizeof(addr));
 | |
|   assert(err == 0);
 | |
| 
 | |
|   err = ::listen(server_socket, 1);
 | |
|   assert(err == 0);
 | |
| 
 | |
|   socklen_t addrlen;
 | |
|   struct sockaddr_un client_addr;
 | |
|   memset(&client_addr, 0, sizeof(client_addr));
 | |
|   int client_socket = ::accept(server_socket, (struct sockaddr*)&client_addr, &addrlen);
 | |
|   assert(client_socket >= 0);
 | |
| 
 | |
|   // cout << "server thread got a connection" << endl;
 | |
| 
 | |
|   uint8_t buf[4096];
 | |
|   uint32_t response[4] = {storagemanager::SM_MSG_START, 8, (uint32_t)-1, EINVAL};
 | |
|   uint remainingBytes = 0;
 | |
| 
 | |
|   while (!die)
 | |
|   {
 | |
|     /* This just scans for SM_MSG_START, and as it finds them it sends a generic error
 | |
|        response. */
 | |
| 
 | |
|     err = ::recv(client_socket, &buf[remainingBytes], 4096 - remainingBytes, MSG_DONTWAIT);
 | |
|     if (err < 0)
 | |
|     {
 | |
|       if (errno == EAGAIN || errno == EWOULDBLOCK)
 | |
|       {
 | |
|         // cout << "server looping..." << endl;
 | |
|         sleep(1);  // who cares
 | |
|         continue;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         // char errbuf[80];
 | |
|         // cout << "server thread got an error: " << strerror_r(errno, errbuf, 80) << endl;
 | |
|         close(client_socket);
 | |
|         errCode = -1;
 | |
|         die = true;
 | |
|         return;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // cout << "server thread got some data" << endl;
 | |
|     uint endOfData = remainingBytes + err;
 | |
|     uint i;
 | |
|     if (endOfData < 4)
 | |
|     {
 | |
|       remainingBytes = endOfData;
 | |
|       continue;
 | |
|     }
 | |
|     for (i = 0; i <= endOfData - 4; i++)
 | |
|     {
 | |
|       if (*((uint32_t*)&buf[i]) == storagemanager::SM_MSG_START)
 | |
|       {
 | |
|         // cout << "server thread found a msg start magic" << endl;
 | |
|         err = ::send(client_socket, response, 16, 0);
 | |
|         assert(err > 0);
 | |
|       }
 | |
|     }
 | |
|     memmove(buf, &buf[i], endOfData - i);  // should be the trailing 3 bytes of the data
 | |
|     remainingBytes = endOfData - i;
 | |
|   }
 | |
| }
 | |
| 
 | |
| int test1()
 | |
| {
 | |
|   /* Start a server thread that returns generic errors */
 | |
|   boost::thread server_thread(error_server_thread);
 | |
| 
 | |
|   /* Instantiate each of SM subclasses, call each function, and verify the expected error response */
 | |
|   int err;
 | |
|   SMFileFactory factory;
 | |
| 
 | |
|   cout << "open" << endl;
 | |
|   IDBDataFile* file = factory.open("dummy", "r", 0, 0);
 | |
|   assert(file == NULL && errno == EINVAL && !die);
 | |
| 
 | |
|   SMFileSystem filesystem;
 | |
| 
 | |
|   cout << "compressedSize" << endl;
 | |
|   bool gotException = false;
 | |
|   try
 | |
|   {
 | |
|     filesystem.compressedSize("dummy");
 | |
|   }
 | |
|   catch (NotImplementedYet&)
 | |
|   {
 | |
|     gotException = true;
 | |
|   }
 | |
|   assert(gotException && !die);
 | |
| 
 | |
|   cout << "copyFile" << endl;
 | |
|   try
 | |
|   {
 | |
|     filesystem.copyFile("dummy1", "dummy2");
 | |
|   }
 | |
|   catch (NotImplementedYet&)
 | |
|   {
 | |
|     gotException = true;
 | |
|   }
 | |
|   assert(gotException && !die);
 | |
| 
 | |
|   cout << "rename" << endl;
 | |
|   try
 | |
|   {
 | |
|     filesystem.rename("dummy1", "dummy2");
 | |
|   }
 | |
|   catch (NotImplementedYet&)
 | |
|   {
 | |
|     gotException = true;
 | |
|   }
 | |
|   assert(gotException && !die);
 | |
| 
 | |
|   cout << "exists" << endl;
 | |
|   err = filesystem.exists("dummy");
 | |
|   assert(!err && errno == EINVAL);
 | |
| 
 | |
|   cout << "filesystemisup" << endl;
 | |
|   err = filesystem.filesystemIsUp();
 | |
|   assert(!err && errno == EINVAL && !die);
 | |
| 
 | |
|   cout << "isdir" << endl;
 | |
|   err = filesystem.isDir("dummy");
 | |
|   assert(!err && errno == EINVAL && !die);
 | |
| 
 | |
|   cout << "listdirectory" << endl;
 | |
|   list<string> filenames;
 | |
|   err = filesystem.listDirectory("dummy", filenames);
 | |
|   assert(err == -1 && errno == EINVAL && filenames.empty() && !die);
 | |
| 
 | |
|   cout << "remove" << endl;
 | |
|   err = filesystem.remove("dummy");
 | |
|   assert(err == -1 && errno == EINVAL && !die);
 | |
| 
 | |
|   cout << "size" << endl;
 | |
|   err = filesystem.size("dummy");
 | |
|   assert(err == -1 && errno == EINVAL && !die);
 | |
| 
 | |
|   cout << "mkdir" << endl;
 | |
|   err = filesystem.mkdir("dummy");
 | |
|   assert(err == 0 && !die);
 | |
| 
 | |
|   cout << "datafile constructor" << endl;
 | |
|   SMDataFile f("dummy", O_RDONLY, 12345);
 | |
|   f = SMDataFile("dummy2", O_WRONLY, 123456);
 | |
|   f = SMDataFile("dummy2", O_RDWR | O_APPEND, 1234567);
 | |
| 
 | |
|   cout << "pread" << endl;
 | |
|   uint8_t buf[1024];
 | |
|   err = f.pread(buf, 0, 1024);
 | |
|   assert(err == -1 && errno == EINVAL && !die);
 | |
| 
 | |
|   cout << "read" << endl;
 | |
|   err = f.read(buf, 1024);
 | |
|   assert(err == -1 && errno == EINVAL && !die);
 | |
| 
 | |
|   cout << "write" << endl;
 | |
|   err = f.write(buf, 1024);
 | |
|   assert(err == -1 && errno == EINVAL && !die);
 | |
| 
 | |
|   cout << "seek" << endl;
 | |
|   err = f.seek(1234, SEEK_SET);
 | |
|   assert(err == 0 && !die);
 | |
| 
 | |
|   err = f.seek(1234, SEEK_CUR);
 | |
|   assert(err == 0 && !die);
 | |
| 
 | |
|   err = f.seek(1234, SEEK_END);
 | |
|   assert(err == -1 && errno == EINVAL && !die);
 | |
| 
 | |
|   cout << "truncate" << endl;
 | |
|   err = f.truncate(1234);
 | |
|   assert(err == -1 && errno == EINVAL && !die);
 | |
| 
 | |
|   cout << "size" << endl;
 | |
|   err = f.size();
 | |
|   assert(err == -1 && errno == EINVAL && !die);
 | |
| 
 | |
|   cout << "tell" << endl;
 | |
|   err = f.tell();
 | |
|   assert(err == 2468);
 | |
| 
 | |
|   cout << "flush" << endl;
 | |
|   err = f.flush();
 | |
|   assert(err == 0);
 | |
| 
 | |
|   cout << "mtime" << endl;
 | |
|   err = f.mtime();
 | |
|   assert(err == -1 && errno == EINVAL && !die);
 | |
| 
 | |
|   cout << "close" << endl;
 | |
|   err = f.close();
 | |
|   assert(err == 0);
 | |
| 
 | |
|   // done, return errCode
 | |
|   die = true;
 | |
|   cout << "done, waiting for server thread to stop" << endl;
 | |
|   server_thread.join();
 | |
|   return errCode;
 | |
| }
 | |
| 
 | |
| int main()
 | |
| {
 | |
|   int ret;
 | |
| 
 | |
|   ret = test1();
 | |
|   return ret;
 | |
| }
 |