Home | History | Annotate | Download | only in test
      1 /*
      2  ** Copyright 2011, The Android Open Source Project
      3  **
      4  ** Licensed under the Apache License, Version 2.0 (the "License");
      5  ** you may not use this file except in compliance with the License.
      6  ** You may obtain a copy of the License at
      7  **
      8  **     http://www.apache.org/licenses/LICENSE-2.0
      9  **
     10  ** Unless required by applicable law or agreed to in writing, software
     11  ** distributed under the License is distributed on an "AS IS" BASIS,
     12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  ** See the License for the specific language governing permissions and
     14  ** limitations under the License.
     15  */
     16 
     17 #include <sys/socket.h>
     18 #include <sys/ioctl.h>
     19 
     20 #include "header.h"
     21 #include "gtest/gtest.h"
     22 #include "hooks.h"
     23 
     24 namespace android
     25 {
     26 extern int serverSock, clientSock;
     27 };
     28 
     29 void * glNoop();
     30 
     31 class SocketContextTest : public ::testing::Test
     32 {
     33 protected:
     34     DbgContext* dbg;
     35     gl_hooks_t hooks;
     36     int sock;
     37     char * buffer;
     38     unsigned int bufferSize;
     39 
     40     SocketContextTest() : sock(-1) {
     41     }
     42 
     43     virtual ~SocketContextTest() {
     44     }
     45 
     46     virtual void SetUp() {
     47         dbg = new DbgContext(1, &hooks, 32);
     48         ASSERT_TRUE(dbg != NULL);
     49         for (unsigned int i = 0; i < sizeof(hooks) / sizeof(void *); i++)
     50             ((void **)&hooks)[i] = (void *)glNoop;
     51 
     52         int socks[2] = {-1, -1};
     53         ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, socks));
     54         clientSock = socks[0];
     55         sock = socks[1];
     56 
     57         bufferSize = 128;
     58         buffer = new char [128];
     59         ASSERT_NE((char *)NULL, buffer);
     60     }
     61 
     62     virtual void TearDown() {
     63         close(sock);
     64         close(clientSock);
     65         clientSock = -1;
     66         delete buffer;
     67     }
     68 
     69     void Write(glesv2debugger::Message & msg) const {
     70         msg.set_context_id((int)dbg);
     71         msg.set_type(msg.Response);
     72         ASSERT_TRUE(msg.has_context_id());
     73         ASSERT_TRUE(msg.has_function());
     74         ASSERT_TRUE(msg.has_type());
     75         ASSERT_TRUE(msg.has_expect_response());
     76         static std::string str;
     77         msg.SerializeToString(&str);
     78         const uint32_t len = str.length();
     79         ASSERT_EQ(sizeof(len), send(sock, &len, sizeof(len), 0));
     80         ASSERT_EQ(str.length(), send(sock, str.data(), str.length(), 0));
     81     }
     82 
     83     void Read(glesv2debugger::Message & msg) {
     84         int available = 0;
     85         ASSERT_EQ(0, ioctl(sock, FIONREAD, &available));
     86         ASSERT_GT(available, 0);
     87         uint32_t len = 0;
     88         ASSERT_EQ(sizeof(len), recv(sock, &len, sizeof(len), 0));
     89         if (len > bufferSize) {
     90             bufferSize = len;
     91             buffer = new char[bufferSize];
     92             ASSERT_TRUE(buffer != NULL);
     93         }
     94         ASSERT_EQ(len, recv(sock, buffer, len, 0));
     95         msg.Clear();
     96         msg.ParseFromArray(buffer, len);
     97         ASSERT_TRUE(msg.has_context_id());
     98         ASSERT_TRUE(msg.has_function());
     99         ASSERT_TRUE(msg.has_type());
    100         ASSERT_TRUE(msg.has_expect_response());
    101     }
    102 
    103     void CheckNoAvailable() {
    104         int available = 0;
    105         ASSERT_EQ(0, ioctl(sock, FIONREAD, &available));
    106         ASSERT_EQ(available, 0);
    107     }
    108 };
    109 
    110 TEST_F(SocketContextTest, MessageLoopSkip)
    111 {
    112     static const int arg0 = 45;
    113     static const float arg7 = -87.2331f;
    114     static const int arg8 = -3;
    115     static const int * ret = (int *)870;
    116 
    117     struct Caller : public FunctionCall {
    118         const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
    119             msg.set_arg0(arg0);
    120             msg.set_arg7((int &)arg7);
    121             msg.set_arg8(arg8);
    122             return ret;
    123         }
    124     } caller;
    125     glesv2debugger::Message msg, read, cmd;
    126     dbg->expectResponse.Bit(msg.glFinish, true);
    127 
    128     cmd.set_function(cmd.SKIP);
    129     cmd.set_expect_response(false);
    130     Write(cmd);
    131 
    132     EXPECT_NE(ret, MessageLoop(caller, msg, msg.glFinish));
    133 
    134     Read(read);
    135     EXPECT_EQ(read.glFinish, read.function());
    136     EXPECT_EQ(read.BeforeCall, read.type());
    137     EXPECT_NE(arg0, read.arg0());
    138     EXPECT_NE((int &)arg7, read.arg7());
    139     EXPECT_NE(arg8, read.arg8());
    140 
    141     CheckNoAvailable();
    142 }
    143 
    144 TEST_F(SocketContextTest, MessageLoopContinue)
    145 {
    146     static const int arg0 = GL_FRAGMENT_SHADER;
    147     static const int ret = -342;
    148     struct Caller : public FunctionCall {
    149         const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
    150             msg.set_ret(ret);
    151             return (int *)ret;
    152         }
    153     } caller;
    154     glesv2debugger::Message msg, read, cmd;
    155     dbg->expectResponse.Bit(msg.glCreateShader, true);
    156 
    157     cmd.set_function(cmd.CONTINUE);
    158     cmd.set_expect_response(false); // MessageLoop should automatically skip after continue
    159     Write(cmd);
    160 
    161     msg.set_arg0(arg0);
    162     EXPECT_EQ((int *)ret, MessageLoop(caller, msg, msg.glCreateShader));
    163 
    164     Read(read);
    165     EXPECT_EQ(read.glCreateShader, read.function());
    166     EXPECT_EQ(read.BeforeCall, read.type());
    167     EXPECT_EQ(arg0, read.arg0());
    168 
    169     Read(read);
    170     EXPECT_EQ(read.glCreateShader, read.function());
    171     EXPECT_EQ(read.AfterCall, read.type());
    172     EXPECT_EQ(ret, read.ret());
    173 
    174     CheckNoAvailable();
    175 }
    176 
    177 TEST_F(SocketContextTest, MessageLoopGenerateCall)
    178 {
    179     static const int ret = -342;
    180     static unsigned int createShader, createProgram;
    181     createShader = 0;
    182     createProgram = 0;
    183     struct Caller : public FunctionCall {
    184         const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
    185             const int r = (int)_c->glCreateProgram();
    186             msg.set_ret(r);
    187             return (int *)r;
    188         }
    189         static GLuint CreateShader(const GLenum type) {
    190             createShader++;
    191             return type;
    192         }
    193         static GLuint CreateProgram() {
    194             createProgram++;
    195             return ret;
    196         }
    197     } caller;
    198     glesv2debugger::Message msg, read, cmd;
    199     hooks.gl.glCreateShader = caller.CreateShader;
    200     hooks.gl.glCreateProgram = caller.CreateProgram;
    201     dbg->expectResponse.Bit(msg.glCreateProgram, true);
    202 
    203     cmd.set_function(cmd.glCreateShader);
    204     cmd.set_arg0(GL_FRAGMENT_SHADER);
    205     cmd.set_expect_response(true);
    206     Write(cmd);
    207 
    208     cmd.Clear();
    209     cmd.set_function(cmd.CONTINUE);
    210     cmd.set_expect_response(true);
    211     Write(cmd);
    212 
    213     cmd.set_function(cmd.glCreateShader);
    214     cmd.set_arg0(GL_VERTEX_SHADER);
    215     cmd.set_expect_response(false); // MessageLoop should automatically skip afterwards
    216     Write(cmd);
    217 
    218     EXPECT_EQ((int *)ret, MessageLoop(caller, msg, msg.glCreateProgram));
    219 
    220     Read(read);
    221     EXPECT_EQ(read.glCreateProgram, read.function());
    222     EXPECT_EQ(read.BeforeCall, read.type());
    223 
    224     Read(read);
    225     EXPECT_EQ(read.glCreateShader, read.function());
    226     EXPECT_EQ(read.AfterGeneratedCall, read.type());
    227     EXPECT_EQ(GL_FRAGMENT_SHADER, read.ret());
    228 
    229     Read(read);
    230     EXPECT_EQ(read.glCreateProgram, read.function());
    231     EXPECT_EQ(read.AfterCall, read.type());
    232     EXPECT_EQ(ret, read.ret());
    233 
    234     Read(read);
    235     EXPECT_EQ(read.glCreateShader, read.function());
    236     EXPECT_EQ(read.AfterGeneratedCall, read.type());
    237     EXPECT_EQ(GL_VERTEX_SHADER, read.ret());
    238 
    239     EXPECT_EQ(2, createShader);
    240     EXPECT_EQ(1, createProgram);
    241 
    242     CheckNoAvailable();
    243 }
    244 
    245 TEST_F(SocketContextTest, MessageLoopSetProp)
    246 {
    247     static const int ret = -342;
    248     static unsigned int createShader, createProgram;
    249     createShader = 0;
    250     createProgram = 0;
    251     struct Caller : public FunctionCall {
    252         const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
    253             const int r = (int)_c->glCreateProgram();
    254             msg.set_ret(r);
    255             return (int *)r;
    256         }
    257         static GLuint CreateShader(const GLenum type) {
    258             createShader++;
    259             return type;
    260         }
    261         static GLuint CreateProgram() {
    262             createProgram++;
    263             return ret;
    264         }
    265     } caller;
    266     glesv2debugger::Message msg, read, cmd;
    267     hooks.gl.glCreateShader = caller.CreateShader;
    268     hooks.gl.glCreateProgram = caller.CreateProgram;
    269     dbg->expectResponse.Bit(msg.glCreateProgram, false);
    270 
    271     cmd.set_function(cmd.SETPROP);
    272     cmd.set_prop(cmd.ExpectResponse);
    273     cmd.set_arg0(cmd.glCreateProgram);
    274     cmd.set_arg1(true);
    275     cmd.set_expect_response(true);
    276     Write(cmd);
    277 
    278     cmd.Clear();
    279     cmd.set_function(cmd.glCreateShader);
    280     cmd.set_arg0(GL_FRAGMENT_SHADER);
    281     cmd.set_expect_response(true);
    282     Write(cmd);
    283 
    284     cmd.set_function(cmd.SETPROP);
    285     cmd.set_prop(cmd.CaptureDraw);
    286     cmd.set_arg0(819);
    287     cmd.set_expect_response(true);
    288     Write(cmd);
    289 
    290     cmd.Clear();
    291     cmd.set_function(cmd.CONTINUE);
    292     cmd.set_expect_response(true);
    293     Write(cmd);
    294 
    295     cmd.set_function(cmd.glCreateShader);
    296     cmd.set_arg0(GL_VERTEX_SHADER);
    297     cmd.set_expect_response(false); // MessageLoop should automatically skip afterwards
    298     Write(cmd);
    299 
    300     EXPECT_EQ((int *)ret, MessageLoop(caller, msg, msg.glCreateProgram));
    301 
    302     EXPECT_TRUE(dbg->expectResponse.Bit(msg.glCreateProgram));
    303     EXPECT_EQ(819, dbg->captureDraw);
    304 
    305     Read(read);
    306     EXPECT_EQ(read.glCreateProgram, read.function());
    307     EXPECT_EQ(read.BeforeCall, read.type());
    308 
    309     Read(read);
    310     EXPECT_EQ(read.glCreateShader, read.function());
    311     EXPECT_EQ(read.AfterGeneratedCall, read.type());
    312     EXPECT_EQ(GL_FRAGMENT_SHADER, read.ret());
    313 
    314     Read(read);
    315     EXPECT_EQ(read.glCreateProgram, read.function());
    316     EXPECT_EQ(read.AfterCall, read.type());
    317     EXPECT_EQ(ret, read.ret());
    318 
    319     Read(read);
    320     EXPECT_EQ(read.glCreateShader, read.function());
    321     EXPECT_EQ(read.AfterGeneratedCall, read.type());
    322     EXPECT_EQ(GL_VERTEX_SHADER, read.ret());
    323 
    324     EXPECT_EQ(2, createShader);
    325     EXPECT_EQ(1, createProgram);
    326 
    327     CheckNoAvailable();
    328 }
    329 
    330 TEST_F(SocketContextTest, TexImage2D)
    331 {
    332     static const GLenum _target = GL_TEXTURE_2D;
    333     static const GLint _level = 1, _internalformat = GL_RGBA;
    334     static const GLsizei _width = 2, _height = 2;
    335     static const GLint _border = 333;
    336     static const GLenum _format = GL_RGB, _type = GL_UNSIGNED_SHORT_5_6_5;
    337     static const short _pixels [_width * _height] = {11, 22, 33, 44};
    338     static unsigned int texImage2D;
    339     texImage2D = 0;
    340 
    341     struct Caller {
    342         static void TexImage2D(GLenum target, GLint level, GLint internalformat,
    343                                GLsizei width, GLsizei height, GLint border,
    344                                GLenum format, GLenum type, const GLvoid* pixels) {
    345             EXPECT_EQ(_target, target);
    346             EXPECT_EQ(_level, level);
    347             EXPECT_EQ(_internalformat, internalformat);
    348             EXPECT_EQ(_width, width);
    349             EXPECT_EQ(_height, height);
    350             EXPECT_EQ(_border, border);
    351             EXPECT_EQ(_format, format);
    352             EXPECT_EQ(_type, type);
    353             EXPECT_EQ(0, memcmp(_pixels, pixels, sizeof(_pixels)));
    354             texImage2D++;
    355         }
    356     } caller;
    357     glesv2debugger::Message msg, read, cmd;
    358     hooks.gl.glTexImage2D = caller.TexImage2D;
    359     dbg->expectResponse.Bit(msg.glTexImage2D, false);
    360 
    361     Debug_glTexImage2D(_target, _level, _internalformat, _width, _height, _border,
    362                        _format, _type, _pixels);
    363     EXPECT_EQ(1, texImage2D);
    364 
    365     Read(read);
    366     EXPECT_EQ(read.glTexImage2D, read.function());
    367     EXPECT_EQ(read.BeforeCall, read.type());
    368     EXPECT_EQ(_target, read.arg0());
    369     EXPECT_EQ(_level, read.arg1());
    370     EXPECT_EQ(_internalformat, read.arg2());
    371     EXPECT_EQ(_width, read.arg3());
    372     EXPECT_EQ(_height, read.arg4());
    373     EXPECT_EQ(_border, read.arg5());
    374     EXPECT_EQ(_format, read.arg6());
    375     EXPECT_EQ(_type, read.arg7());
    376 
    377     EXPECT_TRUE(read.has_data());
    378     uint32_t dataLen = 0;
    379     const unsigned char * data = dbg->Decompress(read.data().data(),
    380                                  read.data().length(), &dataLen);
    381     EXPECT_EQ(sizeof(_pixels), dataLen);
    382     if (sizeof(_pixels) == dataLen)
    383         EXPECT_EQ(0, memcmp(_pixels, data, sizeof(_pixels)));
    384 
    385     Read(read);
    386     EXPECT_EQ(read.glTexImage2D, read.function());
    387     EXPECT_EQ(read.AfterCall, read.type());
    388 
    389     CheckNoAvailable();
    390 }
    391 
    392 TEST_F(SocketContextTest, CopyTexImage2D)
    393 {
    394     static const GLenum _target = GL_TEXTURE_2D;
    395     static const GLint _level = 1, _internalformat = GL_RGBA;
    396     static const GLint _x = 9, _y = 99;
    397     static const GLsizei _width = 2, _height = 3;
    398     static const GLint _border = 333;
    399     static const int _pixels [_width * _height] = {11, 22, 33, 44, 55, 66};
    400     static unsigned int copyTexImage2D, readPixels;
    401     copyTexImage2D = 0, readPixels = 0;
    402 
    403     struct Caller {
    404         static void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
    405                                    GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
    406             EXPECT_EQ(_target, target);
    407             EXPECT_EQ(_level, level);
    408             EXPECT_EQ(_internalformat, internalformat);
    409             EXPECT_EQ(_x, x);
    410             EXPECT_EQ(_y, y);
    411             EXPECT_EQ(_width, width);
    412             EXPECT_EQ(_height, height);
    413             EXPECT_EQ(_border, border);
    414             copyTexImage2D++;
    415         }
    416         static void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
    417                                GLenum format, GLenum type, GLvoid* pixels) {
    418             EXPECT_EQ(_x, x);
    419             EXPECT_EQ(_y, y);
    420             EXPECT_EQ(_width, width);
    421             EXPECT_EQ(_height, height);
    422             EXPECT_EQ(GL_RGBA, format);
    423             EXPECT_EQ(GL_UNSIGNED_BYTE, type);
    424             ASSERT_TRUE(pixels != NULL);
    425             memcpy(pixels, _pixels, sizeof(_pixels));
    426             readPixels++;
    427         }
    428     } caller;
    429     glesv2debugger::Message msg, read, cmd;
    430     hooks.gl.glCopyTexImage2D = caller.CopyTexImage2D;
    431     hooks.gl.glReadPixels = caller.ReadPixels;
    432     dbg->expectResponse.Bit(msg.glCopyTexImage2D, false);
    433 
    434     Debug_glCopyTexImage2D(_target, _level, _internalformat, _x, _y, _width, _height,
    435                            _border);
    436     ASSERT_EQ(1, copyTexImage2D);
    437     ASSERT_EQ(1, readPixels);
    438 
    439     Read(read);
    440     EXPECT_EQ(read.glCopyTexImage2D, read.function());
    441     EXPECT_EQ(read.BeforeCall, read.type());
    442     EXPECT_EQ(_target, read.arg0());
    443     EXPECT_EQ(_level, read.arg1());
    444     EXPECT_EQ(_internalformat, read.arg2());
    445     EXPECT_EQ(_x, read.arg3());
    446     EXPECT_EQ(_y, read.arg4());
    447     EXPECT_EQ(_width, read.arg5());
    448     EXPECT_EQ(_height, read.arg6());
    449     EXPECT_EQ(_border, read.arg7());
    450 
    451     EXPECT_TRUE(read.has_data());
    452     EXPECT_EQ(read.ReferencedImage, read.data_type());
    453     EXPECT_EQ(GL_RGBA, read.pixel_format());
    454     EXPECT_EQ(GL_UNSIGNED_BYTE, read.pixel_type());
    455     uint32_t dataLen = 0;
    456     unsigned char * const data = dbg->Decompress(read.data().data(),
    457                                  read.data().length(), &dataLen);
    458     ASSERT_EQ(sizeof(_pixels), dataLen);
    459     for (unsigned i = 0; i < sizeof(_pixels) / sizeof(*_pixels); i++)
    460         EXPECT_EQ(_pixels[i], ((const int *)data)[i]) << "xor with 0 ref is identity";
    461     free(data);
    462 
    463     Read(read);
    464     EXPECT_EQ(read.glCopyTexImage2D, read.function());
    465     EXPECT_EQ(read.AfterCall, read.type());
    466 
    467     CheckNoAvailable();
    468 }
    469