- finish functionality of ike_sa_manager
[strongswan.git] / Source / charon / tests / ike_sa_manager_test.c
index 9d812a6..e85efe1 100644 (file)
 static struct ike_sa_manager_test_struct_s {
        tester_t *tester;
        ike_sa_manager_t *isam;
-} globals;
+} td;
 
-static void sa_blocker_thread(ike_sa_id_t *ike_sa_id)
+static void successful_thread(ike_sa_id_t *ike_sa_id)
 {
        ike_sa_t *ike_sa;
-       ike_sa_manager_t *isam;
-       tester_t *tester;
        status_t status;
        
-       isam = globals.isam;
-       tester = globals.tester;
-       status = isam->checkout_ike_sa(isam, ike_sa_id, &ike_sa);
-       tester->assert_true(tester, (status == SUCCESS), "checkout_ike_sa as blocker");
-       sleep(1);
-       status = isam->checkin_ike_sa(isam, ike_sa);
-       
+       status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
+       td.tester->assert_true(td.tester, (status == SUCCESS), "checkout of a blocked ike_sa");
+       usleep(10000);
+       status = td.isam->checkin(td.isam, ike_sa);
+       td.tester->assert_true(td.tester, (status == SUCCESS), "checkin of a requested ike_sa");
+}
+
+static void failed_thread(ike_sa_id_t *ike_sa_id)
+{
+       ike_sa_t *ike_sa;
+       status_t status;
        
+       status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
+       td.tester->assert_true(td.tester, (status == NOT_FOUND), "IKE_SA already deleted");
 }
 
 void test_ike_sa_manager(tester_t *tester)
@@ -58,28 +62,150 @@ void test_ike_sa_manager(tester_t *tester)
        spi_t initiator, responder;
        ike_sa_id_t *ike_sa_id;
        ike_sa_t *ike_sa;
-       ike_sa_manager_t *isam;
-       pthread_t threads[3];
+       int thread_count = 200;
+       int sa_count = 50;
+       int i;
+       pthread_t threads[thread_count];
+       
+       td.tester = tester;
+       td.isam = ike_sa_manager_create();
+       
        
-       isam = ike_sa_manager_create();
        
-       /* we play initiator for IKE_SA_INIT first */
+       
+       
+       /* First Test:
+        * we play initiator for IKE_SA_INIT first 
+        * create an IKE_SA, 
+        * 
+        */
        memset(&initiator, 0, sizeof(initiator));
        memset(&responder, 0, sizeof(responder));
        
        ike_sa_id = ike_sa_id_create(initiator, responder, INITIATOR);
 
-       status = isam->checkout_ike_sa(isam, ike_sa_id, &ike_sa);
+       status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
+       tester->assert_true(tester, (status == SUCCESS), "checkout unexisting IKE_SA");
+       /* for testing purposes, we manipulate the responder spi.
+        * this is usually done be the response from the communication partner, 
+        * but we don't have one...
+        */
+       ike_sa_id->destroy(ike_sa_id);
+       ike_sa_id = ike_sa->get_id(ike_sa);
+       responder.low = 123;
+       ike_sa_id->set_responder_spi(ike_sa_id, responder);     
+       /* check in, so we should have a "completed" sa, specified by ike_sa_id */
+       status = td.isam->checkin(td.isam, ike_sa);
+       tester->assert_true(tester, (status == SUCCESS), "checkin modified IKE_SA");
        
-       tester->assert_true(tester, (status == SUCCESS), "checkout_ike_sa as initiator");
-       pthread_create(&threads[0], NULL, (void*(*)(void*))sa_blocker_thread, (void*)ike_sa_id);
+       /* now we check it out and start some other threads */
+       status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
+       tester->assert_true(tester, (status == SUCCESS), "checkout existing IKE_SA 1");
        
        
-       status = isam->checkin_ike_sa(isam, ike_sa);
        
-       pthread_join(threads[0], NULL);
+       for (i = 0; i < thread_count; i++) 
+       {
+               if (pthread_create(&threads[i], NULL, (void*(*)(void*))successful_thread, (void*)ike_sa_id))
+               {
+                       /* failed, decrease list */
+                       thread_count--;
+                       i--;    
+               }
+       }
+       sleep(1);
        
+       status = td.isam->checkin(td.isam, ike_sa);
+       tester->assert_true(tester, (status == SUCCESS), "checkin IKE_SA");
+       
+               
+       sleep(1);
+       /* we now delete the IKE_SA, while it is requested by the threads.
+        * this should block until the have done their work.*/
+       status = td.isam->delete(td.isam, ike_sa_id);
+       tester->assert_true(tester, (status == SUCCESS), "delete IKE_SA by id");
+       
+
+       for (i = 0; i < thread_count; i++) 
+       {
+               pthread_join(threads[i], NULL);
+       }
+       
+       
+       
+       
+       
+       /* Second Test:
+        * now we simulate our partner initiates an IKE_SA_INIT,
+        * so we are the responder.
+        * 
+        */
+       
+       memset(&initiator, 0, sizeof(initiator));
+       memset(&responder, 0, sizeof(responder));
+       
+       initiator.low = 123;
+       ike_sa_id = ike_sa_id_create(initiator, responder, RESPONDER);
+       
+       status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
+       tester->assert_true(tester, (status == SUCCESS), "checkout unexisting IKE_SA 2");
+       //ike_sa_id->destroy(ike_sa_id);
+       for (i = 0; i < thread_count; i++) 
+       {
+               if (pthread_create(&threads[i], NULL, (void*(*)(void*))failed_thread, (void*)ike_sa_id))
+               {
+                       /* failed, decrease list */
+                       thread_count--;
+                       i--;    
+               }
+       }
+       /* let them go acquiring */
+       sleep(1);
+       
+       /* this time, we delete the ike_sa while its checked out */
+       td.isam->checkin_and_delete(td.isam, ike_sa);
+       tester->assert_true(tester, (status == SUCCESS), "delete IKE_SA by SA");
+       
+       for (i = 0; i < thread_count; i++) 
+       {
+               pthread_join(threads[i], NULL);
+       }
+       
+       /* Third Test:
+        * put in a lot of IKE_SAs, check it out, set a thread waiting
+        * and destroy the manager...
+        */
+               
+       memset(&initiator, 0, sizeof(initiator));
+       memset(&responder, 0, sizeof(responder));
+       
+       thread_count = sa_count;
+       
+       for (i = 0; i < sa_count; i++) 
+       {
+               initiator.low = i + 1;
+               ike_sa_id = ike_sa_id_create(initiator, responder, RESPONDER);
+               
+               status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
+               tester->assert_true(tester, (status == SUCCESS), "checkout unexisting IKE_SA 3");
+
+               if (pthread_create(&threads[i], NULL, (void*(*)(void*))failed_thread, (void*)ike_sa_id))
+               {
+                       /* failed, decrease list */
+                       thread_count--;
+               }
+               //ike_sa_id->destroy(ike_sa_id);
+       }
+       
+       /* let them go acquiring */
+       sleep(1);
+       
+       td.isam->destroy(td.isam);
+       
+       for (i = 0; i < thread_count; i++) 
+       {
+               pthread_join(threads[i], NULL);
+       }
        
-       ike_sa_id->destroy(ike_sa_id);
-       isam->destroy(isam);
 }
+