1/** 2 * Copyright © 2009 Red Hat, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#ifdef HAVE_DIX_CONFIG_H 25#include <dix-config.h> 26#endif 27 28/* 29 * Protocol testing for XIQueryVersion request and reply. 30 * 31 * Test approach: 32 * Wrap WriteToClient to intercept the server's reply. 33 * Repeatedly test a client/server version combination, compare version in 34 * reply with versions given. Version must be equal to either 35 * server version or client version, whichever is smaller. 36 * Client version less than 2 must return BadValue. 37 */ 38 39#include <stdint.h> 40#include <X11/X.h> 41#include <X11/Xproto.h> 42#include <X11/extensions/XI2proto.h> 43#include "inputstr.h" 44#include "extinit.h" /* for XInputExtensionInit */ 45#include "scrnintstr.h" 46#include "xiqueryversion.h" 47 48#include "protocol-common.h" 49#include <glib.h> 50 51extern XExtensionVersion XIVersion; 52 53struct test_data { 54 int major_client; 55 int minor_client; 56 int major_server; 57 int minor_server; 58}; 59 60static void reply_XIQueryVersion(ClientPtr client, int len, char* data, void *userdata) 61{ 62 xXIQueryVersionReply *rep = (xXIQueryVersionReply*)data; 63 struct test_data *versions = (struct test_data*)userdata; 64 unsigned int sver, cver, ver; 65 66 if (client->swapped) 67 { 68 char n; 69 swapl(&rep->length, n); 70 swaps(&rep->sequenceNumber, n); 71 swaps(&rep->major_version, n); 72 swaps(&rep->minor_version, n); 73 } 74 75 reply_check_defaults(rep, len, XIQueryVersion); 76 77 g_assert(rep->length == 0); 78 79 sver = versions->major_server * 1000 + versions->minor_server; 80 cver = versions->major_client * 1000 + versions->minor_client; 81 ver = rep->major_version * 1000 + rep->minor_version; 82 83 g_assert(ver >= 2000); 84 g_assert((sver > cver) ? ver == cver : ver == sver); 85} 86 87/** 88 * Run a single test with server version smaj.smin and client 89 * version cmaj.cmin. Verify that return code is equal to 'error'. 90 * 91 * Test is run normal, then for a swapped client. 92 */ 93static void request_XIQueryVersion(int smaj, int smin, int cmaj, int cmin, int error) 94{ 95 char n; 96 int rc; 97 struct test_data versions; 98 xXIQueryVersionReq request; 99 ClientRec client; 100 101 request_init(&request, XIQueryVersion); 102 client = init_client(request.length, &request); 103 userdata = (void*)&versions; 104 105 /* Change the server to support smaj.smin */ 106 XIVersion.major_version = smaj; 107 XIVersion.minor_version = smin; 108 109 /* remember versions we send and expect */ 110 versions.major_client = cmaj; 111 versions.minor_client = cmin; 112 versions.major_server = XIVersion.major_version; 113 versions.minor_server = XIVersion.minor_version; 114 115 request.major_version = versions.major_client; 116 request.minor_version = versions.minor_client; 117 rc = ProcXIQueryVersion(&client); 118 g_assert(rc == error); 119 120 client.swapped = TRUE; 121 122 swaps(&request.length, n); 123 swaps(&request.major_version, n); 124 swaps(&request.minor_version, n); 125 126 rc = SProcXIQueryVersion(&client); 127 g_assert(rc == error); 128} 129 130/* Client version less than 2.0 must return BadValue, all other combinations 131 * Success */ 132static void test_XIQueryVersion(void) 133{ 134 reply_handler = reply_XIQueryVersion; 135 136 g_test_message("Server version 2.0 - client versions [1..3].0"); 137 /* some simple tests to catch common errors quickly */ 138 request_XIQueryVersion(2, 0, 1, 0, BadValue); 139 request_XIQueryVersion(2, 0, 2, 0, Success); 140 request_XIQueryVersion(2, 0, 3, 0, Success); 141 142 g_test_message("Server version 3.0 - client versions [1..3].0"); 143 request_XIQueryVersion(3, 0, 1, 0, BadValue); 144 request_XIQueryVersion(3, 0, 2, 0, Success); 145 request_XIQueryVersion(3, 0, 3, 0, Success); 146 147 g_test_message("Server version 2.0 - client versions [1..3].[1..3]"); 148 request_XIQueryVersion(2, 0, 1, 1, BadValue); 149 request_XIQueryVersion(2, 0, 2, 2, Success); 150 request_XIQueryVersion(2, 0, 3, 3, Success); 151 152 g_test_message("Server version 2.2 - client versions [1..3].0"); 153 request_XIQueryVersion(2, 2, 1, 0, BadValue); 154 request_XIQueryVersion(2, 2, 2, 0, Success); 155 request_XIQueryVersion(2, 2, 3, 0, Success); 156 157#if 0 158 /* this one takes a while */ 159 unsigned int cmin, cmaj, smin, smaj; 160 161 g_test_message("Testing all combinations."); 162 for (smaj = 2; smaj <= 0xFFFF; smaj++) 163 for (smin = 0; smin <= 0xFFFF; smin++) 164 for (cmin = 0; cmin <= 0xFFFF; cmin++) 165 for (cmaj = 0; cmaj <= 0xFFFF; cmaj++) 166 { 167 int error = (cmaj < 2) ? BadValue : Success; 168 request_XIQueryVersion(smaj, smin, cmaj, cmin, error); 169 } 170 171#endif 172 173 reply_handler = NULL; 174} 175 176int main(int argc, char** argv) 177{ 178 g_test_init(&argc, &argv,NULL); 179 g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id="); 180 181 init_simple(); 182 183 g_test_add_func("/xi2/protocol/XIQueryVersion", test_XIQueryVersion); 184 185 return g_test_run(); 186} 187